remote-components 0.0.51 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/dist/{component-loader-1838f572.d.ts → component-loader-21865da3.d.ts} +142 -16
  2. package/dist/host-config-58cdccea.d.ts +87 -0
  3. package/dist/html/host.cjs +589 -377
  4. package/dist/html/host.cjs.map +1 -1
  5. package/dist/html/host.d.ts +2 -0
  6. package/dist/html/host.js +588 -377
  7. package/dist/html/host.js.map +1 -1
  8. package/dist/html/remote.cjs +65 -57
  9. package/dist/html/remote.cjs.map +1 -1
  10. package/dist/html/remote.js +65 -57
  11. package/dist/html/remote.js.map +1 -1
  12. package/dist/internal/next/host/app-router-client.cjs +21 -10
  13. package/dist/internal/next/host/app-router-client.cjs.map +1 -1
  14. package/dist/internal/next/host/app-router-client.d.ts +36 -14
  15. package/dist/internal/next/host/app-router-client.js +21 -10
  16. package/dist/internal/next/host/app-router-client.js.map +1 -1
  17. package/dist/internal/next/remote/render-server.cjs.map +1 -1
  18. package/dist/internal/next/remote/render-server.d.ts +13 -14
  19. package/dist/internal/next/remote/render-server.js.map +1 -1
  20. package/dist/internal/react/context.cjs +43 -0
  21. package/dist/internal/react/context.cjs.map +1 -0
  22. package/dist/internal/react/context.d.ts +20 -0
  23. package/dist/internal/react/context.js +18 -0
  24. package/dist/internal/react/context.js.map +1 -0
  25. package/dist/internal/react/hooks/use-resolve-client-url.cjs +39 -0
  26. package/dist/internal/react/hooks/use-resolve-client-url.cjs.map +1 -0
  27. package/dist/internal/react/hooks/use-resolve-client-url.d.ts +5 -0
  28. package/dist/internal/react/hooks/use-resolve-client-url.js +15 -0
  29. package/dist/internal/react/hooks/use-resolve-client-url.js.map +1 -0
  30. package/dist/internal/shared/client/apply-origin.cjs +10 -5
  31. package/dist/internal/shared/client/apply-origin.cjs.map +1 -1
  32. package/dist/internal/shared/client/apply-origin.d.ts +3 -1
  33. package/dist/internal/shared/client/apply-origin.js +10 -5
  34. package/dist/internal/shared/client/apply-origin.js.map +1 -1
  35. package/dist/internal/shared/client/default-resolve-client-url.cjs +32 -0
  36. package/dist/internal/shared/client/default-resolve-client-url.cjs.map +1 -0
  37. package/dist/internal/shared/client/default-resolve-client-url.d.ts +5 -0
  38. package/dist/internal/shared/client/default-resolve-client-url.js +10 -0
  39. package/dist/internal/shared/client/default-resolve-client-url.js.map +1 -0
  40. package/dist/internal/shared/client/protected-rc-fallback.cjs +11 -2
  41. package/dist/internal/shared/client/protected-rc-fallback.cjs.map +1 -1
  42. package/dist/internal/shared/client/protected-rc-fallback.d.ts +2 -1
  43. package/dist/internal/shared/client/protected-rc-fallback.js +9 -1
  44. package/dist/internal/shared/client/protected-rc-fallback.js.map +1 -1
  45. package/dist/internal/shared/client/proxy-through-host.cjs +65 -0
  46. package/dist/internal/shared/client/proxy-through-host.cjs.map +1 -0
  47. package/dist/internal/shared/client/proxy-through-host.d.ts +62 -0
  48. package/dist/internal/shared/client/proxy-through-host.js +40 -0
  49. package/dist/internal/shared/client/proxy-through-host.js.map +1 -0
  50. package/dist/internal/shared/client/remote-component.cjs +121 -137
  51. package/dist/internal/shared/client/remote-component.cjs.map +1 -1
  52. package/dist/internal/shared/client/remote-component.d.ts +7 -5
  53. package/dist/internal/shared/client/remote-component.js +120 -137
  54. package/dist/internal/shared/client/remote-component.js.map +1 -1
  55. package/dist/internal/shared/constants.cjs +3 -0
  56. package/dist/internal/shared/constants.cjs.map +1 -1
  57. package/dist/internal/shared/constants.d.ts +2 -1
  58. package/dist/internal/shared/constants.js +2 -0
  59. package/dist/internal/shared/constants.js.map +1 -1
  60. package/dist/internal/shared/contract/host-state.cjs +38 -0
  61. package/dist/internal/shared/contract/host-state.cjs.map +1 -0
  62. package/dist/internal/shared/contract/host-state.d.ts +53 -0
  63. package/dist/internal/shared/contract/host-state.js +14 -0
  64. package/dist/internal/shared/contract/host-state.js.map +1 -0
  65. package/dist/internal/shared/contract/resolve-name-from-src.cjs +40 -0
  66. package/dist/internal/shared/contract/resolve-name-from-src.cjs.map +1 -0
  67. package/dist/internal/shared/contract/resolve-name-from-src.d.ts +13 -0
  68. package/dist/internal/shared/contract/resolve-name-from-src.js +16 -0
  69. package/dist/internal/shared/contract/resolve-name-from-src.js.map +1 -0
  70. package/dist/internal/shared/error.cjs +70 -0
  71. package/dist/internal/shared/error.cjs.map +1 -1
  72. package/dist/internal/shared/error.d.ts +3 -1
  73. package/dist/internal/shared/error.js +71 -0
  74. package/dist/internal/shared/error.js.map +1 -1
  75. package/dist/internal/shared/ssr/dom-flight.d.ts +1 -1
  76. package/dist/internal/shared/ssr/fetch-remote-component.cjs.map +1 -1
  77. package/dist/internal/shared/ssr/fetch-remote-component.d.ts +1 -1
  78. package/dist/internal/shared/ssr/fetch-remote-component.js.map +1 -1
  79. package/dist/internal/shared/ssr/fetch-with-hooks.cjs +7 -2
  80. package/dist/internal/shared/ssr/fetch-with-hooks.cjs.map +1 -1
  81. package/dist/internal/shared/ssr/fetch-with-hooks.d.ts +1 -1
  82. package/dist/internal/shared/ssr/fetch-with-hooks.js +7 -2
  83. package/dist/internal/shared/ssr/fetch-with-hooks.js.map +1 -1
  84. package/dist/internal/shared/utils/logger.cjs +26 -10
  85. package/dist/internal/shared/utils/logger.cjs.map +1 -1
  86. package/dist/internal/shared/utils/logger.d.ts +6 -1
  87. package/dist/internal/shared/utils/logger.js +24 -9
  88. package/dist/internal/shared/utils/logger.js.map +1 -1
  89. package/dist/next/config.cjs +2 -2
  90. package/dist/next/config.cjs.map +1 -1
  91. package/dist/next/config.js +2 -2
  92. package/dist/next/config.js.map +1 -1
  93. package/dist/next/host/app-router-server.cjs.map +1 -1
  94. package/dist/next/host/app-router-server.d.ts +11 -41
  95. package/dist/next/host/app-router-server.js.map +1 -1
  96. package/dist/next/host/client/index.cjs +467 -298
  97. package/dist/next/host/client/index.cjs.map +1 -1
  98. package/dist/next/host/client/index.d.ts +3 -1
  99. package/dist/next/host/client/index.js +445 -277
  100. package/dist/next/host/client/index.js.map +1 -1
  101. package/dist/next/host/pages-router-client.cjs +15 -2
  102. package/dist/next/host/pages-router-client.cjs.map +1 -1
  103. package/dist/next/host/pages-router-client.d.ts +14 -26
  104. package/dist/next/host/pages-router-client.js +15 -2
  105. package/dist/next/host/pages-router-client.js.map +1 -1
  106. package/dist/next/host/pages-router-server.cjs +2 -0
  107. package/dist/next/host/pages-router-server.cjs.map +1 -1
  108. package/dist/next/host/pages-router-server.d.ts +17 -31
  109. package/dist/next/host/pages-router-server.js +2 -0
  110. package/dist/next/host/pages-router-server.js.map +1 -1
  111. package/dist/next/index.cjs.map +1 -1
  112. package/dist/next/index.d.ts +13 -39
  113. package/dist/next/index.js.map +1 -1
  114. package/dist/next/proxy.cjs +33 -6
  115. package/dist/next/proxy.cjs.map +1 -1
  116. package/dist/next/proxy.js +33 -6
  117. package/dist/next/proxy.js.map +1 -1
  118. package/dist/next/remote/server.d.ts +4 -0
  119. package/dist/proxy-through-host-a676a522.d.ts +52 -0
  120. package/dist/react/index.cjs +486 -298
  121. package/dist/react/index.cjs.map +1 -1
  122. package/dist/react/index.d.ts +27 -40
  123. package/dist/react/index.js +463 -277
  124. package/dist/react/index.js.map +1 -1
  125. package/dist/shared/host/proxy.cjs +32 -6
  126. package/dist/shared/host/proxy.cjs.map +1 -1
  127. package/dist/shared/host/proxy.js +36 -7
  128. package/dist/shared/host/proxy.js.map +1 -1
  129. package/dist/{types-cbe44b51.d.ts → types-2b26a246.d.ts} +23 -6
  130. package/package.json +1 -1
  131. package/dist/internal/shared/client/fetch-with-protected-rc-fallback.cjs +0 -65
  132. package/dist/internal/shared/client/fetch-with-protected-rc-fallback.cjs.map +0 -1
  133. package/dist/internal/shared/client/fetch-with-protected-rc-fallback.d.ts +0 -13
  134. package/dist/internal/shared/client/fetch-with-protected-rc-fallback.js +0 -41
  135. package/dist/internal/shared/client/fetch-with-protected-rc-fallback.js.map +0 -1
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Intercepts client-side URL resolution for remote component resources.
3
+ * Called before each asset (script, stylesheet, chunk, module, image) is fetched.
4
+ *
5
+ * Return a new URL string to redirect the fetch (e.g., through a proxy),
6
+ * or undefined to use the original URL.
7
+ *
8
+ * @param remoteSrc - The `src` of the remote component being loaded
9
+ * @param url - The asset URL about to be fetched
10
+ *
11
+ * @example
12
+ * // Proxy all assets from the remote's origin through the host
13
+ * const resolveClientUrl = (remoteSrc, url) => {
14
+ * const remoteOrigin = new URL(remoteSrc).origin;
15
+ * const parsed = new URL(url);
16
+ * if (parsed.origin !== location.origin && parsed.origin === remoteOrigin) {
17
+ * return `/rc-fetch-protected-remote?url=${encodeURIComponent(url)}`;
18
+ * }
19
+ * };
20
+ */
21
+ type ResolveClientUrl = (remoteSrc: string, url: string) => string | undefined;
22
+ /**
23
+ * Internal bound resolver — `ResolveClientUrl` with `remoteSrc` already applied.
24
+ * Used by internal loaders that don't need to know the remote src.
25
+ */
26
+ type InternalResolveClientUrl = (url: string) => string | undefined;
27
+ /**
28
+ * Binds a `ResolveClientUrl` to a specific `remoteSrc`, producing an
29
+ * `InternalResolveClientUrl` that only needs the asset URL.
30
+ *
31
+ * Only invokes the callback for URLs whose origin matches the remote
32
+ * component's origin. Third-party scripts (e.g. `vercel.live` toolbar)
33
+ * are left untouched. To proxy additional domains in the future, a
34
+ * field or flag can be added to the host configuration.
35
+ */
36
+ declare function withRemoteSrc(resolveClientUrl: ResolveClientUrl, remoteSrc: string): InternalResolveClientUrl;
37
+ /**
38
+ * A `ResolveClientUrl` that proxies cross-origin asset URLs
39
+ * through the host's protected remote fetch endpoint (`/rc-fetch-protected-remote`).
40
+ * Same-origin URLs are left unchanged.
41
+ *
42
+ * On Vercel preview deployments, deployment protection blocks direct cross-origin
43
+ * asset fetches. This function proxies those requests through the host so they
44
+ * inherit the host's authentication cookies.
45
+ *
46
+ * Requires `withRemoteComponentsHost` middleware on the host to handle the
47
+ * proxied requests. Configure `allowedProxyUrls` to restrict which URLs can
48
+ * be proxied.
49
+ *
50
+ * @example
51
+ * ```tsx
52
+ * import { RemoteComponent, proxyClientRequestsThroughHost } from 'remote-components/react';
53
+ *
54
+ * <RemoteComponent
55
+ * src="https://remote-app.com/components/header"
56
+ * resolveClientUrl={proxyClientRequestsThroughHost}
57
+ * />
58
+ * ```
59
+ */
60
+ declare const proxyClientRequestsThroughHost: ResolveClientUrl;
61
+
62
+ export { InternalResolveClientUrl, ResolveClientUrl, proxyClientRequestsThroughHost, withRemoteSrc };
@@ -0,0 +1,40 @@
1
+ import { generateProtectedRcFallbackSrc } from "./protected-rc-fallback";
2
+ function withRemoteSrc(resolveClientUrl, remoteSrc) {
3
+ const remoteOrigin = parseOrigin(remoteSrc);
4
+ return (url) => {
5
+ const urlOrigin = parseOrigin(url);
6
+ if (remoteOrigin && urlOrigin && urlOrigin !== remoteOrigin) {
7
+ return void 0;
8
+ }
9
+ return resolveClientUrl(remoteSrc, url);
10
+ };
11
+ }
12
+ function parseOrigin(url) {
13
+ try {
14
+ return new URL(url).origin;
15
+ } catch {
16
+ return void 0;
17
+ }
18
+ }
19
+ const proxyClientRequestsThroughHost = (remoteSrc, url) => {
20
+ if (typeof location === "undefined") {
21
+ return void 0;
22
+ }
23
+ const remoteOrigin = new URL(remoteSrc, location.href).origin;
24
+ if (remoteOrigin === location.origin) {
25
+ return void 0;
26
+ }
27
+ try {
28
+ const parsed = new URL(url, location.href);
29
+ if (parsed.origin === remoteOrigin) {
30
+ return generateProtectedRcFallbackSrc(url);
31
+ }
32
+ } catch {
33
+ }
34
+ return void 0;
35
+ };
36
+ export {
37
+ proxyClientRequestsThroughHost,
38
+ withRemoteSrc
39
+ };
40
+ //# sourceMappingURL=proxy-through-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/shared/client/proxy-through-host.ts"],"sourcesContent":["import { generateProtectedRcFallbackSrc } from './protected-rc-fallback';\n\n/**\n * Intercepts client-side URL resolution for remote component resources.\n * Called before each asset (script, stylesheet, chunk, module, image) is fetched.\n *\n * Return a new URL string to redirect the fetch (e.g., through a proxy),\n * or undefined to use the original URL.\n *\n * @param remoteSrc - The `src` of the remote component being loaded\n * @param url - The asset URL about to be fetched\n *\n * @example\n * // Proxy all assets from the remote's origin through the host\n * const resolveClientUrl = (remoteSrc, url) => {\n * const remoteOrigin = new URL(remoteSrc).origin;\n * const parsed = new URL(url);\n * if (parsed.origin !== location.origin && parsed.origin === remoteOrigin) {\n * return `/rc-fetch-protected-remote?url=${encodeURIComponent(url)}`;\n * }\n * };\n */\nexport type ResolveClientUrl = (\n remoteSrc: string,\n url: string,\n) => string | undefined;\n\n/**\n * Internal bound resolver — `ResolveClientUrl` with `remoteSrc` already applied.\n * Used by internal loaders that don't need to know the remote src.\n */\nexport type InternalResolveClientUrl = (url: string) => string | undefined;\n\n/**\n * Binds a `ResolveClientUrl` to a specific `remoteSrc`, producing an\n * `InternalResolveClientUrl` that only needs the asset URL.\n *\n * Only invokes the callback for URLs whose origin matches the remote\n * component's origin. Third-party scripts (e.g. `vercel.live` toolbar)\n * are left untouched. To proxy additional domains in the future, a\n * field or flag can be added to the host configuration.\n */\nexport function withRemoteSrc(\n resolveClientUrl: ResolveClientUrl,\n remoteSrc: string,\n): InternalResolveClientUrl {\n const remoteOrigin = parseOrigin(remoteSrc);\n return (url) => {\n const urlOrigin = parseOrigin(url);\n if (remoteOrigin && urlOrigin && urlOrigin !== remoteOrigin) {\n return undefined;\n }\n return resolveClientUrl(remoteSrc, url);\n };\n}\n\nfunction parseOrigin(url: string): string | undefined {\n try {\n return new URL(url).origin;\n } catch {\n return undefined;\n }\n}\n\n/**\n * A `ResolveClientUrl` that proxies cross-origin asset URLs\n * through the host's protected remote fetch endpoint (`/rc-fetch-protected-remote`).\n * Same-origin URLs are left unchanged.\n *\n * On Vercel preview deployments, deployment protection blocks direct cross-origin\n * asset fetches. This function proxies those requests through the host so they\n * inherit the host's authentication cookies.\n *\n * Requires `withRemoteComponentsHost` middleware on the host to handle the\n * proxied requests. Configure `allowedProxyUrls` to restrict which URLs can\n * be proxied.\n *\n * @example\n * ```tsx\n * import { RemoteComponent, proxyClientRequestsThroughHost } from 'remote-components/react';\n *\n * <RemoteComponent\n * src=\"https://remote-app.com/components/header\"\n * resolveClientUrl={proxyClientRequestsThroughHost}\n * />\n * ```\n */\nexport const proxyClientRequestsThroughHost: ResolveClientUrl = (\n remoteSrc,\n url,\n) => {\n if (typeof location === 'undefined') {\n return undefined;\n }\n const remoteOrigin = new URL(remoteSrc, location.href).origin;\n if (remoteOrigin === location.origin) {\n return undefined;\n }\n try {\n const parsed = new URL(url, location.href);\n if (parsed.origin === remoteOrigin) {\n return generateProtectedRcFallbackSrc(url);\n }\n } catch {\n // If URL parsing fails, return undefined to use the original\n }\n return undefined;\n};\n"],"mappings":"AAAA,SAAS,sCAAsC;AA0CxC,SAAS,cACd,kBACA,WAC0B;AAC1B,QAAM,eAAe,YAAY,SAAS;AAC1C,SAAO,CAAC,QAAQ;AACd,UAAM,YAAY,YAAY,GAAG;AACjC,QAAI,gBAAgB,aAAa,cAAc,cAAc;AAC3D,aAAO;AAAA,IACT;AACA,WAAO,iBAAiB,WAAW,GAAG;AAAA,EACxC;AACF;AAEA,SAAS,YAAY,KAAiC;AACpD,MAAI;AACF,WAAO,IAAI,IAAI,GAAG,EAAE;AAAA,EACtB,QAAE;AACA,WAAO;AAAA,EACT;AACF;AAyBO,MAAM,iCAAmD,CAC9D,WACA,QACG;AACH,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO;AAAA,EACT;AACA,QAAM,eAAe,IAAI,IAAI,WAAW,SAAS,IAAI,EAAE;AACvD,MAAI,iBAAiB,SAAS,QAAQ;AACpC,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI;AACzC,QAAI,OAAO,WAAW,cAAc;AAClC,aAAO,+BAA+B,GAAG;AAAA,IAC3C;AAAA,EACF,QAAE;AAAA,EAEF;AACA,SAAO;AACT;","names":[]}
@@ -42,11 +42,28 @@ __export(remote_component_exports, {
42
42
  loadRemoteComponent: () => loadRemoteComponent,
43
43
  loadScripts: () => loadScripts,
44
44
  loadStaticRemoteComponent: () => loadStaticRemoteComponent,
45
+ proxyClientRequestsThroughHost: () => proxyClientRequestsThroughHost,
45
46
  setAttributesFromProps: () => setAttributesFromProps,
46
47
  setupWebpackRuntime: () => setupWebpackRuntime
47
48
  });
48
49
  module.exports = __toCommonJS(remote_component_exports);
49
50
 
51
+ // src/shared/constants.ts
52
+ var RC_PROTECTED_REMOTE_FETCH_PATHNAME = "/rc-fetch-protected-remote";
53
+ var CORS_DOCS_URL = "https://vercel.com/docs/remote-components/concepts/cors-external-urls#accessing-cross-site-protected-remote-components";
54
+
55
+ // src/shared/client/protected-rc-fallback.ts
56
+ function generateProtectedRcFallbackSrc(url) {
57
+ return `${RC_PROTECTED_REMOTE_FETCH_PATHNAME}?url=${encodeURIComponent(url)}`;
58
+ }
59
+ function isProxiedUrl(url) {
60
+ try {
61
+ return new URL(url, location.href).pathname === RC_PROTECTED_REMOTE_FETCH_PATHNAME;
62
+ } catch {
63
+ return false;
64
+ }
65
+ }
66
+
50
67
  // src/shared/error.ts
51
68
  var RemoteComponentsError = class extends Error {
52
69
  code = "REMOTE_COMPONENTS_ERROR";
@@ -71,9 +88,6 @@ function logDebug(location2, message) {
71
88
  console.debug(`[${PREFIX}:${location2}]: ${message}`);
72
89
  }
73
90
  }
74
- function logInfo(location2, message) {
75
- console.info(`[${PREFIX}:${location2}]: ${message}`);
76
- }
77
91
  function logWarn(location2, message) {
78
92
  console.warn(`[${PREFIX}:${location2}]: ${message}`);
79
93
  }
@@ -84,6 +98,19 @@ function logError(location2, message, cause) {
84
98
  })
85
99
  );
86
100
  }
101
+ function warnCrossOriginFetchError(logLocation, url) {
102
+ try {
103
+ const parsed = typeof url === "string" ? new URL(url) : url;
104
+ if (typeof location === "undefined" || parsed.origin === location.origin) {
105
+ return;
106
+ }
107
+ logWarn(
108
+ logLocation,
109
+ `Failed to fetch cross-origin resource "${parsed.href}". If this is a protected deployment, ensure withRemoteComponentsHost middleware is configured in your host and that the remote URL is included in allowedProxyUrls. See: ${CORS_DOCS_URL}`
110
+ );
111
+ } catch {
112
+ }
113
+ }
87
114
 
88
115
  // src/shared/webpack/next-client-pages-loader.ts
89
116
  function nextClientPagesLoader(bundle, route, styleContainer = document.head) {
@@ -324,19 +351,11 @@ function createRSCStream(rscName, data) {
324
351
  });
325
352
  }
326
353
 
327
- // src/shared/constants.ts
328
- var RC_PROTECTED_REMOTE_FETCH_PATHNAME = "/rc-fetch-protected-remote";
329
-
330
- // src/shared/client/protected-rc-fallback.ts
331
- function generateProtectedRcFallbackSrc(url) {
332
- return `${RC_PROTECTED_REMOTE_FETCH_PATHNAME}?url=${encodeURIComponent(url)}`;
333
- }
334
-
335
354
  // src/shared/client/webpack-patterns.ts
336
355
  var NEXT_BUNDLE_PATH_RE = /\/_next\/\[.+\](?:%20| )/;
337
356
 
338
357
  // src/shared/client/script-loader.ts
339
- async function loadScripts(scripts) {
358
+ async function loadScripts(scripts, resolveClientUrl) {
340
359
  await Promise.all(
341
360
  scripts.map((script) => {
342
361
  return new Promise((resolve, reject) => {
@@ -345,42 +364,29 @@ async function loadScripts(scripts) {
345
364
  script.src.replace(NEXT_BUNDLE_PATH_RE, "/_next/"),
346
365
  location.origin
347
366
  ).href;
348
- const loadScriptWithProtectedRcFallback = (src, isFallback = false) => {
349
- const newScript = document.createElement("script");
350
- newScript.onload = () => {
351
- if (isFallback) {
352
- logInfo(
353
- "ScriptLoader",
354
- `Successfully loaded <script src="${newSrc}"> using fallback.`
355
- );
356
- }
357
- resolve();
358
- };
359
- newScript.onerror = () => {
360
- if (!isFallback) {
361
- const fallbackSrc = generateProtectedRcFallbackSrc(newSrc);
362
- logWarn(
363
- "ScriptLoader",
364
- `Failed to load <script src="${newSrc}"> for Remote Component. Trying fallback with ${RC_PROTECTED_REMOTE_FETCH_PATHNAME} (withRemoteComponentsHost)...`
365
- );
366
- loadScriptWithProtectedRcFallback(fallbackSrc, true);
367
- } else {
368
- logError(
369
- "ScriptLoader",
370
- `Failed to load fallback for <script src="${newSrc}"> for Remote Component.`
371
- );
372
- reject(
373
- new RemoteComponentsError(
374
- `Failed to load <script src="${newSrc}"> for Remote Component. Check the URL is correct.`
375
- )
376
- );
377
- }
378
- };
379
- newScript.src = src;
380
- newScript.async = true;
381
- document.head.appendChild(newScript);
367
+ const resolvedSrc = resolveClientUrl?.(newSrc) ?? newSrc;
368
+ const newScript = document.createElement("script");
369
+ newScript.onload = () => resolve();
370
+ newScript.onerror = () => {
371
+ const isProxied = isProxiedUrl(resolvedSrc);
372
+ if (isProxied) {
373
+ reject(
374
+ new RemoteComponentsError(
375
+ `Failed to load script "${newSrc}" via proxy "${resolvedSrc}". Ensure withRemoteComponentsHost middleware is configured and "${RC_PROTECTED_REMOTE_FETCH_PATHNAME}" is in the matcher. See: ${CORS_DOCS_URL}`
376
+ )
377
+ );
378
+ } else {
379
+ warnCrossOriginFetchError("ScriptLoader", newSrc);
380
+ reject(
381
+ new RemoteComponentsError(
382
+ `Failed to load <script src="${newSrc}"> for Remote Component. Check the URL is correct.`
383
+ )
384
+ );
385
+ }
382
386
  };
383
- loadScriptWithProtectedRcFallback(newSrc);
387
+ newScript.src = resolvedSrc;
388
+ newScript.async = true;
389
+ document.head.appendChild(newScript);
384
390
  });
385
391
  })
386
392
  );
@@ -401,54 +407,6 @@ function getBundleKey(bundle) {
401
407
  return escapeString(bundle);
402
408
  }
403
409
 
404
- // src/shared/utils/abort.ts
405
- function isAbortError(error) {
406
- if (error instanceof DOMException && error.name === "AbortError") {
407
- return true;
408
- }
409
- if (error !== null && typeof error === "object" && "name" in error && error.name === "AbortError" && "message" in error && typeof error.message === "string") {
410
- const e = error;
411
- return typeof e.code === "number" || e.constructor?.name === "DOMException";
412
- }
413
- return false;
414
- }
415
-
416
- // src/shared/client/fetch-with-protected-rc-fallback.ts
417
- async function fetchWithProtectedRcFallback(url, init) {
418
- try {
419
- const res = await fetch(url, init);
420
- return res;
421
- } catch (error) {
422
- if (isAbortError(error)) {
423
- throw error;
424
- }
425
- const parsedUrl = new URL(url);
426
- if (typeof document === "object" && typeof document.location === "object" && document.location.origin !== parsedUrl.origin) {
427
- logWarn(
428
- "FetchRemoteComponent",
429
- "Request failed due to CORS, attempting to fetch it via the withRemoteComponentsHost proxy."
430
- );
431
- const proxiedRes = await fetch(
432
- generateProtectedRcFallbackSrc(parsedUrl.href),
433
- init?.signal ? { signal: init.signal } : void 0
434
- );
435
- if (proxiedRes.status === 200) {
436
- logInfo(
437
- "FetchRemoteComponent",
438
- `Successfully fetched ${parsedUrl.href} with fallback withRemoteComponentsHost proxy`
439
- );
440
- return proxiedRes;
441
- } else {
442
- logError(
443
- "FetchRemoteComponent",
444
- `Could not proxy remote: [response status ${proxiedRes.status}] ${await proxiedRes.text()}`
445
- );
446
- }
447
- }
448
- throw error;
449
- }
450
- }
451
-
452
410
  // src/shared/client/turbopack-patterns.ts
453
411
  var REMOTE_SHARED_MARKER_RE = /(?:self|[a-z])\.TURBOPACK_REMOTE_SHARED/;
454
412
  var REMOTE_SHARED_ASSIGNMENT_RE = /\.TURBOPACK_REMOTE_SHARED=await (?:__turbopack_context__|e)\.A\((?<sharedModuleId>[0-9]+)\)/;
@@ -458,7 +416,7 @@ var ASYNC_MODULE_ALL_RE = /(?<ctx>__turbopack_context__|e)=>\{\k<ctx>\.v\((?<vCb
458
416
  var TURBOPACK_GLOBAL_RE = /(?:globalThis|self)\s*(?:\.TURBOPACK|\[\s*["']TURBOPACK["']\s*\])/;
459
417
 
460
418
  // src/shared/client/chunk-loader.ts
461
- function createChunkLoader(runtime) {
419
+ function createChunkLoader(runtime, resolveClientUrl) {
462
420
  return function __turbopack_chunk_load__(chunkId, scriptBundle) {
463
421
  logDebug("ChunkLoader", `Loading chunk: "${chunkId}"`);
464
422
  const self = globalThis;
@@ -498,9 +456,10 @@ function createChunkLoader(runtime) {
498
456
  logDebug("ChunkLoader", `Returning cached promise for: "${url}"`);
499
457
  return self.__remote_components_turbopack_chunk_loader_promise__[url];
500
458
  }
501
- logDebug("ChunkLoader", `Fetching chunk from: "${url}"`);
459
+ const resolvedUrl = resolveClientUrl?.(url) ?? url;
460
+ logDebug("ChunkLoader", `Fetching chunk from: "${resolvedUrl}"`);
502
461
  self.__remote_components_turbopack_chunk_loader_promise__[url] = new Promise((resolve, reject) => {
503
- fetchWithProtectedRcFallback(url).then((res) => res.text()).then((code) => {
462
+ fetch(resolvedUrl).then((res) => res.text()).then((code) => {
504
463
  const hasTurbopack = TURBOPACK_GLOBAL_RE.test(code);
505
464
  if (hasTurbopack) {
506
465
  return handleTurbopackChunk(code, bundle ?? "", url);
@@ -513,7 +472,19 @@ function createChunkLoader(runtime) {
513
472
  "ChunkLoader",
514
473
  `First 500 chars of chunk: ${code.slice(0, 500)}`
515
474
  );
516
- }).then(resolve).catch(reject);
475
+ }).then(resolve).catch((error) => {
476
+ const isProxied = isProxiedUrl(resolvedUrl);
477
+ if (isProxied) {
478
+ reject(
479
+ new RemoteComponentsError(
480
+ `Failed to load chunk "${url}" via proxy "${resolvedUrl}". Ensure withRemoteComponentsHost middleware is configured and "${RC_PROTECTED_REMOTE_FETCH_PATHNAME}" is in the matcher. See: ${CORS_DOCS_URL}`
481
+ )
482
+ );
483
+ } else {
484
+ warnCrossOriginFetchError("ChunkLoader", url);
485
+ reject(error);
486
+ }
487
+ });
517
488
  });
518
489
  return self.__remote_components_turbopack_chunk_loader_promise__[url];
519
490
  };
@@ -1006,7 +977,7 @@ function getSharedModule(bundle, id) {
1006
977
  }
1007
978
 
1008
979
  // src/shared/client/webpack-adapter.ts
1009
- async function setupWebpackRuntime(runtime, scripts = [], url = new URL(location.href), bundle, shared = {}, remoteShared = {}) {
980
+ async function setupWebpackRuntime(runtime, scripts = [], url = new URL(location.href), bundle, shared = {}, remoteShared = {}, resolveClientUrl) {
1010
981
  const self = globalThis;
1011
982
  if (!self.__remote_bundle_url__) {
1012
983
  self.__remote_bundle_url__ = {};
@@ -1018,7 +989,7 @@ async function setupWebpackRuntime(runtime, scripts = [], url = new URL(location
1018
989
  self.__original_webpack_chunk_load__ = self.__webpack_chunk_load__;
1019
990
  self.__original_webpack_require__ = self.__webpack_require__;
1020
991
  }
1021
- self.__webpack_chunk_load__ = createChunkLoader(runtime);
992
+ self.__webpack_chunk_load__ = createChunkLoader(runtime, resolveClientUrl);
1022
993
  self.__webpack_require__ = createModuleRequire(runtime);
1023
994
  self.__webpack_require_type__ = runtime;
1024
995
  if (self.__remote_webpack_require__ && runtime === RUNTIME_TURBOPACK) {
@@ -1113,7 +1084,8 @@ async function loadRemoteComponent({
1113
1084
  scripts = [],
1114
1085
  shared = Promise.resolve({}),
1115
1086
  remoteShared = {},
1116
- container
1087
+ container,
1088
+ resolveClientUrl
1117
1089
  }) {
1118
1090
  try {
1119
1091
  if (runtime === "webpack") {
@@ -1122,7 +1094,7 @@ async function loadRemoteComponent({
1122
1094
  self.__DISABLE_WEBPACK_EXEC__ = {};
1123
1095
  }
1124
1096
  self.__DISABLE_WEBPACK_EXEC__[bundle] = true;
1125
- await loadScripts(scripts);
1097
+ await loadScripts(scripts, resolveClientUrl);
1126
1098
  }
1127
1099
  const hostShared = await shared;
1128
1100
  logDebug(
@@ -1143,7 +1115,8 @@ async function loadRemoteComponent({
1143
1115
  url,
1144
1116
  bundle,
1145
1117
  hostShared,
1146
- remoteShared
1118
+ remoteShared,
1119
+ resolveClientUrl
1147
1120
  );
1148
1121
  if (bundle) {
1149
1122
  const resolve = {
@@ -1232,6 +1205,25 @@ function loadNextPagesComponent(bundle, route, nextData, name, container) {
1232
1205
  return { component };
1233
1206
  }
1234
1207
 
1208
+ // src/shared/client/proxy-through-host.ts
1209
+ var proxyClientRequestsThroughHost = (remoteSrc, url) => {
1210
+ if (typeof location === "undefined") {
1211
+ return void 0;
1212
+ }
1213
+ const remoteOrigin = new URL(remoteSrc, location.href).origin;
1214
+ if (remoteOrigin === location.origin) {
1215
+ return void 0;
1216
+ }
1217
+ try {
1218
+ const parsed = new URL(url, location.href);
1219
+ if (parsed.origin === remoteOrigin) {
1220
+ return generateProtectedRcFallbackSrc(url);
1221
+ }
1222
+ } catch {
1223
+ }
1224
+ return void 0;
1225
+ };
1226
+
1235
1227
  // src/shared/client/set-attributes-from-props.ts
1236
1228
  var DOMAttributeNames = {
1237
1229
  acceptCharset: "accept-charset",
@@ -1275,27 +1267,21 @@ function setAttributesFromProps(el, props) {
1275
1267
  }
1276
1268
 
1277
1269
  // src/shared/client/static-loader.ts
1278
- async function importViaProxy(absoluteSrc) {
1279
- const proxyUrl = new URL(
1280
- generateProtectedRcFallbackSrc(absoluteSrc),
1281
- location.href
1282
- ).href;
1283
- const response = await fetch(proxyUrl);
1270
+ async function importViaCallback(absoluteSrc, resolveClientUrl) {
1271
+ const resolvedUrl = resolveClientUrl(absoluteSrc) ?? absoluteSrc;
1272
+ const fetchUrl = new URL(resolvedUrl, location.href).href;
1273
+ const response = await fetch(fetchUrl);
1284
1274
  if (!response.ok)
1285
- throw new Error(`Proxy fetch failed: ${response.status}`);
1286
- logInfo(
1287
- "StaticLoader",
1288
- `Successfully loaded ${absoluteSrc} via protected RC proxy fallback.`
1289
- );
1275
+ throw new Error(`Proxied fetch failed: ${response.status}`);
1290
1276
  const content = (await response.text()).replace(/import\.meta\.url/g, JSON.stringify(absoluteSrc)).replace(
1291
1277
  /\b(from|import)\s*(["'])(\.\.?\/[^"']+)\2/g,
1292
1278
  (_, keyword, quote, relativePath) => {
1293
1279
  const absoluteImportUrl = new URL(relativePath, absoluteSrc).href;
1294
- const absoluteProxyUrl = new URL(
1295
- generateProtectedRcFallbackSrc(absoluteImportUrl),
1280
+ const resolvedImportUrl = new URL(
1281
+ resolveClientUrl(absoluteImportUrl) ?? absoluteImportUrl,
1296
1282
  location.href
1297
1283
  ).href;
1298
- return `${keyword} ${quote}${absoluteProxyUrl}${quote}`;
1284
+ return `${keyword} ${quote}${resolvedImportUrl}${quote}`;
1299
1285
  }
1300
1286
  );
1301
1287
  const moduleBlobUrl = URL.createObjectURL(
@@ -1329,6 +1315,20 @@ async function importViaProxy(absoluteSrc) {
1329
1315
  delete registry[absoluteSrc];
1330
1316
  return mod;
1331
1317
  }
1318
+ async function importDirectly(absoluteSrc) {
1319
+ try {
1320
+ return await import(
1321
+ /* @vite-ignore */
1322
+ /* webpackIgnore: true */
1323
+ absoluteSrc
1324
+ );
1325
+ } catch (importError) {
1326
+ if (!absoluteSrc.startsWith("blob:")) {
1327
+ warnCrossOriginFetchError("StaticLoader", absoluteSrc);
1328
+ }
1329
+ throw importError;
1330
+ }
1331
+ }
1332
1332
  function resolveScriptSrc(script, url) {
1333
1333
  const rawSrc = typeof script.getAttribute === "function" ? script.getAttribute("src") ?? script.src : script.src;
1334
1334
  if (!rawSrc && script.textContent) {
@@ -1341,24 +1341,7 @@ function resolveScriptSrc(script, url) {
1341
1341
  }
1342
1342
  return rawSrc;
1343
1343
  }
1344
- async function importScriptMod(absoluteSrc) {
1345
- try {
1346
- return await import(
1347
- /* @vite-ignore */
1348
- /* webpackIgnore: true */
1349
- absoluteSrc
1350
- );
1351
- } catch (importError) {
1352
- if (absoluteSrc.startsWith("blob:"))
1353
- throw importError;
1354
- logWarn(
1355
- "StaticLoader",
1356
- `Direct import of ${absoluteSrc} failed, attempting via protected RC proxy fallback.`
1357
- );
1358
- return importViaProxy(absoluteSrc);
1359
- }
1360
- }
1361
- async function loadStaticRemoteComponent(scripts, url) {
1344
+ async function loadStaticRemoteComponent(scripts, url, resolveClientUrl) {
1362
1345
  const self = globalThis;
1363
1346
  if (self.__remote_script_entrypoint_mount__?.[url.href]) {
1364
1347
  self.__remote_script_entrypoint_mount__[url.href] = /* @__PURE__ */ new Set();
@@ -1371,7 +1354,7 @@ async function loadStaticRemoteComponent(scripts, url) {
1371
1354
  try {
1372
1355
  const src = resolveScriptSrc(script, url);
1373
1356
  const absoluteSrc = new URL(src, url).href;
1374
- const mod = await importScriptMod(absoluteSrc);
1357
+ const mod = resolveClientUrl ? await importViaCallback(absoluteSrc, resolveClientUrl) : await importDirectly(absoluteSrc);
1375
1358
  if (src.startsWith("blob:")) {
1376
1359
  URL.revokeObjectURL(src);
1377
1360
  }
@@ -1446,6 +1429,7 @@ async function loadStaticRemoteComponent(scripts, url) {
1446
1429
  loadRemoteComponent,
1447
1430
  loadScripts,
1448
1431
  loadStaticRemoteComponent,
1432
+ proxyClientRequestsThroughHost,
1449
1433
  setAttributesFromProps,
1450
1434
  setupWebpackRuntime
1451
1435
  });