remote-components 0.3.3 → 0.3.4
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 +524 -338
- package/dist/host/html.cjs.map +1 -1
- package/dist/host/html.js +524 -338
- package/dist/host/html.js.map +1 -1
- package/dist/host/nextjs/app/client-only.cjs +462 -259
- package/dist/host/nextjs/app/client-only.cjs.map +1 -1
- package/dist/host/nextjs/app/client-only.js +436 -233
- package/dist/host/nextjs/app/client-only.js.map +1 -1
- package/dist/host/react.cjs +403 -228
- package/dist/host/react.cjs.map +1 -1
- package/dist/host/react.js +403 -228
- 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 +4 -3
- package/dist/internal/host/nextjs/app-client.cjs.map +1 -1
- package/dist/internal/host/nextjs/app-client.js +4 -3
- 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/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/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 +1 -1
- 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
package/dist/remote/html.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/constants.ts","../../src/runtime/url/protected-rc-fallback.ts","../../src/utils/abort.ts","../../src/utils/error.ts","../../src/utils/logger.ts","../../src/runtime/loaders/static-loader.ts","../../src/remote/html/index.tsx"],"sourcesContent":["export const RC_PROTECTED_REMOTE_FETCH_PATHNAME = '/rc-fetch-protected-remote';\n\nexport const MISSING_SHARED_MODULES_MESSAGE =\n 'Remote Components shared modules not found. Did you forget to wrap your config with `withRemoteComponentsConfig` on both host and remote?';\n\nexport const CORS_DOCS_URL =\n 'https://vercel.com/docs/remote-components/concepts/cors-external-urls#accessing-cross-site-protected-remote-components';\n","import { RC_PROTECTED_REMOTE_FETCH_PATHNAME } from '#internal/utils/constants';\n\n/**\n * Generates a fallback URL that proxies the request through the host's protected remote fetch endpoint\n */\nexport function generateProtectedRcFallbackSrc(url: string): string {\n return `${RC_PROTECTED_REMOTE_FETCH_PATHNAME}?url=${encodeURIComponent(url)}`;\n}\n\nexport function isProxiedUrl(url: string): boolean {\n try {\n return (\n new URL(url, location.href).pathname ===\n RC_PROTECTED_REMOTE_FETCH_PATHNAME\n );\n } catch {\n return false;\n }\n}\n","/**\n * Type guard to check if an error is an AbortError.\n * Handles cross-environment differences (Node.js, browsers, JSDOM).\n */\nexport function isAbortError(error: unknown): error is DOMException {\n if (error instanceof DOMException && error.name === 'AbortError') {\n return true;\n }\n\n // Handle Node.js native AbortError which may not be instanceof global DOMException\n if (\n error !== null &&\n typeof error === 'object' &&\n 'name' in error &&\n error.name === 'AbortError' &&\n 'message' in error &&\n typeof (error as { message: unknown }).message === 'string'\n ) {\n // Additional check: verify it has DOMException-like structure\n const e = error as { code?: unknown; constructor?: { name?: string } };\n return typeof e.code === 'number' || e.constructor?.name === 'DOMException';\n }\n\n return false;\n}\n","import { isProxiedUrl } from '#internal/runtime/url/protected-rc-fallback';\nimport { isAbortError } from '#internal/utils/abort';\nimport {\n CORS_DOCS_URL,\n RC_PROTECTED_REMOTE_FETCH_PATHNAME,\n} from '#internal/utils/constants';\n\nexport class RemoteComponentsError extends Error {\n code = 'REMOTE_COMPONENTS_ERROR';\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'RemoteComponentsError';\n }\n}\n\nexport function multipleRemoteComponentsError(url: string | undefined) {\n return new RemoteComponentsError(\n `Multiple Remote Components found at \"${url}\". When a page exposes multiple Remote Components you must specify the \"name\" prop to select which one to load.`,\n );\n}\n\nexport function failedToFetchRemoteComponentError(\n url: string,\n { status, statusText }: { status: number; statusText: string },\n help: string = 'Is the URL correct and accessible?',\n) {\n return new RemoteComponentsError(\n `Failed to fetch Remote Component from \"${url}\". ${help}`,\n { cause: new Error(`${status} ${statusText}`) },\n );\n}\n\nexport async function errorFromFailedFetch(\n originalUrl: string,\n resolvedUrl: URL,\n res: Response | null | undefined,\n): Promise<RemoteComponentsError> {\n const isProxied = isProxiedUrl(resolvedUrl.href);\n\n if (isProxied && res) {\n const body = await res.text().catch(() => '');\n return failedProxyFetchError(\n originalUrl,\n resolvedUrl.href,\n res.status,\n body,\n );\n }\n\n const fallback = failedToFetchRemoteComponentError(\n originalUrl,\n res ?? { status: 0, statusText: 'No Response' },\n );\n\n if (!res) return fallback;\n\n try {\n const body = await res.text();\n const parser = new DOMParser();\n const doc = parser.parseFromString(body, 'text/html');\n const errorTemplate = doc.querySelector(\n 'template[data-next-error-message]',\n );\n const errorMessage = errorTemplate?.getAttribute('data-next-error-message');\n if (errorMessage) {\n const error = new RemoteComponentsError(errorMessage);\n const errorStack = errorTemplate?.getAttribute('data-next-error-stack');\n if (errorStack) {\n error.stack = errorStack;\n }\n return error;\n }\n } catch (parseError) {\n // Re-throw abort errors, ignore parse errors\n if (isAbortError(parseError)) throw parseError;\n }\n\n return fallback;\n}\n\nexport function failedProxiedAssetError(\n kind: 'chunk' | 'script',\n url: string,\n resolvedUrl: string,\n): RemoteComponentsError {\n return new RemoteComponentsError(\n `Failed to load ${kind} \"${url}\" via proxy \"${resolvedUrl}\". ` +\n `Ensure withRemoteComponentsHostProxy middleware is configured, \"${RC_PROTECTED_REMOTE_FETCH_PATHNAME}\" is in the matcher, ` +\n `and the remote URL is included in allowedProxyUrls. ` +\n `See: ${CORS_DOCS_URL}`,\n );\n}\n\nexport function failedProxyFetchError(\n originalUrl: string,\n proxyUrl: string,\n status: number,\n responseBody?: string,\n): RemoteComponentsError {\n if (status === 404) {\n return new RemoteComponentsError(\n `Could not proxy the request to \"${originalUrl}\" — the proxy endpoint \"${RC_PROTECTED_REMOTE_FETCH_PATHNAME}\" returned 404.\\n\\n` +\n `The host server needs middleware or a route that handles \"${RC_PROTECTED_REMOTE_FETCH_PATHNAME}\".\\n\\n` +\n `Proxying requires two pieces:\\n` +\n ` 1. resolveClientUrl={routeThroughHostProxy} on <RemoteComponent>\\n` +\n ` 2. Middleware or a route for \"${RC_PROTECTED_REMOTE_FETCH_PATHNAME}\" on the host server\\n\\n` +\n `Docs: ${CORS_DOCS_URL}`,\n );\n }\n if (status === 403) {\n const detail = responseBody ? ` ${responseBody}` : '';\n return new RemoteComponentsError(\n `Proxied request to \"${proxyUrl}\" was forbidden.${detail} ` +\n `See: ${CORS_DOCS_URL}`,\n );\n }\n return new RemoteComponentsError(\n `Proxied request for \"${originalUrl}\" via \"${proxyUrl}\" failed with status ${status}. ` +\n `See: ${CORS_DOCS_URL}`,\n );\n}\n","import { CORS_DOCS_URL } from '#internal/utils/constants';\nimport { RemoteComponentsError } from '#internal/utils/error';\n\ntype LogLocation =\n | 'ChunkLoader'\n | 'ChunkDispatcher'\n | 'ComponentLoader'\n | 'ModuleDispatcher'\n | 'RemoteScope'\n | 'SharedModules'\n | 'WebpackRuntime'\n | 'TurbopackModule'\n | 'StaticLoader'\n | 'ScriptLoader'\n | 'Polyfill'\n | 'HtmlRemote'\n | 'HtmlHost'\n | 'Config'\n | 'NextAppRouter'\n | 'NextAppRouterCompat'\n | 'FetchRemoteComponent';\n\nconst PREFIX = 'remote-components';\nconst DEBUG =\n typeof window !== 'undefined' && localStorage.getItem('RC_DEBUG') === 'true';\n\nexport function logDebug(location: LogLocation, message: string) {\n if (DEBUG) {\n // eslint-disable-next-line no-console\n console.debug(`[${PREFIX}:${location}]: ${message}`);\n }\n}\n\nexport function logInfo(location: LogLocation, message: string) {\n // eslint-disable-next-line no-console\n console.info(`[${PREFIX}:${location}]: ${message}`);\n}\n\nexport function logWarn(location: LogLocation, message: string) {\n // eslint-disable-next-line no-console\n console.warn(`[${PREFIX}:${location}]: ${message}`);\n}\n\nexport function logError(\n location: LogLocation,\n message: string,\n cause?: unknown,\n) {\n // eslint-disable-next-line no-console\n console.error(\n new RemoteComponentsError(`[${PREFIX}:${location}]: ${message}`, {\n cause,\n }),\n );\n}\n\n/**\n * Logs a warning when a cross-origin asset request fails, guiding users\n * to configure the proxy middleware and resolveClientUrl on their host.\n */\nexport function warnCrossOriginFetchError(\n logLocation: LogLocation,\n url: string | URL,\n): void {\n try {\n const parsed = typeof url === 'string' ? new URL(url) : url;\n if (typeof location === 'undefined' || parsed.origin === location.origin) {\n return;\n }\n logWarn(\n logLocation,\n `Failed to fetch cross-origin resource \"${parsed.href}\". ` +\n 'To load assets from a protected deployment, two steps are required: ' +\n '(1) configure withRemoteComponentsHostProxy middleware in your host with the remote URL in allowedProxyUrls, ' +\n 'and (2) provide a resolveClientUrl prop that rewrites cross-origin asset URLs to go through the proxy. ' +\n `See: ${CORS_DOCS_URL}`,\n );\n } catch {\n // URL parsing failed — skip the warning\n }\n}\n","import type { InternalResolveClientUrl } from '#internal/host/server/types';\nimport type {\n MountOrUnmountFunction,\n MountUnmountFunctions,\n} from '#internal/runtime/types';\nimport { logError, warnCrossOriginFetchError } from '#internal/utils/logger';\n\ntype ScriptMod = {\n mount?: MountOrUnmountFunction;\n unmount?: MountOrUnmountFunction;\n default?: {\n mount?: MountOrUnmountFunction;\n unmount?: MountOrUnmountFunction;\n };\n};\n\n/**\n * Fetches an ES module via the resolveClientUrl callback, rewrites its\n * relative imports to also go through the callback, then loads it by injecting a\n * wrapper <script type=\"module\"> tag. The module's namespace is captured via\n * a temporary global and returned.\n *\n * This is needed when a direct import() of a cross-origin module fails due to\n * CORS restrictions or Vercel preview-deployment auth. A simple URL rewrite\n * doesn't work for import() because relative imports inside the module would\n * resolve against the rewritten URL instead of the original remote origin.\n */\nasync function importViaCallback<T>(\n absoluteSrc: string,\n resolveClientUrl: InternalResolveClientUrl,\n): Promise<T> {\n const resolvedUrl = resolveClientUrl(absoluteSrc) ?? absoluteSrc;\n const fetchUrl = new URL(resolvedUrl, location.href).href;\n const response = await fetch(fetchUrl);\n if (!response.ok) throw new Error(`Proxied fetch failed: ${response.status}`);\n\n // Restore import.meta.url to the original module URL so any code that\n // relies on it (e.g. for asset resolution) gets the right value.\n // Rewrite relative imports to absolute URLs resolved through the callback so\n // that transitive dependencies also bypass CORS/auth.\n const content = (await response.text())\n .replace(/import\\.meta\\.url/g, JSON.stringify(absoluteSrc))\n .replace(\n /\\b(from|import)\\s*([\"'])(\\.\\.?\\/[^\"']+)\\2/g,\n (_, keyword, quote, relativePath) => {\n const absoluteImportUrl = new URL(relativePath, absoluteSrc).href;\n const resolvedImportUrl = new URL(\n resolveClientUrl(absoluteImportUrl) ?? absoluteImportUrl,\n location.href,\n ).href;\n return `${keyword} ${quote}${resolvedImportUrl}${quote}`;\n },\n );\n const moduleBlobUrl = URL.createObjectURL(\n new Blob([content], { type: 'text/javascript' }),\n );\n const wrapperContent = [\n `import*as m from${JSON.stringify(moduleBlobUrl)};`,\n `globalThis.__rc_module_registry__=globalThis.__rc_module_registry__||{};`,\n `globalThis.__rc_module_registry__[${JSON.stringify(absoluteSrc)}]=m;`,\n ].join('');\n const wrapperBlobUrl = URL.createObjectURL(\n new Blob([wrapperContent], { type: 'text/javascript' }),\n );\n const scriptEl = document.createElement('script');\n scriptEl.type = 'module';\n scriptEl.src = wrapperBlobUrl;\n try {\n await new Promise<void>((resolve, reject) => {\n scriptEl.onload = () => resolve();\n scriptEl.onerror = () =>\n reject(new Error(`Failed to load module for ${absoluteSrc}`));\n document.head.appendChild(scriptEl);\n });\n } finally {\n scriptEl.remove();\n URL.revokeObjectURL(moduleBlobUrl);\n URL.revokeObjectURL(wrapperBlobUrl);\n }\n const registry = (\n globalThis as unknown as { __rc_module_registry__?: Record<string, T> }\n ).__rc_module_registry__;\n const mod = registry?.[absoluteSrc] ?? ({} as T);\n if (registry) delete registry[absoluteSrc];\n return mod;\n}\n\nasync function importDirectly<T>(absoluteSrc: string): Promise<T> {\n try {\n return (await import(\n /* @vite-ignore */\n /* webpackIgnore: true */ absoluteSrc\n )) as T;\n } catch (importError) {\n if (!absoluteSrc.startsWith('blob:')) {\n warnCrossOriginFetchError('StaticLoader', absoluteSrc);\n }\n throw importError;\n }\n}\n\nfunction resolveScriptSrc(script: HTMLScriptElement, url: URL): string {\n const rawSrc =\n typeof script.getAttribute === 'function'\n ? (script.getAttribute('src') ?? script.src)\n : script.src;\n if (!rawSrc && script.textContent) {\n return URL.createObjectURL(\n new Blob(\n [script.textContent.replace(/import\\.meta\\.url/g, JSON.stringify(url))],\n { type: 'text/javascript' },\n ),\n );\n }\n return rawSrc;\n}\n\nexport async function loadStaticRemoteComponent(\n scripts: HTMLScriptElement[],\n url: URL,\n resolveClientUrl?: InternalResolveClientUrl,\n) {\n const self = globalThis as typeof globalThis & MountUnmountFunctions;\n if (self.__remote_script_entrypoint_mount__?.[url.href]) {\n self.__remote_script_entrypoint_mount__[url.href] = new Set();\n }\n if (self.__remote_script_entrypoint_unmount__?.[url.href]) {\n self.__remote_script_entrypoint_unmount__[url.href] = new Set();\n }\n const mountUnmountSets = await Promise.all(\n scripts.map(async (script) => {\n try {\n const src = resolveScriptSrc(script, url);\n const absoluteSrc = new URL(src, url).href;\n const mod: ScriptMod = resolveClientUrl\n ? await importViaCallback<ScriptMod>(absoluteSrc, resolveClientUrl)\n : await importDirectly<ScriptMod>(absoluteSrc);\n // revoke the object URL if we created one for inline script content\n if (src.startsWith('blob:')) {\n URL.revokeObjectURL(src);\n }\n if (\n typeof mod.mount === 'function' ||\n typeof mod.default?.mount === 'function'\n ) {\n if (!self.__remote_script_entrypoint_mount__) {\n // eslint-disable-next-line camelcase\n self.__remote_script_entrypoint_mount__ = {};\n }\n if (!self.__remote_script_entrypoint_mount__[url.href]) {\n self.__remote_script_entrypoint_mount__[url.href] = new Set();\n }\n self.__remote_script_entrypoint_mount__[url.href]?.add(\n mod.mount ||\n mod.default?.mount ||\n (() => {\n // noop\n }),\n );\n }\n if (\n typeof mod.unmount === 'function' ||\n typeof mod.default?.unmount === 'function'\n ) {\n if (!self.__remote_script_entrypoint_unmount__) {\n // eslint-disable-next-line camelcase\n self.__remote_script_entrypoint_unmount__ = {};\n }\n if (!self.__remote_script_entrypoint_unmount__[url.href]) {\n self.__remote_script_entrypoint_unmount__[url.href] = new Set();\n }\n self.__remote_script_entrypoint_unmount__[url.href]?.add(\n mod.unmount ||\n mod.default?.unmount ||\n (() => {\n // noop\n }),\n );\n }\n return {\n mount: mod.mount || mod.default?.mount,\n unmount: mod.unmount || mod.default?.unmount,\n };\n } catch (e) {\n logError(\n 'StaticLoader',\n `Error loading remote component script from \"${script.src || url.href}\".`,\n e,\n );\n return {\n mount: undefined,\n unmount: undefined,\n };\n }\n }),\n );\n return mountUnmountSets.reduce(\n (acc, { mount, unmount }) => {\n if (typeof mount === 'function') {\n acc.mount.add(mount);\n }\n if (typeof unmount === 'function') {\n acc.unmount.add(unmount);\n }\n return acc;\n },\n {\n mount: new Set<MountOrUnmountFunction>(),\n unmount: new Set<MountOrUnmountFunction>(),\n },\n );\n}\n","import type { MountOrUnmountFunction } from '#internal/runtime/types';\nimport { logError } from '#internal/utils/logger';\n\nif (typeof HTMLElement !== 'undefined') {\n class RemoteComponent extends HTMLElement {\n name?: string;\n root?: ShadowRoot | null = null;\n unmount?: Set<MountOrUnmountFunction> | null = null;\n\n constructor() {\n super();\n\n const html = this.innerHTML;\n this.root = this.attachShadow({\n mode: this.getAttribute('mode') === 'closed' ? 'closed' : 'open',\n });\n this.root.innerHTML = html;\n // Clear light DOM — content was copied into the shadow root above.\n // Without this the original children render twice (once in light DOM,\n // once in shadow DOM).\n this.replaceChildren();\n\n // run the mount functions for any scripts inside the shadow root asynchronously\n (async () => {\n const { loadStaticRemoteComponent } = await import(\n '../../runtime/loaders/static-loader'\n );\n loadStaticRemoteComponent(\n Array.from(this.root?.querySelectorAll('script') ?? []),\n new URL(location.href),\n )\n .then(({ mount, unmount }) => {\n this.unmount = unmount;\n return Promise.all(\n Array.from(mount).map((mountFn) => mountFn(this.root)),\n );\n })\n .catch((e) => {\n logError('HtmlRemote', 'Error mounting remote component.', e);\n });\n })().catch((e) => {\n logError('HtmlRemote', 'Error mounting remote component.', e);\n });\n }\n\n disconnectedCallback() {\n // run the unmount functions for any scripts inside the shadow root asynchronously\n (async () => {\n if (this.unmount) {\n await Promise.all(\n Array.from(this.unmount).map(async (unmount) => {\n try {\n await unmount(this.root);\n } catch (e) {\n logError('HtmlRemote', 'Error unmounting remote component.', e);\n }\n }),\n );\n }\n })().catch((e) => {\n logError('HtmlRemote', 'Error unmounting remote component.', e);\n });\n }\n }\n\n // register the custom element\n customElements.define('remote-component', RemoteComponent);\n}\n"],"mappings":"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","names":["location","loadStaticRemoteComponent"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/constants.ts","../../src/runtime/url/protected-rc-fallback.ts","../../src/utils/abort.ts","../../src/utils/error.ts","../../src/utils/logger.ts","../../src/runtime/namespace.ts","../../src/runtime/loaders/static-loader.ts","../../src/remote/html/index.tsx"],"sourcesContent":["export const RC_PROTECTED_REMOTE_FETCH_PATHNAME = '/rc-fetch-protected-remote';\n\nexport const MISSING_SHARED_MODULES_MESSAGE =\n 'Remote Components shared modules not found. Did you forget to wrap your config with `withRemoteComponentsConfig` on both host and remote?';\n\nexport const CORS_DOCS_URL =\n 'https://vercel.com/docs/remote-components/concepts/cors-external-urls#accessing-cross-site-protected-remote-components';\n","import { RC_PROTECTED_REMOTE_FETCH_PATHNAME } from '#internal/utils/constants';\n\n/**\n * Generates a fallback URL that proxies the request through the host's protected remote fetch endpoint\n */\nexport function generateProtectedRcFallbackSrc(url: string): string {\n return `${RC_PROTECTED_REMOTE_FETCH_PATHNAME}?url=${encodeURIComponent(url)}`;\n}\n\nexport function isProxiedUrl(url: string): boolean {\n try {\n return (\n new URL(url, location.href).pathname ===\n RC_PROTECTED_REMOTE_FETCH_PATHNAME\n );\n } catch {\n return false;\n }\n}\n","/**\n * Type guard to check if an error is an AbortError.\n * Handles cross-environment differences (Node.js, browsers, JSDOM).\n */\nexport function isAbortError(error: unknown): error is DOMException {\n if (error instanceof DOMException && error.name === 'AbortError') {\n return true;\n }\n\n // Handle Node.js native AbortError which may not be instanceof global DOMException\n if (\n error !== null &&\n typeof error === 'object' &&\n 'name' in error &&\n error.name === 'AbortError' &&\n 'message' in error &&\n typeof (error as { message: unknown }).message === 'string'\n ) {\n // Additional check: verify it has DOMException-like structure\n const e = error as { code?: unknown; constructor?: { name?: string } };\n return typeof e.code === 'number' || e.constructor?.name === 'DOMException';\n }\n\n return false;\n}\n","import { isProxiedUrl } from '#internal/runtime/url/protected-rc-fallback';\nimport { isAbortError } from '#internal/utils/abort';\nimport {\n CORS_DOCS_URL,\n RC_PROTECTED_REMOTE_FETCH_PATHNAME,\n} from '#internal/utils/constants';\n\nexport class RemoteComponentsError extends Error {\n code = 'REMOTE_COMPONENTS_ERROR';\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'RemoteComponentsError';\n }\n}\n\nexport function multipleRemoteComponentsError(url: string | undefined) {\n return new RemoteComponentsError(\n `Multiple Remote Components found at \"${url}\". When a page exposes multiple Remote Components you must specify the \"name\" prop to select which one to load.`,\n );\n}\n\nexport function failedToFetchRemoteComponentError(\n url: string,\n { status, statusText }: { status: number; statusText: string },\n help: string = 'Is the URL correct and accessible?',\n) {\n return new RemoteComponentsError(\n `Failed to fetch Remote Component from \"${url}\". ${help}`,\n { cause: new Error(`${status} ${statusText}`) },\n );\n}\n\nexport async function errorFromFailedFetch(\n originalUrl: string,\n resolvedUrl: URL,\n res: Response | null | undefined,\n): Promise<RemoteComponentsError> {\n const isProxied = isProxiedUrl(resolvedUrl.href);\n\n if (isProxied && res) {\n const body = await res.text().catch(() => '');\n return failedProxyFetchError(\n originalUrl,\n resolvedUrl.href,\n res.status,\n body,\n );\n }\n\n const fallback = failedToFetchRemoteComponentError(\n originalUrl,\n res ?? { status: 0, statusText: 'No Response' },\n );\n\n if (!res) return fallback;\n\n try {\n const body = await res.text();\n const parser = new DOMParser();\n const doc = parser.parseFromString(body, 'text/html');\n const errorTemplate = doc.querySelector(\n 'template[data-next-error-message]',\n );\n const errorMessage = errorTemplate?.getAttribute('data-next-error-message');\n if (errorMessage) {\n const error = new RemoteComponentsError(errorMessage);\n const errorStack = errorTemplate?.getAttribute('data-next-error-stack');\n if (errorStack) {\n error.stack = errorStack;\n }\n return error;\n }\n } catch (parseError) {\n // Re-throw abort errors, ignore parse errors\n if (isAbortError(parseError)) throw parseError;\n }\n\n return fallback;\n}\n\nexport function failedProxiedAssetError(\n kind: 'chunk' | 'script',\n url: string,\n resolvedUrl: string,\n): RemoteComponentsError {\n return new RemoteComponentsError(\n `Failed to load ${kind} \"${url}\" via proxy \"${resolvedUrl}\". ` +\n `Ensure withRemoteComponentsHostProxy middleware is configured, \"${RC_PROTECTED_REMOTE_FETCH_PATHNAME}\" is in the matcher, ` +\n `and the remote URL is included in allowedProxyUrls. ` +\n `See: ${CORS_DOCS_URL}`,\n );\n}\n\nexport function failedProxyFetchError(\n originalUrl: string,\n proxyUrl: string,\n status: number,\n responseBody?: string,\n): RemoteComponentsError {\n if (status === 404) {\n return new RemoteComponentsError(\n `Could not proxy the request to \"${originalUrl}\" — the proxy endpoint \"${RC_PROTECTED_REMOTE_FETCH_PATHNAME}\" returned 404.\\n\\n` +\n `The host server needs middleware or a route that handles \"${RC_PROTECTED_REMOTE_FETCH_PATHNAME}\".\\n\\n` +\n `Proxying requires two pieces:\\n` +\n ` 1. resolveClientUrl={routeThroughHostProxy} on <RemoteComponent>\\n` +\n ` 2. Middleware or a route for \"${RC_PROTECTED_REMOTE_FETCH_PATHNAME}\" on the host server\\n\\n` +\n `Docs: ${CORS_DOCS_URL}`,\n );\n }\n if (status === 403) {\n const detail = responseBody ? ` ${responseBody}` : '';\n return new RemoteComponentsError(\n `Proxied request to \"${proxyUrl}\" was forbidden.${detail} ` +\n `See: ${CORS_DOCS_URL}`,\n );\n }\n return new RemoteComponentsError(\n `Proxied request for \"${originalUrl}\" via \"${proxyUrl}\" failed with status ${status}. ` +\n `See: ${CORS_DOCS_URL}`,\n );\n}\n","import { CORS_DOCS_URL } from '#internal/utils/constants';\nimport { RemoteComponentsError } from '#internal/utils/error';\n\nexport type LogLocation =\n | 'ChunkLoader'\n | 'ChunkDispatcher'\n | 'ComponentLoader'\n | 'ModuleDispatcher'\n | 'RemoteScope'\n | 'SharedModules'\n | 'WebpackRuntime'\n | 'TurbopackModule'\n | 'StaticLoader'\n | 'ScriptLoader'\n | 'Polyfill'\n | 'HtmlRemote'\n | 'HtmlHost'\n | 'Config'\n | 'NextAppRouter'\n | 'NextAppRouterCompat'\n | 'FetchRemoteComponent'\n | 'SharedModuleResolver';\n\nconst PREFIX = 'remote-components';\nconst DEBUG =\n (typeof window !== 'undefined' &&\n localStorage.getItem('RC_DEBUG') === 'true') ||\n (typeof process !== 'undefined' && process.env.RC_DEBUG === 'true');\n\nexport function logDebug(location: LogLocation, message: string) {\n if (DEBUG) {\n // eslint-disable-next-line no-console\n console.debug(`[${PREFIX}:${location}]: ${message}`);\n }\n}\n\nexport function logInfo(location: LogLocation, message: string) {\n // eslint-disable-next-line no-console\n console.info(`[${PREFIX}:${location}]: ${message}`);\n}\n\nexport function logWarn(location: LogLocation, message: string) {\n // eslint-disable-next-line no-console\n console.warn(`[${PREFIX}:${location}]: ${message}`);\n}\n\nexport function logError(\n location: LogLocation,\n message: string,\n cause?: unknown,\n) {\n // eslint-disable-next-line no-console\n console.error(\n new RemoteComponentsError(`[${PREFIX}:${location}]: ${message}`, {\n cause,\n }),\n );\n}\n\n/**\n * Logs a warning when a cross-origin asset request fails, guiding users\n * to configure the proxy middleware and resolveClientUrl on their host.\n */\nexport function warnCrossOriginFetchError(\n logLocation: LogLocation,\n url: string | URL,\n): void {\n try {\n const parsed = typeof url === 'string' ? new URL(url) : url;\n if (typeof location === 'undefined' || parsed.origin === location.origin) {\n return;\n }\n logWarn(\n logLocation,\n `Failed to fetch cross-origin resource \"${parsed.href}\". ` +\n 'To load assets from a protected deployment, two steps are required: ' +\n '(1) configure withRemoteComponentsHostProxy middleware in your host with the remote URL in allowedProxyUrls, ' +\n 'and (2) provide a resolveClientUrl prop that rewrites cross-origin asset URLs to go through the proxy. ' +\n `See: ${CORS_DOCS_URL}`,\n );\n } catch {\n // URL parsing failed — skip the warning\n }\n}\n","import type { RemoteScope } from '#internal/runtime/turbopack/remote-scope';\nimport type {\n GlobalScope,\n MountOrUnmountFunction,\n MountUnmountFunctions,\n} from '#internal/runtime/types';\n\n/**\n * Typed namespace for all remote-components runtime state.\n *\n * Consolidates scattered `globalThis` globals into a single object at\n * `globalThis.__remote_components__`. Each property corresponds to a\n * previously independent global — see inline `@see` tags for the original\n * global name. Code that previously read from those globals still works\n * because each migration writes through to both the namespace and the\n * legacy global (pointing at the same underlying object).\n */\nexport interface RemoteComponentsNamespace {\n /** @see `__remote_component_scopes__` */\n scopes: Map<string, RemoteScope>;\n /** @see `__remote_components_turbopack_chunk_loader_promise__` */\n chunkCache: Record<string, Promise<unknown>>;\n /** @see `__remote_script_entrypoint_mount__` */\n mountFns: Record<string, Set<MountOrUnmountFunction>>;\n /** @see `__remote_script_entrypoint_unmount__` */\n unmountFns: Record<string, Set<MountOrUnmountFunction>>;\n /** @see `__remote_bundle_url__` */\n bundleUrls: Record<string, string | URL>;\n /** @see `__rc_module_registry__` */\n moduleRegistry: Record<string, unknown>;\n /** @see `__webpack_require_type__` */\n dispatcherRuntime: string | undefined;\n /** @see `__remote_component_host_shared_modules__` */\n hostSharedModules: Record<string, () => Promise<unknown>>;\n /** @see `__remote_next_css__` */\n cssCache: Record<string, ChildNode[]>;\n /** @see `__remote_components_shadowroot_*` */\n shadowRoots: Record<string, ShadowRoot | null>;\n}\n\n/** Prefix for legacy per-key shadow root globals (`__remote_components_shadowroot_*`). */\nconst SHADOW_ROOT_PREFIX = '__remote_components_shadowroot_';\n\n/**\n * Backward-compat aliases for globals used in <=0.3.3.\n *\n * Only includes object/Map values that can be aliased by reference.\n * Primitives (`dispatcherRuntime`) must use write-through at their call sites.\n * Dynamic-key shadow root globals are adopted separately in `getNamespace()`.\n */\nconst LEGACY_ALIASES: ReadonlyArray<{\n global: string;\n prop: keyof RemoteComponentsNamespace;\n}> = [\n { global: '__remote_component_scopes__', prop: 'scopes' },\n {\n global: '__remote_components_turbopack_chunk_loader_promise__',\n prop: 'chunkCache',\n },\n { global: '__remote_script_entrypoint_mount__', prop: 'mountFns' },\n { global: '__remote_script_entrypoint_unmount__', prop: 'unmountFns' },\n { global: '__remote_bundle_url__', prop: 'bundleUrls' },\n { global: '__rc_module_registry__', prop: 'moduleRegistry' },\n {\n global: '__remote_component_host_shared_modules__',\n prop: 'hostSharedModules',\n },\n { global: '__remote_next_css__', prop: 'cssCache' },\n];\n\n/**\n * Returns the single shared `RemoteComponentsNamespace` instance, creating\n * it on first access. The namespace lives at `globalThis.__remote_components__`\n * so every module in the page shares the same state regardless of how many\n * copies of the library are loaded.\n *\n * On first initialization this function also handles backward compatibility\n * with legacy globals:\n * 1. **Adopt**: if a legacy global already exists (written by older code before\n * the namespace was created), its value becomes the initial namespace value.\n * 2. **Alias**: legacy globals are assigned to point at the namespace's objects,\n * so older code that reads the legacy global sees the same reference.\n */\nexport function getNamespace(): RemoteComponentsNamespace {\n const g = globalThis as GlobalScope & MountUnmountFunctions;\n const existing = g.__remote_components__;\n if (existing) {\n return existing;\n }\n\n const ns: RemoteComponentsNamespace = {\n scopes: new Map(),\n chunkCache: {},\n mountFns: {},\n unmountFns: {},\n bundleUrls: {},\n moduleRegistry: {},\n dispatcherRuntime: undefined,\n hostSharedModules: {},\n cssCache: {},\n shadowRoots: {},\n };\n\n // Adopt any pre-existing legacy globals, then alias them to the namespace.\n const nsRecord = ns as unknown as Record<string, unknown>;\n for (const { global, prop } of LEGACY_ALIASES) {\n const legacyValue = (g as Record<string, unknown>)[global];\n if (legacyValue != null) {\n nsRecord[prop] = legacyValue;\n }\n (g as Record<string, unknown>)[global] = ns[prop];\n }\n\n // Adopt per-key shadow root globals used in <=0.3.3\n // (e.g. `globalThis.__remote_components_shadowroot_<key> = root`).\n const gRecord = g as Record<string, unknown>;\n for (const key of Object.keys(gRecord)) {\n if (key.startsWith(SHADOW_ROOT_PREFIX)) {\n const suffix = key.slice(SHADOW_ROOT_PREFIX.length);\n ns.shadowRoots[suffix] = gRecord[key] as ShadowRoot | null;\n delete gRecord[key];\n }\n }\n\n g.__remote_components__ = ns;\n return ns;\n}\n","import type { InternalResolveClientUrl } from '#internal/host/server/types';\nimport { getNamespace } from '#internal/runtime/namespace';\nimport type { MountOrUnmountFunction } from '#internal/runtime/types';\nimport { logError, warnCrossOriginFetchError } from '#internal/utils/logger';\n\ntype ScriptMod = {\n mount?: MountOrUnmountFunction;\n unmount?: MountOrUnmountFunction;\n default?: {\n mount?: MountOrUnmountFunction;\n unmount?: MountOrUnmountFunction;\n };\n};\n\n/**\n * Fetches an ES module via the resolveClientUrl callback, rewrites its\n * relative imports to also go through the callback, then loads it by injecting a\n * wrapper <script type=\"module\"> tag. The module's namespace is captured via\n * a temporary global and returned.\n *\n * This is needed when a direct import() of a cross-origin module fails due to\n * CORS restrictions or Vercel preview-deployment auth. A simple URL rewrite\n * doesn't work for import() because relative imports inside the module would\n * resolve against the rewritten URL instead of the original remote origin.\n */\nasync function importViaCallback<T>(\n absoluteSrc: string,\n resolveClientUrl: InternalResolveClientUrl,\n): Promise<T> {\n const resolvedUrl = resolveClientUrl(absoluteSrc) ?? absoluteSrc;\n const fetchUrl = new URL(resolvedUrl, location.href).href;\n const response = await fetch(fetchUrl);\n if (!response.ok) throw new Error(`Proxied fetch failed: ${response.status}`);\n\n // Restore import.meta.url to the original module URL so any code that\n // relies on it (e.g. for asset resolution) gets the right value.\n // Rewrite relative imports to absolute URLs resolved through the callback so\n // that transitive dependencies also bypass CORS/auth.\n const content = (await response.text())\n .replace(/import\\.meta\\.url/g, JSON.stringify(absoluteSrc))\n .replace(\n /\\b(from|import)\\s*([\"'])(\\.\\.?\\/[^\"']+)\\2/g,\n (_, keyword, quote, relativePath) => {\n const absoluteImportUrl = new URL(relativePath, absoluteSrc).href;\n const resolvedImportUrl = new URL(\n resolveClientUrl(absoluteImportUrl) ?? absoluteImportUrl,\n location.href,\n ).href;\n return `${keyword} ${quote}${resolvedImportUrl}${quote}`;\n },\n );\n const moduleBlobUrl = URL.createObjectURL(\n new Blob([content], { type: 'text/javascript' }),\n );\n const wrapperContent = [\n `import*as m from${JSON.stringify(moduleBlobUrl)};`,\n `globalThis.__rc_module_registry__=globalThis.__rc_module_registry__||{};`,\n `globalThis.__rc_module_registry__[${JSON.stringify(absoluteSrc)}]=m;`,\n ].join('');\n const wrapperBlobUrl = URL.createObjectURL(\n new Blob([wrapperContent], { type: 'text/javascript' }),\n );\n const scriptEl = document.createElement('script');\n scriptEl.type = 'module';\n scriptEl.src = wrapperBlobUrl;\n try {\n await new Promise<void>((resolve, reject) => {\n scriptEl.onload = () => resolve();\n scriptEl.onerror = () =>\n reject(new Error(`Failed to load module for ${absoluteSrc}`));\n document.head.appendChild(scriptEl);\n });\n } finally {\n scriptEl.remove();\n URL.revokeObjectURL(moduleBlobUrl);\n URL.revokeObjectURL(wrapperBlobUrl);\n }\n const registry = getNamespace().moduleRegistry as Record<string, T>;\n const mod = registry[absoluteSrc] ?? ({} as T);\n delete registry[absoluteSrc];\n return mod;\n}\n\nasync function importDirectly<T>(absoluteSrc: string): Promise<T> {\n try {\n return (await import(\n /* @vite-ignore */\n /* webpackIgnore: true */ absoluteSrc\n )) as T;\n } catch (importError) {\n if (!absoluteSrc.startsWith('blob:')) {\n warnCrossOriginFetchError('StaticLoader', absoluteSrc);\n }\n throw importError;\n }\n}\n\nfunction resolveScriptSrc(script: HTMLScriptElement, url: URL): string {\n const rawSrc =\n typeof script.getAttribute === 'function'\n ? (script.getAttribute('src') ?? script.src)\n : script.src;\n if (!rawSrc && script.textContent) {\n return URL.createObjectURL(\n new Blob(\n [script.textContent.replace(/import\\.meta\\.url/g, JSON.stringify(url))],\n { type: 'text/javascript' },\n ),\n );\n }\n return rawSrc;\n}\n\nexport async function loadStaticRemoteComponent(\n scripts: HTMLScriptElement[],\n url: URL,\n resolveClientUrl?: InternalResolveClientUrl,\n) {\n const ns = getNamespace();\n\n if (ns.mountFns[url.href]) {\n ns.mountFns[url.href] = new Set();\n }\n if (ns.unmountFns[url.href]) {\n ns.unmountFns[url.href] = new Set();\n }\n const mountUnmountSets = await Promise.all(\n scripts.map(async (script) => {\n try {\n const src = resolveScriptSrc(script, url);\n const absoluteSrc = new URL(src, url).href;\n const mod: ScriptMod = resolveClientUrl\n ? await importViaCallback<ScriptMod>(absoluteSrc, resolveClientUrl)\n : await importDirectly<ScriptMod>(absoluteSrc);\n // revoke the object URL if we created one for inline script content\n if (src.startsWith('blob:')) {\n URL.revokeObjectURL(src);\n }\n if (\n typeof mod.mount === 'function' ||\n typeof mod.default?.mount === 'function'\n ) {\n if (!ns.mountFns[url.href]) {\n ns.mountFns[url.href] = new Set();\n }\n ns.mountFns[url.href]?.add(\n mod.mount ||\n mod.default?.mount ||\n (() => {\n // noop\n }),\n );\n }\n if (\n typeof mod.unmount === 'function' ||\n typeof mod.default?.unmount === 'function'\n ) {\n if (!ns.unmountFns[url.href]) {\n ns.unmountFns[url.href] = new Set();\n }\n ns.unmountFns[url.href]?.add(\n mod.unmount ||\n mod.default?.unmount ||\n (() => {\n // noop\n }),\n );\n }\n return {\n mount: mod.mount || mod.default?.mount,\n unmount: mod.unmount || mod.default?.unmount,\n };\n } catch (e) {\n logError(\n 'StaticLoader',\n `Error loading remote component script from \"${script.src || url.href}\".`,\n e,\n );\n return {\n mount: undefined,\n unmount: undefined,\n };\n }\n }),\n );\n return mountUnmountSets.reduce(\n (acc, { mount, unmount }) => {\n if (typeof mount === 'function') {\n acc.mount.add(mount);\n }\n if (typeof unmount === 'function') {\n acc.unmount.add(unmount);\n }\n return acc;\n },\n {\n mount: new Set<MountOrUnmountFunction>(),\n unmount: new Set<MountOrUnmountFunction>(),\n },\n );\n}\n","import type { MountOrUnmountFunction } from '#internal/runtime/types';\nimport { logError } from '#internal/utils/logger';\n\nif (typeof HTMLElement !== 'undefined') {\n class RemoteComponent extends HTMLElement {\n name?: string;\n root?: ShadowRoot | null = null;\n unmount?: Set<MountOrUnmountFunction> | null = null;\n\n constructor() {\n super();\n\n const html = this.innerHTML;\n this.root = this.attachShadow({\n mode: this.getAttribute('mode') === 'closed' ? 'closed' : 'open',\n });\n this.root.innerHTML = html;\n // Clear light DOM — content was copied into the shadow root above.\n // Without this the original children render twice (once in light DOM,\n // once in shadow DOM).\n this.replaceChildren();\n\n // run the mount functions for any scripts inside the shadow root asynchronously\n (async () => {\n const { loadStaticRemoteComponent } = await import(\n '../../runtime/loaders/static-loader'\n );\n loadStaticRemoteComponent(\n Array.from(this.root?.querySelectorAll('script') ?? []),\n new URL(location.href),\n )\n .then(({ mount, unmount }) => {\n this.unmount = unmount;\n return Promise.all(\n Array.from(mount).map((mountFn) => mountFn(this.root)),\n );\n })\n .catch((e) => {\n logError('HtmlRemote', 'Error mounting remote component.', e);\n });\n })().catch((e) => {\n logError('HtmlRemote', 'Error mounting remote component.', e);\n });\n }\n\n disconnectedCallback() {\n // run the unmount functions for any scripts inside the shadow root asynchronously\n (async () => {\n if (this.unmount) {\n await Promise.all(\n Array.from(this.unmount).map(async (unmount) => {\n try {\n await unmount(this.root);\n } catch (e) {\n logError('HtmlRemote', 'Error unmounting remote component.', e);\n }\n }),\n );\n }\n })().catch((e) => {\n logError('HtmlRemote', 'Error unmounting remote component.', e);\n });\n }\n }\n\n // register the custom element\n customElements.define('remote-component', RemoteComponent);\n}\n"],"mappings":"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","names":["location","loadStaticRemoteComponent"]}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
var app_exports = {};
|
|
30
20
|
__export(app_exports, {
|
|
@@ -33,26 +23,17 @@ __export(app_exports, {
|
|
|
33
23
|
module.exports = __toCommonJS(app_exports);
|
|
34
24
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
35
25
|
var import_wrapper = require("remote-components/remote/defaults/wrapper");
|
|
36
|
-
var import_work_async_storage = require("next/dist/server/app-render/work-async-storage.external");
|
|
37
26
|
var import_react = require("react");
|
|
38
27
|
var import_app_client = require("#internal/remote/nextjs/app-client");
|
|
28
|
+
var import_next_internals = require("#internal/remote/nextjs/next-internals");
|
|
39
29
|
var import_constants = require("#internal/runtime/constants");
|
|
30
|
+
var import_html_spec = require("#internal/runtime/html/html-spec");
|
|
31
|
+
var import_rsc_imports = require("#internal/runtime/rsc-imports");
|
|
40
32
|
var import_error = require("#internal/utils/error");
|
|
41
33
|
var import_project_id_env = require("#internal/utils/project-id-env");
|
|
42
|
-
const SERVER_ACTION_MANIFESTS_SINGLETON = Symbol.for(
|
|
43
|
-
"next.server.action-manifests"
|
|
44
|
-
);
|
|
45
|
-
const MANIFESTS_SINGLETON = Symbol.for("next.server.manifests");
|
|
46
34
|
const PROJECT_ID = (0, import_project_id_env.resolveProjectIdFromEnv)();
|
|
47
|
-
async function tryImport(importer) {
|
|
48
|
-
try {
|
|
49
|
-
return await importer();
|
|
50
|
-
} catch {
|
|
51
|
-
return {};
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
35
|
function RemoteComponentData({ name, data }) {
|
|
55
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("script", { id: `${name}
|
|
36
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("script", { id: `${name}${import_html_spec.ID_SUFFIX_RSC}`, children: data.map(
|
|
56
37
|
(chunk, i) => (
|
|
57
38
|
// make the data handling somewhat safe
|
|
58
39
|
`${i === 0 ? `self["${name}"]=self["${name}"]||[];` : ""}self["${name}"].push(${JSON.stringify(chunk)});`
|
|
@@ -63,13 +44,9 @@ async function ExposeRemoteComponent({
|
|
|
63
44
|
name = import_constants.DEFAULT_COMPONENT_NAME,
|
|
64
45
|
children
|
|
65
46
|
}) {
|
|
66
|
-
const { page, route } =
|
|
67
|
-
|
|
68
|
-
route: "/"
|
|
69
|
-
};
|
|
47
|
+
const { page, route } = (0, import_next_internals.getWorkStore)();
|
|
48
|
+
const manifest = (0, import_next_internals.resolveManifest)(route);
|
|
70
49
|
const self = globalThis;
|
|
71
|
-
const manifests = self[MANIFESTS_SINGLETON] ?? self[SERVER_ACTION_MANIFESTS_SINGLETON] ?? {};
|
|
72
|
-
const manifest = "clientReferenceManifestsPerRoute" in manifests ? manifests.clientReferenceManifestsPerRoute?.get?.(route) : "clientReferenceManifestsPerPage" in manifests ? manifests.clientReferenceManifestsPerPage?.[route] : void 0;
|
|
73
50
|
self.__RSC_MANIFEST = self.__RSC_MANIFEST || {};
|
|
74
51
|
self.__RSC_MANIFEST[page] = self.__RSC_MANIFEST[page] || manifest;
|
|
75
52
|
self.__RSC_SERVER_MANIFEST = self.__RSC_SERVER_MANIFEST || {};
|
|
@@ -91,27 +68,7 @@ async function ExposeRemoteComponent({
|
|
|
91
68
|
];
|
|
92
69
|
})
|
|
93
70
|
);
|
|
94
|
-
const
|
|
95
|
-
{ renderToReadableStream: nextRenderToReadableStream },
|
|
96
|
-
{ renderToReadableStream: legacyRenderToReadableStream }
|
|
97
|
-
] = await Promise.all(
|
|
98
|
-
process.env.TURBOPACK ? [
|
|
99
|
-
tryImport(
|
|
100
|
-
() => import("react-server-dom-turbopack/server")
|
|
101
|
-
),
|
|
102
|
-
tryImport(
|
|
103
|
-
() => import("react-server-dom-turbopack/server.edge")
|
|
104
|
-
)
|
|
105
|
-
] : [
|
|
106
|
-
tryImport(
|
|
107
|
-
() => import("react-server-dom-webpack/server")
|
|
108
|
-
),
|
|
109
|
-
tryImport(
|
|
110
|
-
() => import("react-server-dom-webpack/server.edge")
|
|
111
|
-
)
|
|
112
|
-
]
|
|
113
|
-
);
|
|
114
|
-
const renderToReadableStream = nextRenderToReadableStream ?? legacyRenderToReadableStream;
|
|
71
|
+
const { renderToReadableStream } = await (0, import_rsc_imports.importRSCServer)();
|
|
115
72
|
if (typeof renderToReadableStream !== "function") {
|
|
116
73
|
throw new import_error.RemoteComponentsError(
|
|
117
74
|
"No valid `renderToReadableStream()` function found. Do you have Next.js installed?"
|
|
@@ -135,11 +92,13 @@ async function ExposeRemoteComponent({
|
|
|
135
92
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
136
93
|
"div",
|
|
137
94
|
{
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
95
|
+
...{
|
|
96
|
+
[import_html_spec.DATA_BUNDLE]: PROJECT_ID,
|
|
97
|
+
[import_html_spec.DATA_ROUTE]: route,
|
|
98
|
+
[import_html_spec.DATA_RUNTIME]: runtime,
|
|
99
|
+
[import_html_spec.DATA_TYPE]: "nextjs"
|
|
100
|
+
},
|
|
101
|
+
id: `${remoteComponentName}${import_html_spec.ID_SUFFIX_SSR}`,
|
|
143
102
|
children: [
|
|
144
103
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_app_client.RemoteComponentSharedRemote, { name: remoteComponentName }),
|
|
145
104
|
typeof error !== "undefined" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/remote/nextjs/app.tsx"],"sourcesContent":["import 'remote-components/remote/defaults/wrapper';\nimport { workAsyncStorage } from 'next/dist/server/app-render/work-async-storage.external';\nimport { Suspense } from 'react';\nimport type { ConsumeLifecycleCallbacks } from '#internal/host/shared/config';\nimport { RemoteComponentSharedRemote } from '#internal/remote/nextjs/app-client';\nimport { DEFAULT_COMPONENT_NAME } from '#internal/runtime/constants';\nimport { RemoteComponentsError } from '#internal/utils/error';\nimport { resolveProjectIdFromEnv } from '#internal/utils/project-id-env';\n\ninterface Manifest {\n clientModules?: Record<\n string,\n { id: string; name: string; chunks: string[]; async: boolean }\n >;\n moduleLoading: { prefix?: string; crossOrigin?: boolean | null };\n ssrModuleMapping?: Record<string, unknown>;\n}\n\n// internal Next.js symbol to access the manifest which is stored in the global scope\nconst SERVER_ACTION_MANIFESTS_SINGLETON = Symbol.for(\n 'next.server.action-manifests',\n);\nconst MANIFESTS_SINGLETON = Symbol.for('next.server.manifests');\n\nconst PROJECT_ID = resolveProjectIdFromEnv();\n\nasync function tryImport<T>(importer: () => Promise<T>) {\n try {\n return (await importer()) as T;\n } catch {\n return {} as T;\n }\n}\n\n// inject the RSC flight data into the HTML response using <script>\n// the RSC flight data is used to hydrate the remote component on the host\n// this approach is similar to an island architecture on the host\n// the remote component is static HTML until it is hydrated using this RSC flight data\nfunction RemoteComponentData({ name, data }: { name: string; data: string[] }) {\n return (\n <script id={`${name}_rsc`}>\n {data\n .map(\n (chunk, i) =>\n // make the data handling somewhat safe\n `${\n i === 0 ? `self[\"${name}\"]=self[\"${name}\"]||[];` : ''\n }self[\"${name}\"].push(${JSON.stringify(chunk)});`,\n )\n .join('\\n')}\n </script>\n );\n}\n\n/**\n * Props for exposing a Next.js component as a remote component.\n *\n * Extends {@link ConsumeLifecycleCallbacks} so the consuming host can wire up lifecycle\n * events. The `children` prop is the component content to expose (required,\n * unlike host props where children are an optional loading fallback).\n */\nexport interface ExposeRemoteComponentProps extends ConsumeLifecycleCallbacks {\n /** The name of the remote component. Use a unique name to expose multiple remote components from the same page. */\n name?: string;\n /** The content of the remote component. This is the content that will be rendered as the remote component. */\n children: React.ReactNode;\n}\n\n/**\n * ExposeRemoteComponent is a Next.js component that exposes a remote component\n * that can be used in a host application.\n *\n * @param name - The name of the remote component. Use a unique name to expose multiple remote components from the same page.\n * @param children - The content of the remote component. This is the content that will be rendered as the remote component.\n * @returns A React component that renders the remote component.\n *\n * @example\n *\n * Use the `<ExposeRemoteComponent>` in your Next.js App Router application to expose the children as a remote component:\n *\n * ```tsx\n * import { ExposeRemoteComponent } from 'remote-components/remote/nextjs/app';\n *\n * export default function MyPage() {\n * return (\n * <ExposeRemoteComponent>\n * <h1>Hello from the remote component!</h1>\n * <p>This is a remote component that can be used in a host application.</p>\n * </ExposeRemoteComponent>\n * );\n * }\n * ```\n */\nexport async function ExposeRemoteComponent({\n name = DEFAULT_COMPONENT_NAME,\n children,\n}: ExposeRemoteComponentProps): Promise<React.ReactElement> {\n // access the internal Next.js work store to get the active page and route\n const { page, route } = workAsyncStorage.getStore() ?? {\n page: '/',\n route: '/',\n };\n\n // get reference to the manifests from the global scope\n const self = globalThis as typeof globalThis & {\n [SERVER_ACTION_MANIFESTS_SINGLETON]?: {\n clientReferenceManifestsPerPage?: Record<string, Manifest>;\n };\n [MANIFESTS_SINGLETON]?: {\n clientReferenceManifestsPerRoute?: Map<string, Manifest>;\n };\n __RSC_MANIFEST?: Record<string, unknown>;\n __RSC_SERVER_MANIFEST?: Record<string, unknown>;\n };\n const manifests =\n self[MANIFESTS_SINGLETON] ?? self[SERVER_ACTION_MANIFESTS_SINGLETON] ?? {};\n const manifest =\n 'clientReferenceManifestsPerRoute' in manifests\n ? manifests.clientReferenceManifestsPerRoute?.get?.(route)\n : 'clientReferenceManifestsPerPage' in manifests\n ? manifests.clientReferenceManifestsPerPage?.[route]\n : undefined;\n\n // manually handle the internal Next.js manifest\n self.__RSC_MANIFEST = self.__RSC_MANIFEST || {};\n self.__RSC_MANIFEST[page] = self.__RSC_MANIFEST[page] || manifest;\n self.__RSC_SERVER_MANIFEST = self.__RSC_SERVER_MANIFEST || {};\n self.__RSC_SERVER_MANIFEST[page] =\n self.__RSC_SERVER_MANIFEST[page] || manifest;\n\n // get the client and SSR module mapping to be able to use client components in the remote component\n const ssrModuleMapping = { ...manifest?.ssrModuleMapping };\n\n // if the remote component is used in a hosting application, we need to mutate the module map to include the zone\n const clientModules = Object.fromEntries(\n Object.entries(manifest?.clientModules ?? {}).map(([key, value]) => {\n // append a prefix to each entry in the module map to include the zone of the remote component\n const remoteId = `[${PROJECT_ID}] ${value.id}`;\n ssrModuleMapping[remoteId] = ssrModuleMapping[value.id];\n // override the original id with the new remote id\n return [\n key,\n {\n ...value,\n id: remoteId,\n // prepend the current zone to the chunks to handle remote component chunk loading in Webpack\n // this is required to avoid loading the wrong chunk in the host application\n chunks: value.chunks.map((chunk) => `[${PROJECT_ID}] ${chunk}`),\n },\n ];\n }),\n );\n\n // dynamically import the runtime specific RSC rendering functions and client component\n const [\n { renderToReadableStream: nextRenderToReadableStream },\n { renderToReadableStream: legacyRenderToReadableStream },\n ] = await Promise.all(\n process.env.TURBOPACK\n ? [\n tryImport<RSDWServer>(\n () => import('react-server-dom-turbopack/server'),\n ),\n tryImport<RSDWServer>(\n () => import('react-server-dom-turbopack/server.edge'),\n ),\n ]\n : [\n tryImport<RSDWServer>(\n () => import('react-server-dom-webpack/server'),\n ),\n tryImport<RSDWServer>(\n () => import('react-server-dom-webpack/server.edge'),\n ),\n ],\n );\n const renderToReadableStream =\n nextRenderToReadableStream ?? legacyRenderToReadableStream;\n\n if (typeof renderToReadableStream !== 'function') {\n throw new RemoteComponentsError(\n 'No valid `renderToReadableStream()` function found. Do you have Next.js installed?',\n );\n }\n\n let error: Error | undefined;\n // render the wrapped content of this component (children) into an RSC stream\n const stream = renderToReadableStream(children, clientModules, {\n onError(e) {\n error = e;\n },\n });\n\n const data = [];\n const decoder = new TextDecoder();\n\n // convert the stream to an array for safe passing to the client\n for await (const chunk of stream as unknown as AsyncIterable<Uint8Array>) {\n data.push(decoder.decode(chunk));\n }\n\n const runtime = process.env.TURBOPACK ? 'turbopack' : 'webpack';\n const remoteComponentName = `${name}_${route.replace(/[/[\\].]/g, '_')}`;\n\n return (\n // wrap the remote component content into a div to know which part of the HTML belongs to the remote component\n <div\n data-bundle={PROJECT_ID}\n data-route={route}\n data-runtime={runtime}\n data-type=\"nextjs\"\n id={`${remoteComponentName}_ssr`}\n >\n <RemoteComponentSharedRemote name={remoteComponentName} />\n {typeof error !== 'undefined' ? (\n <>\n <template\n data-next-error-message={\n error instanceof Error ? error.message : String(error)\n }\n data-next-error-stack={\n error instanceof Error ? (error.stack ?? '') : ''\n }\n />\n <Suspense fallback={null}>{children}</Suspense>\n </>\n ) : (\n children\n )}\n {/* inject RSC flight data as <script> */}\n <RemoteComponentData data={data} name={remoteComponentName} />\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/remote/nextjs/app.tsx"],"sourcesContent":["import 'remote-components/remote/defaults/wrapper';\nimport { Suspense } from 'react';\nimport type { ConsumeLifecycleCallbacks } from '#internal/host/shared/config';\nimport { RemoteComponentSharedRemote } from '#internal/remote/nextjs/app-client';\nimport {\n getWorkStore,\n resolveManifest,\n} from '#internal/remote/nextjs/next-internals';\nimport { DEFAULT_COMPONENT_NAME } from '#internal/runtime/constants';\nimport {\n DATA_BUNDLE,\n DATA_ROUTE,\n DATA_RUNTIME,\n DATA_TYPE,\n ID_SUFFIX_RSC,\n ID_SUFFIX_SSR,\n} from '#internal/runtime/html/html-spec';\nimport { importRSCServer } from '#internal/runtime/rsc-imports';\nimport { RemoteComponentsError } from '#internal/utils/error';\nimport { resolveProjectIdFromEnv } from '#internal/utils/project-id-env';\n\nconst PROJECT_ID = resolveProjectIdFromEnv();\n\n// inject the RSC flight data into the HTML response using <script>\n// the RSC flight data is used to hydrate the remote component on the host\n// this approach is similar to an island architecture on the host\n// the remote component is static HTML until it is hydrated using this RSC flight data\nfunction RemoteComponentData({ name, data }: { name: string; data: string[] }) {\n return (\n <script id={`${name}${ID_SUFFIX_RSC}`}>\n {data\n .map(\n (chunk, i) =>\n // make the data handling somewhat safe\n `${\n i === 0 ? `self[\"${name}\"]=self[\"${name}\"]||[];` : ''\n }self[\"${name}\"].push(${JSON.stringify(chunk)});`,\n )\n .join('\\n')}\n </script>\n );\n}\n\n/**\n * Props for exposing a Next.js component as a remote component.\n *\n * Extends {@link ConsumeLifecycleCallbacks} so the consuming host can wire up lifecycle\n * events. The `children` prop is the component content to expose (required,\n * unlike host props where children are an optional loading fallback).\n */\nexport interface ExposeRemoteComponentProps extends ConsumeLifecycleCallbacks {\n /** The name of the remote component. Use a unique name to expose multiple remote components from the same page. */\n name?: string;\n /** The content of the remote component. This is the content that will be rendered as the remote component. */\n children: React.ReactNode;\n}\n\n/**\n * ExposeRemoteComponent is a Next.js component that exposes a remote component\n * that can be used in a host application.\n *\n * @param name - The name of the remote component. Use a unique name to expose multiple remote components from the same page.\n * @param children - The content of the remote component. This is the content that will be rendered as the remote component.\n * @returns A React component that renders the remote component.\n *\n * @example\n *\n * Use the `<ExposeRemoteComponent>` in your Next.js App Router application to expose the children as a remote component:\n *\n * ```tsx\n * import { ExposeRemoteComponent } from 'remote-components/remote/nextjs/app';\n *\n * export default function MyPage() {\n * return (\n * <ExposeRemoteComponent>\n * <h1>Hello from the remote component!</h1>\n * <p>This is a remote component that can be used in a host application.</p>\n * </ExposeRemoteComponent>\n * );\n * }\n * ```\n */\nexport async function ExposeRemoteComponent({\n name = DEFAULT_COMPONENT_NAME,\n children,\n}: ExposeRemoteComponentProps): Promise<React.ReactElement> {\n const { page, route } = getWorkStore();\n\n const manifest = resolveManifest(route);\n\n // Populate the global RSC manifest cache that Next.js reads during rendering\n const self = globalThis as typeof globalThis & {\n __RSC_MANIFEST?: Record<string, unknown>;\n __RSC_SERVER_MANIFEST?: Record<string, unknown>;\n };\n self.__RSC_MANIFEST = self.__RSC_MANIFEST || {};\n self.__RSC_MANIFEST[page] = self.__RSC_MANIFEST[page] || manifest;\n self.__RSC_SERVER_MANIFEST = self.__RSC_SERVER_MANIFEST || {};\n self.__RSC_SERVER_MANIFEST[page] =\n self.__RSC_SERVER_MANIFEST[page] || manifest;\n\n // get the client and SSR module mapping to be able to use client components in the remote component\n const ssrModuleMapping = { ...manifest?.ssrModuleMapping };\n\n // if the remote component is used in a hosting application, we need to mutate the module map to include the zone\n const clientModules = Object.fromEntries(\n Object.entries(manifest?.clientModules ?? {}).map(([key, value]) => {\n // append a prefix to each entry in the module map to include the zone of the remote component\n const remoteId = `[${PROJECT_ID}] ${value.id}`;\n ssrModuleMapping[remoteId] = ssrModuleMapping[value.id];\n // override the original id with the new remote id\n return [\n key,\n {\n ...value,\n id: remoteId,\n // prepend the current zone to the chunks to handle remote component chunk loading in Webpack\n // this is required to avoid loading the wrong chunk in the host application\n chunks: value.chunks.map((chunk) => `[${PROJECT_ID}] ${chunk}`),\n },\n ];\n }),\n );\n\n const { renderToReadableStream } = await importRSCServer();\n\n if (typeof renderToReadableStream !== 'function') {\n throw new RemoteComponentsError(\n 'No valid `renderToReadableStream()` function found. Do you have Next.js installed?',\n );\n }\n\n let error: Error | undefined;\n // render the wrapped content of this component (children) into an RSC stream\n const stream = renderToReadableStream(children, clientModules, {\n onError(e) {\n error = e;\n },\n });\n\n const data = [];\n const decoder = new TextDecoder();\n\n // convert the stream to an array for safe passing to the client\n for await (const chunk of stream as unknown as AsyncIterable<Uint8Array>) {\n data.push(decoder.decode(chunk));\n }\n\n const runtime = process.env.TURBOPACK ? 'turbopack' : 'webpack';\n const remoteComponentName = `${name}_${route.replace(/[/[\\].]/g, '_')}`;\n\n return (\n // wrap the remote component content into a div to know which part of the HTML belongs to the remote component\n <div\n {...{\n [DATA_BUNDLE]: PROJECT_ID,\n [DATA_ROUTE]: route,\n [DATA_RUNTIME]: runtime,\n [DATA_TYPE]: 'nextjs',\n }}\n id={`${remoteComponentName}${ID_SUFFIX_SSR}`}\n >\n <RemoteComponentSharedRemote name={remoteComponentName} />\n {typeof error !== 'undefined' ? (\n <>\n <template\n data-next-error-message={\n error instanceof Error ? error.message : String(error)\n }\n data-next-error-stack={\n error instanceof Error ? (error.stack ?? '') : ''\n }\n />\n <Suspense fallback={null}>{children}</Suspense>\n </>\n ) : (\n children\n )}\n {/* inject RSC flight data as <script> */}\n <RemoteComponentData data={data} name={remoteComponentName} />\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import "remote-components/remote/defaults/wrapper";
|
|
3
|
-
import { workAsyncStorage } from "next/dist/server/app-render/work-async-storage.external";
|
|
4
3
|
import { Suspense } from "react";
|
|
5
4
|
import { RemoteComponentSharedRemote } from "#internal/remote/nextjs/app-client";
|
|
5
|
+
import {
|
|
6
|
+
getWorkStore,
|
|
7
|
+
resolveManifest
|
|
8
|
+
} from "#internal/remote/nextjs/next-internals";
|
|
6
9
|
import { DEFAULT_COMPONENT_NAME } from "#internal/runtime/constants";
|
|
10
|
+
import {
|
|
11
|
+
DATA_BUNDLE,
|
|
12
|
+
DATA_ROUTE,
|
|
13
|
+
DATA_RUNTIME,
|
|
14
|
+
DATA_TYPE,
|
|
15
|
+
ID_SUFFIX_RSC,
|
|
16
|
+
ID_SUFFIX_SSR
|
|
17
|
+
} from "#internal/runtime/html/html-spec";
|
|
18
|
+
import { importRSCServer } from "#internal/runtime/rsc-imports";
|
|
7
19
|
import { RemoteComponentsError } from "#internal/utils/error";
|
|
8
20
|
import { resolveProjectIdFromEnv } from "#internal/utils/project-id-env";
|
|
9
|
-
const SERVER_ACTION_MANIFESTS_SINGLETON = Symbol.for(
|
|
10
|
-
"next.server.action-manifests"
|
|
11
|
-
);
|
|
12
|
-
const MANIFESTS_SINGLETON = Symbol.for("next.server.manifests");
|
|
13
21
|
const PROJECT_ID = resolveProjectIdFromEnv();
|
|
14
|
-
async function tryImport(importer) {
|
|
15
|
-
try {
|
|
16
|
-
return await importer();
|
|
17
|
-
} catch {
|
|
18
|
-
return {};
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
22
|
function RemoteComponentData({ name, data }) {
|
|
22
|
-
return /* @__PURE__ */ jsx("script", { id: `${name}
|
|
23
|
+
return /* @__PURE__ */ jsx("script", { id: `${name}${ID_SUFFIX_RSC}`, children: data.map(
|
|
23
24
|
(chunk, i) => (
|
|
24
25
|
// make the data handling somewhat safe
|
|
25
26
|
`${i === 0 ? `self["${name}"]=self["${name}"]||[];` : ""}self["${name}"].push(${JSON.stringify(chunk)});`
|
|
@@ -30,13 +31,9 @@ async function ExposeRemoteComponent({
|
|
|
30
31
|
name = DEFAULT_COMPONENT_NAME,
|
|
31
32
|
children
|
|
32
33
|
}) {
|
|
33
|
-
const { page, route } =
|
|
34
|
-
|
|
35
|
-
route: "/"
|
|
36
|
-
};
|
|
34
|
+
const { page, route } = getWorkStore();
|
|
35
|
+
const manifest = resolveManifest(route);
|
|
37
36
|
const self = globalThis;
|
|
38
|
-
const manifests = self[MANIFESTS_SINGLETON] ?? self[SERVER_ACTION_MANIFESTS_SINGLETON] ?? {};
|
|
39
|
-
const manifest = "clientReferenceManifestsPerRoute" in manifests ? manifests.clientReferenceManifestsPerRoute?.get?.(route) : "clientReferenceManifestsPerPage" in manifests ? manifests.clientReferenceManifestsPerPage?.[route] : void 0;
|
|
40
37
|
self.__RSC_MANIFEST = self.__RSC_MANIFEST || {};
|
|
41
38
|
self.__RSC_MANIFEST[page] = self.__RSC_MANIFEST[page] || manifest;
|
|
42
39
|
self.__RSC_SERVER_MANIFEST = self.__RSC_SERVER_MANIFEST || {};
|
|
@@ -58,27 +55,7 @@ async function ExposeRemoteComponent({
|
|
|
58
55
|
];
|
|
59
56
|
})
|
|
60
57
|
);
|
|
61
|
-
const
|
|
62
|
-
{ renderToReadableStream: nextRenderToReadableStream },
|
|
63
|
-
{ renderToReadableStream: legacyRenderToReadableStream }
|
|
64
|
-
] = await Promise.all(
|
|
65
|
-
process.env.TURBOPACK ? [
|
|
66
|
-
tryImport(
|
|
67
|
-
() => import("react-server-dom-turbopack/server")
|
|
68
|
-
),
|
|
69
|
-
tryImport(
|
|
70
|
-
() => import("react-server-dom-turbopack/server.edge")
|
|
71
|
-
)
|
|
72
|
-
] : [
|
|
73
|
-
tryImport(
|
|
74
|
-
() => import("react-server-dom-webpack/server")
|
|
75
|
-
),
|
|
76
|
-
tryImport(
|
|
77
|
-
() => import("react-server-dom-webpack/server.edge")
|
|
78
|
-
)
|
|
79
|
-
]
|
|
80
|
-
);
|
|
81
|
-
const renderToReadableStream = nextRenderToReadableStream ?? legacyRenderToReadableStream;
|
|
58
|
+
const { renderToReadableStream } = await importRSCServer();
|
|
82
59
|
if (typeof renderToReadableStream !== "function") {
|
|
83
60
|
throw new RemoteComponentsError(
|
|
84
61
|
"No valid `renderToReadableStream()` function found. Do you have Next.js installed?"
|
|
@@ -102,11 +79,13 @@ async function ExposeRemoteComponent({
|
|
|
102
79
|
/* @__PURE__ */ jsxs(
|
|
103
80
|
"div",
|
|
104
81
|
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
82
|
+
...{
|
|
83
|
+
[DATA_BUNDLE]: PROJECT_ID,
|
|
84
|
+
[DATA_ROUTE]: route,
|
|
85
|
+
[DATA_RUNTIME]: runtime,
|
|
86
|
+
[DATA_TYPE]: "nextjs"
|
|
87
|
+
},
|
|
88
|
+
id: `${remoteComponentName}${ID_SUFFIX_SSR}`,
|
|
110
89
|
children: [
|
|
111
90
|
/* @__PURE__ */ jsx(RemoteComponentSharedRemote, { name: remoteComponentName }),
|
|
112
91
|
typeof error !== "undefined" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/remote/nextjs/app.tsx"],"sourcesContent":["import 'remote-components/remote/defaults/wrapper';\nimport { workAsyncStorage } from 'next/dist/server/app-render/work-async-storage.external';\nimport { Suspense } from 'react';\nimport type { ConsumeLifecycleCallbacks } from '#internal/host/shared/config';\nimport { RemoteComponentSharedRemote } from '#internal/remote/nextjs/app-client';\nimport { DEFAULT_COMPONENT_NAME } from '#internal/runtime/constants';\nimport { RemoteComponentsError } from '#internal/utils/error';\nimport { resolveProjectIdFromEnv } from '#internal/utils/project-id-env';\n\ninterface Manifest {\n clientModules?: Record<\n string,\n { id: string; name: string; chunks: string[]; async: boolean }\n >;\n moduleLoading: { prefix?: string; crossOrigin?: boolean | null };\n ssrModuleMapping?: Record<string, unknown>;\n}\n\n// internal Next.js symbol to access the manifest which is stored in the global scope\nconst SERVER_ACTION_MANIFESTS_SINGLETON = Symbol.for(\n 'next.server.action-manifests',\n);\nconst MANIFESTS_SINGLETON = Symbol.for('next.server.manifests');\n\nconst PROJECT_ID = resolveProjectIdFromEnv();\n\nasync function tryImport<T>(importer: () => Promise<T>) {\n try {\n return (await importer()) as T;\n } catch {\n return {} as T;\n }\n}\n\n// inject the RSC flight data into the HTML response using <script>\n// the RSC flight data is used to hydrate the remote component on the host\n// this approach is similar to an island architecture on the host\n// the remote component is static HTML until it is hydrated using this RSC flight data\nfunction RemoteComponentData({ name, data }: { name: string; data: string[] }) {\n return (\n <script id={`${name}_rsc`}>\n {data\n .map(\n (chunk, i) =>\n // make the data handling somewhat safe\n `${\n i === 0 ? `self[\"${name}\"]=self[\"${name}\"]||[];` : ''\n }self[\"${name}\"].push(${JSON.stringify(chunk)});`,\n )\n .join('\\n')}\n </script>\n );\n}\n\n/**\n * Props for exposing a Next.js component as a remote component.\n *\n * Extends {@link ConsumeLifecycleCallbacks} so the consuming host can wire up lifecycle\n * events. The `children` prop is the component content to expose (required,\n * unlike host props where children are an optional loading fallback).\n */\nexport interface ExposeRemoteComponentProps extends ConsumeLifecycleCallbacks {\n /** The name of the remote component. Use a unique name to expose multiple remote components from the same page. */\n name?: string;\n /** The content of the remote component. This is the content that will be rendered as the remote component. */\n children: React.ReactNode;\n}\n\n/**\n * ExposeRemoteComponent is a Next.js component that exposes a remote component\n * that can be used in a host application.\n *\n * @param name - The name of the remote component. Use a unique name to expose multiple remote components from the same page.\n * @param children - The content of the remote component. This is the content that will be rendered as the remote component.\n * @returns A React component that renders the remote component.\n *\n * @example\n *\n * Use the `<ExposeRemoteComponent>` in your Next.js App Router application to expose the children as a remote component:\n *\n * ```tsx\n * import { ExposeRemoteComponent } from 'remote-components/remote/nextjs/app';\n *\n * export default function MyPage() {\n * return (\n * <ExposeRemoteComponent>\n * <h1>Hello from the remote component!</h1>\n * <p>This is a remote component that can be used in a host application.</p>\n * </ExposeRemoteComponent>\n * );\n * }\n * ```\n */\nexport async function ExposeRemoteComponent({\n name = DEFAULT_COMPONENT_NAME,\n children,\n}: ExposeRemoteComponentProps): Promise<React.ReactElement> {\n // access the internal Next.js work store to get the active page and route\n const { page, route } = workAsyncStorage.getStore() ?? {\n page: '/',\n route: '/',\n };\n\n // get reference to the manifests from the global scope\n const self = globalThis as typeof globalThis & {\n [SERVER_ACTION_MANIFESTS_SINGLETON]?: {\n clientReferenceManifestsPerPage?: Record<string, Manifest>;\n };\n [MANIFESTS_SINGLETON]?: {\n clientReferenceManifestsPerRoute?: Map<string, Manifest>;\n };\n __RSC_MANIFEST?: Record<string, unknown>;\n __RSC_SERVER_MANIFEST?: Record<string, unknown>;\n };\n const manifests =\n self[MANIFESTS_SINGLETON] ?? self[SERVER_ACTION_MANIFESTS_SINGLETON] ?? {};\n const manifest =\n 'clientReferenceManifestsPerRoute' in manifests\n ? manifests.clientReferenceManifestsPerRoute?.get?.(route)\n : 'clientReferenceManifestsPerPage' in manifests\n ? manifests.clientReferenceManifestsPerPage?.[route]\n : undefined;\n\n // manually handle the internal Next.js manifest\n self.__RSC_MANIFEST = self.__RSC_MANIFEST || {};\n self.__RSC_MANIFEST[page] = self.__RSC_MANIFEST[page] || manifest;\n self.__RSC_SERVER_MANIFEST = self.__RSC_SERVER_MANIFEST || {};\n self.__RSC_SERVER_MANIFEST[page] =\n self.__RSC_SERVER_MANIFEST[page] || manifest;\n\n // get the client and SSR module mapping to be able to use client components in the remote component\n const ssrModuleMapping = { ...manifest?.ssrModuleMapping };\n\n // if the remote component is used in a hosting application, we need to mutate the module map to include the zone\n const clientModules = Object.fromEntries(\n Object.entries(manifest?.clientModules ?? {}).map(([key, value]) => {\n // append a prefix to each entry in the module map to include the zone of the remote component\n const remoteId = `[${PROJECT_ID}] ${value.id}`;\n ssrModuleMapping[remoteId] = ssrModuleMapping[value.id];\n // override the original id with the new remote id\n return [\n key,\n {\n ...value,\n id: remoteId,\n // prepend the current zone to the chunks to handle remote component chunk loading in Webpack\n // this is required to avoid loading the wrong chunk in the host application\n chunks: value.chunks.map((chunk) => `[${PROJECT_ID}] ${chunk}`),\n },\n ];\n }),\n );\n\n // dynamically import the runtime specific RSC rendering functions and client component\n const [\n { renderToReadableStream: nextRenderToReadableStream },\n { renderToReadableStream: legacyRenderToReadableStream },\n ] = await Promise.all(\n process.env.TURBOPACK\n ? [\n tryImport<RSDWServer>(\n () => import('react-server-dom-turbopack/server'),\n ),\n tryImport<RSDWServer>(\n () => import('react-server-dom-turbopack/server.edge'),\n ),\n ]\n : [\n tryImport<RSDWServer>(\n () => import('react-server-dom-webpack/server'),\n ),\n tryImport<RSDWServer>(\n () => import('react-server-dom-webpack/server.edge'),\n ),\n ],\n );\n const renderToReadableStream =\n nextRenderToReadableStream ?? legacyRenderToReadableStream;\n\n if (typeof renderToReadableStream !== 'function') {\n throw new RemoteComponentsError(\n 'No valid `renderToReadableStream()` function found. Do you have Next.js installed?',\n );\n }\n\n let error: Error | undefined;\n // render the wrapped content of this component (children) into an RSC stream\n const stream = renderToReadableStream(children, clientModules, {\n onError(e) {\n error = e;\n },\n });\n\n const data = [];\n const decoder = new TextDecoder();\n\n // convert the stream to an array for safe passing to the client\n for await (const chunk of stream as unknown as AsyncIterable<Uint8Array>) {\n data.push(decoder.decode(chunk));\n }\n\n const runtime = process.env.TURBOPACK ? 'turbopack' : 'webpack';\n const remoteComponentName = `${name}_${route.replace(/[/[\\].]/g, '_')}`;\n\n return (\n // wrap the remote component content into a div to know which part of the HTML belongs to the remote component\n <div\n data-bundle={PROJECT_ID}\n data-route={route}\n data-runtime={runtime}\n data-type=\"nextjs\"\n id={`${remoteComponentName}_ssr`}\n >\n <RemoteComponentSharedRemote name={remoteComponentName} />\n {typeof error !== 'undefined' ? (\n <>\n <template\n data-next-error-message={\n error instanceof Error ? error.message : String(error)\n }\n data-next-error-stack={\n error instanceof Error ? (error.stack ?? '') : ''\n }\n />\n <Suspense fallback={null}>{children}</Suspense>\n </>\n ) : (\n children\n )}\n {/* inject RSC flight data as <script> */}\n <RemoteComponentData data={data} name={remoteComponentName} />\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/remote/nextjs/app.tsx"],"sourcesContent":["import 'remote-components/remote/defaults/wrapper';\nimport { Suspense } from 'react';\nimport type { ConsumeLifecycleCallbacks } from '#internal/host/shared/config';\nimport { RemoteComponentSharedRemote } from '#internal/remote/nextjs/app-client';\nimport {\n getWorkStore,\n resolveManifest,\n} from '#internal/remote/nextjs/next-internals';\nimport { DEFAULT_COMPONENT_NAME } from '#internal/runtime/constants';\nimport {\n DATA_BUNDLE,\n DATA_ROUTE,\n DATA_RUNTIME,\n DATA_TYPE,\n ID_SUFFIX_RSC,\n ID_SUFFIX_SSR,\n} from '#internal/runtime/html/html-spec';\nimport { importRSCServer } from '#internal/runtime/rsc-imports';\nimport { RemoteComponentsError } from '#internal/utils/error';\nimport { resolveProjectIdFromEnv } from '#internal/utils/project-id-env';\n\nconst PROJECT_ID = resolveProjectIdFromEnv();\n\n// inject the RSC flight data into the HTML response using <script>\n// the RSC flight data is used to hydrate the remote component on the host\n// this approach is similar to an island architecture on the host\n// the remote component is static HTML until it is hydrated using this RSC flight data\nfunction RemoteComponentData({ name, data }: { name: string; data: string[] }) {\n return (\n <script id={`${name}${ID_SUFFIX_RSC}`}>\n {data\n .map(\n (chunk, i) =>\n // make the data handling somewhat safe\n `${\n i === 0 ? `self[\"${name}\"]=self[\"${name}\"]||[];` : ''\n }self[\"${name}\"].push(${JSON.stringify(chunk)});`,\n )\n .join('\\n')}\n </script>\n );\n}\n\n/**\n * Props for exposing a Next.js component as a remote component.\n *\n * Extends {@link ConsumeLifecycleCallbacks} so the consuming host can wire up lifecycle\n * events. The `children` prop is the component content to expose (required,\n * unlike host props where children are an optional loading fallback).\n */\nexport interface ExposeRemoteComponentProps extends ConsumeLifecycleCallbacks {\n /** The name of the remote component. Use a unique name to expose multiple remote components from the same page. */\n name?: string;\n /** The content of the remote component. This is the content that will be rendered as the remote component. */\n children: React.ReactNode;\n}\n\n/**\n * ExposeRemoteComponent is a Next.js component that exposes a remote component\n * that can be used in a host application.\n *\n * @param name - The name of the remote component. Use a unique name to expose multiple remote components from the same page.\n * @param children - The content of the remote component. This is the content that will be rendered as the remote component.\n * @returns A React component that renders the remote component.\n *\n * @example\n *\n * Use the `<ExposeRemoteComponent>` in your Next.js App Router application to expose the children as a remote component:\n *\n * ```tsx\n * import { ExposeRemoteComponent } from 'remote-components/remote/nextjs/app';\n *\n * export default function MyPage() {\n * return (\n * <ExposeRemoteComponent>\n * <h1>Hello from the remote component!</h1>\n * <p>This is a remote component that can be used in a host application.</p>\n * </ExposeRemoteComponent>\n * );\n * }\n * ```\n */\nexport async function ExposeRemoteComponent({\n name = DEFAULT_COMPONENT_NAME,\n children,\n}: ExposeRemoteComponentProps): Promise<React.ReactElement> {\n const { page, route } = getWorkStore();\n\n const manifest = resolveManifest(route);\n\n // Populate the global RSC manifest cache that Next.js reads during rendering\n const self = globalThis as typeof globalThis & {\n __RSC_MANIFEST?: Record<string, unknown>;\n __RSC_SERVER_MANIFEST?: Record<string, unknown>;\n };\n self.__RSC_MANIFEST = self.__RSC_MANIFEST || {};\n self.__RSC_MANIFEST[page] = self.__RSC_MANIFEST[page] || manifest;\n self.__RSC_SERVER_MANIFEST = self.__RSC_SERVER_MANIFEST || {};\n self.__RSC_SERVER_MANIFEST[page] =\n self.__RSC_SERVER_MANIFEST[page] || manifest;\n\n // get the client and SSR module mapping to be able to use client components in the remote component\n const ssrModuleMapping = { ...manifest?.ssrModuleMapping };\n\n // if the remote component is used in a hosting application, we need to mutate the module map to include the zone\n const clientModules = Object.fromEntries(\n Object.entries(manifest?.clientModules ?? {}).map(([key, value]) => {\n // append a prefix to each entry in the module map to include the zone of the remote component\n const remoteId = `[${PROJECT_ID}] ${value.id}`;\n ssrModuleMapping[remoteId] = ssrModuleMapping[value.id];\n // override the original id with the new remote id\n return [\n key,\n {\n ...value,\n id: remoteId,\n // prepend the current zone to the chunks to handle remote component chunk loading in Webpack\n // this is required to avoid loading the wrong chunk in the host application\n chunks: value.chunks.map((chunk) => `[${PROJECT_ID}] ${chunk}`),\n },\n ];\n }),\n );\n\n const { renderToReadableStream } = await importRSCServer();\n\n if (typeof renderToReadableStream !== 'function') {\n throw new RemoteComponentsError(\n 'No valid `renderToReadableStream()` function found. Do you have Next.js installed?',\n );\n }\n\n let error: Error | undefined;\n // render the wrapped content of this component (children) into an RSC stream\n const stream = renderToReadableStream(children, clientModules, {\n onError(e) {\n error = e;\n },\n });\n\n const data = [];\n const decoder = new TextDecoder();\n\n // convert the stream to an array for safe passing to the client\n for await (const chunk of stream as unknown as AsyncIterable<Uint8Array>) {\n data.push(decoder.decode(chunk));\n }\n\n const runtime = process.env.TURBOPACK ? 'turbopack' : 'webpack';\n const remoteComponentName = `${name}_${route.replace(/[/[\\].]/g, '_')}`;\n\n return (\n // wrap the remote component content into a div to know which part of the HTML belongs to the remote component\n <div\n {...{\n [DATA_BUNDLE]: PROJECT_ID,\n [DATA_ROUTE]: route,\n [DATA_RUNTIME]: runtime,\n [DATA_TYPE]: 'nextjs',\n }}\n id={`${remoteComponentName}${ID_SUFFIX_SSR}`}\n >\n <RemoteComponentSharedRemote name={remoteComponentName} />\n {typeof error !== 'undefined' ? (\n <>\n <template\n data-next-error-message={\n error instanceof Error ? error.message : String(error)\n }\n data-next-error-stack={\n error instanceof Error ? (error.stack ?? '') : ''\n }\n />\n <Suspense fallback={null}>{children}</Suspense>\n </>\n ) : (\n children\n )}\n {/* inject RSC flight data as <script> */}\n <RemoteComponentData data={data} name={remoteComponentName} />\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { RemoteComponentMetadata } from './internal/runtime/metadata.js';
|
|
2
|
+
import { RemoteScope } from './internal/runtime/turbopack/remote-scope.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Typed namespace for all remote-components runtime state.
|
|
6
|
+
*
|
|
7
|
+
* Consolidates scattered `globalThis` globals into a single object at
|
|
8
|
+
* `globalThis.__remote_components__`. Each property corresponds to a
|
|
9
|
+
* previously independent global — see inline `@see` tags for the original
|
|
10
|
+
* global name. Code that previously read from those globals still works
|
|
11
|
+
* because each migration writes through to both the namespace and the
|
|
12
|
+
* legacy global (pointing at the same underlying object).
|
|
13
|
+
*/
|
|
14
|
+
interface RemoteComponentsNamespace {
|
|
15
|
+
/** @see `__remote_component_scopes__` */
|
|
16
|
+
scopes: Map<string, RemoteScope>;
|
|
17
|
+
/** @see `__remote_components_turbopack_chunk_loader_promise__` */
|
|
18
|
+
chunkCache: Record<string, Promise<unknown>>;
|
|
19
|
+
/** @see `__remote_script_entrypoint_mount__` */
|
|
20
|
+
mountFns: Record<string, Set<MountOrUnmountFunction>>;
|
|
21
|
+
/** @see `__remote_script_entrypoint_unmount__` */
|
|
22
|
+
unmountFns: Record<string, Set<MountOrUnmountFunction>>;
|
|
23
|
+
/** @see `__remote_bundle_url__` */
|
|
24
|
+
bundleUrls: Record<string, string | URL>;
|
|
25
|
+
/** @see `__rc_module_registry__` */
|
|
26
|
+
moduleRegistry: Record<string, unknown>;
|
|
27
|
+
/** @see `__webpack_require_type__` */
|
|
28
|
+
dispatcherRuntime: string | undefined;
|
|
29
|
+
/** @see `__remote_component_host_shared_modules__` */
|
|
30
|
+
hostSharedModules: Record<string, () => Promise<unknown>>;
|
|
31
|
+
/** @see `__remote_next_css__` */
|
|
32
|
+
cssCache: Record<string, ChildNode[]>;
|
|
33
|
+
/** @see `__remote_components_shadowroot_*` */
|
|
34
|
+
shadowRoots: Record<string, ShadowRoot | null>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns the single shared `RemoteComponentsNamespace` instance, creating
|
|
38
|
+
* it on first access. The namespace lives at `globalThis.__remote_components__`
|
|
39
|
+
* so every module in the page shares the same state regardless of how many
|
|
40
|
+
* copies of the library are loaded.
|
|
41
|
+
*
|
|
42
|
+
* On first initialization this function also handles backward compatibility
|
|
43
|
+
* with legacy globals:
|
|
44
|
+
* 1. **Adopt**: if a legacy global already exists (written by older code before
|
|
45
|
+
* the namespace was created), its value becomes the initial namespace value.
|
|
46
|
+
* 2. **Alias**: legacy globals are assigned to point at the namespace's objects,
|
|
47
|
+
* so older code that reads the legacy global sees the same reference.
|
|
48
|
+
*/
|
|
49
|
+
declare function getNamespace(): RemoteComponentsNamespace;
|
|
50
|
+
|
|
51
|
+
interface GlobalScope {
|
|
52
|
+
/** Consolidated namespace — prefer `getNamespace()` over individual globals. */
|
|
53
|
+
__remote_components__?: RemoteComponentsNamespace;
|
|
54
|
+
__DISABLE_WEBPACK_EXEC__?: Record<string, boolean>;
|
|
55
|
+
__webpack_chunk_load__?: (chunkId: string, scriptBundle?: string) => Promise<unknown> | undefined;
|
|
56
|
+
__original_webpack_chunk_load__?: (chunkId: string, scriptBundle?: string) => Promise<unknown> | undefined;
|
|
57
|
+
__webpack_require__?: (id: string) => unknown;
|
|
58
|
+
__webpack_get_script_filename__?: (id: string) => string | null | undefined;
|
|
59
|
+
__original_webpack_require__?: (id: string) => unknown;
|
|
60
|
+
__remote_webpack_require__?: Record<string, ((remoteId: string | number) => unknown) & {
|
|
61
|
+
c?: Record<string | number, {
|
|
62
|
+
id: string;
|
|
63
|
+
parents: string[];
|
|
64
|
+
children: string[];
|
|
65
|
+
}>;
|
|
66
|
+
m?: Record<string | number, (module: {
|
|
67
|
+
exports: unknown;
|
|
68
|
+
}) => void>;
|
|
69
|
+
type?: 'turbopack' | 'webpack' | 'script';
|
|
70
|
+
}>;
|
|
71
|
+
/** @deprecated since 0.3.4 — use `getNamespace().dispatcherRuntime` instead. */
|
|
72
|
+
__webpack_require_type__?: RemoteComponentMetadata['runtime'];
|
|
73
|
+
/** @deprecated since 0.3.4 — use `getNamespace().bundleUrls` instead. */
|
|
74
|
+
__remote_bundle_url__?: Record<string, string | URL>;
|
|
75
|
+
/** @deprecated since 0.3.4 — use `getNamespace().chunkCache` instead. */
|
|
76
|
+
__remote_components_turbopack_chunk_loader_promise__?: Record<string, Promise<unknown>>;
|
|
77
|
+
/** @deprecated since 0.3.4 — use `getNamespace().scopes` instead. */
|
|
78
|
+
__remote_component_scopes__?: Map<string, unknown>;
|
|
79
|
+
[key: string]: unknown;
|
|
80
|
+
}
|
|
81
|
+
interface LoaderResult {
|
|
82
|
+
component: React.ReactNode;
|
|
83
|
+
error?: Error;
|
|
84
|
+
}
|
|
85
|
+
type RSCKey = `__remote_component_rsc_${string}__`;
|
|
86
|
+
type MountOrUnmountFunction = (el?: ShadowRoot | DocumentFragment | HTMLElement | HTMLCollection | null) => Promise<void> | void;
|
|
87
|
+
interface MountUnmountFunctions {
|
|
88
|
+
/** @deprecated since 0.3.4 — use `getNamespace().mountFns` instead. */
|
|
89
|
+
__remote_script_entrypoint_mount__?: Record<string, Set<MountOrUnmountFunction>>;
|
|
90
|
+
/** @deprecated since 0.3.4 — use `getNamespace().unmountFns` instead. */
|
|
91
|
+
__remote_script_entrypoint_unmount__?: Record<string, Set<MountOrUnmountFunction>>;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { GlobalScope as G, LoaderResult as L, MountOrUnmountFunction as M, RemoteComponentsNamespace as R, RSCKey as a, MountUnmountFunctions as b, getNamespace as g };
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/runtime/turbopack/webpack-runtime.ts"],"sourcesContent":["import type { InternalResolveClientUrl } from '#internal/host/server/types';\nimport {\n RUNTIME_TURBOPACK,\n RUNTIME_WEBPACK,\n type Runtime,\n} from '#internal/runtime/constants';\nimport { REMOTE_COMPONENT_REGEX } from '#internal/runtime/patterns';\nimport type { GlobalScope } from '#internal/runtime/types';\nimport { RemoteComponentsError } from '#internal/utils/error';\nimport { logDebug, logWarn } from '#internal/utils/logger';\nimport { createChunkDispatcher, loadChunkWithScope } from './chunk-loader';\nimport { requireModule } from './module';\nimport { createScope, getScope, registerScope } from './remote-scope';\nimport { initializeSharedModules } from './shared-modules';\n\n/**\n * Sets up webpack runtime environment for remote components.\n *\n * Creates a RemoteScope that encapsulates all per-remote state (base URL,\n * proxy callback, module cache, shared modules) and registers it in the\n * global scope registry. Global dispatchers (__webpack_require__,\n * __webpack_chunk_load__) are set once and route to the correct scope.\n *\n * @param runtime - The bundler runtime type ('webpack' or 'turbopack')\n * @param scripts - Initial script chunks to load for Turbopack runtime\n * @param url - Base URL for the remote component bundle\n * @param bundle - Bundle identifier (defaults to 'default')\n * @param shared - Host-provided shared modules (e.g., React)\n * @param remoteShared - Mapping of remote module IDs to shared module names\n */\nexport async function setupWebpackRuntime(\n runtime: Runtime,\n scripts: { src: string | null }[] = [],\n url: URL = new URL(location.href),\n bundle?: string,\n shared: Record<string, () => Promise<unknown>> = {},\n remoteShared: Record<string, string> = {},\n resolveClientUrl?: InternalResolveClientUrl,\n): Promise<void> {\n const self = globalThis as GlobalScope;\n const bundleName = bundle ?? 'default';\n\n // Create and register a scope for this remote\n const scope = createScope(bundleName, url, runtime, resolveClientUrl);\n registerScope(scope);\n\n // Still needed by patch-require.ts (webpack plugin that generates runtime\n // code as a string template — can't call getScope at build time) and the\n // HTML host (html/index.tsx writes this before setupWebpackRuntime runs).\n if (!self.__remote_bundle_url__) {\n self.__remote_bundle_url__ = {};\n }\n self.__remote_bundle_url__[bundleName] = url;\n // Also register under scopedName so webpack hosts (patch-require.ts) can\n // resolve cross-origin remotes whose bundle identifiers were rewritten.\n if (scope.scopedName !== bundleName) {\n self.__remote_bundle_url__[scope.scopedName] = url;\n }\n self.__webpack_get_script_filename__ = () => null;\n\n const willCreateDispatchers =\n typeof self.__webpack_require__ !== 'function' ||\n self.__webpack_require_type__ !== 'turbopack';\n\n if (willCreateDispatchers) {\n // preserve original webpack functions for fallback\n if (\n !self.__original_webpack_require__ &&\n !self.__original_webpack_chunk_load__\n ) {\n self.__original_webpack_chunk_load__ = self.__webpack_chunk_load__;\n self.__original_webpack_require__ = self.__webpack_require__;\n }\n\n self.__webpack_chunk_load__ = createChunkDispatcher();\n self.__webpack_require__ = createModuleDispatcher(runtime);\n self.__webpack_require_type__ = runtime;\n\n if (self.__remote_webpack_require__ && runtime === RUNTIME_TURBOPACK) {\n self.__remote_webpack_require__[bundleName] =\n self.__webpack_require__ as (remoteId: string | number) => unknown;\n self.__remote_webpack_require__[bundleName].type = 'turbopack';\n }\n }\n\n // Alias __remote_webpack_require__ under the scoped name so the module\n // dispatcher can find it when RSC data uses the rewritten bundle identifier.\n // For turbopack remotes the entry was just created above; for webpack remotes\n // it was populated by the remote's own scripts under the plain name.\n if (\n self.__remote_webpack_require__?.[bundleName] &&\n scope.scopedName !== bundleName\n ) {\n self.__remote_webpack_require__[scope.scopedName] =\n self.__remote_webpack_require__[bundleName];\n }\n\n // load all initial chunks directly via scope — no global dispatch needed\n if (runtime === RUNTIME_TURBOPACK) {\n const results = await Promise.allSettled(\n scripts.map((script) => {\n if (script.src) {\n return loadChunkWithScope(scope, script.src);\n }\n return Promise.resolve(undefined);\n }),\n );\n\n for (const result of results) {\n if (result.status === 'rejected') {\n logWarn(\n 'WebpackRuntime',\n `Initial chunk load failed: ${String(result.reason)}`,\n );\n }\n }\n }\n\n // initialize shared modules with core React dependencies\n const coreShared = {\n react: async () => (await import('react')).default,\n 'react-dom': async () => (await import('react-dom')).default,\n 'react/jsx-dev-runtime': async () =>\n (await import('react/jsx-dev-runtime')).default,\n 'react/jsx-runtime': async () =>\n (await import('react/jsx-runtime')).default,\n 'react-dom/client': async () => (await import('react-dom/client')).default,\n ...shared,\n };\n await initializeSharedModules(scope, coreShared, remoteShared);\n}\n\n/**\n * Creates the global module dispatcher for __webpack_require__.\n * Called by external code (React's RSC runtime) that doesn't have access to\n * a scope. Parses the module ID to find the correct scope and delegates\n * to scope-local module resolution.\n */\nfunction createModuleDispatcher(runtime: Runtime): (id: string) => unknown {\n return (id: string) => {\n const self = globalThis as GlobalScope;\n const { bundle, id: moduleId } = id.match(REMOTE_COMPONENT_REGEX)\n ?.groups ?? {\n bundle: 'default',\n id,\n };\n const bundleName = bundle ?? 'default';\n const remoteRuntime = self.__remote_webpack_require__?.[bundleName]\n ? self.__remote_webpack_require__[bundleName]?.type || 'webpack'\n : runtime;\n\n logDebug(\n 'ModuleDispatcher',\n `Resolving \"${id}\" (bundle: \"${bundleName}\", runtime: \"${remoteRuntime}\")`,\n );\n\n try {\n // for webpack remotes, use the pre-loaded require function\n if (remoteRuntime === RUNTIME_WEBPACK && bundle && moduleId) {\n return self.__remote_webpack_require__?.[bundle]?.(moduleId);\n }\n\n // Look up scope by parsed bundle name. Works with both the scoped\n // name (Next.js hosts with server-side rewriting) and the plain\n // bundle name (static/HTML hosts with unrewritten chunks).\n const scope = getScope(bundleName);\n if (scope) {\n return requireModule(scope, moduleId ?? id, id);\n }\n\n throw new Error(\n `Module \"${id}\" not found — no scope for bundle \"${bundleName}\".`,\n );\n } catch (requireError) {\n logWarn(\n 'ModuleDispatcher',\n `Module require failed: ${String(requireError)}`,\n );\n if (typeof self.__original_webpack_require__ !== 'function') {\n throw new RemoteComponentsError(\n `Module \"${id}\" not found in remote component bundle \"${bundleName}\".`,\n {\n cause: requireError instanceof Error ? requireError : undefined,\n },\n );\n }\n try {\n logDebug(\n 'ModuleDispatcher',\n 'Falling back to original webpack require',\n );\n return self.__original_webpack_require__(id);\n } catch (originalError) {\n throw new RemoteComponentsError(\n `Module \"${id}\" not found in remote component bundle \"${bundleName}\".`,\n { cause: originalError instanceof Error ? originalError : undefined },\n );\n }\n }\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { InternalResolveClientUrl } from '../url/resolve-client-url.js';
|
|
2
|
-
import { Runtime } from '../constants.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Sets up webpack runtime environment for remote components.
|
|
6
|
-
*
|
|
7
|
-
* Creates a RemoteScope that encapsulates all per-remote state (base URL,
|
|
8
|
-
* proxy callback, module cache, shared modules) and registers it in the
|
|
9
|
-
* global scope registry. Global dispatchers (__webpack_require__,
|
|
10
|
-
* __webpack_chunk_load__) are set once and route to the correct scope.
|
|
11
|
-
*
|
|
12
|
-
* @param runtime - The bundler runtime type ('webpack' or 'turbopack')
|
|
13
|
-
* @param scripts - Initial script chunks to load for Turbopack runtime
|
|
14
|
-
* @param url - Base URL for the remote component bundle
|
|
15
|
-
* @param bundle - Bundle identifier (defaults to 'default')
|
|
16
|
-
* @param shared - Host-provided shared modules (e.g., React)
|
|
17
|
-
* @param remoteShared - Mapping of remote module IDs to shared module names
|
|
18
|
-
*/
|
|
19
|
-
declare function setupWebpackRuntime(runtime: Runtime, scripts?: {
|
|
20
|
-
src: string | null;
|
|
21
|
-
}[], url?: URL, bundle?: string, shared?: Record<string, () => Promise<unknown>>, remoteShared?: Record<string, string>, resolveClientUrl?: InternalResolveClientUrl): Promise<void>;
|
|
22
|
-
|
|
23
|
-
export { setupWebpackRuntime };
|