remote-components 0.2.0 → 0.2.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 (80) hide show
  1. package/dist/config/nextjs.cjs +1 -1
  2. package/dist/config/nextjs.cjs.map +1 -1
  3. package/dist/config/nextjs.js +1 -1
  4. package/dist/config/nextjs.js.map +1 -1
  5. package/dist/host/html.cjs +19 -17
  6. package/dist/host/html.cjs.map +1 -1
  7. package/dist/host/html.js +19 -17
  8. package/dist/host/html.js.map +1 -1
  9. package/dist/host/nextjs/app/client-only.cjs +93 -59
  10. package/dist/host/nextjs/app/client-only.cjs.map +1 -1
  11. package/dist/host/nextjs/app/client-only.d.ts +28 -9
  12. package/dist/host/nextjs/app/client-only.js +91 -58
  13. package/dist/host/nextjs/app/client-only.js.map +1 -1
  14. package/dist/host/nextjs/pages.cjs +4 -4
  15. package/dist/host/nextjs/pages.cjs.map +1 -1
  16. package/dist/host/nextjs/pages.js +4 -4
  17. package/dist/host/nextjs/pages.js.map +1 -1
  18. package/dist/host/react.cjs +33 -23
  19. package/dist/host/react.cjs.map +1 -1
  20. package/dist/host/react.d.ts +2 -366
  21. package/dist/host/react.js +33 -23
  22. package/dist/host/react.js.map +1 -1
  23. package/dist/index-4c65355c.d.ts +298 -0
  24. package/dist/internal/config/webpack/apply-shared-modules.cjs +6 -2
  25. package/dist/internal/config/webpack/apply-shared-modules.cjs.map +1 -1
  26. package/dist/internal/config/webpack/apply-shared-modules.js +6 -2
  27. package/dist/internal/config/webpack/apply-shared-modules.js.map +1 -1
  28. package/dist/internal/config/webpack/next-client-pages-loader.d.ts +3 -3
  29. package/dist/internal/host/nextjs/app-client.cjs +4 -3
  30. package/dist/internal/host/nextjs/app-client.cjs.map +1 -1
  31. package/dist/internal/host/nextjs/app-client.d.ts +1 -1
  32. package/dist/internal/host/nextjs/app-client.js +4 -3
  33. package/dist/internal/host/nextjs/app-client.js.map +1 -1
  34. package/dist/internal/host/nextjs/image-impl.cjs +8 -4
  35. package/dist/internal/host/nextjs/image-impl.cjs.map +1 -1
  36. package/dist/internal/host/nextjs/image-impl.d.ts +2 -2
  37. package/dist/internal/host/nextjs/image-impl.js +8 -4
  38. package/dist/internal/host/nextjs/image-impl.js.map +1 -1
  39. package/dist/internal/host/react/context.cjs +5 -10
  40. package/dist/internal/host/react/context.cjs.map +1 -1
  41. package/dist/internal/host/react/context.d.ts +7 -18
  42. package/dist/internal/host/react/context.js +4 -9
  43. package/dist/internal/host/react/context.js.map +1 -1
  44. package/dist/internal/host/react/hooks/use-resolve-client-url.cjs +5 -4
  45. package/dist/internal/host/react/hooks/use-resolve-client-url.cjs.map +1 -1
  46. package/dist/internal/host/react/hooks/use-resolve-client-url.d.ts +4 -1
  47. package/dist/internal/host/react/hooks/use-resolve-client-url.js +5 -4
  48. package/dist/internal/host/react/hooks/use-resolve-client-url.js.map +1 -1
  49. package/dist/internal/host/shared/config.cjs.map +1 -1
  50. package/dist/internal/host/shared/config.d.ts +7 -0
  51. package/dist/internal/host/shared/resolved-data.d.ts +2 -2
  52. package/dist/internal/runtime/loaders/component-loader.d.ts +1 -1
  53. package/dist/internal/runtime/loaders/script-loader.cjs +1 -6
  54. package/dist/internal/runtime/loaders/script-loader.cjs.map +1 -1
  55. package/dist/internal/runtime/loaders/script-loader.js +4 -9
  56. package/dist/internal/runtime/loaders/script-loader.js.map +1 -1
  57. package/dist/internal/runtime/turbopack/chunk-loader.cjs +1 -6
  58. package/dist/internal/runtime/turbopack/chunk-loader.cjs.map +1 -1
  59. package/dist/internal/runtime/turbopack/chunk-loader.js +4 -9
  60. package/dist/internal/runtime/turbopack/chunk-loader.js.map +1 -1
  61. package/dist/internal/runtime/turbopack/shared-modules.cjs +3 -2
  62. package/dist/internal/runtime/turbopack/shared-modules.cjs.map +1 -1
  63. package/dist/internal/runtime/turbopack/shared-modules.js +3 -2
  64. package/dist/internal/runtime/turbopack/shared-modules.js.map +1 -1
  65. package/dist/internal/utils/error.cjs +7 -0
  66. package/dist/internal/utils/error.cjs.map +1 -1
  67. package/dist/internal/utils/error.d.ts +2 -1
  68. package/dist/internal/utils/error.js +6 -0
  69. package/dist/internal/utils/error.js.map +1 -1
  70. package/dist/internal/utils/logger.cjs +1 -1
  71. package/dist/internal/utils/logger.cjs.map +1 -1
  72. package/dist/internal/utils/logger.d.ts +1 -1
  73. package/dist/internal/utils/logger.js +1 -1
  74. package/dist/internal/utils/logger.js.map +1 -1
  75. package/dist/remote/html.cjs +1 -1
  76. package/dist/remote/html.cjs.map +1 -1
  77. package/dist/remote/html.js +1 -1
  78. package/dist/remote/html.js.map +1 -1
  79. package/dist/{server-handoff-8c89b856.d.ts → server-handoff-ce13bebc.d.ts} +2 -2
  80. package/package.json +1 -9
@@ -61,10 +61,12 @@ var init_app = __esm({
61
61
  // src/host/nextjs/app-client-only.tsx
62
62
  var app_client_only_exports = {};
63
63
  __export(app_client_only_exports, {
64
- ConsumeRemoteComponent: () => ConsumeRemoteComponent2
64
+ ConsumeRemoteComponent: () => ConsumeRemoteComponent2,
65
+ RemoteComponentsClientProvider: () => RemoteComponentsClientProvider
65
66
  });
66
67
  module.exports = __toCommonJS(app_client_only_exports);
67
68
  var Image = __toESM(require("next/image"), 1);
69
+ var import_react5 = require("react");
68
70
 
69
71
  // src/utils/logger.ts
70
72
  init_constants();
@@ -150,6 +152,11 @@ async function errorFromFailedFetch(originalUrl, resolvedUrl, res) {
150
152
  }
151
153
  return fallback;
152
154
  }
155
+ function failedProxiedAssetError(kind, url, resolvedUrl) {
156
+ return new RemoteComponentsError(
157
+ `Failed to load ${kind} "${url}" via proxy "${resolvedUrl}". Ensure withRemoteComponentsHostProxy middleware is configured, "${RC_PROTECTED_REMOTE_FETCH_PATHNAME}" is in the matcher, and the remote URL is included in allowedProxyUrls. See: ${CORS_DOCS_URL}`
158
+ );
159
+ }
153
160
  function failedProxyFetchError(originalUrl, proxyUrl, status, responseBody) {
154
161
  if (status === 404) {
155
162
  return new RemoteComponentsError(
@@ -201,7 +208,7 @@ function warnCrossOriginFetchError(logLocation, url) {
201
208
  }
202
209
  logWarn(
203
210
  logLocation,
204
- `Failed to fetch cross-origin resource "${parsed.href}". If this is a protected deployment, ensure withRemoteComponentsHostProxy middleware is configured in your host and that the remote URL is included in allowedProxyUrls. See: ${CORS_DOCS_URL}`
211
+ `Failed to fetch cross-origin resource "${parsed.href}". To load assets from a protected deployment, two steps are required: (1) configure withRemoteComponentsHostProxy middleware in your host with the remote URL in allowedProxyUrls, and (2) provide a resolveClientUrl prop that rewrites cross-origin asset URLs to go through the proxy. See: ${CORS_DOCS_URL}`
205
212
  );
206
213
  } catch {
207
214
  }
@@ -406,10 +413,11 @@ function sharedPolyfills(shared2, resolveClientUrl) {
406
413
 
407
414
  // src/host/nextjs/image-impl.tsx
408
415
  var import_jsx_runtime2 = require("react/jsx-runtime");
416
+ var getBundleUrl = (bundle) => globalThis.__remote_bundle_url__?.[bundle];
409
417
  function createRemoteLoader(bundle, resolveClientUrl) {
410
418
  return ({ src, width, quality }) => {
411
- const self = globalThis;
412
- const origin = self.__remote_bundle_url__?.[bundle]?.origin ?? "";
419
+ const bundleUrl = getBundleUrl(bundle);
420
+ const origin = bundleUrl?.origin ?? "";
413
421
  let imageUrl = src;
414
422
  try {
415
423
  const parsed = new URL(src);
@@ -420,7 +428,8 @@ function createRemoteLoader(bundle, resolveClientUrl) {
420
428
  }
421
429
  const { assetPrefix } = /^(?<assetPrefix>.*?)\/_next\//.exec(imageUrl)?.groups ?? {};
422
430
  const url = `${origin}${assetPrefix ?? ""}/_next/image?url=${encodeURIComponent(imageUrl)}&w=${width}&q=${quality ?? 75}`;
423
- return resolveClientUrl?.(url) ?? url;
431
+ const remoteSrc = bundleUrl?.href ?? url;
432
+ return resolveClientUrl?.(remoteSrc, url) ?? url;
424
433
  };
425
434
  }
426
435
  function imageImpl2(ImageComponent, bundle, resolveClientUrl, useRemoteLoader) {
@@ -430,40 +439,22 @@ function imageImpl2(ImageComponent, bundle, resolveClientUrl, useRemoteLoader) {
430
439
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ImageComponent, { loader: remoteLoader, ...props });
431
440
  }
432
441
  const rawSrc = applyBundleUrlToImagePropsSrc(bundle, props.src);
433
- const src = resolveClientUrl?.(rawSrc) ?? rawSrc;
442
+ const bundleUrl = getBundleUrl(bundle);
443
+ const remoteSrc = bundleUrl?.href ?? rawSrc;
444
+ const src = resolveClientUrl?.(remoteSrc, rawSrc) ?? rawSrc;
434
445
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ImageComponent, { ...props, src });
435
446
  };
436
447
  component.default = component;
437
448
  return component;
438
449
  }
439
450
 
440
- // src/runtime/url/resolve-client-url.ts
441
- function withRemoteSrc(resolveClientUrl, remoteSrc) {
442
- const remoteOrigin = parseOrigin(remoteSrc);
443
- return (url) => {
444
- const urlOrigin = parseOrigin(url);
445
- if (remoteOrigin && urlOrigin && urlOrigin !== remoteOrigin) {
446
- return void 0;
447
- }
448
- return resolveClientUrl(remoteSrc, url);
449
- };
450
- }
451
- function parseOrigin(url) {
452
- try {
453
- return new URL(url).origin;
454
- } catch {
455
- return void 0;
456
- }
457
- }
458
-
459
- // src/runtime/url/default-resolve-client-url.ts
460
- function bindResolveClientUrl(prop, remoteSrc) {
461
- return prop ? withRemoteSrc(prop, remoteSrc) : void 0;
462
- }
451
+ // src/host/nextjs/app-client-only.tsx
452
+ var import_context3 = require("#internal/host/react/context");
463
453
 
464
454
  // src/host/react/index.tsx
465
455
  var import_react3 = require("react");
466
456
  var import_react_dom = require("react-dom");
457
+ var import_context2 = require("#internal/host/react/context");
467
458
 
468
459
  // src/host/server/fetch-headers.ts
469
460
  function remoteFetchHeaders() {
@@ -775,6 +766,7 @@ var ReactDOM = __toESM(require("react-dom"), 1);
775
766
  var ReactDOMClient = __toESM(require("react-dom/client"), 1);
776
767
 
777
768
  // src/config/webpack/apply-shared-modules.ts
769
+ var DEDUPLICATION_SKIPPED = "shared module deduplication skipped. The remote may load its own copy of shared dependencies.";
778
770
  function applySharedModules(bundle, resolve) {
779
771
  logDebug(
780
772
  "SharedModules",
@@ -818,13 +810,16 @@ function applySharedModules(bundle, resolve) {
818
810
  } else {
819
811
  logWarn(
820
812
  "SharedModules",
821
- `webpackBundle.m is not available for bundle "${bundle}"`
813
+ `webpackBundle.m is not available for bundle "${bundle}" \u2014 ${DEDUPLICATION_SKIPPED}`
822
814
  );
823
815
  }
824
816
  }
825
817
  }
826
818
  } else {
827
- logWarn("SharedModules", `No webpack require found for bundle "${bundle}"`);
819
+ logWarn(
820
+ "SharedModules",
821
+ `No webpack require found for bundle "${bundle}" \u2014 ${DEDUPLICATION_SKIPPED}`
822
+ );
828
823
  logDebug(
829
824
  "SharedModules",
830
825
  `Available bundles: ${Object.keys(self.__remote_webpack_require__ ?? {})}`
@@ -1010,9 +1005,6 @@ function createRSCStream(rscName, data) {
1010
1005
  });
1011
1006
  }
1012
1007
 
1013
- // src/runtime/turbopack/chunk-loader.ts
1014
- init_constants();
1015
-
1016
1008
  // src/runtime/turbopack/patterns.ts
1017
1009
  var REMOTE_SHARED_MARKER_RE = /(?:self|[a-z])\.TURBOPACK_REMOTE_SHARED/;
1018
1010
  var REMOTE_SHARED_ASSIGNMENT_RE = /\.TURBOPACK_REMOTE_SHARED=await (?:__turbopack_context__|[a-z])\.A\((?<sharedModuleId>[0-9]+)\)/;
@@ -1081,11 +1073,7 @@ function createChunkLoader(runtime, resolveClientUrl) {
1081
1073
  }).then(resolve).catch((error) => {
1082
1074
  const isProxied = isProxiedUrl(resolvedUrl);
1083
1075
  if (isProxied) {
1084
- reject(
1085
- new RemoteComponentsError(
1086
- `Failed to load chunk "${url}" via proxy "${resolvedUrl}". Ensure withRemoteComponentsHostProxy middleware is configured and "${RC_PROTECTED_REMOTE_FETCH_PATHNAME}" is in the matcher. See: ${CORS_DOCS_URL}`
1087
- )
1088
- );
1076
+ reject(failedProxiedAssetError("chunk", url, resolvedUrl));
1089
1077
  } else {
1090
1078
  warnCrossOriginFetchError("ChunkLoader", url);
1091
1079
  reject(error);
@@ -1463,6 +1451,7 @@ function createTurbopackContext(bundle, exports, moduleExports, modules, moduleI
1463
1451
  }
1464
1452
 
1465
1453
  // src/runtime/turbopack/shared-modules.ts
1454
+ var DEDUPLICATION_WARNING = "This module will not be deduplicated \u2014 the remote may load its own copy, which can cause duplicate instance errors (e.g. invalid hook calls if React is loaded twice).";
1466
1455
  async function initializeSharedModules(bundle, hostShared = {}, remoteShared = {}) {
1467
1456
  const self = globalThis;
1468
1457
  self.__remote_shared_modules__ = self.__remote_shared_modules__ ?? {};
@@ -1513,7 +1502,7 @@ async function initializeSharedModules(bundle, hostShared = {}, remoteShared = {
1513
1502
  } else {
1514
1503
  logError(
1515
1504
  "SharedModules",
1516
- `Host shared module "${module2}" not found for ID ${id}`
1505
+ `Host shared module "${module2}" not found for ID ${id}. ${DEDUPLICATION_WARNING}`
1517
1506
  );
1518
1507
  }
1519
1508
  }
@@ -1530,7 +1519,7 @@ async function initializeSharedModules(bundle, hostShared = {}, remoteShared = {
1530
1519
  } else {
1531
1520
  logError(
1532
1521
  "SharedModules",
1533
- `Shared module "${module2}" not found for "${bundle}"`
1522
+ `Shared module "${module2}" not found for "${bundle}". ${DEDUPLICATION_WARNING}`
1534
1523
  );
1535
1524
  }
1536
1525
  }
@@ -1678,7 +1667,6 @@ function createModuleRequire(runtime) {
1678
1667
  }
1679
1668
 
1680
1669
  // src/runtime/loaders/script-loader.ts
1681
- init_constants();
1682
1670
  async function loadScripts(scripts, resolveClientUrl) {
1683
1671
  await Promise.all(
1684
1672
  scripts.map((script) => {
@@ -1694,11 +1682,7 @@ async function loadScripts(scripts, resolveClientUrl) {
1694
1682
  newScript.onerror = () => {
1695
1683
  const isProxied = isProxiedUrl(resolvedSrc);
1696
1684
  if (isProxied) {
1697
- reject(
1698
- new RemoteComponentsError(
1699
- `Failed to load script "${newSrc}" via proxy "${resolvedSrc}". Ensure withRemoteComponentsHostProxy middleware is configured and "${RC_PROTECTED_REMOTE_FETCH_PATHNAME}" is in the matcher. See: ${CORS_DOCS_URL}`
1700
- )
1701
- );
1685
+ reject(failedProxiedAssetError("script", newSrc, resolvedSrc));
1702
1686
  } else {
1703
1687
  warnCrossOriginFetchError("ScriptLoader", newSrc);
1704
1688
  reject(
@@ -2005,13 +1989,40 @@ async function loadStaticRemoteComponent(scripts, url, resolveClientUrl) {
2005
1989
  // src/host/react/hooks/use-resolve-client-url.ts
2006
1990
  var import_react = require("react");
2007
1991
  var import_context = require("#internal/host/react/context");
1992
+
1993
+ // src/runtime/url/resolve-client-url.ts
1994
+ function withRemoteSrc(resolveClientUrl, remoteSrc) {
1995
+ const remoteOrigin = parseOrigin(remoteSrc);
1996
+ return (url) => {
1997
+ const urlOrigin = parseOrigin(url);
1998
+ if (remoteOrigin && urlOrigin && urlOrigin !== remoteOrigin) {
1999
+ return void 0;
2000
+ }
2001
+ return resolveClientUrl(remoteSrc, url);
2002
+ };
2003
+ }
2004
+ function parseOrigin(url) {
2005
+ try {
2006
+ return new URL(url).origin;
2007
+ } catch {
2008
+ return void 0;
2009
+ }
2010
+ }
2011
+
2012
+ // src/runtime/url/default-resolve-client-url.ts
2013
+ function bindResolveClientUrl(prop, remoteSrc) {
2014
+ return prop ? withRemoteSrc(prop, remoteSrc) : void 0;
2015
+ }
2016
+
2017
+ // src/host/react/hooks/use-resolve-client-url.ts
2008
2018
  function useResolveClientUrl(prop, urlHref) {
2009
2019
  const { resolveClientUrl: contextValue } = (0, import_context.useRemoteComponentsContext)();
2010
- const resolveClientUrl = prop ?? contextValue;
2011
- return (0, import_react.useMemo)(
2012
- () => bindResolveClientUrl(resolveClientUrl, urlHref),
2013
- [resolveClientUrl, urlHref]
2020
+ const raw = prop ?? contextValue;
2021
+ const bound = (0, import_react.useMemo)(
2022
+ () => bindResolveClientUrl(raw, urlHref),
2023
+ [raw, urlHref]
2014
2024
  );
2025
+ return { bound, raw };
2015
2026
  }
2016
2027
 
2017
2028
  // src/host/react/hooks/use-shadow-root.ts
@@ -2096,9 +2107,9 @@ function ConsumeRemoteComponent({
2096
2107
  isolate,
2097
2108
  mode = "open",
2098
2109
  reset,
2099
- credentials = "same-origin",
2110
+ credentials: credentialsProp,
2100
2111
  name: nameProp = "__vercel_remote_component",
2101
- shared: shared2 = {},
2112
+ shared: sharedProp,
2102
2113
  children,
2103
2114
  onBeforeLoad,
2104
2115
  onLoad,
@@ -2106,9 +2117,12 @@ function ConsumeRemoteComponent({
2106
2117
  onChange,
2107
2118
  onRequest,
2108
2119
  onResponse,
2109
- resolveClientUrl: _resolveClientUrl
2120
+ resolveClientUrl: resolveClientUrlProp
2110
2121
  }) {
2111
2122
  const instanceId = (0, import_react3.useId)();
2123
+ const { credentials: contextCredentials, shared: contextShared } = (0, import_context2.useRemoteComponentsContext)();
2124
+ const credentials = credentialsProp ?? contextCredentials ?? "same-origin";
2125
+ const shared2 = sharedProp ?? contextShared ?? {};
2112
2126
  const name = (0, import_react3.useMemo)(
2113
2127
  () => resolveNameFromSrc(src, nameProp),
2114
2128
  [src, nameProp]
@@ -2117,7 +2131,10 @@ function ConsumeRemoteComponent({
2117
2131
  null
2118
2132
  );
2119
2133
  const url = (0, import_react3.useMemo)(() => getClientOrServerUrl(src, DUMMY_FALLBACK), [src]);
2120
- const resolveClientUrl = useResolveClientUrl(_resolveClientUrl, url.href);
2134
+ const { bound: resolveClientUrl } = useResolveClientUrl(
2135
+ resolveClientUrlProp,
2136
+ url.href
2137
+ );
2121
2138
  const id = url.origin === (typeof location !== "undefined" ? location.origin : DUMMY_FALLBACK) ? url.pathname : url.href;
2122
2139
  const keySuffix = `${escapeString(id)}_${escapeString(
2123
2140
  data?.name ?? name
@@ -2719,22 +2736,39 @@ var sharedModules = async (userShared, resolveClientUrl) => {
2719
2736
  ...resolvedUserShared
2720
2737
  };
2721
2738
  };
2739
+ function RemoteComponentsClientProvider({
2740
+ shared: shared2,
2741
+ resolveClientUrl,
2742
+ children,
2743
+ ...props
2744
+ }) {
2745
+ const mergedShared = (0, import_react5.useMemo)(
2746
+ () => sharedModules(shared2, resolveClientUrl),
2747
+ [shared2, resolveClientUrl]
2748
+ );
2749
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2750
+ import_context3.RemoteComponentsContext,
2751
+ {
2752
+ value: { shared: mergedShared, resolveClientUrl, ...props },
2753
+ children
2754
+ }
2755
+ );
2756
+ }
2722
2757
  function ConsumeRemoteComponent2(props) {
2723
2758
  if (typeof props.src !== "string" && !(props.src instanceof URL)) {
2724
2759
  return props.children ?? null;
2725
2760
  }
2726
- const src = typeof props.src === "string" ? props.src : props.src.href;
2727
- const resolveClientUrl = props.resolveClientUrl ? bindResolveClientUrl(props.resolveClientUrl, src) : void 0;
2728
2761
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2729
2762
  ConsumeRemoteComponent,
2730
2763
  {
2731
2764
  ...props,
2732
- shared: sharedModules(props.shared, resolveClientUrl)
2765
+ shared: sharedModules(props.shared, props.resolveClientUrl)
2733
2766
  }
2734
2767
  );
2735
2768
  }
2736
2769
  // Annotate the CommonJS export names for ESM import in node:
2737
2770
  0 && (module.exports = {
2738
- ConsumeRemoteComponent
2771
+ ConsumeRemoteComponent,
2772
+ RemoteComponentsClientProvider
2739
2773
  });
2740
2774
  //# sourceMappingURL=client-only.cjs.map