remote-components 0.4.10 → 0.4.12
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/{chunk-GR5FN73U.js → chunk-24LEEDHP.js} +2 -2
- package/dist/{chunk-VFK4HGZT.js → chunk-BEGVH64U.js} +13 -4
- package/dist/chunk-BEGVH64U.js.map +1 -0
- package/dist/{chunk-RHRDUJ3K.js → chunk-CLO56ON2.js} +2 -2
- package/dist/{chunk-HZP4FWPG.cjs → chunk-HXCW3WDT.cjs} +8 -8
- package/dist/{chunk-N6AJM72A.js → chunk-RZGFQTX6.js} +3 -3
- package/dist/{chunk-PCHSF5LH.cjs → chunk-SULMNRMJ.cjs} +13 -4
- package/dist/chunk-SULMNRMJ.cjs.map +1 -0
- package/dist/{chunk-RZ224NSH.cjs → chunk-TGE3K3TR.cjs} +6 -6
- package/dist/{chunk-OSSMJQFE.cjs → chunk-YSJ4FKGI.cjs} +10 -10
- package/dist/host/html.cjs +64 -48
- package/dist/host/html.cjs.map +1 -1
- package/dist/host/html.js +48 -32
- package/dist/host/html.js.map +1 -1
- package/dist/host/nextjs/app/client-only.cjs +6 -6
- package/dist/host/nextjs/app/client-only.js +4 -4
- package/dist/host/react.cjs +5 -5
- package/dist/host/react.js +4 -4
- package/dist/internal/host/shared/provider.cjs +10 -1
- package/dist/internal/host/shared/provider.cjs.map +1 -1
- package/dist/internal/host/shared/provider.js +10 -1
- package/dist/internal/host/shared/provider.js.map +1 -1
- package/dist/internal/runtime/turbopack/shared-modules.cjs +2 -2
- package/dist/internal/runtime/turbopack/shared-modules.cjs.map +1 -1
- package/dist/internal/runtime/turbopack/shared-modules.js +2 -2
- package/dist/internal/runtime/turbopack/shared-modules.js.map +1 -1
- package/dist/{turbopack-6BSS3SYN.js → turbopack-43N2UJNN.js} +3 -3
- package/dist/{turbopack-UMJ7SLJL.cjs → turbopack-5VGMYUL4.cjs} +8 -8
- package/dist/{webpack-65BVWX2U.cjs → webpack-FSN5UBA2.cjs} +6 -6
- package/dist/{webpack-4QYGIVE6.js → webpack-LXE2UWTA.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-PCHSF5LH.cjs.map +0 -1
- package/dist/chunk-VFK4HGZT.js.map +0 -1
- /package/dist/{chunk-GR5FN73U.js.map → chunk-24LEEDHP.js.map} +0 -0
- /package/dist/{chunk-RHRDUJ3K.js.map → chunk-CLO56ON2.js.map} +0 -0
- /package/dist/{chunk-HZP4FWPG.cjs.map → chunk-HXCW3WDT.cjs.map} +0 -0
- /package/dist/{chunk-N6AJM72A.js.map → chunk-RZGFQTX6.js.map} +0 -0
- /package/dist/{chunk-RZ224NSH.cjs.map → chunk-TGE3K3TR.cjs.map} +0 -0
- /package/dist/{chunk-OSSMJQFE.cjs.map → chunk-YSJ4FKGI.cjs.map} +0 -0
- /package/dist/{turbopack-6BSS3SYN.js.map → turbopack-43N2UJNN.js.map} +0 -0
- /package/dist/{turbopack-UMJ7SLJL.cjs.map → turbopack-5VGMYUL4.cjs.map} +0 -0
- /package/dist/{webpack-65BVWX2U.cjs.map → webpack-FSN5UBA2.cjs.map} +0 -0
- /package/dist/{webpack-4QYGIVE6.js.map → webpack-LXE2UWTA.js.map} +0 -0
package/dist/host/html.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/host/html/index.tsx","../../src/host/html/attach-styles.ts","../../src/host/html/runtime/index.ts"],"sourcesContent":["import { startTransition, useLayoutEffect } from 'react';\nimport { hydrateRoot } from 'react-dom/client';\nimport { fetchWithHooks } from '#internal/host/server/fetch-with-hooks';\nimport { getClientOrServerUrl } from '#internal/host/server/get-client-or-server-url';\nimport type {\n ConsumeClientConfig,\n ConsumeServerConfig,\n} from '#internal/host/shared/config';\nimport {\n type LifecycleEmitter,\n makeEventEmitter,\n} from '#internal/host/shared/lifecycle';\nimport { preparePipeline } from '#internal/host/shared/pipeline';\nimport type { HostState } from '#internal/host/shared/state';\nimport { createHostState } from '#internal/host/shared/state';\nimport { resolveNameFromSrc } from '#internal/host/utils/resolve-name-from-src';\nimport {\n DEFAULT_BUNDLE_NAME,\n DEFAULT_COMPONENT_NAME,\n} from '#internal/runtime/constants';\nimport { getNamespace } from '#internal/runtime/namespace';\nimport { createRSCStream } from '#internal/runtime/rsc';\nimport type { RSCKey } from '#internal/runtime/types';\nimport { bindResolveClientUrl } from '#internal/runtime/url/default-resolve-client-url';\nimport { escapeString } from '#internal/utils';\nimport { isAbortError } from '#internal/utils/abort';\nimport {\n errorFromFailedFetch,\n RemoteComponentsError,\n} from '#internal/utils/error';\nimport { logError } from '#internal/utils/logger';\nimport { attachStyles } from './attach-styles';\nimport { getRuntime, type Runtime } from './runtime';\n\nif (typeof HTMLElement !== 'undefined') {\n /**\n * `<remote-component>` custom element — the HTML host implementation.\n *\n * Implements {@link ConsumeClientConfig}\n * via typed property accessors that reflect to/from DOM attributes.\n *\n * {@link ConsumeLifecycleCallbacks} are dispatched as DOM events:\n * `beforeload`, `load`, `error`, `change`.\n */\n class RemoteComponent extends HTMLElement implements ConsumeClientConfig {\n name: string = DEFAULT_COMPONENT_NAME;\n bundle: string = DEFAULT_BUNDLE_NAME;\n fallbackSlot?: HTMLSlotElement;\n __next: HTMLDivElement | null = null;\n fouc: HTMLStyleElement | null = null;\n hostState: HostState = createHostState();\n root?: ShadowRoot | null = null;\n reactRoot?: ReturnType<typeof hydrateRoot>;\n emitter: LifecycleEmitter = makeEventEmitter(this);\n onRequest?: ConsumeServerConfig['onRequest'];\n onResponse?: ConsumeServerConfig['onResponse'];\n resolveClientUrl?: ConsumeClientConfig['resolveClientUrl'];\n\n // -- ConsumeServerConfig property accessors (attribute-reflected) --\n\n get src(): string | URL | undefined {\n return this.getAttribute('src') ?? undefined;\n }\n\n set src(value: string | URL | undefined) {\n if (value == null) {\n this.removeAttribute('src');\n } else {\n this.setAttribute('src', String(value));\n }\n }\n\n /** Always `true` — the HTML host always isolates via Shadow DOM. */\n get isolate(): boolean {\n return true;\n }\n\n get mode(): 'open' | 'closed' | undefined {\n const attr = this.getAttribute('mode');\n return attr === 'closed' ? 'closed' : 'open';\n }\n\n set mode(value: 'open' | 'closed' | undefined) {\n if (value) {\n this.setAttribute('mode', value);\n }\n }\n\n get reset(): boolean | undefined {\n return this.getAttribute('reset') !== null;\n }\n\n set reset(value: boolean | undefined) {\n if (value) {\n this.setAttribute('reset', '');\n } else {\n this.removeAttribute('reset');\n }\n }\n\n get credentials(): RequestCredentials | undefined {\n return (this.getAttribute('credentials') ||\n 'same-origin') as RequestCredentials;\n }\n\n set credentials(value: RequestCredentials | undefined) {\n if (value) {\n this.setAttribute('credentials', value);\n } else {\n this.removeAttribute('credentials');\n }\n }\n\n static get observedAttributes() {\n return ['src', 'name', 'mode'];\n }\n\n attributeChangedCallback(name: string, oldValue: string, newValue: string) {\n if ((name === 'src' || name === 'name') && oldValue !== newValue) {\n if (this.src) {\n this.load().catch((e) => {\n // AbortError is expected when loading is cancelled - don't log or dispatch\n if (isAbortError(e)) {\n return;\n }\n logError('HtmlHost', 'Error loading remote component.', e);\n this.emitter.error(e, this.src);\n this.hostState.stage = 'error';\n });\n }\n } else if (name === 'mode' && oldValue !== newValue && this.root) {\n // changing the shadow DOM mode is not supported\n // we need to recreate the shadow DOM and reload the component\n const newRoot = this.attachShadow({\n mode: newValue === 'closed' ? 'closed' : 'open',\n });\n // move all existing children to the new shadow root\n Array.from(this.root.children).forEach((child) => {\n newRoot.appendChild(child);\n });\n this.root = newRoot;\n // reload the remote component to apply the new shadow DOM\n this.load().catch((e) => {\n // AbortError is expected when loading is cancelled - don't log or dispatch\n if (isAbortError(e)) {\n return;\n }\n logError('HtmlHost', 'Error reloading remote component.', e);\n this.emitter.error(e, this.src);\n });\n }\n }\n\n async load() {\n // wait for the current call stack to finish\n await new Promise((resolve) => {\n (typeof queueMicrotask === 'function'\n ? queueMicrotask\n : requestAnimationFrame)(() => {\n resolve(undefined);\n });\n });\n\n // Abort any in-progress load so the latest src always wins.\n if (this.hostState.stage === 'loading') {\n this.hostState.abortController?.abort();\n this.hostState.stage = 'idle';\n // The aborted load may have already appended partial content to the shadow DOM\n // (styles, component children) before reaching an isCurrentLoad() check.\n // Clear it now so the new load starts from a clean state. Skip this when a\n // React root exists — that means a previous load completed successfully and\n // we'll take the startTransition re-render path instead.\n if (this.root && !this.reactRoot) {\n this.root.innerHTML = '';\n this.fouc = null;\n this.fallbackSlot = document.createElement('slot');\n this.root.appendChild(this.fallbackSlot);\n }\n }\n\n if (!this.root) {\n this.root = this.attachShadow({\n mode: this.mode === 'closed' ? 'closed' : 'open',\n });\n\n // create a slot element to allow the remote component to use the default slot\n this.fallbackSlot = document.createElement('slot');\n this.root.appendChild(this.fallbackSlot);\n }\n\n this.name = this.getAttribute('name') || this.name;\n\n this.hostState.stage = 'loading';\n const src = this.src;\n\n // Create AbortController for this load operation\n this.hostState.abortController = new AbortController();\n const signal = this.hostState.abortController.signal;\n\n // Returns true if this is still the active load — the signal hasn't been\n // aborted by a newer load() call, and the src hasn't changed in the meantime.\n // Checking the signal (not just the src) handles the case where the user\n // cycles back to the same src (e.g. styled → basic → styled): both loads\n // share the same src string, so a src-only check would pass for both,\n // causing double renders.\n const isCurrentLoad = () => !signal.aborted && this.src === src;\n\n // Resets stage to 'idle' for expected cancellations (AbortError). Real\n // errors are thrown and caught by attributeChangedCallback which sets\n // stage to 'error'. Only resets if no newer load() has superseded this\n // one — a new load replaces the abortController so the signal comparison\n // fails, preventing us from clobbering the new load's stage.\n const abandonLoad = () => {\n if (\n this.hostState.abortController?.signal === signal &&\n this.hostState.stage === 'loading'\n ) {\n this.hostState.stage = 'idle';\n }\n };\n\n this.emitter.beforeLoad(src ?? '');\n\n const remoteComponentChild =\n this.querySelector('div#__REMOTE_COMPONENT__') ||\n this.querySelector('div[data-bundle][data-route]');\n\n if (!src && !remoteComponentChild) {\n throw new RemoteComponentsError('\"src\" attribute is required');\n }\n\n let url: URL | null = null;\n let html = this.innerHTML;\n\n if (src) {\n url = getClientOrServerUrl(src, window.location.href);\n this.name = resolveNameFromSrc(src, this.name);\n }\n\n const resolveClientUrl = url\n ? bindResolveClientUrl(this.resolveClientUrl, url.href)\n : undefined;\n\n if (!remoteComponentChild && url) {\n // fetch the remote component\n const fetchInit = {\n credentials: this.credentials || 'same-origin',\n } as RequestInit;\n\n const resolvedUrl = new URL(\n resolveClientUrl?.(url.href) ?? url.href,\n window.location.href,\n );\n let res: Response;\n try {\n res = await fetchWithHooks(resolvedUrl, fetchInit, {\n onRequest: this.onRequest,\n onResponse: this.onResponse,\n abortController: this.hostState.abortController,\n });\n } catch (e) {\n if (isAbortError(e)) {\n return abandonLoad();\n }\n throw e;\n }\n\n if (!res || !res.ok) {\n throw await errorFromFailedFetch(url.href, resolvedUrl, res);\n }\n\n // get the full HTML content as a string - race with abort signal\n try {\n html = await res.text();\n } catch (e) {\n if (isAbortError(e)) {\n return abandonLoad();\n }\n throw e;\n }\n if (!isCurrentLoad()) {\n return abandonLoad();\n }\n }\n\n const effectiveUrl = url ?? new URL(window.location.href);\n const { doc, parsed } = preparePipeline({\n html,\n name: this.name,\n url: effectiveUrl,\n shared: {},\n resolveClientUrl,\n });\n const {\n component,\n name: resolvedName,\n isRemoteComponent,\n metadata: parsedMetadata,\n nextData,\n rsc,\n remoteShared,\n } = parsed;\n\n // when using a Next.js Pages Router remote application in development mode\n // we hide the remote component to prevent flickering\n // until the CSS is loaded for the remote component\n if (nextData && nextData.buildId === 'development' && !this.reactRoot) {\n this.fouc = document.createElement('style');\n this.fouc.textContent = `:host { display: none; }`;\n this.root.appendChild(this.fouc);\n }\n\n this.name = resolvedName;\n this.bundle = parsedMetadata.bundle;\n\n if (url) {\n getNamespace().bundleUrls[this.bundle] = url;\n }\n\n // add remote component metadata information at the custom element\n const metadataEl = document.createElement('script');\n metadataEl.type = 'application/json';\n metadataEl.setAttribute('data-remote-component', '');\n const metadataObj = {\n name: this.name,\n bundle: this.bundle,\n route: parsedMetadata.route,\n runtime: parsedMetadata.runtime,\n };\n metadataEl.textContent = JSON.stringify(metadataObj);\n\n if (\n this.previousElementSibling?.getAttribute('data-remote-component') !==\n null\n ) {\n this.previousElementSibling?.remove();\n }\n this.parentElement?.insertBefore(metadataEl, this);\n\n if (this.hostState.prevIsRemoteComponent) {\n if (this.hostState.prevUrl) {\n const prevUrl = this.hostState.prevUrl;\n const nsUnmount = getNamespace();\n if (nsUnmount.unmountFns[prevUrl.href]) {\n // call unmount() for all registered unmount functions for the previous remote component\n await Promise.all(\n Array.from(nsUnmount.unmountFns[prevUrl.href] ?? []).map(\n async (unmount) => {\n try {\n await unmount(this.root);\n } catch (e) {\n logError(\n 'HtmlHost',\n `Error while calling unmount() for Remote Component from ${prevUrl.href}.`,\n e,\n );\n }\n },\n ),\n );\n if (!isCurrentLoad()) {\n return abandonLoad();\n }\n }\n }\n this.root.innerHTML = '';\n }\n // Dispatch change event if this is not the first load\n if (this.hostState.prevSrc !== undefined) {\n this.emitter.change({\n previousSrc: this.hostState.prevSrc ?? null,\n nextSrc: src ?? null,\n previousName: this.hostState.prevName,\n nextName: this.name,\n });\n }\n\n this.hostState.prevUrl = effectiveUrl;\n this.hostState.prevIsRemoteComponent = isRemoteComponent;\n this.hostState.prevSrc = src;\n this.hostState.prevName = this.name;\n\n // store the original loading content of the custom element\n // this is required to remove the loading content after the remote component is loaded\n const removable = Array.from(this.childNodes);\n\n // reference to all link elements in the remote component\n const links = doc.querySelectorAll<HTMLLinkElement>('link[href]');\n\n const remoteComponentSrc = this.src ? String(this.src) : null;\n\n // Bound function for attaching styles — used both initially and in React effects\n const doAttachStyles = () =>\n attachStyles({\n doc,\n component,\n links,\n signal: undefined, // Effects run after load, no abort needed\n baseUrl: url?.href,\n remoteComponentSrc,\n root: this.root ?? null,\n resolveClientUrl,\n });\n\n if (!this.reactRoot) {\n // ensure all styles are loaded before hydrating to prevent FOUC\n await attachStyles({\n doc,\n component,\n links,\n signal,\n baseUrl: url?.href,\n remoteComponentSrc,\n root: this.root,\n resolveClientUrl,\n });\n if (!isCurrentLoad()) {\n return abandonLoad();\n }\n }\n\n if (!this.reactRoot) {\n // attach the remote component content to the shadow DOM\n Array.from(component.children).forEach((el) => {\n if (!isRemoteComponent && el.tagName.toLowerCase() === 'script') {\n const newScript = document.createElement('script');\n // copy all attributes\n for (const attr of el.attributes) {\n if (attr.name === 'src') {\n const absoluteSrc = new URL(\n attr.value,\n url ?? window.location.origin,\n ).href;\n newScript.setAttribute(\n attr.name,\n resolveClientUrl?.(absoluteSrc) ?? absoluteSrc,\n );\n } else {\n newScript.setAttribute(attr.name, attr.value);\n }\n }\n newScript.textContent = el.textContent;\n if (remoteComponentSrc) {\n newScript.setAttribute(\n 'data-remote-component-src',\n remoteComponentSrc,\n );\n }\n this.root?.appendChild(newScript);\n } else {\n const newEl = el.cloneNode(true) as HTMLElement;\n for (const attr of el.attributes) {\n if (attr.name.startsWith('on')) {\n newEl.setAttribute(attr.name, attr.value);\n }\n }\n this.root?.appendChild(newEl);\n }\n });\n }\n\n // clear the loading content of the shadow DOM root\n for (const el of removable) {\n el.parentElement?.removeChild(el);\n }\n this.fallbackSlot?.remove();\n\n // function to apply the reset styles to the shadow DOM\n const applyReset = () => {\n if (\n this.reset &&\n !this.root?.querySelector('link[data-remote-components-reset]')\n ) {\n // all initial styles to reset inherited styles leaking from the host page\n const allInitial = document.createElement('link');\n allInitial.setAttribute('data-remote-components-reset', '');\n const css = `:host { all: initial; }`;\n const allInitialHref = URL.createObjectURL(\n new Blob([css], { type: 'text/css' }),\n );\n allInitial.href = allInitialHref;\n allInitial.rel = 'stylesheet';\n // we need to revoke the object URL after the stylesheet is loaded to free up memory\n allInitial.onload = () => {\n URL.revokeObjectURL(allInitialHref);\n allInitial.removeAttribute('onload');\n };\n allInitial.onerror = () => {\n URL.revokeObjectURL(allInitialHref);\n allInitial.removeAttribute('onload');\n };\n this.root?.prepend(allInitial);\n } else if (\n !this.reset &&\n this.root?.querySelector('link[data-remote-components-reset]')\n ) {\n this.root\n .querySelector('link[data-remote-components-reset]')\n ?.remove();\n }\n };\n\n // apply the reset styles if required and not already applied\n if (!this.reactRoot) {\n applyReset();\n }\n\n const {\n self,\n createFromReadableStream,\n nextClientPagesLoader,\n preloadScripts,\n } = await getRuntime(\n metadataObj.runtime as Runtime,\n effectiveUrl,\n this.bundle,\n {\n react: async () => (await import('react')).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': async () => (await import('react-dom')).default,\n 'react-dom/client': async () =>\n (await import('react-dom/client')).default,\n },\n remoteShared,\n resolveClientUrl,\n );\n if (!isCurrentLoad()) {\n return abandonLoad();\n }\n\n const scripts = isRemoteComponent\n ? component.querySelectorAll<HTMLScriptElement>('script')\n : doc.querySelectorAll<HTMLScriptElement>(\n 'script[src],script[data-src],script[data-remote-component-entrypoint]',\n );\n if (!url) {\n url = new URL(\n component.getAttribute('data-route') ?? '/',\n window.location.href,\n );\n }\n\n await preloadScripts(Array.from(scripts), url, this.bundle, this.name);\n if (!isCurrentLoad()) {\n return abandonLoad();\n }\n\n // remove all script elements from the shadow DOM to prevent re-execution of scripts\n if (isRemoteComponent) {\n Array.from(component.children).forEach((child) => {\n if (child.tagName === 'SCRIPT') {\n child.remove();\n }\n });\n }\n\n // cleanup previous remote component instances when a new remote component is loaded\n // this is required when the src attribute is changed to load a new remote component\n const doCleanup = () => {\n if (this.root && remoteComponentSrc) {\n const selector = `[data-remote-component-src]:not([data-remote-component-src=\"${remoteComponentSrc}\"])`;\n const prevCleanup = [\n ...this.root.querySelectorAll(selector),\n ...document.body.querySelectorAll(selector),\n ] as HTMLElement[];\n\n if (prevCleanup.length > 0) {\n prevCleanup.forEach((prev) => {\n prev.remove();\n });\n }\n }\n };\n\n // using RSC hydration if the RSC flight data is available\n if (rsc) {\n // remove the RSC flight data script element\n rsc.parentElement?.removeChild(rsc);\n\n // reload the RSC flight data script to eval it's content\n const rscName = `__remote_component_rsc_${escapeString(\n url.href,\n )}_${escapeString(this.name)}`;\n const rscClone = document.createElement('script');\n rscClone.id = `${rscName}_rsc`;\n rscClone.textContent =\n rsc.textContent?.replace(\n new RegExp(`self\\\\[\"${this.name}\"\\\\]`, 'g'),\n `self[\"${rscName}\"]`,\n ) ?? '';\n document.body.appendChild(rscClone);\n\n let cache: React.ReactNode;\n // React component to convert the RSC flight data into a React component\n const RemoteComponentFromReadableStream = ({\n name,\n initial,\n }: {\n name: string;\n initial: boolean;\n }) => {\n // convert the RSC flight data array into a ReadableStream\n // get the RSC flight data from the global scope\n // the RSC flight data is stored in an array\n // fallback to an empty RSC payload if the data is not found\n const stream = createRSCStream(\n rscName,\n self[rscName as RSCKey] ?? [`0:[null]\\n`],\n );\n const Component =\n cache ??\n // cache the component to avoid reloading the RSC flight data\n (cache = createFromReadableStream(stream) as React.ReactNode);\n\n useLayoutEffect(() => {\n // clear the RSC flight data from the global scope to free up memory\n if (self[name as RSCKey]) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete self[name as RSCKey];\n }\n const rscScript = document.getElementById(`${name}_rsc`);\n if (rscScript) {\n rscScript.remove();\n }\n\n doCleanup();\n applyReset();\n if (!initial) {\n doAttachStyles().catch((e: unknown) => {\n logError('HtmlHost', 'Error attaching styles.', e);\n });\n }\n if (isCurrentLoad()) {\n this.hostState.stage = 'loaded';\n }\n\n this.emitter.load(this.src ?? '');\n }, [initial, name]);\n\n // React can handle the component reference and will wait for the component to be ready\n return Component;\n };\n\n // when we already have a React root, we just need to render the new component\n if (this.reactRoot) {\n const root = this.reactRoot;\n startTransition(() => {\n root.render(\n <RemoteComponentFromReadableStream\n initial={false}\n name={this.name}\n />,\n );\n });\n return;\n }\n\n // hydrate the remote component using the RSC flight data\n this.reactRoot = hydrateRoot(\n // hydrateRoot expects a document or element, but it works for the shadow DOM too\n // @ts-expect-error support for shadow DOM\n this.root,\n <RemoteComponentFromReadableStream initial name={this.name} />,\n );\n } else if (nextData) {\n // using Next.js client pages loader if the Next.js hydration data is available\n const { Component, App } = nextClientPagesLoader(\n this.bundle,\n nextData.page ?? '/',\n this.root,\n );\n\n // if we have the component, we can hydrate it\n if (Component) {\n const RemoteComponentFromNext = ((\n NextApp: ReturnType<typeof nextClientPagesLoader>['App'],\n NextComponent: NonNullable<\n ReturnType<typeof nextClientPagesLoader>['Component']\n >,\n remoteComponent = this,\n ) =>\n function RemoteComponentNext({ initial }: { initial: boolean }) {\n useLayoutEffect(() => {\n doCleanup();\n if (!initial) {\n applyReset();\n doAttachStyles().catch((e: unknown) => {\n logError('HtmlHost', 'Error attaching styles.', e);\n });\n }\n if (isCurrentLoad()) {\n remoteComponent.hostState.stage = 'loaded';\n }\n\n remoteComponent.emitter.load(remoteComponent.src ?? '');\n }, [initial, remoteComponent]);\n\n return NextApp ? (\n <NextApp Component={NextComponent} {...nextData.props} />\n ) : (\n <NextComponent {...nextData.props} />\n );\n })(App, Component, this);\n\n // when we already have a React root, we just need to render the new component\n if (this.reactRoot) {\n const root = this.reactRoot;\n startTransition(() => {\n root.render(<RemoteComponentFromNext initial={false} />);\n doCleanup();\n if (isCurrentLoad()) {\n this.hostState.stage = 'loaded';\n }\n });\n return;\n }\n\n // hydrate the remote component using the Next.js pages router\n this.reactRoot = hydrateRoot(\n // hydrateRoot expects a document or element, but it works for the shadow DOM too\n // @ts-expect-error support for shadow DOM\n this.root,\n <RemoteComponentFromNext initial />,\n );\n }\n\n // remove the FOUC workaround style element to show the remote component\n // this is only for development mode\n if (this.fouc) {\n this.root.removeChild(this.fouc);\n }\n } else if (getNamespace().mountFns[url.href]) {\n // using script entrypoint when no RSC or Next.js data is available\n await Promise.all(\n Array.from(getNamespace().mountFns[url.href] ?? []).map(\n async (mount) => {\n try {\n await mount(this.root);\n } catch (e) {\n logError(\n 'HtmlHost',\n `Error while calling mount() for Remote Component from ${url.href}.`,\n e,\n );\n }\n },\n ),\n );\n\n this.emitter.load(this.src ?? '');\n } else {\n this.emitter.load(this.src ?? '');\n }\n\n if (isCurrentLoad()) {\n this.hostState.stage = 'loaded';\n }\n }\n }\n\n // register the custom element\n customElements.define('remote-component', RemoteComponent);\n}\n\nexport function registerSharedModules(\n modules: Record<string, () => Promise<unknown>> = {},\n) {\n const ns = getNamespace();\n Object.entries(modules).forEach(([key, value]) => {\n ns.hostSharedModules[key] = value;\n });\n}\n","import type { InternalResolveClientUrl } from '#internal/host/server/types';\nimport { RemoteComponentsError } from '#internal/utils/error';\n\ninterface AttachStylesOptions {\n /** The parsed document containing link and style elements */\n doc: Document;\n /** The component element to check if links are already contained */\n component: Element;\n /** Links from the document head */\n links: NodeListOf<HTMLLinkElement>;\n /** AbortSignal to cancel loading */\n signal: AbortSignal | undefined;\n /** Base URL for resolving relative hrefs */\n baseUrl: string | undefined;\n /** Source URL to set as data attribute */\n remoteComponentSrc: string | null;\n /** Root element to append styles to (ShadowRoot or Element) */\n root: ShadowRoot | Element | null;\n /** Callback to transform asset URLs before loading */\n resolveClientUrl?: InternalResolveClientUrl;\n}\n\n/**\n * Attaches link and style elements from a remote component document to the shadow root.\n * Handles abort signals efficiently with a single shared listener for all links.\n *\n * @throws DOMException with name 'AbortError' if signal is aborted\n * @throws RemoteComponentsError if a stylesheet fails to load\n */\nexport async function attachStyles({\n doc,\n component,\n links,\n signal,\n baseUrl,\n remoteComponentSrc,\n root,\n resolveClientUrl,\n}: AttachStylesOptions): Promise<void> {\n // Track appended links for cleanup on abort\n const appendedLinks: HTMLLinkElement[] = [];\n\n // Single shared abort promise - avoids N listeners for N links\n let abortReject: ((error: DOMException) => void) | null = null;\n const abortPromise = new Promise<never>((_, reject) => {\n abortReject = reject;\n });\n const abortHandler = () => {\n // Clean up all pending links on abort\n for (const link of appendedLinks) {\n link.onload = null;\n link.onerror = null;\n link.remove();\n }\n abortReject?.(new DOMException('Aborted', 'AbortError'));\n };\n signal?.addEventListener('abort', abortHandler, { once: true });\n\n try {\n // Attach each link element to the shadow DOM to load the styles\n await Promise.all(\n Array.from(links)\n .filter((link) => !component.contains(link))\n .map((link) => {\n const newLink = document.createElement('link');\n appendedLinks.push(newLink);\n\n const loadPromise = new Promise<void>((resolve, reject) => {\n if (link.rel === 'stylesheet') {\n // TODO: needs to be cancellable with a singular listener for the abort signal https://linear.app/vercel/issue/MFES-1253/handle-abortcontroller-clean-up-scenarios\n newLink.onload = () => resolve();\n newLink.onerror = () =>\n reject(\n new RemoteComponentsError(\n `Failed to load <link href=\"${link.href}\"> for Remote Component. Check the URL is correct.`,\n ),\n );\n } else {\n resolve();\n }\n });\n\n for (const attr of link.attributes) {\n if (attr.name === 'href') {\n const absoluteHref = new URL(\n attr.value,\n baseUrl ?? location.origin,\n ).href;\n newLink.setAttribute(\n attr.name,\n resolveClientUrl?.(absoluteHref) ?? absoluteHref,\n );\n } else {\n newLink.setAttribute(attr.name, attr.value);\n }\n }\n\n if (remoteComponentSrc) {\n newLink.setAttribute(\n 'data-remote-component-src',\n remoteComponentSrc,\n );\n }\n\n // TODO: needs to be cancellable with a singular listener for the abort signal https://linear.app/vercel/issue/MFES-1253/handle-abortcontroller-clean-up-scenarios\n root?.appendChild(newLink);\n\n // Race each link load against the shared abort promise\n return Promise.race([loadPromise, abortPromise]);\n }),\n );\n } finally {\n signal?.removeEventListener('abort', abortHandler);\n }\n\n // Attach inline styles from the document head\n const styles = doc.querySelectorAll<HTMLStyleElement>('style');\n for (const style of styles) {\n if (style.parentElement?.tagName.toLowerCase() === 'head') {\n const newStyle = document.createElement('style');\n newStyle.textContent = style.textContent;\n\n if (remoteComponentSrc) {\n newStyle.setAttribute('data-remote-component-src', remoteComponentSrc);\n }\n\n root?.appendChild(newStyle);\n }\n }\n}\n","import type { InternalResolveClientUrl } from '#internal/host/server/types';\nimport type { RemoteSharedModules } from '#internal/host/shared/shared-broker';\nimport { RemoteComponentsError } from '#internal/utils/error';\n\nexport type Runtime = 'webpack' | 'turbopack' | 'script' | 'unknown';\n\nexport async function getRuntime(\n type: Runtime,\n url: URL,\n bundle: string,\n shared?: Record<string, () => Promise<unknown>>,\n remoteShared?: RemoteSharedModules,\n resolveClientUrl?: InternalResolveClientUrl,\n) {\n // minimally mock process.env for browser environments\n if (typeof globalThis.process === 'undefined') {\n globalThis.process = {\n env: {},\n } as NodeJS.Process;\n }\n\n if (type === 'webpack') {\n const { webpackRuntime } = await import(`./webpack`);\n return webpackRuntime(bundle, shared, remoteShared, resolveClientUrl);\n } else if (type === 'turbopack') {\n const { turbopackRuntime } = await import(`./turbopack`);\n return turbopackRuntime(\n url,\n bundle,\n shared,\n remoteShared,\n resolveClientUrl,\n );\n } else if (type === 'script') {\n const { scriptRuntime } = await import(`./script`);\n return scriptRuntime(resolveClientUrl);\n }\n throw new RemoteComponentsError(\n `Remote Components runtime \"${type}\" is not supported. Supported runtimes are \"webpack\", \"turbopack\", and \"script\".`,\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/host/html/index.tsx","../../src/host/html/attach-styles.ts","../../src/host/html/runtime/index.ts"],"sourcesContent":["import { startTransition, useLayoutEffect } from 'react';\nimport { hydrateRoot } from 'react-dom/client';\nimport { fetchWithHooks } from '#internal/host/server/fetch-with-hooks';\nimport { getClientOrServerUrl } from '#internal/host/server/get-client-or-server-url';\nimport type {\n ConsumeClientConfig,\n ConsumeServerConfig,\n} from '#internal/host/shared/config';\nimport {\n type LifecycleEmitter,\n makeEventEmitter,\n} from '#internal/host/shared/lifecycle';\nimport { preparePipeline } from '#internal/host/shared/pipeline';\nimport type { HostState } from '#internal/host/shared/state';\nimport { createHostState } from '#internal/host/shared/state';\nimport { resolveNameFromSrc } from '#internal/host/utils/resolve-name-from-src';\nimport {\n DEFAULT_BUNDLE_NAME,\n DEFAULT_COMPONENT_NAME,\n} from '#internal/runtime/constants';\nimport { getNamespace } from '#internal/runtime/namespace';\nimport { createRSCStream } from '#internal/runtime/rsc';\nimport type { RSCKey } from '#internal/runtime/types';\nimport { bindResolveClientUrl } from '#internal/runtime/url/default-resolve-client-url';\nimport { escapeString } from '#internal/utils';\nimport { isAbortError } from '#internal/utils/abort';\nimport {\n errorFromFailedFetch,\n RemoteComponentsError,\n} from '#internal/utils/error';\nimport { logError } from '#internal/utils/logger';\nimport { attachStyles } from './attach-styles';\nimport { getRuntime, type Runtime } from './runtime';\n\nif (typeof HTMLElement !== 'undefined') {\n /**\n * `<remote-component>` custom element — the HTML host implementation.\n *\n * Implements {@link ConsumeClientConfig}\n * via typed property accessors that reflect to/from DOM attributes.\n *\n * {@link ConsumeLifecycleCallbacks} are dispatched as DOM events:\n * `beforeload`, `load`, `error`, `change`.\n */\n class RemoteComponent extends HTMLElement implements ConsumeClientConfig {\n name: string = DEFAULT_COMPONENT_NAME;\n bundle: string = DEFAULT_BUNDLE_NAME;\n fallbackSlot?: HTMLSlotElement;\n __next: HTMLDivElement | null = null;\n fouc: HTMLStyleElement | null = null;\n hostState: HostState = createHostState();\n root?: ShadowRoot | null = null;\n reactRoot?: ReturnType<typeof hydrateRoot>;\n emitter: LifecycleEmitter = makeEventEmitter(this);\n onRequest?: ConsumeServerConfig['onRequest'];\n onResponse?: ConsumeServerConfig['onResponse'];\n resolveClientUrl?: ConsumeClientConfig['resolveClientUrl'];\n\n // -- ConsumeServerConfig property accessors (attribute-reflected) --\n\n get src(): string | URL | undefined {\n return this.getAttribute('src') ?? undefined;\n }\n\n set src(value: string | URL | undefined) {\n if (value == null) {\n this.removeAttribute('src');\n } else {\n this.setAttribute('src', String(value));\n }\n }\n\n /** Always `true` — the HTML host always isolates via Shadow DOM. */\n get isolate(): boolean {\n return true;\n }\n\n get mode(): 'open' | 'closed' | undefined {\n const attr = this.getAttribute('mode');\n return attr === 'closed' ? 'closed' : 'open';\n }\n\n set mode(value: 'open' | 'closed' | undefined) {\n if (value) {\n this.setAttribute('mode', value);\n }\n }\n\n get reset(): boolean | undefined {\n return this.getAttribute('reset') !== null;\n }\n\n set reset(value: boolean | undefined) {\n if (value) {\n this.setAttribute('reset', '');\n } else {\n this.removeAttribute('reset');\n }\n }\n\n get credentials(): RequestCredentials | undefined {\n return (this.getAttribute('credentials') ||\n 'same-origin') as RequestCredentials;\n }\n\n set credentials(value: RequestCredentials | undefined) {\n if (value) {\n this.setAttribute('credentials', value);\n } else {\n this.removeAttribute('credentials');\n }\n }\n\n static get observedAttributes() {\n return ['src', 'name', 'mode'];\n }\n\n attributeChangedCallback(name: string, oldValue: string, newValue: string) {\n if ((name === 'src' || name === 'name') && oldValue !== newValue) {\n if (this.src) {\n this.load().catch((e) => {\n // AbortError is expected when loading is cancelled - don't log or dispatch\n if (isAbortError(e)) {\n return;\n }\n logError('HtmlHost', 'Error loading remote component.', e);\n this.emitter.error(e, this.src);\n this.hostState.stage = 'error';\n });\n }\n } else if (name === 'mode' && oldValue !== newValue && this.root) {\n // changing the shadow DOM mode is not supported\n // we need to recreate the shadow DOM and reload the component\n const newRoot = this.attachShadow({\n mode: newValue === 'closed' ? 'closed' : 'open',\n });\n // move all existing children to the new shadow root\n Array.from(this.root.children).forEach((child) => {\n newRoot.appendChild(child);\n });\n this.root = newRoot;\n // reload the remote component to apply the new shadow DOM\n this.load().catch((e) => {\n // AbortError is expected when loading is cancelled - don't log or dispatch\n if (isAbortError(e)) {\n return;\n }\n logError('HtmlHost', 'Error reloading remote component.', e);\n this.emitter.error(e, this.src);\n });\n }\n }\n\n async load() {\n // wait for the current call stack to finish\n await new Promise((resolve) => {\n (typeof queueMicrotask === 'function'\n ? queueMicrotask\n : requestAnimationFrame)(() => {\n resolve(undefined);\n });\n });\n\n // Abort any in-progress load so the latest src always wins.\n if (this.hostState.stage === 'loading') {\n this.hostState.abortController?.abort();\n this.hostState.stage = 'idle';\n // The aborted load may have already appended partial content to the shadow DOM\n // (styles, component children) before reaching an isCurrentLoad() check.\n // Clear it now so the new load starts from a clean state. Skip this when a\n // React root exists — that means a previous load completed successfully and\n // we'll take the startTransition re-render path instead.\n if (this.root && !this.reactRoot) {\n this.root.innerHTML = '';\n this.fouc = null;\n this.fallbackSlot = document.createElement('slot');\n this.root.appendChild(this.fallbackSlot);\n }\n }\n\n if (!this.root) {\n this.root = this.attachShadow({\n mode: this.mode === 'closed' ? 'closed' : 'open',\n });\n\n // create a slot element to allow the remote component to use the default slot\n this.fallbackSlot = document.createElement('slot');\n this.root.appendChild(this.fallbackSlot);\n }\n\n this.name = this.getAttribute('name') || this.name;\n\n this.hostState.stage = 'loading';\n const src = this.src;\n\n // Create AbortController for this load operation\n this.hostState.abortController = new AbortController();\n const signal = this.hostState.abortController.signal;\n\n // Returns true if this is still the active load — the signal hasn't been\n // aborted by a newer load() call, and the src hasn't changed in the meantime.\n // Checking the signal (not just the src) handles the case where the user\n // cycles back to the same src (e.g. styled → basic → styled): both loads\n // share the same src string, so a src-only check would pass for both,\n // causing double renders.\n const isCurrentLoad = () => !signal.aborted && this.src === src;\n\n // Resets stage to 'idle' for expected cancellations (AbortError). Real\n // errors are thrown and caught by attributeChangedCallback which sets\n // stage to 'error'. Only resets if no newer load() has superseded this\n // one — a new load replaces the abortController so the signal comparison\n // fails, preventing us from clobbering the new load's stage.\n const abandonLoad = () => {\n if (\n this.hostState.abortController?.signal === signal &&\n this.hostState.stage === 'loading'\n ) {\n this.hostState.stage = 'idle';\n }\n };\n\n this.emitter.beforeLoad(src ?? '');\n\n const remoteComponentChild =\n this.querySelector('div#__REMOTE_COMPONENT__') ||\n this.querySelector('div[data-bundle][data-route]');\n\n if (!src && !remoteComponentChild) {\n throw new RemoteComponentsError('\"src\" attribute is required');\n }\n\n let url: URL | null = null;\n let html = this.innerHTML;\n\n if (src) {\n url = getClientOrServerUrl(src, window.location.href);\n this.name = resolveNameFromSrc(src, this.name);\n }\n\n const resolveClientUrl = url\n ? bindResolveClientUrl(this.resolveClientUrl, url.href)\n : undefined;\n\n if (!remoteComponentChild && url) {\n // fetch the remote component\n const fetchInit = {\n credentials: this.credentials || 'same-origin',\n } as RequestInit;\n\n const resolvedUrl = new URL(\n resolveClientUrl?.(url.href) ?? url.href,\n window.location.href,\n );\n let res: Response;\n try {\n res = await fetchWithHooks(resolvedUrl, fetchInit, {\n onRequest: this.onRequest,\n onResponse: this.onResponse,\n abortController: this.hostState.abortController,\n });\n } catch (e) {\n if (isAbortError(e)) {\n return abandonLoad();\n }\n throw e;\n }\n\n if (!res || !res.ok) {\n throw await errorFromFailedFetch(url.href, resolvedUrl, res);\n }\n\n // get the full HTML content as a string - race with abort signal\n try {\n html = await res.text();\n } catch (e) {\n if (isAbortError(e)) {\n return abandonLoad();\n }\n throw e;\n }\n if (!isCurrentLoad()) {\n return abandonLoad();\n }\n }\n\n const effectiveUrl = url ?? new URL(window.location.href);\n const { doc, parsed } = preparePipeline({\n html,\n name: this.name,\n url: effectiveUrl,\n shared: {},\n resolveClientUrl,\n });\n const {\n component,\n name: resolvedName,\n isRemoteComponent,\n metadata: parsedMetadata,\n nextData,\n rsc,\n remoteShared,\n } = parsed;\n\n // when using a Next.js Pages Router remote application in development mode\n // we hide the remote component to prevent flickering\n // until the CSS is loaded for the remote component\n if (nextData && nextData.buildId === 'development' && !this.reactRoot) {\n this.fouc = document.createElement('style');\n this.fouc.textContent = `:host { display: none; }`;\n this.root.appendChild(this.fouc);\n }\n\n this.name = resolvedName;\n this.bundle = parsedMetadata.bundle;\n\n if (url) {\n getNamespace().bundleUrls[this.bundle] = url;\n }\n\n // add remote component metadata information at the custom element\n const metadataEl = document.createElement('script');\n metadataEl.type = 'application/json';\n metadataEl.setAttribute('data-remote-component', '');\n const metadataObj = {\n name: this.name,\n bundle: this.bundle,\n route: parsedMetadata.route,\n runtime: parsedMetadata.runtime,\n };\n metadataEl.textContent = JSON.stringify(metadataObj);\n\n if (\n this.previousElementSibling?.getAttribute('data-remote-component') !==\n null\n ) {\n this.previousElementSibling?.remove();\n }\n this.parentElement?.insertBefore(metadataEl, this);\n\n if (this.hostState.prevIsRemoteComponent) {\n if (this.hostState.prevUrl) {\n const prevUrl = this.hostState.prevUrl;\n const nsUnmount = getNamespace();\n if (nsUnmount.unmountFns[prevUrl.href]) {\n // call unmount() for all registered unmount functions for the previous remote component\n await Promise.all(\n Array.from(nsUnmount.unmountFns[prevUrl.href] ?? []).map(\n async (unmount) => {\n try {\n await unmount(this.root);\n } catch (e) {\n logError(\n 'HtmlHost',\n `Error while calling unmount() for Remote Component from ${prevUrl.href}.`,\n e,\n );\n }\n },\n ),\n );\n if (!isCurrentLoad()) {\n return abandonLoad();\n }\n }\n }\n this.root.innerHTML = '';\n }\n // Dispatch change event if this is not the first load\n if (this.hostState.prevSrc !== undefined) {\n this.emitter.change({\n previousSrc: this.hostState.prevSrc ?? null,\n nextSrc: src ?? null,\n previousName: this.hostState.prevName,\n nextName: this.name,\n });\n }\n\n this.hostState.prevUrl = effectiveUrl;\n this.hostState.prevIsRemoteComponent = isRemoteComponent;\n this.hostState.prevSrc = src;\n this.hostState.prevName = this.name;\n\n // store the original loading content of the custom element\n // this is required to remove the loading content after the remote component is loaded\n const removable = Array.from(this.childNodes);\n\n // reference to all link elements in the remote component\n const links = doc.querySelectorAll<HTMLLinkElement>('link[href]');\n\n const remoteComponentSrc = this.src ? String(this.src) : null;\n\n // Bound function for attaching styles — used both initially and in React effects\n const doAttachStyles = () =>\n attachStyles({\n doc,\n component,\n links,\n signal: undefined, // Effects run after load, no abort needed\n baseUrl: url?.href,\n remoteComponentSrc,\n root: this.root ?? null,\n resolveClientUrl,\n });\n\n if (!this.reactRoot) {\n // ensure all styles are loaded before hydrating to prevent FOUC\n await attachStyles({\n doc,\n component,\n links,\n signal,\n baseUrl: url?.href,\n remoteComponentSrc,\n root: this.root,\n resolveClientUrl,\n });\n if (!isCurrentLoad()) {\n return abandonLoad();\n }\n }\n\n // React hydrates into this dedicated wrapper, not the ShadowRoot directly.\n // It holds ONLY the remote's server-rendered markup; framework nodes in\n // the ShadowRoot (preload <link>s, RSC flight <script>, reset stylesheet)\n // stay outside it. On a hydration mismatch React's client-render recovery\n // only removes the stale server nodes when the container is a plain\n // Element — inside a ShadowRoot interleaved with non-React nodes the\n // cleanup silently fails and the subtree renders twice (PR #286).\n // `display: contents` keeps the wrapper layout-transparent so content\n // lays out as it did directly in the ShadowRoot.\n let reactContainer: HTMLElement | null = null;\n\n if (!this.reactRoot) {\n const container = document.createElement('div');\n container.setAttribute('data-remote-component-root', '');\n container.style.display = 'contents';\n reactContainer = container;\n\n // attach the remote component content to the shadow DOM\n Array.from(component.children).forEach((el) => {\n if (el.tagName.toLowerCase() === 'script') {\n if (!isRemoteComponent) {\n const newScript = document.createElement('script');\n // copy all attributes\n for (const attr of el.attributes) {\n if (attr.name === 'src') {\n const absoluteSrc = new URL(\n attr.value,\n url ?? window.location.origin,\n ).href;\n newScript.setAttribute(\n attr.name,\n resolveClientUrl?.(absoluteSrc) ?? absoluteSrc,\n );\n } else {\n newScript.setAttribute(attr.name, attr.value);\n }\n }\n newScript.textContent = el.textContent;\n if (remoteComponentSrc) {\n newScript.setAttribute(\n 'data-remote-component-src',\n remoteComponentSrc,\n );\n }\n this.root?.appendChild(newScript);\n } else {\n // remote-component scripts (RSC flight data, entrypoints) are not\n // part of React's hydrated tree — keep them in the ShadowRoot,\n // outside the hydration container.\n const newEl = el.cloneNode(true) as HTMLElement;\n for (const attr of el.attributes) {\n if (attr.name.startsWith('on')) {\n newEl.setAttribute(attr.name, attr.value);\n }\n }\n this.root?.appendChild(newEl);\n }\n } else {\n const newEl = el.cloneNode(true) as HTMLElement;\n for (const attr of el.attributes) {\n if (attr.name.startsWith('on')) {\n newEl.setAttribute(attr.name, attr.value);\n }\n }\n container.appendChild(newEl);\n }\n });\n\n this.root?.appendChild(container);\n }\n\n // clear the loading content of the shadow DOM root\n for (const el of removable) {\n el.parentElement?.removeChild(el);\n }\n this.fallbackSlot?.remove();\n\n // function to apply the reset styles to the shadow DOM\n const applyReset = () => {\n if (\n this.reset &&\n !this.root?.querySelector('link[data-remote-components-reset]')\n ) {\n // all initial styles to reset inherited styles leaking from the host page\n const allInitial = document.createElement('link');\n allInitial.setAttribute('data-remote-components-reset', '');\n const css = `:host { all: initial; }`;\n const allInitialHref = URL.createObjectURL(\n new Blob([css], { type: 'text/css' }),\n );\n allInitial.href = allInitialHref;\n allInitial.rel = 'stylesheet';\n // we need to revoke the object URL after the stylesheet is loaded to free up memory\n allInitial.onload = () => {\n URL.revokeObjectURL(allInitialHref);\n allInitial.removeAttribute('onload');\n };\n allInitial.onerror = () => {\n URL.revokeObjectURL(allInitialHref);\n allInitial.removeAttribute('onload');\n };\n this.root?.prepend(allInitial);\n } else if (\n !this.reset &&\n this.root?.querySelector('link[data-remote-components-reset]')\n ) {\n this.root\n .querySelector('link[data-remote-components-reset]')\n ?.remove();\n }\n };\n\n // apply the reset styles if required and not already applied\n if (!this.reactRoot) {\n applyReset();\n }\n\n const {\n self,\n createFromReadableStream,\n nextClientPagesLoader,\n preloadScripts,\n } = await getRuntime(\n metadataObj.runtime as Runtime,\n effectiveUrl,\n this.bundle,\n {\n react: async () => (await import('react')).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': async () => (await import('react-dom')).default,\n 'react-dom/client': async () =>\n (await import('react-dom/client')).default,\n },\n remoteShared,\n resolveClientUrl,\n );\n if (!isCurrentLoad()) {\n return abandonLoad();\n }\n\n const scripts = isRemoteComponent\n ? component.querySelectorAll<HTMLScriptElement>('script')\n : doc.querySelectorAll<HTMLScriptElement>(\n 'script[src],script[data-src],script[data-remote-component-entrypoint]',\n );\n if (!url) {\n url = new URL(\n component.getAttribute('data-route') ?? '/',\n window.location.href,\n );\n }\n\n await preloadScripts(Array.from(scripts), url, this.bundle, this.name);\n if (!isCurrentLoad()) {\n return abandonLoad();\n }\n\n // remove all script elements from the shadow DOM to prevent re-execution of scripts\n if (isRemoteComponent) {\n Array.from(component.children).forEach((child) => {\n if (child.tagName === 'SCRIPT') {\n child.remove();\n }\n });\n }\n\n // cleanup previous remote component instances when a new remote component is loaded\n // this is required when the src attribute is changed to load a new remote component\n const doCleanup = () => {\n if (this.root && remoteComponentSrc) {\n const selector = `[data-remote-component-src]:not([data-remote-component-src=\"${remoteComponentSrc}\"])`;\n const prevCleanup = [\n ...this.root.querySelectorAll(selector),\n ...document.body.querySelectorAll(selector),\n ] as HTMLElement[];\n\n if (prevCleanup.length > 0) {\n prevCleanup.forEach((prev) => {\n prev.remove();\n });\n }\n }\n };\n\n // using RSC hydration if the RSC flight data is available\n if (rsc) {\n // remove the RSC flight data script element\n rsc.parentElement?.removeChild(rsc);\n\n // reload the RSC flight data script to eval it's content\n const rscName = `__remote_component_rsc_${escapeString(\n url.href,\n )}_${escapeString(this.name)}`;\n const rscClone = document.createElement('script');\n rscClone.id = `${rscName}_rsc`;\n rscClone.textContent =\n rsc.textContent?.replace(\n new RegExp(`self\\\\[\"${this.name}\"\\\\]`, 'g'),\n `self[\"${rscName}\"]`,\n ) ?? '';\n document.body.appendChild(rscClone);\n\n let cache: React.ReactNode;\n // React component to convert the RSC flight data into a React component\n const RemoteComponentFromReadableStream = ({\n name,\n initial,\n }: {\n name: string;\n initial: boolean;\n }) => {\n // convert the RSC flight data array into a ReadableStream\n // get the RSC flight data from the global scope\n // the RSC flight data is stored in an array\n // fallback to an empty RSC payload if the data is not found\n const stream = createRSCStream(\n rscName,\n self[rscName as RSCKey] ?? [`0:[null]\\n`],\n );\n const Component =\n cache ??\n // cache the component to avoid reloading the RSC flight data\n (cache = createFromReadableStream(stream) as React.ReactNode);\n\n useLayoutEffect(() => {\n // clear the RSC flight data from the global scope to free up memory\n if (self[name as RSCKey]) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete self[name as RSCKey];\n }\n const rscScript = document.getElementById(`${name}_rsc`);\n if (rscScript) {\n rscScript.remove();\n }\n\n doCleanup();\n applyReset();\n if (!initial) {\n doAttachStyles().catch((e: unknown) => {\n logError('HtmlHost', 'Error attaching styles.', e);\n });\n }\n if (isCurrentLoad()) {\n this.hostState.stage = 'loaded';\n }\n\n this.emitter.load(this.src ?? '');\n }, [initial, name]);\n\n // React can handle the component reference and will wait for the component to be ready\n return Component;\n };\n\n // when we already have a React root, we just need to render the new component\n if (this.reactRoot) {\n const root = this.reactRoot;\n startTransition(() => {\n root.render(\n <RemoteComponentFromReadableStream\n initial={false}\n name={this.name}\n />,\n );\n });\n return;\n }\n\n // hydrate the remote component using the RSC flight data\n this.reactRoot = hydrateRoot(\n // hydrate into the dedicated wrapper (falls back to the ShadowRoot)\n // @ts-expect-error this.root is a ShadowRoot, accepted at runtime\n reactContainer ?? this.root,\n <RemoteComponentFromReadableStream initial name={this.name} />,\n );\n } else if (nextData) {\n // using Next.js client pages loader if the Next.js hydration data is available\n const { Component, App } = nextClientPagesLoader(\n this.bundle,\n nextData.page ?? '/',\n this.root,\n );\n\n // if we have the component, we can hydrate it\n if (Component) {\n const RemoteComponentFromNext = ((\n NextApp: ReturnType<typeof nextClientPagesLoader>['App'],\n NextComponent: NonNullable<\n ReturnType<typeof nextClientPagesLoader>['Component']\n >,\n remoteComponent = this,\n ) =>\n function RemoteComponentNext({ initial }: { initial: boolean }) {\n useLayoutEffect(() => {\n doCleanup();\n if (!initial) {\n applyReset();\n doAttachStyles().catch((e: unknown) => {\n logError('HtmlHost', 'Error attaching styles.', e);\n });\n }\n if (isCurrentLoad()) {\n remoteComponent.hostState.stage = 'loaded';\n }\n\n remoteComponent.emitter.load(remoteComponent.src ?? '');\n }, [initial, remoteComponent]);\n\n return NextApp ? (\n <NextApp Component={NextComponent} {...nextData.props} />\n ) : (\n <NextComponent {...nextData.props} />\n );\n })(App, Component, this);\n\n // when we already have a React root, we just need to render the new component\n if (this.reactRoot) {\n const root = this.reactRoot;\n startTransition(() => {\n root.render(<RemoteComponentFromNext initial={false} />);\n doCleanup();\n if (isCurrentLoad()) {\n this.hostState.stage = 'loaded';\n }\n });\n return;\n }\n\n // hydrate the remote component using the Next.js pages router\n this.reactRoot = hydrateRoot(\n // hydrate into the dedicated wrapper (falls back to the ShadowRoot)\n // @ts-expect-error this.root is a ShadowRoot, accepted at runtime\n reactContainer ?? this.root,\n <RemoteComponentFromNext initial />,\n );\n }\n\n // remove the FOUC workaround style element to show the remote component\n // this is only for development mode\n if (this.fouc) {\n this.root.removeChild(this.fouc);\n }\n } else if (getNamespace().mountFns[url.href]) {\n // using script entrypoint when no RSC or Next.js data is available\n await Promise.all(\n Array.from(getNamespace().mountFns[url.href] ?? []).map(\n async (mount) => {\n try {\n await mount(this.root);\n } catch (e) {\n logError(\n 'HtmlHost',\n `Error while calling mount() for Remote Component from ${url.href}.`,\n e,\n );\n }\n },\n ),\n );\n\n this.emitter.load(this.src ?? '');\n } else {\n this.emitter.load(this.src ?? '');\n }\n\n if (isCurrentLoad()) {\n this.hostState.stage = 'loaded';\n }\n }\n }\n\n // register the custom element\n customElements.define('remote-component', RemoteComponent);\n}\n\nexport function registerSharedModules(\n modules: Record<string, () => Promise<unknown>> = {},\n) {\n const ns = getNamespace();\n Object.entries(modules).forEach(([key, value]) => {\n ns.hostSharedModules[key] = value;\n });\n}\n","import type { InternalResolveClientUrl } from '#internal/host/server/types';\nimport { RemoteComponentsError } from '#internal/utils/error';\n\ninterface AttachStylesOptions {\n /** The parsed document containing link and style elements */\n doc: Document;\n /** The component element to check if links are already contained */\n component: Element;\n /** Links from the document head */\n links: NodeListOf<HTMLLinkElement>;\n /** AbortSignal to cancel loading */\n signal: AbortSignal | undefined;\n /** Base URL for resolving relative hrefs */\n baseUrl: string | undefined;\n /** Source URL to set as data attribute */\n remoteComponentSrc: string | null;\n /** Root element to append styles to (ShadowRoot or Element) */\n root: ShadowRoot | Element | null;\n /** Callback to transform asset URLs before loading */\n resolveClientUrl?: InternalResolveClientUrl;\n}\n\n/**\n * Attaches link and style elements from a remote component document to the shadow root.\n * Handles abort signals efficiently with a single shared listener for all links.\n *\n * @throws DOMException with name 'AbortError' if signal is aborted\n * @throws RemoteComponentsError if a stylesheet fails to load\n */\nexport async function attachStyles({\n doc,\n component,\n links,\n signal,\n baseUrl,\n remoteComponentSrc,\n root,\n resolveClientUrl,\n}: AttachStylesOptions): Promise<void> {\n // Track appended links for cleanup on abort\n const appendedLinks: HTMLLinkElement[] = [];\n\n // Single shared abort promise - avoids N listeners for N links\n let abortReject: ((error: DOMException) => void) | null = null;\n const abortPromise = new Promise<never>((_, reject) => {\n abortReject = reject;\n });\n const abortHandler = () => {\n // Clean up all pending links on abort\n for (const link of appendedLinks) {\n link.onload = null;\n link.onerror = null;\n link.remove();\n }\n abortReject?.(new DOMException('Aborted', 'AbortError'));\n };\n signal?.addEventListener('abort', abortHandler, { once: true });\n\n try {\n // Attach each link element to the shadow DOM to load the styles\n await Promise.all(\n Array.from(links)\n .filter((link) => !component.contains(link))\n .map((link) => {\n const newLink = document.createElement('link');\n appendedLinks.push(newLink);\n\n const loadPromise = new Promise<void>((resolve, reject) => {\n if (link.rel === 'stylesheet') {\n // TODO: needs to be cancellable with a singular listener for the abort signal https://linear.app/vercel/issue/MFES-1253/handle-abortcontroller-clean-up-scenarios\n newLink.onload = () => resolve();\n newLink.onerror = () =>\n reject(\n new RemoteComponentsError(\n `Failed to load <link href=\"${link.href}\"> for Remote Component. Check the URL is correct.`,\n ),\n );\n } else {\n resolve();\n }\n });\n\n for (const attr of link.attributes) {\n if (attr.name === 'href') {\n const absoluteHref = new URL(\n attr.value,\n baseUrl ?? location.origin,\n ).href;\n newLink.setAttribute(\n attr.name,\n resolveClientUrl?.(absoluteHref) ?? absoluteHref,\n );\n } else {\n newLink.setAttribute(attr.name, attr.value);\n }\n }\n\n if (remoteComponentSrc) {\n newLink.setAttribute(\n 'data-remote-component-src',\n remoteComponentSrc,\n );\n }\n\n // TODO: needs to be cancellable with a singular listener for the abort signal https://linear.app/vercel/issue/MFES-1253/handle-abortcontroller-clean-up-scenarios\n root?.appendChild(newLink);\n\n // Race each link load against the shared abort promise\n return Promise.race([loadPromise, abortPromise]);\n }),\n );\n } finally {\n signal?.removeEventListener('abort', abortHandler);\n }\n\n // Attach inline styles from the document head\n const styles = doc.querySelectorAll<HTMLStyleElement>('style');\n for (const style of styles) {\n if (style.parentElement?.tagName.toLowerCase() === 'head') {\n const newStyle = document.createElement('style');\n newStyle.textContent = style.textContent;\n\n if (remoteComponentSrc) {\n newStyle.setAttribute('data-remote-component-src', remoteComponentSrc);\n }\n\n root?.appendChild(newStyle);\n }\n }\n}\n","import type { InternalResolveClientUrl } from '#internal/host/server/types';\nimport type { RemoteSharedModules } from '#internal/host/shared/shared-broker';\nimport { RemoteComponentsError } from '#internal/utils/error';\n\nexport type Runtime = 'webpack' | 'turbopack' | 'script' | 'unknown';\n\nexport async function getRuntime(\n type: Runtime,\n url: URL,\n bundle: string,\n shared?: Record<string, () => Promise<unknown>>,\n remoteShared?: RemoteSharedModules,\n resolveClientUrl?: InternalResolveClientUrl,\n) {\n // minimally mock process.env for browser environments\n if (typeof globalThis.process === 'undefined') {\n globalThis.process = {\n env: {},\n } as NodeJS.Process;\n }\n\n if (type === 'webpack') {\n const { webpackRuntime } = await import(`./webpack`);\n return webpackRuntime(bundle, shared, remoteShared, resolveClientUrl);\n } else if (type === 'turbopack') {\n const { turbopackRuntime } = await import(`./turbopack`);\n return turbopackRuntime(\n url,\n bundle,\n shared,\n remoteShared,\n resolveClientUrl,\n );\n } else if (type === 'script') {\n const { scriptRuntime } = await import(`./script`);\n return scriptRuntime(resolveClientUrl);\n }\n throw new RemoteComponentsError(\n `Remote Components runtime \"${type}\" is not supported. Supported runtimes are \"webpack\", \"turbopack\", and \"script\".`,\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,iBAAiB,uBAAuB;AACjD,SAAS,mBAAmB;;;AC4B5B,eAAsB,aAAa;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuC;AAErC,QAAM,gBAAmC,CAAC;AAG1C,MAAI,cAAsD;AAC1D,QAAM,eAAe,IAAI,QAAe,CAAC,GAAG,WAAW;AACrD,kBAAc;AAAA,EAChB,CAAC;AACD,QAAM,eAAe,MAAM;AAEzB,eAAW,QAAQ,eAAe;AAChC,WAAK,SAAS;AACd,WAAK,UAAU;AACf,WAAK,OAAO;AAAA,IACd;AACA,kBAAc,IAAI,aAAa,WAAW,YAAY,CAAC;AAAA,EACzD;AACA,UAAQ,iBAAiB,SAAS,cAAc,EAAE,MAAM,KAAK,CAAC;AAE9D,MAAI;AAEF,UAAM,QAAQ;AAAA,MACZ,MAAM,KAAK,KAAK,EACb,OAAO,CAAC,SAAS,CAAC,UAAU,SAAS,IAAI,CAAC,EAC1C,IAAI,CAAC,SAAS;AACb,cAAM,UAAU,SAAS,cAAc,MAAM;AAC7C,sBAAc,KAAK,OAAO;AAE1B,cAAM,cAAc,IAAI,QAAc,CAAC,SAAS,WAAW;AACzD,cAAI,KAAK,QAAQ,cAAc;AAE7B,oBAAQ,SAAS,MAAM,QAAQ;AAC/B,oBAAQ,UAAU,MAChB;AAAA,cACE,IAAI;AAAA,gBACF,8BAA8B,KAAK;AAAA,cACrC;AAAA,YACF;AAAA,UACJ,OAAO;AACL,oBAAQ;AAAA,UACV;AAAA,QACF,CAAC;AAED,mBAAW,QAAQ,KAAK,YAAY;AAClC,cAAI,KAAK,SAAS,QAAQ;AACxB,kBAAM,eAAe,IAAI;AAAA,cACvB,KAAK;AAAA,cACL,WAAW,SAAS;AAAA,YACtB,EAAE;AACF,oBAAQ;AAAA,cACN,KAAK;AAAA,cACL,mBAAmB,YAAY,KAAK;AAAA,YACtC;AAAA,UACF,OAAO;AACL,oBAAQ,aAAa,KAAK,MAAM,KAAK,KAAK;AAAA,UAC5C;AAAA,QACF;AAEA,YAAI,oBAAoB;AACtB,kBAAQ;AAAA,YACN;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAGA,cAAM,YAAY,OAAO;AAGzB,eAAO,QAAQ,KAAK,CAAC,aAAa,YAAY,CAAC;AAAA,MACjD,CAAC;AAAA,IACL;AAAA,EACF,UAAE;AACA,YAAQ,oBAAoB,SAAS,YAAY;AAAA,EACnD;AAGA,QAAM,SAAS,IAAI,iBAAmC,OAAO;AAC7D,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,eAAe,QAAQ,YAAY,MAAM,QAAQ;AACzD,YAAM,WAAW,SAAS,cAAc,OAAO;AAC/C,eAAS,cAAc,MAAM;AAE7B,UAAI,oBAAoB;AACtB,iBAAS,aAAa,6BAA6B,kBAAkB;AAAA,MACvE;AAEA,YAAM,YAAY,QAAQ;AAAA,IAC5B;AAAA,EACF;AACF;;;AC3HA,eAAsB,WACpB,MACA,KACA,QACA,QACA,cACA,kBACA;AAEA,MAAI,OAAO,WAAW,YAAY,aAAa;AAC7C,eAAW,UAAU;AAAA,MACnB,KAAK,CAAC;AAAA,IACR;AAAA,EACF;AAEA,MAAI,SAAS,WAAW;AACtB,UAAM,EAAE,eAAe,IAAI,MAAM,OAAO,wBAAW;AACnD,WAAO,eAAe,QAAQ,QAAQ,cAAc,gBAAgB;AAAA,EACtE,WAAW,SAAS,aAAa;AAC/B,UAAM,EAAE,iBAAiB,IAAI,MAAM,OAAO,0BAAa;AACvD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,WAAW,SAAS,UAAU;AAC5B,UAAM,EAAE,cAAc,IAAI,MAAM,OAAO,uBAAU;AACjD,WAAO,cAAc,gBAAgB;AAAA,EACvC;AACA,QAAM,IAAI;AAAA,IACR,8BAA8B;AAAA,EAChC;AACF;;;AFkoBc;AAxoBd,IAAI,OAAO,gBAAgB,aAAa;AAUtC,QAAM,wBAAwB,YAA2C;AAAA,IACvE,OAAe;AAAA,IACf,SAAiB;AAAA,IACjB;AAAA,IACA,SAAgC;AAAA,IAChC,OAAgC;AAAA,IAChC,YAAuB,gBAAgB;AAAA,IACvC,OAA2B;AAAA,IAC3B;AAAA,IACA,UAA4B,iBAAiB,IAAI;AAAA,IACjD;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAIA,IAAI,MAAgC;AAClC,aAAO,KAAK,aAAa,KAAK,KAAK;AAAA,IACrC;AAAA,IAEA,IAAI,IAAI,OAAiC;AACvC,UAAI,SAAS,MAAM;AACjB,aAAK,gBAAgB,KAAK;AAAA,MAC5B,OAAO;AACL,aAAK,aAAa,OAAO,OAAO,KAAK,CAAC;AAAA,MACxC;AAAA,IACF;AAAA;AAAA,IAGA,IAAI,UAAmB;AACrB,aAAO;AAAA,IACT;AAAA,IAEA,IAAI,OAAsC;AACxC,YAAM,OAAO,KAAK,aAAa,MAAM;AACrC,aAAO,SAAS,WAAW,WAAW;AAAA,IACxC;AAAA,IAEA,IAAI,KAAK,OAAsC;AAC7C,UAAI,OAAO;AACT,aAAK,aAAa,QAAQ,KAAK;AAAA,MACjC;AAAA,IACF;AAAA,IAEA,IAAI,QAA6B;AAC/B,aAAO,KAAK,aAAa,OAAO,MAAM;AAAA,IACxC;AAAA,IAEA,IAAI,MAAM,OAA4B;AACpC,UAAI,OAAO;AACT,aAAK,aAAa,SAAS,EAAE;AAAA,MAC/B,OAAO;AACL,aAAK,gBAAgB,OAAO;AAAA,MAC9B;AAAA,IACF;AAAA,IAEA,IAAI,cAA8C;AAChD,aAAQ,KAAK,aAAa,aAAa,KACrC;AAAA,IACJ;AAAA,IAEA,IAAI,YAAY,OAAuC;AACrD,UAAI,OAAO;AACT,aAAK,aAAa,eAAe,KAAK;AAAA,MACxC,OAAO;AACL,aAAK,gBAAgB,aAAa;AAAA,MACpC;AAAA,IACF;AAAA,IAEA,WAAW,qBAAqB;AAC9B,aAAO,CAAC,OAAO,QAAQ,MAAM;AAAA,IAC/B;AAAA,IAEA,yBAAyB,MAAc,UAAkB,UAAkB;AACzE,WAAK,SAAS,SAAS,SAAS,WAAW,aAAa,UAAU;AAChE,YAAI,KAAK,KAAK;AACZ,eAAK,KAAK,EAAE,MAAM,CAAC,MAAM;AAEvB,gBAAI,aAAa,CAAC,GAAG;AACnB;AAAA,YACF;AACA,qBAAS,YAAY,mCAAmC,CAAC;AACzD,iBAAK,QAAQ,MAAM,GAAG,KAAK,GAAG;AAC9B,iBAAK,UAAU,QAAQ;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF,WAAW,SAAS,UAAU,aAAa,YAAY,KAAK,MAAM;AAGhE,cAAM,UAAU,KAAK,aAAa;AAAA,UAChC,MAAM,aAAa,WAAW,WAAW;AAAA,QAC3C,CAAC;AAED,cAAM,KAAK,KAAK,KAAK,QAAQ,EAAE,QAAQ,CAAC,UAAU;AAChD,kBAAQ,YAAY,KAAK;AAAA,QAC3B,CAAC;AACD,aAAK,OAAO;AAEZ,aAAK,KAAK,EAAE,MAAM,CAAC,MAAM;AAEvB,cAAI,aAAa,CAAC,GAAG;AACnB;AAAA,UACF;AACA,mBAAS,YAAY,qCAAqC,CAAC;AAC3D,eAAK,QAAQ,MAAM,GAAG,KAAK,GAAG;AAAA,QAChC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IAEA,MAAM,OAAO;AAEX,YAAM,IAAI,QAAQ,CAAC,YAAY;AAC7B,SAAC,OAAO,mBAAmB,aACvB,iBACA,uBAAuB,MAAM;AAC/B,kBAAQ,MAAS;AAAA,QACnB,CAAC;AAAA,MACH,CAAC;AAGD,UAAI,KAAK,UAAU,UAAU,WAAW;AACtC,aAAK,UAAU,iBAAiB,MAAM;AACtC,aAAK,UAAU,QAAQ;AAMvB,YAAI,KAAK,QAAQ,CAAC,KAAK,WAAW;AAChC,eAAK,KAAK,YAAY;AACtB,eAAK,OAAO;AACZ,eAAK,eAAe,SAAS,cAAc,MAAM;AACjD,eAAK,KAAK,YAAY,KAAK,YAAY;AAAA,QACzC;AAAA,MACF;AAEA,UAAI,CAAC,KAAK,MAAM;AACd,aAAK,OAAO,KAAK,aAAa;AAAA,UAC5B,MAAM,KAAK,SAAS,WAAW,WAAW;AAAA,QAC5C,CAAC;AAGD,aAAK,eAAe,SAAS,cAAc,MAAM;AACjD,aAAK,KAAK,YAAY,KAAK,YAAY;AAAA,MACzC;AAEA,WAAK,OAAO,KAAK,aAAa,MAAM,KAAK,KAAK;AAE9C,WAAK,UAAU,QAAQ;AACvB,YAAM,MAAM,KAAK;AAGjB,WAAK,UAAU,kBAAkB,IAAI,gBAAgB;AACrD,YAAM,SAAS,KAAK,UAAU,gBAAgB;AAQ9C,YAAM,gBAAgB,MAAM,CAAC,OAAO,WAAW,KAAK,QAAQ;AAO5D,YAAM,cAAc,MAAM;AACxB,YACE,KAAK,UAAU,iBAAiB,WAAW,UAC3C,KAAK,UAAU,UAAU,WACzB;AACA,eAAK,UAAU,QAAQ;AAAA,QACzB;AAAA,MACF;AAEA,WAAK,QAAQ,WAAW,OAAO,EAAE;AAEjC,YAAM,uBACJ,KAAK,cAAc,0BAA0B,KAC7C,KAAK,cAAc,8BAA8B;AAEnD,UAAI,CAAC,OAAO,CAAC,sBAAsB;AACjC,cAAM,IAAI,sBAAsB,6BAA6B;AAAA,MAC/D;AAEA,UAAI,MAAkB;AACtB,UAAI,OAAO,KAAK;AAEhB,UAAI,KAAK;AACP,cAAM,qBAAqB,KAAK,OAAO,SAAS,IAAI;AACpD,aAAK,OAAO,mBAAmB,KAAK,KAAK,IAAI;AAAA,MAC/C;AAEA,YAAM,mBAAmB,MACrB,qBAAqB,KAAK,kBAAkB,IAAI,IAAI,IACpD;AAEJ,UAAI,CAAC,wBAAwB,KAAK;AAEhC,cAAM,YAAY;AAAA,UAChB,aAAa,KAAK,eAAe;AAAA,QACnC;AAEA,cAAM,cAAc,IAAI;AAAA,UACtB,mBAAmB,IAAI,IAAI,KAAK,IAAI;AAAA,UACpC,OAAO,SAAS;AAAA,QAClB;AACA,YAAI;AACJ,YAAI;AACF,gBAAM,MAAM,eAAe,aAAa,WAAW;AAAA,YACjD,WAAW,KAAK;AAAA,YAChB,YAAY,KAAK;AAAA,YACjB,iBAAiB,KAAK,UAAU;AAAA,UAClC,CAAC;AAAA,QACH,SAAS,GAAP;AACA,cAAI,aAAa,CAAC,GAAG;AACnB,mBAAO,YAAY;AAAA,UACrB;AACA,gBAAM;AAAA,QACR;AAEA,YAAI,CAAC,OAAO,CAAC,IAAI,IAAI;AACnB,gBAAM,MAAM,qBAAqB,IAAI,MAAM,aAAa,GAAG;AAAA,QAC7D;AAGA,YAAI;AACF,iBAAO,MAAM,IAAI,KAAK;AAAA,QACxB,SAAS,GAAP;AACA,cAAI,aAAa,CAAC,GAAG;AACnB,mBAAO,YAAY;AAAA,UACrB;AACA,gBAAM;AAAA,QACR;AACA,YAAI,CAAC,cAAc,GAAG;AACpB,iBAAO,YAAY;AAAA,QACrB;AAAA,MACF;AAEA,YAAM,eAAe,OAAO,IAAI,IAAI,OAAO,SAAS,IAAI;AACxD,YAAM,EAAE,KAAK,OAAO,IAAI,gBAAgB;AAAA,QACtC;AAAA,QACA,MAAM,KAAK;AAAA,QACX,KAAK;AAAA,QACL,QAAQ,CAAC;AAAA,QACT;AAAA,MACF,CAAC;AACD,YAAM;AAAA,QACJ;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF,IAAI;AAKJ,UAAI,YAAY,SAAS,YAAY,iBAAiB,CAAC,KAAK,WAAW;AACrE,aAAK,OAAO,SAAS,cAAc,OAAO;AAC1C,aAAK,KAAK,cAAc;AACxB,aAAK,KAAK,YAAY,KAAK,IAAI;AAAA,MACjC;AAEA,WAAK,OAAO;AACZ,WAAK,SAAS,eAAe;AAE7B,UAAI,KAAK;AACP,qBAAa,EAAE,WAAW,KAAK,MAAM,IAAI;AAAA,MAC3C;AAGA,YAAM,aAAa,SAAS,cAAc,QAAQ;AAClD,iBAAW,OAAO;AAClB,iBAAW,aAAa,yBAAyB,EAAE;AACnD,YAAM,cAAc;AAAA,QAClB,MAAM,KAAK;AAAA,QACX,QAAQ,KAAK;AAAA,QACb,OAAO,eAAe;AAAA,QACtB,SAAS,eAAe;AAAA,MAC1B;AACA,iBAAW,cAAc,KAAK,UAAU,WAAW;AAEnD,UACE,KAAK,wBAAwB,aAAa,uBAAuB,MACjE,MACA;AACA,aAAK,wBAAwB,OAAO;AAAA,MACtC;AACA,WAAK,eAAe,aAAa,YAAY,IAAI;AAEjD,UAAI,KAAK,UAAU,uBAAuB;AACxC,YAAI,KAAK,UAAU,SAAS;AAC1B,gBAAM,UAAU,KAAK,UAAU;AAC/B,gBAAM,YAAY,aAAa;AAC/B,cAAI,UAAU,WAAW,QAAQ,IAAI,GAAG;AAEtC,kBAAM,QAAQ;AAAA,cACZ,MAAM,KAAK,UAAU,WAAW,QAAQ,IAAI,KAAK,CAAC,CAAC,EAAE;AAAA,gBACnD,OAAO,YAAY;AACjB,sBAAI;AACF,0BAAM,QAAQ,KAAK,IAAI;AAAA,kBACzB,SAAS,GAAP;AACA;AAAA,sBACE;AAAA,sBACA,2DAA2D,QAAQ;AAAA,sBACnE;AAAA,oBACF;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AACA,gBAAI,CAAC,cAAc,GAAG;AACpB,qBAAO,YAAY;AAAA,YACrB;AAAA,UACF;AAAA,QACF;AACA,aAAK,KAAK,YAAY;AAAA,MACxB;AAEA,UAAI,KAAK,UAAU,YAAY,QAAW;AACxC,aAAK,QAAQ,OAAO;AAAA,UAClB,aAAa,KAAK,UAAU,WAAW;AAAA,UACvC,SAAS,OAAO;AAAA,UAChB,cAAc,KAAK,UAAU;AAAA,UAC7B,UAAU,KAAK;AAAA,QACjB,CAAC;AAAA,MACH;AAEA,WAAK,UAAU,UAAU;AACzB,WAAK,UAAU,wBAAwB;AACvC,WAAK,UAAU,UAAU;AACzB,WAAK,UAAU,WAAW,KAAK;AAI/B,YAAM,YAAY,MAAM,KAAK,KAAK,UAAU;AAG5C,YAAM,QAAQ,IAAI,iBAAkC,YAAY;AAEhE,YAAM,qBAAqB,KAAK,MAAM,OAAO,KAAK,GAAG,IAAI;AAGzD,YAAM,iBAAiB,MACrB,aAAa;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA;AAAA,QACR,SAAS,KAAK;AAAA,QACd;AAAA,QACA,MAAM,KAAK,QAAQ;AAAA,QACnB;AAAA,MACF,CAAC;AAEH,UAAI,CAAC,KAAK,WAAW;AAEnB,cAAM,aAAa;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,SAAS,KAAK;AAAA,UACd;AAAA,UACA,MAAM,KAAK;AAAA,UACX;AAAA,QACF,CAAC;AACD,YAAI,CAAC,cAAc,GAAG;AACpB,iBAAO,YAAY;AAAA,QACrB;AAAA,MACF;AAWA,UAAI,iBAAqC;AAEzC,UAAI,CAAC,KAAK,WAAW;AACnB,cAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,kBAAU,aAAa,8BAA8B,EAAE;AACvD,kBAAU,MAAM,UAAU;AAC1B,yBAAiB;AAGjB,cAAM,KAAK,UAAU,QAAQ,EAAE,QAAQ,CAAC,OAAO;AAC7C,cAAI,GAAG,QAAQ,YAAY,MAAM,UAAU;AACzC,gBAAI,CAAC,mBAAmB;AACtB,oBAAM,YAAY,SAAS,cAAc,QAAQ;AAEjD,yBAAW,QAAQ,GAAG,YAAY;AAChC,oBAAI,KAAK,SAAS,OAAO;AACvB,wBAAM,cAAc,IAAI;AAAA,oBACtB,KAAK;AAAA,oBACL,OAAO,OAAO,SAAS;AAAA,kBACzB,EAAE;AACF,4BAAU;AAAA,oBACR,KAAK;AAAA,oBACL,mBAAmB,WAAW,KAAK;AAAA,kBACrC;AAAA,gBACF,OAAO;AACL,4BAAU,aAAa,KAAK,MAAM,KAAK,KAAK;AAAA,gBAC9C;AAAA,cACF;AACA,wBAAU,cAAc,GAAG;AAC3B,kBAAI,oBAAoB;AACtB,0BAAU;AAAA,kBACR;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AACA,mBAAK,MAAM,YAAY,SAAS;AAAA,YAClC,OAAO;AAIL,oBAAM,QAAQ,GAAG,UAAU,IAAI;AAC/B,yBAAW,QAAQ,GAAG,YAAY;AAChC,oBAAI,KAAK,KAAK,WAAW,IAAI,GAAG;AAC9B,wBAAM,aAAa,KAAK,MAAM,KAAK,KAAK;AAAA,gBAC1C;AAAA,cACF;AACA,mBAAK,MAAM,YAAY,KAAK;AAAA,YAC9B;AAAA,UACF,OAAO;AACL,kBAAM,QAAQ,GAAG,UAAU,IAAI;AAC/B,uBAAW,QAAQ,GAAG,YAAY;AAChC,kBAAI,KAAK,KAAK,WAAW,IAAI,GAAG;AAC9B,sBAAM,aAAa,KAAK,MAAM,KAAK,KAAK;AAAA,cAC1C;AAAA,YACF;AACA,sBAAU,YAAY,KAAK;AAAA,UAC7B;AAAA,QACF,CAAC;AAED,aAAK,MAAM,YAAY,SAAS;AAAA,MAClC;AAGA,iBAAW,MAAM,WAAW;AAC1B,WAAG,eAAe,YAAY,EAAE;AAAA,MAClC;AACA,WAAK,cAAc,OAAO;AAG1B,YAAM,aAAa,MAAM;AACvB,YACE,KAAK,SACL,CAAC,KAAK,MAAM,cAAc,oCAAoC,GAC9D;AAEA,gBAAM,aAAa,SAAS,cAAc,MAAM;AAChD,qBAAW,aAAa,gCAAgC,EAAE;AAC1D,gBAAM,MAAM;AACZ,gBAAM,iBAAiB,IAAI;AAAA,YACzB,IAAI,KAAK,CAAC,GAAG,GAAG,EAAE,MAAM,WAAW,CAAC;AAAA,UACtC;AACA,qBAAW,OAAO;AAClB,qBAAW,MAAM;AAEjB,qBAAW,SAAS,MAAM;AACxB,gBAAI,gBAAgB,cAAc;AAClC,uBAAW,gBAAgB,QAAQ;AAAA,UACrC;AACA,qBAAW,UAAU,MAAM;AACzB,gBAAI,gBAAgB,cAAc;AAClC,uBAAW,gBAAgB,QAAQ;AAAA,UACrC;AACA,eAAK,MAAM,QAAQ,UAAU;AAAA,QAC/B,WACE,CAAC,KAAK,SACN,KAAK,MAAM,cAAc,oCAAoC,GAC7D;AACA,eAAK,KACF,cAAc,oCAAoC,GACjD,OAAO;AAAA,QACb;AAAA,MACF;AAGA,UAAI,CAAC,KAAK,WAAW;AACnB,mBAAW;AAAA,MACb;AAEA,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,IAAI,MAAM;AAAA,QACR,YAAY;AAAA,QACZ;AAAA,QACA,KAAK;AAAA,QACL;AAAA,UACE,OAAO,aAAa,MAAM,OAAO,OAAO,GAAG;AAAA,UAC3C,yBAAyB,aACtB,MAAM,OAAO,uBAAuB,GAAG;AAAA,UAC1C,qBAAqB,aAClB,MAAM,OAAO,mBAAmB,GAAG;AAAA,UACtC,aAAa,aAAa,MAAM,OAAO,WAAW,GAAG;AAAA,UACrD,oBAAoB,aACjB,MAAM,OAAO,kBAAkB,GAAG;AAAA,QACvC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,UAAI,CAAC,cAAc,GAAG;AACpB,eAAO,YAAY;AAAA,MACrB;AAEA,YAAM,UAAU,oBACZ,UAAU,iBAAoC,QAAQ,IACtD,IAAI;AAAA,QACF;AAAA,MACF;AACJ,UAAI,CAAC,KAAK;AACR,cAAM,IAAI;AAAA,UACR,UAAU,aAAa,YAAY,KAAK;AAAA,UACxC,OAAO,SAAS;AAAA,QAClB;AAAA,MACF;AAEA,YAAM,eAAe,MAAM,KAAK,OAAO,GAAG,KAAK,KAAK,QAAQ,KAAK,IAAI;AACrE,UAAI,CAAC,cAAc,GAAG;AACpB,eAAO,YAAY;AAAA,MACrB;AAGA,UAAI,mBAAmB;AACrB,cAAM,KAAK,UAAU,QAAQ,EAAE,QAAQ,CAAC,UAAU;AAChD,cAAI,MAAM,YAAY,UAAU;AAC9B,kBAAM,OAAO;AAAA,UACf;AAAA,QACF,CAAC;AAAA,MACH;AAIA,YAAM,YAAY,MAAM;AACtB,YAAI,KAAK,QAAQ,oBAAoB;AACnC,gBAAM,WAAW,+DAA+D;AAChF,gBAAM,cAAc;AAAA,YAClB,GAAG,KAAK,KAAK,iBAAiB,QAAQ;AAAA,YACtC,GAAG,SAAS,KAAK,iBAAiB,QAAQ;AAAA,UAC5C;AAEA,cAAI,YAAY,SAAS,GAAG;AAC1B,wBAAY,QAAQ,CAAC,SAAS;AAC5B,mBAAK,OAAO;AAAA,YACd,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAGA,UAAI,KAAK;AAEP,YAAI,eAAe,YAAY,GAAG;AAGlC,cAAM,UAAU,0BAA0B;AAAA,UACxC,IAAI;AAAA,QACN,KAAK,aAAa,KAAK,IAAI;AAC3B,cAAM,WAAW,SAAS,cAAc,QAAQ;AAChD,iBAAS,KAAK,GAAG;AACjB,iBAAS,cACP,IAAI,aAAa;AAAA,UACf,IAAI,OAAO,WAAW,KAAK,YAAY,GAAG;AAAA,UAC1C,SAAS;AAAA,QACX,KAAK;AACP,iBAAS,KAAK,YAAY,QAAQ;AAElC,YAAI;AAEJ,cAAM,oCAAoC,CAAC;AAAA,UACzC;AAAA,UACA;AAAA,QACF,MAGM;AAKJ,gBAAM,SAAS;AAAA,YACb;AAAA,YACA,KAAK,OAAiB,KAAK,CAAC;AAAA,CAAY;AAAA,UAC1C;AACA,gBAAM,YACJ;AAAA,WAEC,QAAQ,yBAAyB,MAAM;AAE1C,0BAAgB,MAAM;AAEpB,gBAAI,KAAK,IAAc,GAAG;AAExB,qBAAO,KAAK,IAAc;AAAA,YAC5B;AACA,kBAAM,YAAY,SAAS,eAAe,GAAG,UAAU;AACvD,gBAAI,WAAW;AACb,wBAAU,OAAO;AAAA,YACnB;AAEA,sBAAU;AACV,uBAAW;AACX,gBAAI,CAAC,SAAS;AACZ,6BAAe,EAAE,MAAM,CAAC,MAAe;AACrC,yBAAS,YAAY,2BAA2B,CAAC;AAAA,cACnD,CAAC;AAAA,YACH;AACA,gBAAI,cAAc,GAAG;AACnB,mBAAK,UAAU,QAAQ;AAAA,YACzB;AAEA,iBAAK,QAAQ,KAAK,KAAK,OAAO,EAAE;AAAA,UAClC,GAAG,CAAC,SAAS,IAAI,CAAC;AAGlB,iBAAO;AAAA,QACT;AAGA,YAAI,KAAK,WAAW;AAClB,gBAAM,OAAO,KAAK;AAClB,0BAAgB,MAAM;AACpB,iBAAK;AAAA,cACH;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAS;AAAA,kBACT,MAAM,KAAK;AAAA;AAAA,cACb;AAAA,YACF;AAAA,UACF,CAAC;AACD;AAAA,QACF;AAGA,aAAK,YAAY;AAAA;AAAA;AAAA,UAGf,kBAAkB,KAAK;AAAA,UACvB,oBAAC,qCAAkC,SAAO,MAAC,MAAM,KAAK,MAAM;AAAA,QAC9D;AAAA,MACF,WAAW,UAAU;AAEnB,cAAM,EAAE,WAAW,IAAI,IAAI;AAAA,UACzB,KAAK;AAAA,UACL,SAAS,QAAQ;AAAA,UACjB,KAAK;AAAA,QACP;AAGA,YAAI,WAAW;AACb,gBAAM,2BAA2B,CAC/B,SACA,eAGA,kBAAkB,SAElB,SAAS,oBAAoB,EAAE,QAAQ,GAAyB;AAC9D,4BAAgB,MAAM;AACpB,wBAAU;AACV,kBAAI,CAAC,SAAS;AACZ,2BAAW;AACX,+BAAe,EAAE,MAAM,CAAC,MAAe;AACrC,2BAAS,YAAY,2BAA2B,CAAC;AAAA,gBACnD,CAAC;AAAA,cACH;AACA,kBAAI,cAAc,GAAG;AACnB,gCAAgB,UAAU,QAAQ;AAAA,cACpC;AAEA,8BAAgB,QAAQ,KAAK,gBAAgB,OAAO,EAAE;AAAA,YACxD,GAAG,CAAC,SAAS,eAAe,CAAC;AAE7B,mBAAO,UACL,oBAAC,WAAQ,WAAW,eAAgB,GAAG,SAAS,OAAO,IAEvD,oBAAC,iBAAe,GAAG,SAAS,OAAO;AAAA,UAEvC,GAAG,KAAK,WAAW,IAAI;AAGzB,cAAI,KAAK,WAAW;AAClB,kBAAM,OAAO,KAAK;AAClB,4BAAgB,MAAM;AACpB,mBAAK,OAAO,oBAAC,2BAAwB,SAAS,OAAO,CAAE;AACvD,wBAAU;AACV,kBAAI,cAAc,GAAG;AACnB,qBAAK,UAAU,QAAQ;AAAA,cACzB;AAAA,YACF,CAAC;AACD;AAAA,UACF;AAGA,eAAK,YAAY;AAAA;AAAA;AAAA,YAGf,kBAAkB,KAAK;AAAA,YACvB,oBAAC,2BAAwB,SAAO,MAAC;AAAA,UACnC;AAAA,QACF;AAIA,YAAI,KAAK,MAAM;AACb,eAAK,KAAK,YAAY,KAAK,IAAI;AAAA,QACjC;AAAA,MACF,WAAW,aAAa,EAAE,SAAS,IAAI,IAAI,GAAG;AAE5C,cAAM,QAAQ;AAAA,UACZ,MAAM,KAAK,aAAa,EAAE,SAAS,IAAI,IAAI,KAAK,CAAC,CAAC,EAAE;AAAA,YAClD,OAAO,UAAU;AACf,kBAAI;AACF,sBAAM,MAAM,KAAK,IAAI;AAAA,cACvB,SAAS,GAAP;AACA;AAAA,kBACE;AAAA,kBACA,yDAAyD,IAAI;AAAA,kBAC7D;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,aAAK,QAAQ,KAAK,KAAK,OAAO,EAAE;AAAA,MAClC,OAAO;AACL,aAAK,QAAQ,KAAK,KAAK,OAAO,EAAE;AAAA,MAClC;AAEA,UAAI,cAAc,GAAG;AACnB,aAAK,UAAU,QAAQ;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAGA,iBAAe,OAAO,oBAAoB,eAAe;AAC3D;AAEO,SAAS,sBACd,UAAkD,CAAC,GACnD;AACA,QAAM,KAAK,aAAa;AACxB,SAAO,QAAQ,OAAO,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAChD,OAAG,kBAAkB,GAAG,IAAI;AAAA,EAC9B,CAAC;AACH;","names":[]}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var _chunkYSJ4FKGIcjs = require('../../../chunk-YSJ4FKGI.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkHXCW3WDTcjs = require('../../../chunk-HXCW3WDT.cjs');
|
|
8
8
|
require('../../../chunk-XWRB6CEA.cjs');
|
|
9
|
-
require('../../../chunk-
|
|
10
|
-
require('../../../chunk-
|
|
9
|
+
require('../../../chunk-TGE3K3TR.cjs');
|
|
10
|
+
require('../../../chunk-SULMNRMJ.cjs');
|
|
11
11
|
require('../../../chunk-3AX5WLZD.cjs');
|
|
12
12
|
require('../../../chunk-N3SQTOSE.cjs');
|
|
13
13
|
|
|
@@ -32,7 +32,7 @@ function resolveForBundle(unbound, bundle) {
|
|
|
32
32
|
if (!unbound)
|
|
33
33
|
return void 0;
|
|
34
34
|
const remoteSrc = _nullishCoalesce(_optionalChain([_chunk6PZEDIAKcjs.getScope.call(void 0, bundle), 'optionalAccess', _2 => _2.url, 'access', _3 => _3.href]), () => ( ""));
|
|
35
|
-
return
|
|
35
|
+
return _chunkHXCW3WDTcjs.bindResolveClientUrl.call(void 0, unbound, remoteSrc);
|
|
36
36
|
}
|
|
37
37
|
function createImageLoaderSharedEntries({
|
|
38
38
|
bound,
|
|
@@ -191,7 +191,7 @@ function ConsumeRemoteComponent2(props) {
|
|
|
191
191
|
return _nullishCoalesce(props.children, () => ( null));
|
|
192
192
|
}
|
|
193
193
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
194
|
-
|
|
194
|
+
_chunkYSJ4FKGIcjs.ConsumeRemoteComponent,
|
|
195
195
|
{
|
|
196
196
|
...props,
|
|
197
197
|
shared: sharedModules(props.shared, props.resolveClientUrl)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
ConsumeRemoteComponent
|
|
4
|
-
} from "../../../chunk-
|
|
4
|
+
} from "../../../chunk-CLO56ON2.js";
|
|
5
5
|
import {
|
|
6
6
|
bindResolveClientUrl
|
|
7
|
-
} from "../../../chunk-
|
|
7
|
+
} from "../../../chunk-RZGFQTX6.js";
|
|
8
8
|
import "../../../chunk-M6ACTSVB.js";
|
|
9
|
-
import "../../../chunk-
|
|
10
|
-
import "../../../chunk-
|
|
9
|
+
import "../../../chunk-24LEEDHP.js";
|
|
10
|
+
import "../../../chunk-BEGVH64U.js";
|
|
11
11
|
import "../../../chunk-LEKG4YWI.js";
|
|
12
12
|
import "../../../chunk-RHGEBXPL.js";
|
|
13
13
|
import {
|
package/dist/host/react.cjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
require('../chunk-
|
|
4
|
+
var _chunkYSJ4FKGIcjs = require('../chunk-YSJ4FKGI.cjs');
|
|
5
|
+
require('../chunk-HXCW3WDT.cjs');
|
|
6
6
|
require('../chunk-XWRB6CEA.cjs');
|
|
7
|
-
require('../chunk-
|
|
8
|
-
require('../chunk-
|
|
7
|
+
require('../chunk-TGE3K3TR.cjs');
|
|
8
|
+
require('../chunk-SULMNRMJ.cjs');
|
|
9
9
|
require('../chunk-3AX5WLZD.cjs');
|
|
10
10
|
require('../chunk-N3SQTOSE.cjs');
|
|
11
11
|
require('../chunk-6PZEDIAK.cjs');
|
|
@@ -18,5 +18,5 @@ require('../chunk-SHFJ5OQA.cjs');
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
exports.ConsumeRemoteComponent =
|
|
21
|
+
exports.ConsumeRemoteComponent = _chunkYSJ4FKGIcjs.ConsumeRemoteComponent; exports.useRemoteNavigate = _chunkYSJ4FKGIcjs.useRemoteNavigate;
|
|
22
22
|
//# sourceMappingURL=react.cjs.map
|
package/dist/host/react.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ConsumeRemoteComponent,
|
|
3
3
|
useRemoteNavigate
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-CLO56ON2.js";
|
|
5
|
+
import "../chunk-RZGFQTX6.js";
|
|
6
6
|
import "../chunk-M6ACTSVB.js";
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-24LEEDHP.js";
|
|
8
|
+
import "../chunk-BEGVH64U.js";
|
|
9
9
|
import "../chunk-LEKG4YWI.js";
|
|
10
10
|
import "../chunk-RHGEBXPL.js";
|
|
11
11
|
import "../chunk-3PR3SWYZ.js";
|
|
@@ -75,9 +75,18 @@ async function buildSharedProviderPlan({
|
|
|
75
75
|
additionalEntries = [],
|
|
76
76
|
onMissing
|
|
77
77
|
}) {
|
|
78
|
+
let hostSharedForPlan = hostShared;
|
|
79
|
+
if (additionalEntries.length > 0) {
|
|
80
|
+
hostSharedForPlan = { ...hostShared };
|
|
81
|
+
for (const entry of additionalEntries) {
|
|
82
|
+
if (typeof entry.value !== "undefined" && !(entry.specifier in hostSharedForPlan)) {
|
|
83
|
+
hostSharedForPlan[entry.specifier] = entry.value;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
78
87
|
const sharedModulePlan = (0, import_shared_broker.createSharedModulePlan)({
|
|
79
88
|
bundle,
|
|
80
|
-
hostShared,
|
|
89
|
+
hostShared: hostSharedForPlan,
|
|
81
90
|
remoteShared,
|
|
82
91
|
scope,
|
|
83
92
|
callerTag
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/host/shared/provider.ts"],"sourcesContent":["import {\n createSharedModulePlan,\n type RemoteSharedModules,\n resolveSharedModulePlan,\n SHARED_MODULE_MANIFEST_PROTOCOL,\n type SharedModuleFactory,\n type SharedModuleResolution,\n} from '#internal/host/shared/shared-broker';\nimport type { LogLocation } from '#internal/utils/logger';\n\nconst DEFAULT_VERSION = '0';\nconst GLOBAL_PROVIDER_SCOPES_KEY =\n '__remote_components_shared_provider_scopes__';\n\nexport interface SharedProvider {\n get: () => unknown;\n from: string;\n eager?: boolean;\n loaded?: boolean | number;\n}\n\nexport type SharedProviderScope = Record<\n string,\n Record<string, SharedProvider>\n>;\n\nexport type SharedProviderScopes = Record<string, SharedProviderScope>;\n\nexport interface SharedProviderEntry {\n id: string;\n specifier: string;\n provider: SharedProvider;\n required: boolean;\n singleton: boolean;\n scope: string;\n}\n\nexport interface SharedProviderPlan {\n protocol: 'legacy' | typeof SHARED_MODULE_MANIFEST_PROTOCOL;\n entries: SharedProviderEntry[];\n}\n\nexport interface AdditionalSharedProviderEntry {\n id: string;\n specifier: string;\n value: unknown;\n required?: boolean;\n singleton?: boolean;\n scope?: string;\n from?: string;\n}\n\nfunction getProviderScopes(): SharedProviderScopes {\n const self = globalThis as typeof globalThis & {\n [GLOBAL_PROVIDER_SCOPES_KEY]?: SharedProviderScopes;\n };\n self[GLOBAL_PROVIDER_SCOPES_KEY] ??= {};\n return self[GLOBAL_PROVIDER_SCOPES_KEY];\n}\n\nexport function createSharedProvider({\n value,\n from,\n}: {\n value: unknown;\n from: string;\n}): SharedProvider {\n return {\n get: () => value,\n from,\n eager: true,\n loaded: 1,\n };\n}\n\nexport function createSharedProviderEntry({\n id,\n specifier,\n value,\n required = true,\n singleton = true,\n scope,\n from = 'host',\n}: AdditionalSharedProviderEntry & { scope: string }): SharedProviderEntry {\n return {\n id,\n specifier,\n provider: createSharedProvider({ value, from }),\n required,\n singleton,\n scope,\n };\n}\n\nexport async function buildSharedProviderPlan({\n bundle,\n hostShared,\n remoteShared,\n scope = `remote:${bundle}`,\n callerTag = 'SharedBroker',\n normalizeId = (id) => id,\n additionalEntries = [],\n onMissing,\n}: {\n bundle: string;\n hostShared: Record<string, SharedModuleFactory | unknown>;\n remoteShared: RemoteSharedModules;\n scope?: string;\n callerTag?: LogLocation;\n normalizeId?: (id: string) => string;\n additionalEntries?: AdditionalSharedProviderEntry[];\n onMissing?: (entry: SharedModuleResolution) => void;\n}): Promise<SharedProviderPlan> {\n const sharedModulePlan = createSharedModulePlan({\n bundle,\n hostShared,\n remoteShared,\n scope,\n callerTag,\n });\n const resolved = await resolveSharedModulePlan(sharedModulePlan);\n const entriesByIdAndSpecifier = new Map<string, SharedProviderEntry>();\n const addEntry = (entry: SharedProviderEntry) => {\n entriesByIdAndSpecifier.set(`${entry.id}\\0${entry.specifier}`, entry);\n };\n\n for (const entry of additionalEntries) {\n addEntry(\n createSharedProviderEntry({\n ...entry,\n scope: entry.scope ?? scope,\n }),\n );\n }\n\n for (const entry of sharedModulePlan.entries) {\n if (entry.status !== 'resolved') {\n if (\n onMissing &&\n !(\n sharedModulePlan.protocol === SHARED_MODULE_MANIFEST_PROTOCOL &&\n entry.required\n )\n ) {\n onMissing(entry);\n }\n continue;\n }\n\n const value = resolved[entry.id];\n if (typeof value === 'undefined') continue;\n addEntry(\n createSharedProviderEntry({\n id: normalizeId(entry.id),\n specifier: entry.specifier,\n value,\n required: entry.required,\n singleton: entry.singleton,\n scope: entry.scope,\n }),\n );\n }\n\n return {\n protocol: sharedModulePlan.protocol,\n entries: Array.from(entriesByIdAndSpecifier.values()),\n };\n}\n\nexport function installSharedProvider({\n scope,\n specifier,\n value,\n from,\n provider,\n version = DEFAULT_VERSION,\n}: {\n scope: string;\n specifier: string;\n value?: unknown;\n from?: string;\n provider?: SharedProvider;\n version?: string;\n}): SharedProvider {\n const scopes = getProviderScopes();\n const providerScope = (scopes[scope] ??= {});\n const versions = (providerScope[specifier] ??= {});\n const sharedProvider =\n provider ??\n createSharedProvider({\n value,\n from: from ?? 'host',\n });\n versions[version] = sharedProvider;\n return sharedProvider;\n}\n\nexport function installSharedProviderEntry(\n entry: SharedProviderEntry,\n): SharedProvider {\n return installSharedProvider({\n scope: entry.scope,\n specifier: entry.specifier,\n provider: entry.provider,\n });\n}\n\nexport function getSharedProvider({\n scope,\n specifier,\n version = DEFAULT_VERSION,\n}: {\n scope: string;\n specifier: string;\n version?: string;\n}): SharedProvider | undefined {\n const versions = getProviderScopes()[scope]?.[specifier];\n if (!versions) return undefined;\n\n // This provider scope does not implement semver negotiation. Use an exact\n // version match, then the host default provider when a constrained version is\n // unavailable.\n return (\n versions[version] ??\n (version === DEFAULT_VERSION ? undefined : versions[DEFAULT_VERSION])\n );\n}\n\nexport function getSharedProviderModule({\n scope,\n specifier,\n version,\n}: {\n scope: string;\n specifier: string;\n version?: string;\n}): unknown {\n const provider = getSharedProvider({ scope, specifier, version });\n if (!provider) {\n throw new Error(\n `Shared module \"${specifier}\" not found in provider scope \"${scope}\".`,\n );\n }\n provider.loaded = 1;\n return provider.get();\n}\n\nexport function resetSharedProviderScopesForTest(): void {\n const self = globalThis as typeof globalThis & {\n [GLOBAL_PROVIDER_SCOPES_KEY]?: SharedProviderScopes;\n };\n delete self[GLOBAL_PROVIDER_SCOPES_KEY];\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/shared/provider.ts"],"sourcesContent":["import {\n createSharedModulePlan,\n type RemoteSharedModules,\n resolveSharedModulePlan,\n SHARED_MODULE_MANIFEST_PROTOCOL,\n type SharedModuleFactory,\n type SharedModuleResolution,\n} from '#internal/host/shared/shared-broker';\nimport type { LogLocation } from '#internal/utils/logger';\n\nconst DEFAULT_VERSION = '0';\nconst GLOBAL_PROVIDER_SCOPES_KEY =\n '__remote_components_shared_provider_scopes__';\n\nexport interface SharedProvider {\n get: () => unknown;\n from: string;\n eager?: boolean;\n loaded?: boolean | number;\n}\n\nexport type SharedProviderScope = Record<\n string,\n Record<string, SharedProvider>\n>;\n\nexport type SharedProviderScopes = Record<string, SharedProviderScope>;\n\nexport interface SharedProviderEntry {\n id: string;\n specifier: string;\n provider: SharedProvider;\n required: boolean;\n singleton: boolean;\n scope: string;\n}\n\nexport interface SharedProviderPlan {\n protocol: 'legacy' | typeof SHARED_MODULE_MANIFEST_PROTOCOL;\n entries: SharedProviderEntry[];\n}\n\nexport interface AdditionalSharedProviderEntry {\n id: string;\n specifier: string;\n value: unknown;\n required?: boolean;\n singleton?: boolean;\n scope?: string;\n from?: string;\n}\n\nfunction getProviderScopes(): SharedProviderScopes {\n const self = globalThis as typeof globalThis & {\n [GLOBAL_PROVIDER_SCOPES_KEY]?: SharedProviderScopes;\n };\n self[GLOBAL_PROVIDER_SCOPES_KEY] ??= {};\n return self[GLOBAL_PROVIDER_SCOPES_KEY];\n}\n\nexport function createSharedProvider({\n value,\n from,\n}: {\n value: unknown;\n from: string;\n}): SharedProvider {\n return {\n get: () => value,\n from,\n eager: true,\n loaded: 1,\n };\n}\n\nexport function createSharedProviderEntry({\n id,\n specifier,\n value,\n required = true,\n singleton = true,\n scope,\n from = 'host',\n}: AdditionalSharedProviderEntry & { scope: string }): SharedProviderEntry {\n return {\n id,\n specifier,\n provider: createSharedProvider({ value, from }),\n required,\n singleton,\n scope,\n };\n}\n\nexport async function buildSharedProviderPlan({\n bundle,\n hostShared,\n remoteShared,\n scope = `remote:${bundle}`,\n callerTag = 'SharedBroker',\n normalizeId = (id) => id,\n additionalEntries = [],\n onMissing,\n}: {\n bundle: string;\n hostShared: Record<string, SharedModuleFactory | unknown>;\n remoteShared: RemoteSharedModules;\n scope?: string;\n callerTag?: LogLocation;\n normalizeId?: (id: string) => string;\n additionalEntries?: AdditionalSharedProviderEntry[];\n onMissing?: (entry: SharedModuleResolution) => void;\n}): Promise<SharedProviderPlan> {\n // `additionalEntries` are host-provided fallbacks (e.g. the host's own React\n // in the Webpack runtime, where core React is supplied here rather than\n // through `hostShared`). They satisfy remote requirements just like\n // `hostShared`, so fold them into the lookup the broker uses to build the\n // plan. Without this, a requirement met only by an additional entry is\n // marked \"missing\" and `resolveSharedModulePlan` emits a spurious\n // \"requires shared module ... but the host does not provide it\" diagnostic,\n // even though the module is provided a few lines below. Explicit `hostShared`\n // entries take precedence over these fallbacks.\n let hostSharedForPlan = hostShared;\n if (additionalEntries.length > 0) {\n hostSharedForPlan = { ...hostShared };\n for (const entry of additionalEntries) {\n if (\n typeof entry.value !== 'undefined' &&\n !(entry.specifier in hostSharedForPlan)\n ) {\n hostSharedForPlan[entry.specifier] = entry.value;\n }\n }\n }\n\n const sharedModulePlan = createSharedModulePlan({\n bundle,\n hostShared: hostSharedForPlan,\n remoteShared,\n scope,\n callerTag,\n });\n const resolved = await resolveSharedModulePlan(sharedModulePlan);\n const entriesByIdAndSpecifier = new Map<string, SharedProviderEntry>();\n const addEntry = (entry: SharedProviderEntry) => {\n entriesByIdAndSpecifier.set(`${entry.id}\\0${entry.specifier}`, entry);\n };\n\n for (const entry of additionalEntries) {\n addEntry(\n createSharedProviderEntry({\n ...entry,\n scope: entry.scope ?? scope,\n }),\n );\n }\n\n for (const entry of sharedModulePlan.entries) {\n if (entry.status !== 'resolved') {\n if (\n onMissing &&\n !(\n sharedModulePlan.protocol === SHARED_MODULE_MANIFEST_PROTOCOL &&\n entry.required\n )\n ) {\n onMissing(entry);\n }\n continue;\n }\n\n const value = resolved[entry.id];\n if (typeof value === 'undefined') continue;\n addEntry(\n createSharedProviderEntry({\n id: normalizeId(entry.id),\n specifier: entry.specifier,\n value,\n required: entry.required,\n singleton: entry.singleton,\n scope: entry.scope,\n }),\n );\n }\n\n return {\n protocol: sharedModulePlan.protocol,\n entries: Array.from(entriesByIdAndSpecifier.values()),\n };\n}\n\nexport function installSharedProvider({\n scope,\n specifier,\n value,\n from,\n provider,\n version = DEFAULT_VERSION,\n}: {\n scope: string;\n specifier: string;\n value?: unknown;\n from?: string;\n provider?: SharedProvider;\n version?: string;\n}): SharedProvider {\n const scopes = getProviderScopes();\n const providerScope = (scopes[scope] ??= {});\n const versions = (providerScope[specifier] ??= {});\n const sharedProvider =\n provider ??\n createSharedProvider({\n value,\n from: from ?? 'host',\n });\n versions[version] = sharedProvider;\n return sharedProvider;\n}\n\nexport function installSharedProviderEntry(\n entry: SharedProviderEntry,\n): SharedProvider {\n return installSharedProvider({\n scope: entry.scope,\n specifier: entry.specifier,\n provider: entry.provider,\n });\n}\n\nexport function getSharedProvider({\n scope,\n specifier,\n version = DEFAULT_VERSION,\n}: {\n scope: string;\n specifier: string;\n version?: string;\n}): SharedProvider | undefined {\n const versions = getProviderScopes()[scope]?.[specifier];\n if (!versions) return undefined;\n\n // This provider scope does not implement semver negotiation. Use an exact\n // version match, then the host default provider when a constrained version is\n // unavailable.\n return (\n versions[version] ??\n (version === DEFAULT_VERSION ? undefined : versions[DEFAULT_VERSION])\n );\n}\n\nexport function getSharedProviderModule({\n scope,\n specifier,\n version,\n}: {\n scope: string;\n specifier: string;\n version?: string;\n}): unknown {\n const provider = getSharedProvider({ scope, specifier, version });\n if (!provider) {\n throw new Error(\n `Shared module \"${specifier}\" not found in provider scope \"${scope}\".`,\n );\n }\n provider.loaded = 1;\n return provider.get();\n}\n\nexport function resetSharedProviderScopesForTest(): void {\n const self = globalThis as typeof globalThis & {\n [GLOBAL_PROVIDER_SCOPES_KEY]?: SharedProviderScopes;\n };\n delete self[GLOBAL_PROVIDER_SCOPES_KEY];\n}\n"],"mappings":"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","names":[]}
|
|
@@ -49,9 +49,18 @@ async function buildSharedProviderPlan({
|
|
|
49
49
|
additionalEntries = [],
|
|
50
50
|
onMissing
|
|
51
51
|
}) {
|
|
52
|
+
let hostSharedForPlan = hostShared;
|
|
53
|
+
if (additionalEntries.length > 0) {
|
|
54
|
+
hostSharedForPlan = { ...hostShared };
|
|
55
|
+
for (const entry of additionalEntries) {
|
|
56
|
+
if (typeof entry.value !== "undefined" && !(entry.specifier in hostSharedForPlan)) {
|
|
57
|
+
hostSharedForPlan[entry.specifier] = entry.value;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
52
61
|
const sharedModulePlan = createSharedModulePlan({
|
|
53
62
|
bundle,
|
|
54
|
-
hostShared,
|
|
63
|
+
hostShared: hostSharedForPlan,
|
|
55
64
|
remoteShared,
|
|
56
65
|
scope,
|
|
57
66
|
callerTag
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/host/shared/provider.ts"],"sourcesContent":["import {\n createSharedModulePlan,\n type RemoteSharedModules,\n resolveSharedModulePlan,\n SHARED_MODULE_MANIFEST_PROTOCOL,\n type SharedModuleFactory,\n type SharedModuleResolution,\n} from '#internal/host/shared/shared-broker';\nimport type { LogLocation } from '#internal/utils/logger';\n\nconst DEFAULT_VERSION = '0';\nconst GLOBAL_PROVIDER_SCOPES_KEY =\n '__remote_components_shared_provider_scopes__';\n\nexport interface SharedProvider {\n get: () => unknown;\n from: string;\n eager?: boolean;\n loaded?: boolean | number;\n}\n\nexport type SharedProviderScope = Record<\n string,\n Record<string, SharedProvider>\n>;\n\nexport type SharedProviderScopes = Record<string, SharedProviderScope>;\n\nexport interface SharedProviderEntry {\n id: string;\n specifier: string;\n provider: SharedProvider;\n required: boolean;\n singleton: boolean;\n scope: string;\n}\n\nexport interface SharedProviderPlan {\n protocol: 'legacy' | typeof SHARED_MODULE_MANIFEST_PROTOCOL;\n entries: SharedProviderEntry[];\n}\n\nexport interface AdditionalSharedProviderEntry {\n id: string;\n specifier: string;\n value: unknown;\n required?: boolean;\n singleton?: boolean;\n scope?: string;\n from?: string;\n}\n\nfunction getProviderScopes(): SharedProviderScopes {\n const self = globalThis as typeof globalThis & {\n [GLOBAL_PROVIDER_SCOPES_KEY]?: SharedProviderScopes;\n };\n self[GLOBAL_PROVIDER_SCOPES_KEY] ??= {};\n return self[GLOBAL_PROVIDER_SCOPES_KEY];\n}\n\nexport function createSharedProvider({\n value,\n from,\n}: {\n value: unknown;\n from: string;\n}): SharedProvider {\n return {\n get: () => value,\n from,\n eager: true,\n loaded: 1,\n };\n}\n\nexport function createSharedProviderEntry({\n id,\n specifier,\n value,\n required = true,\n singleton = true,\n scope,\n from = 'host',\n}: AdditionalSharedProviderEntry & { scope: string }): SharedProviderEntry {\n return {\n id,\n specifier,\n provider: createSharedProvider({ value, from }),\n required,\n singleton,\n scope,\n };\n}\n\nexport async function buildSharedProviderPlan({\n bundle,\n hostShared,\n remoteShared,\n scope = `remote:${bundle}`,\n callerTag = 'SharedBroker',\n normalizeId = (id) => id,\n additionalEntries = [],\n onMissing,\n}: {\n bundle: string;\n hostShared: Record<string, SharedModuleFactory | unknown>;\n remoteShared: RemoteSharedModules;\n scope?: string;\n callerTag?: LogLocation;\n normalizeId?: (id: string) => string;\n additionalEntries?: AdditionalSharedProviderEntry[];\n onMissing?: (entry: SharedModuleResolution) => void;\n}): Promise<SharedProviderPlan> {\n const sharedModulePlan = createSharedModulePlan({\n bundle,\n hostShared,\n remoteShared,\n scope,\n callerTag,\n });\n const resolved = await resolveSharedModulePlan(sharedModulePlan);\n const entriesByIdAndSpecifier = new Map<string, SharedProviderEntry>();\n const addEntry = (entry: SharedProviderEntry) => {\n entriesByIdAndSpecifier.set(`${entry.id}\\0${entry.specifier}`, entry);\n };\n\n for (const entry of additionalEntries) {\n addEntry(\n createSharedProviderEntry({\n ...entry,\n scope: entry.scope ?? scope,\n }),\n );\n }\n\n for (const entry of sharedModulePlan.entries) {\n if (entry.status !== 'resolved') {\n if (\n onMissing &&\n !(\n sharedModulePlan.protocol === SHARED_MODULE_MANIFEST_PROTOCOL &&\n entry.required\n )\n ) {\n onMissing(entry);\n }\n continue;\n }\n\n const value = resolved[entry.id];\n if (typeof value === 'undefined') continue;\n addEntry(\n createSharedProviderEntry({\n id: normalizeId(entry.id),\n specifier: entry.specifier,\n value,\n required: entry.required,\n singleton: entry.singleton,\n scope: entry.scope,\n }),\n );\n }\n\n return {\n protocol: sharedModulePlan.protocol,\n entries: Array.from(entriesByIdAndSpecifier.values()),\n };\n}\n\nexport function installSharedProvider({\n scope,\n specifier,\n value,\n from,\n provider,\n version = DEFAULT_VERSION,\n}: {\n scope: string;\n specifier: string;\n value?: unknown;\n from?: string;\n provider?: SharedProvider;\n version?: string;\n}): SharedProvider {\n const scopes = getProviderScopes();\n const providerScope = (scopes[scope] ??= {});\n const versions = (providerScope[specifier] ??= {});\n const sharedProvider =\n provider ??\n createSharedProvider({\n value,\n from: from ?? 'host',\n });\n versions[version] = sharedProvider;\n return sharedProvider;\n}\n\nexport function installSharedProviderEntry(\n entry: SharedProviderEntry,\n): SharedProvider {\n return installSharedProvider({\n scope: entry.scope,\n specifier: entry.specifier,\n provider: entry.provider,\n });\n}\n\nexport function getSharedProvider({\n scope,\n specifier,\n version = DEFAULT_VERSION,\n}: {\n scope: string;\n specifier: string;\n version?: string;\n}): SharedProvider | undefined {\n const versions = getProviderScopes()[scope]?.[specifier];\n if (!versions) return undefined;\n\n // This provider scope does not implement semver negotiation. Use an exact\n // version match, then the host default provider when a constrained version is\n // unavailable.\n return (\n versions[version] ??\n (version === DEFAULT_VERSION ? undefined : versions[DEFAULT_VERSION])\n );\n}\n\nexport function getSharedProviderModule({\n scope,\n specifier,\n version,\n}: {\n scope: string;\n specifier: string;\n version?: string;\n}): unknown {\n const provider = getSharedProvider({ scope, specifier, version });\n if (!provider) {\n throw new Error(\n `Shared module \"${specifier}\" not found in provider scope \"${scope}\".`,\n );\n }\n provider.loaded = 1;\n return provider.get();\n}\n\nexport function resetSharedProviderScopesForTest(): void {\n const self = globalThis as typeof globalThis & {\n [GLOBAL_PROVIDER_SCOPES_KEY]?: SharedProviderScopes;\n };\n delete self[GLOBAL_PROVIDER_SCOPES_KEY];\n}\n"],"mappings":"AAAA;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,OAGK;AAGP,MAAM,kBAAkB;AACxB,MAAM,6BACJ;AAwCF,SAAS,oBAA0C;AACjD,QAAM,OAAO;AAGb,OAAK,0BAA0B,MAAM,CAAC;AACtC,SAAO,KAAK,0BAA0B;AACxC;AAEO,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AACF,GAGmB;AACjB,SAAO;AAAA,IACL,KAAK,MAAM;AAAA,IACX;AAAA,IACA,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AACF;AAEO,SAAS,0BAA0B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,YAAY;AAAA,EACZ;AAAA,EACA,OAAO;AACT,GAA2E;AACzE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU,qBAAqB,EAAE,OAAO,KAAK,CAAC;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,wBAAwB;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ,UAAU;AAAA,EAClB,YAAY;AAAA,EACZ,cAAc,CAAC,OAAO;AAAA,EACtB,oBAAoB,CAAC;AAAA,EACrB;AACF,GASgC;
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/shared/provider.ts"],"sourcesContent":["import {\n createSharedModulePlan,\n type RemoteSharedModules,\n resolveSharedModulePlan,\n SHARED_MODULE_MANIFEST_PROTOCOL,\n type SharedModuleFactory,\n type SharedModuleResolution,\n} from '#internal/host/shared/shared-broker';\nimport type { LogLocation } from '#internal/utils/logger';\n\nconst DEFAULT_VERSION = '0';\nconst GLOBAL_PROVIDER_SCOPES_KEY =\n '__remote_components_shared_provider_scopes__';\n\nexport interface SharedProvider {\n get: () => unknown;\n from: string;\n eager?: boolean;\n loaded?: boolean | number;\n}\n\nexport type SharedProviderScope = Record<\n string,\n Record<string, SharedProvider>\n>;\n\nexport type SharedProviderScopes = Record<string, SharedProviderScope>;\n\nexport interface SharedProviderEntry {\n id: string;\n specifier: string;\n provider: SharedProvider;\n required: boolean;\n singleton: boolean;\n scope: string;\n}\n\nexport interface SharedProviderPlan {\n protocol: 'legacy' | typeof SHARED_MODULE_MANIFEST_PROTOCOL;\n entries: SharedProviderEntry[];\n}\n\nexport interface AdditionalSharedProviderEntry {\n id: string;\n specifier: string;\n value: unknown;\n required?: boolean;\n singleton?: boolean;\n scope?: string;\n from?: string;\n}\n\nfunction getProviderScopes(): SharedProviderScopes {\n const self = globalThis as typeof globalThis & {\n [GLOBAL_PROVIDER_SCOPES_KEY]?: SharedProviderScopes;\n };\n self[GLOBAL_PROVIDER_SCOPES_KEY] ??= {};\n return self[GLOBAL_PROVIDER_SCOPES_KEY];\n}\n\nexport function createSharedProvider({\n value,\n from,\n}: {\n value: unknown;\n from: string;\n}): SharedProvider {\n return {\n get: () => value,\n from,\n eager: true,\n loaded: 1,\n };\n}\n\nexport function createSharedProviderEntry({\n id,\n specifier,\n value,\n required = true,\n singleton = true,\n scope,\n from = 'host',\n}: AdditionalSharedProviderEntry & { scope: string }): SharedProviderEntry {\n return {\n id,\n specifier,\n provider: createSharedProvider({ value, from }),\n required,\n singleton,\n scope,\n };\n}\n\nexport async function buildSharedProviderPlan({\n bundle,\n hostShared,\n remoteShared,\n scope = `remote:${bundle}`,\n callerTag = 'SharedBroker',\n normalizeId = (id) => id,\n additionalEntries = [],\n onMissing,\n}: {\n bundle: string;\n hostShared: Record<string, SharedModuleFactory | unknown>;\n remoteShared: RemoteSharedModules;\n scope?: string;\n callerTag?: LogLocation;\n normalizeId?: (id: string) => string;\n additionalEntries?: AdditionalSharedProviderEntry[];\n onMissing?: (entry: SharedModuleResolution) => void;\n}): Promise<SharedProviderPlan> {\n // `additionalEntries` are host-provided fallbacks (e.g. the host's own React\n // in the Webpack runtime, where core React is supplied here rather than\n // through `hostShared`). They satisfy remote requirements just like\n // `hostShared`, so fold them into the lookup the broker uses to build the\n // plan. Without this, a requirement met only by an additional entry is\n // marked \"missing\" and `resolveSharedModulePlan` emits a spurious\n // \"requires shared module ... but the host does not provide it\" diagnostic,\n // even though the module is provided a few lines below. Explicit `hostShared`\n // entries take precedence over these fallbacks.\n let hostSharedForPlan = hostShared;\n if (additionalEntries.length > 0) {\n hostSharedForPlan = { ...hostShared };\n for (const entry of additionalEntries) {\n if (\n typeof entry.value !== 'undefined' &&\n !(entry.specifier in hostSharedForPlan)\n ) {\n hostSharedForPlan[entry.specifier] = entry.value;\n }\n }\n }\n\n const sharedModulePlan = createSharedModulePlan({\n bundle,\n hostShared: hostSharedForPlan,\n remoteShared,\n scope,\n callerTag,\n });\n const resolved = await resolveSharedModulePlan(sharedModulePlan);\n const entriesByIdAndSpecifier = new Map<string, SharedProviderEntry>();\n const addEntry = (entry: SharedProviderEntry) => {\n entriesByIdAndSpecifier.set(`${entry.id}\\0${entry.specifier}`, entry);\n };\n\n for (const entry of additionalEntries) {\n addEntry(\n createSharedProviderEntry({\n ...entry,\n scope: entry.scope ?? scope,\n }),\n );\n }\n\n for (const entry of sharedModulePlan.entries) {\n if (entry.status !== 'resolved') {\n if (\n onMissing &&\n !(\n sharedModulePlan.protocol === SHARED_MODULE_MANIFEST_PROTOCOL &&\n entry.required\n )\n ) {\n onMissing(entry);\n }\n continue;\n }\n\n const value = resolved[entry.id];\n if (typeof value === 'undefined') continue;\n addEntry(\n createSharedProviderEntry({\n id: normalizeId(entry.id),\n specifier: entry.specifier,\n value,\n required: entry.required,\n singleton: entry.singleton,\n scope: entry.scope,\n }),\n );\n }\n\n return {\n protocol: sharedModulePlan.protocol,\n entries: Array.from(entriesByIdAndSpecifier.values()),\n };\n}\n\nexport function installSharedProvider({\n scope,\n specifier,\n value,\n from,\n provider,\n version = DEFAULT_VERSION,\n}: {\n scope: string;\n specifier: string;\n value?: unknown;\n from?: string;\n provider?: SharedProvider;\n version?: string;\n}): SharedProvider {\n const scopes = getProviderScopes();\n const providerScope = (scopes[scope] ??= {});\n const versions = (providerScope[specifier] ??= {});\n const sharedProvider =\n provider ??\n createSharedProvider({\n value,\n from: from ?? 'host',\n });\n versions[version] = sharedProvider;\n return sharedProvider;\n}\n\nexport function installSharedProviderEntry(\n entry: SharedProviderEntry,\n): SharedProvider {\n return installSharedProvider({\n scope: entry.scope,\n specifier: entry.specifier,\n provider: entry.provider,\n });\n}\n\nexport function getSharedProvider({\n scope,\n specifier,\n version = DEFAULT_VERSION,\n}: {\n scope: string;\n specifier: string;\n version?: string;\n}): SharedProvider | undefined {\n const versions = getProviderScopes()[scope]?.[specifier];\n if (!versions) return undefined;\n\n // This provider scope does not implement semver negotiation. Use an exact\n // version match, then the host default provider when a constrained version is\n // unavailable.\n return (\n versions[version] ??\n (version === DEFAULT_VERSION ? undefined : versions[DEFAULT_VERSION])\n );\n}\n\nexport function getSharedProviderModule({\n scope,\n specifier,\n version,\n}: {\n scope: string;\n specifier: string;\n version?: string;\n}): unknown {\n const provider = getSharedProvider({ scope, specifier, version });\n if (!provider) {\n throw new Error(\n `Shared module \"${specifier}\" not found in provider scope \"${scope}\".`,\n );\n }\n provider.loaded = 1;\n return provider.get();\n}\n\nexport function resetSharedProviderScopesForTest(): void {\n const self = globalThis as typeof globalThis & {\n [GLOBAL_PROVIDER_SCOPES_KEY]?: SharedProviderScopes;\n };\n delete self[GLOBAL_PROVIDER_SCOPES_KEY];\n}\n"],"mappings":"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","names":[]}
|
|
@@ -265,10 +265,10 @@ function getSharedModule(scope, id) {
|
|
|
265
265
|
return null;
|
|
266
266
|
}
|
|
267
267
|
function matchesSharedModuleKey(id, key) {
|
|
268
|
-
if (id.endsWith(key))
|
|
269
|
-
return true;
|
|
270
268
|
if (!key.includes("/") && !key.endsWith(".js"))
|
|
271
269
|
return false;
|
|
270
|
+
if (id.endsWith(key))
|
|
271
|
+
return true;
|
|
272
272
|
const index = id.lastIndexOf(key);
|
|
273
273
|
if (index < 0)
|
|
274
274
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/runtime/turbopack/shared-modules.ts"],"sourcesContent":["import {\n buildSharedProviderPlan,\n getSharedProviderModule,\n installSharedProviderEntry,\n} from '#internal/host/shared/provider';\nimport {\n isSharedModuleManifest,\n type RemoteSharedModules,\n SHARED_MODULE_MANIFEST_PROTOCOL,\n type SharedModuleFactory,\n type SharedModuleManifest,\n} from '#internal/host/shared/shared-broker';\nimport type { GlobalScope } from '#internal/runtime/types';\nimport { logDebug, logError, logWarn } from '#internal/utils/logger';\nimport { findModuleInit, handleTurbopackModule, requireModule } from './module';\nimport {\n ASYNC_MODULE_CALLBACK_RE,\n ASYNC_MODULE_LOADER_RE,\n extractGroup,\n normalizeModuleId,\n REMOTE_SHARED_ASSIGNMENT_RE,\n REMOTE_SHARED_MARKER_RE,\n} from './patterns';\nimport { formatRemoteId, type RemoteScope } from './remote-scope';\n\nconst DEDUPLICATION_WARNING =\n 'This module will not be deduplicated — the remote may load its own copy, ' +\n 'which can cause duplicate instance errors (e.g. invalid hook calls if React is loaded twice).';\n// `asyncSharedModuleId` accepts: quoted string, integer, or integer in\n// scientific notation (e.g. `35e3`). Production minifiers occasionally\n// emit the scientific form; see normalizeModuleId() / MODULE_ID_PATTERN\n// in ./patterns.ts for the matching marker-extraction path.\nconst INLINE_REMOTE_SHARED_RE =\n /[\"']?__remote_shared_module_(?<specifier>[^\"':]+)[\"']?\\s*:\\s*\\(\\)\\s*=>\\s*(?:__turbopack_context__|[a-z])\\.A\\((?<asyncSharedModuleId>\"[^\"]+\"|[0-9]+e[0-9]+|[0-9]+)\\)/g;\n\n/**\n * Returns the flat module list for a scope.\n *\n * The primary source is `scope.turbopackModules` — a flat array populated by\n * the push interceptor in handleTurbopackChunk. This is immune to the\n * turbopack runtime replacing the TURBOPACK global (canary builds swap the\n * array for a deferred-loading dispatcher object).\n *\n * Falls back to reading the global for pre-populated bundles where the push\n * interceptor was never installed.\n */\nexport function getTurbopackModules(scope: RemoteScope): unknown[] | undefined {\n if (scope.turbopackModules.length > 0) {\n return scope.turbopackModules;\n }\n\n // Fallback: read the global for pre-populated bundles or legacy setups.\n const self = globalThis as GlobalScope;\n const raw = self[`TURBOPACK_${scope.globalKey}`];\n if (!raw) return undefined;\n\n if (Array.isArray(raw)) {\n return (raw as unknown[]).flat();\n }\n return Object.entries(raw as Record<string, unknown>).flat();\n}\n\n/**\n * Initializes shared modules between the host application and remote components.\n * This enables sharing of common dependencies like React to avoid duplicate instances.\n *\n * The function works by:\n * 1. Looking for a shared module initializer in the Turbopack bundle\n * 2. Extracting module IDs from the initializer\n * 3. Loading the corresponding host modules and mapping them to the remote's expected IDs\n */\nexport async function initializeSharedModules(\n scope: RemoteScope,\n hostShared: Record<string, SharedModuleFactory> = {},\n remoteShared: RemoteSharedModules = {},\n // biome-ignore lint/suspicious/noConfusingVoidType: Runtime is undefined but in TS land service it is void\n): Promise<void[]> {\n const allModules = getTurbopackModules(scope);\n\n logDebug(\n 'SharedModules',\n `initializeSharedModules: scope=\"${scope.scopedName}\", ` +\n `allModules=${allModules ? allModules.length : 'null'}, ` +\n `hostShared=[${Object.keys(hostShared).join(', ')}], ` +\n `remoteShared=${JSON.stringify(remoteShared)}`,\n );\n\n let sharedModuleInitializer: Promise<{\n shared: Record<string, string | (() => Promise<unknown>)>;\n }> | null = null;\n\n // find the shared module initializer in the Turbopack bundle\n if (allModules) {\n // find the shared module initializer module id by looking for\n // a function that contains the TURBOPACK_REMOTE_SHARED pattern\n const sharedModuleInitializerIndex = allModules.findIndex((idOrFunc) => {\n if (typeof idOrFunc !== 'function') {\n return false;\n }\n const funcCode = idOrFunc.toString();\n return REMOTE_SHARED_MARKER_RE.test(funcCode);\n });\n\n // if found, extract the shared module initializer\n // first element in the array is always the source script element\n if (sharedModuleInitializerIndex > 0) {\n const sharedModuleInitializerCode = (\n allModules[sharedModuleInitializerIndex] as () => unknown\n ).toString();\n const sharedModuleInitializerId = allModules[\n sharedModuleInitializerIndex - 1\n ] as string | number;\n // extract the shared module id from the function code\n const sharedModuleId = extractGroup(\n REMOTE_SHARED_ASSIGNMENT_RE,\n sharedModuleInitializerCode,\n 'sharedModuleId',\n );\n // Load the shared-module-initializer module. Turbopack emits its\n // factory body as\n // ctx.v((parentImport) => Promise.all([...]).then(() => parentImport(id)))\n // so `module.exports` IS the loader function (upstream `exportValue`\n // semantics). Earlier versions of remote-components' `ctx.v` eagerly\n // invoked the function and stored the resulting Promise on\n // `exports.default` — that shape is preserved here as a fallback for\n // bundles built against the old runtime, but the primary path now\n // invokes the loader explicitly with `requireModule` as the parent\n // import (the actual scope-bound require).\n if (sharedModuleId) {\n const moduleExports = handleTurbopackModule(\n scope,\n sharedModuleId,\n formatRemoteId(scope, String(sharedModuleInitializerId)),\n );\n type Loader = (\n parentImport: (id: string | number) => unknown,\n ) => Promise<{\n shared: Record<string, string | (() => Promise<unknown>)>;\n }>;\n const loaderCandidate =\n typeof moduleExports === 'function'\n ? moduleExports\n : (moduleExports as { default?: unknown })?.default;\n if (typeof loaderCandidate === 'function') {\n sharedModuleInitializer = (loaderCandidate as Loader)((parentId) =>\n requireModule(scope, parentId),\n );\n } else if (\n loaderCandidate &&\n typeof (loaderCandidate as { then?: unknown }).then === 'function'\n ) {\n sharedModuleInitializer = loaderCandidate as Promise<{\n shared: Record<string, string | (() => Promise<unknown>)>;\n }>;\n }\n }\n }\n\n // if we have a shared module initializer, load the shared modules from the host application\n if (sharedModuleInitializer) {\n const { shared } = await sharedModuleInitializer;\n // map shared module ids to their initializer functions\n const sharedModuleIds = extractSharedModuleIds(shared, scope);\n logDebug(\n 'SharedModules',\n `Resolved shared modules for scope=\"${scope.scopedName}\": ${JSON.stringify(sharedModuleIds)}`,\n );\n\n return installSharedModules(\n scope,\n hostShared,\n preferSharedManifest(sharedModuleIds, remoteShared),\n (id, module) =>\n `Host shared module \"${module}\" not found for ID ${id}. ${DEDUPLICATION_WARNING}`,\n );\n }\n\n const inlineSharedModuleIds = extractInlineSharedModuleIds(\n allModules,\n scope,\n );\n if (Object.keys(inlineSharedModuleIds).length > 0) {\n logDebug(\n 'SharedModules',\n `Resolved inline shared modules for scope=\"${scope.scopedName}\": ${JSON.stringify(inlineSharedModuleIds)}`,\n );\n\n return installSharedModules(\n scope,\n hostShared,\n preferSharedManifest(inlineSharedModuleIds, remoteShared),\n (id, module) =>\n `Host shared module \"${module}\" not found for inline ID ${id}. ${DEDUPLICATION_WARNING}`,\n );\n }\n\n logWarn(\n 'SharedModules',\n `No shared module initializer found in bundle for scope=\"${scope.scopedName}\" — falling back to remoteShared mapping`,\n );\n } else {\n logWarn(\n 'SharedModules',\n `No TURBOPACK modules found for scope=\"${scope.scopedName}\" (TURBOPACK_${scope.globalKey} is empty)`,\n );\n }\n\n const normalizedRemoteShared =\n normalizeRemoteSharedForTurbopackFallback(remoteShared);\n return installSharedModules(\n scope,\n hostShared,\n normalizedRemoteShared,\n (_id, module) =>\n `Shared module \"${module}\" not found for \"${scope.name}\". ${DEDUPLICATION_WARNING}`,\n );\n}\n\n/**\n * Extracts shared module IDs from the shared module initializer functions.\n * This parses the minified Turbopack code to find the module ID mappings.\n */\nfunction extractSharedModuleIds(\n shared: Record<string, string | (() => Promise<unknown>)>,\n scope: RemoteScope,\n): Record<string, string> {\n return Object.entries(shared)\n .filter(([, value]) => typeof value === 'function')\n .reduce<Record<string, string>>((acc, [key, value]) => {\n const asyncSharedModuleId = extractGroup(\n ASYNC_MODULE_LOADER_RE,\n value.toString(),\n 'asyncSharedModuleId',\n );\n\n if (asyncSharedModuleId) {\n const asyncSharedModule = findModuleInit(\n getTurbopackModules(scope),\n asyncSharedModuleId,\n );\n if (asyncSharedModule) {\n const sharedModuleId = extractGroup(\n ASYNC_MODULE_CALLBACK_RE,\n asyncSharedModule.toString(),\n 'sharedModuleId',\n );\n // map the shared module id to the actual module name\n acc[sharedModuleId ?? asyncSharedModuleId] = key.replace(\n '__remote_shared_module_',\n '',\n );\n }\n }\n return acc;\n }, {});\n}\n\nfunction extractInlineSharedModuleIds(\n allModules: unknown[],\n scope: RemoteScope,\n): Record<string, string> {\n const sharedModuleIds: Record<string, string> = {};\n\n for (const idOrFunc of allModules) {\n if (typeof idOrFunc !== 'function') continue;\n\n const funcCode = idOrFunc.toString();\n if (!funcCode.includes('__remote_shared_module_')) continue;\n\n INLINE_REMOTE_SHARED_RE.lastIndex = 0;\n for (const match of funcCode.matchAll(INLINE_REMOTE_SHARED_RE)) {\n const specifier = match.groups?.specifier;\n const rawAsyncSharedModuleId = stripQuotes(\n match.groups?.asyncSharedModuleId,\n );\n const asyncSharedModuleId = rawAsyncSharedModuleId\n ? normalizeModuleId(rawAsyncSharedModuleId)\n : undefined;\n if (!specifier || !asyncSharedModuleId) continue;\n\n const asyncSharedModule = findModuleInit(\n getTurbopackModules(scope),\n asyncSharedModuleId,\n );\n if (!asyncSharedModule) continue;\n\n const sharedModuleId = extractGroup(\n ASYNC_MODULE_CALLBACK_RE,\n asyncSharedModule.toString(),\n 'sharedModuleId',\n );\n sharedModuleIds[sharedModuleId ?? asyncSharedModuleId] = specifier;\n }\n }\n\n return sharedModuleIds;\n}\n\nfunction stripQuotes(value: string | undefined): string | undefined {\n if (value?.startsWith('\"') && value.endsWith('\"')) {\n return value.slice(1, -1);\n }\n return value;\n}\n\nfunction installSharedModules(\n scope: RemoteScope,\n hostShared: Record<string, SharedModuleFactory>,\n sharedModuleIds: RemoteSharedModules,\n missingMessage: (id: string, module: string) => string,\n): Promise<undefined[]> {\n return buildSharedProviderPlan({\n bundle: scope.name,\n hostShared,\n remoteShared: sharedModuleIds,\n scope: `remote:${scope.scopedName}`,\n callerTag: 'SharedModules',\n onMissing: (entry) => {\n logError('SharedModules', missingMessage(entry.id, entry.specifier));\n },\n }).then((results) =>\n results.entries.map((entry) => {\n installSharedProviderEntry(entry);\n scope.sharedModules[entry.id] = getSharedProviderModule({\n scope: entry.scope,\n specifier: entry.specifier,\n });\n // Compatibility with the old shared-modules architecture: a remote\n // factory may have already cached its own implementation for this ID.\n // The provider-owned scope.sharedModules entry must replace it. Remove\n // this cache cleanup once Turbopack remotes cannot execute shared\n // factories before the scoped provider plan is installed.\n delete scope.moduleCache[entry.id];\n return undefined;\n }),\n );\n}\n\nfunction preferSharedManifest(\n sharedModuleIds: Record<string, string>,\n remoteShared: RemoteSharedModules,\n): RemoteSharedModules {\n if (!isSharedModuleManifest(remoteShared)) return sharedModuleIds;\n\n const extractedIdBySpecifier = new Map(\n Object.entries(sharedModuleIds).map(([id, specifier]) => [specifier, id]),\n );\n\n return {\n protocol: SHARED_MODULE_MANIFEST_PROTOCOL,\n requirements: remoteShared.requirements.map((requirement) => {\n return {\n ...requirement,\n id: extractedIdBySpecifier.get(requirement.specifier) ?? requirement.id,\n };\n }),\n };\n}\n\nfunction normalizeRemoteSharedForTurbopackFallback(\n remoteShared: RemoteSharedModules,\n): RemoteSharedModules {\n if (isSharedModuleManifest(remoteShared)) {\n return {\n ...remoteShared,\n requirements: remoteShared.requirements.map((requirement) => ({\n ...requirement,\n id:\n typeof requirement.id === 'string'\n ? requirement.id.replace('[app-ssr]', '[app-client]')\n : requirement.id,\n })),\n } satisfies SharedModuleManifest;\n }\n\n // @legacy(remote-components<=0.4.x): normalize server-side generated\n // Turbopack IDs from the historical shared map until 0.4.x remotes are\n // outside the compatibility window.\n return Object.fromEntries(\n Object.entries(remoteShared).map(([id, module]) => [\n id.replace('[app-ssr]', '[app-client]'),\n module,\n ]),\n );\n}\n\n/**\n * Returns a shared module for the given scope and module ID.\n * Shared modules are common dependencies like React that are provided by the host.\n */\nexport function getSharedModule(\n scope: RemoteScope,\n id: string | number,\n): unknown {\n const idStr = String(id);\n\n // Exact match first (covers both string and numeric IDs)\n if (scope.sharedModules[idStr] !== undefined) {\n return scope.sharedModules[idStr];\n }\n\n // Fallback: the id may be a bundle-prefixed string like \"[bundle] /react/index.js\"\n // or a Turbopack dev id like \"[project]/node_modules/react/index.js [client]\".\n // Only path-like keys use the dev-id qualifier match to avoid \"react\"\n // matching \"react-dom\".\n for (const [key, value] of Object.entries(scope.sharedModules)) {\n if (\n typeof value !== 'undefined' &&\n idStr !== key &&\n matchesSharedModuleKey(idStr, key)\n ) {\n return value;\n }\n }\n\n return null;\n}\n\nfunction matchesSharedModuleKey(id: string, key: string): boolean {\n if (id.endsWith(key)) return true;\n if (!key.includes('/') && !key.endsWith('.js')) return false;\n\n const index = id.lastIndexOf(key);\n if (index < 0) return false;\n\n const afterKey = id.slice(index + key.length);\n return /^\\s+(?:\\[[^\\]]+\\]\\s*)?(?:\\([^)]*\\))?$/.test(afterKey);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAIO;AACP,2BAMO;AAEP,oBAA4C;AAC5C,oBAAqE;AACrE,sBAOO;AACP,0BAAiD;AAEjD,MAAM,wBACJ;AAMF,MAAM,0BACJ;AAaK,SAAS,oBAAoB,OAA2C;AAC7E,MAAI,MAAM,iBAAiB,SAAS,GAAG;AACrC,WAAO,MAAM;AAAA,EACf;AAGA,QAAM,OAAO;AACb,QAAM,MAAM,KAAK,aAAa,MAAM,WAAW;AAC/C,MAAI,CAAC;AAAK,WAAO;AAEjB,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,WAAQ,IAAkB,KAAK;AAAA,EACjC;AACA,SAAO,OAAO,QAAQ,GAA8B,EAAE,KAAK;AAC7D;AAWA,eAAsB,wBACpB,OACA,aAAkD,CAAC,GACnD,eAAoC,CAAC,GAEpB;AACjB,QAAM,aAAa,oBAAoB,KAAK;AAE5C;AAAA,IACE;AAAA,IACA,mCAAmC,MAAM,2BACzB,aAAa,WAAW,SAAS,uBAChC,OAAO,KAAK,UAAU,EAAE,KAAK,IAAI,oBAChC,KAAK,UAAU,YAAY;AAAA,EAC/C;AAEA,MAAI,0BAEQ;AAGZ,MAAI,YAAY;AAGd,UAAM,+BAA+B,WAAW,UAAU,CAAC,aAAa;AACtE,UAAI,OAAO,aAAa,YAAY;AAClC,eAAO;AAAA,MACT;AACA,YAAM,WAAW,SAAS,SAAS;AACnC,aAAO,wCAAwB,KAAK,QAAQ;AAAA,IAC9C,CAAC;AAID,QAAI,+BAA+B,GAAG;AACpC,YAAM,8BACJ,WAAW,4BAA4B,EACvC,SAAS;AACX,YAAM,4BAA4B,WAChC,+BAA+B,CACjC;AAEA,YAAM,qBAAiB;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAWA,UAAI,gBAAgB;AAClB,cAAM,oBAAgB;AAAA,UACpB;AAAA,UACA;AAAA,cACA,oCAAe,OAAO,OAAO,yBAAyB,CAAC;AAAA,QACzD;AAMA,cAAM,kBACJ,OAAO,kBAAkB,aACrB,gBACC,eAAyC;AAChD,YAAI,OAAO,oBAAoB,YAAY;AACzC,oCAA2B;AAAA,YAA2B,CAAC,iBACrD,6BAAc,OAAO,QAAQ;AAAA,UAC/B;AAAA,QACF,WACE,mBACA,OAAQ,gBAAuC,SAAS,YACxD;AACA,oCAA0B;AAAA,QAG5B;AAAA,MACF;AAAA,IACF;AAGA,QAAI,yBAAyB;AAC3B,YAAM,EAAE,OAAO,IAAI,MAAM;AAEzB,YAAM,kBAAkB,uBAAuB,QAAQ,KAAK;AAC5D;AAAA,QACE;AAAA,QACA,sCAAsC,MAAM,gBAAgB,KAAK,UAAU,eAAe;AAAA,MAC5F;AAEA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,qBAAqB,iBAAiB,YAAY;AAAA,QAClD,CAAC,IAAIA,YACH,uBAAuBA,6BAA4B,OAAO;AAAA,MAC9D;AAAA,IACF;AAEA,UAAM,wBAAwB;AAAA,MAC5B;AAAA,MACA;AAAA,IACF;AACA,QAAI,OAAO,KAAK,qBAAqB,EAAE,SAAS,GAAG;AACjD;AAAA,QACE;AAAA,QACA,6CAA6C,MAAM,gBAAgB,KAAK,UAAU,qBAAqB;AAAA,MACzG;AAEA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,qBAAqB,uBAAuB,YAAY;AAAA,QACxD,CAAC,IAAIA,YACH,uBAAuBA,oCAAmC,OAAO;AAAA,MACrE;AAAA,IACF;AAEA;AAAA,MACE;AAAA,MACA,2DAA2D,MAAM;AAAA,IACnE;AAAA,EACF,OAAO;AACL;AAAA,MACE;AAAA,MACA,yCAAyC,MAAM,0BAA0B,MAAM;AAAA,IACjF;AAAA,EACF;AAEA,QAAM,yBACJ,0CAA0C,YAAY;AACxD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,KAAKA,YACJ,kBAAkBA,2BAA0B,MAAM,UAAU;AAAA,EAChE;AACF;AAMA,SAAS,uBACP,QACA,OACwB;AACxB,SAAO,OAAO,QAAQ,MAAM,EACzB,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,OAAO,UAAU,UAAU,EACjD,OAA+B,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM;AACrD,UAAM,0BAAsB;AAAA,MAC1B;AAAA,MACA,MAAM,SAAS;AAAA,MACf;AAAA,IACF;AAEA,QAAI,qBAAqB;AACvB,YAAM,wBAAoB;AAAA,QACxB,oBAAoB,KAAK;AAAA,QACzB;AAAA,MACF;AACA,UAAI,mBAAmB;AACrB,cAAM,qBAAiB;AAAA,UACrB;AAAA,UACA,kBAAkB,SAAS;AAAA,UAC3B;AAAA,QACF;AAEA,YAAI,kBAAkB,mBAAmB,IAAI,IAAI;AAAA,UAC/C;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACT;AAEA,SAAS,6BACP,YACA,OACwB;AACxB,QAAM,kBAA0C,CAAC;AAEjD,aAAW,YAAY,YAAY;AACjC,QAAI,OAAO,aAAa;AAAY;AAEpC,UAAM,WAAW,SAAS,SAAS;AACnC,QAAI,CAAC,SAAS,SAAS,yBAAyB;AAAG;AAEnD,4BAAwB,YAAY;AACpC,eAAW,SAAS,SAAS,SAAS,uBAAuB,GAAG;AAC9D,YAAM,YAAY,MAAM,QAAQ;AAChC,YAAM,yBAAyB;AAAA,QAC7B,MAAM,QAAQ;AAAA,MAChB;AACA,YAAM,sBAAsB,6BACxB,mCAAkB,sBAAsB,IACxC;AACJ,UAAI,CAAC,aAAa,CAAC;AAAqB;AAExC,YAAM,wBAAoB;AAAA,QACxB,oBAAoB,KAAK;AAAA,QACzB;AAAA,MACF;AACA,UAAI,CAAC;AAAmB;AAExB,YAAM,qBAAiB;AAAA,QACrB;AAAA,QACA,kBAAkB,SAAS;AAAA,QAC3B;AAAA,MACF;AACA,sBAAgB,kBAAkB,mBAAmB,IAAI;AAAA,IAC3D;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,YAAY,OAA+C;AAClE,MAAI,OAAO,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,GAAG;AACjD,WAAO,MAAM,MAAM,GAAG,EAAE;AAAA,EAC1B;AACA,SAAO;AACT;AAEA,SAAS,qBACP,OACA,YACA,iBACA,gBACsB;AACtB,aAAO,yCAAwB;AAAA,IAC7B,QAAQ,MAAM;AAAA,IACd;AAAA,IACA,cAAc;AAAA,IACd,OAAO,UAAU,MAAM;AAAA,IACvB,WAAW;AAAA,IACX,WAAW,CAAC,UAAU;AACpB,kCAAS,iBAAiB,eAAe,MAAM,IAAI,MAAM,SAAS,CAAC;AAAA,IACrE;AAAA,EACF,CAAC,EAAE;AAAA,IAAK,CAAC,YACP,QAAQ,QAAQ,IAAI,CAAC,UAAU;AAC7B,sDAA2B,KAAK;AAChC,YAAM,cAAc,MAAM,EAAE,QAAI,yCAAwB;AAAA,QACtD,OAAO,MAAM;AAAA,QACb,WAAW,MAAM;AAAA,MACnB,CAAC;AAMD,aAAO,MAAM,YAAY,MAAM,EAAE;AACjC,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;AAEA,SAAS,qBACP,iBACA,cACqB;AACrB,MAAI,KAAC,6CAAuB,YAAY;AAAG,WAAO;AAElD,QAAM,yBAAyB,IAAI;AAAA,IACjC,OAAO,QAAQ,eAAe,EAAE,IAAI,CAAC,CAAC,IAAI,SAAS,MAAM,CAAC,WAAW,EAAE,CAAC;AAAA,EAC1E;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV,cAAc,aAAa,aAAa,IAAI,CAAC,gBAAgB;AAC3D,aAAO;AAAA,QACL,GAAG;AAAA,QACH,IAAI,uBAAuB,IAAI,YAAY,SAAS,KAAK,YAAY;AAAA,MACvE;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,0CACP,cACqB;AACrB,UAAI,6CAAuB,YAAY,GAAG;AACxC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,cAAc,aAAa,aAAa,IAAI,CAAC,iBAAiB;AAAA,QAC5D,GAAG;AAAA,QACH,IACE,OAAO,YAAY,OAAO,WACtB,YAAY,GAAG,QAAQ,aAAa,cAAc,IAClD,YAAY;AAAA,MACpB,EAAE;AAAA,IACJ;AAAA,EACF;AAKA,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,YAAY,EAAE,IAAI,CAAC,CAAC,IAAIA,OAAM,MAAM;AAAA,MACjD,GAAG,QAAQ,aAAa,cAAc;AAAA,MACtCA;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAMO,SAAS,gBACd,OACA,IACS;AACT,QAAM,QAAQ,OAAO,EAAE;AAGvB,MAAI,MAAM,cAAc,KAAK,MAAM,QAAW;AAC5C,WAAO,MAAM,cAAc,KAAK;AAAA,EAClC;AAMA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,aAAa,GAAG;AAC9D,QACE,OAAO,UAAU,eACjB,UAAU,OACV,uBAAuB,OAAO,GAAG,GACjC;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,uBAAuB,IAAY,KAAsB;AAChE,MAAI,GAAG,SAAS,GAAG;AAAG,WAAO;AAC7B,MAAI,CAAC,IAAI,SAAS,GAAG,KAAK,CAAC,IAAI,SAAS,KAAK;AAAG,WAAO;AAEvD,QAAM,QAAQ,GAAG,YAAY,GAAG;AAChC,MAAI,QAAQ;AAAG,WAAO;AAEtB,QAAM,WAAW,GAAG,MAAM,QAAQ,IAAI,MAAM;AAC5C,SAAO,wCAAwC,KAAK,QAAQ;AAC9D;","names":["module"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/runtime/turbopack/shared-modules.ts"],"sourcesContent":["import {\n buildSharedProviderPlan,\n getSharedProviderModule,\n installSharedProviderEntry,\n} from '#internal/host/shared/provider';\nimport {\n isSharedModuleManifest,\n type RemoteSharedModules,\n SHARED_MODULE_MANIFEST_PROTOCOL,\n type SharedModuleFactory,\n type SharedModuleManifest,\n} from '#internal/host/shared/shared-broker';\nimport type { GlobalScope } from '#internal/runtime/types';\nimport { logDebug, logError, logWarn } from '#internal/utils/logger';\nimport { findModuleInit, handleTurbopackModule, requireModule } from './module';\nimport {\n ASYNC_MODULE_CALLBACK_RE,\n ASYNC_MODULE_LOADER_RE,\n extractGroup,\n normalizeModuleId,\n REMOTE_SHARED_ASSIGNMENT_RE,\n REMOTE_SHARED_MARKER_RE,\n} from './patterns';\nimport { formatRemoteId, type RemoteScope } from './remote-scope';\n\nconst DEDUPLICATION_WARNING =\n 'This module will not be deduplicated — the remote may load its own copy, ' +\n 'which can cause duplicate instance errors (e.g. invalid hook calls if React is loaded twice).';\n// `asyncSharedModuleId` accepts: quoted string, integer, or integer in\n// scientific notation (e.g. `35e3`). Production minifiers occasionally\n// emit the scientific form; see normalizeModuleId() / MODULE_ID_PATTERN\n// in ./patterns.ts for the matching marker-extraction path.\nconst INLINE_REMOTE_SHARED_RE =\n /[\"']?__remote_shared_module_(?<specifier>[^\"':]+)[\"']?\\s*:\\s*\\(\\)\\s*=>\\s*(?:__turbopack_context__|[a-z])\\.A\\((?<asyncSharedModuleId>\"[^\"]+\"|[0-9]+e[0-9]+|[0-9]+)\\)/g;\n\n/**\n * Returns the flat module list for a scope.\n *\n * The primary source is `scope.turbopackModules` — a flat array populated by\n * the push interceptor in handleTurbopackChunk. This is immune to the\n * turbopack runtime replacing the TURBOPACK global (canary builds swap the\n * array for a deferred-loading dispatcher object).\n *\n * Falls back to reading the global for pre-populated bundles where the push\n * interceptor was never installed.\n */\nexport function getTurbopackModules(scope: RemoteScope): unknown[] | undefined {\n if (scope.turbopackModules.length > 0) {\n return scope.turbopackModules;\n }\n\n // Fallback: read the global for pre-populated bundles or legacy setups.\n const self = globalThis as GlobalScope;\n const raw = self[`TURBOPACK_${scope.globalKey}`];\n if (!raw) return undefined;\n\n if (Array.isArray(raw)) {\n return (raw as unknown[]).flat();\n }\n return Object.entries(raw as Record<string, unknown>).flat();\n}\n\n/**\n * Initializes shared modules between the host application and remote components.\n * This enables sharing of common dependencies like React to avoid duplicate instances.\n *\n * The function works by:\n * 1. Looking for a shared module initializer in the Turbopack bundle\n * 2. Extracting module IDs from the initializer\n * 3. Loading the corresponding host modules and mapping them to the remote's expected IDs\n */\nexport async function initializeSharedModules(\n scope: RemoteScope,\n hostShared: Record<string, SharedModuleFactory> = {},\n remoteShared: RemoteSharedModules = {},\n // biome-ignore lint/suspicious/noConfusingVoidType: Runtime is undefined but in TS land service it is void\n): Promise<void[]> {\n const allModules = getTurbopackModules(scope);\n\n logDebug(\n 'SharedModules',\n `initializeSharedModules: scope=\"${scope.scopedName}\", ` +\n `allModules=${allModules ? allModules.length : 'null'}, ` +\n `hostShared=[${Object.keys(hostShared).join(', ')}], ` +\n `remoteShared=${JSON.stringify(remoteShared)}`,\n );\n\n let sharedModuleInitializer: Promise<{\n shared: Record<string, string | (() => Promise<unknown>)>;\n }> | null = null;\n\n // find the shared module initializer in the Turbopack bundle\n if (allModules) {\n // find the shared module initializer module id by looking for\n // a function that contains the TURBOPACK_REMOTE_SHARED pattern\n const sharedModuleInitializerIndex = allModules.findIndex((idOrFunc) => {\n if (typeof idOrFunc !== 'function') {\n return false;\n }\n const funcCode = idOrFunc.toString();\n return REMOTE_SHARED_MARKER_RE.test(funcCode);\n });\n\n // if found, extract the shared module initializer\n // first element in the array is always the source script element\n if (sharedModuleInitializerIndex > 0) {\n const sharedModuleInitializerCode = (\n allModules[sharedModuleInitializerIndex] as () => unknown\n ).toString();\n const sharedModuleInitializerId = allModules[\n sharedModuleInitializerIndex - 1\n ] as string | number;\n // extract the shared module id from the function code\n const sharedModuleId = extractGroup(\n REMOTE_SHARED_ASSIGNMENT_RE,\n sharedModuleInitializerCode,\n 'sharedModuleId',\n );\n // Load the shared-module-initializer module. Turbopack emits its\n // factory body as\n // ctx.v((parentImport) => Promise.all([...]).then(() => parentImport(id)))\n // so `module.exports` IS the loader function (upstream `exportValue`\n // semantics). Earlier versions of remote-components' `ctx.v` eagerly\n // invoked the function and stored the resulting Promise on\n // `exports.default` — that shape is preserved here as a fallback for\n // bundles built against the old runtime, but the primary path now\n // invokes the loader explicitly with `requireModule` as the parent\n // import (the actual scope-bound require).\n if (sharedModuleId) {\n const moduleExports = handleTurbopackModule(\n scope,\n sharedModuleId,\n formatRemoteId(scope, String(sharedModuleInitializerId)),\n );\n type Loader = (\n parentImport: (id: string | number) => unknown,\n ) => Promise<{\n shared: Record<string, string | (() => Promise<unknown>)>;\n }>;\n const loaderCandidate =\n typeof moduleExports === 'function'\n ? moduleExports\n : (moduleExports as { default?: unknown })?.default;\n if (typeof loaderCandidate === 'function') {\n sharedModuleInitializer = (loaderCandidate as Loader)((parentId) =>\n requireModule(scope, parentId),\n );\n } else if (\n loaderCandidate &&\n typeof (loaderCandidate as { then?: unknown }).then === 'function'\n ) {\n sharedModuleInitializer = loaderCandidate as Promise<{\n shared: Record<string, string | (() => Promise<unknown>)>;\n }>;\n }\n }\n }\n\n // if we have a shared module initializer, load the shared modules from the host application\n if (sharedModuleInitializer) {\n const { shared } = await sharedModuleInitializer;\n // map shared module ids to their initializer functions\n const sharedModuleIds = extractSharedModuleIds(shared, scope);\n logDebug(\n 'SharedModules',\n `Resolved shared modules for scope=\"${scope.scopedName}\": ${JSON.stringify(sharedModuleIds)}`,\n );\n\n return installSharedModules(\n scope,\n hostShared,\n preferSharedManifest(sharedModuleIds, remoteShared),\n (id, module) =>\n `Host shared module \"${module}\" not found for ID ${id}. ${DEDUPLICATION_WARNING}`,\n );\n }\n\n const inlineSharedModuleIds = extractInlineSharedModuleIds(\n allModules,\n scope,\n );\n if (Object.keys(inlineSharedModuleIds).length > 0) {\n logDebug(\n 'SharedModules',\n `Resolved inline shared modules for scope=\"${scope.scopedName}\": ${JSON.stringify(inlineSharedModuleIds)}`,\n );\n\n return installSharedModules(\n scope,\n hostShared,\n preferSharedManifest(inlineSharedModuleIds, remoteShared),\n (id, module) =>\n `Host shared module \"${module}\" not found for inline ID ${id}. ${DEDUPLICATION_WARNING}`,\n );\n }\n\n logWarn(\n 'SharedModules',\n `No shared module initializer found in bundle for scope=\"${scope.scopedName}\" — falling back to remoteShared mapping`,\n );\n } else {\n logWarn(\n 'SharedModules',\n `No TURBOPACK modules found for scope=\"${scope.scopedName}\" (TURBOPACK_${scope.globalKey} is empty)`,\n );\n }\n\n const normalizedRemoteShared =\n normalizeRemoteSharedForTurbopackFallback(remoteShared);\n return installSharedModules(\n scope,\n hostShared,\n normalizedRemoteShared,\n (_id, module) =>\n `Shared module \"${module}\" not found for \"${scope.name}\". ${DEDUPLICATION_WARNING}`,\n );\n}\n\n/**\n * Extracts shared module IDs from the shared module initializer functions.\n * This parses the minified Turbopack code to find the module ID mappings.\n */\nfunction extractSharedModuleIds(\n shared: Record<string, string | (() => Promise<unknown>)>,\n scope: RemoteScope,\n): Record<string, string> {\n return Object.entries(shared)\n .filter(([, value]) => typeof value === 'function')\n .reduce<Record<string, string>>((acc, [key, value]) => {\n const asyncSharedModuleId = extractGroup(\n ASYNC_MODULE_LOADER_RE,\n value.toString(),\n 'asyncSharedModuleId',\n );\n\n if (asyncSharedModuleId) {\n const asyncSharedModule = findModuleInit(\n getTurbopackModules(scope),\n asyncSharedModuleId,\n );\n if (asyncSharedModule) {\n const sharedModuleId = extractGroup(\n ASYNC_MODULE_CALLBACK_RE,\n asyncSharedModule.toString(),\n 'sharedModuleId',\n );\n // map the shared module id to the actual module name\n acc[sharedModuleId ?? asyncSharedModuleId] = key.replace(\n '__remote_shared_module_',\n '',\n );\n }\n }\n return acc;\n }, {});\n}\n\nfunction extractInlineSharedModuleIds(\n allModules: unknown[],\n scope: RemoteScope,\n): Record<string, string> {\n const sharedModuleIds: Record<string, string> = {};\n\n for (const idOrFunc of allModules) {\n if (typeof idOrFunc !== 'function') continue;\n\n const funcCode = idOrFunc.toString();\n if (!funcCode.includes('__remote_shared_module_')) continue;\n\n INLINE_REMOTE_SHARED_RE.lastIndex = 0;\n for (const match of funcCode.matchAll(INLINE_REMOTE_SHARED_RE)) {\n const specifier = match.groups?.specifier;\n const rawAsyncSharedModuleId = stripQuotes(\n match.groups?.asyncSharedModuleId,\n );\n const asyncSharedModuleId = rawAsyncSharedModuleId\n ? normalizeModuleId(rawAsyncSharedModuleId)\n : undefined;\n if (!specifier || !asyncSharedModuleId) continue;\n\n const asyncSharedModule = findModuleInit(\n getTurbopackModules(scope),\n asyncSharedModuleId,\n );\n if (!asyncSharedModule) continue;\n\n const sharedModuleId = extractGroup(\n ASYNC_MODULE_CALLBACK_RE,\n asyncSharedModule.toString(),\n 'sharedModuleId',\n );\n sharedModuleIds[sharedModuleId ?? asyncSharedModuleId] = specifier;\n }\n }\n\n return sharedModuleIds;\n}\n\nfunction stripQuotes(value: string | undefined): string | undefined {\n if (value?.startsWith('\"') && value.endsWith('\"')) {\n return value.slice(1, -1);\n }\n return value;\n}\n\nfunction installSharedModules(\n scope: RemoteScope,\n hostShared: Record<string, SharedModuleFactory>,\n sharedModuleIds: RemoteSharedModules,\n missingMessage: (id: string, module: string) => string,\n): Promise<undefined[]> {\n return buildSharedProviderPlan({\n bundle: scope.name,\n hostShared,\n remoteShared: sharedModuleIds,\n scope: `remote:${scope.scopedName}`,\n callerTag: 'SharedModules',\n onMissing: (entry) => {\n logError('SharedModules', missingMessage(entry.id, entry.specifier));\n },\n }).then((results) =>\n results.entries.map((entry) => {\n installSharedProviderEntry(entry);\n scope.sharedModules[entry.id] = getSharedProviderModule({\n scope: entry.scope,\n specifier: entry.specifier,\n });\n // Compatibility with the old shared-modules architecture: a remote\n // factory may have already cached its own implementation for this ID.\n // The provider-owned scope.sharedModules entry must replace it. Remove\n // this cache cleanup once Turbopack remotes cannot execute shared\n // factories before the scoped provider plan is installed.\n delete scope.moduleCache[entry.id];\n return undefined;\n }),\n );\n}\n\nfunction preferSharedManifest(\n sharedModuleIds: Record<string, string>,\n remoteShared: RemoteSharedModules,\n): RemoteSharedModules {\n if (!isSharedModuleManifest(remoteShared)) return sharedModuleIds;\n\n const extractedIdBySpecifier = new Map(\n Object.entries(sharedModuleIds).map(([id, specifier]) => [specifier, id]),\n );\n\n return {\n protocol: SHARED_MODULE_MANIFEST_PROTOCOL,\n requirements: remoteShared.requirements.map((requirement) => {\n return {\n ...requirement,\n id: extractedIdBySpecifier.get(requirement.specifier) ?? requirement.id,\n };\n }),\n };\n}\n\nfunction normalizeRemoteSharedForTurbopackFallback(\n remoteShared: RemoteSharedModules,\n): RemoteSharedModules {\n if (isSharedModuleManifest(remoteShared)) {\n return {\n ...remoteShared,\n requirements: remoteShared.requirements.map((requirement) => ({\n ...requirement,\n id:\n typeof requirement.id === 'string'\n ? requirement.id.replace('[app-ssr]', '[app-client]')\n : requirement.id,\n })),\n } satisfies SharedModuleManifest;\n }\n\n // @legacy(remote-components<=0.4.x): normalize server-side generated\n // Turbopack IDs from the historical shared map until 0.4.x remotes are\n // outside the compatibility window.\n return Object.fromEntries(\n Object.entries(remoteShared).map(([id, module]) => [\n id.replace('[app-ssr]', '[app-client]'),\n module,\n ]),\n );\n}\n\n/**\n * Returns a shared module for the given scope and module ID.\n * Shared modules are common dependencies like React that are provided by the host.\n */\nexport function getSharedModule(\n scope: RemoteScope,\n id: string | number,\n): unknown {\n const idStr = String(id);\n\n // Exact match first (covers both string and numeric IDs)\n if (scope.sharedModules[idStr] !== undefined) {\n return scope.sharedModules[idStr];\n }\n\n // Fallback: the id may be a bundle-prefixed string like \"[bundle] /react/index.js\"\n // or a Turbopack dev id like \"[project]/node_modules/react/index.js [client]\".\n // Only path-like keys use the dev-id qualifier match to avoid \"react\"\n // matching \"react-dom\".\n for (const [key, value] of Object.entries(scope.sharedModules)) {\n if (\n typeof value !== 'undefined' &&\n idStr !== key &&\n matchesSharedModuleKey(idStr, key)\n ) {\n return value;\n }\n }\n\n return null;\n}\n\nfunction matchesSharedModuleKey(id: string, key: string): boolean {\n // Suffix matching only applies to path-like keys (e.g. a bundle-prefixed id\n // \"[bundle] /react/index.js\" or a dev id matching the shared key\n // \"/react/index.js\"). Plain numeric Turbopack IDs must match exactly — which\n // the caller already handles before this fallback. This guard MUST run before\n // the `endsWith` check: otherwise a longer numeric id spuriously matches a\n // shorter shared numeric key (e.g. id \"6487\" ends with shared key \"487\", the\n // `next/dist/build/polyfills/process` module), handing the wrong module to the\n // host. Turbopack reassigns numeric ids per build, so such collisions surface\n // unpredictably across Next.js versions.\n if (!key.includes('/') && !key.endsWith('.js')) return false;\n\n if (id.endsWith(key)) return true;\n\n const index = id.lastIndexOf(key);\n if (index < 0) return false;\n\n const afterKey = id.slice(index + key.length);\n return /^\\s+(?:\\[[^\\]]+\\]\\s*)?(?:\\([^)]*\\))?$/.test(afterKey);\n}\n"],"mappings":"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","names":["module"]}
|