remote-components 0.4.12 → 0.4.14
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-CLO56ON2.js → chunk-EIEIT5PG.js} +82 -4
- package/dist/chunk-EIEIT5PG.js.map +1 -0
- package/dist/{chunk-BEGVH64U.js → chunk-GG32LZD3.js} +2 -2
- package/dist/{chunk-SULMNRMJ.cjs → chunk-JKDPK6L5.cjs} +23 -23
- package/dist/{chunk-XWRB6CEA.cjs → chunk-MAVMKFFL.cjs} +3 -3
- package/dist/{chunk-RZGFQTX6.js → chunk-PNKSHWZ3.js} +8 -8
- package/dist/{chunk-HXCW3WDT.cjs → chunk-T2JJIQUJ.cjs} +25 -25
- package/dist/{chunk-TGE3K3TR.cjs → chunk-TIS6PXSQ.cjs} +18 -18
- package/dist/{chunk-YSJ4FKGI.cjs → chunk-WCZKEWRM.cjs} +97 -19
- package/dist/chunk-WCZKEWRM.cjs.map +1 -0
- package/dist/{chunk-3PR3SWYZ.js → chunk-WWHNG5YP.js} +38 -3
- package/dist/chunk-WWHNG5YP.js.map +1 -0
- package/dist/{chunk-M6ACTSVB.js → chunk-XLGLCKZZ.js} +2 -2
- package/dist/{chunk-24LEEDHP.js → chunk-YKCU7RFM.js} +3 -3
- package/dist/{chunk-6PZEDIAK.cjs → chunk-ZPJ5J24T.cjs} +47 -12
- package/dist/chunk-ZPJ5J24T.cjs.map +1 -0
- 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 +21 -12
- package/dist/host/nextjs/app/client-only.cjs.map +1 -1
- package/dist/host/nextjs/app/client-only.js +18 -9
- package/dist/host/nextjs/app/client-only.js.map +1 -1
- package/dist/host/nextjs/app.cjs +2 -0
- package/dist/host/nextjs/app.cjs.map +1 -1
- package/dist/host/nextjs/app.js +2 -0
- package/dist/host/nextjs/app.js.map +1 -1
- package/dist/host/nextjs/pages.cjs +14 -7
- package/dist/host/nextjs/pages.cjs.map +1 -1
- package/dist/host/nextjs/pages.d.ts +2 -0
- package/dist/host/nextjs/pages.js +14 -7
- package/dist/host/nextjs/pages.js.map +1 -1
- package/dist/host/react.cjs +8 -8
- package/dist/host/react.js +7 -7
- package/dist/internal/host/nextjs/app-client.cjs +15 -6
- package/dist/internal/host/nextjs/app-client.cjs.map +1 -1
- package/dist/internal/host/nextjs/app-client.d.ts +3 -2
- package/dist/internal/host/nextjs/app-client.js +15 -6
- package/dist/internal/host/nextjs/app-client.js.map +1 -1
- package/dist/internal/host/nextjs/dom-flight.cjs +1 -0
- package/dist/internal/host/nextjs/dom-flight.cjs.map +1 -1
- package/dist/internal/host/nextjs/dom-flight.d.ts +1 -0
- package/dist/internal/host/nextjs/dom-flight.js +1 -0
- package/dist/internal/host/nextjs/dom-flight.js.map +1 -1
- package/dist/internal/host/nextjs/image-shared.cjs +11 -2
- package/dist/internal/host/nextjs/image-shared.cjs.map +1 -1
- package/dist/internal/host/nextjs/image-shared.d.ts +3 -1
- package/dist/internal/host/nextjs/image-shared.js +11 -2
- package/dist/internal/host/nextjs/image-shared.js.map +1 -1
- package/dist/internal/host/server/fetch-remote-component.cjs +58 -3
- package/dist/internal/host/server/fetch-remote-component.cjs.map +1 -1
- package/dist/internal/host/server/fetch-remote-component.d.ts +1 -0
- package/dist/internal/host/server/fetch-remote-component.js +61 -3
- package/dist/internal/host/server/fetch-remote-component.js.map +1 -1
- package/dist/internal/host/server/types.cjs.map +1 -1
- package/dist/internal/host/server/types.d.ts +2 -0
- package/dist/internal/host/shared/next-image-deployment-id.cjs +50 -0
- package/dist/internal/host/shared/next-image-deployment-id.cjs.map +1 -0
- package/dist/internal/host/shared/next-image-deployment-id.d.ts +14 -0
- package/dist/internal/host/shared/next-image-deployment-id.js +25 -0
- package/dist/internal/host/shared/next-image-deployment-id.js.map +1 -0
- package/dist/internal/host/shared/pipeline.d.ts +2 -1
- package/dist/internal/host/shared/remote-image-loader.cjs +16 -2
- package/dist/internal/host/shared/remote-image-loader.cjs.map +1 -1
- package/dist/internal/host/shared/remote-image-loader.d.ts +2 -1
- package/dist/internal/host/shared/remote-image-loader.js +19 -2
- package/dist/internal/host/shared/remote-image-loader.js.map +1 -1
- package/dist/internal/runtime/html/parse-remote-html.d.ts +1 -0
- package/dist/internal/runtime/loaders/component-loader.d.ts +2 -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/{server-handoff-9e905049.d.ts → server-handoff-006f9cb5.d.ts} +2 -0
- package/dist/{turbopack-43N2UJNN.js → turbopack-HK7DVYUG.js} +4 -4
- package/dist/{turbopack-5VGMYUL4.cjs → turbopack-YZOIO55D.cjs} +11 -11
- package/dist/{webpack-LXE2UWTA.js → webpack-2HP73JL7.js} +4 -4
- package/dist/{webpack-FSN5UBA2.cjs → webpack-W2MODB73.cjs} +11 -11
- 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-GG32LZD3.js.map} +0 -0
- /package/dist/{chunk-SULMNRMJ.cjs.map → chunk-JKDPK6L5.cjs.map} +0 -0
- /package/dist/{chunk-XWRB6CEA.cjs.map → chunk-MAVMKFFL.cjs.map} +0 -0
- /package/dist/{chunk-RZGFQTX6.js.map → chunk-PNKSHWZ3.js.map} +0 -0
- /package/dist/{chunk-HXCW3WDT.cjs.map → chunk-T2JJIQUJ.cjs.map} +0 -0
- /package/dist/{chunk-TGE3K3TR.cjs.map → chunk-TIS6PXSQ.cjs.map} +0 -0
- /package/dist/{chunk-M6ACTSVB.js.map → chunk-XLGLCKZZ.js.map} +0 -0
- /package/dist/{chunk-24LEEDHP.js.map → chunk-YKCU7RFM.js.map} +0 -0
- /package/dist/{turbopack-43N2UJNN.js.map → turbopack-HK7DVYUG.js.map} +0 -0
- /package/dist/{turbopack-5VGMYUL4.cjs.map → turbopack-YZOIO55D.cjs.map} +0 -0
- /package/dist/{webpack-LXE2UWTA.js.map → webpack-2HP73JL7.js.map} +0 -0
- /package/dist/{webpack-FSN5UBA2.cjs.map → webpack-W2MODB73.cjs.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/host/nextjs/image-shared.ts"],"sourcesContent":["import { createElement, forwardRef } from 'react';\nimport { createRemoteImageLoader } from '#internal/host/shared/remote-image-loader';\nimport { getScope } from '#internal/runtime/turbopack/remote-scope';\nimport { bindResolveClientUrl } from '#internal/runtime/url/default-resolve-client-url';\nimport type {\n InternalResolveClientUrl,\n ResolveClientUrl,\n} from '#internal/runtime/url/resolve-client-url';\n\ntype SharedImageModule = (bundle: string) => Promise<unknown>;\n\nfunction resolveForBundle(\n unbound: ResolveClientUrl | undefined,\n bundle: string,\n): InternalResolveClientUrl | undefined {\n if (!unbound) return undefined;\n const remoteSrc = getScope(bundle)?.url.href ?? '';\n return bindResolveClientUrl(unbound, remoteSrc);\n}\n\n/**\n * Creates shared module entries for image-related modules that route\n * optimization requests through the remote's `/_next/image` endpoint.\n *\n * Pass `bound` when the resolver already has `remoteSrc` applied (App Router).\n * Pass `unbound` when only the raw 2-arg `ResolveClientUrl` is available\n * (Pages Router, client-only provider).\n */\nexport function createImageLoaderSharedEntries({\n bound,\n unbound,\n}: {\n bound?: InternalResolveClientUrl;\n unbound?: ResolveClientUrl;\n} = {}): Record<string, SharedImageModule> {\n const loaderEntry: SharedImageModule = (bundle: string) => {\n const resolveClientUrl = bound ?? resolveForBundle(unbound, bundle);\n return Promise.resolve({\n default: createRemoteImageLoader(bundle
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/nextjs/image-shared.ts"],"sourcesContent":["import { createElement, forwardRef } from 'react';\nimport type { NextImageDeploymentId } from '#internal/host/shared/next-image-deployment-id';\nimport { createRemoteImageLoader } from '#internal/host/shared/remote-image-loader';\nimport { getScope } from '#internal/runtime/turbopack/remote-scope';\nimport { bindResolveClientUrl } from '#internal/runtime/url/default-resolve-client-url';\nimport type {\n InternalResolveClientUrl,\n ResolveClientUrl,\n} from '#internal/runtime/url/resolve-client-url';\n\ntype SharedImageModule = (bundle: string) => Promise<unknown>;\n\nfunction resolveForBundle(\n unbound: ResolveClientUrl | undefined,\n bundle: string,\n): InternalResolveClientUrl | undefined {\n if (!unbound) return undefined;\n const remoteSrc = getScope(bundle)?.url.href ?? '';\n return bindResolveClientUrl(unbound, remoteSrc);\n}\n\n/**\n * Creates shared module entries for image-related modules that route\n * optimization requests through the remote's `/_next/image` endpoint.\n *\n * Pass `bound` when the resolver already has `remoteSrc` applied (App Router).\n * Pass `unbound` when only the raw 2-arg `ResolveClientUrl` is available\n * (Pages Router, client-only provider).\n */\nexport function createImageLoaderSharedEntries({\n bound,\n ssrImageDeploymentIds,\n unbound,\n}: {\n bound?: InternalResolveClientUrl;\n ssrImageDeploymentIds?: readonly NextImageDeploymentId[];\n unbound?: ResolveClientUrl;\n} = {}): Record<string, SharedImageModule> {\n const loaderEntry: SharedImageModule = (bundle: string) => {\n const resolveClientUrl = bound ?? resolveForBundle(unbound, bundle);\n return Promise.resolve({\n default: createRemoteImageLoader(\n bundle,\n resolveClientUrl,\n ssrImageDeploymentIds,\n ),\n __esModule: true,\n });\n };\n\n // Cross-version compat: remotes <=0.2.x request `next/image` as a shared module.\n // Wraps the host's Image component with the remote image loader injected\n // via the `loader` prop. Can be removed once 0.2.x support is dropped.\n const imageEntry: SharedImageModule = async (bundle: string) => {\n const resolveClientUrl = bound ?? resolveForBundle(unbound, bundle);\n const rawLoader = createRemoteImageLoader(\n bundle,\n resolveClientUrl,\n ssrImageDeploymentIds,\n );\n // Wrap to match Next.js `ImageLoader` signature (no `config` param).\n // The raw loader expects `{ config, src, width, quality }` but the public\n // `loader` prop is called with `{ src, width, quality }` only.\n const remoteLoader = Object.assign(\n (p: { src: string; width: number; quality?: number }) =>\n rawLoader({ ...p, config: { path: '/_next/image' } }),\n { __next_img_default: true as const },\n );\n const mod = await import('next/image');\n const OriginalImage = mod.default;\n type ImageProps = Parameters<typeof OriginalImage>[0];\n const RemoteImage = forwardRef<HTMLImageElement, ImageProps>((props, ref) =>\n createElement(OriginalImage, {\n ...props,\n loader: props.loader ?? remoteLoader,\n ref,\n }),\n );\n RemoteImage.displayName = 'RemoteImage';\n return { ...mod, default: RemoteImage, __esModule: true };\n };\n\n return {\n 'next/dist/shared/lib/image-loader': loaderEntry,\n 'next/dist/esm/shared/lib/image-loader': loaderEntry,\n // Can be removed once 0.2.x support is dropped.\n 'next/image': imageEntry,\n // Can be removed once 0.2.x support is dropped.\n 'next/dist/client/image-component': imageEntry,\n // Can be removed once 0.2.x support is dropped.\n 'next/dist/api/image': imageEntry,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0C;AAE1C,iCAAwC;AACxC,0BAAyB;AACzB,wCAAqC;AAQrC,SAAS,iBACP,SACA,QACsC;AACtC,MAAI,CAAC;AAAS,WAAO;AACrB,QAAM,gBAAY,8BAAS,MAAM,GAAG,IAAI,QAAQ;AAChD,aAAO,wDAAqB,SAAS,SAAS;AAChD;AAUO,SAAS,+BAA+B;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AACF,IAII,CAAC,GAAsC;AACzC,QAAM,cAAiC,CAAC,WAAmB;AACzD,UAAM,mBAAmB,SAAS,iBAAiB,SAAS,MAAM;AAClE,WAAO,QAAQ,QAAQ;AAAA,MACrB,aAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,YAAY;AAAA,IACd,CAAC;AAAA,EACH;AAKA,QAAM,aAAgC,OAAO,WAAmB;AAC9D,UAAM,mBAAmB,SAAS,iBAAiB,SAAS,MAAM;AAClE,UAAM,gBAAY;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAIA,UAAM,eAAe,OAAO;AAAA,MAC1B,CAAC,MACC,UAAU,EAAE,GAAG,GAAG,QAAQ,EAAE,MAAM,eAAe,EAAE,CAAC;AAAA,MACtD,EAAE,oBAAoB,KAAc;AAAA,IACtC;AACA,UAAM,MAAM,MAAM,OAAO,YAAY;AACrC,UAAM,gBAAgB,IAAI;AAE1B,UAAM,kBAAc;AAAA,MAAyC,CAAC,OAAO,YACnE,4BAAc,eAAe;AAAA,QAC3B,GAAG;AAAA,QACH,QAAQ,MAAM,UAAU;AAAA,QACxB;AAAA,MACF,CAAC;AAAA,IACH;AACA,gBAAY,cAAc;AAC1B,WAAO,EAAE,GAAG,KAAK,SAAS,aAAa,YAAY,KAAK;AAAA,EAC1D;AAEA,SAAO;AAAA,IACL,qCAAqC;AAAA,IACrC,yCAAyC;AAAA;AAAA,IAEzC,cAAc;AAAA;AAAA,IAEd,oCAAoC;AAAA;AAAA,IAEpC,uBAAuB;AAAA,EACzB;AACF;","names":[]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NextImageDeploymentId } from '../shared/next-image-deployment-id.js';
|
|
1
2
|
import { InternalResolveClientUrl, ResolveClientUrl } from '../../runtime/url/resolve-client-url.js';
|
|
2
3
|
|
|
3
4
|
type SharedImageModule = (bundle: string) => Promise<unknown>;
|
|
@@ -9,8 +10,9 @@ type SharedImageModule = (bundle: string) => Promise<unknown>;
|
|
|
9
10
|
* Pass `unbound` when only the raw 2-arg `ResolveClientUrl` is available
|
|
10
11
|
* (Pages Router, client-only provider).
|
|
11
12
|
*/
|
|
12
|
-
declare function createImageLoaderSharedEntries({ bound, unbound, }?: {
|
|
13
|
+
declare function createImageLoaderSharedEntries({ bound, ssrImageDeploymentIds, unbound, }?: {
|
|
13
14
|
bound?: InternalResolveClientUrl;
|
|
15
|
+
ssrImageDeploymentIds?: readonly NextImageDeploymentId[];
|
|
14
16
|
unbound?: ResolveClientUrl;
|
|
15
17
|
}): Record<string, SharedImageModule>;
|
|
16
18
|
|
|
@@ -10,18 +10,27 @@ function resolveForBundle(unbound, bundle) {
|
|
|
10
10
|
}
|
|
11
11
|
function createImageLoaderSharedEntries({
|
|
12
12
|
bound,
|
|
13
|
+
ssrImageDeploymentIds,
|
|
13
14
|
unbound
|
|
14
15
|
} = {}) {
|
|
15
16
|
const loaderEntry = (bundle) => {
|
|
16
17
|
const resolveClientUrl = bound ?? resolveForBundle(unbound, bundle);
|
|
17
18
|
return Promise.resolve({
|
|
18
|
-
default: createRemoteImageLoader(
|
|
19
|
+
default: createRemoteImageLoader(
|
|
20
|
+
bundle,
|
|
21
|
+
resolveClientUrl,
|
|
22
|
+
ssrImageDeploymentIds
|
|
23
|
+
),
|
|
19
24
|
__esModule: true
|
|
20
25
|
});
|
|
21
26
|
};
|
|
22
27
|
const imageEntry = async (bundle) => {
|
|
23
28
|
const resolveClientUrl = bound ?? resolveForBundle(unbound, bundle);
|
|
24
|
-
const rawLoader = createRemoteImageLoader(
|
|
29
|
+
const rawLoader = createRemoteImageLoader(
|
|
30
|
+
bundle,
|
|
31
|
+
resolveClientUrl,
|
|
32
|
+
ssrImageDeploymentIds
|
|
33
|
+
);
|
|
25
34
|
const remoteLoader = Object.assign(
|
|
26
35
|
(p) => rawLoader({ ...p, config: { path: "/_next/image" } }),
|
|
27
36
|
{ __next_img_default: true }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/host/nextjs/image-shared.ts"],"sourcesContent":["import { createElement, forwardRef } from 'react';\nimport { createRemoteImageLoader } from '#internal/host/shared/remote-image-loader';\nimport { getScope } from '#internal/runtime/turbopack/remote-scope';\nimport { bindResolveClientUrl } from '#internal/runtime/url/default-resolve-client-url';\nimport type {\n InternalResolveClientUrl,\n ResolveClientUrl,\n} from '#internal/runtime/url/resolve-client-url';\n\ntype SharedImageModule = (bundle: string) => Promise<unknown>;\n\nfunction resolveForBundle(\n unbound: ResolveClientUrl | undefined,\n bundle: string,\n): InternalResolveClientUrl | undefined {\n if (!unbound) return undefined;\n const remoteSrc = getScope(bundle)?.url.href ?? '';\n return bindResolveClientUrl(unbound, remoteSrc);\n}\n\n/**\n * Creates shared module entries for image-related modules that route\n * optimization requests through the remote's `/_next/image` endpoint.\n *\n * Pass `bound` when the resolver already has `remoteSrc` applied (App Router).\n * Pass `unbound` when only the raw 2-arg `ResolveClientUrl` is available\n * (Pages Router, client-only provider).\n */\nexport function createImageLoaderSharedEntries({\n bound,\n unbound,\n}: {\n bound?: InternalResolveClientUrl;\n unbound?: ResolveClientUrl;\n} = {}): Record<string, SharedImageModule> {\n const loaderEntry: SharedImageModule = (bundle: string) => {\n const resolveClientUrl = bound ?? resolveForBundle(unbound, bundle);\n return Promise.resolve({\n default: createRemoteImageLoader(bundle
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/nextjs/image-shared.ts"],"sourcesContent":["import { createElement, forwardRef } from 'react';\nimport type { NextImageDeploymentId } from '#internal/host/shared/next-image-deployment-id';\nimport { createRemoteImageLoader } from '#internal/host/shared/remote-image-loader';\nimport { getScope } from '#internal/runtime/turbopack/remote-scope';\nimport { bindResolveClientUrl } from '#internal/runtime/url/default-resolve-client-url';\nimport type {\n InternalResolveClientUrl,\n ResolveClientUrl,\n} from '#internal/runtime/url/resolve-client-url';\n\ntype SharedImageModule = (bundle: string) => Promise<unknown>;\n\nfunction resolveForBundle(\n unbound: ResolveClientUrl | undefined,\n bundle: string,\n): InternalResolveClientUrl | undefined {\n if (!unbound) return undefined;\n const remoteSrc = getScope(bundle)?.url.href ?? '';\n return bindResolveClientUrl(unbound, remoteSrc);\n}\n\n/**\n * Creates shared module entries for image-related modules that route\n * optimization requests through the remote's `/_next/image` endpoint.\n *\n * Pass `bound` when the resolver already has `remoteSrc` applied (App Router).\n * Pass `unbound` when only the raw 2-arg `ResolveClientUrl` is available\n * (Pages Router, client-only provider).\n */\nexport function createImageLoaderSharedEntries({\n bound,\n ssrImageDeploymentIds,\n unbound,\n}: {\n bound?: InternalResolveClientUrl;\n ssrImageDeploymentIds?: readonly NextImageDeploymentId[];\n unbound?: ResolveClientUrl;\n} = {}): Record<string, SharedImageModule> {\n const loaderEntry: SharedImageModule = (bundle: string) => {\n const resolveClientUrl = bound ?? resolveForBundle(unbound, bundle);\n return Promise.resolve({\n default: createRemoteImageLoader(\n bundle,\n resolveClientUrl,\n ssrImageDeploymentIds,\n ),\n __esModule: true,\n });\n };\n\n // Cross-version compat: remotes <=0.2.x request `next/image` as a shared module.\n // Wraps the host's Image component with the remote image loader injected\n // via the `loader` prop. Can be removed once 0.2.x support is dropped.\n const imageEntry: SharedImageModule = async (bundle: string) => {\n const resolveClientUrl = bound ?? resolveForBundle(unbound, bundle);\n const rawLoader = createRemoteImageLoader(\n bundle,\n resolveClientUrl,\n ssrImageDeploymentIds,\n );\n // Wrap to match Next.js `ImageLoader` signature (no `config` param).\n // The raw loader expects `{ config, src, width, quality }` but the public\n // `loader` prop is called with `{ src, width, quality }` only.\n const remoteLoader = Object.assign(\n (p: { src: string; width: number; quality?: number }) =>\n rawLoader({ ...p, config: { path: '/_next/image' } }),\n { __next_img_default: true as const },\n );\n const mod = await import('next/image');\n const OriginalImage = mod.default;\n type ImageProps = Parameters<typeof OriginalImage>[0];\n const RemoteImage = forwardRef<HTMLImageElement, ImageProps>((props, ref) =>\n createElement(OriginalImage, {\n ...props,\n loader: props.loader ?? remoteLoader,\n ref,\n }),\n );\n RemoteImage.displayName = 'RemoteImage';\n return { ...mod, default: RemoteImage, __esModule: true };\n };\n\n return {\n 'next/dist/shared/lib/image-loader': loaderEntry,\n 'next/dist/esm/shared/lib/image-loader': loaderEntry,\n // Can be removed once 0.2.x support is dropped.\n 'next/image': imageEntry,\n // Can be removed once 0.2.x support is dropped.\n 'next/dist/client/image-component': imageEntry,\n // Can be removed once 0.2.x support is dropped.\n 'next/dist/api/image': imageEntry,\n };\n}\n"],"mappings":"AAAA,SAAS,eAAe,kBAAkB;AAE1C,SAAS,+BAA+B;AACxC,SAAS,gBAAgB;AACzB,SAAS,4BAA4B;AAQrC,SAAS,iBACP,SACA,QACsC;AACtC,MAAI,CAAC;AAAS,WAAO;AACrB,QAAM,YAAY,SAAS,MAAM,GAAG,IAAI,QAAQ;AAChD,SAAO,qBAAqB,SAAS,SAAS;AAChD;AAUO,SAAS,+BAA+B;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AACF,IAII,CAAC,GAAsC;AACzC,QAAM,cAAiC,CAAC,WAAmB;AACzD,UAAM,mBAAmB,SAAS,iBAAiB,SAAS,MAAM;AAClE,WAAO,QAAQ,QAAQ;AAAA,MACrB,SAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,YAAY;AAAA,IACd,CAAC;AAAA,EACH;AAKA,QAAM,aAAgC,OAAO,WAAmB;AAC9D,UAAM,mBAAmB,SAAS,iBAAiB,SAAS,MAAM;AAClE,UAAM,YAAY;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAIA,UAAM,eAAe,OAAO;AAAA,MAC1B,CAAC,MACC,UAAU,EAAE,GAAG,GAAG,QAAQ,EAAE,MAAM,eAAe,EAAE,CAAC;AAAA,MACtD,EAAE,oBAAoB,KAAc;AAAA,IACtC;AACA,UAAM,MAAM,MAAM,OAAO,YAAY;AACrC,UAAM,gBAAgB,IAAI;AAE1B,UAAM,cAAc;AAAA,MAAyC,CAAC,OAAO,QACnE,cAAc,eAAe;AAAA,QAC3B,GAAG;AAAA,QACH,QAAQ,MAAM,UAAU;AAAA,QACxB;AAAA,MACF,CAAC;AAAA,IACH;AACA,gBAAY,cAAc;AAC1B,WAAO,EAAE,GAAG,KAAK,SAAS,aAAa,YAAY,KAAK;AAAA,EAC1D;AAEA,SAAO;AAAA,IACL,qCAAqC;AAAA,IACrC,yCAAyC;AAAA;AAAA,IAEzC,cAAc;AAAA;AAAA,IAEd,oCAAoC;AAAA;AAAA,IAEpC,uBAAuB;AAAA,EACzB;AACF;","names":[]}
|
|
@@ -37,9 +37,11 @@ var import_skeleton = require("#internal/host/nextjs/skeleton");
|
|
|
37
37
|
var import_fetch_with_hooks = require("#internal/host/server/fetch-with-hooks");
|
|
38
38
|
var import_get_client_src = require("#internal/host/server/get-client-src");
|
|
39
39
|
var import_get_ssr_relative_path_base_url = require("#internal/host/server/get-ssr-relative-path-base-url");
|
|
40
|
+
var import_next_image_deployment_id = require("#internal/host/shared/next-image-deployment-id");
|
|
40
41
|
var import_metadata = require("#internal/runtime/metadata");
|
|
41
42
|
var import_rsc_imports = require("#internal/runtime/rsc-imports");
|
|
42
43
|
var import_error = require("#internal/utils/error");
|
|
44
|
+
const NEXT_IMAGE_PATHNAME = "/_next/image";
|
|
43
45
|
async function buildRscComponent(rsc, serverUrl) {
|
|
44
46
|
const componentRSC = `0:${JSON.stringify(rsc)}
|
|
45
47
|
`;
|
|
@@ -79,9 +81,44 @@ function buildSkeletonResponse(serverUrl, metadata, skeletonComponent) {
|
|
|
79
81
|
nextData: void 0,
|
|
80
82
|
component: skeletonComponent,
|
|
81
83
|
html: (0, import_skeleton.getSkeletonHtml)(serverUrl.href),
|
|
82
|
-
remoteShared: {}
|
|
84
|
+
remoteShared: {},
|
|
85
|
+
ssrImageDeploymentIds: []
|
|
83
86
|
};
|
|
84
87
|
}
|
|
88
|
+
function getNextImageDeploymentId(value, base) {
|
|
89
|
+
try {
|
|
90
|
+
const parsed = new URL(value.replace(/&/g, "&"), base);
|
|
91
|
+
const imageSrc = parsed.searchParams.get("url");
|
|
92
|
+
if (!parsed.pathname.endsWith(NEXT_IMAGE_PATHNAME) || !(0, import_next_image_deployment_id.isNextDeploymentAssetSrc)(imageSrc)) {
|
|
93
|
+
return void 0;
|
|
94
|
+
}
|
|
95
|
+
const extracted = (0, import_next_image_deployment_id.extractDeploymentIdFromSrc)(imageSrc);
|
|
96
|
+
const deploymentId = parsed.searchParams.get("dpl") || extracted.deploymentId;
|
|
97
|
+
return deploymentId ? { src: extracted.src, deploymentId } : void 0;
|
|
98
|
+
} catch {
|
|
99
|
+
return void 0;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function addNextImageDeploymentId(value, serverUrl, result) {
|
|
103
|
+
if (!value) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const image = getNextImageDeploymentId(value, serverUrl);
|
|
107
|
+
if (image) {
|
|
108
|
+
result.set(image.src, image.deploymentId);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function addNextImageDeploymentIdsFromSrcset(value, serverUrl, result) {
|
|
112
|
+
if (!value)
|
|
113
|
+
return;
|
|
114
|
+
for (const candidate of value.split(",")) {
|
|
115
|
+
addNextImageDeploymentId(
|
|
116
|
+
candidate.trim().split(/\s+/)[0],
|
|
117
|
+
serverUrl,
|
|
118
|
+
result
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
85
122
|
function visitFragment(fragment, serverUrl, remoteName) {
|
|
86
123
|
const scriptSrcSet = /* @__PURE__ */ new Set();
|
|
87
124
|
const scriptTextSet = /* @__PURE__ */ new Set();
|
|
@@ -90,6 +127,7 @@ function visitFragment(fragment, serverUrl, remoteName) {
|
|
|
90
127
|
const links = [];
|
|
91
128
|
const hydrationData = [];
|
|
92
129
|
const htmlChunks = /* @__PURE__ */ new Set();
|
|
130
|
+
const ssrImageDeploymentIdMap = /* @__PURE__ */ new Map();
|
|
93
131
|
let metadata;
|
|
94
132
|
let nextData;
|
|
95
133
|
let remoteShared = {};
|
|
@@ -152,6 +190,17 @@ function visitFragment(fragment, serverUrl, remoteName) {
|
|
|
152
190
|
if (stack) {
|
|
153
191
|
error.stack = stack;
|
|
154
192
|
}
|
|
193
|
+
},
|
|
194
|
+
onElement(nodeName, attrs) {
|
|
195
|
+
if (nodeName !== "img") {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
addNextImageDeploymentId(attrs.src, serverUrl, ssrImageDeploymentIdMap);
|
|
199
|
+
addNextImageDeploymentIdsFromSrcset(
|
|
200
|
+
attrs.srcset,
|
|
201
|
+
serverUrl,
|
|
202
|
+
ssrImageDeploymentIdMap
|
|
203
|
+
);
|
|
155
204
|
}
|
|
156
205
|
});
|
|
157
206
|
hydrationData.push(...rawRscChunks);
|
|
@@ -181,6 +230,10 @@ function visitFragment(fragment, serverUrl, remoteName) {
|
|
|
181
230
|
hydrationData,
|
|
182
231
|
nextData,
|
|
183
232
|
remoteShared: resolvedShared,
|
|
233
|
+
ssrImageDeploymentIds: Array.from(
|
|
234
|
+
ssrImageDeploymentIdMap,
|
|
235
|
+
([src, deploymentId]) => ({ src, deploymentId })
|
|
236
|
+
),
|
|
184
237
|
html: Array.from(htmlChunks).join("")
|
|
185
238
|
};
|
|
186
239
|
}
|
|
@@ -262,7 +315,8 @@ async function fetchRemoteComponent(src, options = {}) {
|
|
|
262
315
|
hydrationData,
|
|
263
316
|
nextData,
|
|
264
317
|
remoteShared,
|
|
265
|
-
html
|
|
318
|
+
html,
|
|
319
|
+
ssrImageDeploymentIds
|
|
266
320
|
} = visitFragment(fragment, serverUrl, remoteName);
|
|
267
321
|
if (!metadata) {
|
|
268
322
|
const isSSGBuild = process.env.NEXT_PHASE === "phase-production-build";
|
|
@@ -302,7 +356,8 @@ async function fetchRemoteComponent(src, options = {}) {
|
|
|
302
356
|
nextData,
|
|
303
357
|
component,
|
|
304
358
|
html,
|
|
305
|
-
remoteShared
|
|
359
|
+
remoteShared,
|
|
360
|
+
ssrImageDeploymentIds
|
|
306
361
|
};
|
|
307
362
|
}
|
|
308
363
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/host/server/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { type RSC, visit } from '#internal/host/nextjs/dom-flight';\nimport {\n getSkeletonHtml,\n getSkeletonMessage,\n} from '#internal/host/nextjs/skeleton';\nimport { fetchWithHooks } from '#internal/host/server/fetch-with-hooks';\nimport { getClientSrc } from '#internal/host/server/get-client-src';\nimport {\n DEPLOYMENT_URL,\n getSSRRelativePathBaseUrl,\n PRODUCTION_URL,\n} from '#internal/host/server/get-ssr-relative-path-base-url';\nimport type {\n LinkDescriptor,\n ScriptDescriptor,\n} from '#internal/host/shared/asset-descriptors';\nimport type {\n OnRequestHook,\n OnResponseHook,\n} from '#internal/host/shared/fetch-interceptors';\nimport type { RemoteSharedModules } from '#internal/host/shared/shared-broker';\nimport {\n buildMetadata,\n type RawMetadataAttrs,\n type RemoteComponentMetadata,\n} from '#internal/runtime/metadata';\nimport { importRSCClientEdge } from '#internal/runtime/rsc-imports';\nimport {\n failedToFetchRemoteComponentError,\n multipleRemoteComponentsError,\n RemoteComponentsError,\n} from '#internal/utils/error';\nimport type { FetchRemoteComponentResponse, NextData } from './types';\n\n/**\n * Converts RSC flight data into a React element tree using the edge streaming\n * runtime. The manifest tells React how to resolve module references back to\n * the remote origin.\n */\nasync function buildRscComponent(\n rsc: RSC | RSC[] | string | null,\n serverUrl: URL,\n): Promise<React.ReactNode> {\n const componentRSC = `0:${JSON.stringify(rsc)}\\n`;\n const { createFromReadableStream } = await importRSCClientEdge();\n return createFromReadableStream(\n new ReadableStream({\n type: 'bytes',\n start(controller) {\n const encoder = new TextEncoder();\n controller.enqueue(encoder.encode(componentRSC));\n controller.close();\n },\n }),\n {\n serverConsumerManifest: {\n moduleLoading: {\n prefix: serverUrl.origin,\n crossOrigin: true,\n },\n moduleMap: {},\n },\n },\n );\n}\n\nfunction buildSkeletonResponse(\n serverUrl: URL,\n metadata: RemoteComponentMetadata,\n skeletonComponent: React.ReactNode | undefined,\n): FetchRemoteComponentResponse {\n return {\n name: 'remote-component-skeleton',\n serverUrl,\n metadata: {\n ...metadata,\n type: 'remote-component',\n },\n rsc: getSkeletonMessage(),\n scripts: [],\n links: [],\n hydrationData: [],\n nextData: undefined,\n component: skeletonComponent,\n html: getSkeletonHtml(serverUrl.href),\n remoteShared: {},\n };\n}\n\n/**\n * Walks the parsed HTML fragment and extracts all remote component data:\n * metadata, scripts, links, hydration data, Next.js data, shared deps, and HTML.\n */\nfunction visitFragment(\n fragment: DefaultTreeAdapterMap['documentFragment'],\n serverUrl: URL,\n remoteName: string | undefined,\n) {\n const scriptSrcSet = new Set<string>();\n const scriptTextSet = new Set<string>();\n const scripts: ScriptDescriptor[] = [];\n\n const linkKeySet = new Set<string>();\n const links: LinkDescriptor[] = [];\n\n const hydrationData: string[] = [];\n const htmlChunks = new Set<string>();\n\n let metadata: RemoteComponentMetadata | undefined;\n let nextData: NextData | undefined;\n let remoteShared: RemoteSharedModules = {};\n let hasRSC = false;\n let hasShared = false;\n let error: RemoteComponentsError | undefined;\n\n const rawRscChunks: string[] = [];\n\n const rsc = visit(fragment, {\n url: serverUrl,\n name: remoteName,\n onMetadata(attrs: RawMetadataAttrs) {\n const incoming = buildMetadata(attrs, serverUrl);\n // Skip multiple component detection for Pages Router (__next) since\n // it only supports one remote component per page\n if (\n !remoteName &&\n metadata &&\n metadata.id !== incoming.id &&\n incoming.id !== '__next' &&\n metadata.id !== '__next' &&\n !nextData\n ) {\n throw multipleRemoteComponentsError(serverUrl.href);\n }\n metadata = incoming;\n },\n onScript(attrs) {\n const clientSrc = getClientSrc(attrs.src, serverUrl.href);\n const textContent =\n typeof attrs.textContent === 'string' ? attrs.textContent : undefined;\n\n if (textContent) {\n if (!scriptTextSet.has(textContent)) {\n scriptTextSet.add(textContent);\n scripts.push({ src: '', textContent });\n }\n } else if (!scriptSrcSet.has(clientSrc)) {\n scriptSrcSet.add(clientSrc);\n scripts.push({ src: clientSrc });\n }\n },\n onLink(attrs) {\n const relativeAttrs = {\n ...attrs,\n href: getClientSrc(attrs.href, serverUrl.href),\n };\n const linkKey = `${relativeAttrs.href}::${attrs.rel}`;\n if (!linkKeySet.has(linkKey)) {\n linkKeySet.add(linkKey);\n links.push(relativeAttrs);\n }\n },\n onRSC(chunk) {\n rawRscChunks.push(chunk);\n hasRSC = true;\n },\n onNextData(data) {\n nextData = data;\n },\n onHTML(chunk) {\n if (!htmlChunks.has(chunk)) {\n htmlChunks.add(chunk);\n }\n },\n onShared(_shared) {\n remoteShared = _shared;\n hasShared = true;\n },\n onError(message, stack) {\n error = new RemoteComponentsError(message);\n if (stack) {\n error.stack = stack;\n }\n },\n });\n\n hydrationData.push(...rawRscChunks);\n\n if (error) {\n throw error;\n }\n\n if (metadata) {\n if (!hasRSC && !nextData && metadata.type === 'nextjs') {\n throw new RemoteComponentsError(\n `The Remote Component at \"${serverUrl.href}\" seems to be a Next.js component but it does not contain any RSC flight data or Next.js props data. Make sure the remote URL is correct and contains a Remote Component.`,\n );\n }\n\n if (\n metadata.type === 'nextjs' &&\n !hasShared &&\n !nextData?.props.__REMOTE_COMPONENT__?.sharedManifest &&\n !nextData?.props.__REMOTE_COMPONENT__?.shared\n ) {\n throw new RemoteComponentsError(\n `No shared dependencies found for Remote Component at \"${serverUrl.href}\". Make sure the remote URL is correct and contains a Remote Component with shared dependencies.`,\n );\n }\n }\n\n const resolvedShared =\n nextData?.props.__REMOTE_COMPONENT__?.sharedManifest ??\n // @legacy(remote-components<=0.4.x): keep accepting the Pages Router\n // shared map until remotes on 0.4.x are outside the compatibility window.\n nextData?.props.__REMOTE_COMPONENT__?.shared ??\n remoteShared;\n\n return {\n rsc,\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n remoteShared: resolvedShared,\n html: Array.from(htmlChunks).join(''),\n };\n}\n\ninterface Options {\n name?: string;\n rsc?: boolean;\n /** Whether this is being called from Next.js App Router. Used to enable skeleton fallback during SSG builds. */\n appRouter?: boolean;\n onRequest?: OnRequestHook;\n onResponse?: OnResponseHook;\n}\n\nasync function fetchWithTags(\n src: string | URL,\n relativePathBaseUrl: string,\n options: Options,\n) {\n const serverUrl = new URL(src, relativePathBaseUrl);\n const tags = [\n '_vc_rc:fetch-remote-component',\n // the max size of a next cache tag is 256 characters\n serverUrl.host.slice(0, 256),\n // use the suffix so this tag is unique if multiple remote\n // components have the same host, but unique pathnames / query params\n (typeof src === 'string' ? src : src.href).slice(-256),\n ];\n if (options.name) {\n tags.push(options.name.slice(-256));\n }\n\n const fetchInit = { next: { tags } };\n\n const res = await fetchWithHooks(serverUrl, fetchInit, {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\n });\n\n return {\n res,\n serverUrl,\n // If the remote component is part of a microfrontend, the src provided will be relative.\n isMfeRelativeSrc: serverUrl.host === new URL(relativePathBaseUrl).host,\n };\n}\n\nexport async function fetchRemoteComponent(\n src: string | URL,\n options: Options = {},\n): Promise<FetchRemoteComponentResponse> {\n let { res, isMfeRelativeSrc, serverUrl } = await fetchWithTags(\n src,\n getSSRRelativePathBaseUrl(),\n options,\n );\n\n const maybeFirstMfeProductionDeployment =\n isMfeRelativeSrc && serverUrl.host === PRODUCTION_URL;\n\n // When deploying a microfrontend with remote components to production for the first time, the fetch with the\n // production URL will fail if the production URL is not already an MFE alias. The URL becomes an MFE alias\n // on the first MFE deployment. For this fetch, use the deployment URL which is an MFE alias.\n if (\n res.status === 404 &&\n maybeFirstMfeProductionDeployment &&\n DEPLOYMENT_URL\n ) {\n ({ res, isMfeRelativeSrc, serverUrl } = await fetchWithTags(\n src,\n `https://${DEPLOYMENT_URL}`,\n options,\n ));\n }\n\n // If there is an error in the remote, parse and extract the remote error (except 404 and 401).\n if (!res.ok && !res.body) {\n throw failedToFetchRemoteComponentError(serverUrl.href, res);\n }\n\n if (res.status === 401) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n 'If you are using Deployment Protection, ensure the automation bypass environment variable secret in the host matches an automation bypass value in the remote. See https://remote-components-docs.vercel.sh/docs/concepts/cors-external-urls#deployment-protection for details.',\n );\n }\n\n if (res.status === 404) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n maybeFirstMfeProductionDeployment\n ? `If this is the first production build of a microfrontends setup, try redeploying once the remote is deployed to production. Once deployed, this error will not re-occur, and ISR revalidation will happen automatically for remote components once they deploy. https://remote-components-docs.vercel.sh/docs/concepts/isr-deployment`\n : `Check if you can open it in the browser.`,\n );\n }\n\n if (!res.body) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n `Response body is empty. Check if you can open it in the browser and you see the Remote Component content.`,\n );\n }\n\n const parser = Parser.getFragmentParser<DefaultTreeAdapterMap>();\n const decoder = new TextDecoder();\n // read the response body as a stream and parse it using the parse5 fragment parser\n for await (const chunk of res.body as unknown as AsyncIterable<Uint8Array>) {\n parser.tokenizer.write(decoder.decode(chunk), false);\n }\n const fragment = parser.getFragment();\n\n const remoteName =\n options.name || (serverUrl.hash ? serverUrl.hash.substring(1) : undefined);\n\n const {\n rsc,\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n remoteShared,\n html,\n } = visitFragment(fragment, serverUrl, remoteName);\n\n if (!metadata) {\n // For microfrontend builds during run time, the host and remote build\n // may be happening concurrently. In this case, the request will 404.\n // We want to allow the build to continue with a placeholder remote\n // component. Once the build completes, vercel will automatically revalidate\n // ISR and fetch the built remote component.\n const isSSGBuild = process.env.NEXT_PHASE === 'phase-production-build';\n // Only want this skeleton behaviour in previews to unblock development.\n // For production, the remote component should already be built.\n const isPreview = process.env.VERCEL_TARGET_ENV === 'preview';\n // For app router previews, the host and remote build at the same time, to allow this, render a skeleton\n // in the host if the remote is not found, which will revalidate when the remote deploys, or give a helpful error in the UI\n if (isSSGBuild && isMfeRelativeSrc && isPreview && options.appRouter) {\n let skeletonComponent: React.ReactNode | undefined;\n if (options.rsc) {\n const { createElement } = await import('react');\n skeletonComponent = createElement('div', {\n dangerouslySetInnerHTML: {\n __html: getSkeletonHtml(serverUrl.href),\n },\n });\n }\n\n return buildSkeletonResponse(\n serverUrl,\n buildMetadata({}, serverUrl),\n skeletonComponent,\n );\n }\n\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n `No Remote Component found. Make sure the remote URL is correct and contains a Remote Component.`,\n );\n }\n\n const name = remoteName || metadata.name;\n const component = options.rsc\n ? await buildRscComponent(rsc, serverUrl)\n : undefined;\n\n return {\n name,\n serverUrl,\n metadata,\n rsc,\n scripts,\n links,\n hydrationData,\n nextData,\n component,\n html,\n remoteShared,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAmD;AACnD,wBAAgC;AAChC,sBAGO;AACP,8BAA+B;AAC/B,4BAA6B;AAC7B,4CAIO;AAUP,sBAIO;AACP,yBAAoC;AACpC,mBAIO;AAQP,eAAe,kBACb,KACA,WAC0B;AAC1B,QAAM,eAAe,KAAK,KAAK,UAAU,GAAG;AAAA;AAC5C,QAAM,EAAE,yBAAyB,IAAI,UAAM,wCAAoB;AAC/D,SAAO;AAAA,IACL,IAAI,eAAe;AAAA,MACjB,MAAM;AAAA,MACN,MAAM,YAAY;AAChB,cAAM,UAAU,IAAI,YAAY;AAChC,mBAAW,QAAQ,QAAQ,OAAO,YAAY,CAAC;AAC/C,mBAAW,MAAM;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,IACD;AAAA,MACE,wBAAwB;AAAA,QACtB,eAAe;AAAA,UACb,QAAQ,UAAU;AAAA,UAClB,aAAa;AAAA,QACf;AAAA,QACA,WAAW,CAAC;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,sBACP,WACA,UACA,mBAC8B;AAC9B,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,UAAU;AAAA,MACR,GAAG;AAAA,MACH,MAAM;AAAA,IACR;AAAA,IACA,SAAK,oCAAmB;AAAA,IACxB,SAAS,CAAC;AAAA,IACV,OAAO,CAAC;AAAA,IACR,eAAe,CAAC;AAAA,IAChB,UAAU;AAAA,IACV,WAAW;AAAA,IACX,UAAM,iCAAgB,UAAU,IAAI;AAAA,IACpC,cAAc,CAAC;AAAA,EACjB;AACF;AAMA,SAAS,cACP,UACA,WACA,YACA;AACA,QAAM,eAAe,oBAAI,IAAY;AACrC,QAAM,gBAAgB,oBAAI,IAAY;AACtC,QAAM,UAA8B,CAAC;AAErC,QAAM,aAAa,oBAAI,IAAY;AACnC,QAAM,QAA0B,CAAC;AAEjC,QAAM,gBAA0B,CAAC;AACjC,QAAM,aAAa,oBAAI,IAAY;AAEnC,MAAI;AACJ,MAAI;AACJ,MAAI,eAAoC,CAAC;AACzC,MAAI,SAAS;AACb,MAAI,YAAY;AAChB,MAAI;AAEJ,QAAM,eAAyB,CAAC;AAEhC,QAAM,UAAM,yBAAM,UAAU;AAAA,IAC1B,KAAK;AAAA,IACL,MAAM;AAAA,IACN,WAAW,OAAyB;AAClC,YAAM,eAAW,+BAAc,OAAO,SAAS;AAG/C,UACE,CAAC,cACD,YACA,SAAS,OAAO,SAAS,MACzB,SAAS,OAAO,YAChB,SAAS,OAAO,YAChB,CAAC,UACD;AACA,kBAAM,4CAA8B,UAAU,IAAI;AAAA,MACpD;AACA,iBAAW;AAAA,IACb;AAAA,IACA,SAAS,OAAO;AACd,YAAM,gBAAY,oCAAa,MAAM,KAAK,UAAU,IAAI;AACxD,YAAM,cACJ,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc;AAE9D,UAAI,aAAa;AACf,YAAI,CAAC,cAAc,IAAI,WAAW,GAAG;AACnC,wBAAc,IAAI,WAAW;AAC7B,kBAAQ,KAAK,EAAE,KAAK,IAAI,YAAY,CAAC;AAAA,QACvC;AAAA,MACF,WAAW,CAAC,aAAa,IAAI,SAAS,GAAG;AACvC,qBAAa,IAAI,SAAS;AAC1B,gBAAQ,KAAK,EAAE,KAAK,UAAU,CAAC;AAAA,MACjC;AAAA,IACF;AAAA,IACA,OAAO,OAAO;AACZ,YAAM,gBAAgB;AAAA,QACpB,GAAG;AAAA,QACH,UAAM,oCAAa,MAAM,MAAM,UAAU,IAAI;AAAA,MAC/C;AACA,YAAM,UAAU,GAAG,cAAc,SAAS,MAAM;AAChD,UAAI,CAAC,WAAW,IAAI,OAAO,GAAG;AAC5B,mBAAW,IAAI,OAAO;AACtB,cAAM,KAAK,aAAa;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,MAAM,OAAO;AACX,mBAAa,KAAK,KAAK;AACvB,eAAS;AAAA,IACX;AAAA,IACA,WAAW,MAAM;AACf,iBAAW;AAAA,IACb;AAAA,IACA,OAAO,OAAO;AACZ,UAAI,CAAC,WAAW,IAAI,KAAK,GAAG;AAC1B,mBAAW,IAAI,KAAK;AAAA,MACtB;AAAA,IACF;AAAA,IACA,SAAS,SAAS;AAChB,qBAAe;AACf,kBAAY;AAAA,IACd;AAAA,IACA,QAAQ,SAAS,OAAO;AACtB,cAAQ,IAAI,mCAAsB,OAAO;AACzC,UAAI,OAAO;AACT,cAAM,QAAQ;AAAA,MAChB;AAAA,IACF;AAAA,EACF,CAAC;AAED,gBAAc,KAAK,GAAG,YAAY;AAElC,MAAI,OAAO;AACT,UAAM;AAAA,EACR;AAEA,MAAI,UAAU;AACZ,QAAI,CAAC,UAAU,CAAC,YAAY,SAAS,SAAS,UAAU;AACtD,YAAM,IAAI;AAAA,QACR,4BAA4B,UAAU;AAAA,MACxC;AAAA,IACF;AAEA,QACE,SAAS,SAAS,YAClB,CAAC,aACD,CAAC,UAAU,MAAM,sBAAsB,kBACvC,CAAC,UAAU,MAAM,sBAAsB,QACvC;AACA,YAAM,IAAI;AAAA,QACR,yDAAyD,UAAU;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,iBACJ,UAAU,MAAM,sBAAsB;AAAA;AAAA,EAGtC,UAAU,MAAM,sBAAsB,UACtC;AAEF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,MAAM,MAAM,KAAK,UAAU,EAAE,KAAK,EAAE;AAAA,EACtC;AACF;AAWA,eAAe,cACb,KACA,qBACA,SACA;AACA,QAAM,YAAY,IAAI,IAAI,KAAK,mBAAmB;AAClD,QAAM,OAAO;AAAA,IACX;AAAA;AAAA,IAEA,UAAU,KAAK,MAAM,GAAG,GAAG;AAAA;AAAA;AAAA,KAG1B,OAAO,QAAQ,WAAW,MAAM,IAAI,MAAM,MAAM,IAAI;AAAA,EACvD;AACA,MAAI,QAAQ,MAAM;AAChB,SAAK,KAAK,QAAQ,KAAK,MAAM,IAAI,CAAC;AAAA,EACpC;AAEA,QAAM,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE;AAEnC,QAAM,MAAM,UAAM,wCAAe,WAAW,WAAW;AAAA,IACrD,WAAW,QAAQ;AAAA,IACnB,YAAY,QAAQ;AAAA,EACtB,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA;AAAA,IAEA,kBAAkB,UAAU,SAAS,IAAI,IAAI,mBAAmB,EAAE;AAAA,EACpE;AACF;AAEA,eAAsB,qBACpB,KACA,UAAmB,CAAC,GACmB;AACvC,MAAI,EAAE,KAAK,kBAAkB,UAAU,IAAI,MAAM;AAAA,IAC/C;AAAA,QACA,iEAA0B;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,oCACJ,oBAAoB,UAAU,SAAS;AAKzC,MACE,IAAI,WAAW,OACf,qCACA,sDACA;AACA,KAAC,EAAE,KAAK,kBAAkB,UAAU,IAAI,MAAM;AAAA,MAC5C;AAAA,MACA,WAAW;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAGA,MAAI,CAAC,IAAI,MAAM,CAAC,IAAI,MAAM;AACxB,cAAM,gDAAkC,UAAU,MAAM,GAAG;AAAA,EAC7D;AAEA,MAAI,IAAI,WAAW,KAAK;AACtB,cAAM;AAAA,MACJ,UAAU;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,IAAI,WAAW,KAAK;AACtB,cAAM;AAAA,MACJ,UAAU;AAAA,MACV;AAAA,MACA,oCACI,0UACA;AAAA,IACN;AAAA,EACF;AAEA,MAAI,CAAC,IAAI,MAAM;AACb,cAAM;AAAA,MACJ,UAAU;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,qBAAO,kBAAyC;AAC/D,QAAM,UAAU,IAAI,YAAY;AAEhC,mBAAiB,SAAS,IAAI,MAA8C;AAC1E,WAAO,UAAU,MAAM,QAAQ,OAAO,KAAK,GAAG,KAAK;AAAA,EACrD;AACA,QAAM,WAAW,OAAO,YAAY;AAEpC,QAAM,aACJ,QAAQ,SAAS,UAAU,OAAO,UAAU,KAAK,UAAU,CAAC,IAAI;AAElE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,cAAc,UAAU,WAAW,UAAU;AAEjD,MAAI,CAAC,UAAU;AAMb,UAAM,aAAa,QAAQ,IAAI,eAAe;AAG9C,UAAM,YAAY,QAAQ,IAAI,sBAAsB;AAGpD,QAAI,cAAc,oBAAoB,aAAa,QAAQ,WAAW;AACpE,UAAI;AACJ,UAAI,QAAQ,KAAK;AACf,cAAM,EAAE,cAAc,IAAI,MAAM,OAAO,OAAO;AAC9C,4BAAoB,cAAc,OAAO;AAAA,UACvC,yBAAyB;AAAA,YACvB,YAAQ,iCAAgB,UAAU,IAAI;AAAA,UACxC;AAAA,QACF,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,QACL;AAAA,YACA,+BAAc,CAAC,GAAG,SAAS;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAEA,cAAM;AAAA,MACJ,UAAU;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,OAAO,cAAc,SAAS;AACpC,QAAM,YAAY,QAAQ,MACtB,MAAM,kBAAkB,KAAK,SAAS,IACtC;AAEJ,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/server/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { type RSC, visit } from '#internal/host/nextjs/dom-flight';\nimport {\n getSkeletonHtml,\n getSkeletonMessage,\n} from '#internal/host/nextjs/skeleton';\nimport { fetchWithHooks } from '#internal/host/server/fetch-with-hooks';\nimport { getClientSrc } from '#internal/host/server/get-client-src';\nimport {\n DEPLOYMENT_URL,\n getSSRRelativePathBaseUrl,\n PRODUCTION_URL,\n} from '#internal/host/server/get-ssr-relative-path-base-url';\nimport type {\n LinkDescriptor,\n ScriptDescriptor,\n} from '#internal/host/shared/asset-descriptors';\nimport type {\n OnRequestHook,\n OnResponseHook,\n} from '#internal/host/shared/fetch-interceptors';\nimport {\n extractDeploymentIdFromSrc,\n isNextDeploymentAssetSrc,\n type NextImageDeploymentId,\n} from '#internal/host/shared/next-image-deployment-id';\nimport type { RemoteSharedModules } from '#internal/host/shared/shared-broker';\nimport {\n buildMetadata,\n type RawMetadataAttrs,\n type RemoteComponentMetadata,\n} from '#internal/runtime/metadata';\nimport { importRSCClientEdge } from '#internal/runtime/rsc-imports';\nimport {\n failedToFetchRemoteComponentError,\n multipleRemoteComponentsError,\n RemoteComponentsError,\n} from '#internal/utils/error';\nimport type { FetchRemoteComponentResponse, NextData } from './types';\n\nconst NEXT_IMAGE_PATHNAME = '/_next/image';\n/**\n * Converts RSC flight data into a React element tree using the edge streaming\n * runtime. The manifest tells React how to resolve module references back to\n * the remote origin.\n */\nasync function buildRscComponent(\n rsc: RSC | RSC[] | string | null,\n serverUrl: URL,\n): Promise<React.ReactNode> {\n const componentRSC = `0:${JSON.stringify(rsc)}\\n`;\n const { createFromReadableStream } = await importRSCClientEdge();\n return createFromReadableStream(\n new ReadableStream({\n type: 'bytes',\n start(controller) {\n const encoder = new TextEncoder();\n controller.enqueue(encoder.encode(componentRSC));\n controller.close();\n },\n }),\n {\n serverConsumerManifest: {\n moduleLoading: {\n prefix: serverUrl.origin,\n crossOrigin: true,\n },\n moduleMap: {},\n },\n },\n );\n}\n\nfunction buildSkeletonResponse(\n serverUrl: URL,\n metadata: RemoteComponentMetadata,\n skeletonComponent: React.ReactNode | undefined,\n): FetchRemoteComponentResponse {\n return {\n name: 'remote-component-skeleton',\n serverUrl,\n metadata: {\n ...metadata,\n type: 'remote-component',\n },\n rsc: getSkeletonMessage(),\n scripts: [],\n links: [],\n hydrationData: [],\n nextData: undefined,\n component: skeletonComponent,\n html: getSkeletonHtml(serverUrl.href),\n remoteShared: {},\n ssrImageDeploymentIds: [],\n };\n}\n\nfunction getNextImageDeploymentId(\n value: string,\n base: URL,\n): NextImageDeploymentId | undefined {\n try {\n const parsed = new URL(value.replace(/&/g, '&'), base);\n const imageSrc = parsed.searchParams.get('url');\n if (\n !parsed.pathname.endsWith(NEXT_IMAGE_PATHNAME) ||\n !isNextDeploymentAssetSrc(imageSrc)\n ) {\n return undefined;\n }\n\n const extracted = extractDeploymentIdFromSrc(imageSrc);\n const deploymentId =\n parsed.searchParams.get('dpl') || extracted.deploymentId;\n\n return deploymentId ? { src: extracted.src, deploymentId } : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction addNextImageDeploymentId(\n value: string | undefined,\n serverUrl: URL,\n result: Map<string, string>,\n) {\n if (!value) {\n return;\n }\n\n const image = getNextImageDeploymentId(value, serverUrl);\n if (image) {\n result.set(image.src, image.deploymentId);\n }\n}\n\nfunction addNextImageDeploymentIdsFromSrcset(\n value: string | undefined,\n serverUrl: URL,\n result: Map<string, string>,\n) {\n if (!value) return;\n for (const candidate of value.split(',')) {\n addNextImageDeploymentId(\n candidate.trim().split(/\\s+/)[0],\n serverUrl,\n result,\n );\n }\n}\n\n/**\n * Walks the parsed HTML fragment and extracts all remote component data:\n * metadata, scripts, links, hydration data, Next.js data, shared deps, and HTML.\n */\nfunction visitFragment(\n fragment: DefaultTreeAdapterMap['documentFragment'],\n serverUrl: URL,\n remoteName: string | undefined,\n) {\n const scriptSrcSet = new Set<string>();\n const scriptTextSet = new Set<string>();\n const scripts: ScriptDescriptor[] = [];\n\n const linkKeySet = new Set<string>();\n const links: LinkDescriptor[] = [];\n\n const hydrationData: string[] = [];\n const htmlChunks = new Set<string>();\n const ssrImageDeploymentIdMap = new Map<string, string>();\n\n let metadata: RemoteComponentMetadata | undefined;\n let nextData: NextData | undefined;\n let remoteShared: RemoteSharedModules = {};\n let hasRSC = false;\n let hasShared = false;\n let error: RemoteComponentsError | undefined;\n\n const rawRscChunks: string[] = [];\n\n const rsc = visit(fragment, {\n url: serverUrl,\n name: remoteName,\n onMetadata(attrs: RawMetadataAttrs) {\n const incoming = buildMetadata(attrs, serverUrl);\n // Skip multiple component detection for Pages Router (__next) since\n // it only supports one remote component per page\n if (\n !remoteName &&\n metadata &&\n metadata.id !== incoming.id &&\n incoming.id !== '__next' &&\n metadata.id !== '__next' &&\n !nextData\n ) {\n throw multipleRemoteComponentsError(serverUrl.href);\n }\n metadata = incoming;\n },\n onScript(attrs) {\n const clientSrc = getClientSrc(attrs.src, serverUrl.href);\n const textContent =\n typeof attrs.textContent === 'string' ? attrs.textContent : undefined;\n\n if (textContent) {\n if (!scriptTextSet.has(textContent)) {\n scriptTextSet.add(textContent);\n scripts.push({ src: '', textContent });\n }\n } else if (!scriptSrcSet.has(clientSrc)) {\n scriptSrcSet.add(clientSrc);\n scripts.push({ src: clientSrc });\n }\n },\n onLink(attrs) {\n const relativeAttrs = {\n ...attrs,\n href: getClientSrc(attrs.href, serverUrl.href),\n };\n const linkKey = `${relativeAttrs.href}::${attrs.rel}`;\n if (!linkKeySet.has(linkKey)) {\n linkKeySet.add(linkKey);\n links.push(relativeAttrs);\n }\n },\n onRSC(chunk) {\n rawRscChunks.push(chunk);\n hasRSC = true;\n },\n onNextData(data) {\n nextData = data;\n },\n onHTML(chunk) {\n if (!htmlChunks.has(chunk)) {\n htmlChunks.add(chunk);\n }\n },\n onShared(_shared) {\n remoteShared = _shared;\n hasShared = true;\n },\n onError(message, stack) {\n error = new RemoteComponentsError(message);\n if (stack) {\n error.stack = stack;\n }\n },\n onElement(nodeName, attrs) {\n if (nodeName !== 'img') {\n return;\n }\n\n addNextImageDeploymentId(attrs.src, serverUrl, ssrImageDeploymentIdMap);\n addNextImageDeploymentIdsFromSrcset(\n attrs.srcset,\n serverUrl,\n ssrImageDeploymentIdMap,\n );\n },\n });\n\n hydrationData.push(...rawRscChunks);\n\n if (error) {\n throw error;\n }\n\n if (metadata) {\n if (!hasRSC && !nextData && metadata.type === 'nextjs') {\n throw new RemoteComponentsError(\n `The Remote Component at \"${serverUrl.href}\" seems to be a Next.js component but it does not contain any RSC flight data or Next.js props data. Make sure the remote URL is correct and contains a Remote Component.`,\n );\n }\n\n if (\n metadata.type === 'nextjs' &&\n !hasShared &&\n !nextData?.props.__REMOTE_COMPONENT__?.sharedManifest &&\n !nextData?.props.__REMOTE_COMPONENT__?.shared\n ) {\n throw new RemoteComponentsError(\n `No shared dependencies found for Remote Component at \"${serverUrl.href}\". Make sure the remote URL is correct and contains a Remote Component with shared dependencies.`,\n );\n }\n }\n\n const resolvedShared =\n nextData?.props.__REMOTE_COMPONENT__?.sharedManifest ??\n // @legacy(remote-components<=0.4.x): keep accepting the Pages Router\n // shared map until remotes on 0.4.x are outside the compatibility window.\n nextData?.props.__REMOTE_COMPONENT__?.shared ??\n remoteShared;\n\n return {\n rsc,\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n remoteShared: resolvedShared,\n ssrImageDeploymentIds: Array.from(\n ssrImageDeploymentIdMap,\n ([src, deploymentId]) => ({ src, deploymentId }),\n ),\n html: Array.from(htmlChunks).join(''),\n };\n}\n\ninterface Options {\n name?: string;\n rsc?: boolean;\n /** Whether this is being called from Next.js App Router. Used to enable skeleton fallback during SSG builds. */\n appRouter?: boolean;\n onRequest?: OnRequestHook;\n onResponse?: OnResponseHook;\n}\n\nasync function fetchWithTags(\n src: string | URL,\n relativePathBaseUrl: string,\n options: Options,\n) {\n const serverUrl = new URL(src, relativePathBaseUrl);\n const tags = [\n '_vc_rc:fetch-remote-component',\n // the max size of a next cache tag is 256 characters\n serverUrl.host.slice(0, 256),\n // use the suffix so this tag is unique if multiple remote\n // components have the same host, but unique pathnames / query params\n (typeof src === 'string' ? src : src.href).slice(-256),\n ];\n if (options.name) {\n tags.push(options.name.slice(-256));\n }\n\n const fetchInit = { next: { tags } };\n\n const res = await fetchWithHooks(serverUrl, fetchInit, {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\n });\n\n return {\n res,\n serverUrl,\n // If the remote component is part of a microfrontend, the src provided will be relative.\n isMfeRelativeSrc: serverUrl.host === new URL(relativePathBaseUrl).host,\n };\n}\n\nexport async function fetchRemoteComponent(\n src: string | URL,\n options: Options = {},\n): Promise<FetchRemoteComponentResponse> {\n let { res, isMfeRelativeSrc, serverUrl } = await fetchWithTags(\n src,\n getSSRRelativePathBaseUrl(),\n options,\n );\n\n const maybeFirstMfeProductionDeployment =\n isMfeRelativeSrc && serverUrl.host === PRODUCTION_URL;\n\n // When deploying a microfrontend with remote components to production for the first time, the fetch with the\n // production URL will fail if the production URL is not already an MFE alias. The URL becomes an MFE alias\n // on the first MFE deployment. For this fetch, use the deployment URL which is an MFE alias.\n if (\n res.status === 404 &&\n maybeFirstMfeProductionDeployment &&\n DEPLOYMENT_URL\n ) {\n ({ res, isMfeRelativeSrc, serverUrl } = await fetchWithTags(\n src,\n `https://${DEPLOYMENT_URL}`,\n options,\n ));\n }\n\n // If there is an error in the remote, parse and extract the remote error (except 404 and 401).\n if (!res.ok && !res.body) {\n throw failedToFetchRemoteComponentError(serverUrl.href, res);\n }\n\n if (res.status === 401) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n 'If you are using Deployment Protection, ensure the automation bypass environment variable secret in the host matches an automation bypass value in the remote. See https://remote-components-docs.vercel.sh/docs/concepts/cors-external-urls#deployment-protection for details.',\n );\n }\n\n if (res.status === 404) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n maybeFirstMfeProductionDeployment\n ? `If this is the first production build of a microfrontends setup, try redeploying once the remote is deployed to production. Once deployed, this error will not re-occur, and ISR revalidation will happen automatically for remote components once they deploy. https://remote-components-docs.vercel.sh/docs/concepts/isr-deployment`\n : `Check if you can open it in the browser.`,\n );\n }\n\n if (!res.body) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n `Response body is empty. Check if you can open it in the browser and you see the Remote Component content.`,\n );\n }\n\n const parser = Parser.getFragmentParser<DefaultTreeAdapterMap>();\n const decoder = new TextDecoder();\n // read the response body as a stream and parse it using the parse5 fragment parser\n for await (const chunk of res.body as unknown as AsyncIterable<Uint8Array>) {\n parser.tokenizer.write(decoder.decode(chunk), false);\n }\n const fragment = parser.getFragment();\n\n const remoteName =\n options.name || (serverUrl.hash ? serverUrl.hash.substring(1) : undefined);\n\n const {\n rsc,\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n remoteShared,\n html,\n ssrImageDeploymentIds,\n } = visitFragment(fragment, serverUrl, remoteName);\n\n if (!metadata) {\n // For microfrontend builds during run time, the host and remote build\n // may be happening concurrently. In this case, the request will 404.\n // We want to allow the build to continue with a placeholder remote\n // component. Once the build completes, vercel will automatically revalidate\n // ISR and fetch the built remote component.\n const isSSGBuild = process.env.NEXT_PHASE === 'phase-production-build';\n // Only want this skeleton behaviour in previews to unblock development.\n // For production, the remote component should already be built.\n const isPreview = process.env.VERCEL_TARGET_ENV === 'preview';\n // For app router previews, the host and remote build at the same time, to allow this, render a skeleton\n // in the host if the remote is not found, which will revalidate when the remote deploys, or give a helpful error in the UI\n if (isSSGBuild && isMfeRelativeSrc && isPreview && options.appRouter) {\n let skeletonComponent: React.ReactNode | undefined;\n if (options.rsc) {\n const { createElement } = await import('react');\n skeletonComponent = createElement('div', {\n dangerouslySetInnerHTML: {\n __html: getSkeletonHtml(serverUrl.href),\n },\n });\n }\n\n return buildSkeletonResponse(\n serverUrl,\n buildMetadata({}, serverUrl),\n skeletonComponent,\n );\n }\n\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n `No Remote Component found. Make sure the remote URL is correct and contains a Remote Component.`,\n );\n }\n\n const name = remoteName || metadata.name;\n const component = options.rsc\n ? await buildRscComponent(rsc, serverUrl)\n : undefined;\n\n return {\n name,\n serverUrl,\n metadata,\n rsc,\n scripts,\n links,\n hydrationData,\n nextData,\n component,\n html,\n remoteShared,\n ssrImageDeploymentIds,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -6,6 +6,7 @@ import '../shared/shared-broker.js';
|
|
|
6
6
|
import '../../utils/logger.js';
|
|
7
7
|
import '../../runtime/metadata.js';
|
|
8
8
|
import '../shared/asset-descriptors.js';
|
|
9
|
+
import '../shared/next-image-deployment-id.js';
|
|
9
10
|
import '../../runtime/url/resolve-client-url.js';
|
|
10
11
|
|
|
11
12
|
interface Options {
|
|
@@ -11,6 +11,10 @@ import {
|
|
|
11
11
|
getSSRRelativePathBaseUrl,
|
|
12
12
|
PRODUCTION_URL
|
|
13
13
|
} from "#internal/host/server/get-ssr-relative-path-base-url";
|
|
14
|
+
import {
|
|
15
|
+
extractDeploymentIdFromSrc,
|
|
16
|
+
isNextDeploymentAssetSrc
|
|
17
|
+
} from "#internal/host/shared/next-image-deployment-id";
|
|
14
18
|
import {
|
|
15
19
|
buildMetadata
|
|
16
20
|
} from "#internal/runtime/metadata";
|
|
@@ -20,6 +24,7 @@ import {
|
|
|
20
24
|
multipleRemoteComponentsError,
|
|
21
25
|
RemoteComponentsError
|
|
22
26
|
} from "#internal/utils/error";
|
|
27
|
+
const NEXT_IMAGE_PATHNAME = "/_next/image";
|
|
23
28
|
async function buildRscComponent(rsc, serverUrl) {
|
|
24
29
|
const componentRSC = `0:${JSON.stringify(rsc)}
|
|
25
30
|
`;
|
|
@@ -59,9 +64,44 @@ function buildSkeletonResponse(serverUrl, metadata, skeletonComponent) {
|
|
|
59
64
|
nextData: void 0,
|
|
60
65
|
component: skeletonComponent,
|
|
61
66
|
html: getSkeletonHtml(serverUrl.href),
|
|
62
|
-
remoteShared: {}
|
|
67
|
+
remoteShared: {},
|
|
68
|
+
ssrImageDeploymentIds: []
|
|
63
69
|
};
|
|
64
70
|
}
|
|
71
|
+
function getNextImageDeploymentId(value, base) {
|
|
72
|
+
try {
|
|
73
|
+
const parsed = new URL(value.replace(/&/g, "&"), base);
|
|
74
|
+
const imageSrc = parsed.searchParams.get("url");
|
|
75
|
+
if (!parsed.pathname.endsWith(NEXT_IMAGE_PATHNAME) || !isNextDeploymentAssetSrc(imageSrc)) {
|
|
76
|
+
return void 0;
|
|
77
|
+
}
|
|
78
|
+
const extracted = extractDeploymentIdFromSrc(imageSrc);
|
|
79
|
+
const deploymentId = parsed.searchParams.get("dpl") || extracted.deploymentId;
|
|
80
|
+
return deploymentId ? { src: extracted.src, deploymentId } : void 0;
|
|
81
|
+
} catch {
|
|
82
|
+
return void 0;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function addNextImageDeploymentId(value, serverUrl, result) {
|
|
86
|
+
if (!value) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const image = getNextImageDeploymentId(value, serverUrl);
|
|
90
|
+
if (image) {
|
|
91
|
+
result.set(image.src, image.deploymentId);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function addNextImageDeploymentIdsFromSrcset(value, serverUrl, result) {
|
|
95
|
+
if (!value)
|
|
96
|
+
return;
|
|
97
|
+
for (const candidate of value.split(",")) {
|
|
98
|
+
addNextImageDeploymentId(
|
|
99
|
+
candidate.trim().split(/\s+/)[0],
|
|
100
|
+
serverUrl,
|
|
101
|
+
result
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
65
105
|
function visitFragment(fragment, serverUrl, remoteName) {
|
|
66
106
|
const scriptSrcSet = /* @__PURE__ */ new Set();
|
|
67
107
|
const scriptTextSet = /* @__PURE__ */ new Set();
|
|
@@ -70,6 +110,7 @@ function visitFragment(fragment, serverUrl, remoteName) {
|
|
|
70
110
|
const links = [];
|
|
71
111
|
const hydrationData = [];
|
|
72
112
|
const htmlChunks = /* @__PURE__ */ new Set();
|
|
113
|
+
const ssrImageDeploymentIdMap = /* @__PURE__ */ new Map();
|
|
73
114
|
let metadata;
|
|
74
115
|
let nextData;
|
|
75
116
|
let remoteShared = {};
|
|
@@ -132,6 +173,17 @@ function visitFragment(fragment, serverUrl, remoteName) {
|
|
|
132
173
|
if (stack) {
|
|
133
174
|
error.stack = stack;
|
|
134
175
|
}
|
|
176
|
+
},
|
|
177
|
+
onElement(nodeName, attrs) {
|
|
178
|
+
if (nodeName !== "img") {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
addNextImageDeploymentId(attrs.src, serverUrl, ssrImageDeploymentIdMap);
|
|
182
|
+
addNextImageDeploymentIdsFromSrcset(
|
|
183
|
+
attrs.srcset,
|
|
184
|
+
serverUrl,
|
|
185
|
+
ssrImageDeploymentIdMap
|
|
186
|
+
);
|
|
135
187
|
}
|
|
136
188
|
});
|
|
137
189
|
hydrationData.push(...rawRscChunks);
|
|
@@ -161,6 +213,10 @@ function visitFragment(fragment, serverUrl, remoteName) {
|
|
|
161
213
|
hydrationData,
|
|
162
214
|
nextData,
|
|
163
215
|
remoteShared: resolvedShared,
|
|
216
|
+
ssrImageDeploymentIds: Array.from(
|
|
217
|
+
ssrImageDeploymentIdMap,
|
|
218
|
+
([src, deploymentId]) => ({ src, deploymentId })
|
|
219
|
+
),
|
|
164
220
|
html: Array.from(htmlChunks).join("")
|
|
165
221
|
};
|
|
166
222
|
}
|
|
@@ -242,7 +298,8 @@ async function fetchRemoteComponent(src, options = {}) {
|
|
|
242
298
|
hydrationData,
|
|
243
299
|
nextData,
|
|
244
300
|
remoteShared,
|
|
245
|
-
html
|
|
301
|
+
html,
|
|
302
|
+
ssrImageDeploymentIds
|
|
246
303
|
} = visitFragment(fragment, serverUrl, remoteName);
|
|
247
304
|
if (!metadata) {
|
|
248
305
|
const isSSGBuild = process.env.NEXT_PHASE === "phase-production-build";
|
|
@@ -282,7 +339,8 @@ async function fetchRemoteComponent(src, options = {}) {
|
|
|
282
339
|
nextData,
|
|
283
340
|
component,
|
|
284
341
|
html,
|
|
285
|
-
remoteShared
|
|
342
|
+
remoteShared,
|
|
343
|
+
ssrImageDeploymentIds
|
|
286
344
|
};
|
|
287
345
|
}
|
|
288
346
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/host/server/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { type RSC, visit } from '#internal/host/nextjs/dom-flight';\nimport {\n getSkeletonHtml,\n getSkeletonMessage,\n} from '#internal/host/nextjs/skeleton';\nimport { fetchWithHooks } from '#internal/host/server/fetch-with-hooks';\nimport { getClientSrc } from '#internal/host/server/get-client-src';\nimport {\n DEPLOYMENT_URL,\n getSSRRelativePathBaseUrl,\n PRODUCTION_URL,\n} from '#internal/host/server/get-ssr-relative-path-base-url';\nimport type {\n LinkDescriptor,\n ScriptDescriptor,\n} from '#internal/host/shared/asset-descriptors';\nimport type {\n OnRequestHook,\n OnResponseHook,\n} from '#internal/host/shared/fetch-interceptors';\nimport type { RemoteSharedModules } from '#internal/host/shared/shared-broker';\nimport {\n buildMetadata,\n type RawMetadataAttrs,\n type RemoteComponentMetadata,\n} from '#internal/runtime/metadata';\nimport { importRSCClientEdge } from '#internal/runtime/rsc-imports';\nimport {\n failedToFetchRemoteComponentError,\n multipleRemoteComponentsError,\n RemoteComponentsError,\n} from '#internal/utils/error';\nimport type { FetchRemoteComponentResponse, NextData } from './types';\n\n/**\n * Converts RSC flight data into a React element tree using the edge streaming\n * runtime. The manifest tells React how to resolve module references back to\n * the remote origin.\n */\nasync function buildRscComponent(\n rsc: RSC | RSC[] | string | null,\n serverUrl: URL,\n): Promise<React.ReactNode> {\n const componentRSC = `0:${JSON.stringify(rsc)}\\n`;\n const { createFromReadableStream } = await importRSCClientEdge();\n return createFromReadableStream(\n new ReadableStream({\n type: 'bytes',\n start(controller) {\n const encoder = new TextEncoder();\n controller.enqueue(encoder.encode(componentRSC));\n controller.close();\n },\n }),\n {\n serverConsumerManifest: {\n moduleLoading: {\n prefix: serverUrl.origin,\n crossOrigin: true,\n },\n moduleMap: {},\n },\n },\n );\n}\n\nfunction buildSkeletonResponse(\n serverUrl: URL,\n metadata: RemoteComponentMetadata,\n skeletonComponent: React.ReactNode | undefined,\n): FetchRemoteComponentResponse {\n return {\n name: 'remote-component-skeleton',\n serverUrl,\n metadata: {\n ...metadata,\n type: 'remote-component',\n },\n rsc: getSkeletonMessage(),\n scripts: [],\n links: [],\n hydrationData: [],\n nextData: undefined,\n component: skeletonComponent,\n html: getSkeletonHtml(serverUrl.href),\n remoteShared: {},\n };\n}\n\n/**\n * Walks the parsed HTML fragment and extracts all remote component data:\n * metadata, scripts, links, hydration data, Next.js data, shared deps, and HTML.\n */\nfunction visitFragment(\n fragment: DefaultTreeAdapterMap['documentFragment'],\n serverUrl: URL,\n remoteName: string | undefined,\n) {\n const scriptSrcSet = new Set<string>();\n const scriptTextSet = new Set<string>();\n const scripts: ScriptDescriptor[] = [];\n\n const linkKeySet = new Set<string>();\n const links: LinkDescriptor[] = [];\n\n const hydrationData: string[] = [];\n const htmlChunks = new Set<string>();\n\n let metadata: RemoteComponentMetadata | undefined;\n let nextData: NextData | undefined;\n let remoteShared: RemoteSharedModules = {};\n let hasRSC = false;\n let hasShared = false;\n let error: RemoteComponentsError | undefined;\n\n const rawRscChunks: string[] = [];\n\n const rsc = visit(fragment, {\n url: serverUrl,\n name: remoteName,\n onMetadata(attrs: RawMetadataAttrs) {\n const incoming = buildMetadata(attrs, serverUrl);\n // Skip multiple component detection for Pages Router (__next) since\n // it only supports one remote component per page\n if (\n !remoteName &&\n metadata &&\n metadata.id !== incoming.id &&\n incoming.id !== '__next' &&\n metadata.id !== '__next' &&\n !nextData\n ) {\n throw multipleRemoteComponentsError(serverUrl.href);\n }\n metadata = incoming;\n },\n onScript(attrs) {\n const clientSrc = getClientSrc(attrs.src, serverUrl.href);\n const textContent =\n typeof attrs.textContent === 'string' ? attrs.textContent : undefined;\n\n if (textContent) {\n if (!scriptTextSet.has(textContent)) {\n scriptTextSet.add(textContent);\n scripts.push({ src: '', textContent });\n }\n } else if (!scriptSrcSet.has(clientSrc)) {\n scriptSrcSet.add(clientSrc);\n scripts.push({ src: clientSrc });\n }\n },\n onLink(attrs) {\n const relativeAttrs = {\n ...attrs,\n href: getClientSrc(attrs.href, serverUrl.href),\n };\n const linkKey = `${relativeAttrs.href}::${attrs.rel}`;\n if (!linkKeySet.has(linkKey)) {\n linkKeySet.add(linkKey);\n links.push(relativeAttrs);\n }\n },\n onRSC(chunk) {\n rawRscChunks.push(chunk);\n hasRSC = true;\n },\n onNextData(data) {\n nextData = data;\n },\n onHTML(chunk) {\n if (!htmlChunks.has(chunk)) {\n htmlChunks.add(chunk);\n }\n },\n onShared(_shared) {\n remoteShared = _shared;\n hasShared = true;\n },\n onError(message, stack) {\n error = new RemoteComponentsError(message);\n if (stack) {\n error.stack = stack;\n }\n },\n });\n\n hydrationData.push(...rawRscChunks);\n\n if (error) {\n throw error;\n }\n\n if (metadata) {\n if (!hasRSC && !nextData && metadata.type === 'nextjs') {\n throw new RemoteComponentsError(\n `The Remote Component at \"${serverUrl.href}\" seems to be a Next.js component but it does not contain any RSC flight data or Next.js props data. Make sure the remote URL is correct and contains a Remote Component.`,\n );\n }\n\n if (\n metadata.type === 'nextjs' &&\n !hasShared &&\n !nextData?.props.__REMOTE_COMPONENT__?.sharedManifest &&\n !nextData?.props.__REMOTE_COMPONENT__?.shared\n ) {\n throw new RemoteComponentsError(\n `No shared dependencies found for Remote Component at \"${serverUrl.href}\". Make sure the remote URL is correct and contains a Remote Component with shared dependencies.`,\n );\n }\n }\n\n const resolvedShared =\n nextData?.props.__REMOTE_COMPONENT__?.sharedManifest ??\n // @legacy(remote-components<=0.4.x): keep accepting the Pages Router\n // shared map until remotes on 0.4.x are outside the compatibility window.\n nextData?.props.__REMOTE_COMPONENT__?.shared ??\n remoteShared;\n\n return {\n rsc,\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n remoteShared: resolvedShared,\n html: Array.from(htmlChunks).join(''),\n };\n}\n\ninterface Options {\n name?: string;\n rsc?: boolean;\n /** Whether this is being called from Next.js App Router. Used to enable skeleton fallback during SSG builds. */\n appRouter?: boolean;\n onRequest?: OnRequestHook;\n onResponse?: OnResponseHook;\n}\n\nasync function fetchWithTags(\n src: string | URL,\n relativePathBaseUrl: string,\n options: Options,\n) {\n const serverUrl = new URL(src, relativePathBaseUrl);\n const tags = [\n '_vc_rc:fetch-remote-component',\n // the max size of a next cache tag is 256 characters\n serverUrl.host.slice(0, 256),\n // use the suffix so this tag is unique if multiple remote\n // components have the same host, but unique pathnames / query params\n (typeof src === 'string' ? src : src.href).slice(-256),\n ];\n if (options.name) {\n tags.push(options.name.slice(-256));\n }\n\n const fetchInit = { next: { tags } };\n\n const res = await fetchWithHooks(serverUrl, fetchInit, {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\n });\n\n return {\n res,\n serverUrl,\n // If the remote component is part of a microfrontend, the src provided will be relative.\n isMfeRelativeSrc: serverUrl.host === new URL(relativePathBaseUrl).host,\n };\n}\n\nexport async function fetchRemoteComponent(\n src: string | URL,\n options: Options = {},\n): Promise<FetchRemoteComponentResponse> {\n let { res, isMfeRelativeSrc, serverUrl } = await fetchWithTags(\n src,\n getSSRRelativePathBaseUrl(),\n options,\n );\n\n const maybeFirstMfeProductionDeployment =\n isMfeRelativeSrc && serverUrl.host === PRODUCTION_URL;\n\n // When deploying a microfrontend with remote components to production for the first time, the fetch with the\n // production URL will fail if the production URL is not already an MFE alias. The URL becomes an MFE alias\n // on the first MFE deployment. For this fetch, use the deployment URL which is an MFE alias.\n if (\n res.status === 404 &&\n maybeFirstMfeProductionDeployment &&\n DEPLOYMENT_URL\n ) {\n ({ res, isMfeRelativeSrc, serverUrl } = await fetchWithTags(\n src,\n `https://${DEPLOYMENT_URL}`,\n options,\n ));\n }\n\n // If there is an error in the remote, parse and extract the remote error (except 404 and 401).\n if (!res.ok && !res.body) {\n throw failedToFetchRemoteComponentError(serverUrl.href, res);\n }\n\n if (res.status === 401) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n 'If you are using Deployment Protection, ensure the automation bypass environment variable secret in the host matches an automation bypass value in the remote. See https://remote-components-docs.vercel.sh/docs/concepts/cors-external-urls#deployment-protection for details.',\n );\n }\n\n if (res.status === 404) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n maybeFirstMfeProductionDeployment\n ? `If this is the first production build of a microfrontends setup, try redeploying once the remote is deployed to production. Once deployed, this error will not re-occur, and ISR revalidation will happen automatically for remote components once they deploy. https://remote-components-docs.vercel.sh/docs/concepts/isr-deployment`\n : `Check if you can open it in the browser.`,\n );\n }\n\n if (!res.body) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n `Response body is empty. Check if you can open it in the browser and you see the Remote Component content.`,\n );\n }\n\n const parser = Parser.getFragmentParser<DefaultTreeAdapterMap>();\n const decoder = new TextDecoder();\n // read the response body as a stream and parse it using the parse5 fragment parser\n for await (const chunk of res.body as unknown as AsyncIterable<Uint8Array>) {\n parser.tokenizer.write(decoder.decode(chunk), false);\n }\n const fragment = parser.getFragment();\n\n const remoteName =\n options.name || (serverUrl.hash ? serverUrl.hash.substring(1) : undefined);\n\n const {\n rsc,\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n remoteShared,\n html,\n } = visitFragment(fragment, serverUrl, remoteName);\n\n if (!metadata) {\n // For microfrontend builds during run time, the host and remote build\n // may be happening concurrently. In this case, the request will 404.\n // We want to allow the build to continue with a placeholder remote\n // component. Once the build completes, vercel will automatically revalidate\n // ISR and fetch the built remote component.\n const isSSGBuild = process.env.NEXT_PHASE === 'phase-production-build';\n // Only want this skeleton behaviour in previews to unblock development.\n // For production, the remote component should already be built.\n const isPreview = process.env.VERCEL_TARGET_ENV === 'preview';\n // For app router previews, the host and remote build at the same time, to allow this, render a skeleton\n // in the host if the remote is not found, which will revalidate when the remote deploys, or give a helpful error in the UI\n if (isSSGBuild && isMfeRelativeSrc && isPreview && options.appRouter) {\n let skeletonComponent: React.ReactNode | undefined;\n if (options.rsc) {\n const { createElement } = await import('react');\n skeletonComponent = createElement('div', {\n dangerouslySetInnerHTML: {\n __html: getSkeletonHtml(serverUrl.href),\n },\n });\n }\n\n return buildSkeletonResponse(\n serverUrl,\n buildMetadata({}, serverUrl),\n skeletonComponent,\n );\n }\n\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n `No Remote Component found. Make sure the remote URL is correct and contains a Remote Component.`,\n );\n }\n\n const name = remoteName || metadata.name;\n const component = options.rsc\n ? await buildRscComponent(rsc, serverUrl)\n : undefined;\n\n return {\n name,\n serverUrl,\n metadata,\n rsc,\n scripts,\n links,\n hydrationData,\n nextData,\n component,\n html,\n remoteShared,\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/server/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { type RSC, visit } from '#internal/host/nextjs/dom-flight';\nimport {\n getSkeletonHtml,\n getSkeletonMessage,\n} from '#internal/host/nextjs/skeleton';\nimport { fetchWithHooks } from '#internal/host/server/fetch-with-hooks';\nimport { getClientSrc } from '#internal/host/server/get-client-src';\nimport {\n DEPLOYMENT_URL,\n getSSRRelativePathBaseUrl,\n PRODUCTION_URL,\n} from '#internal/host/server/get-ssr-relative-path-base-url';\nimport type {\n LinkDescriptor,\n ScriptDescriptor,\n} from '#internal/host/shared/asset-descriptors';\nimport type {\n OnRequestHook,\n OnResponseHook,\n} from '#internal/host/shared/fetch-interceptors';\nimport {\n extractDeploymentIdFromSrc,\n isNextDeploymentAssetSrc,\n type NextImageDeploymentId,\n} from '#internal/host/shared/next-image-deployment-id';\nimport type { RemoteSharedModules } from '#internal/host/shared/shared-broker';\nimport {\n buildMetadata,\n type RawMetadataAttrs,\n type RemoteComponentMetadata,\n} from '#internal/runtime/metadata';\nimport { importRSCClientEdge } from '#internal/runtime/rsc-imports';\nimport {\n failedToFetchRemoteComponentError,\n multipleRemoteComponentsError,\n RemoteComponentsError,\n} from '#internal/utils/error';\nimport type { FetchRemoteComponentResponse, NextData } from './types';\n\nconst NEXT_IMAGE_PATHNAME = '/_next/image';\n/**\n * Converts RSC flight data into a React element tree using the edge streaming\n * runtime. The manifest tells React how to resolve module references back to\n * the remote origin.\n */\nasync function buildRscComponent(\n rsc: RSC | RSC[] | string | null,\n serverUrl: URL,\n): Promise<React.ReactNode> {\n const componentRSC = `0:${JSON.stringify(rsc)}\\n`;\n const { createFromReadableStream } = await importRSCClientEdge();\n return createFromReadableStream(\n new ReadableStream({\n type: 'bytes',\n start(controller) {\n const encoder = new TextEncoder();\n controller.enqueue(encoder.encode(componentRSC));\n controller.close();\n },\n }),\n {\n serverConsumerManifest: {\n moduleLoading: {\n prefix: serverUrl.origin,\n crossOrigin: true,\n },\n moduleMap: {},\n },\n },\n );\n}\n\nfunction buildSkeletonResponse(\n serverUrl: URL,\n metadata: RemoteComponentMetadata,\n skeletonComponent: React.ReactNode | undefined,\n): FetchRemoteComponentResponse {\n return {\n name: 'remote-component-skeleton',\n serverUrl,\n metadata: {\n ...metadata,\n type: 'remote-component',\n },\n rsc: getSkeletonMessage(),\n scripts: [],\n links: [],\n hydrationData: [],\n nextData: undefined,\n component: skeletonComponent,\n html: getSkeletonHtml(serverUrl.href),\n remoteShared: {},\n ssrImageDeploymentIds: [],\n };\n}\n\nfunction getNextImageDeploymentId(\n value: string,\n base: URL,\n): NextImageDeploymentId | undefined {\n try {\n const parsed = new URL(value.replace(/&/g, '&'), base);\n const imageSrc = parsed.searchParams.get('url');\n if (\n !parsed.pathname.endsWith(NEXT_IMAGE_PATHNAME) ||\n !isNextDeploymentAssetSrc(imageSrc)\n ) {\n return undefined;\n }\n\n const extracted = extractDeploymentIdFromSrc(imageSrc);\n const deploymentId =\n parsed.searchParams.get('dpl') || extracted.deploymentId;\n\n return deploymentId ? { src: extracted.src, deploymentId } : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction addNextImageDeploymentId(\n value: string | undefined,\n serverUrl: URL,\n result: Map<string, string>,\n) {\n if (!value) {\n return;\n }\n\n const image = getNextImageDeploymentId(value, serverUrl);\n if (image) {\n result.set(image.src, image.deploymentId);\n }\n}\n\nfunction addNextImageDeploymentIdsFromSrcset(\n value: string | undefined,\n serverUrl: URL,\n result: Map<string, string>,\n) {\n if (!value) return;\n for (const candidate of value.split(',')) {\n addNextImageDeploymentId(\n candidate.trim().split(/\\s+/)[0],\n serverUrl,\n result,\n );\n }\n}\n\n/**\n * Walks the parsed HTML fragment and extracts all remote component data:\n * metadata, scripts, links, hydration data, Next.js data, shared deps, and HTML.\n */\nfunction visitFragment(\n fragment: DefaultTreeAdapterMap['documentFragment'],\n serverUrl: URL,\n remoteName: string | undefined,\n) {\n const scriptSrcSet = new Set<string>();\n const scriptTextSet = new Set<string>();\n const scripts: ScriptDescriptor[] = [];\n\n const linkKeySet = new Set<string>();\n const links: LinkDescriptor[] = [];\n\n const hydrationData: string[] = [];\n const htmlChunks = new Set<string>();\n const ssrImageDeploymentIdMap = new Map<string, string>();\n\n let metadata: RemoteComponentMetadata | undefined;\n let nextData: NextData | undefined;\n let remoteShared: RemoteSharedModules = {};\n let hasRSC = false;\n let hasShared = false;\n let error: RemoteComponentsError | undefined;\n\n const rawRscChunks: string[] = [];\n\n const rsc = visit(fragment, {\n url: serverUrl,\n name: remoteName,\n onMetadata(attrs: RawMetadataAttrs) {\n const incoming = buildMetadata(attrs, serverUrl);\n // Skip multiple component detection for Pages Router (__next) since\n // it only supports one remote component per page\n if (\n !remoteName &&\n metadata &&\n metadata.id !== incoming.id &&\n incoming.id !== '__next' &&\n metadata.id !== '__next' &&\n !nextData\n ) {\n throw multipleRemoteComponentsError(serverUrl.href);\n }\n metadata = incoming;\n },\n onScript(attrs) {\n const clientSrc = getClientSrc(attrs.src, serverUrl.href);\n const textContent =\n typeof attrs.textContent === 'string' ? attrs.textContent : undefined;\n\n if (textContent) {\n if (!scriptTextSet.has(textContent)) {\n scriptTextSet.add(textContent);\n scripts.push({ src: '', textContent });\n }\n } else if (!scriptSrcSet.has(clientSrc)) {\n scriptSrcSet.add(clientSrc);\n scripts.push({ src: clientSrc });\n }\n },\n onLink(attrs) {\n const relativeAttrs = {\n ...attrs,\n href: getClientSrc(attrs.href, serverUrl.href),\n };\n const linkKey = `${relativeAttrs.href}::${attrs.rel}`;\n if (!linkKeySet.has(linkKey)) {\n linkKeySet.add(linkKey);\n links.push(relativeAttrs);\n }\n },\n onRSC(chunk) {\n rawRscChunks.push(chunk);\n hasRSC = true;\n },\n onNextData(data) {\n nextData = data;\n },\n onHTML(chunk) {\n if (!htmlChunks.has(chunk)) {\n htmlChunks.add(chunk);\n }\n },\n onShared(_shared) {\n remoteShared = _shared;\n hasShared = true;\n },\n onError(message, stack) {\n error = new RemoteComponentsError(message);\n if (stack) {\n error.stack = stack;\n }\n },\n onElement(nodeName, attrs) {\n if (nodeName !== 'img') {\n return;\n }\n\n addNextImageDeploymentId(attrs.src, serverUrl, ssrImageDeploymentIdMap);\n addNextImageDeploymentIdsFromSrcset(\n attrs.srcset,\n serverUrl,\n ssrImageDeploymentIdMap,\n );\n },\n });\n\n hydrationData.push(...rawRscChunks);\n\n if (error) {\n throw error;\n }\n\n if (metadata) {\n if (!hasRSC && !nextData && metadata.type === 'nextjs') {\n throw new RemoteComponentsError(\n `The Remote Component at \"${serverUrl.href}\" seems to be a Next.js component but it does not contain any RSC flight data or Next.js props data. Make sure the remote URL is correct and contains a Remote Component.`,\n );\n }\n\n if (\n metadata.type === 'nextjs' &&\n !hasShared &&\n !nextData?.props.__REMOTE_COMPONENT__?.sharedManifest &&\n !nextData?.props.__REMOTE_COMPONENT__?.shared\n ) {\n throw new RemoteComponentsError(\n `No shared dependencies found for Remote Component at \"${serverUrl.href}\". Make sure the remote URL is correct and contains a Remote Component with shared dependencies.`,\n );\n }\n }\n\n const resolvedShared =\n nextData?.props.__REMOTE_COMPONENT__?.sharedManifest ??\n // @legacy(remote-components<=0.4.x): keep accepting the Pages Router\n // shared map until remotes on 0.4.x are outside the compatibility window.\n nextData?.props.__REMOTE_COMPONENT__?.shared ??\n remoteShared;\n\n return {\n rsc,\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n remoteShared: resolvedShared,\n ssrImageDeploymentIds: Array.from(\n ssrImageDeploymentIdMap,\n ([src, deploymentId]) => ({ src, deploymentId }),\n ),\n html: Array.from(htmlChunks).join(''),\n };\n}\n\ninterface Options {\n name?: string;\n rsc?: boolean;\n /** Whether this is being called from Next.js App Router. Used to enable skeleton fallback during SSG builds. */\n appRouter?: boolean;\n onRequest?: OnRequestHook;\n onResponse?: OnResponseHook;\n}\n\nasync function fetchWithTags(\n src: string | URL,\n relativePathBaseUrl: string,\n options: Options,\n) {\n const serverUrl = new URL(src, relativePathBaseUrl);\n const tags = [\n '_vc_rc:fetch-remote-component',\n // the max size of a next cache tag is 256 characters\n serverUrl.host.slice(0, 256),\n // use the suffix so this tag is unique if multiple remote\n // components have the same host, but unique pathnames / query params\n (typeof src === 'string' ? src : src.href).slice(-256),\n ];\n if (options.name) {\n tags.push(options.name.slice(-256));\n }\n\n const fetchInit = { next: { tags } };\n\n const res = await fetchWithHooks(serverUrl, fetchInit, {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\n });\n\n return {\n res,\n serverUrl,\n // If the remote component is part of a microfrontend, the src provided will be relative.\n isMfeRelativeSrc: serverUrl.host === new URL(relativePathBaseUrl).host,\n };\n}\n\nexport async function fetchRemoteComponent(\n src: string | URL,\n options: Options = {},\n): Promise<FetchRemoteComponentResponse> {\n let { res, isMfeRelativeSrc, serverUrl } = await fetchWithTags(\n src,\n getSSRRelativePathBaseUrl(),\n options,\n );\n\n const maybeFirstMfeProductionDeployment =\n isMfeRelativeSrc && serverUrl.host === PRODUCTION_URL;\n\n // When deploying a microfrontend with remote components to production for the first time, the fetch with the\n // production URL will fail if the production URL is not already an MFE alias. The URL becomes an MFE alias\n // on the first MFE deployment. For this fetch, use the deployment URL which is an MFE alias.\n if (\n res.status === 404 &&\n maybeFirstMfeProductionDeployment &&\n DEPLOYMENT_URL\n ) {\n ({ res, isMfeRelativeSrc, serverUrl } = await fetchWithTags(\n src,\n `https://${DEPLOYMENT_URL}`,\n options,\n ));\n }\n\n // If there is an error in the remote, parse and extract the remote error (except 404 and 401).\n if (!res.ok && !res.body) {\n throw failedToFetchRemoteComponentError(serverUrl.href, res);\n }\n\n if (res.status === 401) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n 'If you are using Deployment Protection, ensure the automation bypass environment variable secret in the host matches an automation bypass value in the remote. See https://remote-components-docs.vercel.sh/docs/concepts/cors-external-urls#deployment-protection for details.',\n );\n }\n\n if (res.status === 404) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n maybeFirstMfeProductionDeployment\n ? `If this is the first production build of a microfrontends setup, try redeploying once the remote is deployed to production. Once deployed, this error will not re-occur, and ISR revalidation will happen automatically for remote components once they deploy. https://remote-components-docs.vercel.sh/docs/concepts/isr-deployment`\n : `Check if you can open it in the browser.`,\n );\n }\n\n if (!res.body) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n `Response body is empty. Check if you can open it in the browser and you see the Remote Component content.`,\n );\n }\n\n const parser = Parser.getFragmentParser<DefaultTreeAdapterMap>();\n const decoder = new TextDecoder();\n // read the response body as a stream and parse it using the parse5 fragment parser\n for await (const chunk of res.body as unknown as AsyncIterable<Uint8Array>) {\n parser.tokenizer.write(decoder.decode(chunk), false);\n }\n const fragment = parser.getFragment();\n\n const remoteName =\n options.name || (serverUrl.hash ? serverUrl.hash.substring(1) : undefined);\n\n const {\n rsc,\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n remoteShared,\n html,\n ssrImageDeploymentIds,\n } = visitFragment(fragment, serverUrl, remoteName);\n\n if (!metadata) {\n // For microfrontend builds during run time, the host and remote build\n // may be happening concurrently. In this case, the request will 404.\n // We want to allow the build to continue with a placeholder remote\n // component. Once the build completes, vercel will automatically revalidate\n // ISR and fetch the built remote component.\n const isSSGBuild = process.env.NEXT_PHASE === 'phase-production-build';\n // Only want this skeleton behaviour in previews to unblock development.\n // For production, the remote component should already be built.\n const isPreview = process.env.VERCEL_TARGET_ENV === 'preview';\n // For app router previews, the host and remote build at the same time, to allow this, render a skeleton\n // in the host if the remote is not found, which will revalidate when the remote deploys, or give a helpful error in the UI\n if (isSSGBuild && isMfeRelativeSrc && isPreview && options.appRouter) {\n let skeletonComponent: React.ReactNode | undefined;\n if (options.rsc) {\n const { createElement } = await import('react');\n skeletonComponent = createElement('div', {\n dangerouslySetInnerHTML: {\n __html: getSkeletonHtml(serverUrl.href),\n },\n });\n }\n\n return buildSkeletonResponse(\n serverUrl,\n buildMetadata({}, serverUrl),\n skeletonComponent,\n );\n }\n\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n `No Remote Component found. Make sure the remote URL is correct and contains a Remote Component.`,\n );\n }\n\n const name = remoteName || metadata.name;\n const component = options.rsc\n ? await buildRscComponent(rsc, serverUrl)\n : undefined;\n\n return {\n name,\n serverUrl,\n metadata,\n rsc,\n scripts,\n links,\n hydrationData,\n nextData,\n component,\n html,\n remoteShared,\n ssrImageDeploymentIds,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/host/server/types.ts"],"sourcesContent":["import type {\n LinkDescriptor,\n ScriptDescriptor,\n} from '#internal/host/shared/asset-descriptors';\nimport type {\n RemoteSharedModules,\n SharedModuleManifest,\n} from '#internal/host/shared/shared-broker';\nimport type { RemoteComponentMetadata } from '#internal/runtime/metadata';\n\nexport type {\n InternalResolveClientUrl,\n ResolveClientUrl,\n} from '#internal/runtime/url/resolve-client-url';\n\nexport interface NextData {\n props: {\n pageProps: Record<string, unknown>;\n __REMOTE_COMPONENT__?: {\n bundle: string;\n runtime: string;\n shared?: Record<string, string>;\n sharedManifest?: SharedModuleManifest;\n };\n };\n page?: string;\n buildId?: string;\n}\n\nexport interface FetchRemoteComponentResponse {\n name: string;\n serverUrl: URL;\n metadata: RemoteComponentMetadata;\n rsc:\n | import('#internal/host/nextjs/dom-flight').RSC\n | import('#internal/host/nextjs/dom-flight').RSC[]\n | string\n | null;\n scripts: ScriptDescriptor[];\n links: LinkDescriptor[];\n hydrationData: string[];\n nextData: NextData | undefined;\n component: React.ReactNode | undefined;\n html: string;\n remoteShared: RemoteSharedModules;\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/server/types.ts"],"sourcesContent":["import type {\n LinkDescriptor,\n ScriptDescriptor,\n} from '#internal/host/shared/asset-descriptors';\nimport type { NextImageDeploymentId } from '#internal/host/shared/next-image-deployment-id';\nimport type {\n RemoteSharedModules,\n SharedModuleManifest,\n} from '#internal/host/shared/shared-broker';\nimport type { RemoteComponentMetadata } from '#internal/runtime/metadata';\n\nexport type {\n InternalResolveClientUrl,\n ResolveClientUrl,\n} from '#internal/runtime/url/resolve-client-url';\n\nexport interface NextData {\n props: {\n pageProps: Record<string, unknown>;\n __REMOTE_COMPONENT__?: {\n bundle: string;\n runtime: string;\n shared?: Record<string, string>;\n sharedManifest?: SharedModuleManifest;\n };\n };\n page?: string;\n buildId?: string;\n}\n\nexport interface FetchRemoteComponentResponse {\n name: string;\n serverUrl: URL;\n metadata: RemoteComponentMetadata;\n rsc:\n | import('#internal/host/nextjs/dom-flight').RSC\n | import('#internal/host/nextjs/dom-flight').RSC[]\n | string\n | null;\n scripts: ScriptDescriptor[];\n links: LinkDescriptor[];\n hydrationData: string[];\n nextData: NextData | undefined;\n component: React.ReactNode | undefined;\n html: string;\n remoteShared: RemoteSharedModules;\n ssrImageDeploymentIds: NextImageDeploymentId[];\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RSC } from '../nextjs/dom-flight.js';
|
|
2
2
|
import { ScriptDescriptor, LinkDescriptor } from '../shared/asset-descriptors.js';
|
|
3
|
+
import { NextImageDeploymentId } from '../shared/next-image-deployment-id.js';
|
|
3
4
|
import { SharedModuleManifest, RemoteSharedModules } from '../shared/shared-broker.js';
|
|
4
5
|
import { RemoteComponentMetadata } from '../../runtime/metadata.js';
|
|
5
6
|
export { InternalResolveClientUrl, ResolveClientUrl } from '../../runtime/url/resolve-client-url.js';
|
|
@@ -31,6 +32,7 @@ interface FetchRemoteComponentResponse {
|
|
|
31
32
|
component: React.ReactNode | undefined;
|
|
32
33
|
html: string;
|
|
33
34
|
remoteShared: RemoteSharedModules;
|
|
35
|
+
ssrImageDeploymentIds: NextImageDeploymentId[];
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
export { FetchRemoteComponentResponse, NextData };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var next_image_deployment_id_exports = {};
|
|
20
|
+
__export(next_image_deployment_id_exports, {
|
|
21
|
+
extractDeploymentIdFromSrc: () => extractDeploymentIdFromSrc,
|
|
22
|
+
isNextDeploymentAssetSrc: () => isNextDeploymentAssetSrc
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(next_image_deployment_id_exports);
|
|
25
|
+
function isNextDeploymentAssetSrc(src) {
|
|
26
|
+
return typeof src === "string" && src.startsWith("/") && !src.startsWith("//");
|
|
27
|
+
}
|
|
28
|
+
function extractDeploymentIdFromSrc(src) {
|
|
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
|
+
}
|
|
45
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
46
|
+
0 && (module.exports = {
|
|
47
|
+
extractDeploymentIdFromSrc,
|
|
48
|
+
isNextDeploymentAssetSrc
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=next-image-deployment-id.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/shared/next-image-deployment-id.ts"],"sourcesContent":["export interface NextImageDeploymentId {\n src: string;\n deploymentId: string;\n}\n\nexport function isNextDeploymentAssetSrc(src: string | null): src is string {\n return (\n typeof src === 'string' && src.startsWith('/') && !src.startsWith('//')\n );\n}\n\nexport function extractDeploymentIdFromSrc(src: string) {\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"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKO,SAAS,yBAAyB,KAAmC;AAC1E,SACE,OAAO,QAAQ,YAAY,IAAI,WAAW,GAAG,KAAK,CAAC,IAAI,WAAW,IAAI;AAE1E;AAEO,SAAS,2BAA2B,KAAa;AACtD,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;","names":[]}
|