remote-components 0.0.31 → 0.0.33
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/{component-loader-e5513139.d.ts → component-loader-28ad0083.d.ts} +1 -0
- package/dist/html/host.cjs +152 -56
- package/dist/html/host.cjs.map +1 -1
- package/dist/html/host.js +152 -56
- package/dist/html/host.js.map +1 -1
- package/dist/internal/next/host/app-router-client.cjs +6 -2
- package/dist/internal/next/host/app-router-client.cjs.map +1 -1
- package/dist/internal/next/host/app-router-client.d.ts +2 -2
- package/dist/internal/next/host/app-router-client.js +6 -2
- package/dist/internal/next/host/app-router-client.js.map +1 -1
- package/dist/internal/next/remote/render-client.cjs +13 -3
- package/dist/internal/next/remote/render-client.cjs.map +1 -1
- package/dist/internal/next/remote/render-client.js +13 -3
- package/dist/internal/next/remote/render-client.js.map +1 -1
- package/dist/internal/next/remote/render-server.cjs +22 -3
- package/dist/internal/next/remote/render-server.cjs.map +1 -1
- package/dist/internal/next/remote/render-server.js +23 -4
- package/dist/internal/next/remote/render-server.js.map +1 -1
- package/dist/internal/shared/client/remote-component.cjs +82 -45
- package/dist/internal/shared/client/remote-component.cjs.map +1 -1
- package/dist/internal/shared/client/remote-component.d.ts +9 -2
- package/dist/internal/shared/client/remote-component.js +81 -45
- package/dist/internal/shared/client/remote-component.js.map +1 -1
- package/dist/internal/shared/error.cjs +50 -0
- package/dist/internal/shared/error.cjs.map +1 -0
- package/dist/internal/shared/error.d.ts +10 -0
- package/dist/internal/shared/error.js +24 -0
- package/dist/internal/shared/error.js.map +1 -0
- package/dist/internal/shared/ssr/dom-flight.cjs +8 -1
- package/dist/internal/shared/ssr/dom-flight.cjs.map +1 -1
- package/dist/internal/shared/ssr/dom-flight.d.ts +2 -1
- package/dist/internal/shared/ssr/dom-flight.js +8 -1
- package/dist/internal/shared/ssr/dom-flight.js.map +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.cjs +48 -5
- package/dist/internal/shared/ssr/fetch-remote-component.cjs.map +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.d.ts +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.js +52 -5
- package/dist/internal/shared/ssr/fetch-remote-component.js.map +1 -1
- package/dist/internal/webpack/next-client-pages-loader.cjs +3 -2
- package/dist/internal/webpack/next-client-pages-loader.cjs.map +1 -1
- package/dist/internal/webpack/next-client-pages-loader.js +3 -2
- package/dist/internal/webpack/next-client-pages-loader.js.map +1 -1
- package/dist/next/config.cjs +26 -9
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.js +26 -9
- package/dist/next/config.js.map +1 -1
- package/dist/next/host/client/index.cjs +133 -57
- package/dist/next/host/client/index.cjs.map +1 -1
- package/dist/next/host/client/index.d.ts +1 -1
- package/dist/next/host/client/index.js +133 -57
- package/dist/next/host/client/index.js.map +1 -1
- package/dist/next/host/pages-router-client.cjs +1 -1
- package/dist/next/host/pages-router-client.cjs.map +1 -1
- package/dist/next/host/pages-router-client.js +1 -1
- package/dist/next/host/pages-router-client.js.map +1 -1
- package/dist/next/host/pages-router-server.cjs +4 -3
- package/dist/next/host/pages-router-server.cjs.map +1 -1
- package/dist/next/host/pages-router-server.js +4 -3
- package/dist/next/host/pages-router-server.js.map +1 -1
- package/dist/next/index.cjs +4 -2
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.js +4 -2
- package/dist/next/index.js.map +1 -1
- package/dist/next/remote/pages-router.cjs +1 -1
- package/dist/next/remote/pages-router.cjs.map +1 -1
- package/dist/next/remote/pages-router.js +1 -1
- package/dist/next/remote/pages-router.js.map +1 -1
- package/dist/react/index.cjs +42 -11
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +46 -11
- package/dist/react/index.js.map +1 -1
- package/dist/shared/host/app.cjs +36 -0
- package/dist/shared/host/app.cjs.map +1 -0
- package/dist/shared/host/app.d.ts +3 -0
- package/dist/shared/host/app.js +12 -0
- package/dist/shared/host/app.js.map +1 -0
- package/dist/shared/host/pages.cjs +36 -0
- package/dist/shared/host/pages.cjs.map +1 -0
- package/dist/shared/host/pages.d.ts +3 -0
- package/dist/shared/host/pages.js +12 -0
- package/dist/shared/host/pages.js.map +1 -0
- package/dist/shared/remote/app.cjs +32 -0
- package/dist/shared/remote/app.cjs.map +1 -0
- package/dist/shared/remote/app.d.ts +3 -0
- package/dist/shared/remote/app.js +8 -0
- package/dist/shared/remote/app.js.map +1 -0
- package/dist/shared/remote/pages.cjs +32 -0
- package/dist/shared/remote/pages.cjs.map +1 -0
- package/dist/shared/remote/pages.d.ts +3 -0
- package/dist/shared/remote/pages.js +8 -0
- package/dist/shared/remote/pages.js.map +1 -0
- package/dist/shared/remote/wrapper.cjs +48 -0
- package/dist/shared/remote/wrapper.cjs.map +1 -0
- package/dist/shared/remote/wrapper.d.ts +2 -0
- package/dist/shared/remote/wrapper.js +25 -0
- package/dist/shared/remote/wrapper.js.map +1 -0
- package/dist/{types-b8210fd3.d.ts → types-7c207455.d.ts} +1 -1
- package/dist/{types-280a3640.d.ts → types-e4a3fa37.d.ts} +1 -0
- package/package.json +37 -1
|
@@ -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 error_exports = {};
|
|
20
|
+
__export(error_exports, {
|
|
21
|
+
RemoteComponentsError: () => RemoteComponentsError,
|
|
22
|
+
failedToFetchRemoteComponentError: () => failedToFetchRemoteComponentError,
|
|
23
|
+
multipleRemoteComponentsError: () => multipleRemoteComponentsError
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(error_exports);
|
|
26
|
+
class RemoteComponentsError extends Error {
|
|
27
|
+
constructor(message, options) {
|
|
28
|
+
super(message, options);
|
|
29
|
+
this.code = "REMOTE_COMPONENTS_ERROR";
|
|
30
|
+
this.name = "RemoteComponentsError";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function multipleRemoteComponentsError(url) {
|
|
34
|
+
return new Error(
|
|
35
|
+
`Multiple Remote Components found at "${url}". When a page exposes multiple Remote Components you must specify the "name" prop to select which one to load.`
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
function failedToFetchRemoteComponentError(url, error) {
|
|
39
|
+
return new RemoteComponentsError(
|
|
40
|
+
`Failed to fetch Remote Component from "${url}". Is the URL correct and accessible?`,
|
|
41
|
+
{ cause: error instanceof Error ? error : new Error(String(error)) }
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
45
|
+
0 && (module.exports = {
|
|
46
|
+
RemoteComponentsError,
|
|
47
|
+
failedToFetchRemoteComponentError,
|
|
48
|
+
multipleRemoteComponentsError
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=error.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/error.ts"],"sourcesContent":["export class RemoteComponentsError extends Error {\n code = 'REMOTE_COMPONENTS_ERROR';\n\n constructor(message: string, options?: { cause?: Error }) {\n super(message, options);\n this.name = 'RemoteComponentsError';\n }\n}\n\nexport function multipleRemoteComponentsError(url: string | undefined) {\n return new Error(\n `Multiple Remote Components found at \"${url}\". When a page exposes multiple Remote Components you must specify the \"name\" prop to select which one to load.`,\n );\n}\n\nexport function failedToFetchRemoteComponentError(url: string, error: unknown) {\n return new RemoteComponentsError(\n `Failed to fetch Remote Component from \"${url}\". Is the URL correct and accessible?`,\n { cause: error instanceof Error ? error : new Error(String(error)) },\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,8BAA8B,MAAM;AAAA,EAG/C,YAAY,SAAiB,SAA6B;AACxD,UAAM,SAAS,OAAO;AAHxB,gBAAO;AAIL,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,8BAA8B,KAAyB;AACrE,SAAO,IAAI;AAAA,IACT,wCAAwC;AAAA,EAC1C;AACF;AAEO,SAAS,kCAAkC,KAAa,OAAgB;AAC7E,SAAO,IAAI;AAAA,IACT,0CAA0C;AAAA,IAC1C,EAAE,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,EAAE;AAAA,EACrE;AACF;","names":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare class RemoteComponentsError extends Error {
|
|
2
|
+
code: string;
|
|
3
|
+
constructor(message: string, options?: {
|
|
4
|
+
cause?: Error;
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
declare function multipleRemoteComponentsError(url: string | undefined): Error;
|
|
8
|
+
declare function failedToFetchRemoteComponentError(url: string, error: unknown): RemoteComponentsError;
|
|
9
|
+
|
|
10
|
+
export { RemoteComponentsError, failedToFetchRemoteComponentError, multipleRemoteComponentsError };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class RemoteComponentsError extends Error {
|
|
2
|
+
constructor(message, options) {
|
|
3
|
+
super(message, options);
|
|
4
|
+
this.code = "REMOTE_COMPONENTS_ERROR";
|
|
5
|
+
this.name = "RemoteComponentsError";
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
function multipleRemoteComponentsError(url) {
|
|
9
|
+
return new Error(
|
|
10
|
+
`Multiple Remote Components found at "${url}". When a page exposes multiple Remote Components you must specify the "name" prop to select which one to load.`
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
function failedToFetchRemoteComponentError(url, error) {
|
|
14
|
+
return new RemoteComponentsError(
|
|
15
|
+
`Failed to fetch Remote Component from "${url}". Is the URL correct and accessible?`,
|
|
16
|
+
{ cause: error instanceof Error ? error : new Error(String(error)) }
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
RemoteComponentsError,
|
|
21
|
+
failedToFetchRemoteComponentError,
|
|
22
|
+
multipleRemoteComponentsError
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/error.ts"],"sourcesContent":["export class RemoteComponentsError extends Error {\n code = 'REMOTE_COMPONENTS_ERROR';\n\n constructor(message: string, options?: { cause?: Error }) {\n super(message, options);\n this.name = 'RemoteComponentsError';\n }\n}\n\nexport function multipleRemoteComponentsError(url: string | undefined) {\n return new Error(\n `Multiple Remote Components found at \"${url}\". When a page exposes multiple Remote Components you must specify the \"name\" prop to select which one to load.`,\n );\n}\n\nexport function failedToFetchRemoteComponentError(url: string, error: unknown) {\n return new RemoteComponentsError(\n `Failed to fetch Remote Component from \"${url}\". Is the URL correct and accessible?`,\n { cause: error instanceof Error ? error : new Error(String(error)) },\n );\n}\n"],"mappings":"AAAO,MAAM,8BAA8B,MAAM;AAAA,EAG/C,YAAY,SAAiB,SAA6B;AACxD,UAAM,SAAS,OAAO;AAHxB,gBAAO;AAIL,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,8BAA8B,KAAyB;AACrE,SAAO,IAAI;AAAA,IACT,wCAAwC;AAAA,EAC1C;AACF;AAEO,SAAS,kCAAkC,KAAa,OAAgB;AAC7E,SAAO,IAAI;AAAA,IACT,0CAA0C;AAAA,IAC1C,EAAE,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,EAAE;AAAA,EACrE;AACF;","names":[]}
|
|
@@ -61,6 +61,12 @@ function visit(node, context = {
|
|
|
61
61
|
return acc;
|
|
62
62
|
}, {});
|
|
63
63
|
}
|
|
64
|
+
if (node.nodeName === "template" && node.attrsObj?.["data-next-error-message"]) {
|
|
65
|
+
context.onError?.(
|
|
66
|
+
node.attrsObj["data-next-error-message"],
|
|
67
|
+
node.attrsObj["data-next-error-stack"]
|
|
68
|
+
);
|
|
69
|
+
}
|
|
64
70
|
if (applyOriginToNodes.includes(node.nodeName.toLowerCase()) && "attrs" in node) {
|
|
65
71
|
const origin = context.origin ?? context.url.origin;
|
|
66
72
|
const src = node.attrsObj?.src;
|
|
@@ -214,7 +220,8 @@ function visit(node, context = {
|
|
|
214
220
|
bundle: node.attrsObj?.["data-bundle"] ?? "default",
|
|
215
221
|
route: node.attrsObj?.["data-route"] ?? "/",
|
|
216
222
|
runtime: node.attrsObj?.["data-runtime"] ?? "webpack",
|
|
217
|
-
id: nodeId?.endsWith("_ssr") ? nodeId : "__vercel_remote_component"
|
|
223
|
+
id: nodeId?.endsWith("_ssr") ? nodeId : "__vercel_remote_component",
|
|
224
|
+
type: node.attrsObj?.["data-type"] || "unknown"
|
|
218
225
|
});
|
|
219
226
|
context.onHTML?.((0, import_parse5.serializeOuter)(node));
|
|
220
227
|
return node.childNodes.reduce((acc, childNode) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/shared/ssr/dom-flight.ts"],"sourcesContent":["import { isCustomAttribute, possibleStandardNames } from 'react-property';\nimport styleToJs from 'style-to-js';\nimport type {\n ChildNode,\n Element,\n Node,\n TextNode,\n} from 'parse5/dist/tree-adapters/default';\nimport { serializeOuter } from 'parse5';\nimport type { RemoteComponentMetadata } from './types';\n\n// add fetch-priority to the possible standard names\npossibleStandardNames.fetchpriority = 'fetchPriority';\npossibleStandardNames['data-precedence'] = 'precedence';\n\nexport interface Context {\n name?: string;\n url: URL;\n origin?: string;\n defer?: boolean;\n active?: boolean;\n visitedRSCNodes?: Set<Node>;\n visitedNonActiveNodes?: Set<Node>;\n onMetadata?: (metadata: RemoteComponentMetadata) => void;\n onScript?: (attrs: Record<string, string | boolean>) => void;\n onLink?: (attrs: Record<string, string | boolean>) => void;\n onRSC?: (rsc: string) => void;\n onNextData?: (data: {\n props: {\n pageProps: Record<string, unknown>;\n __REMOTE_COMPONENT__?: {\n bundle: string;\n runtime: string;\n };\n };\n page?: string;\n }) => void;\n onHTML?: (html: string) => void;\n onShared?: (shared: Record<string, string>) => void;\n}\n\ntype RSC =\n | ['$', string, null, Record<string, unknown>, null, null, number]\n | (\n | ['$', string, null, Record<string, unknown>, null, null, number]\n | string\n | null\n )[]\n | string\n | null;\n\nconst applyOriginToNodes = [\n 'img',\n 'source',\n 'video',\n 'audio',\n 'track',\n 'iframe',\n 'embed',\n 'script',\n 'link',\n];\n\nexport function visit(\n node: (Node | ChildNode) & {\n attrsObj?: Record<string, string>;\n attrsObjToArray?: Record<string, { name: string; value: string }>;\n },\n context: Context = {\n url: new URL('http://localhost'),\n active: false,\n },\n): RSC | RSC[] | string | null {\n if ('attrs' in node && typeof node.attrsObj === 'undefined') {\n node.attrsObjToArray = {};\n node.attrsObj = node.attrs.reduce<Record<string, string>>((acc, attr) => {\n acc[attr.name] = attr.value;\n if (node.attrsObjToArray) {\n node.attrsObjToArray[attr.name] = attr;\n }\n return acc;\n }, {});\n }\n\n // apply origin to src and srcset attributes\n if (\n applyOriginToNodes.includes(node.nodeName.toLowerCase()) &&\n 'attrs' in node\n ) {\n const origin = context.origin ?? context.url.origin;\n const src = node.attrsObj?.src;\n if (src) {\n const url = new URL(src, origin);\n if (node.attrsObjToArray && 'src' in node.attrsObjToArray) {\n node.attrsObjToArray.src.value = url.href;\n }\n }\n const href = node.attrsObj?.href;\n if (href) {\n const url = new URL(href, origin);\n if (node.attrsObjToArray && 'href' in node.attrsObjToArray) {\n node.attrsObjToArray.href.value = url.href;\n }\n }\n\n const srcSet = node.attrsObj?.srcset;\n if (srcSet) {\n const srcSetValue = srcSet\n .split(',')\n .map((entry) => {\n const [url, descriptor] = entry.trim().split(/\\s+/);\n if (!url) return entry;\n\n const absoluteUrl = new URL(url, origin).href;\n return descriptor ? `${absoluteUrl} ${descriptor}` : absoluteUrl;\n })\n .join(', ');\n if (node.attrsObjToArray && 'srcset' in node.attrsObjToArray) {\n node.attrsObjToArray.srcset.value = srcSetValue;\n }\n }\n const imageSrcSet = node.attrsObj?.imagesrcset;\n if (imageSrcSet) {\n const srcSetValue = imageSrcSet\n .split(',')\n .map((entry) => {\n const [url, descriptor] = entry.trim().split(/\\s+/);\n if (!url) return entry;\n\n const absoluteUrl = new URL(url, origin).href;\n return descriptor ? `${absoluteUrl} ${descriptor}` : absoluteUrl;\n })\n .join(', ');\n if (node.attrsObjToArray && 'imagesrcset' in node.attrsObjToArray) {\n node.attrsObjToArray.imagesrcset.value = srcSetValue;\n }\n }\n }\n\n if (node.nodeName === 'script' || node.nodeName === 'link') {\n const nodeId = node.attrsObj?.id;\n if (nodeId?.endsWith('_shared')) {\n context.onShared?.(\n JSON.parse((node.childNodes[0] as TextNode).value) as Record<\n string,\n string\n >,\n );\n return null;\n } else if (nodeId?.endsWith('_rsc') && 'childNodes' in node) {\n if (!context.visitedRSCNodes) {\n context.visitedRSCNodes = new Set();\n }\n if (\n !context.visitedRSCNodes.has(node) &&\n (context.name ? nodeId.startsWith(context.name) : true)\n ) {\n context.visitedRSCNodes.add(node);\n context.onRSC?.((node.childNodes[0] as TextNode).value);\n }\n } else if (nodeId === '__NEXT_DATA__' && 'childNodes' in node) {\n context.onHTML?.(\n `<script id=\"__REMOTE_NEXT_DATA__\" type=\"application/json\">${(node.childNodes[0] as TextNode).value}</script>`,\n );\n context.onNextData?.(\n JSON.parse((node.childNodes[0] as TextNode).value) as {\n props: { pageProps: Record<string, unknown> };\n },\n );\n } else if (node.childNodes.length === 0) {\n if (\n node.nodeName === 'script' &&\n node.attrsObj &&\n !('src' in node.attrsObj)\n ) {\n return [\n '$',\n node.nodeName,\n null,\n node.attrs.reduce<Record<string, string>>((props, attr) => {\n props[possibleStandardNames[attr.name] ?? attr.name] = attr.value;\n return props;\n }, {}),\n null,\n null,\n 1,\n ] as RSC;\n }\n if (node.nodeName === 'script') {\n context.onScript?.(\n node.attrs.reduce<Record<string, string | boolean>>((props, attr) => {\n props[attr.name] = attr.value || true;\n return props;\n }, {}),\n );\n const src = node.attrsObj?.src;\n if (src) {\n node.attrs = node.attrs.filter((attr) => attr.name !== 'src');\n node.attrs.push({\n name: 'data-src',\n value: src,\n });\n if (node.attrsObj) {\n delete node.attrsObj.src;\n node.attrsObj['data-src'] = src;\n }\n }\n context.onHTML?.(serializeOuter(node));\n } else {\n context.onLink?.(\n node.attrs.reduce<Record<string, string | boolean>>((props, attr) => {\n if (attr.name === 'href') {\n attr.value = new URL(attr.value, context.url.origin).href;\n }\n props[possibleStandardNames[attr.name] ?? attr.name] =\n attr.value || true;\n return props;\n }, {}),\n );\n context.onHTML?.(serializeOuter(node));\n }\n return null;\n }\n }\n\n if (!context.active) {\n if (!context.visitedNonActiveNodes) {\n context.visitedNonActiveNodes = new Set();\n }\n\n if ('childNodes' in node) {\n if (!context.visitedNonActiveNodes.has(node)) {\n context.visitedNonActiveNodes.add(node);\n (node as Element).childNodes.forEach((childNode) => {\n visit(childNode, context);\n });\n }\n } else return null;\n }\n\n switch (node.nodeName) {\n case '#document-fragment':\n return node.childNodes.reduce<RSC[]>((acc, childNode) => {\n const result = visit(childNode, context);\n if (result !== null) {\n acc.push(result as unknown as RSC);\n }\n return acc;\n }, []);\n case '#text':\n return (node as TextNode).value;\n case '#comment':\n case 'head':\n case 'meta':\n case 'title':\n case 'noscript':\n return null;\n default: {\n const nodeId = node.attrsObj?.id;\n\n if (\n node.nodeName === 'div' &&\n (nodeId === '__next' ||\n (context.name\n ? nodeId?.startsWith(context.name)\n : node.attrsObj &&\n 'data-bundle' in node.attrsObj &&\n node.attrsObj['data-bundle'] &&\n 'data-route' in node.attrsObj &&\n nodeId?.endsWith('_ssr')))\n ) {\n context.onMetadata?.({\n bundle: node.attrsObj?.['data-bundle'] ?? 'default',\n route: node.attrsObj?.['data-route'] ?? '/',\n runtime: (node.attrsObj?.['data-runtime'] ??\n 'webpack') as RemoteComponentMetadata['runtime'],\n id: nodeId?.endsWith('_ssr') ? nodeId : '__vercel_remote_component',\n });\n context.onHTML?.(serializeOuter(node));\n return node.childNodes.reduce<RSC[]>((acc, childNode) => {\n const result = visit(childNode, {\n ...context,\n active: true,\n });\n if (result !== null) {\n acc.push(result as unknown as RSC);\n }\n return acc;\n }, []);\n }\n const childNodes = (node as Element).childNodes.reduce<unknown[]>(\n (acc, childNode) => {\n const result = visit(childNode, context);\n if (result !== null) {\n acc.push(result as unknown);\n }\n return acc;\n },\n [],\n );\n const children = childNodes.length > 1 ? childNodes : childNodes[0];\n const nodeProps = (node as Element).attrs.reduce<\n Record<string, string | ReturnType<typeof styleToJs>> & {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n children?: any;\n }\n >((props, attr) => {\n if (attr.name === 'style') {\n props.style = styleToJs(attr.value, {\n reactCompat: true,\n });\n return props;\n }\n if (node.nodeName === 'input' && attr.name === 'value') {\n props.defaultValue = attr.value;\n return props;\n }\n if (isCustomAttribute(attr.name)) {\n props[attr.name] = attr.value;\n return props;\n }\n props[possibleStandardNames[attr.name] ?? attr.name] = attr.value;\n return props;\n }, {});\n if (typeof children !== 'undefined') {\n if (\n node.nodeName === 'script' &&\n typeof children === 'string' &&\n children.startsWith('$')\n ) {\n nodeProps.children = `$${children}`;\n } else {\n nodeProps.children = children;\n }\n }\n if (!context.active) {\n if (childNodes.length > 0) {\n return childNodes as RSC;\n }\n return null;\n }\n return ['$', node.nodeName, null, nodeProps, null, null, 1] as RSC;\n }\n }\n}\n"],"mappings":"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","names":["styleToJs"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/shared/ssr/dom-flight.ts"],"sourcesContent":["import { isCustomAttribute, possibleStandardNames } from 'react-property';\nimport styleToJs from 'style-to-js';\nimport type {\n ChildNode,\n Element,\n Node,\n TextNode,\n} from 'parse5/dist/tree-adapters/default';\nimport { serializeOuter } from 'parse5';\nimport type { RemoteComponentMetadata } from './types';\n\n// add fetch-priority to the possible standard names\npossibleStandardNames.fetchpriority = 'fetchPriority';\npossibleStandardNames['data-precedence'] = 'precedence';\n\nexport interface Context {\n name?: string;\n url: URL;\n origin?: string;\n defer?: boolean;\n active?: boolean;\n visitedRSCNodes?: Set<Node>;\n visitedNonActiveNodes?: Set<Node>;\n onMetadata?: (metadata: RemoteComponentMetadata) => void;\n onScript?: (attrs: Record<string, string | boolean>) => void;\n onLink?: (attrs: Record<string, string | boolean>) => void;\n onRSC?: (rsc: string) => void;\n onNextData?: (data: {\n props: {\n pageProps: Record<string, unknown>;\n __REMOTE_COMPONENT__?: {\n bundle: string;\n runtime: string;\n };\n };\n page?: string;\n }) => void;\n onHTML?: (html: string) => void;\n onShared?: (shared: Record<string, string>) => void;\n onError?: (message: string, stack?: string) => void;\n}\n\ntype RSC =\n | ['$', string, null, Record<string, unknown>, null, null, number]\n | (\n | ['$', string, null, Record<string, unknown>, null, null, number]\n | string\n | null\n )[]\n | string\n | null;\n\nconst applyOriginToNodes = [\n 'img',\n 'source',\n 'video',\n 'audio',\n 'track',\n 'iframe',\n 'embed',\n 'script',\n 'link',\n];\n\nexport function visit(\n node: (Node | ChildNode) & {\n attrsObj?: Record<string, string>;\n attrsObjToArray?: Record<string, { name: string; value: string }>;\n },\n context: Context = {\n url: new URL('http://localhost'),\n active: false,\n },\n): RSC | RSC[] | string | null {\n if ('attrs' in node && typeof node.attrsObj === 'undefined') {\n node.attrsObjToArray = {};\n node.attrsObj = node.attrs.reduce<Record<string, string>>((acc, attr) => {\n acc[attr.name] = attr.value;\n if (node.attrsObjToArray) {\n node.attrsObjToArray[attr.name] = attr;\n }\n return acc;\n }, {});\n }\n\n if (\n node.nodeName === 'template' &&\n node.attrsObj?.['data-next-error-message']\n ) {\n context.onError?.(\n node.attrsObj['data-next-error-message'],\n node.attrsObj['data-next-error-stack'],\n );\n }\n\n // apply origin to src and srcset attributes\n if (\n applyOriginToNodes.includes(node.nodeName.toLowerCase()) &&\n 'attrs' in node\n ) {\n const origin = context.origin ?? context.url.origin;\n const src = node.attrsObj?.src;\n if (src) {\n const url = new URL(src, origin);\n if (node.attrsObjToArray && 'src' in node.attrsObjToArray) {\n node.attrsObjToArray.src.value = url.href;\n }\n }\n const href = node.attrsObj?.href;\n if (href) {\n const url = new URL(href, origin);\n if (node.attrsObjToArray && 'href' in node.attrsObjToArray) {\n node.attrsObjToArray.href.value = url.href;\n }\n }\n\n const srcSet = node.attrsObj?.srcset;\n if (srcSet) {\n const srcSetValue = srcSet\n .split(',')\n .map((entry) => {\n const [url, descriptor] = entry.trim().split(/\\s+/);\n if (!url) return entry;\n\n const absoluteUrl = new URL(url, origin).href;\n return descriptor ? `${absoluteUrl} ${descriptor}` : absoluteUrl;\n })\n .join(', ');\n if (node.attrsObjToArray && 'srcset' in node.attrsObjToArray) {\n node.attrsObjToArray.srcset.value = srcSetValue;\n }\n }\n const imageSrcSet = node.attrsObj?.imagesrcset;\n if (imageSrcSet) {\n const srcSetValue = imageSrcSet\n .split(',')\n .map((entry) => {\n const [url, descriptor] = entry.trim().split(/\\s+/);\n if (!url) return entry;\n\n const absoluteUrl = new URL(url, origin).href;\n return descriptor ? `${absoluteUrl} ${descriptor}` : absoluteUrl;\n })\n .join(', ');\n if (node.attrsObjToArray && 'imagesrcset' in node.attrsObjToArray) {\n node.attrsObjToArray.imagesrcset.value = srcSetValue;\n }\n }\n }\n\n if (node.nodeName === 'script' || node.nodeName === 'link') {\n const nodeId = node.attrsObj?.id;\n if (nodeId?.endsWith('_shared')) {\n context.onShared?.(\n JSON.parse((node.childNodes[0] as TextNode).value) as Record<\n string,\n string\n >,\n );\n return null;\n } else if (nodeId?.endsWith('_rsc') && 'childNodes' in node) {\n if (!context.visitedRSCNodes) {\n context.visitedRSCNodes = new Set();\n }\n if (\n !context.visitedRSCNodes.has(node) &&\n (context.name ? nodeId.startsWith(context.name) : true)\n ) {\n context.visitedRSCNodes.add(node);\n context.onRSC?.((node.childNodes[0] as TextNode).value);\n }\n } else if (nodeId === '__NEXT_DATA__' && 'childNodes' in node) {\n context.onHTML?.(\n `<script id=\"__REMOTE_NEXT_DATA__\" type=\"application/json\">${(node.childNodes[0] as TextNode).value}</script>`,\n );\n context.onNextData?.(\n JSON.parse((node.childNodes[0] as TextNode).value) as {\n props: { pageProps: Record<string, unknown> };\n },\n );\n } else if (node.childNodes.length === 0) {\n if (\n node.nodeName === 'script' &&\n node.attrsObj &&\n !('src' in node.attrsObj)\n ) {\n return [\n '$',\n node.nodeName,\n null,\n node.attrs.reduce<Record<string, string>>((props, attr) => {\n props[possibleStandardNames[attr.name] ?? attr.name] = attr.value;\n return props;\n }, {}),\n null,\n null,\n 1,\n ] as RSC;\n }\n if (node.nodeName === 'script') {\n context.onScript?.(\n node.attrs.reduce<Record<string, string | boolean>>((props, attr) => {\n props[attr.name] = attr.value || true;\n return props;\n }, {}),\n );\n const src = node.attrsObj?.src;\n if (src) {\n node.attrs = node.attrs.filter((attr) => attr.name !== 'src');\n node.attrs.push({\n name: 'data-src',\n value: src,\n });\n if (node.attrsObj) {\n delete node.attrsObj.src;\n node.attrsObj['data-src'] = src;\n }\n }\n context.onHTML?.(serializeOuter(node));\n } else {\n context.onLink?.(\n node.attrs.reduce<Record<string, string | boolean>>((props, attr) => {\n if (attr.name === 'href') {\n attr.value = new URL(attr.value, context.url.origin).href;\n }\n props[possibleStandardNames[attr.name] ?? attr.name] =\n attr.value || true;\n return props;\n }, {}),\n );\n context.onHTML?.(serializeOuter(node));\n }\n return null;\n }\n }\n\n if (!context.active) {\n if (!context.visitedNonActiveNodes) {\n context.visitedNonActiveNodes = new Set();\n }\n\n if ('childNodes' in node) {\n if (!context.visitedNonActiveNodes.has(node)) {\n context.visitedNonActiveNodes.add(node);\n (node as Element).childNodes.forEach((childNode) => {\n visit(childNode, context);\n });\n }\n } else return null;\n }\n\n switch (node.nodeName) {\n case '#document-fragment':\n return node.childNodes.reduce<RSC[]>((acc, childNode) => {\n const result = visit(childNode, context);\n if (result !== null) {\n acc.push(result as unknown as RSC);\n }\n return acc;\n }, []);\n case '#text':\n return (node as TextNode).value;\n case '#comment':\n case 'head':\n case 'meta':\n case 'title':\n case 'noscript':\n return null;\n default: {\n const nodeId = node.attrsObj?.id;\n\n if (\n node.nodeName === 'div' &&\n (nodeId === '__next' ||\n (context.name\n ? nodeId?.startsWith(context.name)\n : node.attrsObj &&\n 'data-bundle' in node.attrsObj &&\n node.attrsObj['data-bundle'] &&\n 'data-route' in node.attrsObj &&\n nodeId?.endsWith('_ssr')))\n ) {\n context.onMetadata?.({\n bundle: node.attrsObj?.['data-bundle'] ?? 'default',\n route: node.attrsObj?.['data-route'] ?? '/',\n runtime: (node.attrsObj?.['data-runtime'] ??\n 'webpack') as RemoteComponentMetadata['runtime'],\n id: nodeId?.endsWith('_ssr') ? nodeId : '__vercel_remote_component',\n type: (node.attrsObj?.['data-type'] ||\n 'unknown') as RemoteComponentMetadata['type'],\n });\n context.onHTML?.(serializeOuter(node));\n return node.childNodes.reduce<RSC[]>((acc, childNode) => {\n const result = visit(childNode, {\n ...context,\n active: true,\n });\n if (result !== null) {\n acc.push(result as unknown as RSC);\n }\n return acc;\n }, []);\n }\n const childNodes = (node as Element).childNodes.reduce<unknown[]>(\n (acc, childNode) => {\n const result = visit(childNode, context);\n if (result !== null) {\n acc.push(result as unknown);\n }\n return acc;\n },\n [],\n );\n const children = childNodes.length > 1 ? childNodes : childNodes[0];\n const nodeProps = (node as Element).attrs.reduce<\n Record<string, string | ReturnType<typeof styleToJs>> & {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n children?: any;\n }\n >((props, attr) => {\n if (attr.name === 'style') {\n props.style = styleToJs(attr.value, {\n reactCompat: true,\n });\n return props;\n }\n if (node.nodeName === 'input' && attr.name === 'value') {\n props.defaultValue = attr.value;\n return props;\n }\n if (isCustomAttribute(attr.name)) {\n props[attr.name] = attr.value;\n return props;\n }\n props[possibleStandardNames[attr.name] ?? attr.name] = attr.value;\n return props;\n }, {});\n if (typeof children !== 'undefined') {\n if (\n node.nodeName === 'script' &&\n typeof children === 'string' &&\n children.startsWith('$')\n ) {\n nodeProps.children = `$${children}`;\n } else {\n nodeProps.children = children;\n }\n }\n if (!context.active) {\n if (childNodes.length > 0) {\n return childNodes as RSC;\n }\n return null;\n }\n return ['$', node.nodeName, null, nodeProps, null, null, 1] as RSC;\n }\n }\n}\n"],"mappings":"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","names":["styleToJs"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Node, ChildNode } from 'parse5/dist/tree-adapters/default';
|
|
2
|
-
import { R as RemoteComponentMetadata } from '../../../types-
|
|
2
|
+
import { R as RemoteComponentMetadata } from '../../../types-e4a3fa37.js';
|
|
3
3
|
|
|
4
4
|
interface Context {
|
|
5
5
|
name?: string;
|
|
@@ -25,6 +25,7 @@ interface Context {
|
|
|
25
25
|
}) => void;
|
|
26
26
|
onHTML?: (html: string) => void;
|
|
27
27
|
onShared?: (shared: Record<string, string>) => void;
|
|
28
|
+
onError?: (message: string, stack?: string) => void;
|
|
28
29
|
}
|
|
29
30
|
type RSC = ['$', string, null, Record<string, unknown>, null, null, number] | (['$', string, null, Record<string, unknown>, null, null, number] | string | null)[] | string | null;
|
|
30
31
|
declare function visit(node: (Node | ChildNode) & {
|
|
@@ -28,6 +28,12 @@ function visit(node, context = {
|
|
|
28
28
|
return acc;
|
|
29
29
|
}, {});
|
|
30
30
|
}
|
|
31
|
+
if (node.nodeName === "template" && node.attrsObj?.["data-next-error-message"]) {
|
|
32
|
+
context.onError?.(
|
|
33
|
+
node.attrsObj["data-next-error-message"],
|
|
34
|
+
node.attrsObj["data-next-error-stack"]
|
|
35
|
+
);
|
|
36
|
+
}
|
|
31
37
|
if (applyOriginToNodes.includes(node.nodeName.toLowerCase()) && "attrs" in node) {
|
|
32
38
|
const origin = context.origin ?? context.url.origin;
|
|
33
39
|
const src = node.attrsObj?.src;
|
|
@@ -181,7 +187,8 @@ function visit(node, context = {
|
|
|
181
187
|
bundle: node.attrsObj?.["data-bundle"] ?? "default",
|
|
182
188
|
route: node.attrsObj?.["data-route"] ?? "/",
|
|
183
189
|
runtime: node.attrsObj?.["data-runtime"] ?? "webpack",
|
|
184
|
-
id: nodeId?.endsWith("_ssr") ? nodeId : "__vercel_remote_component"
|
|
190
|
+
id: nodeId?.endsWith("_ssr") ? nodeId : "__vercel_remote_component",
|
|
191
|
+
type: node.attrsObj?.["data-type"] || "unknown"
|
|
185
192
|
});
|
|
186
193
|
context.onHTML?.(serializeOuter(node));
|
|
187
194
|
return node.childNodes.reduce((acc, childNode) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/shared/ssr/dom-flight.ts"],"sourcesContent":["import { isCustomAttribute, possibleStandardNames } from 'react-property';\nimport styleToJs from 'style-to-js';\nimport type {\n ChildNode,\n Element,\n Node,\n TextNode,\n} from 'parse5/dist/tree-adapters/default';\nimport { serializeOuter } from 'parse5';\nimport type { RemoteComponentMetadata } from './types';\n\n// add fetch-priority to the possible standard names\npossibleStandardNames.fetchpriority = 'fetchPriority';\npossibleStandardNames['data-precedence'] = 'precedence';\n\nexport interface Context {\n name?: string;\n url: URL;\n origin?: string;\n defer?: boolean;\n active?: boolean;\n visitedRSCNodes?: Set<Node>;\n visitedNonActiveNodes?: Set<Node>;\n onMetadata?: (metadata: RemoteComponentMetadata) => void;\n onScript?: (attrs: Record<string, string | boolean>) => void;\n onLink?: (attrs: Record<string, string | boolean>) => void;\n onRSC?: (rsc: string) => void;\n onNextData?: (data: {\n props: {\n pageProps: Record<string, unknown>;\n __REMOTE_COMPONENT__?: {\n bundle: string;\n runtime: string;\n };\n };\n page?: string;\n }) => void;\n onHTML?: (html: string) => void;\n onShared?: (shared: Record<string, string>) => void;\n}\n\ntype RSC =\n | ['$', string, null, Record<string, unknown>, null, null, number]\n | (\n | ['$', string, null, Record<string, unknown>, null, null, number]\n | string\n | null\n )[]\n | string\n | null;\n\nconst applyOriginToNodes = [\n 'img',\n 'source',\n 'video',\n 'audio',\n 'track',\n 'iframe',\n 'embed',\n 'script',\n 'link',\n];\n\nexport function visit(\n node: (Node | ChildNode) & {\n attrsObj?: Record<string, string>;\n attrsObjToArray?: Record<string, { name: string; value: string }>;\n },\n context: Context = {\n url: new URL('http://localhost'),\n active: false,\n },\n): RSC | RSC[] | string | null {\n if ('attrs' in node && typeof node.attrsObj === 'undefined') {\n node.attrsObjToArray = {};\n node.attrsObj = node.attrs.reduce<Record<string, string>>((acc, attr) => {\n acc[attr.name] = attr.value;\n if (node.attrsObjToArray) {\n node.attrsObjToArray[attr.name] = attr;\n }\n return acc;\n }, {});\n }\n\n // apply origin to src and srcset attributes\n if (\n applyOriginToNodes.includes(node.nodeName.toLowerCase()) &&\n 'attrs' in node\n ) {\n const origin = context.origin ?? context.url.origin;\n const src = node.attrsObj?.src;\n if (src) {\n const url = new URL(src, origin);\n if (node.attrsObjToArray && 'src' in node.attrsObjToArray) {\n node.attrsObjToArray.src.value = url.href;\n }\n }\n const href = node.attrsObj?.href;\n if (href) {\n const url = new URL(href, origin);\n if (node.attrsObjToArray && 'href' in node.attrsObjToArray) {\n node.attrsObjToArray.href.value = url.href;\n }\n }\n\n const srcSet = node.attrsObj?.srcset;\n if (srcSet) {\n const srcSetValue = srcSet\n .split(',')\n .map((entry) => {\n const [url, descriptor] = entry.trim().split(/\\s+/);\n if (!url) return entry;\n\n const absoluteUrl = new URL(url, origin).href;\n return descriptor ? `${absoluteUrl} ${descriptor}` : absoluteUrl;\n })\n .join(', ');\n if (node.attrsObjToArray && 'srcset' in node.attrsObjToArray) {\n node.attrsObjToArray.srcset.value = srcSetValue;\n }\n }\n const imageSrcSet = node.attrsObj?.imagesrcset;\n if (imageSrcSet) {\n const srcSetValue = imageSrcSet\n .split(',')\n .map((entry) => {\n const [url, descriptor] = entry.trim().split(/\\s+/);\n if (!url) return entry;\n\n const absoluteUrl = new URL(url, origin).href;\n return descriptor ? `${absoluteUrl} ${descriptor}` : absoluteUrl;\n })\n .join(', ');\n if (node.attrsObjToArray && 'imagesrcset' in node.attrsObjToArray) {\n node.attrsObjToArray.imagesrcset.value = srcSetValue;\n }\n }\n }\n\n if (node.nodeName === 'script' || node.nodeName === 'link') {\n const nodeId = node.attrsObj?.id;\n if (nodeId?.endsWith('_shared')) {\n context.onShared?.(\n JSON.parse((node.childNodes[0] as TextNode).value) as Record<\n string,\n string\n >,\n );\n return null;\n } else if (nodeId?.endsWith('_rsc') && 'childNodes' in node) {\n if (!context.visitedRSCNodes) {\n context.visitedRSCNodes = new Set();\n }\n if (\n !context.visitedRSCNodes.has(node) &&\n (context.name ? nodeId.startsWith(context.name) : true)\n ) {\n context.visitedRSCNodes.add(node);\n context.onRSC?.((node.childNodes[0] as TextNode).value);\n }\n } else if (nodeId === '__NEXT_DATA__' && 'childNodes' in node) {\n context.onHTML?.(\n `<script id=\"__REMOTE_NEXT_DATA__\" type=\"application/json\">${(node.childNodes[0] as TextNode).value}</script>`,\n );\n context.onNextData?.(\n JSON.parse((node.childNodes[0] as TextNode).value) as {\n props: { pageProps: Record<string, unknown> };\n },\n );\n } else if (node.childNodes.length === 0) {\n if (\n node.nodeName === 'script' &&\n node.attrsObj &&\n !('src' in node.attrsObj)\n ) {\n return [\n '$',\n node.nodeName,\n null,\n node.attrs.reduce<Record<string, string>>((props, attr) => {\n props[possibleStandardNames[attr.name] ?? attr.name] = attr.value;\n return props;\n }, {}),\n null,\n null,\n 1,\n ] as RSC;\n }\n if (node.nodeName === 'script') {\n context.onScript?.(\n node.attrs.reduce<Record<string, string | boolean>>((props, attr) => {\n props[attr.name] = attr.value || true;\n return props;\n }, {}),\n );\n const src = node.attrsObj?.src;\n if (src) {\n node.attrs = node.attrs.filter((attr) => attr.name !== 'src');\n node.attrs.push({\n name: 'data-src',\n value: src,\n });\n if (node.attrsObj) {\n delete node.attrsObj.src;\n node.attrsObj['data-src'] = src;\n }\n }\n context.onHTML?.(serializeOuter(node));\n } else {\n context.onLink?.(\n node.attrs.reduce<Record<string, string | boolean>>((props, attr) => {\n if (attr.name === 'href') {\n attr.value = new URL(attr.value, context.url.origin).href;\n }\n props[possibleStandardNames[attr.name] ?? attr.name] =\n attr.value || true;\n return props;\n }, {}),\n );\n context.onHTML?.(serializeOuter(node));\n }\n return null;\n }\n }\n\n if (!context.active) {\n if (!context.visitedNonActiveNodes) {\n context.visitedNonActiveNodes = new Set();\n }\n\n if ('childNodes' in node) {\n if (!context.visitedNonActiveNodes.has(node)) {\n context.visitedNonActiveNodes.add(node);\n (node as Element).childNodes.forEach((childNode) => {\n visit(childNode, context);\n });\n }\n } else return null;\n }\n\n switch (node.nodeName) {\n case '#document-fragment':\n return node.childNodes.reduce<RSC[]>((acc, childNode) => {\n const result = visit(childNode, context);\n if (result !== null) {\n acc.push(result as unknown as RSC);\n }\n return acc;\n }, []);\n case '#text':\n return (node as TextNode).value;\n case '#comment':\n case 'head':\n case 'meta':\n case 'title':\n case 'noscript':\n return null;\n default: {\n const nodeId = node.attrsObj?.id;\n\n if (\n node.nodeName === 'div' &&\n (nodeId === '__next' ||\n (context.name\n ? nodeId?.startsWith(context.name)\n : node.attrsObj &&\n 'data-bundle' in node.attrsObj &&\n node.attrsObj['data-bundle'] &&\n 'data-route' in node.attrsObj &&\n nodeId?.endsWith('_ssr')))\n ) {\n context.onMetadata?.({\n bundle: node.attrsObj?.['data-bundle'] ?? 'default',\n route: node.attrsObj?.['data-route'] ?? '/',\n runtime: (node.attrsObj?.['data-runtime'] ??\n 'webpack') as RemoteComponentMetadata['runtime'],\n id: nodeId?.endsWith('_ssr') ? nodeId : '__vercel_remote_component',\n });\n context.onHTML?.(serializeOuter(node));\n return node.childNodes.reduce<RSC[]>((acc, childNode) => {\n const result = visit(childNode, {\n ...context,\n active: true,\n });\n if (result !== null) {\n acc.push(result as unknown as RSC);\n }\n return acc;\n }, []);\n }\n const childNodes = (node as Element).childNodes.reduce<unknown[]>(\n (acc, childNode) => {\n const result = visit(childNode, context);\n if (result !== null) {\n acc.push(result as unknown);\n }\n return acc;\n },\n [],\n );\n const children = childNodes.length > 1 ? childNodes : childNodes[0];\n const nodeProps = (node as Element).attrs.reduce<\n Record<string, string | ReturnType<typeof styleToJs>> & {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n children?: any;\n }\n >((props, attr) => {\n if (attr.name === 'style') {\n props.style = styleToJs(attr.value, {\n reactCompat: true,\n });\n return props;\n }\n if (node.nodeName === 'input' && attr.name === 'value') {\n props.defaultValue = attr.value;\n return props;\n }\n if (isCustomAttribute(attr.name)) {\n props[attr.name] = attr.value;\n return props;\n }\n props[possibleStandardNames[attr.name] ?? attr.name] = attr.value;\n return props;\n }, {});\n if (typeof children !== 'undefined') {\n if (\n node.nodeName === 'script' &&\n typeof children === 'string' &&\n children.startsWith('$')\n ) {\n nodeProps.children = `$${children}`;\n } else {\n nodeProps.children = children;\n }\n }\n if (!context.active) {\n if (childNodes.length > 0) {\n return childNodes as RSC;\n }\n return null;\n }\n return ['$', node.nodeName, null, nodeProps, null, null, 1] as RSC;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/shared/ssr/dom-flight.ts"],"sourcesContent":["import { isCustomAttribute, possibleStandardNames } from 'react-property';\nimport styleToJs from 'style-to-js';\nimport type {\n ChildNode,\n Element,\n Node,\n TextNode,\n} from 'parse5/dist/tree-adapters/default';\nimport { serializeOuter } from 'parse5';\nimport type { RemoteComponentMetadata } from './types';\n\n// add fetch-priority to the possible standard names\npossibleStandardNames.fetchpriority = 'fetchPriority';\npossibleStandardNames['data-precedence'] = 'precedence';\n\nexport interface Context {\n name?: string;\n url: URL;\n origin?: string;\n defer?: boolean;\n active?: boolean;\n visitedRSCNodes?: Set<Node>;\n visitedNonActiveNodes?: Set<Node>;\n onMetadata?: (metadata: RemoteComponentMetadata) => void;\n onScript?: (attrs: Record<string, string | boolean>) => void;\n onLink?: (attrs: Record<string, string | boolean>) => void;\n onRSC?: (rsc: string) => void;\n onNextData?: (data: {\n props: {\n pageProps: Record<string, unknown>;\n __REMOTE_COMPONENT__?: {\n bundle: string;\n runtime: string;\n };\n };\n page?: string;\n }) => void;\n onHTML?: (html: string) => void;\n onShared?: (shared: Record<string, string>) => void;\n onError?: (message: string, stack?: string) => void;\n}\n\ntype RSC =\n | ['$', string, null, Record<string, unknown>, null, null, number]\n | (\n | ['$', string, null, Record<string, unknown>, null, null, number]\n | string\n | null\n )[]\n | string\n | null;\n\nconst applyOriginToNodes = [\n 'img',\n 'source',\n 'video',\n 'audio',\n 'track',\n 'iframe',\n 'embed',\n 'script',\n 'link',\n];\n\nexport function visit(\n node: (Node | ChildNode) & {\n attrsObj?: Record<string, string>;\n attrsObjToArray?: Record<string, { name: string; value: string }>;\n },\n context: Context = {\n url: new URL('http://localhost'),\n active: false,\n },\n): RSC | RSC[] | string | null {\n if ('attrs' in node && typeof node.attrsObj === 'undefined') {\n node.attrsObjToArray = {};\n node.attrsObj = node.attrs.reduce<Record<string, string>>((acc, attr) => {\n acc[attr.name] = attr.value;\n if (node.attrsObjToArray) {\n node.attrsObjToArray[attr.name] = attr;\n }\n return acc;\n }, {});\n }\n\n if (\n node.nodeName === 'template' &&\n node.attrsObj?.['data-next-error-message']\n ) {\n context.onError?.(\n node.attrsObj['data-next-error-message'],\n node.attrsObj['data-next-error-stack'],\n );\n }\n\n // apply origin to src and srcset attributes\n if (\n applyOriginToNodes.includes(node.nodeName.toLowerCase()) &&\n 'attrs' in node\n ) {\n const origin = context.origin ?? context.url.origin;\n const src = node.attrsObj?.src;\n if (src) {\n const url = new URL(src, origin);\n if (node.attrsObjToArray && 'src' in node.attrsObjToArray) {\n node.attrsObjToArray.src.value = url.href;\n }\n }\n const href = node.attrsObj?.href;\n if (href) {\n const url = new URL(href, origin);\n if (node.attrsObjToArray && 'href' in node.attrsObjToArray) {\n node.attrsObjToArray.href.value = url.href;\n }\n }\n\n const srcSet = node.attrsObj?.srcset;\n if (srcSet) {\n const srcSetValue = srcSet\n .split(',')\n .map((entry) => {\n const [url, descriptor] = entry.trim().split(/\\s+/);\n if (!url) return entry;\n\n const absoluteUrl = new URL(url, origin).href;\n return descriptor ? `${absoluteUrl} ${descriptor}` : absoluteUrl;\n })\n .join(', ');\n if (node.attrsObjToArray && 'srcset' in node.attrsObjToArray) {\n node.attrsObjToArray.srcset.value = srcSetValue;\n }\n }\n const imageSrcSet = node.attrsObj?.imagesrcset;\n if (imageSrcSet) {\n const srcSetValue = imageSrcSet\n .split(',')\n .map((entry) => {\n const [url, descriptor] = entry.trim().split(/\\s+/);\n if (!url) return entry;\n\n const absoluteUrl = new URL(url, origin).href;\n return descriptor ? `${absoluteUrl} ${descriptor}` : absoluteUrl;\n })\n .join(', ');\n if (node.attrsObjToArray && 'imagesrcset' in node.attrsObjToArray) {\n node.attrsObjToArray.imagesrcset.value = srcSetValue;\n }\n }\n }\n\n if (node.nodeName === 'script' || node.nodeName === 'link') {\n const nodeId = node.attrsObj?.id;\n if (nodeId?.endsWith('_shared')) {\n context.onShared?.(\n JSON.parse((node.childNodes[0] as TextNode).value) as Record<\n string,\n string\n >,\n );\n return null;\n } else if (nodeId?.endsWith('_rsc') && 'childNodes' in node) {\n if (!context.visitedRSCNodes) {\n context.visitedRSCNodes = new Set();\n }\n if (\n !context.visitedRSCNodes.has(node) &&\n (context.name ? nodeId.startsWith(context.name) : true)\n ) {\n context.visitedRSCNodes.add(node);\n context.onRSC?.((node.childNodes[0] as TextNode).value);\n }\n } else if (nodeId === '__NEXT_DATA__' && 'childNodes' in node) {\n context.onHTML?.(\n `<script id=\"__REMOTE_NEXT_DATA__\" type=\"application/json\">${(node.childNodes[0] as TextNode).value}</script>`,\n );\n context.onNextData?.(\n JSON.parse((node.childNodes[0] as TextNode).value) as {\n props: { pageProps: Record<string, unknown> };\n },\n );\n } else if (node.childNodes.length === 0) {\n if (\n node.nodeName === 'script' &&\n node.attrsObj &&\n !('src' in node.attrsObj)\n ) {\n return [\n '$',\n node.nodeName,\n null,\n node.attrs.reduce<Record<string, string>>((props, attr) => {\n props[possibleStandardNames[attr.name] ?? attr.name] = attr.value;\n return props;\n }, {}),\n null,\n null,\n 1,\n ] as RSC;\n }\n if (node.nodeName === 'script') {\n context.onScript?.(\n node.attrs.reduce<Record<string, string | boolean>>((props, attr) => {\n props[attr.name] = attr.value || true;\n return props;\n }, {}),\n );\n const src = node.attrsObj?.src;\n if (src) {\n node.attrs = node.attrs.filter((attr) => attr.name !== 'src');\n node.attrs.push({\n name: 'data-src',\n value: src,\n });\n if (node.attrsObj) {\n delete node.attrsObj.src;\n node.attrsObj['data-src'] = src;\n }\n }\n context.onHTML?.(serializeOuter(node));\n } else {\n context.onLink?.(\n node.attrs.reduce<Record<string, string | boolean>>((props, attr) => {\n if (attr.name === 'href') {\n attr.value = new URL(attr.value, context.url.origin).href;\n }\n props[possibleStandardNames[attr.name] ?? attr.name] =\n attr.value || true;\n return props;\n }, {}),\n );\n context.onHTML?.(serializeOuter(node));\n }\n return null;\n }\n }\n\n if (!context.active) {\n if (!context.visitedNonActiveNodes) {\n context.visitedNonActiveNodes = new Set();\n }\n\n if ('childNodes' in node) {\n if (!context.visitedNonActiveNodes.has(node)) {\n context.visitedNonActiveNodes.add(node);\n (node as Element).childNodes.forEach((childNode) => {\n visit(childNode, context);\n });\n }\n } else return null;\n }\n\n switch (node.nodeName) {\n case '#document-fragment':\n return node.childNodes.reduce<RSC[]>((acc, childNode) => {\n const result = visit(childNode, context);\n if (result !== null) {\n acc.push(result as unknown as RSC);\n }\n return acc;\n }, []);\n case '#text':\n return (node as TextNode).value;\n case '#comment':\n case 'head':\n case 'meta':\n case 'title':\n case 'noscript':\n return null;\n default: {\n const nodeId = node.attrsObj?.id;\n\n if (\n node.nodeName === 'div' &&\n (nodeId === '__next' ||\n (context.name\n ? nodeId?.startsWith(context.name)\n : node.attrsObj &&\n 'data-bundle' in node.attrsObj &&\n node.attrsObj['data-bundle'] &&\n 'data-route' in node.attrsObj &&\n nodeId?.endsWith('_ssr')))\n ) {\n context.onMetadata?.({\n bundle: node.attrsObj?.['data-bundle'] ?? 'default',\n route: node.attrsObj?.['data-route'] ?? '/',\n runtime: (node.attrsObj?.['data-runtime'] ??\n 'webpack') as RemoteComponentMetadata['runtime'],\n id: nodeId?.endsWith('_ssr') ? nodeId : '__vercel_remote_component',\n type: (node.attrsObj?.['data-type'] ||\n 'unknown') as RemoteComponentMetadata['type'],\n });\n context.onHTML?.(serializeOuter(node));\n return node.childNodes.reduce<RSC[]>((acc, childNode) => {\n const result = visit(childNode, {\n ...context,\n active: true,\n });\n if (result !== null) {\n acc.push(result as unknown as RSC);\n }\n return acc;\n }, []);\n }\n const childNodes = (node as Element).childNodes.reduce<unknown[]>(\n (acc, childNode) => {\n const result = visit(childNode, context);\n if (result !== null) {\n acc.push(result as unknown);\n }\n return acc;\n },\n [],\n );\n const children = childNodes.length > 1 ? childNodes : childNodes[0];\n const nodeProps = (node as Element).attrs.reduce<\n Record<string, string | ReturnType<typeof styleToJs>> & {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n children?: any;\n }\n >((props, attr) => {\n if (attr.name === 'style') {\n props.style = styleToJs(attr.value, {\n reactCompat: true,\n });\n return props;\n }\n if (node.nodeName === 'input' && attr.name === 'value') {\n props.defaultValue = attr.value;\n return props;\n }\n if (isCustomAttribute(attr.name)) {\n props[attr.name] = attr.value;\n return props;\n }\n props[possibleStandardNames[attr.name] ?? attr.name] = attr.value;\n return props;\n }, {});\n if (typeof children !== 'undefined') {\n if (\n node.nodeName === 'script' &&\n typeof children === 'string' &&\n children.startsWith('$')\n ) {\n nodeProps.children = `$${children}`;\n } else {\n nodeProps.children = children;\n }\n }\n if (!context.active) {\n if (childNodes.length > 0) {\n return childNodes as RSC;\n }\n return null;\n }\n return ['$', node.nodeName, null, nodeProps, null, null, 1] as RSC;\n }\n }\n}\n"],"mappings":"AAAA,SAAS,mBAAmB,6BAA6B;AACzD,OAAO,eAAe;AAOtB,SAAS,sBAAsB;AAI/B,sBAAsB,gBAAgB;AACtC,sBAAsB,iBAAiB,IAAI;AAuC3C,MAAM,qBAAqB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,MACd,MAIA,UAAmB;AAAA,EACjB,KAAK,IAAI,IAAI,kBAAkB;AAAA,EAC/B,QAAQ;AACV,GAC6B;AAC7B,MAAI,WAAW,QAAQ,OAAO,KAAK,aAAa,aAAa;AAC3D,SAAK,kBAAkB,CAAC;AACxB,SAAK,WAAW,KAAK,MAAM,OAA+B,CAAC,KAAK,SAAS;AACvE,UAAI,KAAK,IAAI,IAAI,KAAK;AACtB,UAAI,KAAK,iBAAiB;AACxB,aAAK,gBAAgB,KAAK,IAAI,IAAI;AAAA,MACpC;AACA,aAAO;AAAA,IACT,GAAG,CAAC,CAAC;AAAA,EACP;AAEA,MACE,KAAK,aAAa,cAClB,KAAK,WAAW,yBAAyB,GACzC;AACA,YAAQ;AAAA,MACN,KAAK,SAAS,yBAAyB;AAAA,MACvC,KAAK,SAAS,uBAAuB;AAAA,IACvC;AAAA,EACF;AAGA,MACE,mBAAmB,SAAS,KAAK,SAAS,YAAY,CAAC,KACvD,WAAW,MACX;AACA,UAAM,SAAS,QAAQ,UAAU,QAAQ,IAAI;AAC7C,UAAM,MAAM,KAAK,UAAU;AAC3B,QAAI,KAAK;AACP,YAAM,MAAM,IAAI,IAAI,KAAK,MAAM;AAC/B,UAAI,KAAK,mBAAmB,SAAS,KAAK,iBAAiB;AACzD,aAAK,gBAAgB,IAAI,QAAQ,IAAI;AAAA,MACvC;AAAA,IACF;AACA,UAAM,OAAO,KAAK,UAAU;AAC5B,QAAI,MAAM;AACR,YAAM,MAAM,IAAI,IAAI,MAAM,MAAM;AAChC,UAAI,KAAK,mBAAmB,UAAU,KAAK,iBAAiB;AAC1D,aAAK,gBAAgB,KAAK,QAAQ,IAAI;AAAA,MACxC;AAAA,IACF;AAEA,UAAM,SAAS,KAAK,UAAU;AAC9B,QAAI,QAAQ;AACV,YAAM,cAAc,OACjB,MAAM,GAAG,EACT,IAAI,CAAC,UAAU;AACd,cAAM,CAAC,KAAK,UAAU,IAAI,MAAM,KAAK,EAAE,MAAM,KAAK;AAClD,YAAI,CAAC;AAAK,iBAAO;AAEjB,cAAM,cAAc,IAAI,IAAI,KAAK,MAAM,EAAE;AACzC,eAAO,aAAa,GAAG,eAAe,eAAe;AAAA,MACvD,CAAC,EACA,KAAK,IAAI;AACZ,UAAI,KAAK,mBAAmB,YAAY,KAAK,iBAAiB;AAC5D,aAAK,gBAAgB,OAAO,QAAQ;AAAA,MACtC;AAAA,IACF;AACA,UAAM,cAAc,KAAK,UAAU;AACnC,QAAI,aAAa;AACf,YAAM,cAAc,YACjB,MAAM,GAAG,EACT,IAAI,CAAC,UAAU;AACd,cAAM,CAAC,KAAK,UAAU,IAAI,MAAM,KAAK,EAAE,MAAM,KAAK;AAClD,YAAI,CAAC;AAAK,iBAAO;AAEjB,cAAM,cAAc,IAAI,IAAI,KAAK,MAAM,EAAE;AACzC,eAAO,aAAa,GAAG,eAAe,eAAe;AAAA,MACvD,CAAC,EACA,KAAK,IAAI;AACZ,UAAI,KAAK,mBAAmB,iBAAiB,KAAK,iBAAiB;AACjE,aAAK,gBAAgB,YAAY,QAAQ;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAEA,MAAI,KAAK,aAAa,YAAY,KAAK,aAAa,QAAQ;AAC1D,UAAM,SAAS,KAAK,UAAU;AAC9B,QAAI,QAAQ,SAAS,SAAS,GAAG;AAC/B,cAAQ;AAAA,QACN,KAAK,MAAO,KAAK,WAAW,CAAC,EAAe,KAAK;AAAA,MAInD;AACA,aAAO;AAAA,IACT,WAAW,QAAQ,SAAS,MAAM,KAAK,gBAAgB,MAAM;AAC3D,UAAI,CAAC,QAAQ,iBAAiB;AAC5B,gBAAQ,kBAAkB,oBAAI,IAAI;AAAA,MACpC;AACA,UACE,CAAC,QAAQ,gBAAgB,IAAI,IAAI,MAChC,QAAQ,OAAO,OAAO,WAAW,QAAQ,IAAI,IAAI,OAClD;AACA,gBAAQ,gBAAgB,IAAI,IAAI;AAChC,gBAAQ,QAAS,KAAK,WAAW,CAAC,EAAe,KAAK;AAAA,MACxD;AAAA,IACF,WAAW,WAAW,mBAAmB,gBAAgB,MAAM;AAC7D,cAAQ;AAAA,QACN,6DAA8D,KAAK,WAAW,CAAC,EAAe;AAAA,MAChG;AACA,cAAQ;AAAA,QACN,KAAK,MAAO,KAAK,WAAW,CAAC,EAAe,KAAK;AAAA,MAGnD;AAAA,IACF,WAAW,KAAK,WAAW,WAAW,GAAG;AACvC,UACE,KAAK,aAAa,YAClB,KAAK,YACL,EAAE,SAAS,KAAK,WAChB;AACA,eAAO;AAAA,UACL;AAAA,UACA,KAAK;AAAA,UACL;AAAA,UACA,KAAK,MAAM,OAA+B,CAAC,OAAO,SAAS;AACzD,kBAAM,sBAAsB,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK;AAC5D,mBAAO;AAAA,UACT,GAAG,CAAC,CAAC;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,UAAI,KAAK,aAAa,UAAU;AAC9B,gBAAQ;AAAA,UACN,KAAK,MAAM,OAAyC,CAAC,OAAO,SAAS;AACnE,kBAAM,KAAK,IAAI,IAAI,KAAK,SAAS;AACjC,mBAAO;AAAA,UACT,GAAG,CAAC,CAAC;AAAA,QACP;AACA,cAAM,MAAM,KAAK,UAAU;AAC3B,YAAI,KAAK;AACP,eAAK,QAAQ,KAAK,MAAM,OAAO,CAAC,SAAS,KAAK,SAAS,KAAK;AAC5D,eAAK,MAAM,KAAK;AAAA,YACd,MAAM;AAAA,YACN,OAAO;AAAA,UACT,CAAC;AACD,cAAI,KAAK,UAAU;AACjB,mBAAO,KAAK,SAAS;AACrB,iBAAK,SAAS,UAAU,IAAI;AAAA,UAC9B;AAAA,QACF;AACA,gBAAQ,SAAS,eAAe,IAAI,CAAC;AAAA,MACvC,OAAO;AACL,gBAAQ;AAAA,UACN,KAAK,MAAM,OAAyC,CAAC,OAAO,SAAS;AACnE,gBAAI,KAAK,SAAS,QAAQ;AACxB,mBAAK,QAAQ,IAAI,IAAI,KAAK,OAAO,QAAQ,IAAI,MAAM,EAAE;AAAA,YACvD;AACA,kBAAM,sBAAsB,KAAK,IAAI,KAAK,KAAK,IAAI,IACjD,KAAK,SAAS;AAChB,mBAAO;AAAA,UACT,GAAG,CAAC,CAAC;AAAA,QACP;AACA,gBAAQ,SAAS,eAAe,IAAI,CAAC;AAAA,MACvC;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,CAAC,QAAQ,QAAQ;AACnB,QAAI,CAAC,QAAQ,uBAAuB;AAClC,cAAQ,wBAAwB,oBAAI,IAAI;AAAA,IAC1C;AAEA,QAAI,gBAAgB,MAAM;AACxB,UAAI,CAAC,QAAQ,sBAAsB,IAAI,IAAI,GAAG;AAC5C,gBAAQ,sBAAsB,IAAI,IAAI;AACtC,QAAC,KAAiB,WAAW,QAAQ,CAAC,cAAc;AAClD,gBAAM,WAAW,OAAO;AAAA,QAC1B,CAAC;AAAA,MACH;AAAA,IACF;AAAO,aAAO;AAAA,EAChB;AAEA,UAAQ,KAAK,UAAU;AAAA,IACrB,KAAK;AACH,aAAO,KAAK,WAAW,OAAc,CAAC,KAAK,cAAc;AACvD,cAAM,SAAS,MAAM,WAAW,OAAO;AACvC,YAAI,WAAW,MAAM;AACnB,cAAI,KAAK,MAAwB;AAAA,QACnC;AACA,eAAO;AAAA,MACT,GAAG,CAAC,CAAC;AAAA,IACP,KAAK;AACH,aAAQ,KAAkB;AAAA,IAC5B,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,SAAS;AACP,YAAM,SAAS,KAAK,UAAU;AAE9B,UACE,KAAK,aAAa,UACjB,WAAW,aACT,QAAQ,OACL,QAAQ,WAAW,QAAQ,IAAI,IAC/B,KAAK,YACL,iBAAiB,KAAK,YACtB,KAAK,SAAS,aAAa,KAC3B,gBAAgB,KAAK,YACrB,QAAQ,SAAS,MAAM,KAC7B;AACA,gBAAQ,aAAa;AAAA,UACnB,QAAQ,KAAK,WAAW,aAAa,KAAK;AAAA,UAC1C,OAAO,KAAK,WAAW,YAAY,KAAK;AAAA,UACxC,SAAU,KAAK,WAAW,cAAc,KACtC;AAAA,UACF,IAAI,QAAQ,SAAS,MAAM,IAAI,SAAS;AAAA,UACxC,MAAO,KAAK,WAAW,WAAW,KAChC;AAAA,QACJ,CAAC;AACD,gBAAQ,SAAS,eAAe,IAAI,CAAC;AACrC,eAAO,KAAK,WAAW,OAAc,CAAC,KAAK,cAAc;AACvD,gBAAM,SAAS,MAAM,WAAW;AAAA,YAC9B,GAAG;AAAA,YACH,QAAQ;AAAA,UACV,CAAC;AACD,cAAI,WAAW,MAAM;AACnB,gBAAI,KAAK,MAAwB;AAAA,UACnC;AACA,iBAAO;AAAA,QACT,GAAG,CAAC,CAAC;AAAA,MACP;AACA,YAAM,aAAc,KAAiB,WAAW;AAAA,QAC9C,CAAC,KAAK,cAAc;AAClB,gBAAM,SAAS,MAAM,WAAW,OAAO;AACvC,cAAI,WAAW,MAAM;AACnB,gBAAI,KAAK,MAAiB;AAAA,UAC5B;AACA,iBAAO;AAAA,QACT;AAAA,QACA,CAAC;AAAA,MACH;AACA,YAAM,WAAW,WAAW,SAAS,IAAI,aAAa,WAAW,CAAC;AAClE,YAAM,YAAa,KAAiB,MAAM,OAKxC,CAAC,OAAO,SAAS;AACjB,YAAI,KAAK,SAAS,SAAS;AACzB,gBAAM,QAAQ,UAAU,KAAK,OAAO;AAAA,YAClC,aAAa;AAAA,UACf,CAAC;AACD,iBAAO;AAAA,QACT;AACA,YAAI,KAAK,aAAa,WAAW,KAAK,SAAS,SAAS;AACtD,gBAAM,eAAe,KAAK;AAC1B,iBAAO;AAAA,QACT;AACA,YAAI,kBAAkB,KAAK,IAAI,GAAG;AAChC,gBAAM,KAAK,IAAI,IAAI,KAAK;AACxB,iBAAO;AAAA,QACT;AACA,cAAM,sBAAsB,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK;AAC5D,eAAO;AAAA,MACT,GAAG,CAAC,CAAC;AACL,UAAI,OAAO,aAAa,aAAa;AACnC,YACE,KAAK,aAAa,YAClB,OAAO,aAAa,YACpB,SAAS,WAAW,GAAG,GACvB;AACA,oBAAU,WAAW,IAAI;AAAA,QAC3B,OAAO;AACL,oBAAU,WAAW;AAAA,QACvB;AAAA,MACF;AACA,UAAI,CAAC,QAAQ,QAAQ;AACnB,YAAI,WAAW,SAAS,GAAG;AACzB,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AACA,aAAO,CAAC,KAAK,KAAK,UAAU,MAAM,WAAW,MAAM,MAAM,CAAC;AAAA,IAC5D;AAAA,EACF;AACF;","names":[]}
|
|
@@ -35,6 +35,7 @@ module.exports = __toCommonJS(fetch_remote_component_exports);
|
|
|
35
35
|
var import_parse5 = require("parse5");
|
|
36
36
|
var import_dom_flight = require("#internal/shared/ssr/dom-flight");
|
|
37
37
|
var import_fetch_headers = require("#internal/shared/ssr/fetch-headers");
|
|
38
|
+
var import_error = require("#internal/shared/error");
|
|
38
39
|
const CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;
|
|
39
40
|
function getBaseUrl(reqHeaders) {
|
|
40
41
|
const host = reqHeaders.get("host");
|
|
@@ -61,14 +62,17 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
61
62
|
credentials: "include"
|
|
62
63
|
};
|
|
63
64
|
const res = await fetch(url, fetchInit);
|
|
64
|
-
if (!res.ok) {
|
|
65
|
-
throw
|
|
66
|
-
|
|
65
|
+
if (!res.ok && !res.body) {
|
|
66
|
+
throw (0, import_error.failedToFetchRemoteComponentError)(
|
|
67
|
+
url.href,
|
|
68
|
+
new Error(`${res.status} ${res.statusText}`)
|
|
67
69
|
);
|
|
68
70
|
}
|
|
69
71
|
const parser = import_parse5.Parser.getFragmentParser();
|
|
70
72
|
if (!res.body) {
|
|
71
|
-
throw new Error(
|
|
73
|
+
throw new Error(
|
|
74
|
+
`Response is empty for Remote Component "${url.href}". Check if you can open it in the browser and you see the Remote Component content.`
|
|
75
|
+
);
|
|
72
76
|
}
|
|
73
77
|
const decoder = new TextDecoder();
|
|
74
78
|
for await (const chunk of res.body) {
|
|
@@ -79,7 +83,8 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
79
83
|
bundle: CURRENT_ZONE ?? "__vercel_remote_component",
|
|
80
84
|
route: "/",
|
|
81
85
|
runtime: "webpack",
|
|
82
|
-
id: "__vercel_remote_component"
|
|
86
|
+
id: "__vercel_remote_component",
|
|
87
|
+
type: "unknown"
|
|
83
88
|
};
|
|
84
89
|
let remoteShared = {};
|
|
85
90
|
const scripts = [];
|
|
@@ -88,11 +93,20 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
88
93
|
let nextData;
|
|
89
94
|
let html = "";
|
|
90
95
|
const remoteName = options.name || url.hash ? url.hash.substring(1) : void 0;
|
|
96
|
+
let hasRemoteComponent = false;
|
|
97
|
+
let hasRSC = false;
|
|
98
|
+
let hasShared = false;
|
|
99
|
+
let hasMultipleRemoteComponents = false;
|
|
100
|
+
let error;
|
|
91
101
|
const rsc = (0, import_dom_flight.visit)(fragment, {
|
|
92
102
|
url,
|
|
93
103
|
name: remoteName,
|
|
94
104
|
onMetadata(_metadata) {
|
|
95
105
|
metadata = _metadata;
|
|
106
|
+
if (hasRemoteComponent && metadata.id !== _metadata.id) {
|
|
107
|
+
hasMultipleRemoteComponents = true;
|
|
108
|
+
}
|
|
109
|
+
hasRemoteComponent = true;
|
|
96
110
|
},
|
|
97
111
|
onScript(attrs) {
|
|
98
112
|
if (!scripts.find((it) => it.src === attrs.src)) {
|
|
@@ -114,6 +128,7 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
114
128
|
},
|
|
115
129
|
onRSC(chunk) {
|
|
116
130
|
hydrationData.push(chunk);
|
|
131
|
+
hasRSC = true;
|
|
117
132
|
},
|
|
118
133
|
onNextData(data) {
|
|
119
134
|
nextData = data;
|
|
@@ -130,8 +145,36 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
130
145
|
},
|
|
131
146
|
onShared(_shared) {
|
|
132
147
|
remoteShared = _shared;
|
|
148
|
+
hasShared = true;
|
|
149
|
+
},
|
|
150
|
+
onError(message, stack) {
|
|
151
|
+
error = new import_error.RemoteComponentsError(message);
|
|
152
|
+
if (stack) {
|
|
153
|
+
error.stack = stack;
|
|
154
|
+
}
|
|
133
155
|
}
|
|
134
156
|
});
|
|
157
|
+
if (error) {
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
if (!hasRemoteComponent) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`No Remote Component found at "${url.href}". Make sure the remote URL is correct and contains a Remote Component.`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
if (hasMultipleRemoteComponents && !remoteName) {
|
|
166
|
+
throw (0, import_error.multipleRemoteComponentsError)(url.href);
|
|
167
|
+
}
|
|
168
|
+
if (!hasRSC && !nextData && metadata.type === "nextjs") {
|
|
169
|
+
throw new Error(
|
|
170
|
+
`The Remote Component at "${url.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.`
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
if (!hasShared && !nextData?.props.__REMOTE_COMPONENT__?.shared) {
|
|
174
|
+
throw new Error(
|
|
175
|
+
`No shared dependencies found for Remote Component at "${url.href}". Make sure the remote URL is correct and contains a Remote Component with shared dependencies.`
|
|
176
|
+
);
|
|
177
|
+
}
|
|
135
178
|
let component;
|
|
136
179
|
if (options.rsc) {
|
|
137
180
|
const componentRSC = `0:${JSON.stringify(rsc)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/shared/ssr/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { visit } from '#internal/shared/ssr/dom-flight';\nimport { remoteFetchHeaders } from '#internal/shared/ssr/fetch-headers';\nimport type { RemoteComponentMetadata } from './types';\n\nconst CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;\n\n/**\n * Resolves the base URL that should be used to fetch the remote component.\n * This function must support local development, Vercel environments, and SSG\n * and dynamic rendering.\n */\nexport function getBaseUrl(reqHeaders: Headers): string {\n const host = reqHeaders.get('host');\n if (host) {\n return host.startsWith('localhost') ? `http://${host}` : `https://${host}`;\n }\n const forwardedHost = reqHeaders.get('x-forwarded-host');\n if (forwardedHost) {\n return `https://${forwardedHost}`;\n }\n if (process.env.VERCEL_PROJECT_PRODUCTION_URL) {\n return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`;\n }\n // TODO: Resolve the correct URL in local development when the proxy is not running.\n return `http://localhost:${process.env.MFE_LOCAL_PROXY_PORT || 3024}`;\n}\n\nexport async function fetchRemoteComponent(\n src: string | URL,\n headers: Headers = new Headers(),\n options: {\n name?: string;\n rsc?: boolean;\n } = {\n rsc: false,\n },\n) {\n const url = new URL(src, getBaseUrl(headers));\n\n const fetchInit = {\n method: 'GET',\n // pass all headers to the remote component\n headers: remoteFetchHeaders(headers),\n credentials: 'include',\n } as RequestInit;\n\n const res = await fetch(url, fetchInit);\n\n if (!res.ok) {\n throw new Error(\n `Failed to fetch remote component \"${url.href}\": ${res.status}`,\n );\n }\n\n // create a parser for the HTML response\n const parser = Parser.getFragmentParser<DefaultTreeAdapterMap>();\n\n if (!res.body) {\n throw new Error(`No response body for remote component \"${url.href}\"`);\n }\n\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 let metadata: RemoteComponentMetadata = {\n bundle: CURRENT_ZONE ?? '__vercel_remote_component',\n route: '/',\n runtime: 'webpack',\n id: '__vercel_remote_component',\n };\n let remoteShared: Record<string, string> = {};\n const scripts: { src: string }[] = [];\n const links: Record<string, string | boolean>[] = [];\n const hydrationData: string[] = [];\n let nextData:\n | {\n props: {\n pageProps: Record<string, unknown>;\n __REMOTE_COMPONENT__?: {\n bundle: string;\n runtime: string;\n shared?: Record<string, string>;\n };\n };\n page?: string;\n buildId?: string;\n }\n | undefined;\n let html = '';\n\n const remoteName =\n options.name || url.hash ? url.hash.substring(1) : undefined;\n // convert the parsed HTML fragment into an RSC flight data\n // and extract the metadata, scripts, links and remote component RSC flight data\n const rsc = visit(fragment, {\n url,\n name: remoteName,\n onMetadata(_metadata) {\n metadata = _metadata;\n },\n onScript(attrs) {\n if (!scripts.find((it) => it.src === attrs.src)) {\n scripts.push({\n src: new URL(attrs.src as string, new URL(url).origin).href,\n });\n }\n },\n onLink(attrs) {\n const relativeAttrs = {\n ...attrs,\n href: new URL(attrs.href as string, new URL(url).origin).href,\n };\n if (\n !links.find(\n (it) => it.href === relativeAttrs.href && it.rel === attrs.rel,\n )\n ) {\n links.push(relativeAttrs);\n }\n },\n onRSC(chunk) {\n hydrationData.push(chunk);\n },\n onNextData(data) {\n nextData = data;\n\n // use the Next.js Pages Router props data to extract remote component metadata\n if (data.props.__REMOTE_COMPONENT__) {\n Object.assign(metadata, data.props.__REMOTE_COMPONENT__);\n // only a singleton remote component is supported per page when using the Next.js Pages Router\n metadata.id = '__next';\n metadata.route = data.page ?? '/';\n }\n },\n onHTML(_html) {\n if (!html.includes(_html)) {\n html += _html;\n }\n },\n onShared(_shared) {\n remoteShared = _shared;\n },\n });\n\n let component: React.ReactNode | undefined;\n\n // only create a React component if requested\n if (options.rsc) {\n // RSC flight data for the static HTML in a single RSC line\n const componentRSC = `0:${JSON.stringify(rsc)}\\n`;\n\n const { createFromReadableStream } = await import(\n 'next/dist/compiled/react-server-dom-webpack/client.edge'\n );\n\n // create a React tree from the RSC flight data\n component = await 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: url.origin,\n crossOrigin: true,\n },\n moduleMap: {},\n },\n },\n );\n }\n\n const name = metadata.id.replace(/_ssr$/, '');\n return {\n name,\n url,\n metadata,\n rsc,\n scripts,\n links,\n hydrationData,\n nextData,\n component,\n html,\n remoteShared: nextData?.props.__REMOTE_COMPONENT__?.shared ?? remoteShared,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAmD;AACnD,wBAAsB;AACtB,2BAAmC;AAGnC,MAAM,eAAe,QAAQ,IAAI;AAO1B,SAAS,WAAW,YAA6B;AACtD,QAAM,OAAO,WAAW,IAAI,MAAM;AAClC,MAAI,MAAM;AACR,WAAO,KAAK,WAAW,WAAW,IAAI,UAAU,SAAS,WAAW;AAAA,EACtE;AACA,QAAM,gBAAgB,WAAW,IAAI,kBAAkB;AACvD,MAAI,eAAe;AACjB,WAAO,WAAW;AAAA,EACpB;AACA,MAAI,QAAQ,IAAI,+BAA+B;AAC7C,WAAO,WAAW,QAAQ,IAAI;AAAA,EAChC;AAEA,SAAO,oBAAoB,QAAQ,IAAI,wBAAwB;AACjE;AAEA,eAAsB,qBACpB,KACA,UAAmB,IAAI,QAAQ,GAC/B,UAGI;AAAA,EACF,KAAK;AACP,GACA;AACA,QAAM,MAAM,IAAI,IAAI,KAAK,WAAW,OAAO,CAAC;AAE5C,QAAM,YAAY;AAAA,IAChB,QAAQ;AAAA;AAAA,IAER,aAAS,yCAAmB,OAAO;AAAA,IACnC,aAAa;AAAA,EACf;AAEA,QAAM,MAAM,MAAM,MAAM,KAAK,SAAS;AAEtC,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI;AAAA,MACR,qCAAqC,IAAI,UAAU,IAAI;AAAA,IACzD;AAAA,EACF;AAGA,QAAM,SAAS,qBAAO,kBAAyC;AAE/D,MAAI,CAAC,IAAI,MAAM;AACb,UAAM,IAAI,MAAM,0CAA0C,IAAI,OAAO;AAAA,EACvE;AAEA,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,MAAI,WAAoC;AAAA,IACtC,QAAQ,gBAAgB;AAAA,IACxB,OAAO;AAAA,IACP,SAAS;AAAA,IACT,IAAI;AAAA,EACN;AACA,MAAI,eAAuC,CAAC;AAC5C,QAAM,UAA6B,CAAC;AACpC,QAAM,QAA4C,CAAC;AACnD,QAAM,gBAA0B,CAAC;AACjC,MAAI;AAcJ,MAAI,OAAO;AAEX,QAAM,aACJ,QAAQ,QAAQ,IAAI,OAAO,IAAI,KAAK,UAAU,CAAC,IAAI;AAGrD,QAAM,UAAM,yBAAM,UAAU;AAAA,IAC1B;AAAA,IACA,MAAM;AAAA,IACN,WAAW,WAAW;AACpB,iBAAW;AAAA,IACb;AAAA,IACA,SAAS,OAAO;AACd,UAAI,CAAC,QAAQ,KAAK,CAAC,OAAO,GAAG,QAAQ,MAAM,GAAG,GAAG;AAC/C,gBAAQ,KAAK;AAAA,UACX,KAAK,IAAI,IAAI,MAAM,KAAe,IAAI,IAAI,GAAG,EAAE,MAAM,EAAE;AAAA,QACzD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,OAAO,OAAO;AACZ,YAAM,gBAAgB;AAAA,QACpB,GAAG;AAAA,QACH,MAAM,IAAI,IAAI,MAAM,MAAgB,IAAI,IAAI,GAAG,EAAE,MAAM,EAAE;AAAA,MAC3D;AACA,UACE,CAAC,MAAM;AAAA,QACL,CAAC,OAAO,GAAG,SAAS,cAAc,QAAQ,GAAG,QAAQ,MAAM;AAAA,MAC7D,GACA;AACA,cAAM,KAAK,aAAa;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,MAAM,OAAO;AACX,oBAAc,KAAK,KAAK;AAAA,IAC1B;AAAA,IACA,WAAW,MAAM;AACf,iBAAW;AAGX,UAAI,KAAK,MAAM,sBAAsB;AACnC,eAAO,OAAO,UAAU,KAAK,MAAM,oBAAoB;AAEvD,iBAAS,KAAK;AACd,iBAAS,QAAQ,KAAK,QAAQ;AAAA,MAChC;AAAA,IACF;AAAA,IACA,OAAO,OAAO;AACZ,UAAI,CAAC,KAAK,SAAS,KAAK,GAAG;AACzB,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,SAAS,SAAS;AAChB,qBAAe;AAAA,IACjB;AAAA,EACF,CAAC;AAED,MAAI;AAGJ,MAAI,QAAQ,KAAK;AAEf,UAAM,eAAe,KAAK,KAAK,UAAU,GAAG;AAAA;AAE5C,UAAM,EAAE,yBAAyB,IAAI,MAAM,OACzC,yDACF;AAGA,gBAAY,MAAM;AAAA,MAChB,IAAI,eAAe;AAAA,QACjB,MAAM;AAAA,QACN,MAAM,YAAY;AAChB,gBAAM,UAAU,IAAI,YAAY;AAChC,qBAAW,QAAQ,QAAQ,OAAO,YAAY,CAAC;AAC/C,qBAAW,MAAM;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,MACD;AAAA,QACE,wBAAwB;AAAA,UACtB,eAAe;AAAA,YACb,QAAQ,IAAI;AAAA,YACZ,aAAa;AAAA,UACf;AAAA,UACA,WAAW,CAAC;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,OAAO,SAAS,GAAG,QAAQ,SAAS,EAAE;AAC5C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,UAAU,MAAM,sBAAsB,UAAU;AAAA,EAChE;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/shared/ssr/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { visit } from '#internal/shared/ssr/dom-flight';\nimport { remoteFetchHeaders } from '#internal/shared/ssr/fetch-headers';\nimport {\n failedToFetchRemoteComponentError,\n multipleRemoteComponentsError,\n RemoteComponentsError,\n} from '#internal/shared/error';\nimport type { RemoteComponentMetadata } from './types';\n\nconst CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;\n\n/**\n * Resolves the base URL that should be used to fetch the remote component.\n * This function must support local development, Vercel environments, and SSG\n * and dynamic rendering.\n */\nexport function getBaseUrl(reqHeaders: Headers): string {\n const host = reqHeaders.get('host');\n if (host) {\n return host.startsWith('localhost') ? `http://${host}` : `https://${host}`;\n }\n const forwardedHost = reqHeaders.get('x-forwarded-host');\n if (forwardedHost) {\n return `https://${forwardedHost}`;\n }\n if (process.env.VERCEL_PROJECT_PRODUCTION_URL) {\n return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`;\n }\n // TODO: Resolve the correct URL in local development when the proxy is not running.\n return `http://localhost:${process.env.MFE_LOCAL_PROXY_PORT || 3024}`;\n}\n\nexport async function fetchRemoteComponent(\n src: string | URL,\n headers: Headers = new Headers(),\n options: {\n name?: string;\n rsc?: boolean;\n } = {\n rsc: false,\n },\n) {\n const url = new URL(src, getBaseUrl(headers));\n\n const fetchInit = {\n method: 'GET',\n // pass all headers to the remote component\n headers: remoteFetchHeaders(headers),\n credentials: 'include',\n } as RequestInit;\n\n const res = await fetch(url, fetchInit);\n\n if (!res.ok && !res.body) {\n throw failedToFetchRemoteComponentError(\n url.href,\n new Error(`${res.status} ${res.statusText}`),\n );\n }\n\n // create a parser for the HTML response\n const parser = Parser.getFragmentParser<DefaultTreeAdapterMap>();\n\n if (!res.body) {\n throw new Error(\n `Response is empty for Remote Component \"${url.href}\". Check if you can open it in the browser and you see the Remote Component content.`,\n );\n }\n\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 let metadata: RemoteComponentMetadata = {\n bundle: CURRENT_ZONE ?? '__vercel_remote_component',\n route: '/',\n runtime: 'webpack',\n id: '__vercel_remote_component',\n type: 'unknown',\n };\n let remoteShared: Record<string, string> = {};\n const scripts: { src: string }[] = [];\n const links: Record<string, string | boolean>[] = [];\n const hydrationData: string[] = [];\n let nextData:\n | {\n props: {\n pageProps: Record<string, unknown>;\n __REMOTE_COMPONENT__?: {\n bundle: string;\n runtime: string;\n shared?: Record<string, string>;\n };\n };\n page?: string;\n buildId?: string;\n }\n | undefined;\n let html = '';\n\n const remoteName =\n options.name || url.hash ? url.hash.substring(1) : undefined;\n // convert the parsed HTML fragment into an RSC flight data\n // and extract the metadata, scripts, links and remote component RSC flight data\n let hasRemoteComponent = false;\n let hasRSC = false;\n let hasShared = false;\n let hasMultipleRemoteComponents = false;\n let error: Error | undefined;\n const rsc = visit(fragment, {\n url,\n name: remoteName,\n onMetadata(_metadata) {\n metadata = _metadata;\n if (hasRemoteComponent && metadata.id !== _metadata.id) {\n hasMultipleRemoteComponents = true;\n }\n hasRemoteComponent = true;\n },\n onScript(attrs) {\n if (!scripts.find((it) => it.src === attrs.src)) {\n scripts.push({\n src: new URL(attrs.src as string, new URL(url).origin).href,\n });\n }\n },\n onLink(attrs) {\n const relativeAttrs = {\n ...attrs,\n href: new URL(attrs.href as string, new URL(url).origin).href,\n };\n if (\n !links.find(\n (it) => it.href === relativeAttrs.href && it.rel === attrs.rel,\n )\n ) {\n links.push(relativeAttrs);\n }\n },\n onRSC(chunk) {\n hydrationData.push(chunk);\n hasRSC = true;\n },\n onNextData(data) {\n nextData = data;\n\n // use the Next.js Pages Router props data to extract remote component metadata\n if (data.props.__REMOTE_COMPONENT__) {\n Object.assign(metadata, data.props.__REMOTE_COMPONENT__);\n // only a singleton remote component is supported per page when using the Next.js Pages Router\n metadata.id = '__next';\n metadata.route = data.page ?? '/';\n }\n },\n onHTML(_html) {\n if (!html.includes(_html)) {\n html += _html;\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 if (error) {\n throw error;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!hasRemoteComponent) {\n throw new Error(\n `No Remote Component found at \"${url.href}\". Make sure the remote URL is correct and contains a Remote Component.`,\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (hasMultipleRemoteComponents && !remoteName) {\n throw multipleRemoteComponentsError(url.href);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!hasRSC && !nextData && metadata.type === 'nextjs') {\n throw new Error(\n `The Remote Component at \"${url.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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!hasShared && !nextData?.props.__REMOTE_COMPONENT__?.shared) {\n throw new Error(\n `No shared dependencies found for Remote Component at \"${url.href}\". Make sure the remote URL is correct and contains a Remote Component with shared dependencies.`,\n );\n }\n\n let component: React.ReactNode | undefined;\n\n // only create a React component if requested\n if (options.rsc) {\n // RSC flight data for the static HTML in a single RSC line\n const componentRSC = `0:${JSON.stringify(rsc)}\\n`;\n\n const { createFromReadableStream } = await import(\n 'next/dist/compiled/react-server-dom-webpack/client.edge'\n );\n\n // create a React tree from the RSC flight data\n component = await 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: url.origin,\n crossOrigin: true,\n },\n moduleMap: {},\n },\n },\n );\n }\n\n const name = metadata.id.replace(/_ssr$/, '');\n return {\n name,\n url,\n metadata,\n rsc,\n scripts,\n links,\n hydrationData,\n nextData,\n component,\n html,\n remoteShared: nextData?.props.__REMOTE_COMPONENT__?.shared ?? remoteShared,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { R as RemoteComponentMetadata } from '../../../types-
|
|
2
|
+
import { R as RemoteComponentMetadata } from '../../../types-e4a3fa37.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Resolves the base URL that should be used to fetch the remote component.
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { Parser } from "parse5";
|
|
2
2
|
import { visit } from "#internal/shared/ssr/dom-flight";
|
|
3
3
|
import { remoteFetchHeaders } from "#internal/shared/ssr/fetch-headers";
|
|
4
|
+
import {
|
|
5
|
+
failedToFetchRemoteComponentError,
|
|
6
|
+
multipleRemoteComponentsError,
|
|
7
|
+
RemoteComponentsError
|
|
8
|
+
} from "#internal/shared/error";
|
|
4
9
|
const CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;
|
|
5
10
|
function getBaseUrl(reqHeaders) {
|
|
6
11
|
const host = reqHeaders.get("host");
|
|
@@ -27,14 +32,17 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
27
32
|
credentials: "include"
|
|
28
33
|
};
|
|
29
34
|
const res = await fetch(url, fetchInit);
|
|
30
|
-
if (!res.ok) {
|
|
31
|
-
throw
|
|
32
|
-
|
|
35
|
+
if (!res.ok && !res.body) {
|
|
36
|
+
throw failedToFetchRemoteComponentError(
|
|
37
|
+
url.href,
|
|
38
|
+
new Error(`${res.status} ${res.statusText}`)
|
|
33
39
|
);
|
|
34
40
|
}
|
|
35
41
|
const parser = Parser.getFragmentParser();
|
|
36
42
|
if (!res.body) {
|
|
37
|
-
throw new Error(
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Response is empty for Remote Component "${url.href}". Check if you can open it in the browser and you see the Remote Component content.`
|
|
45
|
+
);
|
|
38
46
|
}
|
|
39
47
|
const decoder = new TextDecoder();
|
|
40
48
|
for await (const chunk of res.body) {
|
|
@@ -45,7 +53,8 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
45
53
|
bundle: CURRENT_ZONE ?? "__vercel_remote_component",
|
|
46
54
|
route: "/",
|
|
47
55
|
runtime: "webpack",
|
|
48
|
-
id: "__vercel_remote_component"
|
|
56
|
+
id: "__vercel_remote_component",
|
|
57
|
+
type: "unknown"
|
|
49
58
|
};
|
|
50
59
|
let remoteShared = {};
|
|
51
60
|
const scripts = [];
|
|
@@ -54,11 +63,20 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
54
63
|
let nextData;
|
|
55
64
|
let html = "";
|
|
56
65
|
const remoteName = options.name || url.hash ? url.hash.substring(1) : void 0;
|
|
66
|
+
let hasRemoteComponent = false;
|
|
67
|
+
let hasRSC = false;
|
|
68
|
+
let hasShared = false;
|
|
69
|
+
let hasMultipleRemoteComponents = false;
|
|
70
|
+
let error;
|
|
57
71
|
const rsc = visit(fragment, {
|
|
58
72
|
url,
|
|
59
73
|
name: remoteName,
|
|
60
74
|
onMetadata(_metadata) {
|
|
61
75
|
metadata = _metadata;
|
|
76
|
+
if (hasRemoteComponent && metadata.id !== _metadata.id) {
|
|
77
|
+
hasMultipleRemoteComponents = true;
|
|
78
|
+
}
|
|
79
|
+
hasRemoteComponent = true;
|
|
62
80
|
},
|
|
63
81
|
onScript(attrs) {
|
|
64
82
|
if (!scripts.find((it) => it.src === attrs.src)) {
|
|
@@ -80,6 +98,7 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
80
98
|
},
|
|
81
99
|
onRSC(chunk) {
|
|
82
100
|
hydrationData.push(chunk);
|
|
101
|
+
hasRSC = true;
|
|
83
102
|
},
|
|
84
103
|
onNextData(data) {
|
|
85
104
|
nextData = data;
|
|
@@ -96,8 +115,36 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
96
115
|
},
|
|
97
116
|
onShared(_shared) {
|
|
98
117
|
remoteShared = _shared;
|
|
118
|
+
hasShared = true;
|
|
119
|
+
},
|
|
120
|
+
onError(message, stack) {
|
|
121
|
+
error = new RemoteComponentsError(message);
|
|
122
|
+
if (stack) {
|
|
123
|
+
error.stack = stack;
|
|
124
|
+
}
|
|
99
125
|
}
|
|
100
126
|
});
|
|
127
|
+
if (error) {
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
if (!hasRemoteComponent) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
`No Remote Component found at "${url.href}". Make sure the remote URL is correct and contains a Remote Component.`
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
if (hasMultipleRemoteComponents && !remoteName) {
|
|
136
|
+
throw multipleRemoteComponentsError(url.href);
|
|
137
|
+
}
|
|
138
|
+
if (!hasRSC && !nextData && metadata.type === "nextjs") {
|
|
139
|
+
throw new Error(
|
|
140
|
+
`The Remote Component at "${url.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.`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
if (!hasShared && !nextData?.props.__REMOTE_COMPONENT__?.shared) {
|
|
144
|
+
throw new Error(
|
|
145
|
+
`No shared dependencies found for Remote Component at "${url.href}". Make sure the remote URL is correct and contains a Remote Component with shared dependencies.`
|
|
146
|
+
);
|
|
147
|
+
}
|
|
101
148
|
let component;
|
|
102
149
|
if (options.rsc) {
|
|
103
150
|
const componentRSC = `0:${JSON.stringify(rsc)}
|