remote-components 0.4.12 → 0.4.13
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-3PR3SWYZ.js → chunk-3DR4Z24C.js} +24 -2
- package/dist/chunk-3DR4Z24C.js.map +1 -0
- package/dist/{chunk-BEGVH64U.js → chunk-5BBEO4SE.js} +2 -2
- package/dist/{chunk-24LEEDHP.js → chunk-CBEDRGC7.js} +3 -3
- package/dist/{chunk-CLO56ON2.js → chunk-CLB2ATH2.js} +82 -4
- package/dist/chunk-CLB2ATH2.js.map +1 -0
- package/dist/{chunk-M6ACTSVB.js → chunk-IE7FXNFJ.js} +2 -2
- package/dist/{chunk-XWRB6CEA.cjs → chunk-KMG54QXV.cjs} +3 -3
- package/dist/{chunk-SULMNRMJ.cjs → chunk-KP544TQH.cjs} +23 -23
- package/dist/{chunk-HXCW3WDT.cjs → chunk-OI37BBBU.cjs} +25 -25
- package/dist/{chunk-TGE3K3TR.cjs → chunk-OVD7BRLD.cjs} +18 -18
- package/dist/{chunk-6PZEDIAK.cjs → chunk-OZCVXVKU.cjs} +24 -2
- package/dist/chunk-OZCVXVKU.cjs.map +1 -0
- package/dist/{chunk-YSJ4FKGI.cjs → chunk-W7RJUCZQ.cjs} +97 -19
- package/dist/chunk-W7RJUCZQ.cjs.map +1 -0
- package/dist/{chunk-RZGFQTX6.js → chunk-XEO3XD67.js} +8 -8
- package/dist/config/nextjs.cjs +10 -10
- package/dist/config/nextjs.js +7 -7
- package/dist/config/tailwind.cjs +53 -0
- package/dist/config/tailwind.cjs.map +1 -0
- package/dist/config/tailwind.d.ts +21 -0
- package/dist/config/tailwind.js +53 -0
- package/dist/config/tailwind.js.map +1 -0
- package/dist/host/html.cjs +20 -20
- package/dist/host/html.js +8 -8
- package/dist/host/nextjs/app/client-only.cjs +12 -12
- package/dist/host/nextjs/app/client-only.js +7 -7
- package/dist/host/react.cjs +8 -8
- package/dist/host/react.js +7 -7
- package/dist/internal/host/nextjs/app-client.cjs +7 -3
- package/dist/internal/host/nextjs/app-client.cjs.map +1 -1
- package/dist/internal/host/nextjs/app-client.js +7 -3
- package/dist/internal/host/nextjs/app-client.js.map +1 -1
- package/dist/internal/host/shared/remote-image-loader.cjs +23 -1
- package/dist/internal/host/shared/remote-image-loader.cjs.map +1 -1
- package/dist/internal/host/shared/remote-image-loader.js +23 -1
- package/dist/internal/host/shared/remote-image-loader.js.map +1 -1
- package/dist/remote/react/utils/portal.cjs +58 -0
- package/dist/remote/react/utils/portal.cjs.map +1 -0
- package/dist/remote/react/utils/portal.d.ts +12 -0
- package/dist/remote/react/utils/portal.js +58 -0
- package/dist/remote/react/utils/portal.js.map +1 -0
- package/dist/{turbopack-5VGMYUL4.cjs → turbopack-5WAY6QIC.cjs} +11 -11
- package/dist/{turbopack-43N2UJNN.js → turbopack-Z744H3T4.js} +4 -4
- package/dist/{webpack-FSN5UBA2.cjs → webpack-3GSL5AZJ.cjs} +11 -11
- package/dist/{webpack-LXE2UWTA.js → webpack-IQKPPBGH.js} +4 -4
- package/package.json +18 -1
- package/dist/chunk-3PR3SWYZ.js.map +0 -1
- package/dist/chunk-6PZEDIAK.cjs.map +0 -1
- package/dist/chunk-CLO56ON2.js.map +0 -1
- package/dist/chunk-YSJ4FKGI.cjs.map +0 -1
- /package/dist/{chunk-BEGVH64U.js.map → chunk-5BBEO4SE.js.map} +0 -0
- /package/dist/{chunk-24LEEDHP.js.map → chunk-CBEDRGC7.js.map} +0 -0
- /package/dist/{chunk-M6ACTSVB.js.map → chunk-IE7FXNFJ.js.map} +0 -0
- /package/dist/{chunk-XWRB6CEA.cjs.map → chunk-KMG54QXV.cjs.map} +0 -0
- /package/dist/{chunk-SULMNRMJ.cjs.map → chunk-KP544TQH.cjs.map} +0 -0
- /package/dist/{chunk-HXCW3WDT.cjs.map → chunk-OI37BBBU.cjs.map} +0 -0
- /package/dist/{chunk-TGE3K3TR.cjs.map → chunk-OVD7BRLD.cjs.map} +0 -0
- /package/dist/{chunk-RZGFQTX6.js.map → chunk-XEO3XD67.js.map} +0 -0
- /package/dist/{turbopack-5VGMYUL4.cjs.map → turbopack-5WAY6QIC.cjs.map} +0 -0
- /package/dist/{turbopack-43N2UJNN.js.map → turbopack-Z744H3T4.js.map} +0 -0
- /package/dist/{webpack-FSN5UBA2.cjs.map → webpack-3GSL5AZJ.cjs.map} +0 -0
- /package/dist/{webpack-LXE2UWTA.js.map → webpack-IQKPPBGH.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/host/nextjs/app-client.tsx"],"sourcesContent":["'use client';\n\nimport {\n startTransition,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { createImageLoaderSharedEntries } from '#internal/host/nextjs/image-shared';\nimport { tryImportShared } from '#internal/host/nextjs/shared-import';\nimport { useResolveClientUrl } from '#internal/host/react/hooks/use-resolve-client-url';\nimport { getClientOrServerUrl } from '#internal/host/server/get-client-or-server-url';\nimport type { InternalResolveClientUrl } from '#internal/host/server/types';\nimport type { ConsumeClientOnlyConfig } from '#internal/host/shared/config';\nimport { runPipelineFromParsed } from '#internal/host/shared/pipeline';\nimport type { ConsumeServerData } from '#internal/host/shared/server-handoff';\nimport { createHostState } from '#internal/host/shared/state';\nimport { DEFAULT_ROUTE, RUNTIME_WEBPACK } from '#internal/runtime/constants';\nimport { loadStaticRemoteComponent } from '#internal/runtime/loaders/static-loader';\nimport type { MountOrUnmountFunction } from '#internal/runtime/types';\nimport { escapeString } from '#internal/utils';\nimport { logError } from '#internal/utils/logger';\nimport { routerImpl } from './app-compat';\nimport { RemoteComponentLinks } from './remote-component-links';\n\n/**\n * Resolves host-side shared modules (React, Next.js router, image loader, etc.)\n * and returns them as a map the loading pipeline can pass to remotes.\n */\nasync function resolveHostShared(\n resolveClientUrl: InternalResolveClientUrl | undefined,\n): Promise<Record<string, (bundle?: string) => Promise<unknown>>> {\n const shared = await tryImportShared();\n if ('__remote_components_missing_shared__' in shared) {\n await shared.__remote_components_missing_shared__();\n }\n return {\n 'next/router': routerImpl,\n ...shared,\n ...createImageLoaderSharedEntries({ bound: resolveClientUrl }),\n };\n}\n\n/**\n * Extends the RSC-serializable data with {@link ConsumeClientConfig} fields\n * (like `resolveClientUrl`) that can't cross the server→client boundary\n * but are accepted when this component is used directly as a client import.\n */\ninterface ConsumeRemoteComponentClientProps\n extends ConsumeServerData,\n ConsumeClientOnlyConfig {}\n\n/**\n * ConsumeRemoteComponentClient - Main component for rendering remote components\n *\n * This component handles the loading and rendering of remote microfrontends.\n * It supports both RSC (React Server Components) and Next.js Pages Router based components.\n */\nexport function ConsumeRemoteComponentClient({\n src,\n serverUrl,\n name,\n bundle,\n route = DEFAULT_ROUTE,\n runtime = RUNTIME_WEBPACK,\n data,\n nextData,\n scripts = [],\n links = [],\n remoteShared = {},\n isolate,\n mode = 'open',\n resolveClientUrl: resolveClientUrlProp,\n reset,\n type,\n children,\n}: ConsumeRemoteComponentClientProps) {\n const remoteComponentId = useId();\n const [component, setComponent] = useState<React.ReactNode | Error>(null);\n const url = getClientOrServerUrl(src, serverUrl);\n const resolveClientUrl = useResolveClientUrl(resolveClientUrlProp, url.href);\n const hostStateRef = useRef(createHostState());\n const metadataRef = useRef<{\n name: string;\n bundle: string;\n route: string;\n url: string;\n }>({\n name,\n bundle,\n route,\n url: url.href,\n });\n const startRef = useRef<HTMLTemplateElement | null>(null);\n const endRef = useRef<HTMLTemplateElement | null>(null);\n const prevRemoteComponentUnmountRef = useRef<{\n unmount: Set<MountOrUnmountFunction>;\n root: ShadowRoot | DocumentFragment | null;\n } | null>(null);\n\n // Handle errors by re-throwing them\n if (component instanceof Error) {\n throw component;\n }\n\n // determine whether to use children or loaded component\n const shouldUseChildren =\n (!component ||\n (component &&\n !nextData &&\n type !== 'remote-component' &&\n typeof (component as unknown as Promise<unknown>).then !==\n 'function')) &&\n // if the remote Next.js Pages Router application is in development mode\n // we don't use the provided static HTML\n // to mitigate layout shift when loading CSS using JavaScript on the client\n nextData?.buildId !== 'development';\n\n // The pathname is used so this URL is the same across server and client requests for relative src's\n const keySuffix = `${escapeString(bundle)}_${escapeString(\n url.pathname,\n )}_${escapeString(name)}`;\n const rscName = `__remote_components_rsc_${keySuffix}`;\n\n const self = globalThis as Record<\n `__remote_components_shadowroot_${string}`,\n ShadowRoot | null\n > &\n Record<`__remote_components_container_${string}`, HTMLDivElement | null>;\n const shadowRootKey = `__remote_components_shadowroot_${keySuffix}` as const;\n const shadowContainerRef = useRef<HTMLDivElement | null>(\n typeof document === 'undefined'\n ? null\n : document.querySelector(\n `[data-remote-component-id=\"shadowroot_${remoteComponentId}\"]`,\n ),\n );\n const shadowRootRef = useRef<ShadowRoot | null>(\n self[shadowRootKey] ?? shadowContainerRef.current?.shadowRoot ?? null,\n );\n const ssrShadowRootContentRef = useRef<NodeListOf<ChildNode> | null>(null);\n const ssrLinksStylesRef = useRef<(HTMLLinkElement | HTMLStyleElement)[]>([]);\n\n if (self[shadowRootKey] && shadowRootRef.current) {\n self[shadowRootKey] = null;\n }\n\n useLayoutEffect(() => {\n if (\n !shadowContainerRef.current ||\n shadowContainerRef.current !== shadowRootRef.current?.host\n ) {\n shadowRootRef.current = null;\n }\n\n if (\n isolate !== false &&\n typeof document !== 'undefined' &&\n !shadowRootRef.current\n ) {\n let shadowRootElement: ShadowRoot | null = null;\n const element = shadowContainerRef.current;\n\n shadowRootElement = self[shadowRootKey] ?? element?.shadowRoot ?? null;\n self[shadowRootKey] = null;\n\n if (!shadowRootElement && element) {\n // create a shadow root if it doesn't exist\n // this is a fallback for browsers that don't support declarative shadow DOM\n try {\n shadowRootElement = element.attachShadow({ mode });\n } catch {\n // do nothing if attachShadow fails because of existing shadow root\n }\n }\n\n if (shadowRootElement) {\n shadowRootRef.current = shadowRootElement;\n }\n }\n\n // Capture SSR content once the shadow root is available. This runs\n // while shouldUseChildren is still true (before the portal adds its\n // own content), so the query captures only server-rendered nodes.\n if (\n !ssrShadowRootContentRef.current &&\n shadowRootRef.current &&\n shouldUseChildren\n ) {\n ssrShadowRootContentRef.current =\n shadowRootRef.current.querySelectorAll('*');\n }\n\n if (\n shadowRootRef.current &&\n ssrShadowRootContentRef.current &&\n !shouldUseChildren\n ) {\n // remove all nodes from the shadow root except links\n ssrShadowRootContentRef.current.forEach((node) => {\n if (node.nodeName !== 'LINK' && node.nodeName !== 'STYLE') {\n node.parentNode?.removeChild(node);\n } else {\n ssrLinksStylesRef.current.push(\n node as HTMLLinkElement | HTMLStyleElement,\n );\n }\n });\n ssrShadowRootContentRef.current = null;\n }\n\n if (ssrLinksStylesRef.current.length > 0 && shadowRootRef.current) {\n const waitForLoad =\n shadowRootRef.current.querySelectorAll('link[data-wait]');\n if (waitForLoad.length > 0) {\n Promise.all(\n Array.from(waitForLoad).map(\n (link) =>\n new Promise<void>((resolve) => {\n link.addEventListener('load', () => resolve());\n link.addEventListener('error', () => resolve());\n }),\n ),\n )\n .then(() => {\n waitForLoad.forEach((el) => {\n el.removeAttribute('data-wait');\n });\n\n // remove SSR injected styles and links\n ssrLinksStylesRef.current.forEach((el) => {\n el.parentNode?.removeChild(el);\n });\n ssrLinksStylesRef.current = [];\n })\n .catch((e) => {\n logError('NextAppRouter', 'Error in cleanup.', e);\n });\n }\n }\n }, [isolate, mode, self, shadowRootKey, shouldUseChildren]);\n\n useEffect(() => {\n // run unmount functions when the component changes or unmounts\n if (prevRemoteComponentUnmountRef.current && component !== children) {\n const { unmount, root } = prevRemoteComponentUnmountRef.current;\n prevRemoteComponentUnmountRef.current = null;\n Promise.all(\n Array.from(unmount).map(async (unmountFn) => {\n try {\n await unmountFn(root);\n } catch (e) {\n logError('NextAppRouter', 'Error in unmount.', e);\n }\n }),\n ).catch((e) => {\n logError('NextAppRouter', 'Error in unmount cleanup.', e);\n });\n }\n }, [component, children]);\n\n useEffect(() => {\n startTransition(async () => {\n try {\n // if we have a component, we don't need to load it again\n if (\n (hostStateRef.current.stage !== 'loading' &&\n !component &&\n (isolate === false || shadowRootRef.current)) ||\n metadataRef.current.url !== url.href ||\n metadataRef.current.name !== name ||\n metadataRef.current.bundle !== bundle ||\n metadataRef.current.route !== route\n ) {\n // Abort any in-flight load before starting a new one\n hostStateRef.current.abortController?.abort();\n const controller = new AbortController();\n hostStateRef.current.abortController = controller;\n\n hostStateRef.current.stage = 'loading';\n metadataRef.current = {\n name,\n bundle,\n route,\n url: url.href,\n };\n\n // use the children as the component when type is remote-component\n if (type === 'remote-component') {\n setComponent(children);\n // load static scripts and execute mount functions\n // run this async but don't await it as we render children immediately\n loadStaticRemoteComponent(\n scripts as HTMLScriptElement[],\n url,\n resolveClientUrl,\n )\n .then(({ mount, unmount }) => {\n if (mount.size > 0) {\n let root: ShadowRoot | DocumentFragment | null =\n shadowRootRef.current;\n try {\n if (!root && startRef.current && endRef.current) {\n root = document.querySelectorAll(\n `#${startRef.current.id} ~ *:not(#${endRef.current.id}):has(~ #${endRef.current.id})`,\n ) as unknown as DocumentFragment;\n }\n } catch (e) {\n logError('NextAppRouter', 'Error finding root element.', e);\n }\n if (unmount.size > 0) {\n prevRemoteComponentUnmountRef.current = { unmount, root };\n }\n return Promise.all(\n Array.from(mount).map((mountFn) => mountFn(root)),\n );\n }\n })\n .catch((e) => {\n logError(\n 'NextAppRouter',\n 'Error loading static remote component.',\n e,\n );\n setComponent(e as Error);\n });\n return;\n }\n\n const result = await runPipelineFromParsed({\n url,\n name,\n signal: controller.signal,\n payload: {\n name,\n bundle,\n route,\n runtime,\n data,\n nextData,\n scripts,\n },\n shared: resolveHostShared(resolveClientUrl),\n remoteShared,\n container: shadowRootRef.current,\n resolveClientUrl,\n rscName,\n });\n\n if (result.status === 'aborted') {\n return;\n }\n if (result.status === 'error') {\n hostStateRef.current.stage = 'error';\n setComponent(result.error);\n } else {\n hostStateRef.current.stage = 'loaded';\n setComponent(result.component);\n }\n }\n } catch (error: unknown) {\n hostStateRef.current.stage = 'error';\n setComponent(error as Error);\n }\n });\n\n return () => {\n hostStateRef.current.abortController?.abort();\n };\n }, [\n component,\n name,\n bundle,\n route,\n runtime,\n scripts,\n data,\n nextData,\n remoteShared,\n children,\n isolate,\n type,\n rscName,\n url,\n resolveClientUrl,\n ]);\n\n if (\n nextData?.buildId === 'development' &&\n shadowRootRef.current &&\n isolate !== false &&\n reset &&\n !shadowRootRef.current.querySelector('[data-remote-components-reset]')\n ) {\n // inject reset styles into the shadow root\n const style = document.createElement('style');\n style.setAttribute('data-remote-components-reset', '');\n style.textContent = `:host { all: initial; }`;\n shadowRootRef.current.insertBefore(style, shadowRootRef.current.firstChild);\n } else if (\n shadowRootRef.current &&\n isolate !== false &&\n !reset &&\n shadowRootRef.current.querySelector('[data-remote-components-reset]')\n ) {\n // ensure reset styles are the first child in the shadow root\n const style = shadowRootRef.current.querySelector(\n '[data-remote-components-reset]',\n );\n if (style && shadowRootRef.current.firstChild !== style) {\n shadowRootRef.current.removeChild(style);\n }\n }\n\n const linksToRender = (\n <RemoteComponentLinks\n links={links}\n url={url}\n serverUrl={serverUrl}\n bundle={bundle}\n isolate={isolate}\n reset={reset}\n isDevelopment={nextData?.buildId === 'development'}\n />\n );\n\n let componentToRender = shouldUseChildren\n ? children\n : (component as React.ReactNode);\n\n if (isolate !== false) {\n componentToRender = (\n <div\n data-remote-component-id={`shadowroot_${remoteComponentId}`}\n data-remote-component-isolation-root=\"\"\n id={`shadowroot_${name}`}\n ref={shadowContainerRef}\n >\n {typeof document === 'undefined' ? (\n // eslint-disable-next-line react/no-unknown-property\n <template shadowrootmode={mode}>\n {mode === 'closed' ? (\n <div\n dangerouslySetInnerHTML={{\n __html: `<img\n alt=\"\" decoding=\"async\" style=\"display:none\"\n src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==\"\n onload=\"(function(el){\n const root = el.getRootNode();\n globalThis.${shadowRootKey} = root;\n el.parentElement.remove();\n })(this)\"\n />`,\n }}\n />\n ) : null}\n {linksToRender}\n {shouldUseChildren ? children : null}\n </template>\n ) : null}\n {typeof document !== 'undefined' &&\n shadowRootRef.current &&\n !shouldUseChildren\n ? createPortal(\n <>\n {linksToRender}\n {componentToRender}\n </>,\n shadowRootRef.current,\n )\n : null}\n </div>\n );\n }\n\n return (\n <>\n {isolate === false ? (\n <template id={`${name}_start`} ref={startRef} />\n ) : null}\n <script data-remote-component type=\"application/json\">\n {JSON.stringify({\n name,\n bundle,\n route,\n runtime,\n })}\n </script>\n {isolate === false ? linksToRender : null}\n {componentToRender}\n {nextData ? (\n <script\n id={`${bundle}_${route.replace(\n /[^a-zA-Z0-9]+/g,\n '_',\n )}${name}_next_data`}\n type=\"application/json\"\n >\n {JSON.stringify(nextData)}\n </script>\n ) : null}\n {isolate === false ? <template id={`${name}_end`} ref={endRef} /> : null}\n </>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/nextjs/app-client.tsx"],"sourcesContent":["'use client';\n\nimport {\n startTransition,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { createImageLoaderSharedEntries } from '#internal/host/nextjs/image-shared';\nimport { tryImportShared } from '#internal/host/nextjs/shared-import';\nimport { useResolveClientUrl } from '#internal/host/react/hooks/use-resolve-client-url';\nimport { getClientOrServerUrl } from '#internal/host/server/get-client-or-server-url';\nimport type { InternalResolveClientUrl } from '#internal/host/server/types';\nimport type { ConsumeClientOnlyConfig } from '#internal/host/shared/config';\nimport { runPipelineFromParsed } from '#internal/host/shared/pipeline';\nimport type { ConsumeServerData } from '#internal/host/shared/server-handoff';\nimport { createHostState } from '#internal/host/shared/state';\nimport { DEFAULT_ROUTE, RUNTIME_WEBPACK } from '#internal/runtime/constants';\nimport { loadStaticRemoteComponent } from '#internal/runtime/loaders/static-loader';\nimport type { MountOrUnmountFunction } from '#internal/runtime/types';\nimport { escapeString } from '#internal/utils';\nimport { logError } from '#internal/utils/logger';\nimport { routerImpl } from './app-compat';\nimport { RemoteComponentLinks } from './remote-component-links';\n\n/**\n * Resolves host-side shared modules (React, Next.js router, image loader, etc.)\n * and returns them as a map the loading pipeline can pass to remotes.\n */\nasync function resolveHostShared(\n resolveClientUrl: InternalResolveClientUrl | undefined,\n): Promise<Record<string, (bundle?: string) => Promise<unknown>>> {\n const shared = await tryImportShared();\n if ('__remote_components_missing_shared__' in shared) {\n await shared.__remote_components_missing_shared__();\n }\n return {\n 'next/router': routerImpl,\n ...shared,\n ...createImageLoaderSharedEntries({ bound: resolveClientUrl }),\n };\n}\n\n/**\n * Extends the RSC-serializable data with {@link ConsumeClientConfig} fields\n * (like `resolveClientUrl`) that can't cross the server→client boundary\n * but are accepted when this component is used directly as a client import.\n */\ninterface ConsumeRemoteComponentClientProps\n extends ConsumeServerData,\n ConsumeClientOnlyConfig {}\n\n/**\n * ConsumeRemoteComponentClient - Main component for rendering remote components\n *\n * This component handles the loading and rendering of remote microfrontends.\n * It supports both RSC (React Server Components) and Next.js Pages Router based components.\n */\nexport function ConsumeRemoteComponentClient({\n src,\n serverUrl,\n name,\n bundle,\n route = DEFAULT_ROUTE,\n runtime = RUNTIME_WEBPACK,\n data,\n nextData,\n scripts = [],\n links = [],\n remoteShared = {},\n isolate,\n mode = 'open',\n resolveClientUrl: resolveClientUrlProp,\n reset,\n type,\n children,\n}: ConsumeRemoteComponentClientProps) {\n const remoteComponentId = useId();\n const [component, setComponent] = useState<React.ReactNode | Error>(null);\n const url = getClientOrServerUrl(src, serverUrl);\n const resolveClientUrl = useResolveClientUrl(resolveClientUrlProp, url.href);\n const hostStateRef = useRef(createHostState());\n const metadataRef = useRef<{\n name: string;\n bundle: string;\n route: string;\n url: string;\n }>({\n name,\n bundle,\n route,\n url: url.href,\n });\n const startRef = useRef<HTMLTemplateElement | null>(null);\n const endRef = useRef<HTMLTemplateElement | null>(null);\n const prevRemoteComponentUnmountRef = useRef<{\n unmount: Set<MountOrUnmountFunction>;\n root: ShadowRoot | DocumentFragment | null;\n } | null>(null);\n\n // Handle errors by re-throwing them\n if (component instanceof Error) {\n throw component;\n }\n\n // determine whether to use children or loaded component\n const shouldUseChildren =\n (!component ||\n (component &&\n !nextData &&\n type !== 'remote-component' &&\n typeof (component as unknown as Promise<unknown>).then !==\n 'function')) &&\n // if the remote Next.js Pages Router application is in development mode\n // we don't use the provided static HTML\n // to mitigate layout shift when loading CSS using JavaScript on the client\n nextData?.buildId !== 'development';\n\n // The pathname is used so this URL is the same across server and client requests for relative src's\n const keySuffix = `${escapeString(bundle)}_${escapeString(\n url.pathname,\n )}_${escapeString(name)}`;\n const rscName = `__remote_components_rsc_${keySuffix}`;\n\n const self = globalThis as Record<\n `__remote_components_shadowroot_${string}`,\n ShadowRoot | null\n > &\n Record<`__remote_components_container_${string}`, HTMLDivElement | null>;\n const shadowRootKey = `__remote_components_shadowroot_${keySuffix}` as const;\n const shadowContainerRef = useRef<HTMLDivElement | null>(\n typeof document === 'undefined'\n ? null\n : document.querySelector(\n `[data-remote-component-id=\"shadowroot_${remoteComponentId}\"]`,\n ),\n );\n const shadowRootRef = useRef<ShadowRoot | null>(\n self[shadowRootKey] ?? shadowContainerRef.current?.shadowRoot ?? null,\n );\n const ssrShadowRootContentRef = useRef<NodeListOf<ChildNode> | null>(null);\n const ssrLinksStylesRef = useRef<(HTMLLinkElement | HTMLStyleElement)[]>([]);\n\n if (self[shadowRootKey] && shadowRootRef.current) {\n self[shadowRootKey] = null;\n }\n\n useLayoutEffect(() => {\n if (\n !shadowContainerRef.current ||\n shadowContainerRef.current !== shadowRootRef.current?.host\n ) {\n shadowRootRef.current = null;\n }\n\n if (\n isolate !== false &&\n typeof document !== 'undefined' &&\n !shadowRootRef.current\n ) {\n let shadowRootElement: ShadowRoot | null = null;\n const element = shadowContainerRef.current;\n\n shadowRootElement = self[shadowRootKey] ?? element?.shadowRoot ?? null;\n self[shadowRootKey] = null;\n\n if (!shadowRootElement && element) {\n // create a shadow root if it doesn't exist\n // this is a fallback for browsers that don't support declarative shadow DOM\n try {\n shadowRootElement = element.attachShadow({ mode });\n } catch {\n // do nothing if attachShadow fails because of existing shadow root\n }\n }\n\n if (shadowRootElement) {\n shadowRootRef.current = shadowRootElement;\n }\n }\n\n // Capture SSR content once the shadow root is available. This runs\n // while shouldUseChildren is still true (before the portal adds its\n // own content), so the query captures only server-rendered nodes.\n if (\n !ssrShadowRootContentRef.current &&\n shadowRootRef.current &&\n shouldUseChildren\n ) {\n ssrShadowRootContentRef.current =\n shadowRootRef.current.querySelectorAll('*');\n }\n\n if (\n shadowRootRef.current &&\n ssrShadowRootContentRef.current &&\n !shouldUseChildren\n ) {\n // remove all nodes from the shadow root except links\n ssrShadowRootContentRef.current.forEach((node) => {\n if (node.nodeName !== 'LINK' && node.nodeName !== 'STYLE') {\n node.parentNode?.removeChild(node);\n } else {\n ssrLinksStylesRef.current.push(\n node as HTMLLinkElement | HTMLStyleElement,\n );\n }\n });\n ssrShadowRootContentRef.current = null;\n }\n\n if (ssrLinksStylesRef.current.length > 0 && shadowRootRef.current) {\n const waitForLoad =\n shadowRootRef.current.querySelectorAll('link[data-wait]');\n if (waitForLoad.length > 0) {\n Promise.all(\n Array.from(waitForLoad).map(\n (link) =>\n new Promise<void>((resolve) => {\n link.addEventListener('load', () => resolve());\n link.addEventListener('error', () => resolve());\n }),\n ),\n )\n .then(() => {\n waitForLoad.forEach((el) => {\n el.removeAttribute('data-wait');\n });\n\n // remove SSR injected styles and links\n ssrLinksStylesRef.current.forEach((el) => {\n el.parentNode?.removeChild(el);\n });\n ssrLinksStylesRef.current = [];\n })\n .catch((e) => {\n logError('NextAppRouter', 'Error in cleanup.', e);\n });\n }\n }\n }, [isolate, mode, self, shadowRootKey, shouldUseChildren]);\n\n useEffect(() => {\n // run unmount functions when the component changes or unmounts\n if (prevRemoteComponentUnmountRef.current && component !== children) {\n const { unmount, root } = prevRemoteComponentUnmountRef.current;\n prevRemoteComponentUnmountRef.current = null;\n Promise.all(\n Array.from(unmount).map(async (unmountFn) => {\n try {\n await unmountFn(root);\n } catch (e) {\n logError('NextAppRouter', 'Error in unmount.', e);\n }\n }),\n ).catch((e) => {\n logError('NextAppRouter', 'Error in unmount cleanup.', e);\n });\n }\n }, [component, children]);\n\n useEffect(() => {\n return () => {\n hostStateRef.current.abortController?.abort();\n hostStateRef.current.abortController = undefined;\n hostStateRef.current.stage = 'idle';\n };\n }, []);\n\n useEffect(() => {\n startTransition(async () => {\n try {\n // if we have a component, we don't need to load it again\n if (\n (hostStateRef.current.stage !== 'loading' &&\n !component &&\n (isolate === false || shadowRootRef.current)) ||\n metadataRef.current.url !== url.href ||\n metadataRef.current.name !== name ||\n metadataRef.current.bundle !== bundle ||\n metadataRef.current.route !== route\n ) {\n // Abort any in-flight load before starting a new one\n hostStateRef.current.abortController?.abort();\n const controller = new AbortController();\n hostStateRef.current.abortController = controller;\n\n hostStateRef.current.stage = 'loading';\n metadataRef.current = {\n name,\n bundle,\n route,\n url: url.href,\n };\n\n // use the children as the component when type is remote-component\n if (type === 'remote-component') {\n setComponent(children);\n // load static scripts and execute mount functions\n // run this async but don't await it as we render children immediately\n loadStaticRemoteComponent(\n scripts as HTMLScriptElement[],\n url,\n resolveClientUrl,\n )\n .then(({ mount, unmount }) => {\n if (mount.size > 0) {\n let root: ShadowRoot | DocumentFragment | null =\n shadowRootRef.current;\n try {\n if (!root && startRef.current && endRef.current) {\n root = document.querySelectorAll(\n `#${startRef.current.id} ~ *:not(#${endRef.current.id}):has(~ #${endRef.current.id})`,\n ) as unknown as DocumentFragment;\n }\n } catch (e) {\n logError('NextAppRouter', 'Error finding root element.', e);\n }\n if (unmount.size > 0) {\n prevRemoteComponentUnmountRef.current = { unmount, root };\n }\n return Promise.all(\n Array.from(mount).map((mountFn) => mountFn(root)),\n );\n }\n })\n .catch((e) => {\n logError(\n 'NextAppRouter',\n 'Error loading static remote component.',\n e,\n );\n setComponent(e as Error);\n });\n return;\n }\n\n const result = await runPipelineFromParsed({\n url,\n name,\n signal: controller.signal,\n payload: {\n name,\n bundle,\n route,\n runtime,\n data,\n nextData,\n scripts,\n },\n shared: resolveHostShared(resolveClientUrl),\n remoteShared,\n container: shadowRootRef.current,\n resolveClientUrl,\n rscName,\n });\n\n if (result.status === 'aborted') {\n return;\n }\n if (result.status === 'error') {\n hostStateRef.current.stage = 'error';\n setComponent(result.error);\n } else {\n hostStateRef.current.stage = 'loaded';\n setComponent(result.component);\n }\n }\n } catch (error: unknown) {\n hostStateRef.current.stage = 'error';\n setComponent(error as Error);\n }\n });\n }, [\n component,\n name,\n bundle,\n route,\n runtime,\n scripts,\n data,\n nextData,\n remoteShared,\n children,\n isolate,\n type,\n rscName,\n url,\n resolveClientUrl,\n ]);\n\n if (\n nextData?.buildId === 'development' &&\n shadowRootRef.current &&\n isolate !== false &&\n reset &&\n !shadowRootRef.current.querySelector('[data-remote-components-reset]')\n ) {\n // inject reset styles into the shadow root\n const style = document.createElement('style');\n style.setAttribute('data-remote-components-reset', '');\n style.textContent = `:host { all: initial; }`;\n shadowRootRef.current.insertBefore(style, shadowRootRef.current.firstChild);\n } else if (\n shadowRootRef.current &&\n isolate !== false &&\n !reset &&\n shadowRootRef.current.querySelector('[data-remote-components-reset]')\n ) {\n // ensure reset styles are the first child in the shadow root\n const style = shadowRootRef.current.querySelector(\n '[data-remote-components-reset]',\n );\n if (style && shadowRootRef.current.firstChild !== style) {\n shadowRootRef.current.removeChild(style);\n }\n }\n\n const linksToRender = (\n <RemoteComponentLinks\n links={links}\n url={url}\n serverUrl={serverUrl}\n bundle={bundle}\n isolate={isolate}\n reset={reset}\n isDevelopment={nextData?.buildId === 'development'}\n />\n );\n\n let componentToRender = shouldUseChildren\n ? children\n : (component as React.ReactNode);\n\n if (isolate !== false) {\n componentToRender = (\n <div\n data-remote-component-id={`shadowroot_${remoteComponentId}`}\n data-remote-component-isolation-root=\"\"\n id={`shadowroot_${name}`}\n ref={shadowContainerRef}\n >\n {typeof document === 'undefined' ? (\n // eslint-disable-next-line react/no-unknown-property\n <template shadowrootmode={mode}>\n {mode === 'closed' ? (\n <div\n dangerouslySetInnerHTML={{\n __html: `<img\n alt=\"\" decoding=\"async\" style=\"display:none\"\n src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==\"\n onload=\"(function(el){\n const root = el.getRootNode();\n globalThis.${shadowRootKey} = root;\n el.parentElement.remove();\n })(this)\"\n />`,\n }}\n />\n ) : null}\n {linksToRender}\n {shouldUseChildren ? children : null}\n </template>\n ) : null}\n {typeof document !== 'undefined' &&\n shadowRootRef.current &&\n !shouldUseChildren\n ? createPortal(\n <>\n {linksToRender}\n {componentToRender}\n </>,\n shadowRootRef.current,\n )\n : null}\n </div>\n );\n }\n\n return (\n <>\n {isolate === false ? (\n <template id={`${name}_start`} ref={startRef} />\n ) : null}\n <script data-remote-component type=\"application/json\">\n {JSON.stringify({\n name,\n bundle,\n route,\n runtime,\n })}\n </script>\n {isolate === false ? linksToRender : null}\n {componentToRender}\n {nextData ? (\n <script\n id={`${bundle}_${route.replace(\n /[^a-zA-Z0-9]+/g,\n '_',\n )}${name}_next_data`}\n type=\"application/json\"\n >\n {JSON.stringify(nextData)}\n </script>\n ) : null}\n {isolate === false ? <template id={`${name}_end`} ref={endRef} /> : null}\n </>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -22,6 +22,26 @@ __export(remote_image_loader_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(remote_image_loader_exports);
|
|
24
24
|
var import_remote_scope = require("#internal/runtime/turbopack/remote-scope");
|
|
25
|
+
function extractDeploymentIdFromSrc(src) {
|
|
26
|
+
if (!src.startsWith("/") || src.startsWith("//")) {
|
|
27
|
+
return { deploymentId: void 0, src };
|
|
28
|
+
}
|
|
29
|
+
const queryIndex = src.indexOf("?");
|
|
30
|
+
if (queryIndex === -1) {
|
|
31
|
+
return { deploymentId: void 0, src };
|
|
32
|
+
}
|
|
33
|
+
const params = new URLSearchParams(src.slice(queryIndex + 1));
|
|
34
|
+
const deploymentId = params.get("dpl") || void 0;
|
|
35
|
+
if (!deploymentId) {
|
|
36
|
+
return { deploymentId: void 0, src };
|
|
37
|
+
}
|
|
38
|
+
params.delete("dpl");
|
|
39
|
+
const remaining = params.toString();
|
|
40
|
+
return {
|
|
41
|
+
deploymentId,
|
|
42
|
+
src: `${src.slice(0, queryIndex)}${remaining ? `?${remaining}` : ""}`
|
|
43
|
+
};
|
|
44
|
+
}
|
|
25
45
|
function createRemoteImageLoader(bundle, resolveClientUrl) {
|
|
26
46
|
const loader = Object.assign(
|
|
27
47
|
({
|
|
@@ -34,7 +54,9 @@ function createRemoteImageLoader(bundle, resolveClientUrl) {
|
|
|
34
54
|
const remoteOrigin = (0, import_remote_scope.getScope)(bundle)?.url.origin ?? "";
|
|
35
55
|
const isCrossOrigin = remoteOrigin && remoteOrigin !== location.origin;
|
|
36
56
|
const basePath = isCrossOrigin ? `${remoteOrigin}${config.path ?? "/_next/image"}` : config.path ?? `${remoteOrigin}/_next/image`;
|
|
37
|
-
const
|
|
57
|
+
const extracted = extractDeploymentIdFromSrc(src);
|
|
58
|
+
const deploymentParam = extracted.deploymentId ? `&dpl=${encodeURIComponent(extracted.deploymentId)}` : "";
|
|
59
|
+
const url = `${basePath}?url=${encodeURIComponent(extracted.src)}&w=${width}&q=${q}${deploymentParam}`;
|
|
38
60
|
return resolveClientUrl?.(url) ?? url;
|
|
39
61
|
},
|
|
40
62
|
// Signals to getImgProps that this is a default loader (not a user-defined
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/host/shared/remote-image-loader.ts"],"sourcesContent":["import { getScope } from '#internal/runtime/turbopack/remote-scope';\nimport type { InternalResolveClientUrl } from '#internal/runtime/url/resolve-client-url';\n\n/**\n * Replacement for `next/dist/shared/lib/image-loader`.\n *\n * Uses `config.path` (which includes the remote's asset prefix, e.g.\n * `/vc-ap-xxx/_next/image`) to generate URLs that match the server-rendered\n * HTML and avoid hydration mismatches. Under the microfrontends proxy these\n * relative paths are routed to the correct app.\n *\n * For cross-origin deployments (standalone host on a different domain),\n * `config.path` is a relative path that would incorrectly resolve to the host\n * origin, so we prefix it with the remote origin to produce an absolute URL\n * pointing at the remote's optimizer.\n *\n * When `resolveClientUrl` is provided (deployment protection), the final URL\n * is routed through the host's proxy.\n */\nexport function createRemoteImageLoader(\n bundle: string,\n resolveClientUrl?: InternalResolveClientUrl,\n) {\n const loader = Object.assign(\n ({\n config,\n src,\n width,\n quality,\n }: {\n config: { path?: string };\n src: string;\n width: number;\n quality?: number;\n }) => {\n const q = quality ?? 75;\n const remoteOrigin = getScope(bundle)?.url.origin ?? '';\n const isCrossOrigin = remoteOrigin && remoteOrigin !== location.origin;\n const basePath = isCrossOrigin\n ? `${remoteOrigin}${config.path ?? '/_next/image'}`\n : (config.path ?? `${remoteOrigin}/_next/image`);\n const url = `${basePath}?url=${encodeURIComponent(src)}&w=${width}&q=${q}`;\n return resolveClientUrl?.(url) ?? url;\n },\n // Signals to getImgProps that this is a default loader (not a user-defined\n // one), enabling srcSet generation with device/image sizes from the config.\n { __next_img_default: true as const },\n );\n return loader;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAyB;
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/shared/remote-image-loader.ts"],"sourcesContent":["import { getScope } from '#internal/runtime/turbopack/remote-scope';\nimport type { InternalResolveClientUrl } from '#internal/runtime/url/resolve-client-url';\n\nfunction extractDeploymentIdFromSrc(src: string) {\n if (!src.startsWith('/') || src.startsWith('//')) {\n return { deploymentId: undefined, src };\n }\n\n const queryIndex = src.indexOf('?');\n if (queryIndex === -1) {\n return { deploymentId: undefined, src };\n }\n\n const params = new URLSearchParams(src.slice(queryIndex + 1));\n const deploymentId = params.get('dpl') || undefined;\n if (!deploymentId) {\n return { deploymentId: undefined, src };\n }\n\n params.delete('dpl');\n const remaining = params.toString();\n return {\n deploymentId,\n src: `${src.slice(0, queryIndex)}${remaining ? `?${remaining}` : ''}`,\n };\n}\n\n/**\n * Replacement for `next/dist/shared/lib/image-loader`.\n *\n * Uses `config.path` (which includes the remote's asset prefix, e.g.\n * `/vc-ap-xxx/_next/image`) to generate URLs that match the server-rendered\n * HTML and avoid hydration mismatches. Under the microfrontends proxy these\n * relative paths are routed to the correct app.\n *\n * For cross-origin deployments (standalone host on a different domain),\n * `config.path` is a relative path that would incorrectly resolve to the host\n * origin, so we prefix it with the remote origin to produce an absolute URL\n * pointing at the remote's optimizer.\n *\n * When `resolveClientUrl` is provided (deployment protection), the final URL\n * is routed through the host's proxy.\n */\nexport function createRemoteImageLoader(\n bundle: string,\n resolveClientUrl?: InternalResolveClientUrl,\n) {\n const loader = Object.assign(\n ({\n config,\n src,\n width,\n quality,\n }: {\n config: { path?: string };\n src: string;\n width: number;\n quality?: number;\n }) => {\n const q = quality ?? 75;\n const remoteOrigin = getScope(bundle)?.url.origin ?? '';\n const isCrossOrigin = remoteOrigin && remoteOrigin !== location.origin;\n const basePath = isCrossOrigin\n ? `${remoteOrigin}${config.path ?? '/_next/image'}`\n : (config.path ?? `${remoteOrigin}/_next/image`);\n const extracted = extractDeploymentIdFromSrc(src);\n const deploymentParam = extracted.deploymentId\n ? `&dpl=${encodeURIComponent(extracted.deploymentId)}`\n : '';\n const url = `${basePath}?url=${encodeURIComponent(extracted.src)}&w=${width}&q=${q}${deploymentParam}`;\n return resolveClientUrl?.(url) ?? url;\n },\n // Signals to getImgProps that this is a default loader (not a user-defined\n // one), enabling srcSet generation with device/image sizes from the config.\n { __next_img_default: true as const },\n );\n return loader;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAyB;AAGzB,SAAS,2BAA2B,KAAa;AAC/C,MAAI,CAAC,IAAI,WAAW,GAAG,KAAK,IAAI,WAAW,IAAI,GAAG;AAChD,WAAO,EAAE,cAAc,QAAW,IAAI;AAAA,EACxC;AAEA,QAAM,aAAa,IAAI,QAAQ,GAAG;AAClC,MAAI,eAAe,IAAI;AACrB,WAAO,EAAE,cAAc,QAAW,IAAI;AAAA,EACxC;AAEA,QAAM,SAAS,IAAI,gBAAgB,IAAI,MAAM,aAAa,CAAC,CAAC;AAC5D,QAAM,eAAe,OAAO,IAAI,KAAK,KAAK;AAC1C,MAAI,CAAC,cAAc;AACjB,WAAO,EAAE,cAAc,QAAW,IAAI;AAAA,EACxC;AAEA,SAAO,OAAO,KAAK;AACnB,QAAM,YAAY,OAAO,SAAS;AAClC,SAAO;AAAA,IACL;AAAA,IACA,KAAK,GAAG,IAAI,MAAM,GAAG,UAAU,IAAI,YAAY,IAAI,cAAc;AAAA,EACnE;AACF;AAkBO,SAAS,wBACd,QACA,kBACA;AACA,QAAM,SAAS,OAAO;AAAA,IACpB,CAAC;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,MAKM;AACJ,YAAM,IAAI,WAAW;AACrB,YAAM,mBAAe,8BAAS,MAAM,GAAG,IAAI,UAAU;AACrD,YAAM,gBAAgB,gBAAgB,iBAAiB,SAAS;AAChE,YAAM,WAAW,gBACb,GAAG,eAAe,OAAO,QAAQ,mBAChC,OAAO,QAAQ,GAAG;AACvB,YAAM,YAAY,2BAA2B,GAAG;AAChD,YAAM,kBAAkB,UAAU,eAC9B,QAAQ,mBAAmB,UAAU,YAAY,MACjD;AACJ,YAAM,MAAM,GAAG,gBAAgB,mBAAmB,UAAU,GAAG,OAAO,WAAW,IAAI;AACrF,aAAO,mBAAmB,GAAG,KAAK;AAAA,IACpC;AAAA;AAAA;AAAA,IAGA,EAAE,oBAAoB,KAAc;AAAA,EACtC;AACA,SAAO;AACT;","names":[]}
|
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
import { getScope } from "#internal/runtime/turbopack/remote-scope";
|
|
2
|
+
function extractDeploymentIdFromSrc(src) {
|
|
3
|
+
if (!src.startsWith("/") || src.startsWith("//")) {
|
|
4
|
+
return { deploymentId: void 0, src };
|
|
5
|
+
}
|
|
6
|
+
const queryIndex = src.indexOf("?");
|
|
7
|
+
if (queryIndex === -1) {
|
|
8
|
+
return { deploymentId: void 0, src };
|
|
9
|
+
}
|
|
10
|
+
const params = new URLSearchParams(src.slice(queryIndex + 1));
|
|
11
|
+
const deploymentId = params.get("dpl") || void 0;
|
|
12
|
+
if (!deploymentId) {
|
|
13
|
+
return { deploymentId: void 0, src };
|
|
14
|
+
}
|
|
15
|
+
params.delete("dpl");
|
|
16
|
+
const remaining = params.toString();
|
|
17
|
+
return {
|
|
18
|
+
deploymentId,
|
|
19
|
+
src: `${src.slice(0, queryIndex)}${remaining ? `?${remaining}` : ""}`
|
|
20
|
+
};
|
|
21
|
+
}
|
|
2
22
|
function createRemoteImageLoader(bundle, resolveClientUrl) {
|
|
3
23
|
const loader = Object.assign(
|
|
4
24
|
({
|
|
@@ -11,7 +31,9 @@ function createRemoteImageLoader(bundle, resolveClientUrl) {
|
|
|
11
31
|
const remoteOrigin = getScope(bundle)?.url.origin ?? "";
|
|
12
32
|
const isCrossOrigin = remoteOrigin && remoteOrigin !== location.origin;
|
|
13
33
|
const basePath = isCrossOrigin ? `${remoteOrigin}${config.path ?? "/_next/image"}` : config.path ?? `${remoteOrigin}/_next/image`;
|
|
14
|
-
const
|
|
34
|
+
const extracted = extractDeploymentIdFromSrc(src);
|
|
35
|
+
const deploymentParam = extracted.deploymentId ? `&dpl=${encodeURIComponent(extracted.deploymentId)}` : "";
|
|
36
|
+
const url = `${basePath}?url=${encodeURIComponent(extracted.src)}&w=${width}&q=${q}${deploymentParam}`;
|
|
15
37
|
return resolveClientUrl?.(url) ?? url;
|
|
16
38
|
},
|
|
17
39
|
// Signals to getImgProps that this is a default loader (not a user-defined
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/host/shared/remote-image-loader.ts"],"sourcesContent":["import { getScope } from '#internal/runtime/turbopack/remote-scope';\nimport type { InternalResolveClientUrl } from '#internal/runtime/url/resolve-client-url';\n\n/**\n * Replacement for `next/dist/shared/lib/image-loader`.\n *\n * Uses `config.path` (which includes the remote's asset prefix, e.g.\n * `/vc-ap-xxx/_next/image`) to generate URLs that match the server-rendered\n * HTML and avoid hydration mismatches. Under the microfrontends proxy these\n * relative paths are routed to the correct app.\n *\n * For cross-origin deployments (standalone host on a different domain),\n * `config.path` is a relative path that would incorrectly resolve to the host\n * origin, so we prefix it with the remote origin to produce an absolute URL\n * pointing at the remote's optimizer.\n *\n * When `resolveClientUrl` is provided (deployment protection), the final URL\n * is routed through the host's proxy.\n */\nexport function createRemoteImageLoader(\n bundle: string,\n resolveClientUrl?: InternalResolveClientUrl,\n) {\n const loader = Object.assign(\n ({\n config,\n src,\n width,\n quality,\n }: {\n config: { path?: string };\n src: string;\n width: number;\n quality?: number;\n }) => {\n const q = quality ?? 75;\n const remoteOrigin = getScope(bundle)?.url.origin ?? '';\n const isCrossOrigin = remoteOrigin && remoteOrigin !== location.origin;\n const basePath = isCrossOrigin\n ? `${remoteOrigin}${config.path ?? '/_next/image'}`\n : (config.path ?? `${remoteOrigin}/_next/image`);\n const url = `${basePath}?url=${encodeURIComponent(src)}&w=${width}&q=${q}`;\n return resolveClientUrl?.(url) ?? url;\n },\n // Signals to getImgProps that this is a default loader (not a user-defined\n // one), enabling srcSet generation with device/image sizes from the config.\n { __next_img_default: true as const },\n );\n return loader;\n}\n"],"mappings":"AAAA,SAAS,gBAAgB;
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/shared/remote-image-loader.ts"],"sourcesContent":["import { getScope } from '#internal/runtime/turbopack/remote-scope';\nimport type { InternalResolveClientUrl } from '#internal/runtime/url/resolve-client-url';\n\nfunction extractDeploymentIdFromSrc(src: string) {\n if (!src.startsWith('/') || src.startsWith('//')) {\n return { deploymentId: undefined, src };\n }\n\n const queryIndex = src.indexOf('?');\n if (queryIndex === -1) {\n return { deploymentId: undefined, src };\n }\n\n const params = new URLSearchParams(src.slice(queryIndex + 1));\n const deploymentId = params.get('dpl') || undefined;\n if (!deploymentId) {\n return { deploymentId: undefined, src };\n }\n\n params.delete('dpl');\n const remaining = params.toString();\n return {\n deploymentId,\n src: `${src.slice(0, queryIndex)}${remaining ? `?${remaining}` : ''}`,\n };\n}\n\n/**\n * Replacement for `next/dist/shared/lib/image-loader`.\n *\n * Uses `config.path` (which includes the remote's asset prefix, e.g.\n * `/vc-ap-xxx/_next/image`) to generate URLs that match the server-rendered\n * HTML and avoid hydration mismatches. Under the microfrontends proxy these\n * relative paths are routed to the correct app.\n *\n * For cross-origin deployments (standalone host on a different domain),\n * `config.path` is a relative path that would incorrectly resolve to the host\n * origin, so we prefix it with the remote origin to produce an absolute URL\n * pointing at the remote's optimizer.\n *\n * When `resolveClientUrl` is provided (deployment protection), the final URL\n * is routed through the host's proxy.\n */\nexport function createRemoteImageLoader(\n bundle: string,\n resolveClientUrl?: InternalResolveClientUrl,\n) {\n const loader = Object.assign(\n ({\n config,\n src,\n width,\n quality,\n }: {\n config: { path?: string };\n src: string;\n width: number;\n quality?: number;\n }) => {\n const q = quality ?? 75;\n const remoteOrigin = getScope(bundle)?.url.origin ?? '';\n const isCrossOrigin = remoteOrigin && remoteOrigin !== location.origin;\n const basePath = isCrossOrigin\n ? `${remoteOrigin}${config.path ?? '/_next/image'}`\n : (config.path ?? `${remoteOrigin}/_next/image`);\n const extracted = extractDeploymentIdFromSrc(src);\n const deploymentParam = extracted.deploymentId\n ? `&dpl=${encodeURIComponent(extracted.deploymentId)}`\n : '';\n const url = `${basePath}?url=${encodeURIComponent(extracted.src)}&w=${width}&q=${q}${deploymentParam}`;\n return resolveClientUrl?.(url) ?? url;\n },\n // Signals to getImgProps that this is a default loader (not a user-defined\n // one), enabling srcSet generation with device/image sizes from the config.\n { __next_img_default: true as const },\n );\n return loader;\n}\n"],"mappings":"AAAA,SAAS,gBAAgB;AAGzB,SAAS,2BAA2B,KAAa;AAC/C,MAAI,CAAC,IAAI,WAAW,GAAG,KAAK,IAAI,WAAW,IAAI,GAAG;AAChD,WAAO,EAAE,cAAc,QAAW,IAAI;AAAA,EACxC;AAEA,QAAM,aAAa,IAAI,QAAQ,GAAG;AAClC,MAAI,eAAe,IAAI;AACrB,WAAO,EAAE,cAAc,QAAW,IAAI;AAAA,EACxC;AAEA,QAAM,SAAS,IAAI,gBAAgB,IAAI,MAAM,aAAa,CAAC,CAAC;AAC5D,QAAM,eAAe,OAAO,IAAI,KAAK,KAAK;AAC1C,MAAI,CAAC,cAAc;AACjB,WAAO,EAAE,cAAc,QAAW,IAAI;AAAA,EACxC;AAEA,SAAO,OAAO,KAAK;AACnB,QAAM,YAAY,OAAO,SAAS;AAClC,SAAO;AAAA,IACL;AAAA,IACA,KAAK,GAAG,IAAI,MAAM,GAAG,UAAU,IAAI,YAAY,IAAI,cAAc;AAAA,EACnE;AACF;AAkBO,SAAS,wBACd,QACA,kBACA;AACA,QAAM,SAAS,OAAO;AAAA,IACpB,CAAC;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,MAKM;AACJ,YAAM,IAAI,WAAW;AACrB,YAAM,eAAe,SAAS,MAAM,GAAG,IAAI,UAAU;AACrD,YAAM,gBAAgB,gBAAgB,iBAAiB,SAAS;AAChE,YAAM,WAAW,gBACb,GAAG,eAAe,OAAO,QAAQ,mBAChC,OAAO,QAAQ,GAAG;AACvB,YAAM,YAAY,2BAA2B,GAAG;AAChD,YAAM,kBAAkB,UAAU,eAC9B,QAAQ,mBAAmB,UAAU,YAAY,MACjD;AACJ,YAAM,MAAM,GAAG,gBAAgB,mBAAmB,UAAU,GAAG,OAAO,WAAW,IAAI;AACrF,aAAO,mBAAmB,GAAG,KAAK;AAAA,IACpC;AAAA;AAAA;AAAA,IAGA,EAAE,oBAAoB,KAAc;AAAA,EACtC;AACA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }"use client";
|
|
2
|
+
|
|
3
|
+
// src/remote/react/utils/portal.tsx
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _react = require('react');
|
|
8
|
+
var _reactdom = require('react-dom');
|
|
9
|
+
var _jsxruntime = require('react/jsx-runtime');
|
|
10
|
+
var DEFAULT_PORTAL_CONTAINER_NAME = "default";
|
|
11
|
+
function useRemotePortalContainer(anchorRef, options = {}) {
|
|
12
|
+
const [container, setContainer] = _react.useState.call(void 0, null);
|
|
13
|
+
const anchor = anchorRef.current;
|
|
14
|
+
const containerName = _nullishCoalesce(options.name, () => ( DEFAULT_PORTAL_CONTAINER_NAME));
|
|
15
|
+
_react.useLayoutEffect.call(void 0, () => {
|
|
16
|
+
if (!anchor) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const ownerDocument = anchor.ownerDocument;
|
|
20
|
+
const root = anchor.getRootNode();
|
|
21
|
+
if (typeof ShadowRoot !== "undefined" && root instanceof ShadowRoot) {
|
|
22
|
+
const existingContainer = Array.from(
|
|
23
|
+
root.querySelectorAll(
|
|
24
|
+
"[data-remote-components-portal-container]"
|
|
25
|
+
)
|
|
26
|
+
).find(
|
|
27
|
+
(element) => element.getAttribute("data-remote-components-portal-container") === containerName
|
|
28
|
+
);
|
|
29
|
+
if (existingContainer) {
|
|
30
|
+
setContainer(existingContainer);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const shadowContainer = ownerDocument.createElement("div");
|
|
34
|
+
shadowContainer.setAttribute(
|
|
35
|
+
"data-remote-components-portal-container",
|
|
36
|
+
containerName
|
|
37
|
+
);
|
|
38
|
+
root.appendChild(shadowContainer);
|
|
39
|
+
setContainer(shadowContainer);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
setContainer(ownerDocument.body);
|
|
43
|
+
}, [anchor, containerName]);
|
|
44
|
+
return container;
|
|
45
|
+
}
|
|
46
|
+
function RemotePortal({ children, name }) {
|
|
47
|
+
const [anchor, setAnchor] = _react.useState.call(void 0, null);
|
|
48
|
+
const container = useRemotePortalContainer({ current: anchor }, { name });
|
|
49
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
50
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { hidden: true, ref: setAnchor, "data-remote-components-portal-anchor": "" }),
|
|
51
|
+
container ? _reactdom.createPortal.call(void 0, children, container) : null
|
|
52
|
+
] });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
exports.RemotePortal = RemotePortal; exports.useRemotePortalContainer = useRemotePortalContainer;
|
|
58
|
+
//# sourceMappingURL=portal.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/remote/react/utils/portal.tsx"],"names":[],"mappings":";;;AAEA;AAAA,EAGE;AAAA,EACA;AAAA,OACK;AACP,SAAS,oBAAoB;AAiEzB,mBACE,KADF;AAvDJ,IAAM,gCAAgC;AAE/B,SAAS,yBACd,WACA,UAA2C,CAAC,GACxB;AACpB,QAAM,CAAC,WAAW,YAAY,IAAI,SAA6B,IAAI;AACnE,QAAM,SAAS,UAAU;AACzB,QAAM,gBAAgB,QAAQ,QAAQ;AAEtC,kBAAgB,MAAM;AACpB,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,UAAM,gBAAgB,OAAO;AAC7B,UAAM,OAAO,OAAO,YAAY;AAEhC,QAAI,OAAO,eAAe,eAAe,gBAAgB,YAAY;AACnE,YAAM,oBAAoB,MAAM;AAAA,QAC9B,KAAK;AAAA,UACH;AAAA,QACF;AAAA,MACF,EAAE;AAAA,QACA,CAAC,YACC,QAAQ,aAAa,yCAAyC,MAC9D;AAAA,MACJ;AAEA,UAAI,mBAAmB;AACrB,qBAAa,iBAAiB;AAC9B;AAAA,MACF;AAEA,YAAM,kBAAkB,cAAc,cAAc,KAAK;AACzD,sBAAgB;AAAA,QACd;AAAA,QACA;AAAA,MACF;AACA,WAAK,YAAY,eAAe;AAChC,mBAAa,eAAe;AAC5B;AAAA,IACF;AAEA,iBAAa,cAAc,IAAI;AAAA,EACjC,GAAG,CAAC,QAAQ,aAAa,CAAC;AAE1B,SAAO;AACT;AAEO,SAAS,aAAa,EAAE,UAAU,KAAK,GAAiC;AAC7E,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAiC,IAAI;AACjE,QAAM,YAAY,yBAAyB,EAAE,SAAS,OAAO,GAAG,EAAE,KAAK,CAAC;AAExE,SACE,iCACE;AAAA,wBAAC,UAAK,QAAM,MAAC,KAAK,WAAW,wCAAqC,IAAG;AAAA,IACpE,YAAY,aAAa,UAAU,SAAS,IAAI;AAAA,KACnD;AAEJ","sourcesContent":["'use client';\n\nimport {\n type ReactNode,\n type RefObject,\n useLayoutEffect,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\n\nexport interface UseRemotePortalContainerOptions {\n name?: string;\n}\n\nexport interface RemotePortalProps extends UseRemotePortalContainerOptions {\n children: ReactNode;\n}\n\nconst DEFAULT_PORTAL_CONTAINER_NAME = 'default';\n\nexport function useRemotePortalContainer(\n anchorRef: RefObject<Element | null>,\n options: UseRemotePortalContainerOptions = {},\n): HTMLElement | null {\n const [container, setContainer] = useState<HTMLElement | null>(null);\n const anchor = anchorRef.current;\n const containerName = options.name ?? DEFAULT_PORTAL_CONTAINER_NAME;\n\n useLayoutEffect(() => {\n if (!anchor) {\n return;\n }\n\n const ownerDocument = anchor.ownerDocument;\n const root = anchor.getRootNode();\n\n if (typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot) {\n const existingContainer = Array.from(\n root.querySelectorAll<HTMLElement>(\n '[data-remote-components-portal-container]',\n ),\n ).find(\n (element) =>\n element.getAttribute('data-remote-components-portal-container') ===\n containerName,\n );\n\n if (existingContainer) {\n setContainer(existingContainer);\n return;\n }\n\n const shadowContainer = ownerDocument.createElement('div');\n shadowContainer.setAttribute(\n 'data-remote-components-portal-container',\n containerName,\n );\n root.appendChild(shadowContainer);\n setContainer(shadowContainer);\n return;\n }\n\n setContainer(ownerDocument.body);\n }, [anchor, containerName]);\n\n return container;\n}\n\nexport function RemotePortal({ children, name }: RemotePortalProps): ReactNode {\n const [anchor, setAnchor] = useState<HTMLSpanElement | null>(null);\n const container = useRemotePortalContainer({ current: anchor }, { name });\n\n return (\n <>\n <span hidden ref={setAnchor} data-remote-components-portal-anchor=\"\" />\n {container ? createPortal(children, container) : null}\n </>\n );\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ReactNode, RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
interface UseRemotePortalContainerOptions {
|
|
4
|
+
name?: string;
|
|
5
|
+
}
|
|
6
|
+
interface RemotePortalProps extends UseRemotePortalContainerOptions {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
declare function useRemotePortalContainer(anchorRef: RefObject<Element | null>, options?: UseRemotePortalContainerOptions): HTMLElement | null;
|
|
10
|
+
declare function RemotePortal({ children, name }: RemotePortalProps): ReactNode;
|
|
11
|
+
|
|
12
|
+
export { RemotePortal, RemotePortalProps, UseRemotePortalContainerOptions, useRemotePortalContainer };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/remote/react/utils/portal.tsx
|
|
4
|
+
import {
|
|
5
|
+
useLayoutEffect,
|
|
6
|
+
useState
|
|
7
|
+
} from "react";
|
|
8
|
+
import { createPortal } from "react-dom";
|
|
9
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
var DEFAULT_PORTAL_CONTAINER_NAME = "default";
|
|
11
|
+
function useRemotePortalContainer(anchorRef, options = {}) {
|
|
12
|
+
const [container, setContainer] = useState(null);
|
|
13
|
+
const anchor = anchorRef.current;
|
|
14
|
+
const containerName = options.name ?? DEFAULT_PORTAL_CONTAINER_NAME;
|
|
15
|
+
useLayoutEffect(() => {
|
|
16
|
+
if (!anchor) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const ownerDocument = anchor.ownerDocument;
|
|
20
|
+
const root = anchor.getRootNode();
|
|
21
|
+
if (typeof ShadowRoot !== "undefined" && root instanceof ShadowRoot) {
|
|
22
|
+
const existingContainer = Array.from(
|
|
23
|
+
root.querySelectorAll(
|
|
24
|
+
"[data-remote-components-portal-container]"
|
|
25
|
+
)
|
|
26
|
+
).find(
|
|
27
|
+
(element) => element.getAttribute("data-remote-components-portal-container") === containerName
|
|
28
|
+
);
|
|
29
|
+
if (existingContainer) {
|
|
30
|
+
setContainer(existingContainer);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const shadowContainer = ownerDocument.createElement("div");
|
|
34
|
+
shadowContainer.setAttribute(
|
|
35
|
+
"data-remote-components-portal-container",
|
|
36
|
+
containerName
|
|
37
|
+
);
|
|
38
|
+
root.appendChild(shadowContainer);
|
|
39
|
+
setContainer(shadowContainer);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
setContainer(ownerDocument.body);
|
|
43
|
+
}, [anchor, containerName]);
|
|
44
|
+
return container;
|
|
45
|
+
}
|
|
46
|
+
function RemotePortal({ children, name }) {
|
|
47
|
+
const [anchor, setAnchor] = useState(null);
|
|
48
|
+
const container = useRemotePortalContainer({ current: anchor }, { name });
|
|
49
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
50
|
+
/* @__PURE__ */ jsx("span", { hidden: true, ref: setAnchor, "data-remote-components-portal-anchor": "" }),
|
|
51
|
+
container ? createPortal(children, container) : null
|
|
52
|
+
] });
|
|
53
|
+
}
|
|
54
|
+
export {
|
|
55
|
+
RemotePortal,
|
|
56
|
+
useRemotePortalContainer
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=portal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/remote/react/utils/portal.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ReactNode,\n type RefObject,\n useLayoutEffect,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\n\nexport interface UseRemotePortalContainerOptions {\n name?: string;\n}\n\nexport interface RemotePortalProps extends UseRemotePortalContainerOptions {\n children: ReactNode;\n}\n\nconst DEFAULT_PORTAL_CONTAINER_NAME = 'default';\n\nexport function useRemotePortalContainer(\n anchorRef: RefObject<Element | null>,\n options: UseRemotePortalContainerOptions = {},\n): HTMLElement | null {\n const [container, setContainer] = useState<HTMLElement | null>(null);\n const anchor = anchorRef.current;\n const containerName = options.name ?? DEFAULT_PORTAL_CONTAINER_NAME;\n\n useLayoutEffect(() => {\n if (!anchor) {\n return;\n }\n\n const ownerDocument = anchor.ownerDocument;\n const root = anchor.getRootNode();\n\n if (typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot) {\n const existingContainer = Array.from(\n root.querySelectorAll<HTMLElement>(\n '[data-remote-components-portal-container]',\n ),\n ).find(\n (element) =>\n element.getAttribute('data-remote-components-portal-container') ===\n containerName,\n );\n\n if (existingContainer) {\n setContainer(existingContainer);\n return;\n }\n\n const shadowContainer = ownerDocument.createElement('div');\n shadowContainer.setAttribute(\n 'data-remote-components-portal-container',\n containerName,\n );\n root.appendChild(shadowContainer);\n setContainer(shadowContainer);\n return;\n }\n\n setContainer(ownerDocument.body);\n }, [anchor, containerName]);\n\n return container;\n}\n\nexport function RemotePortal({ children, name }: RemotePortalProps): ReactNode {\n const [anchor, setAnchor] = useState<HTMLSpanElement | null>(null);\n const container = useRemotePortalContainer({ current: anchor }, { name });\n\n return (\n <>\n <span hidden ref={setAnchor} data-remote-components-portal-anchor=\"\" />\n {container ? createPortal(children, container) : null}\n </>\n );\n}\n"],"mappings":";;;AAEA;AAAA,EAGE;AAAA,EACA;AAAA,OACK;AACP,SAAS,oBAAoB;AAiEzB,mBACE,KADF;AAvDJ,IAAM,gCAAgC;AAE/B,SAAS,yBACd,WACA,UAA2C,CAAC,GACxB;AACpB,QAAM,CAAC,WAAW,YAAY,IAAI,SAA6B,IAAI;AACnE,QAAM,SAAS,UAAU;AACzB,QAAM,gBAAgB,QAAQ,QAAQ;AAEtC,kBAAgB,MAAM;AACpB,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,UAAM,gBAAgB,OAAO;AAC7B,UAAM,OAAO,OAAO,YAAY;AAEhC,QAAI,OAAO,eAAe,eAAe,gBAAgB,YAAY;AACnE,YAAM,oBAAoB,MAAM;AAAA,QAC9B,KAAK;AAAA,UACH;AAAA,QACF;AAAA,MACF,EAAE;AAAA,QACA,CAAC,YACC,QAAQ,aAAa,yCAAyC,MAC9D;AAAA,MACJ;AAEA,UAAI,mBAAmB;AACrB,qBAAa,iBAAiB;AAC9B;AAAA,MACF;AAEA,YAAM,kBAAkB,cAAc,cAAc,KAAK;AACzD,sBAAgB;AAAA,QACd;AAAA,QACA;AAAA,MACF;AACA,WAAK,YAAY,eAAe;AAChC,mBAAa,eAAe;AAC5B;AAAA,IACF;AAEA,iBAAa,cAAc,IAAI;AAAA,EACjC,GAAG,CAAC,QAAQ,aAAa,CAAC;AAE1B,SAAO;AACT;AAEO,SAAS,aAAa,EAAE,UAAU,KAAK,GAAiC;AAC7E,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAiC,IAAI;AACjE,QAAM,YAAY,yBAAyB,EAAE,SAAS,OAAO,GAAG,EAAE,KAAK,CAAC;AAExE,SACE,iCACE;AAAA,wBAAC,UAAK,QAAM,MAAC,KAAK,WAAW,wCAAqC,IAAG;AAAA,IACpE,YAAY,aAAa,UAAU,SAAS,IAAI;AAAA,KACnD;AAEJ;","names":[]}
|
|
@@ -1,15 +1,15 @@
|
|
|
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(); } }
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkOVD7BRLDcjs = require('./chunk-OVD7BRLD.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _chunkKP544TQHcjs = require('./chunk-KP544TQH.cjs');
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
var
|
|
12
|
+
var _chunkOZCVXVKUcjs = require('./chunk-OZCVXVKU.cjs');
|
|
13
13
|
require('./chunk-Z2SLBFQL.cjs');
|
|
14
14
|
require('./chunk-5KTAEO52.cjs');
|
|
15
15
|
require('./chunk-BBXVML3D.cjs');
|
|
@@ -19,15 +19,15 @@ require('./chunk-SHFJ5OQA.cjs');
|
|
|
19
19
|
// src/host/html/runtime/turbopack.ts
|
|
20
20
|
async function turbopackRuntime(url, bundle, shared, remoteShared, resolveClientUrl) {
|
|
21
21
|
const self = globalThis;
|
|
22
|
-
const hostShared =
|
|
22
|
+
const hostShared = _chunkOZCVXVKUcjs.buildHostShared.call(void 0, shared, resolveClientUrl, {
|
|
23
23
|
includePagesClientSharedGlobal: true
|
|
24
24
|
});
|
|
25
|
-
await
|
|
25
|
+
await _chunkOVD7BRLDcjs.setupRemoteScope.call(void 0, "turbopack", [], url, bundle, resolveClientUrl);
|
|
26
26
|
const {
|
|
27
27
|
default: { createFromReadableStream }
|
|
28
28
|
} = await Promise.resolve().then(() => _interopRequireWildcard(require("react-server-dom-webpack/client.browser")));
|
|
29
29
|
async function preloadScripts(scripts, __) {
|
|
30
|
-
const scope = await
|
|
30
|
+
const scope = await _chunkOVD7BRLDcjs.setupRemoteScope.call(void 0,
|
|
31
31
|
"turbopack",
|
|
32
32
|
scripts.map((script) => ({
|
|
33
33
|
src: script.getAttribute("src") || script.getAttribute("data-src") || script.src
|
|
@@ -36,21 +36,21 @@ async function turbopackRuntime(url, bundle, shared, remoteShared, resolveClient
|
|
|
36
36
|
bundle,
|
|
37
37
|
resolveClientUrl
|
|
38
38
|
);
|
|
39
|
-
await
|
|
39
|
+
await _chunkKP544TQHcjs.initializeSharedModules.call(void 0,
|
|
40
40
|
scope,
|
|
41
|
-
|
|
41
|
+
_chunkOZCVXVKUcjs.buildCoreShared.call(void 0, hostShared),
|
|
42
42
|
_nullishCoalesce(remoteShared, () => ( {}))
|
|
43
43
|
);
|
|
44
44
|
}
|
|
45
45
|
return {
|
|
46
46
|
self,
|
|
47
47
|
createFromReadableStream,
|
|
48
|
-
applySharedModules:
|
|
49
|
-
nextClientPagesLoader:
|
|
48
|
+
applySharedModules: _chunkKP544TQHcjs.applySharedModules,
|
|
49
|
+
nextClientPagesLoader: _chunkKP544TQHcjs.nextClientPagesLoader,
|
|
50
50
|
preloadScripts
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
exports.turbopackRuntime = turbopackRuntime;
|
|
56
|
-
//# sourceMappingURL=turbopack-
|
|
56
|
+
//# sourceMappingURL=turbopack-5WAY6QIC.cjs.map
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
setupRemoteScope
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CBEDRGC7.js";
|
|
4
4
|
import {
|
|
5
5
|
applySharedModules,
|
|
6
6
|
initializeSharedModules,
|
|
7
7
|
nextClientPagesLoader
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5BBEO4SE.js";
|
|
9
9
|
import {
|
|
10
10
|
buildCoreShared,
|
|
11
11
|
buildHostShared
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-3DR4Z24C.js";
|
|
13
13
|
import "./chunk-D5GNZB6O.js";
|
|
14
14
|
import "./chunk-STIJO4AG.js";
|
|
15
15
|
import "./chunk-ULXU6XWH.js";
|
|
@@ -53,4 +53,4 @@ async function turbopackRuntime(url, bundle, shared, remoteShared, resolveClient
|
|
|
53
53
|
export {
|
|
54
54
|
turbopackRuntime
|
|
55
55
|
};
|
|
56
|
-
//# sourceMappingURL=turbopack-
|
|
56
|
+
//# sourceMappingURL=turbopack-Z744H3T4.js.map
|
|
@@ -1,15 +1,15 @@
|
|
|
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; }
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkKMG54QXVcjs = require('./chunk-KMG54QXV.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _chunkKP544TQHcjs = require('./chunk-KP544TQH.cjs');
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
var
|
|
12
|
+
var _chunkOZCVXVKUcjs = require('./chunk-OZCVXVKU.cjs');
|
|
13
13
|
require('./chunk-Z2SLBFQL.cjs');
|
|
14
14
|
require('./chunk-5KTAEO52.cjs');
|
|
15
15
|
|
|
@@ -58,15 +58,15 @@ async function webpackRuntime(bundle, shared, remoteShared, resolveClientUrl) {
|
|
|
58
58
|
return [];
|
|
59
59
|
return [
|
|
60
60
|
{
|
|
61
|
-
src: new URL(scriptSrc.replace(
|
|
61
|
+
src: new URL(scriptSrc.replace(_chunkOZCVXVKUcjs.NEXT_BUNDLE_PATH_RE, "/_next/"), url).href
|
|
62
62
|
}
|
|
63
63
|
];
|
|
64
64
|
});
|
|
65
|
-
await
|
|
66
|
-
const hostShared =
|
|
65
|
+
await _chunkKMG54QXVcjs.loadScripts.call(void 0, scriptSrcs, resolveClientUrl);
|
|
66
|
+
const hostShared = _chunkOZCVXVKUcjs.buildHostShared.call(void 0, shared, resolveClientUrl, {
|
|
67
67
|
includePagesClientSharedGlobal: true
|
|
68
68
|
});
|
|
69
|
-
const resolve = await
|
|
69
|
+
const resolve = await _chunkKP544TQHcjs.buildWebpackResolve.call(void 0,
|
|
70
70
|
hostShared,
|
|
71
71
|
_nullishCoalesce(remoteShared, () => ( {})),
|
|
72
72
|
remoteBundle,
|
|
@@ -79,17 +79,17 @@ async function webpackRuntime(bundle, shared, remoteShared, resolveClientUrl) {
|
|
|
79
79
|
},
|
|
80
80
|
"WebpackRuntime"
|
|
81
81
|
);
|
|
82
|
-
|
|
82
|
+
_chunkKP544TQHcjs.applySharedModules.call(void 0, remoteBundle, resolve);
|
|
83
83
|
}
|
|
84
84
|
return {
|
|
85
85
|
self,
|
|
86
86
|
createFromReadableStream,
|
|
87
|
-
applySharedModules:
|
|
88
|
-
nextClientPagesLoader:
|
|
87
|
+
applySharedModules: _chunkKP544TQHcjs.applySharedModules,
|
|
88
|
+
nextClientPagesLoader: _chunkKP544TQHcjs.nextClientPagesLoader,
|
|
89
89
|
preloadScripts
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
|
|
94
94
|
exports.webpackRuntime = webpackRuntime;
|
|
95
|
-
//# sourceMappingURL=webpack-
|
|
95
|
+
//# sourceMappingURL=webpack-3GSL5AZJ.cjs.map
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadScripts
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IE7FXNFJ.js";
|
|
4
4
|
import {
|
|
5
5
|
applySharedModules,
|
|
6
6
|
buildWebpackResolve,
|
|
7
7
|
nextClientPagesLoader
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5BBEO4SE.js";
|
|
9
9
|
import {
|
|
10
10
|
NEXT_BUNDLE_PATH_RE,
|
|
11
11
|
buildHostShared
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-3DR4Z24C.js";
|
|
13
13
|
import "./chunk-D5GNZB6O.js";
|
|
14
14
|
import "./chunk-STIJO4AG.js";
|
|
15
15
|
import {
|
|
@@ -92,4 +92,4 @@ async function webpackRuntime(bundle, shared, remoteShared, resolveClientUrl) {
|
|
|
92
92
|
export {
|
|
93
93
|
webpackRuntime
|
|
94
94
|
};
|
|
95
|
-
//# sourceMappingURL=webpack-
|
|
95
|
+
//# sourceMappingURL=webpack-IQKPPBGH.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remote-components",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.13",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Compose remote components at runtime between microfrontends applications.",
|
|
6
6
|
"keywords": [
|
|
@@ -86,11 +86,21 @@
|
|
|
86
86
|
"require": "./dist/remote/html.cjs",
|
|
87
87
|
"default": "./dist/remote/html.js"
|
|
88
88
|
},
|
|
89
|
+
"./remote/react/utils/portal": {
|
|
90
|
+
"import": "./dist/remote/react/utils/portal.js",
|
|
91
|
+
"require": "./dist/remote/react/utils/portal.cjs",
|
|
92
|
+
"default": "./dist/remote/react/utils/portal.js"
|
|
93
|
+
},
|
|
89
94
|
"./config/nextjs": {
|
|
90
95
|
"import": "./dist/config/nextjs.js",
|
|
91
96
|
"require": "./dist/config/nextjs.cjs",
|
|
92
97
|
"default": "./dist/config/nextjs.js"
|
|
93
98
|
},
|
|
99
|
+
"./config/tailwind": {
|
|
100
|
+
"import": "./dist/config/tailwind.js",
|
|
101
|
+
"require": "./dist/config/tailwind.cjs",
|
|
102
|
+
"default": "./dist/config/tailwind.js"
|
|
103
|
+
},
|
|
94
104
|
"./config/webpack": {
|
|
95
105
|
"import": "./dist/config/webpack.js",
|
|
96
106
|
"require": "./dist/config/webpack.cjs",
|
|
@@ -159,9 +169,15 @@
|
|
|
159
169
|
"remote/html": [
|
|
160
170
|
"./dist/remote/html.d.ts"
|
|
161
171
|
],
|
|
172
|
+
"remote/react/utils/portal": [
|
|
173
|
+
"./dist/remote/react/utils/portal.d.ts"
|
|
174
|
+
],
|
|
162
175
|
"config/nextjs": [
|
|
163
176
|
"./dist/config/nextjs.d.ts"
|
|
164
177
|
],
|
|
178
|
+
"config/tailwind": [
|
|
179
|
+
"./dist/config/tailwind.d.ts"
|
|
180
|
+
],
|
|
165
181
|
"config/webpack": [
|
|
166
182
|
"./dist/config/webpack.d.ts"
|
|
167
183
|
],
|
|
@@ -210,6 +226,7 @@
|
|
|
210
226
|
"@types/react-dom": "^19.2.3",
|
|
211
227
|
"jsdom": "^26.0.0",
|
|
212
228
|
"next": "^16.1.3",
|
|
229
|
+
"postcss": "^8",
|
|
213
230
|
"react": "^19.2.3",
|
|
214
231
|
"react-dom": "^19.2.3",
|
|
215
232
|
"ts-json-schema-generator": "^1.1.2",
|