remote-components 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/nextjs.cjs +86 -37
- package/dist/config/nextjs.cjs.map +1 -1
- package/dist/config/nextjs.js +86 -37
- package/dist/config/nextjs.js.map +1 -1
- package/dist/config/webpack.cjs +5 -1
- package/dist/config/webpack.cjs.map +1 -1
- package/dist/config/webpack.js +5 -1
- package/dist/config/webpack.js.map +1 -1
- package/dist/host/html.cjs +861 -617
- package/dist/host/html.cjs.map +1 -1
- package/dist/host/html.js +861 -617
- package/dist/host/html.js.map +1 -1
- package/dist/host/nextjs/app/client-only.cjs +700 -383
- package/dist/host/nextjs/app/client-only.cjs.map +1 -1
- package/dist/host/nextjs/app/client-only.js +674 -357
- package/dist/host/nextjs/app/client-only.js.map +1 -1
- package/dist/host/nextjs/app.cjs +34 -2
- package/dist/host/nextjs/app.cjs.map +1 -1
- package/dist/host/nextjs/app.js +35 -3
- package/dist/host/nextjs/app.js.map +1 -1
- package/dist/host/react.cjs +641 -352
- package/dist/host/react.cjs.map +1 -1
- package/dist/host/react.js +641 -352
- package/dist/host/react.js.map +1 -1
- package/dist/internal/config/webpack/apply-shared-modules.cjs +6 -4
- package/dist/internal/config/webpack/apply-shared-modules.cjs.map +1 -1
- package/dist/internal/config/webpack/apply-shared-modules.js +6 -4
- package/dist/internal/config/webpack/apply-shared-modules.js.map +1 -1
- package/dist/internal/config/webpack/next-client-pages-loader.cjs +6 -7
- package/dist/internal/config/webpack/next-client-pages-loader.cjs.map +1 -1
- package/dist/internal/config/webpack/next-client-pages-loader.js +6 -7
- package/dist/internal/config/webpack/next-client-pages-loader.js.map +1 -1
- package/dist/internal/host/nextjs/app-client.cjs +42 -27
- package/dist/internal/host/nextjs/app-client.cjs.map +1 -1
- package/dist/internal/host/nextjs/app-client.js +42 -27
- package/dist/internal/host/nextjs/app-client.js.map +1 -1
- package/dist/internal/host/nextjs/dom-flight.cjs +19 -39
- package/dist/internal/host/nextjs/dom-flight.cjs.map +1 -1
- package/dist/internal/host/nextjs/dom-flight.js +31 -39
- package/dist/internal/host/nextjs/dom-flight.js.map +1 -1
- package/dist/internal/host/nextjs/image-shared.cjs +39 -3
- package/dist/internal/host/nextjs/image-shared.cjs.map +1 -1
- package/dist/internal/host/nextjs/image-shared.d.ts +5 -10
- package/dist/internal/host/nextjs/image-shared.js +29 -3
- package/dist/internal/host/nextjs/image-shared.js.map +1 -1
- package/dist/internal/host/nextjs/remote-component-links.cjs +24 -13
- package/dist/internal/host/nextjs/remote-component-links.cjs.map +1 -1
- package/dist/internal/host/nextjs/remote-component-links.d.ts +3 -0
- package/dist/internal/host/nextjs/remote-component-links.js +24 -13
- package/dist/internal/host/nextjs/remote-component-links.js.map +1 -1
- package/dist/internal/host/server/fetch-remote-component.cjs +2 -1
- package/dist/internal/host/server/fetch-remote-component.cjs.map +1 -1
- package/dist/internal/host/server/fetch-remote-component.js +2 -1
- package/dist/internal/host/server/fetch-remote-component.js.map +1 -1
- package/dist/internal/host/shared/lifecycle.cjs +69 -0
- package/dist/internal/host/shared/lifecycle.cjs.map +1 -0
- package/dist/internal/host/shared/lifecycle.d.ts +34 -0
- package/dist/internal/host/shared/lifecycle.js +44 -0
- package/dist/internal/host/shared/lifecycle.js.map +1 -0
- package/dist/internal/host/shared/pipeline.cjs +222 -0
- package/dist/internal/host/shared/pipeline.cjs.map +1 -0
- package/dist/internal/host/shared/pipeline.d.ts +153 -0
- package/dist/internal/host/shared/pipeline.js +200 -0
- package/dist/internal/host/shared/pipeline.js.map +1 -0
- package/dist/internal/host/shared/polyfill.cjs +8 -7
- package/dist/internal/host/shared/polyfill.cjs.map +1 -1
- package/dist/internal/host/shared/polyfill.js +8 -7
- package/dist/internal/host/shared/polyfill.js.map +1 -1
- package/dist/internal/host/shared/shared-module-resolver.cjs +117 -0
- package/dist/internal/host/shared/shared-module-resolver.cjs.map +1 -0
- package/dist/internal/host/shared/shared-module-resolver.d.ts +64 -0
- package/dist/internal/host/shared/shared-module-resolver.js +78 -0
- package/dist/internal/host/shared/shared-module-resolver.js.map +1 -0
- package/dist/internal/remote/nextjs/next-internals.cjs +53 -0
- package/dist/internal/remote/nextjs/next-internals.cjs.map +1 -0
- package/dist/internal/remote/nextjs/next-internals.d.ts +42 -0
- package/dist/internal/remote/nextjs/next-internals.js +26 -0
- package/dist/internal/remote/nextjs/next-internals.js.map +1 -0
- package/dist/internal/runtime/html/apply-origin.cjs +11 -32
- package/dist/internal/runtime/html/apply-origin.cjs.map +1 -1
- package/dist/internal/runtime/html/apply-origin.js +11 -32
- package/dist/internal/runtime/html/apply-origin.js.map +1 -1
- package/dist/internal/runtime/html/html-spec.cjs +78 -0
- package/dist/internal/runtime/html/html-spec.cjs.map +1 -0
- package/dist/internal/runtime/html/html-spec.d.ts +23 -0
- package/dist/internal/runtime/html/html-spec.js +41 -0
- package/dist/internal/runtime/html/html-spec.js.map +1 -0
- package/dist/internal/runtime/html/parse-remote-html.cjs +15 -12
- package/dist/internal/runtime/html/parse-remote-html.cjs.map +1 -1
- package/dist/internal/runtime/html/parse-remote-html.js +29 -12
- package/dist/internal/runtime/html/parse-remote-html.js.map +1 -1
- package/dist/internal/runtime/html/rewrite-srcset.cjs +38 -0
- package/dist/internal/runtime/html/rewrite-srcset.cjs.map +1 -0
- package/dist/internal/runtime/html/rewrite-srcset.d.ts +12 -0
- package/dist/internal/runtime/html/rewrite-srcset.js +14 -0
- package/dist/internal/runtime/html/rewrite-srcset.js.map +1 -0
- package/dist/internal/runtime/loaders/component-loader.cjs +25 -44
- package/dist/internal/runtime/loaders/component-loader.cjs.map +1 -1
- package/dist/internal/runtime/loaders/component-loader.d.ts +3 -1
- package/dist/internal/runtime/loaders/component-loader.js +28 -44
- package/dist/internal/runtime/loaders/component-loader.js.map +1 -1
- package/dist/internal/runtime/loaders/static-loader.cjs +15 -21
- package/dist/internal/runtime/loaders/static-loader.cjs.map +1 -1
- package/dist/internal/runtime/loaders/static-loader.d.ts +3 -1
- package/dist/internal/runtime/loaders/static-loader.js +15 -21
- package/dist/internal/runtime/loaders/static-loader.js.map +1 -1
- package/dist/internal/runtime/namespace.cjs +82 -0
- package/dist/internal/runtime/namespace.cjs.map +1 -0
- package/dist/internal/runtime/namespace.d.ts +5 -0
- package/dist/internal/runtime/namespace.js +58 -0
- package/dist/internal/runtime/namespace.js.map +1 -0
- package/dist/internal/runtime/rsc-imports.cjs +86 -0
- package/dist/internal/runtime/rsc-imports.cjs.map +1 -0
- package/dist/internal/runtime/rsc-imports.d.ts +39 -0
- package/dist/internal/runtime/rsc-imports.js +50 -0
- package/dist/internal/runtime/rsc-imports.js.map +1 -0
- package/dist/internal/runtime/rsc-runtime.cjs +17 -0
- package/dist/internal/runtime/rsc-runtime.cjs.map +1 -0
- package/dist/internal/runtime/rsc-runtime.d.ts +37 -0
- package/dist/internal/runtime/rsc-runtime.js +1 -0
- package/dist/internal/runtime/rsc-runtime.js.map +1 -0
- package/dist/internal/runtime/rsc.cjs +23 -12
- package/dist/internal/runtime/rsc.cjs.map +1 -1
- package/dist/internal/runtime/rsc.d.ts +19 -2
- package/dist/internal/runtime/rsc.js +20 -11
- package/dist/internal/runtime/rsc.js.map +1 -1
- package/dist/internal/runtime/turbopack/chunk-loader.cjs +53 -35
- package/dist/internal/runtime/turbopack/chunk-loader.cjs.map +1 -1
- package/dist/internal/runtime/turbopack/chunk-loader.d.ts +1 -1
- package/dist/internal/runtime/turbopack/chunk-loader.js +53 -35
- package/dist/internal/runtime/turbopack/chunk-loader.js.map +1 -1
- package/dist/internal/runtime/turbopack/module.cjs +17 -4
- package/dist/internal/runtime/turbopack/module.cjs.map +1 -1
- package/dist/internal/runtime/turbopack/module.d.ts +23 -1
- package/dist/internal/runtime/turbopack/module.js +16 -4
- package/dist/internal/runtime/turbopack/module.js.map +1 -1
- package/dist/internal/runtime/turbopack/patterns.cjs +26 -10
- package/dist/internal/runtime/turbopack/patterns.cjs.map +1 -1
- package/dist/internal/runtime/turbopack/patterns.d.ts +44 -49
- package/dist/internal/runtime/turbopack/patterns.js +23 -7
- package/dist/internal/runtime/turbopack/patterns.js.map +1 -1
- package/dist/internal/runtime/turbopack/{webpack-runtime.cjs → remote-scope-setup.cjs} +35 -32
- package/dist/internal/runtime/turbopack/remote-scope-setup.cjs.map +1 -0
- package/dist/internal/runtime/turbopack/remote-scope-setup.d.ts +25 -0
- package/dist/internal/runtime/turbopack/{webpack-runtime.js → remote-scope-setup.js} +36 -19
- package/dist/internal/runtime/turbopack/remote-scope-setup.js.map +1 -0
- package/dist/internal/runtime/turbopack/remote-scope.cjs +4 -6
- package/dist/internal/runtime/turbopack/remote-scope.cjs.map +1 -1
- package/dist/internal/runtime/turbopack/remote-scope.d.ts +20 -1
- package/dist/internal/runtime/turbopack/remote-scope.js +4 -6
- package/dist/internal/runtime/turbopack/remote-scope.js.map +1 -1
- package/dist/internal/runtime/turbopack/shared-modules.cjs +21 -15
- package/dist/internal/runtime/turbopack/shared-modules.cjs.map +1 -1
- package/dist/internal/runtime/turbopack/shared-modules.d.ts +9 -2
- package/dist/internal/runtime/turbopack/shared-modules.js +24 -18
- package/dist/internal/runtime/turbopack/shared-modules.js.map +1 -1
- package/dist/internal/runtime/types.cjs.map +1 -1
- package/dist/internal/runtime/types.d.ts +5 -41
- package/dist/internal/utils/logger.cjs +1 -1
- package/dist/internal/utils/logger.cjs.map +1 -1
- package/dist/internal/utils/logger.d.ts +2 -2
- package/dist/internal/utils/logger.js +1 -1
- package/dist/internal/utils/logger.js.map +1 -1
- package/dist/remote/html.cjs +78 -22
- package/dist/remote/html.cjs.map +1 -1
- package/dist/remote/html.js +78 -22
- package/dist/remote/html.js.map +1 -1
- package/dist/remote/nextjs/app.cjs +14 -55
- package/dist/remote/nextjs/app.cjs.map +1 -1
- package/dist/remote/nextjs/app.js +24 -45
- package/dist/remote/nextjs/app.js.map +1 -1
- package/dist/types-59251814.d.ts +94 -0
- package/package.json +2 -2
- package/dist/internal/runtime/turbopack/webpack-runtime.cjs.map +0 -1
- package/dist/internal/runtime/turbopack/webpack-runtime.d.ts +0 -23
- package/dist/internal/runtime/turbopack/webpack-runtime.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/host/server/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { type RSC, visit } from '#internal/host/nextjs/dom-flight';\nimport {\n getSkeletonHtml,\n getSkeletonMessage,\n} from '#internal/host/nextjs/skeleton';\nimport { fetchWithHooks } from '#internal/host/server/fetch-with-hooks';\nimport { getClientSrc } from '#internal/host/server/get-client-src';\nimport { getSSRRelativePathBaseUrl } from '#internal/host/server/get-ssr-relative-path-base-url';\nimport type {\n LinkDescriptor,\n ScriptDescriptor,\n} from '#internal/host/shared/asset-descriptors';\nimport type {\n OnRequestHook,\n OnResponseHook,\n} from '#internal/host/shared/fetch-interceptors';\nimport {\n buildMetadata,\n type RawMetadataAttrs,\n type RemoteComponentMetadata,\n} from '#internal/runtime/metadata';\nimport { computeScopedName } from '#internal/utils';\nimport {\n failedToFetchRemoteComponentError,\n multipleRemoteComponentsError,\n RemoteComponentsError,\n} from '#internal/utils/error';\nimport type { FetchRemoteComponentResponse, NextData } from './types';\n\n/**\n * Converts RSC flight data into a React element tree using the edge streaming\n * runtime. The manifest tells React how to resolve module references back to\n * the remote origin.\n */\nasync function buildRscComponent(\n rsc: RSC | RSC[] | string | null,\n serverUrl: URL,\n): Promise<React.ReactNode> {\n const componentRSC = `0:${JSON.stringify(rsc)}\\n`;\n const { createFromReadableStream } = await import(\n 'next/dist/compiled/react-server-dom-webpack/client.edge'\n );\n return createFromReadableStream(\n new ReadableStream({\n type: 'bytes',\n start(controller) {\n const encoder = new TextEncoder();\n controller.enqueue(encoder.encode(componentRSC));\n controller.close();\n },\n }),\n {\n serverConsumerManifest: {\n moduleLoading: {\n prefix: serverUrl.origin,\n crossOrigin: true,\n },\n moduleMap: {},\n },\n },\n );\n}\n\nfunction buildSkeletonResponse(\n serverUrl: URL,\n metadata: RemoteComponentMetadata,\n skeletonComponent: React.ReactNode | undefined,\n): FetchRemoteComponentResponse {\n return {\n name: 'remote-component-skeleton',\n serverUrl,\n metadata: {\n ...metadata,\n type: 'remote-component',\n },\n rsc: getSkeletonMessage(),\n scripts: [],\n links: [],\n hydrationData: [],\n nextData: undefined,\n component: skeletonComponent,\n html: getSkeletonHtml(serverUrl.href),\n remoteShared: {},\n };\n}\n\n/**\n * Rewrites the bundle identifier in RSC flight data from the plain bundle\n * name to the origin-qualified scoped name. When multiple remotes share the\n * same bundle name (e.g. production and preview of the same app), this\n * makes each one unique so the client can look up the correct RemoteScope\n * by name alone.\n *\n * `[bundle] /path` → `[scopedName] /path`\n * `[bundle] 12345` → `[scopedName] 12345`\n *\n * Only applied for cross-origin remotes — same-origin chunks keep the\n * plain bundle name since there's no ambiguity.\n */\nfunction scopeChunkReferences(\n chunk: string,\n bundle: string,\n scopedName: string,\n): string {\n return chunk.replaceAll(`[${bundle}]`, `[${scopedName}]`);\n}\n\n/**\n * Walks the parsed HTML fragment and extracts all remote component data:\n * metadata, scripts, links, hydration data, Next.js data, shared deps, and HTML.\n */\nfunction visitFragment(\n fragment: DefaultTreeAdapterMap['documentFragment'],\n serverUrl: URL,\n remoteName: string | undefined,\n) {\n const scriptSrcSet = new Set<string>();\n const scriptTextSet = new Set<string>();\n const scripts: ScriptDescriptor[] = [];\n\n const linkKeySet = new Set<string>();\n const links: LinkDescriptor[] = [];\n\n const hydrationData: string[] = [];\n const htmlChunks = new Set<string>();\n\n let metadata: RemoteComponentMetadata | undefined;\n let nextData: NextData | undefined;\n let remoteShared: Record<string, string> = {};\n let hasRSC = false;\n let hasShared = false;\n let error: RemoteComponentsError | undefined;\n\n // For cross-origin remotes, rewrite bundle identifiers in RSC chunks to\n // the scoped name so the client dispatchers resolve the correct scope.\n // Chunks are collected raw during visit() and rewritten afterwards because\n // RSC script tags appear before the metadata element in the HTML.\n const isCrossOrigin = serverUrl.origin !== getSSRRelativePathBaseUrl();\n\n const rawRscChunks: string[] = [];\n\n const rsc = visit(fragment, {\n url: serverUrl,\n name: remoteName,\n onMetadata(attrs: RawMetadataAttrs) {\n const incoming = buildMetadata(attrs, serverUrl);\n // Skip multiple component detection for Pages Router (__next) since\n // it only supports one remote component per page\n if (\n !remoteName &&\n metadata &&\n metadata.id !== incoming.id &&\n incoming.id !== '__next' &&\n metadata.id !== '__next' &&\n !nextData\n ) {\n throw multipleRemoteComponentsError(serverUrl.href);\n }\n metadata = incoming;\n },\n onScript(attrs) {\n const clientSrc = getClientSrc(attrs.src, serverUrl.href);\n const textContent =\n typeof attrs.textContent === 'string' ? attrs.textContent : undefined;\n\n if (textContent) {\n if (!scriptTextSet.has(textContent)) {\n scriptTextSet.add(textContent);\n scripts.push({ src: '', textContent });\n }\n } else if (!scriptSrcSet.has(clientSrc)) {\n scriptSrcSet.add(clientSrc);\n scripts.push({ src: clientSrc });\n }\n },\n onLink(attrs) {\n const relativeAttrs = {\n ...attrs,\n href: getClientSrc(attrs.href, serverUrl.href),\n };\n const linkKey = `${relativeAttrs.href}::${attrs.rel}`;\n if (!linkKeySet.has(linkKey)) {\n linkKeySet.add(linkKey);\n links.push(relativeAttrs);\n }\n },\n onRSC(chunk) {\n rawRscChunks.push(chunk);\n hasRSC = true;\n },\n onNextData(data) {\n nextData = data;\n },\n onHTML(chunk) {\n if (!htmlChunks.has(chunk)) {\n htmlChunks.add(chunk);\n }\n },\n onShared(_shared) {\n remoteShared = _shared;\n hasShared = true;\n },\n onError(message, stack) {\n error = new RemoteComponentsError(message);\n if (stack) {\n error.stack = stack;\n }\n },\n });\n\n // Rewrite bundle identifiers in RSC chunk references to use the scoped name\n // so the client dispatchers can resolve the correct scope with a direct lookup.\n // This must happen after visit() because RSC script tags appear before the\n // metadata element in the HTML.\n if (isCrossOrigin && metadata?.bundle) {\n const scopedName = computeScopedName(metadata.bundle, {\n remoteHost: serverUrl.host,\n isCrossOrigin: true,\n });\n for (const chunk of rawRscChunks) {\n hydrationData.push(\n scopeChunkReferences(chunk, metadata.bundle, scopedName),\n );\n }\n } else {\n hydrationData.push(...rawRscChunks);\n }\n\n if (error) {\n throw error;\n }\n\n if (metadata) {\n if (!hasRSC && !nextData && metadata.type === 'nextjs') {\n throw new RemoteComponentsError(\n `The Remote Component at \"${serverUrl.href}\" seems to be a Next.js component but it does not contain any RSC flight data or Next.js props data. Make sure the remote URL is correct and contains a Remote Component.`,\n );\n }\n\n if (\n metadata.type === 'nextjs' &&\n !hasShared &&\n !nextData?.props.__REMOTE_COMPONENT__?.shared\n ) {\n throw new RemoteComponentsError(\n `No shared dependencies found for Remote Component at \"${serverUrl.href}\". Make sure the remote URL is correct and contains a Remote Component with shared dependencies.`,\n );\n }\n }\n\n const resolvedShared =\n nextData?.props.__REMOTE_COMPONENT__?.shared ?? remoteShared;\n\n return {\n rsc,\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n remoteShared: resolvedShared,\n html: Array.from(htmlChunks).join(''),\n };\n}\n\nexport async function fetchRemoteComponent(\n src: string | URL,\n options: {\n name?: string;\n rsc?: boolean;\n /** Whether this is being called from Next.js App Router. Used to enable skeleton fallback during SSG builds. */\n appRouter?: boolean;\n onRequest?: OnRequestHook;\n onResponse?: OnResponseHook;\n } = {},\n): Promise<FetchRemoteComponentResponse> {\n const ssrRelativePathBaseUrl = getSSRRelativePathBaseUrl();\n const serverUrl = new URL(src, ssrRelativePathBaseUrl);\n\n const tags = [\n '_vc_rc:fetch-remote-component',\n // the max size of a next cache tag is 256 characters\n serverUrl.host.slice(0, 256),\n // use the suffix so this tag is unique if multiple remote\n // components have the same host, but unique pathnames / query params\n (typeof src === 'string' ? src : src.href).slice(-256),\n ];\n if (options.name) {\n tags.push(options.name.slice(-256));\n }\n\n const fetchInit = {\n next: {\n tags,\n },\n };\n\n const res = await fetchWithHooks(serverUrl, fetchInit, {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\n });\n\n // If there is an error in the remote, parse and extract the remote error (except 404 and 401).\n if (!res.ok && !res.body) {\n throw failedToFetchRemoteComponentError(serverUrl.href, res);\n }\n\n if (res.status === 401) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n 'If you are using Deployment Protection, ensure the automation bypass environment variable secret in the host matches an automation bypass value in the remote. See https://remote-components-docs.vercel.sh/docs/concepts/cors-external-urls#deployment-protection for details.',\n );\n }\n\n if (res.status === 404) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n 'Check if you can open it in the browser.',\n );\n }\n\n // create a parser for the HTML response\n const parser = Parser.getFragmentParser<DefaultTreeAdapterMap>();\n\n if (!res.body) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n `Response body is empty. Check if you can open it in the browser and you see the Remote Component content.`,\n );\n }\n\n const decoder = new TextDecoder();\n // read the response body as a stream and parse it using the parse5 fragment parser\n for await (const chunk of res.body as unknown as AsyncIterable<Uint8Array>) {\n parser.tokenizer.write(decoder.decode(chunk), false);\n }\n const fragment = parser.getFragment();\n\n const remoteName =\n options.name || (serverUrl.hash ? serverUrl.hash.substring(1) : undefined);\n\n const {\n rsc,\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n remoteShared,\n html,\n } = visitFragment(fragment, serverUrl, remoteName);\n\n if (!metadata) {\n // For microfrontend builds during run time, the host and remote build\n // may be happening concurrently. In this case, the request will 404.\n // We want to allow the build to continue with a placeholder remote\n // component. Once the build completes, vercel will automatically revalidate\n // ISR and fetch the built remote component.\n const isSSGBuild = process.env.NEXT_PHASE === 'phase-production-build';\n // If the remote component is part of a microfrontend, the src provided\n // will be relative.\n const isSSRRelativePathBase =\n serverUrl.host === new URL(ssrRelativePathBaseUrl).host;\n // Only want this skeleton behaviour in previews to unblock development.\n // For production, the remote component should already be built.\n const isPreview = process.env.VERCEL_TARGET_ENV === 'preview';\n\n if (isSSGBuild && isSSRRelativePathBase && isPreview && options.appRouter) {\n let skeletonComponent: React.ReactNode | undefined;\n if (options.rsc) {\n const { createElement } = await import('react');\n skeletonComponent = createElement('div', {\n dangerouslySetInnerHTML: {\n __html: getSkeletonHtml(serverUrl.href),\n },\n });\n }\n\n return buildSkeletonResponse(\n serverUrl,\n buildMetadata({}, serverUrl),\n skeletonComponent,\n );\n }\n\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n `No Remote Component found. Make sure the remote URL is correct and contains a Remote Component.`,\n );\n }\n\n const name = remoteName || metadata.name;\n const component = options.rsc\n ? await buildRscComponent(rsc, serverUrl)\n : undefined;\n\n return {\n name,\n serverUrl,\n metadata,\n rsc,\n scripts,\n links,\n hydrationData,\n nextData,\n component,\n html,\n remoteShared,\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/server/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { type RSC, visit } from '#internal/host/nextjs/dom-flight';\nimport {\n getSkeletonHtml,\n getSkeletonMessage,\n} from '#internal/host/nextjs/skeleton';\nimport { fetchWithHooks } from '#internal/host/server/fetch-with-hooks';\nimport { getClientSrc } from '#internal/host/server/get-client-src';\nimport { getSSRRelativePathBaseUrl } from '#internal/host/server/get-ssr-relative-path-base-url';\nimport type {\n LinkDescriptor,\n ScriptDescriptor,\n} from '#internal/host/shared/asset-descriptors';\nimport type {\n OnRequestHook,\n OnResponseHook,\n} from '#internal/host/shared/fetch-interceptors';\nimport {\n buildMetadata,\n type RawMetadataAttrs,\n type RemoteComponentMetadata,\n} from '#internal/runtime/metadata';\nimport { importRSCClientEdge } from '#internal/runtime/rsc-imports';\nimport { computeScopedName } from '#internal/utils';\nimport {\n failedToFetchRemoteComponentError,\n multipleRemoteComponentsError,\n RemoteComponentsError,\n} from '#internal/utils/error';\nimport type { FetchRemoteComponentResponse, NextData } from './types';\n\n/**\n * Converts RSC flight data into a React element tree using the edge streaming\n * runtime. The manifest tells React how to resolve module references back to\n * the remote origin.\n */\nasync function buildRscComponent(\n rsc: RSC | RSC[] | string | null,\n serverUrl: URL,\n): Promise<React.ReactNode> {\n const componentRSC = `0:${JSON.stringify(rsc)}\\n`;\n const { createFromReadableStream } = await importRSCClientEdge();\n return createFromReadableStream(\n new ReadableStream({\n type: 'bytes',\n start(controller) {\n const encoder = new TextEncoder();\n controller.enqueue(encoder.encode(componentRSC));\n controller.close();\n },\n }),\n {\n serverConsumerManifest: {\n moduleLoading: {\n prefix: serverUrl.origin,\n crossOrigin: true,\n },\n moduleMap: {},\n },\n },\n );\n}\n\nfunction buildSkeletonResponse(\n serverUrl: URL,\n metadata: RemoteComponentMetadata,\n skeletonComponent: React.ReactNode | undefined,\n): FetchRemoteComponentResponse {\n return {\n name: 'remote-component-skeleton',\n serverUrl,\n metadata: {\n ...metadata,\n type: 'remote-component',\n },\n rsc: getSkeletonMessage(),\n scripts: [],\n links: [],\n hydrationData: [],\n nextData: undefined,\n component: skeletonComponent,\n html: getSkeletonHtml(serverUrl.href),\n remoteShared: {},\n };\n}\n\n/**\n * Rewrites the bundle identifier in RSC flight data from the plain bundle\n * name to the origin-qualified scoped name. When multiple remotes share the\n * same bundle name (e.g. production and preview of the same app), this\n * makes each one unique so the client can look up the correct RemoteScope\n * by name alone.\n *\n * `[bundle] /path` → `[scopedName] /path`\n * `[bundle] 12345` → `[scopedName] 12345`\n *\n * Only applied for cross-origin remotes — same-origin chunks keep the\n * plain bundle name since there's no ambiguity.\n */\nfunction scopeChunkReferences(\n chunk: string,\n bundle: string,\n scopedName: string,\n): string {\n return chunk.replaceAll(`[${bundle}]`, `[${scopedName}]`);\n}\n\n/**\n * Walks the parsed HTML fragment and extracts all remote component data:\n * metadata, scripts, links, hydration data, Next.js data, shared deps, and HTML.\n */\nfunction visitFragment(\n fragment: DefaultTreeAdapterMap['documentFragment'],\n serverUrl: URL,\n remoteName: string | undefined,\n) {\n const scriptSrcSet = new Set<string>();\n const scriptTextSet = new Set<string>();\n const scripts: ScriptDescriptor[] = [];\n\n const linkKeySet = new Set<string>();\n const links: LinkDescriptor[] = [];\n\n const hydrationData: string[] = [];\n const htmlChunks = new Set<string>();\n\n let metadata: RemoteComponentMetadata | undefined;\n let nextData: NextData | undefined;\n let remoteShared: Record<string, string> = {};\n let hasRSC = false;\n let hasShared = false;\n let error: RemoteComponentsError | undefined;\n\n // For cross-origin remotes, rewrite bundle identifiers in RSC chunks to\n // the scoped name so the client dispatchers resolve the correct scope.\n // Chunks are collected raw during visit() and rewritten afterwards because\n // RSC script tags appear before the metadata element in the HTML.\n const isCrossOrigin = serverUrl.origin !== getSSRRelativePathBaseUrl();\n\n const rawRscChunks: string[] = [];\n\n const rsc = visit(fragment, {\n url: serverUrl,\n name: remoteName,\n onMetadata(attrs: RawMetadataAttrs) {\n const incoming = buildMetadata(attrs, serverUrl);\n // Skip multiple component detection for Pages Router (__next) since\n // it only supports one remote component per page\n if (\n !remoteName &&\n metadata &&\n metadata.id !== incoming.id &&\n incoming.id !== '__next' &&\n metadata.id !== '__next' &&\n !nextData\n ) {\n throw multipleRemoteComponentsError(serverUrl.href);\n }\n metadata = incoming;\n },\n onScript(attrs) {\n const clientSrc = getClientSrc(attrs.src, serverUrl.href);\n const textContent =\n typeof attrs.textContent === 'string' ? attrs.textContent : undefined;\n\n if (textContent) {\n if (!scriptTextSet.has(textContent)) {\n scriptTextSet.add(textContent);\n scripts.push({ src: '', textContent });\n }\n } else if (!scriptSrcSet.has(clientSrc)) {\n scriptSrcSet.add(clientSrc);\n scripts.push({ src: clientSrc });\n }\n },\n onLink(attrs) {\n const relativeAttrs = {\n ...attrs,\n href: getClientSrc(attrs.href, serverUrl.href),\n };\n const linkKey = `${relativeAttrs.href}::${attrs.rel}`;\n if (!linkKeySet.has(linkKey)) {\n linkKeySet.add(linkKey);\n links.push(relativeAttrs);\n }\n },\n onRSC(chunk) {\n rawRscChunks.push(chunk);\n hasRSC = true;\n },\n onNextData(data) {\n nextData = data;\n },\n onHTML(chunk) {\n if (!htmlChunks.has(chunk)) {\n htmlChunks.add(chunk);\n }\n },\n onShared(_shared) {\n remoteShared = _shared;\n hasShared = true;\n },\n onError(message, stack) {\n error = new RemoteComponentsError(message);\n if (stack) {\n error.stack = stack;\n }\n },\n });\n\n // Rewrite bundle identifiers in RSC chunk references to use the scoped name\n // so the client dispatchers can resolve the correct scope with a direct lookup.\n // This must happen after visit() because RSC script tags appear before the\n // metadata element in the HTML.\n if (isCrossOrigin && metadata?.bundle) {\n const scopedName = computeScopedName(metadata.bundle, {\n remoteHost: serverUrl.host,\n isCrossOrigin: true,\n });\n for (const chunk of rawRscChunks) {\n hydrationData.push(\n scopeChunkReferences(chunk, metadata.bundle, scopedName),\n );\n }\n } else {\n hydrationData.push(...rawRscChunks);\n }\n\n if (error) {\n throw error;\n }\n\n if (metadata) {\n if (!hasRSC && !nextData && metadata.type === 'nextjs') {\n throw new RemoteComponentsError(\n `The Remote Component at \"${serverUrl.href}\" seems to be a Next.js component but it does not contain any RSC flight data or Next.js props data. Make sure the remote URL is correct and contains a Remote Component.`,\n );\n }\n\n if (\n metadata.type === 'nextjs' &&\n !hasShared &&\n !nextData?.props.__REMOTE_COMPONENT__?.shared\n ) {\n throw new RemoteComponentsError(\n `No shared dependencies found for Remote Component at \"${serverUrl.href}\". Make sure the remote URL is correct and contains a Remote Component with shared dependencies.`,\n );\n }\n }\n\n const resolvedShared =\n nextData?.props.__REMOTE_COMPONENT__?.shared ?? remoteShared;\n\n return {\n rsc,\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n remoteShared: resolvedShared,\n html: Array.from(htmlChunks).join(''),\n };\n}\n\nexport async function fetchRemoteComponent(\n src: string | URL,\n options: {\n name?: string;\n rsc?: boolean;\n /** Whether this is being called from Next.js App Router. Used to enable skeleton fallback during SSG builds. */\n appRouter?: boolean;\n onRequest?: OnRequestHook;\n onResponse?: OnResponseHook;\n } = {},\n): Promise<FetchRemoteComponentResponse> {\n const ssrRelativePathBaseUrl = getSSRRelativePathBaseUrl();\n const serverUrl = new URL(src, ssrRelativePathBaseUrl);\n\n const tags = [\n '_vc_rc:fetch-remote-component',\n // the max size of a next cache tag is 256 characters\n serverUrl.host.slice(0, 256),\n // use the suffix so this tag is unique if multiple remote\n // components have the same host, but unique pathnames / query params\n (typeof src === 'string' ? src : src.href).slice(-256),\n ];\n if (options.name) {\n tags.push(options.name.slice(-256));\n }\n\n const fetchInit = {\n next: {\n tags,\n },\n };\n\n const res = await fetchWithHooks(serverUrl, fetchInit, {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\n });\n\n // If there is an error in the remote, parse and extract the remote error (except 404 and 401).\n if (!res.ok && !res.body) {\n throw failedToFetchRemoteComponentError(serverUrl.href, res);\n }\n\n if (res.status === 401) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n 'If you are using Deployment Protection, ensure the automation bypass environment variable secret in the host matches an automation bypass value in the remote. See https://remote-components-docs.vercel.sh/docs/concepts/cors-external-urls#deployment-protection for details.',\n );\n }\n\n if (res.status === 404) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n 'Check if you can open it in the browser.',\n );\n }\n\n // create a parser for the HTML response\n const parser = Parser.getFragmentParser<DefaultTreeAdapterMap>();\n\n if (!res.body) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n `Response body is empty. Check if you can open it in the browser and you see the Remote Component content.`,\n );\n }\n\n const decoder = new TextDecoder();\n // read the response body as a stream and parse it using the parse5 fragment parser\n for await (const chunk of res.body as unknown as AsyncIterable<Uint8Array>) {\n parser.tokenizer.write(decoder.decode(chunk), false);\n }\n const fragment = parser.getFragment();\n\n const remoteName =\n options.name || (serverUrl.hash ? serverUrl.hash.substring(1) : undefined);\n\n const {\n rsc,\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n remoteShared,\n html,\n } = visitFragment(fragment, serverUrl, remoteName);\n\n if (!metadata) {\n // For microfrontend builds during run time, the host and remote build\n // may be happening concurrently. In this case, the request will 404.\n // We want to allow the build to continue with a placeholder remote\n // component. Once the build completes, vercel will automatically revalidate\n // ISR and fetch the built remote component.\n const isSSGBuild = process.env.NEXT_PHASE === 'phase-production-build';\n // If the remote component is part of a microfrontend, the src provided\n // will be relative.\n const isSSRRelativePathBase =\n serverUrl.host === new URL(ssrRelativePathBaseUrl).host;\n // Only want this skeleton behaviour in previews to unblock development.\n // For production, the remote component should already be built.\n const isPreview = process.env.VERCEL_TARGET_ENV === 'preview';\n\n if (isSSGBuild && isSSRRelativePathBase && isPreview && options.appRouter) {\n let skeletonComponent: React.ReactNode | undefined;\n if (options.rsc) {\n const { createElement } = await import('react');\n skeletonComponent = createElement('div', {\n dangerouslySetInnerHTML: {\n __html: getSkeletonHtml(serverUrl.href),\n },\n });\n }\n\n return buildSkeletonResponse(\n serverUrl,\n buildMetadata({}, serverUrl),\n skeletonComponent,\n );\n }\n\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n `No Remote Component found. Make sure the remote URL is correct and contains a Remote Component.`,\n );\n }\n\n const name = remoteName || metadata.name;\n const component = options.rsc\n ? await buildRscComponent(rsc, serverUrl)\n : undefined;\n\n return {\n name,\n serverUrl,\n metadata,\n rsc,\n scripts,\n links,\n hydrationData,\n nextData,\n component,\n html,\n remoteShared,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var lifecycle_exports = {};
|
|
20
|
+
__export(lifecycle_exports, {
|
|
21
|
+
makeEventEmitter: () => makeEventEmitter,
|
|
22
|
+
makeReactEmitter: () => makeReactEmitter
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(lifecycle_exports);
|
|
25
|
+
function makeReactEmitter(callbacks) {
|
|
26
|
+
return {
|
|
27
|
+
beforeLoad(src) {
|
|
28
|
+
callbacks.onBeforeLoad?.(src);
|
|
29
|
+
},
|
|
30
|
+
load(src) {
|
|
31
|
+
callbacks.onLoad?.(src);
|
|
32
|
+
},
|
|
33
|
+
error(error, _src) {
|
|
34
|
+
callbacks.onError?.(error);
|
|
35
|
+
},
|
|
36
|
+
change(info) {
|
|
37
|
+
callbacks.onChange?.(info);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function makeEventEmitter(element) {
|
|
42
|
+
function dispatch(type, detail) {
|
|
43
|
+
const event = new Event(type, { bubbles: true, composed: true });
|
|
44
|
+
if (detail) {
|
|
45
|
+
Object.assign(event, detail);
|
|
46
|
+
}
|
|
47
|
+
element.dispatchEvent(event);
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
beforeLoad(src) {
|
|
51
|
+
dispatch("beforeload", { src });
|
|
52
|
+
},
|
|
53
|
+
load(src) {
|
|
54
|
+
dispatch("load", { src });
|
|
55
|
+
},
|
|
56
|
+
error(error, src) {
|
|
57
|
+
dispatch("error", src != null ? { error, src } : { error });
|
|
58
|
+
},
|
|
59
|
+
change(info) {
|
|
60
|
+
dispatch("change", info);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
65
|
+
0 && (module.exports = {
|
|
66
|
+
makeEventEmitter,
|
|
67
|
+
makeReactEmitter
|
|
68
|
+
});
|
|
69
|
+
//# sourceMappingURL=lifecycle.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/shared/lifecycle.ts"],"sourcesContent":["import type { ChangeInfo, ConsumeLifecycleCallbacks } from './config';\n\n/**\n * Unified lifecycle event emitter used by the host loading pipeline.\n *\n * Hosts create an emitter that matches their eventing model — React hosts\n * wrap callback props via {@link makeReactEmitter}, while the HTML custom\n * element dispatches DOM events via {@link makeEventEmitter}. The pipeline\n * calls emitter methods at the appropriate phases without knowing which\n * host is driving the load.\n */\nexport interface LifecycleEmitter {\n beforeLoad(src: string | URL): void;\n load(src: string | URL): void;\n error(error: unknown, src?: string | URL): void;\n change(info: ChangeInfo): void;\n}\n\n/**\n * Wraps React-style callback props into a {@link LifecycleEmitter}.\n *\n * Missing callbacks are silently ignored — this is the normal case for\n * hosts that only subscribe to a subset of events.\n */\nexport function makeReactEmitter(\n callbacks: ConsumeLifecycleCallbacks,\n): LifecycleEmitter {\n return {\n beforeLoad(src) {\n callbacks.onBeforeLoad?.(src);\n },\n load(src) {\n callbacks.onLoad?.(src);\n },\n error(error, _src?) {\n callbacks.onError?.(error);\n },\n change(info) {\n callbacks.onChange?.(info);\n },\n };\n}\n\n/**\n * Wraps a DOM element into a {@link LifecycleEmitter} by dispatching\n * `CustomEvent`s with `bubbles: true` and `composed: true` (crosses\n * Shadow DOM boundaries).\n */\nexport function makeEventEmitter(element: HTMLElement): LifecycleEmitter {\n function dispatch(\n type: 'beforeload' | 'load' | 'error' | 'change',\n detail?: Record<string, unknown>,\n ) {\n const event = new Event(type, { bubbles: true, composed: true });\n if (detail) {\n Object.assign(event, detail);\n }\n element.dispatchEvent(event);\n }\n\n return {\n beforeLoad(src) {\n dispatch('beforeload', { src });\n },\n load(src) {\n dispatch('load', { src });\n },\n error(error, src?) {\n dispatch('error', src != null ? { error, src } : { error });\n },\n change(info) {\n dispatch('change', info as unknown as Record<string, unknown>);\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBO,SAAS,iBACd,WACkB;AAClB,SAAO;AAAA,IACL,WAAW,KAAK;AACd,gBAAU,eAAe,GAAG;AAAA,IAC9B;AAAA,IACA,KAAK,KAAK;AACR,gBAAU,SAAS,GAAG;AAAA,IACxB;AAAA,IACA,MAAM,OAAO,MAAO;AAClB,gBAAU,UAAU,KAAK;AAAA,IAC3B;AAAA,IACA,OAAO,MAAM;AACX,gBAAU,WAAW,IAAI;AAAA,IAC3B;AAAA,EACF;AACF;AAOO,SAAS,iBAAiB,SAAwC;AACvE,WAAS,SACP,MACA,QACA;AACA,UAAM,QAAQ,IAAI,MAAM,MAAM,EAAE,SAAS,MAAM,UAAU,KAAK,CAAC;AAC/D,QAAI,QAAQ;AACV,aAAO,OAAO,OAAO,MAAM;AAAA,IAC7B;AACA,YAAQ,cAAc,KAAK;AAAA,EAC7B;AAEA,SAAO;AAAA,IACL,WAAW,KAAK;AACd,eAAS,cAAc,EAAE,IAAI,CAAC;AAAA,IAChC;AAAA,IACA,KAAK,KAAK;AACR,eAAS,QAAQ,EAAE,IAAI,CAAC;AAAA,IAC1B;AAAA,IACA,MAAM,OAAO,KAAM;AACjB,eAAS,SAAS,OAAO,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,CAAC;AAAA,IAC5D;AAAA,IACA,OAAO,MAAM;AACX,eAAS,UAAU,IAA0C;AAAA,IAC/D;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ChangeInfo, ConsumeLifecycleCallbacks } from './config.js';
|
|
2
|
+
import '../../runtime/url/resolve-client-url.js';
|
|
3
|
+
import './fetch-interceptors.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Unified lifecycle event emitter used by the host loading pipeline.
|
|
7
|
+
*
|
|
8
|
+
* Hosts create an emitter that matches their eventing model — React hosts
|
|
9
|
+
* wrap callback props via {@link makeReactEmitter}, while the HTML custom
|
|
10
|
+
* element dispatches DOM events via {@link makeEventEmitter}. The pipeline
|
|
11
|
+
* calls emitter methods at the appropriate phases without knowing which
|
|
12
|
+
* host is driving the load.
|
|
13
|
+
*/
|
|
14
|
+
interface LifecycleEmitter {
|
|
15
|
+
beforeLoad(src: string | URL): void;
|
|
16
|
+
load(src: string | URL): void;
|
|
17
|
+
error(error: unknown, src?: string | URL): void;
|
|
18
|
+
change(info: ChangeInfo): void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Wraps React-style callback props into a {@link LifecycleEmitter}.
|
|
22
|
+
*
|
|
23
|
+
* Missing callbacks are silently ignored — this is the normal case for
|
|
24
|
+
* hosts that only subscribe to a subset of events.
|
|
25
|
+
*/
|
|
26
|
+
declare function makeReactEmitter(callbacks: ConsumeLifecycleCallbacks): LifecycleEmitter;
|
|
27
|
+
/**
|
|
28
|
+
* Wraps a DOM element into a {@link LifecycleEmitter} by dispatching
|
|
29
|
+
* `CustomEvent`s with `bubbles: true` and `composed: true` (crosses
|
|
30
|
+
* Shadow DOM boundaries).
|
|
31
|
+
*/
|
|
32
|
+
declare function makeEventEmitter(element: HTMLElement): LifecycleEmitter;
|
|
33
|
+
|
|
34
|
+
export { LifecycleEmitter, makeEventEmitter, makeReactEmitter };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
function makeReactEmitter(callbacks) {
|
|
2
|
+
return {
|
|
3
|
+
beforeLoad(src) {
|
|
4
|
+
callbacks.onBeforeLoad?.(src);
|
|
5
|
+
},
|
|
6
|
+
load(src) {
|
|
7
|
+
callbacks.onLoad?.(src);
|
|
8
|
+
},
|
|
9
|
+
error(error, _src) {
|
|
10
|
+
callbacks.onError?.(error);
|
|
11
|
+
},
|
|
12
|
+
change(info) {
|
|
13
|
+
callbacks.onChange?.(info);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function makeEventEmitter(element) {
|
|
18
|
+
function dispatch(type, detail) {
|
|
19
|
+
const event = new Event(type, { bubbles: true, composed: true });
|
|
20
|
+
if (detail) {
|
|
21
|
+
Object.assign(event, detail);
|
|
22
|
+
}
|
|
23
|
+
element.dispatchEvent(event);
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
beforeLoad(src) {
|
|
27
|
+
dispatch("beforeload", { src });
|
|
28
|
+
},
|
|
29
|
+
load(src) {
|
|
30
|
+
dispatch("load", { src });
|
|
31
|
+
},
|
|
32
|
+
error(error, src) {
|
|
33
|
+
dispatch("error", src != null ? { error, src } : { error });
|
|
34
|
+
},
|
|
35
|
+
change(info) {
|
|
36
|
+
dispatch("change", info);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
makeEventEmitter,
|
|
42
|
+
makeReactEmitter
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/shared/lifecycle.ts"],"sourcesContent":["import type { ChangeInfo, ConsumeLifecycleCallbacks } from './config';\n\n/**\n * Unified lifecycle event emitter used by the host loading pipeline.\n *\n * Hosts create an emitter that matches their eventing model — React hosts\n * wrap callback props via {@link makeReactEmitter}, while the HTML custom\n * element dispatches DOM events via {@link makeEventEmitter}. The pipeline\n * calls emitter methods at the appropriate phases without knowing which\n * host is driving the load.\n */\nexport interface LifecycleEmitter {\n beforeLoad(src: string | URL): void;\n load(src: string | URL): void;\n error(error: unknown, src?: string | URL): void;\n change(info: ChangeInfo): void;\n}\n\n/**\n * Wraps React-style callback props into a {@link LifecycleEmitter}.\n *\n * Missing callbacks are silently ignored — this is the normal case for\n * hosts that only subscribe to a subset of events.\n */\nexport function makeReactEmitter(\n callbacks: ConsumeLifecycleCallbacks,\n): LifecycleEmitter {\n return {\n beforeLoad(src) {\n callbacks.onBeforeLoad?.(src);\n },\n load(src) {\n callbacks.onLoad?.(src);\n },\n error(error, _src?) {\n callbacks.onError?.(error);\n },\n change(info) {\n callbacks.onChange?.(info);\n },\n };\n}\n\n/**\n * Wraps a DOM element into a {@link LifecycleEmitter} by dispatching\n * `CustomEvent`s with `bubbles: true` and `composed: true` (crosses\n * Shadow DOM boundaries).\n */\nexport function makeEventEmitter(element: HTMLElement): LifecycleEmitter {\n function dispatch(\n type: 'beforeload' | 'load' | 'error' | 'change',\n detail?: Record<string, unknown>,\n ) {\n const event = new Event(type, { bubbles: true, composed: true });\n if (detail) {\n Object.assign(event, detail);\n }\n element.dispatchEvent(event);\n }\n\n return {\n beforeLoad(src) {\n dispatch('beforeload', { src });\n },\n load(src) {\n dispatch('load', { src });\n },\n error(error, src?) {\n dispatch('error', src != null ? { error, src } : { error });\n },\n change(info) {\n dispatch('change', info as unknown as Record<string, unknown>);\n },\n };\n}\n"],"mappings":"AAwBO,SAAS,iBACd,WACkB;AAClB,SAAO;AAAA,IACL,WAAW,KAAK;AACd,gBAAU,eAAe,GAAG;AAAA,IAC9B;AAAA,IACA,KAAK,KAAK;AACR,gBAAU,SAAS,GAAG;AAAA,IACxB;AAAA,IACA,MAAM,OAAO,MAAO;AAClB,gBAAU,UAAU,KAAK;AAAA,IAC3B;AAAA,IACA,OAAO,MAAM;AACX,gBAAU,WAAW,IAAI;AAAA,IAC3B;AAAA,EACF;AACF;AAOO,SAAS,iBAAiB,SAAwC;AACvE,WAAS,SACP,MACA,QACA;AACA,UAAM,QAAQ,IAAI,MAAM,MAAM,EAAE,SAAS,MAAM,UAAU,KAAK,CAAC;AAC/D,QAAI,QAAQ;AACV,aAAO,OAAO,OAAO,MAAM;AAAA,IAC7B;AACA,YAAQ,cAAc,KAAK;AAAA,EAC7B;AAEA,SAAO;AAAA,IACL,WAAW,KAAK;AACd,eAAS,cAAc,EAAE,IAAI,CAAC;AAAA,IAChC;AAAA,IACA,KAAK,KAAK;AACR,eAAS,QAAQ,EAAE,IAAI,CAAC;AAAA,IAC1B;AAAA,IACA,MAAM,OAAO,KAAM;AACjB,eAAS,SAAS,OAAO,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,CAAC;AAAA,IAC5D;AAAA,IACA,OAAO,MAAM;AACX,eAAS,UAAU,IAA0C;AAAA,IAC/D;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var pipeline_exports = {};
|
|
20
|
+
__export(pipeline_exports, {
|
|
21
|
+
loadPrepared: () => loadPrepared,
|
|
22
|
+
preparePipeline: () => preparePipeline,
|
|
23
|
+
runPipeline: () => runPipeline,
|
|
24
|
+
runPipelineFromParsed: () => runPipelineFromParsed
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(pipeline_exports);
|
|
27
|
+
var import_shared_module_resolver = require("#internal/host/shared/shared-module-resolver");
|
|
28
|
+
var import_apply_origin = require("#internal/runtime/html/apply-origin");
|
|
29
|
+
var import_parse_remote_html = require("#internal/runtime/html/parse-remote-html");
|
|
30
|
+
var import_component_loader = require("#internal/runtime/loaders/component-loader");
|
|
31
|
+
var import_static_loader = require("#internal/runtime/loaders/static-loader");
|
|
32
|
+
var import_patterns = require("#internal/runtime/patterns");
|
|
33
|
+
var import_utils = require("#internal/utils");
|
|
34
|
+
var import_error = require("#internal/utils/error");
|
|
35
|
+
function preparePipeline(input) {
|
|
36
|
+
const parser = new DOMParser();
|
|
37
|
+
const doc = parser.parseFromString(input.html, "text/html");
|
|
38
|
+
const parsed = (0, import_parse_remote_html.parseRemoteComponentDocument)(doc, input.name, input.url);
|
|
39
|
+
const remoteShared = input.remoteShared ?? parsed.remoteShared;
|
|
40
|
+
if ("__remote_components_missing_shared__" in remoteShared) {
|
|
41
|
+
throw new import_error.RemoteComponentsError(
|
|
42
|
+
remoteShared.__remote_components_missing_shared__
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
(0, import_apply_origin.applyOriginToNodes)(doc, input.url, input.resolveClientUrl);
|
|
46
|
+
const scriptDescriptors = buildScriptDescriptors(parsed.scripts, input.url);
|
|
47
|
+
return { doc, parsed, scriptDescriptors };
|
|
48
|
+
}
|
|
49
|
+
async function loadPrepared(input) {
|
|
50
|
+
const { prepared, url, signal, resolveClientUrl, container, rscName } = input;
|
|
51
|
+
const { doc, parsed, scriptDescriptors } = prepared;
|
|
52
|
+
if (signal.aborted) {
|
|
53
|
+
return { status: "aborted" };
|
|
54
|
+
}
|
|
55
|
+
const userShared = await input.shared;
|
|
56
|
+
if (signal.aborted) {
|
|
57
|
+
return { status: "aborted" };
|
|
58
|
+
}
|
|
59
|
+
if (parsed.isRemoteComponent) {
|
|
60
|
+
return loadStaticPath({
|
|
61
|
+
parsed,
|
|
62
|
+
doc,
|
|
63
|
+
url,
|
|
64
|
+
resolveClientUrl
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return loadDynamicPath({
|
|
68
|
+
parsed,
|
|
69
|
+
doc,
|
|
70
|
+
url,
|
|
71
|
+
scriptDescriptors,
|
|
72
|
+
shared: userShared,
|
|
73
|
+
resolveClientUrl,
|
|
74
|
+
container,
|
|
75
|
+
rscName
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async function runPipeline(input) {
|
|
79
|
+
try {
|
|
80
|
+
const userShared = await input.shared;
|
|
81
|
+
if (input.signal.aborted) {
|
|
82
|
+
return { status: "aborted" };
|
|
83
|
+
}
|
|
84
|
+
const prepared = preparePipeline({
|
|
85
|
+
html: input.html,
|
|
86
|
+
name: input.name,
|
|
87
|
+
url: input.url,
|
|
88
|
+
shared: userShared,
|
|
89
|
+
resolveClientUrl: input.resolveClientUrl
|
|
90
|
+
});
|
|
91
|
+
return await loadPrepared({
|
|
92
|
+
prepared,
|
|
93
|
+
url: input.url,
|
|
94
|
+
signal: input.signal,
|
|
95
|
+
shared: userShared,
|
|
96
|
+
resolveClientUrl: input.resolveClientUrl,
|
|
97
|
+
container: input.container
|
|
98
|
+
});
|
|
99
|
+
} catch (error) {
|
|
100
|
+
return {
|
|
101
|
+
status: "error",
|
|
102
|
+
error: error instanceof Error ? error : new import_error.RemoteComponentsError(String(error))
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async function runPipelineFromParsed(input) {
|
|
107
|
+
try {
|
|
108
|
+
if (input.signal.aborted) {
|
|
109
|
+
return { status: "aborted" };
|
|
110
|
+
}
|
|
111
|
+
const remoteShared = input.remoteShared ?? input.payload.remoteShared ?? {};
|
|
112
|
+
if ("__remote_components_missing_shared__" in remoteShared) {
|
|
113
|
+
throw new import_error.RemoteComponentsError(
|
|
114
|
+
remoteShared.__remote_components_missing_shared__
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
const result = await (0, import_component_loader.loadRemoteComponent)({
|
|
118
|
+
url: input.url,
|
|
119
|
+
name: input.name,
|
|
120
|
+
rscName: input.rscName,
|
|
121
|
+
bundle: input.payload.bundle,
|
|
122
|
+
route: input.payload.route,
|
|
123
|
+
runtime: input.payload.runtime,
|
|
124
|
+
data: input.payload.data,
|
|
125
|
+
nextData: input.payload.nextData,
|
|
126
|
+
scripts: input.payload.scripts,
|
|
127
|
+
shared: input.shared,
|
|
128
|
+
remoteShared,
|
|
129
|
+
container: input.container,
|
|
130
|
+
resolveClientUrl: input.resolveClientUrl
|
|
131
|
+
});
|
|
132
|
+
if (input.signal.aborted) {
|
|
133
|
+
return { status: "aborted" };
|
|
134
|
+
}
|
|
135
|
+
if (result.error) {
|
|
136
|
+
return { status: "error", error: result.error };
|
|
137
|
+
}
|
|
138
|
+
return { status: "loaded", component: result.component };
|
|
139
|
+
} catch (error) {
|
|
140
|
+
return {
|
|
141
|
+
status: "error",
|
|
142
|
+
error: error instanceof Error ? error : new import_error.RemoteComponentsError(String(error))
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function buildScriptDescriptors(scripts, url) {
|
|
147
|
+
return scripts.map((script) => {
|
|
148
|
+
const scriptSrc = script.getAttribute("data-src") || script.getAttribute("src") || script.src;
|
|
149
|
+
const { prefix, id: path } = import_patterns.REMOTE_COMPONENT_REGEX.exec(scriptSrc)?.groups ?? {
|
|
150
|
+
prefix: void 0,
|
|
151
|
+
id: scriptSrc
|
|
152
|
+
};
|
|
153
|
+
return {
|
|
154
|
+
src: new URL((0, import_patterns.collapseDoubleSlashes)(`${prefix ?? ""}${path}`), url).href
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
async function loadStaticPath(input) {
|
|
159
|
+
const { parsed, doc, url, resolveClientUrl } = input;
|
|
160
|
+
const scripts = Array.from(
|
|
161
|
+
parsed.component.querySelectorAll("script")
|
|
162
|
+
);
|
|
163
|
+
const { mount, unmount } = await (0, import_static_loader.loadStaticRemoteComponent)(
|
|
164
|
+
scripts,
|
|
165
|
+
url,
|
|
166
|
+
resolveClientUrl
|
|
167
|
+
);
|
|
168
|
+
return {
|
|
169
|
+
status: "static",
|
|
170
|
+
mount,
|
|
171
|
+
unmount,
|
|
172
|
+
metadata: parsed.metadata,
|
|
173
|
+
parsed,
|
|
174
|
+
doc
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
async function loadDynamicPath(input) {
|
|
178
|
+
const {
|
|
179
|
+
parsed,
|
|
180
|
+
doc,
|
|
181
|
+
url,
|
|
182
|
+
scriptDescriptors,
|
|
183
|
+
shared,
|
|
184
|
+
resolveClientUrl,
|
|
185
|
+
container
|
|
186
|
+
} = input;
|
|
187
|
+
const rscName = input.rscName ?? (parsed.rsc ? `__remote_component_rsc_${(0, import_utils.escapeString)(url.href)}_${(0, import_utils.escapeString)(parsed.name)}` : void 0);
|
|
188
|
+
const rscData = parsed.rsc ? (parsed.rsc.textContent || "").split("\n").filter(Boolean) : [];
|
|
189
|
+
const result = await (0, import_component_loader.loadRemoteComponent)({
|
|
190
|
+
url,
|
|
191
|
+
name: parsed.name,
|
|
192
|
+
rscName,
|
|
193
|
+
bundle: parsed.metadata.bundle,
|
|
194
|
+
route: parsed.metadata.route,
|
|
195
|
+
runtime: parsed.metadata.runtime,
|
|
196
|
+
data: rscData,
|
|
197
|
+
nextData: parsed.nextData,
|
|
198
|
+
scripts: scriptDescriptors,
|
|
199
|
+
shared: (0, import_shared_module_resolver.buildHostShared)(shared, resolveClientUrl),
|
|
200
|
+
remoteShared: parsed.remoteShared,
|
|
201
|
+
container,
|
|
202
|
+
resolveClientUrl
|
|
203
|
+
});
|
|
204
|
+
if (result.error) {
|
|
205
|
+
return { status: "error", error: result.error };
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
status: "loaded",
|
|
209
|
+
component: result.component,
|
|
210
|
+
metadata: parsed.metadata,
|
|
211
|
+
parsed,
|
|
212
|
+
doc
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
216
|
+
0 && (module.exports = {
|
|
217
|
+
loadPrepared,
|
|
218
|
+
preparePipeline,
|
|
219
|
+
runPipeline,
|
|
220
|
+
runPipelineFromParsed
|
|
221
|
+
});
|
|
222
|
+
//# sourceMappingURL=pipeline.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/shared/pipeline.ts"],"sourcesContent":["import type { InternalResolveClientUrl } from '#internal/host/server/types';\nimport type { ScriptDescriptor } from '#internal/host/shared/asset-descriptors';\nimport type { ConsumeLoaderPayload } from '#internal/host/shared/server-handoff';\nimport { buildHostShared } from '#internal/host/shared/shared-module-resolver';\nimport { applyOriginToNodes } from '#internal/runtime/html/apply-origin';\nimport {\n type ParsedRemoteComponent,\n parseRemoteComponentDocument,\n} from '#internal/runtime/html/parse-remote-html';\nimport { loadRemoteComponent } from '#internal/runtime/loaders/component-loader';\nimport { loadStaticRemoteComponent } from '#internal/runtime/loaders/static-loader';\nimport type { RemoteComponentMetadata } from '#internal/runtime/metadata';\nimport {\n collapseDoubleSlashes,\n REMOTE_COMPONENT_REGEX,\n} from '#internal/runtime/patterns';\nimport type { MountOrUnmountFunction } from '#internal/runtime/types';\nimport { escapeString } from '#internal/utils';\nimport { RemoteComponentsError } from '#internal/utils/error';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype SharedModuleMap = Record<string, (bundle?: string) => Promise<unknown>>;\n\n/**\n * Input for {@link runPipeline} — the full post-fetch pipeline that starts\n * from raw HTML.\n */\nexport interface PipelineInput {\n /** Resolved URL of the remote component. */\n url: URL;\n /** Raw HTML string returned by the remote. */\n html: string;\n /** Component name hint (may be refined during parsing). */\n name: string;\n /** Abort signal — the pipeline checks this between async steps. */\n signal: AbortSignal;\n /** Host-provided shared module factories (resolved or promise). */\n shared: Promise<SharedModuleMap> | SharedModuleMap;\n /** URL rewriter for client-side asset URLs. */\n resolveClientUrl?: InternalResolveClientUrl;\n /** Shadow root or element to mount into (for script-based components). */\n container?: ShadowRoot | HTMLElement | null;\n}\n\n/**\n * Input for {@link runPipelineFromParsed} — the pipeline entry point for\n * hosts that receive pre-parsed SSR data (e.g. the App Router client).\n */\nexport interface ParsedPipelineInput {\n /** Resolved URL of the remote component. */\n url: URL;\n /** Component name. */\n name: string;\n /** Abort signal. */\n signal: AbortSignal;\n /** Pre-resolved loader payload from the server component. */\n payload: ConsumeLoaderPayload;\n /** Host-provided shared module factories (resolved or promise). */\n shared: Promise<SharedModuleMap> | SharedModuleMap;\n /** Remote-requested shared modules. */\n remoteShared?: Record<string, string>;\n /** URL rewriter for client-side asset URLs. */\n resolveClientUrl?: InternalResolveClientUrl;\n /** Shadow root or element to mount into. */\n container?: ShadowRoot | HTMLElement | null;\n /** Optional RSC name override (used by App Router for scoped RSC data). */\n rscName?: string;\n}\n\n/**\n * Successful dynamic component load — the component is a React element tree\n * ready to render.\n */\nexport interface PipelineLoaded {\n status: 'loaded';\n component: React.ReactNode;\n metadata: RemoteComponentMetadata;\n parsed: ParsedRemoteComponent;\n doc: Document;\n}\n\n/**\n * Successful static component load — mount/unmount functions are returned\n * for the host to call.\n */\nexport interface PipelineStatic {\n status: 'static';\n mount: Set<MountOrUnmountFunction>;\n unmount: Set<MountOrUnmountFunction>;\n metadata: RemoteComponentMetadata;\n parsed: ParsedRemoteComponent;\n doc: Document;\n}\n\n/** The load was aborted before it could complete. */\nexport interface PipelineAborted {\n status: 'aborted';\n}\n\n/** The load failed with an error. */\nexport interface PipelineError {\n status: 'error';\n error: Error;\n}\n\nexport type PipelineResult =\n | PipelineLoaded\n | PipelineStatic\n | PipelineAborted\n | PipelineError;\n\n/**\n * Intermediate result from {@link preparePipeline}. Hosts that need to run\n * framework-specific logic between parse and load (e.g. inline script\n * execution in the React host) use this to split the pipeline into two\n * phases.\n */\nexport interface PreparedPipeline {\n doc: Document;\n parsed: ParsedRemoteComponent;\n /** Script descriptors ready to pass to `loadRemoteComponent`. */\n scriptDescriptors: ScriptDescriptor[];\n}\n\n// ---------------------------------------------------------------------------\n// Pipeline phases\n// ---------------------------------------------------------------------------\n\n/**\n * Phase 1: Parse HTML, validate shared modules, and normalize URLs.\n *\n * This is the synchronous/cheap portion of the pipeline. Hosts that need to\n * inject logic between parse and load (e.g. executing inline scripts) call\n * this directly, then call {@link loadPrepared} when ready.\n */\nexport function preparePipeline(input: {\n html: string;\n name: string;\n url: URL;\n shared: SharedModuleMap;\n remoteShared?: Record<string, string>;\n resolveClientUrl?: InternalResolveClientUrl;\n}): PreparedPipeline {\n const parser = new DOMParser();\n const doc = parser.parseFromString(input.html, 'text/html');\n\n const parsed = parseRemoteComponentDocument(doc, input.name, input.url);\n\n // Validate shared modules — surface errors early before any script loading.\n // Only check *remote* shared modules here. The host-side marker\n // (`__remote_components_missing_shared__` in `input.shared`) is a callable\n // error signal that the host may intentionally leave in place when\n // `withRemoteComponentsConfig` is not used — blocking on it would break\n // framework-agnostic hosts that don't configure shared modules.\n const remoteShared = input.remoteShared ?? parsed.remoteShared;\n if ('__remote_components_missing_shared__' in remoteShared) {\n throw new RemoteComponentsError(\n remoteShared.__remote_components_missing_shared__,\n );\n }\n\n applyOriginToNodes(doc, input.url, input.resolveClientUrl);\n\n const scriptDescriptors = buildScriptDescriptors(parsed.scripts, input.url);\n\n return { doc, parsed, scriptDescriptors };\n}\n\n/**\n * Phase 2: Load the component from a prepared pipeline result.\n *\n * For dynamic components, delegates to `loadRemoteComponent`. For static\n * components (`isRemoteComponent`), delegates to `loadStaticRemoteComponent`.\n */\nexport async function loadPrepared(input: {\n prepared: PreparedPipeline;\n url: URL;\n signal: AbortSignal;\n shared: Promise<SharedModuleMap> | SharedModuleMap;\n resolveClientUrl?: InternalResolveClientUrl;\n container?: ShadowRoot | HTMLElement | null;\n rscName?: string;\n}): Promise<PipelineResult> {\n const { prepared, url, signal, resolveClientUrl, container, rscName } = input;\n const { doc, parsed, scriptDescriptors } = prepared;\n\n if (signal.aborted) {\n return { status: 'aborted' };\n }\n\n const userShared = await input.shared;\n if (signal.aborted) {\n return { status: 'aborted' };\n }\n\n if (parsed.isRemoteComponent) {\n return loadStaticPath({\n parsed,\n doc,\n url,\n resolveClientUrl,\n });\n }\n\n return loadDynamicPath({\n parsed,\n doc,\n url,\n scriptDescriptors,\n shared: userShared,\n resolveClientUrl,\n container,\n rscName,\n });\n}\n\n// ---------------------------------------------------------------------------\n// Full pipeline entry points\n// ---------------------------------------------------------------------------\n\n/**\n * Full post-fetch pipeline: parse → validate → normalize → load.\n *\n * Use this when starting from a raw HTML string (React host, HTML host).\n */\nexport async function runPipeline(\n input: PipelineInput,\n): Promise<PipelineResult> {\n try {\n const userShared = await input.shared;\n if (input.signal.aborted) {\n return { status: 'aborted' };\n }\n\n const prepared = preparePipeline({\n html: input.html,\n name: input.name,\n url: input.url,\n shared: userShared,\n resolveClientUrl: input.resolveClientUrl,\n });\n\n return await loadPrepared({\n prepared,\n url: input.url,\n signal: input.signal,\n shared: userShared,\n resolveClientUrl: input.resolveClientUrl,\n container: input.container,\n });\n } catch (error) {\n return {\n status: 'error',\n error:\n error instanceof Error\n ? error\n : new RemoteComponentsError(String(error)),\n };\n }\n}\n\n/**\n * Pipeline entry point for pre-parsed SSR data (App Router client).\n *\n * Skips HTML parsing and goes straight to `loadRemoteComponent` with the\n * pre-resolved payload from the server component.\n */\nexport async function runPipelineFromParsed(\n input: ParsedPipelineInput,\n): Promise<\n | { status: 'loaded'; component: React.ReactNode }\n | PipelineAborted\n | PipelineError\n> {\n try {\n if (input.signal.aborted) {\n return { status: 'aborted' };\n }\n\n const remoteShared = input.remoteShared ?? input.payload.remoteShared ?? {};\n\n if ('__remote_components_missing_shared__' in remoteShared) {\n throw new RemoteComponentsError(\n remoteShared.__remote_components_missing_shared__,\n );\n }\n\n const result = await loadRemoteComponent({\n url: input.url,\n name: input.name,\n rscName: input.rscName,\n bundle: input.payload.bundle,\n route: input.payload.route,\n runtime: input.payload.runtime,\n data: input.payload.data,\n nextData: input.payload.nextData,\n scripts: input.payload.scripts,\n shared: input.shared,\n remoteShared,\n container: input.container,\n resolveClientUrl: input.resolveClientUrl,\n });\n\n if (input.signal.aborted) {\n return { status: 'aborted' };\n }\n\n if (result.error) {\n return { status: 'error', error: result.error };\n }\n return { status: 'loaded', component: result.component };\n } catch (error) {\n return {\n status: 'error',\n error:\n error instanceof Error\n ? error\n : new RemoteComponentsError(String(error)),\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Converts parsed `<script>` elements into the `ScriptDescriptor[]` format\n * expected by `loadRemoteComponent`. Handles the `[bundle] id` URL format\n * and collapses double slashes.\n */\nfunction buildScriptDescriptors(\n scripts: HTMLScriptElement[],\n url: URL,\n): ScriptDescriptor[] {\n return scripts.map((script) => {\n const scriptSrc =\n script.getAttribute('data-src') ||\n script.getAttribute('src') ||\n script.src;\n const { prefix, id: path } = REMOTE_COMPONENT_REGEX.exec(scriptSrc)\n ?.groups ?? {\n prefix: undefined,\n id: scriptSrc,\n };\n return {\n src: new URL(collapseDoubleSlashes(`${prefix ?? ''}${path}`), url).href,\n };\n });\n}\n\nasync function loadStaticPath(input: {\n parsed: ParsedRemoteComponent;\n doc: Document;\n url: URL;\n resolveClientUrl?: InternalResolveClientUrl;\n}): Promise<PipelineStatic> {\n const { parsed, doc, url, resolveClientUrl } = input;\n const scripts = Array.from(\n parsed.component.querySelectorAll<HTMLScriptElement>('script'),\n );\n const { mount, unmount } = await loadStaticRemoteComponent(\n scripts,\n url,\n resolveClientUrl,\n );\n return {\n status: 'static',\n mount,\n unmount,\n metadata: parsed.metadata,\n parsed,\n doc,\n };\n}\n\nasync function loadDynamicPath(input: {\n parsed: ParsedRemoteComponent;\n doc: Document;\n url: URL;\n scriptDescriptors: ScriptDescriptor[];\n shared: SharedModuleMap;\n resolveClientUrl?: InternalResolveClientUrl;\n container?: ShadowRoot | HTMLElement | null;\n rscName?: string;\n}): Promise<PipelineLoaded | PipelineError> {\n const {\n parsed,\n doc,\n url,\n scriptDescriptors,\n shared,\n resolveClientUrl,\n container,\n } = input;\n\n const rscName =\n input.rscName ??\n (parsed.rsc\n ? `__remote_component_rsc_${escapeString(url.href)}_${escapeString(parsed.name)}`\n : undefined);\n\n const rscData = parsed.rsc\n ? (parsed.rsc.textContent || '').split('\\n').filter(Boolean)\n : [];\n\n const result = await loadRemoteComponent({\n url,\n name: parsed.name,\n rscName,\n bundle: parsed.metadata.bundle,\n route: parsed.metadata.route,\n runtime: parsed.metadata.runtime,\n data: rscData,\n nextData: parsed.nextData,\n scripts: scriptDescriptors,\n shared: buildHostShared(shared, resolveClientUrl),\n remoteShared: parsed.remoteShared,\n container,\n resolveClientUrl,\n });\n\n if (result.error) {\n return { status: 'error', error: result.error };\n }\n return {\n status: 'loaded',\n component: result.component,\n metadata: parsed.metadata,\n parsed,\n doc,\n };\n}\n"],"mappings":"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","names":[]}
|