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.
Files changed (63) hide show
  1. package/dist/{chunk-3PR3SWYZ.js → chunk-3DR4Z24C.js} +24 -2
  2. package/dist/chunk-3DR4Z24C.js.map +1 -0
  3. package/dist/{chunk-BEGVH64U.js → chunk-5BBEO4SE.js} +2 -2
  4. package/dist/{chunk-24LEEDHP.js → chunk-CBEDRGC7.js} +3 -3
  5. package/dist/{chunk-CLO56ON2.js → chunk-CLB2ATH2.js} +82 -4
  6. package/dist/chunk-CLB2ATH2.js.map +1 -0
  7. package/dist/{chunk-M6ACTSVB.js → chunk-IE7FXNFJ.js} +2 -2
  8. package/dist/{chunk-XWRB6CEA.cjs → chunk-KMG54QXV.cjs} +3 -3
  9. package/dist/{chunk-SULMNRMJ.cjs → chunk-KP544TQH.cjs} +23 -23
  10. package/dist/{chunk-HXCW3WDT.cjs → chunk-OI37BBBU.cjs} +25 -25
  11. package/dist/{chunk-TGE3K3TR.cjs → chunk-OVD7BRLD.cjs} +18 -18
  12. package/dist/{chunk-6PZEDIAK.cjs → chunk-OZCVXVKU.cjs} +24 -2
  13. package/dist/chunk-OZCVXVKU.cjs.map +1 -0
  14. package/dist/{chunk-YSJ4FKGI.cjs → chunk-W7RJUCZQ.cjs} +97 -19
  15. package/dist/chunk-W7RJUCZQ.cjs.map +1 -0
  16. package/dist/{chunk-RZGFQTX6.js → chunk-XEO3XD67.js} +8 -8
  17. package/dist/config/nextjs.cjs +10 -10
  18. package/dist/config/nextjs.js +7 -7
  19. package/dist/config/tailwind.cjs +53 -0
  20. package/dist/config/tailwind.cjs.map +1 -0
  21. package/dist/config/tailwind.d.ts +21 -0
  22. package/dist/config/tailwind.js +53 -0
  23. package/dist/config/tailwind.js.map +1 -0
  24. package/dist/host/html.cjs +20 -20
  25. package/dist/host/html.js +8 -8
  26. package/dist/host/nextjs/app/client-only.cjs +12 -12
  27. package/dist/host/nextjs/app/client-only.js +7 -7
  28. package/dist/host/react.cjs +8 -8
  29. package/dist/host/react.js +7 -7
  30. package/dist/internal/host/nextjs/app-client.cjs +7 -3
  31. package/dist/internal/host/nextjs/app-client.cjs.map +1 -1
  32. package/dist/internal/host/nextjs/app-client.js +7 -3
  33. package/dist/internal/host/nextjs/app-client.js.map +1 -1
  34. package/dist/internal/host/shared/remote-image-loader.cjs +23 -1
  35. package/dist/internal/host/shared/remote-image-loader.cjs.map +1 -1
  36. package/dist/internal/host/shared/remote-image-loader.js +23 -1
  37. package/dist/internal/host/shared/remote-image-loader.js.map +1 -1
  38. package/dist/remote/react/utils/portal.cjs +58 -0
  39. package/dist/remote/react/utils/portal.cjs.map +1 -0
  40. package/dist/remote/react/utils/portal.d.ts +12 -0
  41. package/dist/remote/react/utils/portal.js +58 -0
  42. package/dist/remote/react/utils/portal.js.map +1 -0
  43. package/dist/{turbopack-5VGMYUL4.cjs → turbopack-5WAY6QIC.cjs} +11 -11
  44. package/dist/{turbopack-43N2UJNN.js → turbopack-Z744H3T4.js} +4 -4
  45. package/dist/{webpack-FSN5UBA2.cjs → webpack-3GSL5AZJ.cjs} +11 -11
  46. package/dist/{webpack-LXE2UWTA.js → webpack-IQKPPBGH.js} +4 -4
  47. package/package.json +18 -1
  48. package/dist/chunk-3PR3SWYZ.js.map +0 -1
  49. package/dist/chunk-6PZEDIAK.cjs.map +0 -1
  50. package/dist/chunk-CLO56ON2.js.map +0 -1
  51. package/dist/chunk-YSJ4FKGI.cjs.map +0 -1
  52. /package/dist/{chunk-BEGVH64U.js.map → chunk-5BBEO4SE.js.map} +0 -0
  53. /package/dist/{chunk-24LEEDHP.js.map → chunk-CBEDRGC7.js.map} +0 -0
  54. /package/dist/{chunk-M6ACTSVB.js.map → chunk-IE7FXNFJ.js.map} +0 -0
  55. /package/dist/{chunk-XWRB6CEA.cjs.map → chunk-KMG54QXV.cjs.map} +0 -0
  56. /package/dist/{chunk-SULMNRMJ.cjs.map → chunk-KP544TQH.cjs.map} +0 -0
  57. /package/dist/{chunk-HXCW3WDT.cjs.map → chunk-OI37BBBU.cjs.map} +0 -0
  58. /package/dist/{chunk-TGE3K3TR.cjs.map → chunk-OVD7BRLD.cjs.map} +0 -0
  59. /package/dist/{chunk-RZGFQTX6.js.map → chunk-XEO3XD67.js.map} +0 -0
  60. /package/dist/{turbopack-5VGMYUL4.cjs.map → turbopack-5WAY6QIC.cjs.map} +0 -0
  61. /package/dist/{turbopack-43N2UJNN.js.map → turbopack-Z744H3T4.js.map} +0 -0
  62. /package/dist/{webpack-FSN5UBA2.cjs.map → webpack-3GSL5AZJ.cjs.map} +0 -0
  63. /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":";AAkaI,SAiDU,UAjDV,KAyBM,YAzBN;AAhaJ;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,oBAAoB;AAC7B,SAAS,sCAAsC;AAC/C,SAAS,uBAAuB;AAChC,SAAS,2BAA2B;AACpC,SAAS,4BAA4B;AAGrC,SAAS,6BAA6B;AAEtC,SAAS,uBAAuB;AAChC,SAAS,eAAe,uBAAuB;AAC/C,SAAS,iCAAiC;AAE1C,SAAS,oBAAoB;AAC7B,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,4BAA4B;AAMrC,eAAe,kBACb,kBACgE;AAChE,QAAM,SAAS,MAAM,gBAAgB;AACrC,MAAI,0CAA0C,QAAQ;AACpD,UAAM,OAAO,qCAAqC;AAAA,EACpD;AACA,SAAO;AAAA,IACL,eAAe;AAAA,IACf,GAAG;AAAA,IACH,GAAG,+BAA+B,EAAE,OAAO,iBAAiB,CAAC;AAAA,EAC/D;AACF;AAiBO,SAAS,6BAA6B;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA,UAAU,CAAC;AAAA,EACX,QAAQ,CAAC;AAAA,EACT,eAAe,CAAC;AAAA,EAChB;AAAA,EACA,OAAO;AAAA,EACP,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AACF,GAAsC;AACpC,QAAM,oBAAoB,MAAM;AAChC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAkC,IAAI;AACxE,QAAM,MAAM,qBAAqB,KAAK,SAAS;AAC/C,QAAM,mBAAmB,oBAAoB,sBAAsB,IAAI,IAAI;AAC3E,QAAM,eAAe,OAAO,gBAAgB,CAAC;AAC7C,QAAM,cAAc,OAKjB;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK,IAAI;AAAA,EACX,CAAC;AACD,QAAM,WAAW,OAAmC,IAAI;AACxD,QAAM,SAAS,OAAmC,IAAI;AACtD,QAAM,gCAAgC,OAG5B,IAAI;AAGd,MAAI,qBAAqB,OAAO;AAC9B,UAAM;AAAA,EACR;AAGA,QAAM,qBACH,CAAC,aACC,aACC,CAAC,YACD,SAAS,sBACT,OAAQ,UAA0C,SAChD;AAAA;AAAA;AAAA,EAIN,UAAU,YAAY;AAGxB,QAAM,YAAY,GAAG,aAAa,MAAM,KAAK;AAAA,IAC3C,IAAI;AAAA,EACN,KAAK,aAAa,IAAI;AACtB,QAAM,UAAU,2BAA2B;AAE3C,QAAM,OAAO;AAKb,QAAM,gBAAgB,kCAAkC;AACxD,QAAM,qBAAqB;AAAA,IACzB,OAAO,aAAa,cAChB,OACA,SAAS;AAAA,MACP,yCAAyC;AAAA,IAC3C;AAAA,EACN;AACA,QAAM,gBAAgB;AAAA,IACpB,KAAK,aAAa,KAAK,mBAAmB,SAAS,cAAc;AAAA,EACnE;AACA,QAAM,0BAA0B,OAAqC,IAAI;AACzE,QAAM,oBAAoB,OAA+C,CAAC,CAAC;AAE3E,MAAI,KAAK,aAAa,KAAK,cAAc,SAAS;AAChD,SAAK,aAAa,IAAI;AAAA,EACxB;AAEA,kBAAgB,MAAM;AACpB,QACE,CAAC,mBAAmB,WACpB,mBAAmB,YAAY,cAAc,SAAS,MACtD;AACA,oBAAc,UAAU;AAAA,IAC1B;AAEA,QACE,YAAY,SACZ,OAAO,aAAa,eACpB,CAAC,cAAc,SACf;AACA,UAAI,oBAAuC;AAC3C,YAAM,UAAU,mBAAmB;AAEnC,0BAAoB,KAAK,aAAa,KAAK,SAAS,cAAc;AAClE,WAAK,aAAa,IAAI;AAEtB,UAAI,CAAC,qBAAqB,SAAS;AAGjC,YAAI;AACF,8BAAoB,QAAQ,aAAa,EAAE,KAAK,CAAC;AAAA,QACnD,QAAE;AAAA,QAEF;AAAA,MACF;AAEA,UAAI,mBAAmB;AACrB,sBAAc,UAAU;AAAA,MAC1B;AAAA,IACF;AAKA,QACE,CAAC,wBAAwB,WACzB,cAAc,WACd,mBACA;AACA,8BAAwB,UACtB,cAAc,QAAQ,iBAAiB,GAAG;AAAA,IAC9C;AAEA,QACE,cAAc,WACd,wBAAwB,WACxB,CAAC,mBACD;AAEA,8BAAwB,QAAQ,QAAQ,CAAC,SAAS;AAChD,YAAI,KAAK,aAAa,UAAU,KAAK,aAAa,SAAS;AACzD,eAAK,YAAY,YAAY,IAAI;AAAA,QACnC,OAAO;AACL,4BAAkB,QAAQ;AAAA,YACxB;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AACD,8BAAwB,UAAU;AAAA,IACpC;AAEA,QAAI,kBAAkB,QAAQ,SAAS,KAAK,cAAc,SAAS;AACjE,YAAM,cACJ,cAAc,QAAQ,iBAAiB,iBAAiB;AAC1D,UAAI,YAAY,SAAS,GAAG;AAC1B,gBAAQ;AAAA,UACN,MAAM,KAAK,WAAW,EAAE;AAAA,YACtB,CAAC,SACC,IAAI,QAAc,CAAC,YAAY;AAC7B,mBAAK,iBAAiB,QAAQ,MAAM,QAAQ,CAAC;AAC7C,mBAAK,iBAAiB,SAAS,MAAM,QAAQ,CAAC;AAAA,YAChD,CAAC;AAAA,UACL;AAAA,QACF,EACG,KAAK,MAAM;AACV,sBAAY,QAAQ,CAAC,OAAO;AAC1B,eAAG,gBAAgB,WAAW;AAAA,UAChC,CAAC;AAGD,4BAAkB,QAAQ,QAAQ,CAAC,OAAO;AACxC,eAAG,YAAY,YAAY,EAAE;AAAA,UAC/B,CAAC;AACD,4BAAkB,UAAU,CAAC;AAAA,QAC/B,CAAC,EACA,MAAM,CAAC,MAAM;AACZ,mBAAS,iBAAiB,qBAAqB,CAAC;AAAA,QAClD,CAAC;AAAA,MACL;AAAA,IACF;AAAA,EACF,GAAG,CAAC,SAAS,MAAM,MAAM,eAAe,iBAAiB,CAAC;AAE1D,YAAU,MAAM;AAEd,QAAI,8BAA8B,WAAW,cAAc,UAAU;AACnE,YAAM,EAAE,SAAS,KAAK,IAAI,8BAA8B;AACxD,oCAA8B,UAAU;AACxC,cAAQ;AAAA,QACN,MAAM,KAAK,OAAO,EAAE,IAAI,OAAO,cAAc;AAC3C,cAAI;AACF,kBAAM,UAAU,IAAI;AAAA,UACtB,SAAS,GAAP;AACA,qBAAS,iBAAiB,qBAAqB,CAAC;AAAA,UAClD;AAAA,QACF,CAAC;AAAA,MACH,EAAE,MAAM,CAAC,MAAM;AACb,iBAAS,iBAAiB,6BAA6B,CAAC;AAAA,MAC1D,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,WAAW,QAAQ,CAAC;AAExB,YAAU,MAAM;AACd,oBAAgB,YAAY;AAC1B,UAAI;AAEF,YACG,aAAa,QAAQ,UAAU,aAC9B,CAAC,cACA,YAAY,SAAS,cAAc,YACtC,YAAY,QAAQ,QAAQ,IAAI,QAChC,YAAY,QAAQ,SAAS,QAC7B,YAAY,QAAQ,WAAW,UAC/B,YAAY,QAAQ,UAAU,OAC9B;AAEA,uBAAa,QAAQ,iBAAiB,MAAM;AAC5C,gBAAM,aAAa,IAAI,gBAAgB;AACvC,uBAAa,QAAQ,kBAAkB;AAEvC,uBAAa,QAAQ,QAAQ;AAC7B,sBAAY,UAAU;AAAA,YACpB;AAAA,YACA;AAAA,YACA;AAAA,YACA,KAAK,IAAI;AAAA,UACX;AAGA,cAAI,SAAS,oBAAoB;AAC/B,yBAAa,QAAQ;AAGrB;AAAA,cACE;AAAA,cACA;AAAA,cACA;AAAA,YACF,EACG,KAAK,CAAC,EAAE,OAAO,QAAQ,MAAM;AAC5B,kBAAI,MAAM,OAAO,GAAG;AAClB,oBAAI,OACF,cAAc;AAChB,oBAAI;AACF,sBAAI,CAAC,QAAQ,SAAS,WAAW,OAAO,SAAS;AAC/C,2BAAO,SAAS;AAAA,sBACd,IAAI,SAAS,QAAQ,eAAe,OAAO,QAAQ,cAAc,OAAO,QAAQ;AAAA,oBAClF;AAAA,kBACF;AAAA,gBACF,SAAS,GAAP;AACA,2BAAS,iBAAiB,+BAA+B,CAAC;AAAA,gBAC5D;AACA,oBAAI,QAAQ,OAAO,GAAG;AACpB,gDAA8B,UAAU,EAAE,SAAS,KAAK;AAAA,gBAC1D;AACA,uBAAO,QAAQ;AAAA,kBACb,MAAM,KAAK,KAAK,EAAE,IAAI,CAAC,YAAY,QAAQ,IAAI,CAAC;AAAA,gBAClD;AAAA,cACF;AAAA,YACF,CAAC,EACA,MAAM,CAAC,MAAM;AACZ;AAAA,gBACE;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AACA,2BAAa,CAAU;AAAA,YACzB,CAAC;AACH;AAAA,UACF;AAEA,gBAAM,SAAS,MAAM,sBAAsB;AAAA,YACzC;AAAA,YACA;AAAA,YACA,QAAQ,WAAW;AAAA,YACnB,SAAS;AAAA,cACP;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,YACA,QAAQ,kBAAkB,gBAAgB;AAAA,YAC1C;AAAA,YACA,WAAW,cAAc;AAAA,YACzB;AAAA,YACA;AAAA,UACF,CAAC;AAED,cAAI,OAAO,WAAW,WAAW;AAC/B;AAAA,UACF;AACA,cAAI,OAAO,WAAW,SAAS;AAC7B,yBAAa,QAAQ,QAAQ;AAC7B,yBAAa,OAAO,KAAK;AAAA,UAC3B,OAAO;AACL,yBAAa,QAAQ,QAAQ;AAC7B,yBAAa,OAAO,SAAS;AAAA,UAC/B;AAAA,QACF;AAAA,MACF,SAAS,OAAP;AACA,qBAAa,QAAQ,QAAQ;AAC7B,qBAAa,KAAc;AAAA,MAC7B;AAAA,IACF,CAAC;AAED,WAAO,MAAM;AACX,mBAAa,QAAQ,iBAAiB,MAAM;AAAA,IAC9C;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,MACE,UAAU,YAAY,iBACtB,cAAc,WACd,YAAY,SACZ,SACA,CAAC,cAAc,QAAQ,cAAc,gCAAgC,GACrE;AAEA,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,aAAa,gCAAgC,EAAE;AACrD,UAAM,cAAc;AACpB,kBAAc,QAAQ,aAAa,OAAO,cAAc,QAAQ,UAAU;AAAA,EAC5E,WACE,cAAc,WACd,YAAY,SACZ,CAAC,SACD,cAAc,QAAQ,cAAc,gCAAgC,GACpE;AAEA,UAAM,QAAQ,cAAc,QAAQ;AAAA,MAClC;AAAA,IACF;AACA,QAAI,SAAS,cAAc,QAAQ,eAAe,OAAO;AACvD,oBAAc,QAAQ,YAAY,KAAK;AAAA,IACzC;AAAA,EACF;AAEA,QAAM,gBACJ;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe,UAAU,YAAY;AAAA;AAAA,EACvC;AAGF,MAAI,oBAAoB,oBACpB,WACC;AAEL,MAAI,YAAY,OAAO;AACrB,wBACE;AAAA,MAAC;AAAA;AAAA,QACC,4BAA0B,cAAc;AAAA,QACxC,wCAAqC;AAAA,QACrC,IAAI,cAAc;AAAA,QAClB,KAAK;AAAA,QAEJ;AAAA,iBAAO,aAAa;AAAA;AAAA,YAEnB,qBAAC,cAAS,gBAAgB,MACvB;AAAA,uBAAS,WACR;AAAA,gBAAC;AAAA;AAAA,kBACC,yBAAyB;AAAA,oBACvB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,qBAKL;AAAA;AAAA;AAAA;AAAA,kBAIL;AAAA;AAAA,cACF,IACE;AAAA,cACH;AAAA,cACA,oBAAoB,WAAW;AAAA,eAClC;AAAA,cACE;AAAA,UACH,OAAO,aAAa,eACrB,cAAc,WACd,CAAC,oBACG;AAAA,YACE,iCACG;AAAA;AAAA,cACA;AAAA,eACH;AAAA,YACA,cAAc;AAAA,UAChB,IACA;AAAA;AAAA;AAAA,IACN;AAAA,EAEJ;AAEA,SACE,iCACG;AAAA,gBAAY,QACX,oBAAC,cAAS,IAAI,GAAG,cAAc,KAAK,UAAU,IAC5C;AAAA,IACJ,oBAAC,YAAO,yBAAqB,MAAC,MAAK,oBAChC,eAAK,UAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC,GACH;AAAA,IACC,YAAY,QAAQ,gBAAgB;AAAA,IACpC;AAAA,IACA,WACC;AAAA,MAAC;AAAA;AAAA,QACC,IAAI,GAAG,UAAU,MAAM;AAAA,UACrB;AAAA,UACA;AAAA,QACF,IAAI;AAAA,QACJ,MAAK;AAAA,QAEJ,eAAK,UAAU,QAAQ;AAAA;AAAA,IAC1B,IACE;AAAA,IACH,YAAY,QAAQ,oBAAC,cAAS,IAAI,GAAG,YAAY,KAAK,QAAQ,IAAK;AAAA,KACtE;AAEJ;","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 url = `${basePath}?url=${encodeURIComponent(src)}&w=${width}&q=${q}`;
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;AAmBlB,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,MAAM,GAAG,gBAAgB,mBAAmB,GAAG,OAAO,WAAW;AACvE,aAAO,mBAAmB,GAAG,KAAK;AAAA,IACpC;AAAA;AAAA;AAAA,IAGA,EAAE,oBAAoB,KAAc;AAAA,EACtC;AACA,SAAO;AACT;","names":[]}
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 url = `${basePath}?url=${encodeURIComponent(src)}&w=${width}&q=${q}`;
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;AAmBlB,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,MAAM,GAAG,gBAAgB,mBAAmB,GAAG,OAAO,WAAW;AACvE,aAAO,mBAAmB,GAAG,KAAK;AAAA,IACpC;AAAA;AAAA;AAAA,IAGA,EAAE,oBAAoB,KAAc;AAAA,EACtC;AACA,SAAO;AACT;","names":[]}
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 _chunkTGE3K3TRcjs = require('./chunk-TGE3K3TR.cjs');
3
+ var _chunkOVD7BRLDcjs = require('./chunk-OVD7BRLD.cjs');
4
4
 
5
5
 
6
6
 
7
7
 
8
- var _chunkSULMNRMJcjs = require('./chunk-SULMNRMJ.cjs');
8
+ var _chunkKP544TQHcjs = require('./chunk-KP544TQH.cjs');
9
9
 
10
10
 
11
11
 
12
- var _chunk6PZEDIAKcjs = require('./chunk-6PZEDIAK.cjs');
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 = _chunk6PZEDIAKcjs.buildHostShared.call(void 0, shared, resolveClientUrl, {
22
+ const hostShared = _chunkOZCVXVKUcjs.buildHostShared.call(void 0, shared, resolveClientUrl, {
23
23
  includePagesClientSharedGlobal: true
24
24
  });
25
- await _chunkTGE3K3TRcjs.setupRemoteScope.call(void 0, "turbopack", [], url, bundle, resolveClientUrl);
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 _chunkTGE3K3TRcjs.setupRemoteScope.call(void 0,
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 _chunkSULMNRMJcjs.initializeSharedModules.call(void 0,
39
+ await _chunkKP544TQHcjs.initializeSharedModules.call(void 0,
40
40
  scope,
41
- _chunk6PZEDIAKcjs.buildCoreShared.call(void 0, hostShared),
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: _chunkSULMNRMJcjs.applySharedModules,
49
- nextClientPagesLoader: _chunkSULMNRMJcjs.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-5VGMYUL4.cjs.map
56
+ //# sourceMappingURL=turbopack-5WAY6QIC.cjs.map
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  setupRemoteScope
3
- } from "./chunk-24LEEDHP.js";
3
+ } from "./chunk-CBEDRGC7.js";
4
4
  import {
5
5
  applySharedModules,
6
6
  initializeSharedModules,
7
7
  nextClientPagesLoader
8
- } from "./chunk-BEGVH64U.js";
8
+ } from "./chunk-5BBEO4SE.js";
9
9
  import {
10
10
  buildCoreShared,
11
11
  buildHostShared
12
- } from "./chunk-3PR3SWYZ.js";
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-43N2UJNN.js.map
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 _chunkXWRB6CEAcjs = require('./chunk-XWRB6CEA.cjs');
3
+ var _chunkKMG54QXVcjs = require('./chunk-KMG54QXV.cjs');
4
4
 
5
5
 
6
6
 
7
7
 
8
- var _chunkSULMNRMJcjs = require('./chunk-SULMNRMJ.cjs');
8
+ var _chunkKP544TQHcjs = require('./chunk-KP544TQH.cjs');
9
9
 
10
10
 
11
11
 
12
- var _chunk6PZEDIAKcjs = require('./chunk-6PZEDIAK.cjs');
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(_chunk6PZEDIAKcjs.NEXT_BUNDLE_PATH_RE, "/_next/"), url).href
61
+ src: new URL(scriptSrc.replace(_chunkOZCVXVKUcjs.NEXT_BUNDLE_PATH_RE, "/_next/"), url).href
62
62
  }
63
63
  ];
64
64
  });
65
- await _chunkXWRB6CEAcjs.loadScripts.call(void 0, scriptSrcs, resolveClientUrl);
66
- const hostShared = _chunk6PZEDIAKcjs.buildHostShared.call(void 0, shared, resolveClientUrl, {
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 _chunkSULMNRMJcjs.buildWebpackResolve.call(void 0,
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
- _chunkSULMNRMJcjs.applySharedModules.call(void 0, remoteBundle, resolve);
82
+ _chunkKP544TQHcjs.applySharedModules.call(void 0, remoteBundle, resolve);
83
83
  }
84
84
  return {
85
85
  self,
86
86
  createFromReadableStream,
87
- applySharedModules: _chunkSULMNRMJcjs.applySharedModules,
88
- nextClientPagesLoader: _chunkSULMNRMJcjs.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-FSN5UBA2.cjs.map
95
+ //# sourceMappingURL=webpack-3GSL5AZJ.cjs.map
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  loadScripts
3
- } from "./chunk-M6ACTSVB.js";
3
+ } from "./chunk-IE7FXNFJ.js";
4
4
  import {
5
5
  applySharedModules,
6
6
  buildWebpackResolve,
7
7
  nextClientPagesLoader
8
- } from "./chunk-BEGVH64U.js";
8
+ } from "./chunk-5BBEO4SE.js";
9
9
  import {
10
10
  NEXT_BUNDLE_PATH_RE,
11
11
  buildHostShared
12
- } from "./chunk-3PR3SWYZ.js";
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-LXE2UWTA.js.map
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.12",
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",