remote-components 0.0.43 → 0.0.44
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-2ca91ad8.d.ts → component-loader-26b1f55e.d.ts} +63 -1
- package/dist/html/host.cjs +25 -19
- package/dist/html/host.cjs.map +1 -1
- package/dist/html/host.js +25 -19
- package/dist/html/host.js.map +1 -1
- package/dist/internal/next/host/app-router-client.d.ts +1 -1
- package/dist/internal/next/remote/render-client.cjs +1 -1
- package/dist/internal/next/remote/render-client.cjs.map +1 -1
- package/dist/internal/next/remote/render-client.js +1 -1
- package/dist/internal/next/remote/render-client.js.map +1 -1
- package/dist/internal/shared/client/remote-component.d.ts +2 -2
- package/dist/internal/shared/ssr/dom-flight.d.ts +1 -1
- package/dist/internal/shared/ssr/fetch-headers.cjs +4 -6
- package/dist/internal/shared/ssr/fetch-headers.cjs.map +1 -1
- package/dist/internal/shared/ssr/fetch-headers.d.ts +1 -1
- package/dist/internal/shared/ssr/fetch-headers.js +4 -6
- package/dist/internal/shared/ssr/fetch-headers.js.map +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.cjs +14 -23
- package/dist/internal/shared/ssr/fetch-remote-component.cjs.map +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.d.ts +5 -9
- package/dist/internal/shared/ssr/fetch-remote-component.js +13 -21
- package/dist/internal/shared/ssr/fetch-remote-component.js.map +1 -1
- package/dist/internal/shared/ssr/fetch-with-hooks.cjs +40 -0
- package/dist/internal/shared/ssr/fetch-with-hooks.cjs.map +1 -0
- package/dist/internal/shared/ssr/fetch-with-hooks.d.ts +39 -0
- package/dist/internal/shared/ssr/fetch-with-hooks.js +16 -0
- package/dist/internal/shared/ssr/fetch-with-hooks.js.map +1 -0
- package/dist/internal/shared/ssr/get-ssr-relative-path-base-url.cjs.map +1 -1
- package/dist/internal/shared/ssr/get-ssr-relative-path-base-url.js.map +1 -1
- package/dist/next/config.cjs +1 -9
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.js +1 -9
- package/dist/next/config.js.map +1 -1
- package/dist/next/host/app-router-server.cjs +7 -8
- package/dist/next/host/app-router-server.cjs.map +1 -1
- package/dist/next/host/app-router-server.d.ts +13 -4
- package/dist/next/host/app-router-server.js +7 -8
- package/dist/next/host/app-router-server.js.map +1 -1
- package/dist/next/host/client/index.cjs +29 -12
- 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 +29 -12
- package/dist/next/host/client/index.js.map +1 -1
- package/dist/next/host/pages-router-client.cjs +62 -2
- package/dist/next/host/pages-router-client.cjs.map +1 -1
- package/dist/next/host/pages-router-client.d.ts +26 -1
- package/dist/next/host/pages-router-client.js +63 -3
- package/dist/next/host/pages-router-client.js.map +1 -1
- package/dist/next/host/pages-router-server.cjs +18 -22
- package/dist/next/host/pages-router-server.cjs.map +1 -1
- package/dist/next/host/pages-router-server.d.ts +36 -3
- package/dist/next/host/pages-router-server.js +18 -22
- package/dist/next/host/pages-router-server.js.map +1 -1
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.ts +1 -1
- package/dist/next/index.js.map +1 -1
- package/dist/react/index.cjs +29 -12
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.ts +13 -5
- package/dist/react/index.js +29 -12
- package/dist/react/index.js.map +1 -1
- package/dist/shared/host/app.cjs +1 -1
- package/dist/shared/host/app.cjs.map +1 -1
- package/dist/shared/host/app.js +1 -1
- package/dist/shared/host/app.js.map +1 -1
- package/dist/shared/host/pages.cjs +1 -1
- package/dist/shared/host/pages.cjs.map +1 -1
- package/dist/shared/host/pages.js +1 -1
- package/dist/shared/host/pages.js.map +1 -1
- package/dist/shared/remote/app.cjs +1 -1
- package/dist/shared/remote/app.cjs.map +1 -1
- package/dist/shared/remote/app.js +1 -1
- package/dist/shared/remote/app.js.map +1 -1
- package/dist/shared/remote/pages.cjs +1 -1
- package/dist/shared/remote/pages.cjs.map +1 -1
- package/dist/shared/remote/pages.js +1 -1
- package/dist/shared/remote/pages.js.map +1 -1
- package/dist/types-2ab78f67.d.ts +71 -0
- package/package.json +54 -32
- package/dist/types-cbf6c34f.d.ts +0 -9
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
|
-
import { R as RemoteComponentMetadata } from '../../../types-
|
|
3
|
+
import { R as RemoteComponentMetadata } from '../../../types-2ab78f67.js';
|
|
4
4
|
|
|
5
5
|
interface RemoteComponentProps {
|
|
6
6
|
/** The src provided to the `<RemoteComponent>` component. May be relative or absolute URL. */
|
|
@@ -48,7 +48,7 @@ async function tryImportShared() {
|
|
|
48
48
|
} catch {
|
|
49
49
|
return {
|
|
50
50
|
// eslint-disable-next-line camelcase
|
|
51
|
-
__remote_components_missing_shared__: "Remote Components shared
|
|
51
|
+
__remote_components_missing_shared__: "Remote Components shared modules not found. Did you forget to wrap your config with `withRemoteComponents` on both host and remote?"
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/next/remote/render-client.tsx"],"sourcesContent":["'use client';\n\nimport { use } from 'react';\nimport { RemoteComponentsError } from '#internal/shared/client/remote-component';\n\n// try to import the shared module from the remote application\n// use an empty object as a fallback if the import fails to avoid breaking the application\nasync function tryImportShared() {\n try {\n const self = globalThis as unknown as {\n TURBOPACK_REMOTE_SHARED: { shared: Record<string, string> };\n };\n // this is a marker to find the shared module initializer in the Turbopack bundle\n // DO NOT REMOVE\n self.TURBOPACK_REMOTE_SHARED = await import(\n 'remote-components/shared/remote/app'\n );\n const { shared } = self.TURBOPACK_REMOTE_SHARED;\n return shared;\n } catch {\n return {\n // eslint-disable-next-line camelcase\n __remote_components_missing_shared__:\n 'Remote Components shared
|
|
1
|
+
{"version":3,"sources":["../../../../src/next/remote/render-client.tsx"],"sourcesContent":["'use client';\n\nimport { use } from 'react';\nimport { RemoteComponentsError } from '#internal/shared/client/remote-component';\n\n// try to import the shared module from the remote application\n// use an empty object as a fallback if the import fails to avoid breaking the application\nasync function tryImportShared() {\n try {\n const self = globalThis as unknown as {\n TURBOPACK_REMOTE_SHARED: { shared: Record<string, string> };\n };\n // this is a marker to find the shared module initializer in the Turbopack bundle\n // DO NOT REMOVE\n self.TURBOPACK_REMOTE_SHARED = await import(\n 'remote-components/shared/remote/app'\n );\n const { shared } = self.TURBOPACK_REMOTE_SHARED;\n return shared;\n } catch {\n return {\n // eslint-disable-next-line camelcase\n __remote_components_missing_shared__:\n 'Remote Components shared modules not found. Did you forget to wrap your config with `withRemoteComponents` on both host and remote?',\n };\n }\n}\n\n// create a promise singleton to import the shared module\nexport const tryImportSharedPromise = tryImportShared();\n\nexport function RemoteComponentSharedRemote({ name }: { name: string }) {\n const shared = use(tryImportSharedPromise);\n\n if ('__remote_components_missing_shared__' in shared) {\n throw new RemoteComponentsError(\n shared.__remote_components_missing_shared__,\n );\n }\n\n return (\n // render the shared module as a script tag\n <script\n data-remote-components-shared=\"\"\n id={`${name}_shared`}\n type=\"application/json\"\n >\n {JSON.stringify(shared)}\n </script>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0CI;AAAA;AAAA;AAAA;AAxCJ,mBAAoB;AACpB,8BAAsC;AAItC,eAAe,kBAAkB;AAC/B,MAAI;AACF,UAAM,OAAO;AAKb,SAAK,0BAA0B,MAAM,OACnC,qCACF;AACA,UAAM,EAAE,OAAO,IAAI,KAAK;AACxB,WAAO;AAAA,EACT,QAAE;AACA,WAAO;AAAA;AAAA,MAEL,sCACE;AAAA,IACJ;AAAA,EACF;AACF;AAGO,MAAM,yBAAyB,gBAAgB;AAE/C,SAAS,4BAA4B,EAAE,KAAK,GAAqB;AACtE,QAAM,aAAS,kBAAI,sBAAsB;AAEzC,MAAI,0CAA0C,QAAQ;AACpD,UAAM,IAAI;AAAA,MACR,OAAO;AAAA,IACT;AAAA,EACF;AAEA,SAEE;AAAA,IAAC;AAAA;AAAA,MACC,iCAA8B;AAAA,MAC9B,IAAI,GAAG;AAAA,MACP,MAAK;AAAA,MAEJ,eAAK,UAAU,MAAM;AAAA;AAAA,EACxB;AAEJ;","names":[]}
|
|
@@ -11,7 +11,7 @@ async function tryImportShared() {
|
|
|
11
11
|
} catch {
|
|
12
12
|
return {
|
|
13
13
|
// eslint-disable-next-line camelcase
|
|
14
|
-
__remote_components_missing_shared__: "Remote Components shared
|
|
14
|
+
__remote_components_missing_shared__: "Remote Components shared modules not found. Did you forget to wrap your config with `withRemoteComponents` on both host and remote?"
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/next/remote/render-client.tsx"],"sourcesContent":["'use client';\n\nimport { use } from 'react';\nimport { RemoteComponentsError } from '#internal/shared/client/remote-component';\n\n// try to import the shared module from the remote application\n// use an empty object as a fallback if the import fails to avoid breaking the application\nasync function tryImportShared() {\n try {\n const self = globalThis as unknown as {\n TURBOPACK_REMOTE_SHARED: { shared: Record<string, string> };\n };\n // this is a marker to find the shared module initializer in the Turbopack bundle\n // DO NOT REMOVE\n self.TURBOPACK_REMOTE_SHARED = await import(\n 'remote-components/shared/remote/app'\n );\n const { shared } = self.TURBOPACK_REMOTE_SHARED;\n return shared;\n } catch {\n return {\n // eslint-disable-next-line camelcase\n __remote_components_missing_shared__:\n 'Remote Components shared
|
|
1
|
+
{"version":3,"sources":["../../../../src/next/remote/render-client.tsx"],"sourcesContent":["'use client';\n\nimport { use } from 'react';\nimport { RemoteComponentsError } from '#internal/shared/client/remote-component';\n\n// try to import the shared module from the remote application\n// use an empty object as a fallback if the import fails to avoid breaking the application\nasync function tryImportShared() {\n try {\n const self = globalThis as unknown as {\n TURBOPACK_REMOTE_SHARED: { shared: Record<string, string> };\n };\n // this is a marker to find the shared module initializer in the Turbopack bundle\n // DO NOT REMOVE\n self.TURBOPACK_REMOTE_SHARED = await import(\n 'remote-components/shared/remote/app'\n );\n const { shared } = self.TURBOPACK_REMOTE_SHARED;\n return shared;\n } catch {\n return {\n // eslint-disable-next-line camelcase\n __remote_components_missing_shared__:\n 'Remote Components shared modules not found. Did you forget to wrap your config with `withRemoteComponents` on both host and remote?',\n };\n }\n}\n\n// create a promise singleton to import the shared module\nexport const tryImportSharedPromise = tryImportShared();\n\nexport function RemoteComponentSharedRemote({ name }: { name: string }) {\n const shared = use(tryImportSharedPromise);\n\n if ('__remote_components_missing_shared__' in shared) {\n throw new RemoteComponentsError(\n shared.__remote_components_missing_shared__,\n );\n }\n\n return (\n // render the shared module as a script tag\n <script\n data-remote-components-shared=\"\"\n id={`${name}_shared`}\n type=\"application/json\"\n >\n {JSON.stringify(shared)}\n </script>\n );\n}\n"],"mappings":";AA0CI;AAxCJ,SAAS,WAAW;AACpB,SAAS,6BAA6B;AAItC,eAAe,kBAAkB;AAC/B,MAAI;AACF,UAAM,OAAO;AAKb,SAAK,0BAA0B,MAAM,OACnC,qCACF;AACA,UAAM,EAAE,OAAO,IAAI,KAAK;AACxB,WAAO;AAAA,EACT,QAAE;AACA,WAAO;AAAA;AAAA,MAEL,sCACE;AAAA,IACJ;AAAA,EACF;AACF;AAGO,MAAM,yBAAyB,gBAAgB;AAE/C,SAAS,4BAA4B,EAAE,KAAK,GAAqB;AACtE,QAAM,SAAS,IAAI,sBAAsB;AAEzC,MAAI,0CAA0C,QAAQ;AACpD,UAAM,IAAI;AAAA,MACR,OAAO;AAAA,IACT;AAAA,EACF;AAEA;AAAA;AAAA,IAEE;AAAA,MAAC;AAAA;AAAA,QACC,iCAA8B;AAAA,QAC9B,IAAI,GAAG;AAAA,QACP,MAAK;AAAA,QAEJ,eAAK,UAAU,MAAM;AAAA;AAAA,IACxB;AAAA;AAEJ;","names":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MountOrUnmountFunction } from '../../../component-loader-
|
|
2
|
-
export { G as GlobalScope, L as LoadRemoteComponentProps,
|
|
1
|
+
import { M as MountOrUnmountFunction } from '../../../component-loader-26b1f55e.js';
|
|
2
|
+
export { G as GlobalScope, L as LoadRemoteComponentProps, b as LoaderResult, R as RemoteComponentProps, l as loadRemoteComponent } from '../../../component-loader-26b1f55e.js';
|
|
3
3
|
import { ReadableStream } from 'web-streams-polyfill';
|
|
4
4
|
import 'react';
|
|
5
5
|
|
|
@@ -21,19 +21,17 @@ __export(fetch_headers_exports, {
|
|
|
21
21
|
remoteFetchHeaders: () => remoteFetchHeaders
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(fetch_headers_exports);
|
|
24
|
-
function remoteFetchHeaders(
|
|
24
|
+
function remoteFetchHeaders() {
|
|
25
25
|
return {
|
|
26
26
|
/**
|
|
27
27
|
* Authenticates deployment protection for the remote. Needed for SSR and SSG clients.
|
|
28
|
-
*
|
|
29
|
-
*
|
|
28
|
+
* If the remote component uses vercel deployment protection, ensure the host and remote vercel
|
|
29
|
+
* projects share a common automation bypass secret, and the shared secret is used as the
|
|
30
|
+
* VERCEL_AUTOMATION_BYPASS_SECRET env var in the host project.
|
|
30
31
|
*/
|
|
31
32
|
...typeof process === "object" && typeof process.env === "object" && typeof process.env.VERCEL_AUTOMATION_BYPASS_SECRET === "string" ? {
|
|
32
33
|
"x-vercel-protection-bypass": process.env.VERCEL_AUTOMATION_BYPASS_SECRET
|
|
33
34
|
} : {},
|
|
34
|
-
...Object.fromEntries(
|
|
35
|
-
additionalHeaders instanceof Headers ? additionalHeaders.entries() : Object.entries(additionalHeaders ?? {})
|
|
36
|
-
),
|
|
37
35
|
Accept: "text/html"
|
|
38
36
|
};
|
|
39
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/shared/ssr/fetch-headers.ts"],"sourcesContent":["/**\n * The headers to use when fetching the remote component.\n */\nexport function remoteFetchHeaders(
|
|
1
|
+
{"version":3,"sources":["../../../../src/shared/ssr/fetch-headers.ts"],"sourcesContent":["/**\n * The headers to use when fetching the remote component.\n */\nexport function remoteFetchHeaders() {\n return {\n /**\n * Authenticates deployment protection for the remote. Needed for SSR and SSG clients.\n * If the remote component uses vercel deployment protection, ensure the host and remote vercel\n * projects share a common automation bypass secret, and the shared secret is used as the\n * VERCEL_AUTOMATION_BYPASS_SECRET env var in the host project.\n */\n ...(typeof process === 'object' &&\n typeof process.env === 'object' &&\n typeof process.env.VERCEL_AUTOMATION_BYPASS_SECRET === 'string'\n ? {\n 'x-vercel-protection-bypass':\n process.env.VERCEL_AUTOMATION_BYPASS_SECRET,\n }\n : {}),\n Accept: 'text/html',\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,SAAS,qBAAqB;AACnC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOL,GAAI,OAAO,YAAY,YACvB,OAAO,QAAQ,QAAQ,YACvB,OAAO,QAAQ,IAAI,oCAAoC,WACnD;AAAA,MACE,8BACE,QAAQ,IAAI;AAAA,IAChB,IACA,CAAC;AAAA,IACL,QAAQ;AAAA,EACV;AACF;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The headers to use when fetching the remote component.
|
|
3
3
|
*/
|
|
4
|
-
declare function remoteFetchHeaders(
|
|
4
|
+
declare function remoteFetchHeaders(): {
|
|
5
5
|
Accept: string;
|
|
6
6
|
'x-vercel-protection-bypass'?: string | undefined;
|
|
7
7
|
};
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
function remoteFetchHeaders(
|
|
1
|
+
function remoteFetchHeaders() {
|
|
2
2
|
return {
|
|
3
3
|
/**
|
|
4
4
|
* Authenticates deployment protection for the remote. Needed for SSR and SSG clients.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* If the remote component uses vercel deployment protection, ensure the host and remote vercel
|
|
6
|
+
* projects share a common automation bypass secret, and the shared secret is used as the
|
|
7
|
+
* VERCEL_AUTOMATION_BYPASS_SECRET env var in the host project.
|
|
7
8
|
*/
|
|
8
9
|
...typeof process === "object" && typeof process.env === "object" && typeof process.env.VERCEL_AUTOMATION_BYPASS_SECRET === "string" ? {
|
|
9
10
|
"x-vercel-protection-bypass": process.env.VERCEL_AUTOMATION_BYPASS_SECRET
|
|
10
11
|
} : {},
|
|
11
|
-
...Object.fromEntries(
|
|
12
|
-
additionalHeaders instanceof Headers ? additionalHeaders.entries() : Object.entries(additionalHeaders ?? {})
|
|
13
|
-
),
|
|
14
12
|
Accept: "text/html"
|
|
15
13
|
};
|
|
16
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/shared/ssr/fetch-headers.ts"],"sourcesContent":["/**\n * The headers to use when fetching the remote component.\n */\nexport function remoteFetchHeaders(
|
|
1
|
+
{"version":3,"sources":["../../../../src/shared/ssr/fetch-headers.ts"],"sourcesContent":["/**\n * The headers to use when fetching the remote component.\n */\nexport function remoteFetchHeaders() {\n return {\n /**\n * Authenticates deployment protection for the remote. Needed for SSR and SSG clients.\n * If the remote component uses vercel deployment protection, ensure the host and remote vercel\n * projects share a common automation bypass secret, and the shared secret is used as the\n * VERCEL_AUTOMATION_BYPASS_SECRET env var in the host project.\n */\n ...(typeof process === 'object' &&\n typeof process.env === 'object' &&\n typeof process.env.VERCEL_AUTOMATION_BYPASS_SECRET === 'string'\n ? {\n 'x-vercel-protection-bypass':\n process.env.VERCEL_AUTOMATION_BYPASS_SECRET,\n }\n : {}),\n Accept: 'text/html',\n };\n}\n"],"mappings":"AAGO,SAAS,qBAAqB;AACnC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOL,GAAI,OAAO,YAAY,YACvB,OAAO,QAAQ,QAAQ,YACvB,OAAO,QAAQ,IAAI,oCAAoC,WACnD;AAAA,MACE,8BACE,QAAQ,IAAI;AAAA,IAChB,IACA,CAAC;AAAA,IACL,QAAQ;AAAA,EACV;AACF;","names":[]}
|
|
@@ -28,8 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
var fetch_remote_component_exports = {};
|
|
30
30
|
__export(fetch_remote_component_exports, {
|
|
31
|
-
fetchRemoteComponent: () => fetchRemoteComponent
|
|
32
|
-
getBaseUrl: () => getBaseUrl
|
|
31
|
+
fetchRemoteComponent: () => fetchRemoteComponent
|
|
33
32
|
});
|
|
34
33
|
module.exports = __toCommonJS(fetch_remote_component_exports);
|
|
35
34
|
var import_parse5 = require("parse5");
|
|
@@ -37,30 +36,23 @@ var import_get_client_src = require("#internal/shared/client/get-client-src");
|
|
|
37
36
|
var import_error = require("#internal/shared/error");
|
|
38
37
|
var import_dom_flight = require("#internal/shared/ssr/dom-flight");
|
|
39
38
|
var import_fetch_headers = require("#internal/shared/ssr/fetch-headers");
|
|
39
|
+
var import_fetch_with_hooks = require("#internal/shared/ssr/fetch-with-hooks");
|
|
40
40
|
var import_get_ssr_relative_path_base_url = require("#internal/shared/ssr/get-ssr-relative-path-base-url");
|
|
41
41
|
const CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;
|
|
42
|
-
function
|
|
43
|
-
const host = reqHeaders.get("host");
|
|
44
|
-
if (host) {
|
|
45
|
-
return host.startsWith("localhost") ? `http://${host}` : `https://${host}`;
|
|
46
|
-
}
|
|
47
|
-
const forwardedHost = reqHeaders.get("x-forwarded-host");
|
|
48
|
-
if (forwardedHost) {
|
|
49
|
-
return `https://${forwardedHost}`;
|
|
50
|
-
}
|
|
51
|
-
return (0, import_get_ssr_relative_path_base_url.getSSRRelativePathBaseUrl)();
|
|
52
|
-
}
|
|
53
|
-
async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
42
|
+
async function fetchRemoteComponent(src, options = {
|
|
54
43
|
rsc: false
|
|
55
44
|
}) {
|
|
56
|
-
const serverUrl = new URL(src,
|
|
45
|
+
const serverUrl = new URL(src, (0, import_get_ssr_relative_path_base_url.getSSRRelativePathBaseUrl)());
|
|
57
46
|
const fetchInit = {
|
|
58
47
|
method: "GET",
|
|
59
48
|
// pass all headers to the remote component
|
|
60
|
-
headers: (0, import_fetch_headers.remoteFetchHeaders)(
|
|
49
|
+
headers: (0, import_fetch_headers.remoteFetchHeaders)(),
|
|
61
50
|
credentials: "include"
|
|
62
51
|
};
|
|
63
|
-
const res = await
|
|
52
|
+
const res = await (0, import_fetch_with_hooks.fetchWithHooks)(serverUrl, fetchInit, {
|
|
53
|
+
onRequest: options.onRequest,
|
|
54
|
+
onResponse: options.onResponse
|
|
55
|
+
});
|
|
64
56
|
if (!res.ok && !res.body) {
|
|
65
57
|
throw (0, import_error.failedToFetchRemoteComponentError)(serverUrl.href, res);
|
|
66
58
|
}
|
|
@@ -68,7 +60,7 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
68
60
|
throw (0, import_error.failedToFetchRemoteComponentError)(
|
|
69
61
|
serverUrl.href,
|
|
70
62
|
res,
|
|
71
|
-
|
|
63
|
+
"If you are using Deployment Protection, ensure the automation bypass environment variable secret in the host matches an automation bypass value in the remote."
|
|
72
64
|
);
|
|
73
65
|
}
|
|
74
66
|
if (res.status === 404) {
|
|
@@ -104,7 +96,7 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
104
96
|
const hydrationData = [];
|
|
105
97
|
let nextData;
|
|
106
98
|
let html = "";
|
|
107
|
-
const remoteName = options.name || serverUrl.hash ? serverUrl.hash.substring(1) : void 0;
|
|
99
|
+
const remoteName = options.name || (serverUrl.hash ? serverUrl.hash.substring(1) : void 0);
|
|
108
100
|
let hasRemoteComponent = false;
|
|
109
101
|
let hasRSC = false;
|
|
110
102
|
let hasShared = false;
|
|
@@ -114,10 +106,10 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
114
106
|
url: serverUrl,
|
|
115
107
|
name: remoteName,
|
|
116
108
|
onMetadata(_metadata) {
|
|
117
|
-
metadata
|
|
118
|
-
if (hasRemoteComponent && metadata.id !== _metadata.id) {
|
|
109
|
+
if (hasRemoteComponent && metadata.id !== _metadata.id && _metadata.id !== "__next" && metadata.id !== "__next" && !nextData) {
|
|
119
110
|
hasMultipleRemoteComponents = true;
|
|
120
111
|
}
|
|
112
|
+
metadata = _metadata;
|
|
121
113
|
hasRemoteComponent = true;
|
|
122
114
|
},
|
|
123
115
|
onScript(attrs) {
|
|
@@ -240,7 +232,6 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
240
232
|
}
|
|
241
233
|
// Annotate the CommonJS export names for ESM import in node:
|
|
242
234
|
0 && (module.exports = {
|
|
243
|
-
fetchRemoteComponent
|
|
244
|
-
getBaseUrl
|
|
235
|
+
fetchRemoteComponent
|
|
245
236
|
});
|
|
246
237
|
//# sourceMappingURL=fetch-remote-component.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/shared/ssr/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { getClientSrc } from '#internal/shared/client/get-client-src';\nimport {\n failedToFetchRemoteComponentError,\n multipleRemoteComponentsError,\n RemoteComponentsError,\n} from '#internal/shared/error';\nimport { visit } from '#internal/shared/ssr/dom-flight';\nimport { remoteFetchHeaders } from '#internal/shared/ssr/fetch-headers';\nimport { getSSRRelativePathBaseUrl } from '#internal/shared/ssr/get-ssr-relative-path-base-url';\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 return getSSRRelativePathBaseUrl();\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 serverUrl = 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(serverUrl, fetchInit);\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. Otherwise, manually specify x-vercel-protection-bypass for the remote in the \"additionalHeaders\" parameter.',\n );\n }\n\n if (res.status === 404) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n 'Check if you can open it in the browser.',\n );\n }\n\n // create a parser for the HTML response\n const parser = Parser.getFragmentParser<DefaultTreeAdapterMap>();\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 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; textContent?: 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 || serverUrl.hash ? serverUrl.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: RemoteComponentsError | undefined;\n const rsc = visit(fragment, {\n url: serverUrl,\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 const clientSrc = getClientSrc(attrs.src, serverUrl.href);\n if (\n !scripts.find(\n (it) =>\n it.src === clientSrc ||\n (attrs.textContent && it.textContent === attrs.textContent),\n )\n ) {\n scripts.push(\n typeof attrs.textContent === 'string'\n ? {\n src: '',\n textContent: attrs.textContent,\n }\n : {\n src: clientSrc,\n },\n );\n }\n },\n onLink(attrs) {\n const relativeAttrs = {\n ...attrs,\n href: getClientSrc(attrs.href, serverUrl.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 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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (hasMultipleRemoteComponents && !remoteName) {\n throw multipleRemoteComponentsError(serverUrl.href);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n !hasShared &&\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 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: serverUrl.origin,\n crossOrigin: true,\n },\n moduleMap: {},\n },\n },\n );\n }\n\n const name = metadata.id.replace(/_ssr$/, '');\n return {\n name,\n serverUrl,\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
|
+
{"version":3,"sources":["../../../../src/shared/ssr/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { getClientSrc } from '#internal/shared/client/get-client-src';\nimport {\n failedToFetchRemoteComponentError,\n multipleRemoteComponentsError,\n RemoteComponentsError,\n} from '#internal/shared/error';\nimport { visit } from '#internal/shared/ssr/dom-flight';\nimport { remoteFetchHeaders } from '#internal/shared/ssr/fetch-headers';\nimport { fetchWithHooks } from '#internal/shared/ssr/fetch-with-hooks';\nimport { getSSRRelativePathBaseUrl } from '#internal/shared/ssr/get-ssr-relative-path-base-url';\nimport type {\n OnRequestHook,\n OnResponseHook,\n RemoteComponentMetadata,\n} from './types';\n\nconst CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;\n\nexport async function fetchRemoteComponent(\n src: string | URL,\n options: {\n name?: string;\n rsc?: boolean;\n onRequest?: OnRequestHook;\n onResponse?: OnResponseHook;\n } = {\n rsc: false,\n },\n) {\n const serverUrl = new URL(src, getSSRRelativePathBaseUrl());\n\n const fetchInit = {\n method: 'GET',\n // pass all headers to the remote component\n headers: remoteFetchHeaders(),\n credentials: 'include',\n } as RequestInit;\n\n const res = await fetchWithHooks(serverUrl, fetchInit, {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\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.',\n );\n }\n\n if (res.status === 404) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n 'Check if you can open it in the browser.',\n );\n }\n\n // create a parser for the HTML response\n const parser = Parser.getFragmentParser<DefaultTreeAdapterMap>();\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 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; textContent?: 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 || (serverUrl.hash ? serverUrl.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: RemoteComponentsError | undefined;\n const rsc = visit(fragment, {\n url: serverUrl,\n name: remoteName,\n onMetadata(_metadata) {\n // Skip multiple component detection for Pages Router (__next) since it only supports one remote component per page\n if (\n hasRemoteComponent &&\n metadata.id !== _metadata.id &&\n _metadata.id !== '__next' &&\n metadata.id !== '__next' &&\n !nextData\n ) {\n hasMultipleRemoteComponents = true;\n }\n metadata = _metadata;\n hasRemoteComponent = true;\n },\n onScript(attrs) {\n const clientSrc = getClientSrc(attrs.src, serverUrl.href);\n if (\n !scripts.find(\n (it) =>\n it.src === clientSrc ||\n (attrs.textContent && it.textContent === attrs.textContent),\n )\n ) {\n scripts.push(\n typeof attrs.textContent === 'string'\n ? {\n src: '',\n textContent: attrs.textContent,\n }\n : {\n src: clientSrc,\n },\n );\n }\n },\n onLink(attrs) {\n const relativeAttrs = {\n ...attrs,\n href: getClientSrc(attrs.href, serverUrl.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 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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (hasMultipleRemoteComponents && !remoteName) {\n throw multipleRemoteComponentsError(serverUrl.href);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n !hasShared &&\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 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: serverUrl.origin,\n crossOrigin: true,\n },\n moduleMap: {},\n },\n },\n );\n }\n\n const name = metadata.id.replace(/_ssr$/, '');\n return {\n name,\n serverUrl,\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,15 +1,11 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { R as RemoteComponentMetadata } from '../../../types-
|
|
2
|
+
import { O as OnRequestHook, a as OnResponseHook, R as RemoteComponentMetadata } from '../../../types-2ab78f67.js';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
* Resolves the base URL that should be used to fetch the remote component.
|
|
6
|
-
* This function must support local development, Vercel environments, and SSG
|
|
7
|
-
* and dynamic rendering.
|
|
8
|
-
*/
|
|
9
|
-
declare function getBaseUrl(reqHeaders: Headers): string;
|
|
10
|
-
declare function fetchRemoteComponent(src: string | URL, headers?: Headers, options?: {
|
|
4
|
+
declare function fetchRemoteComponent(src: string | URL, options?: {
|
|
11
5
|
name?: string;
|
|
12
6
|
rsc?: boolean;
|
|
7
|
+
onRequest?: OnRequestHook;
|
|
8
|
+
onResponse?: OnResponseHook;
|
|
13
9
|
}): Promise<{
|
|
14
10
|
name: string;
|
|
15
11
|
serverUrl: URL;
|
|
@@ -38,4 +34,4 @@ declare function fetchRemoteComponent(src: string | URL, headers?: Headers, opti
|
|
|
38
34
|
remoteShared: Record<string, string>;
|
|
39
35
|
}>;
|
|
40
36
|
|
|
41
|
-
export { fetchRemoteComponent
|
|
37
|
+
export { fetchRemoteComponent };
|
|
@@ -7,30 +7,23 @@ import {
|
|
|
7
7
|
} from "#internal/shared/error";
|
|
8
8
|
import { visit } from "#internal/shared/ssr/dom-flight";
|
|
9
9
|
import { remoteFetchHeaders } from "#internal/shared/ssr/fetch-headers";
|
|
10
|
+
import { fetchWithHooks } from "#internal/shared/ssr/fetch-with-hooks";
|
|
10
11
|
import { getSSRRelativePathBaseUrl } from "#internal/shared/ssr/get-ssr-relative-path-base-url";
|
|
11
12
|
const CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;
|
|
12
|
-
function
|
|
13
|
-
const host = reqHeaders.get("host");
|
|
14
|
-
if (host) {
|
|
15
|
-
return host.startsWith("localhost") ? `http://${host}` : `https://${host}`;
|
|
16
|
-
}
|
|
17
|
-
const forwardedHost = reqHeaders.get("x-forwarded-host");
|
|
18
|
-
if (forwardedHost) {
|
|
19
|
-
return `https://${forwardedHost}`;
|
|
20
|
-
}
|
|
21
|
-
return getSSRRelativePathBaseUrl();
|
|
22
|
-
}
|
|
23
|
-
async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
13
|
+
async function fetchRemoteComponent(src, options = {
|
|
24
14
|
rsc: false
|
|
25
15
|
}) {
|
|
26
|
-
const serverUrl = new URL(src,
|
|
16
|
+
const serverUrl = new URL(src, getSSRRelativePathBaseUrl());
|
|
27
17
|
const fetchInit = {
|
|
28
18
|
method: "GET",
|
|
29
19
|
// pass all headers to the remote component
|
|
30
|
-
headers: remoteFetchHeaders(
|
|
20
|
+
headers: remoteFetchHeaders(),
|
|
31
21
|
credentials: "include"
|
|
32
22
|
};
|
|
33
|
-
const res = await
|
|
23
|
+
const res = await fetchWithHooks(serverUrl, fetchInit, {
|
|
24
|
+
onRequest: options.onRequest,
|
|
25
|
+
onResponse: options.onResponse
|
|
26
|
+
});
|
|
34
27
|
if (!res.ok && !res.body) {
|
|
35
28
|
throw failedToFetchRemoteComponentError(serverUrl.href, res);
|
|
36
29
|
}
|
|
@@ -38,7 +31,7 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
38
31
|
throw failedToFetchRemoteComponentError(
|
|
39
32
|
serverUrl.href,
|
|
40
33
|
res,
|
|
41
|
-
|
|
34
|
+
"If you are using Deployment Protection, ensure the automation bypass environment variable secret in the host matches an automation bypass value in the remote."
|
|
42
35
|
);
|
|
43
36
|
}
|
|
44
37
|
if (res.status === 404) {
|
|
@@ -74,7 +67,7 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
74
67
|
const hydrationData = [];
|
|
75
68
|
let nextData;
|
|
76
69
|
let html = "";
|
|
77
|
-
const remoteName = options.name || serverUrl.hash ? serverUrl.hash.substring(1) : void 0;
|
|
70
|
+
const remoteName = options.name || (serverUrl.hash ? serverUrl.hash.substring(1) : void 0);
|
|
78
71
|
let hasRemoteComponent = false;
|
|
79
72
|
let hasRSC = false;
|
|
80
73
|
let hasShared = false;
|
|
@@ -84,10 +77,10 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
84
77
|
url: serverUrl,
|
|
85
78
|
name: remoteName,
|
|
86
79
|
onMetadata(_metadata) {
|
|
87
|
-
metadata
|
|
88
|
-
if (hasRemoteComponent && metadata.id !== _metadata.id) {
|
|
80
|
+
if (hasRemoteComponent && metadata.id !== _metadata.id && _metadata.id !== "__next" && metadata.id !== "__next" && !nextData) {
|
|
89
81
|
hasMultipleRemoteComponents = true;
|
|
90
82
|
}
|
|
83
|
+
metadata = _metadata;
|
|
91
84
|
hasRemoteComponent = true;
|
|
92
85
|
},
|
|
93
86
|
onScript(attrs) {
|
|
@@ -209,7 +202,6 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
209
202
|
};
|
|
210
203
|
}
|
|
211
204
|
export {
|
|
212
|
-
fetchRemoteComponent
|
|
213
|
-
getBaseUrl
|
|
205
|
+
fetchRemoteComponent
|
|
214
206
|
};
|
|
215
207
|
//# sourceMappingURL=fetch-remote-component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/shared/ssr/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { getClientSrc } from '#internal/shared/client/get-client-src';\nimport {\n failedToFetchRemoteComponentError,\n multipleRemoteComponentsError,\n RemoteComponentsError,\n} from '#internal/shared/error';\nimport { visit } from '#internal/shared/ssr/dom-flight';\nimport { remoteFetchHeaders } from '#internal/shared/ssr/fetch-headers';\nimport { getSSRRelativePathBaseUrl } from '#internal/shared/ssr/get-ssr-relative-path-base-url';\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 return getSSRRelativePathBaseUrl();\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 serverUrl = 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(serverUrl, fetchInit);\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. Otherwise, manually specify x-vercel-protection-bypass for the remote in the \"additionalHeaders\" parameter.',\n );\n }\n\n if (res.status === 404) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n 'Check if you can open it in the browser.',\n );\n }\n\n // create a parser for the HTML response\n const parser = Parser.getFragmentParser<DefaultTreeAdapterMap>();\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 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; textContent?: 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 || serverUrl.hash ? serverUrl.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: RemoteComponentsError | undefined;\n const rsc = visit(fragment, {\n url: serverUrl,\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 const clientSrc = getClientSrc(attrs.src, serverUrl.href);\n if (\n !scripts.find(\n (it) =>\n it.src === clientSrc ||\n (attrs.textContent && it.textContent === attrs.textContent),\n )\n ) {\n scripts.push(\n typeof attrs.textContent === 'string'\n ? {\n src: '',\n textContent: attrs.textContent,\n }\n : {\n src: clientSrc,\n },\n );\n }\n },\n onLink(attrs) {\n const relativeAttrs = {\n ...attrs,\n href: getClientSrc(attrs.href, serverUrl.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 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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (hasMultipleRemoteComponents && !remoteName) {\n throw multipleRemoteComponentsError(serverUrl.href);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n !hasShared &&\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 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: serverUrl.origin,\n crossOrigin: true,\n },\n moduleMap: {},\n },\n },\n );\n }\n\n const name = metadata.id.replace(/_ssr$/, '');\n return {\n name,\n serverUrl,\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
|
+
{"version":3,"sources":["../../../../src/shared/ssr/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { getClientSrc } from '#internal/shared/client/get-client-src';\nimport {\n failedToFetchRemoteComponentError,\n multipleRemoteComponentsError,\n RemoteComponentsError,\n} from '#internal/shared/error';\nimport { visit } from '#internal/shared/ssr/dom-flight';\nimport { remoteFetchHeaders } from '#internal/shared/ssr/fetch-headers';\nimport { fetchWithHooks } from '#internal/shared/ssr/fetch-with-hooks';\nimport { getSSRRelativePathBaseUrl } from '#internal/shared/ssr/get-ssr-relative-path-base-url';\nimport type {\n OnRequestHook,\n OnResponseHook,\n RemoteComponentMetadata,\n} from './types';\n\nconst CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;\n\nexport async function fetchRemoteComponent(\n src: string | URL,\n options: {\n name?: string;\n rsc?: boolean;\n onRequest?: OnRequestHook;\n onResponse?: OnResponseHook;\n } = {\n rsc: false,\n },\n) {\n const serverUrl = new URL(src, getSSRRelativePathBaseUrl());\n\n const fetchInit = {\n method: 'GET',\n // pass all headers to the remote component\n headers: remoteFetchHeaders(),\n credentials: 'include',\n } as RequestInit;\n\n const res = await fetchWithHooks(serverUrl, fetchInit, {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\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.',\n );\n }\n\n if (res.status === 404) {\n throw failedToFetchRemoteComponentError(\n serverUrl.href,\n res,\n 'Check if you can open it in the browser.',\n );\n }\n\n // create a parser for the HTML response\n const parser = Parser.getFragmentParser<DefaultTreeAdapterMap>();\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 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; textContent?: 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 || (serverUrl.hash ? serverUrl.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: RemoteComponentsError | undefined;\n const rsc = visit(fragment, {\n url: serverUrl,\n name: remoteName,\n onMetadata(_metadata) {\n // Skip multiple component detection for Pages Router (__next) since it only supports one remote component per page\n if (\n hasRemoteComponent &&\n metadata.id !== _metadata.id &&\n _metadata.id !== '__next' &&\n metadata.id !== '__next' &&\n !nextData\n ) {\n hasMultipleRemoteComponents = true;\n }\n metadata = _metadata;\n hasRemoteComponent = true;\n },\n onScript(attrs) {\n const clientSrc = getClientSrc(attrs.src, serverUrl.href);\n if (\n !scripts.find(\n (it) =>\n it.src === clientSrc ||\n (attrs.textContent && it.textContent === attrs.textContent),\n )\n ) {\n scripts.push(\n typeof attrs.textContent === 'string'\n ? {\n src: '',\n textContent: attrs.textContent,\n }\n : {\n src: clientSrc,\n },\n );\n }\n },\n onLink(attrs) {\n const relativeAttrs = {\n ...attrs,\n href: getClientSrc(attrs.href, serverUrl.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 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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (hasMultipleRemoteComponents && !remoteName) {\n throw multipleRemoteComponentsError(serverUrl.href);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n !hasShared &&\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 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: serverUrl.origin,\n crossOrigin: true,\n },\n moduleMap: {},\n },\n },\n );\n }\n\n const name = metadata.id.replace(/_ssr$/, '');\n return {\n name,\n serverUrl,\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":[]}
|
|
@@ -0,0 +1,40 @@
|
|
|
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 fetch_with_hooks_exports = {};
|
|
20
|
+
__export(fetch_with_hooks_exports, {
|
|
21
|
+
fetchWithHooks: () => fetchWithHooks
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(fetch_with_hooks_exports);
|
|
24
|
+
async function fetchWithHooks(url, init, options = {}) {
|
|
25
|
+
const { onRequest, onResponse } = options;
|
|
26
|
+
let res = await onRequest?.(url, init);
|
|
27
|
+
if (!res) {
|
|
28
|
+
res = await fetch(url, init);
|
|
29
|
+
}
|
|
30
|
+
const transformedRes = await onResponse?.(url, res);
|
|
31
|
+
if (transformedRes) {
|
|
32
|
+
res = transformedRes;
|
|
33
|
+
}
|
|
34
|
+
return res;
|
|
35
|
+
}
|
|
36
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
37
|
+
0 && (module.exports = {
|
|
38
|
+
fetchWithHooks
|
|
39
|
+
});
|
|
40
|
+
//# sourceMappingURL=fetch-with-hooks.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/shared/ssr/fetch-with-hooks.ts"],"sourcesContent":["import type { OnRequestHook, OnResponseHook } from './types';\n\n/**\n * Options for fetching with request/response hooks.\n */\nexport interface FetchWithHooksOptions {\n /** Hook to intercept the request before fetching */\n onRequest?: OnRequestHook;\n /** Hook to process the response after fetching */\n onResponse?: OnResponseHook;\n}\n\n/**\n * Performs a fetch with optional request and response lifecycle hooks.\n *\n * This utility centralizes the logic for:\n * 1. Calling onRequest hook - if it returns a Response, use it instead of fetching\n * 2. Performing the actual fetch if onRequest didn't provide a response\n * 3. Calling onResponse hook - if it returns a Response, use that transformed response\n *\n * @param url - The URL to fetch\n * @param init - The fetch init options\n * @param options - Optional hooks for request/response interception\n * @returns The final Response (either from onRequest, fetch, or transformed by onResponse)\n *\n * @example\n * const response = await fetchWithHooks(url, fetchInit, {\n * onRequest: async (url, init) => {\n * console.log('Fetching:', url.href);\n * },\n * onResponse: async (url, response) => {\n * if (response.redirected) {\n * console.log('Redirected to:', response.url);\n * }\n * },\n * });\n */\nexport async function fetchWithHooks(\n url: URL,\n init: RequestInit,\n options: FetchWithHooksOptions = {},\n): Promise<Response> {\n const { onRequest, onResponse } = options;\n\n // Call onRequest hook if provided - may return a Response to skip fetching\n let res = await onRequest?.(url, init);\n if (!res) {\n res = await fetch(url, init);\n }\n\n // Call onResponse hook if provided - may return a transformed Response\n const transformedRes = await onResponse?.(url, res);\n if (transformedRes) {\n res = transformedRes;\n }\n\n return res;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAqCA,eAAsB,eACpB,KACA,MACA,UAAiC,CAAC,GACf;AACnB,QAAM,EAAE,WAAW,WAAW,IAAI;AAGlC,MAAI,MAAM,MAAM,YAAY,KAAK,IAAI;AACrC,MAAI,CAAC,KAAK;AACR,UAAM,MAAM,MAAM,KAAK,IAAI;AAAA,EAC7B;AAGA,QAAM,iBAAiB,MAAM,aAAa,KAAK,GAAG;AAClD,MAAI,gBAAgB;AAClB,UAAM;AAAA,EACR;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { O as OnRequestHook, a as OnResponseHook } from '../../../types-2ab78f67.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Options for fetching with request/response hooks.
|
|
5
|
+
*/
|
|
6
|
+
interface FetchWithHooksOptions {
|
|
7
|
+
/** Hook to intercept the request before fetching */
|
|
8
|
+
onRequest?: OnRequestHook;
|
|
9
|
+
/** Hook to process the response after fetching */
|
|
10
|
+
onResponse?: OnResponseHook;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Performs a fetch with optional request and response lifecycle hooks.
|
|
14
|
+
*
|
|
15
|
+
* This utility centralizes the logic for:
|
|
16
|
+
* 1. Calling onRequest hook - if it returns a Response, use it instead of fetching
|
|
17
|
+
* 2. Performing the actual fetch if onRequest didn't provide a response
|
|
18
|
+
* 3. Calling onResponse hook - if it returns a Response, use that transformed response
|
|
19
|
+
*
|
|
20
|
+
* @param url - The URL to fetch
|
|
21
|
+
* @param init - The fetch init options
|
|
22
|
+
* @param options - Optional hooks for request/response interception
|
|
23
|
+
* @returns The final Response (either from onRequest, fetch, or transformed by onResponse)
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* const response = await fetchWithHooks(url, fetchInit, {
|
|
27
|
+
* onRequest: async (url, init) => {
|
|
28
|
+
* console.log('Fetching:', url.href);
|
|
29
|
+
* },
|
|
30
|
+
* onResponse: async (url, response) => {
|
|
31
|
+
* if (response.redirected) {
|
|
32
|
+
* console.log('Redirected to:', response.url);
|
|
33
|
+
* }
|
|
34
|
+
* },
|
|
35
|
+
* });
|
|
36
|
+
*/
|
|
37
|
+
declare function fetchWithHooks(url: URL, init: RequestInit, options?: FetchWithHooksOptions): Promise<Response>;
|
|
38
|
+
|
|
39
|
+
export { FetchWithHooksOptions, fetchWithHooks };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
async function fetchWithHooks(url, init, options = {}) {
|
|
2
|
+
const { onRequest, onResponse } = options;
|
|
3
|
+
let res = await onRequest?.(url, init);
|
|
4
|
+
if (!res) {
|
|
5
|
+
res = await fetch(url, init);
|
|
6
|
+
}
|
|
7
|
+
const transformedRes = await onResponse?.(url, res);
|
|
8
|
+
if (transformedRes) {
|
|
9
|
+
res = transformedRes;
|
|
10
|
+
}
|
|
11
|
+
return res;
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
fetchWithHooks
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=fetch-with-hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/shared/ssr/fetch-with-hooks.ts"],"sourcesContent":["import type { OnRequestHook, OnResponseHook } from './types';\n\n/**\n * Options for fetching with request/response hooks.\n */\nexport interface FetchWithHooksOptions {\n /** Hook to intercept the request before fetching */\n onRequest?: OnRequestHook;\n /** Hook to process the response after fetching */\n onResponse?: OnResponseHook;\n}\n\n/**\n * Performs a fetch with optional request and response lifecycle hooks.\n *\n * This utility centralizes the logic for:\n * 1. Calling onRequest hook - if it returns a Response, use it instead of fetching\n * 2. Performing the actual fetch if onRequest didn't provide a response\n * 3. Calling onResponse hook - if it returns a Response, use that transformed response\n *\n * @param url - The URL to fetch\n * @param init - The fetch init options\n * @param options - Optional hooks for request/response interception\n * @returns The final Response (either from onRequest, fetch, or transformed by onResponse)\n *\n * @example\n * const response = await fetchWithHooks(url, fetchInit, {\n * onRequest: async (url, init) => {\n * console.log('Fetching:', url.href);\n * },\n * onResponse: async (url, response) => {\n * if (response.redirected) {\n * console.log('Redirected to:', response.url);\n * }\n * },\n * });\n */\nexport async function fetchWithHooks(\n url: URL,\n init: RequestInit,\n options: FetchWithHooksOptions = {},\n): Promise<Response> {\n const { onRequest, onResponse } = options;\n\n // Call onRequest hook if provided - may return a Response to skip fetching\n let res = await onRequest?.(url, init);\n if (!res) {\n res = await fetch(url, init);\n }\n\n // Call onResponse hook if provided - may return a transformed Response\n const transformedRes = await onResponse?.(url, res);\n if (transformedRes) {\n res = transformedRes;\n }\n\n return res;\n}\n"],"mappings":"AAqCA,eAAsB,eACpB,KACA,MACA,UAAiC,CAAC,GACf;AACnB,QAAM,EAAE,WAAW,WAAW,IAAI;AAGlC,MAAI,MAAM,MAAM,YAAY,KAAK,IAAI;AACrC,MAAI,CAAC,KAAK;AACR,UAAM,MAAM,MAAM,KAAK,IAAI;AAAA,EAC7B;AAGA,QAAM,iBAAiB,MAAM,aAAa,KAAK,GAAG;AAClD,MAAI,gBAAgB;AAClB,UAAM;AAAA,EACR;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/shared/ssr/get-ssr-relative-path-base-url.ts"],"sourcesContent":["/**\n * When fetching a remote component using a relative path with SSR, a base URL is required.\n * This is not used on the client.\n *\n * Can add support in the future with a custom env var for prop for when not building with Vercel\n * and Vercel URL is not available.\n */\nexport function getSSRRelativePathBaseUrl(): string {\n // This is the deployment URL
|
|
1
|
+
{"version":3,"sources":["../../../../src/shared/ssr/get-ssr-relative-path-base-url.ts"],"sourcesContent":["/**\n * When fetching a remote component using a relative path with SSR, a base URL is required.\n * This is not used on the client.\n *\n * Can add support in the future with a custom env var for prop for when not building with Vercel\n * and Vercel URL is not available.\n */\nexport function getSSRRelativePathBaseUrl(): string {\n // This is the deployment URL.\n if (process.env.VERCEL_URL) {\n return `https://${process.env.VERCEL_URL}`;\n }\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"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOO,SAAS,4BAAoC;AAElD,MAAI,QAAQ,IAAI,YAAY;AAC1B,WAAO,WAAW,QAAQ,IAAI;AAAA,EAChC;AAGA,SAAO,oBAAoB,QAAQ,IAAI,wBAAwB;AACjE;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/shared/ssr/get-ssr-relative-path-base-url.ts"],"sourcesContent":["/**\n * When fetching a remote component using a relative path with SSR, a base URL is required.\n * This is not used on the client.\n *\n * Can add support in the future with a custom env var for prop for when not building with Vercel\n * and Vercel URL is not available.\n */\nexport function getSSRRelativePathBaseUrl(): string {\n // This is the deployment URL
|
|
1
|
+
{"version":3,"sources":["../../../../src/shared/ssr/get-ssr-relative-path-base-url.ts"],"sourcesContent":["/**\n * When fetching a remote component using a relative path with SSR, a base URL is required.\n * This is not used on the client.\n *\n * Can add support in the future with a custom env var for prop for when not building with Vercel\n * and Vercel URL is not available.\n */\nexport function getSSRRelativePathBaseUrl(): string {\n // This is the deployment URL.\n if (process.env.VERCEL_URL) {\n return `https://${process.env.VERCEL_URL}`;\n }\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"],"mappings":"AAOO,SAAS,4BAAoC;AAElD,MAAI,QAAQ,IAAI,YAAY;AAC1B,WAAO,WAAW,QAAQ,IAAI;AAAA,EAChC;AAGA,SAAO,oBAAoB,QAAQ,IAAI,wBAAwB;AACjE;","names":[]}
|