remote-components 0.2.2 → 0.3.1

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 (100) hide show
  1. package/dist/config/nextjs.cjs +2 -4
  2. package/dist/config/nextjs.cjs.map +1 -1
  3. package/dist/config/nextjs.d.ts +1 -1
  4. package/dist/config/nextjs.js +2 -4
  5. package/dist/config/nextjs.js.map +1 -1
  6. package/dist/host/html.cjs +128 -112
  7. package/dist/host/html.cjs.map +1 -1
  8. package/dist/host/html.js +128 -115
  9. package/dist/host/html.js.map +1 -1
  10. package/dist/host/nextjs/app/client-only.cjs +233 -259
  11. package/dist/host/nextjs/app/client-only.cjs.map +1 -1
  12. package/dist/host/nextjs/app/client-only.js +234 -260
  13. package/dist/host/nextjs/app/client-only.js.map +1 -1
  14. package/dist/host/nextjs/app.cjs +5 -6
  15. package/dist/host/nextjs/app.cjs.map +1 -1
  16. package/dist/host/nextjs/app.js +5 -6
  17. package/dist/host/nextjs/app.js.map +1 -1
  18. package/dist/host/nextjs/pages.cjs +7 -19
  19. package/dist/host/nextjs/pages.cjs.map +1 -1
  20. package/dist/host/nextjs/pages.js +11 -20
  21. package/dist/host/nextjs/pages.js.map +1 -1
  22. package/dist/host/react.cjs +101 -93
  23. package/dist/host/react.cjs.map +1 -1
  24. package/dist/host/react.js +101 -93
  25. package/dist/host/react.js.map +1 -1
  26. package/dist/internal/host/nextjs/app-client.cjs +3 -8
  27. package/dist/internal/host/nextjs/app-client.cjs.map +1 -1
  28. package/dist/internal/host/nextjs/app-client.js +4 -9
  29. package/dist/internal/host/nextjs/app-client.js.map +1 -1
  30. package/dist/internal/host/nextjs/dom-flight.cjs +16 -7
  31. package/dist/internal/host/nextjs/dom-flight.cjs.map +1 -1
  32. package/dist/internal/host/nextjs/dom-flight.d.ts +2 -2
  33. package/dist/internal/host/nextjs/dom-flight.js +16 -7
  34. package/dist/internal/host/nextjs/dom-flight.js.map +1 -1
  35. package/dist/internal/host/nextjs/image-shared.cjs +25 -15
  36. package/dist/internal/host/nextjs/image-shared.cjs.map +1 -1
  37. package/dist/internal/host/nextjs/image-shared.d.ts +19 -6
  38. package/dist/internal/host/nextjs/image-shared.js +24 -14
  39. package/dist/internal/host/nextjs/image-shared.js.map +1 -1
  40. package/dist/internal/host/react/hooks/use-resolve-client-url.cjs +1 -5
  41. package/dist/internal/host/react/hooks/use-resolve-client-url.cjs.map +1 -1
  42. package/dist/internal/host/react/hooks/use-resolve-client-url.d.ts +1 -4
  43. package/dist/internal/host/react/hooks/use-resolve-client-url.js +1 -5
  44. package/dist/internal/host/react/hooks/use-resolve-client-url.js.map +1 -1
  45. package/dist/internal/host/server/fetch-remote-component.cjs +164 -149
  46. package/dist/internal/host/server/fetch-remote-component.cjs.map +1 -1
  47. package/dist/internal/host/server/fetch-remote-component.js +166 -149
  48. package/dist/internal/host/server/fetch-remote-component.js.map +1 -1
  49. package/dist/internal/host/shared/polyfill.cjs +10 -65
  50. package/dist/internal/host/shared/polyfill.cjs.map +1 -1
  51. package/dist/internal/host/shared/polyfill.d.ts +1 -3
  52. package/dist/internal/host/shared/polyfill.js +9 -63
  53. package/dist/internal/host/shared/polyfill.js.map +1 -1
  54. package/dist/internal/host/shared/remote-image-loader.cjs +53 -0
  55. package/dist/internal/host/shared/remote-image-loader.cjs.map +1 -0
  56. package/dist/internal/host/shared/remote-image-loader.d.ts +30 -0
  57. package/dist/internal/host/shared/remote-image-loader.js +29 -0
  58. package/dist/internal/host/shared/remote-image-loader.js.map +1 -0
  59. package/dist/internal/runtime/constants.cjs +6 -6
  60. package/dist/internal/runtime/constants.cjs.map +1 -1
  61. package/dist/internal/runtime/constants.d.ts +3 -3
  62. package/dist/internal/runtime/constants.js +4 -4
  63. package/dist/internal/runtime/constants.js.map +1 -1
  64. package/dist/internal/runtime/html/parse-remote-html.cjs +11 -15
  65. package/dist/internal/runtime/html/parse-remote-html.cjs.map +1 -1
  66. package/dist/internal/runtime/html/parse-remote-html.d.ts +2 -12
  67. package/dist/internal/runtime/html/parse-remote-html.js +17 -15
  68. package/dist/internal/runtime/html/parse-remote-html.js.map +1 -1
  69. package/dist/internal/runtime/loaders/script-loader.cjs +2 -2
  70. package/dist/internal/runtime/loaders/script-loader.cjs.map +1 -1
  71. package/dist/internal/runtime/loaders/script-loader.js +1 -1
  72. package/dist/internal/runtime/loaders/script-loader.js.map +1 -1
  73. package/dist/internal/runtime/metadata.cjs +42 -0
  74. package/dist/internal/runtime/metadata.cjs.map +1 -1
  75. package/dist/internal/runtime/metadata.d.ts +21 -1
  76. package/dist/internal/runtime/metadata.js +38 -0
  77. package/dist/internal/runtime/metadata.js.map +1 -1
  78. package/dist/internal/runtime/patterns.cjs +38 -0
  79. package/dist/internal/runtime/patterns.cjs.map +1 -0
  80. package/dist/internal/runtime/patterns.d.ts +5 -0
  81. package/dist/internal/runtime/patterns.js +12 -0
  82. package/dist/internal/runtime/patterns.js.map +1 -0
  83. package/dist/internal/runtime/turbopack/chunk-loader.cjs +4 -3
  84. package/dist/internal/runtime/turbopack/chunk-loader.cjs.map +1 -1
  85. package/dist/internal/runtime/turbopack/chunk-loader.js +1 -1
  86. package/dist/internal/runtime/turbopack/chunk-loader.js.map +1 -1
  87. package/dist/internal/runtime/turbopack/webpack-runtime.cjs +11 -2
  88. package/dist/internal/runtime/turbopack/webpack-runtime.cjs.map +1 -1
  89. package/dist/internal/runtime/turbopack/webpack-runtime.js +10 -2
  90. package/dist/internal/runtime/turbopack/webpack-runtime.js.map +1 -1
  91. package/dist/remote/nextjs/app.cjs +2 -1
  92. package/dist/remote/nextjs/app.cjs.map +1 -1
  93. package/dist/remote/nextjs/app.js +2 -1
  94. package/dist/remote/nextjs/app.js.map +1 -1
  95. package/package.json +1 -1
  96. package/dist/internal/host/nextjs/image-impl.cjs +0 -64
  97. package/dist/internal/host/nextjs/image-impl.cjs.map +0 -1
  98. package/dist/internal/host/nextjs/image-impl.d.ts +0 -10
  99. package/dist/internal/host/nextjs/image-impl.js +0 -40
  100. package/dist/internal/host/nextjs/image-impl.js.map +0 -1
@@ -37,9 +37,100 @@ var init_app = __esm({
37
37
  });
38
38
 
39
39
  // src/host/nextjs/app-client-only.tsx
40
- import * as Image from "next/image";
41
40
  import { useMemo as useMemo3 } from "react";
42
41
 
42
+ // src/host/shared/remote-image-loader.ts
43
+ function getRemoteBundleOrigin(bundle) {
44
+ const self = globalThis;
45
+ return self.__remote_bundle_url__?.[bundle]?.origin ?? "";
46
+ }
47
+ function createRemoteImageLoader(bundle, resolveClientUrl) {
48
+ const loader = Object.assign(
49
+ ({
50
+ config,
51
+ src,
52
+ width,
53
+ quality
54
+ }) => {
55
+ const q = quality ?? 75;
56
+ const remoteOrigin = getRemoteBundleOrigin(bundle);
57
+ const isCrossOrigin = remoteOrigin && remoteOrigin !== location.origin;
58
+ const basePath = isCrossOrigin ? `${remoteOrigin}${config.path ?? "/_next/image"}` : config.path ?? `${remoteOrigin}/_next/image`;
59
+ const url = `${basePath}?url=${encodeURIComponent(src)}&w=${width}&q=${q}`;
60
+ return resolveClientUrl?.(url) ?? url;
61
+ },
62
+ // Signals to getImgProps that this is a default loader (not a user-defined
63
+ // one), enabling srcSet generation with device/image sizes from the config.
64
+ { __next_img_default: true }
65
+ );
66
+ return loader;
67
+ }
68
+
69
+ // src/runtime/url/resolve-client-url.ts
70
+ function withRemoteSrc(resolveClientUrl, remoteSrc) {
71
+ const remoteOrigin = parseOrigin(remoteSrc);
72
+ return (url) => {
73
+ const urlOrigin = parseOrigin(url);
74
+ if (remoteOrigin && urlOrigin && urlOrigin !== remoteOrigin) {
75
+ return void 0;
76
+ }
77
+ return resolveClientUrl(remoteSrc, url);
78
+ };
79
+ }
80
+ function parseOrigin(url) {
81
+ try {
82
+ return new URL(url).origin;
83
+ } catch {
84
+ return void 0;
85
+ }
86
+ }
87
+
88
+ // src/runtime/url/default-resolve-client-url.ts
89
+ function bindResolveClientUrl(prop, remoteSrc) {
90
+ return prop ? withRemoteSrc(prop, remoteSrc) : void 0;
91
+ }
92
+
93
+ // src/host/nextjs/image-shared.ts
94
+ function resolveForBundle(unbound, bundle) {
95
+ if (!unbound)
96
+ return void 0;
97
+ const self = globalThis;
98
+ const remoteSrc = self.__remote_bundle_url__?.[bundle]?.href ?? "";
99
+ return bindResolveClientUrl(unbound, remoteSrc);
100
+ }
101
+ function createImageLoaderSharedEntries({
102
+ bound,
103
+ unbound
104
+ } = {}) {
105
+ const entry = (bundle) => {
106
+ const resolveClientUrl = bound ?? resolveForBundle(unbound, bundle);
107
+ return Promise.resolve({
108
+ default: createRemoteImageLoader(bundle, resolveClientUrl),
109
+ __esModule: true
110
+ });
111
+ };
112
+ return {
113
+ "next/dist/shared/lib/image-loader": entry,
114
+ "next/dist/esm/shared/lib/image-loader": entry
115
+ };
116
+ }
117
+
118
+ // src/host/nextjs/app-client-only.tsx
119
+ import { RemoteComponentsContext } from "#internal/host/react/context";
120
+
121
+ // src/host/react/index.tsx
122
+ import {
123
+ startTransition,
124
+ useEffect,
125
+ useId,
126
+ useLayoutEffect as useLayoutEffect2,
127
+ useMemo as useMemo2,
128
+ useRef as useRef2,
129
+ useState as useState2
130
+ } from "react";
131
+ import { createPortal } from "react-dom";
132
+ import { useRemoteComponentsContext as useRemoteComponentsContext2 } from "#internal/host/react/context";
133
+
43
134
  // src/utils/logger.ts
44
135
  init_constants();
45
136
 
@@ -186,58 +277,63 @@ function warnCrossOriginFetchError(logLocation, url) {
186
277
  }
187
278
  }
188
279
 
280
+ // src/host/server/fetch-headers.ts
281
+ function remoteFetchHeaders() {
282
+ return {
283
+ /**
284
+ * Authenticates deployment protection for the remote. Needed for SSR and SSG clients.
285
+ * If the remote component uses vercel deployment protection, ensure the host and remote vercel
286
+ * projects share a common automation bypass secret, and the shared secret is used as the
287
+ * VERCEL_AUTOMATION_BYPASS_SECRET env var in the host project.
288
+ */
289
+ ...typeof process === "object" && typeof process.env === "object" && typeof process.env.VERCEL_AUTOMATION_BYPASS_SECRET === "string" ? {
290
+ "x-vercel-protection-bypass": process.env.VERCEL_AUTOMATION_BYPASS_SECRET
291
+ } : {},
292
+ Accept: "text/html"
293
+ };
294
+ }
295
+
296
+ // src/host/server/fetch-with-hooks.ts
297
+ async function fetchWithWarning(url, init) {
298
+ try {
299
+ return await fetch(url, init);
300
+ } catch (error) {
301
+ warnCrossOriginFetchError("FetchRemoteComponent", url);
302
+ throw error;
303
+ }
304
+ }
305
+ async function fetchWithHooks(url, additionalInit, options = {}) {
306
+ const {
307
+ onRequest,
308
+ onResponse,
309
+ abortController = new AbortController()
310
+ } = options;
311
+ const signal = abortController.signal;
312
+ const hookOptions = {
313
+ signal,
314
+ abort: (reason) => abortController.abort(reason)
315
+ };
316
+ const init = {
317
+ method: "GET",
318
+ headers: remoteFetchHeaders(),
319
+ signal,
320
+ ...additionalInit
321
+ };
322
+ const res = await onRequest?.(url, init, hookOptions) ?? await fetchWithWarning(url, init);
323
+ return await onResponse?.(url, res, hookOptions) ?? res;
324
+ }
325
+
326
+ // src/host/server/get-client-or-server-url.ts
327
+ function getClientOrServerUrl(src, serverFallback) {
328
+ const fallback = typeof location !== "undefined" ? location.href : serverFallback;
329
+ if (!src) {
330
+ return new URL(fallback);
331
+ }
332
+ return typeof src === "string" ? new URL(src, fallback) : src;
333
+ }
334
+
189
335
  // src/host/shared/polyfill.tsx
190
336
  import { jsx } from "react/jsx-runtime";
191
- function applyBundleUrlToSrc(bundle, src) {
192
- const self = globalThis;
193
- if (self.__remote_bundle_url__?.[bundle]?.origin === location.origin) {
194
- return src;
195
- }
196
- const { assetPrefix, path } = /^(?<assetPrefix>.*?)\/_next\/(?<path>.*)/.exec(src)?.groups ?? {};
197
- if (!path) {
198
- return new URL(src, self.__remote_bundle_url__?.[bundle]?.origin).href;
199
- }
200
- return `${self.__remote_bundle_url__?.[bundle]?.origin ?? ""}${assetPrefix}/_next/${path}`;
201
- }
202
- function applyBundleUrlToImagePropsSrc(bundle, src) {
203
- if (typeof src === "string") {
204
- return applyBundleUrlToSrc(bundle, src);
205
- }
206
- const propSrc = src;
207
- return applyBundleUrlToSrc(bundle, propSrc.src);
208
- }
209
- var imageImpl = (bundle, resolveClientUrl) => function RemoteImage({
210
- fill: _fill,
211
- loader: _loader,
212
- quality: _quality,
213
- priority: _priority,
214
- loading: _loading,
215
- placeholder: _placeholder,
216
- blurDataURL: _blurDataURL,
217
- unoptimized: _unoptimized,
218
- overrideSrc: _overrideSrc,
219
- src,
220
- ...props
221
- }) {
222
- const newSrc = applyBundleUrlToImagePropsSrc(
223
- bundle,
224
- typeof src === "string" ? src : src.src
225
- );
226
- const proxiedSrc = resolveClientUrl?.(newSrc) ?? newSrc;
227
- return (
228
- // eslint-disable-next-line @next/next/no-img-element, jsx-a11y/alt-text
229
- /* @__PURE__ */ jsx(
230
- "img",
231
- {
232
- decoding: "async",
233
- style: { color: "transparent" },
234
- ...props,
235
- src: proxiedSrc,
236
- suppressHydrationWarning: true
237
- }
238
- )
239
- );
240
- };
241
337
  function sharedPolyfills(shared2, resolveClientUrl) {
242
338
  const self = globalThis;
243
339
  const polyfill = {
@@ -328,17 +424,13 @@ function sharedPolyfills(shared2, resolveClientUrl) {
328
424
  },
329
425
  __esModule: true
330
426
  })),
331
- "next/dist/client/image-component": self.__remote_component_host_shared_modules__?.["next/image"] ?? shared2?.["next/image"] ?? ((bundle) => Promise.resolve({
332
- Image: imageImpl(bundle, resolveClientUrl),
333
- __esModule: true
334
- })),
335
- "next/image": self.__remote_component_host_shared_modules__?.["next/image"] ?? shared2?.["next/image"] ?? ((bundle) => Promise.resolve({
336
- default: imageImpl(bundle, resolveClientUrl),
337
- getImageProps: (_imgProps) => {
338
- throw new Error(
339
- "Next.js getImageProps() is not implemented in remote components"
340
- );
341
- },
427
+ // Instead of replacing next/image entirely, we let the real Next.js Image
428
+ // component load from the remote bundle and only replace its default loader.
429
+ // This gives us full next/image fidelity (fill, priority, srcSet, blur
430
+ // placeholders, error handling) while routing image optimization through the
431
+ // remote app's /_next/image endpoint.
432
+ "next/dist/shared/lib/image-loader": self.__remote_component_host_shared_modules__?.["next/dist/shared/lib/image-loader"] ?? shared2?.["next/dist/shared/lib/image-loader"] ?? ((bundle) => Promise.resolve({
433
+ default: createRemoteImageLoader(bundle, resolveClientUrl),
342
434
  __esModule: true
343
435
  })),
344
436
  "next/dist/client/script": self.__remote_component_host_shared_modules__?.["next/script"] ?? shared2?.["next/script"] ?? (() => Promise.resolve({
@@ -378,119 +470,11 @@ function sharedPolyfills(shared2, resolveClientUrl) {
378
470
  polyfill["next/navigation"] = polyfill["next/dist/client/components/navigation"];
379
471
  polyfill["next/link"] = polyfill["next/dist/client/app-dir/link"];
380
472
  polyfill["next/form"] = polyfill["next/dist/client/app-dir/form"];
381
- polyfill["next/dist/api/image"] = polyfill["next/dist/client/image-component"];
473
+ polyfill["next/dist/esm/shared/lib/image-loader"] = polyfill["next/dist/shared/lib/image-loader"];
382
474
  polyfill["next/script"] = polyfill["next/dist/client/script"];
383
475
  return polyfill;
384
476
  }
385
477
 
386
- // src/host/nextjs/image-impl.tsx
387
- import { jsx as jsx2 } from "react/jsx-runtime";
388
- var getBundleUrl = (bundle) => globalThis.__remote_bundle_url__?.[bundle];
389
- function createRemoteLoader(bundle, resolveClientUrl) {
390
- return ({ src, width, quality }) => {
391
- const bundleUrl = getBundleUrl(bundle);
392
- const origin = bundleUrl?.origin ?? "";
393
- let imageUrl = src;
394
- try {
395
- const parsed = new URL(src);
396
- if (origin && parsed.origin === origin) {
397
- imageUrl = parsed.pathname + parsed.search;
398
- }
399
- } catch {
400
- }
401
- const { assetPrefix } = /^(?<assetPrefix>.*?)\/_next\//.exec(imageUrl)?.groups ?? {};
402
- const url = `${origin}${assetPrefix ?? ""}/_next/image?url=${encodeURIComponent(imageUrl)}&w=${width}&q=${quality ?? 75}`;
403
- const remoteSrc = bundleUrl?.href ?? url;
404
- return resolveClientUrl?.(remoteSrc, url) ?? url;
405
- };
406
- }
407
- function imageImpl2(ImageComponent, bundle, resolveClientUrl, useRemoteLoader) {
408
- const remoteLoader = useRemoteLoader ? createRemoteLoader(bundle, resolveClientUrl) : void 0;
409
- const component = function RemoteImage(props) {
410
- if (remoteLoader) {
411
- return /* @__PURE__ */ jsx2(ImageComponent, { loader: remoteLoader, ...props });
412
- }
413
- const rawSrc = applyBundleUrlToImagePropsSrc(bundle, props.src);
414
- const bundleUrl = getBundleUrl(bundle);
415
- const remoteSrc = bundleUrl?.href ?? rawSrc;
416
- const src = resolveClientUrl?.(remoteSrc, rawSrc) ?? rawSrc;
417
- return /* @__PURE__ */ jsx2(ImageComponent, { ...props, src });
418
- };
419
- component.default = component;
420
- return component;
421
- }
422
-
423
- // src/host/nextjs/app-client-only.tsx
424
- import { RemoteComponentsContext } from "#internal/host/react/context";
425
-
426
- // src/host/react/index.tsx
427
- import {
428
- startTransition,
429
- useEffect,
430
- useId,
431
- useLayoutEffect as useLayoutEffect2,
432
- useMemo as useMemo2,
433
- useRef as useRef2,
434
- useState as useState2
435
- } from "react";
436
- import { createPortal } from "react-dom";
437
- import { useRemoteComponentsContext as useRemoteComponentsContext2 } from "#internal/host/react/context";
438
-
439
- // src/host/server/fetch-headers.ts
440
- function remoteFetchHeaders() {
441
- return {
442
- /**
443
- * Authenticates deployment protection for the remote. Needed for SSR and SSG clients.
444
- * If the remote component uses vercel deployment protection, ensure the host and remote vercel
445
- * projects share a common automation bypass secret, and the shared secret is used as the
446
- * VERCEL_AUTOMATION_BYPASS_SECRET env var in the host project.
447
- */
448
- ...typeof process === "object" && typeof process.env === "object" && typeof process.env.VERCEL_AUTOMATION_BYPASS_SECRET === "string" ? {
449
- "x-vercel-protection-bypass": process.env.VERCEL_AUTOMATION_BYPASS_SECRET
450
- } : {},
451
- Accept: "text/html"
452
- };
453
- }
454
-
455
- // src/host/server/fetch-with-hooks.ts
456
- async function fetchWithWarning(url, init) {
457
- try {
458
- return await fetch(url, init);
459
- } catch (error) {
460
- warnCrossOriginFetchError("FetchRemoteComponent", url);
461
- throw error;
462
- }
463
- }
464
- async function fetchWithHooks(url, additionalInit, options = {}) {
465
- const {
466
- onRequest,
467
- onResponse,
468
- abortController = new AbortController()
469
- } = options;
470
- const signal = abortController.signal;
471
- const hookOptions = {
472
- signal,
473
- abort: (reason) => abortController.abort(reason)
474
- };
475
- const init = {
476
- method: "GET",
477
- headers: remoteFetchHeaders(),
478
- signal,
479
- ...additionalInit
480
- };
481
- const res = await onRequest?.(url, init, hookOptions) ?? await fetchWithWarning(url, init);
482
- return await onResponse?.(url, res, hookOptions) ?? res;
483
- }
484
-
485
- // src/host/server/get-client-or-server-url.ts
486
- function getClientOrServerUrl(src, serverFallback) {
487
- const fallback = typeof location !== "undefined" ? location.href : serverFallback;
488
- if (!src) {
489
- return new URL(fallback);
490
- }
491
- return typeof src === "string" ? new URL(src, fallback) : src;
492
- }
493
-
494
478
  // src/host/shared/state.ts
495
479
  function createHostState() {
496
480
  return {
@@ -530,12 +514,12 @@ var attrToProp = {
530
514
  };
531
515
 
532
516
  // src/runtime/constants.ts
517
+ var DEFAULT_BUNDLE_NAME = "__vercel_remote_bundle";
518
+ var DEFAULT_COMPONENT_NAME = "__vercel_remote_component";
533
519
  var DEFAULT_ROUTE = "/";
534
520
  var RUNTIME_WEBPACK = "webpack";
535
521
  var RUNTIME_TURBOPACK = "turbopack";
536
522
  var RUNTIME_SCRIPT = "script";
537
- var REMOTE_COMPONENT_REGEX = /(?<prefix>.*?)\[(?<bundle>[^\]]+)\](?:%20| )(?<id>.+)/;
538
- var NEXT_BUNDLE_PATH_RE = /\/_next\/\[.+\](?:%20| )/;
539
523
  function getBundleKey(bundle) {
540
524
  return escapeString(bundle);
541
525
  }
@@ -602,6 +586,38 @@ function applyOriginToNodes(doc, url, resolveClientUrl) {
602
586
  }
603
587
  }
604
588
 
589
+ // src/runtime/metadata.ts
590
+ var VALID_RUNTIMES = /* @__PURE__ */ new Set(["webpack", "turbopack", "script"]);
591
+ var VALID_TYPES = /* @__PURE__ */ new Set([
592
+ "nextjs",
593
+ "remote-component",
594
+ "unknown"
595
+ ]);
596
+ function isRuntime(value) {
597
+ return VALID_RUNTIMES.has(value);
598
+ }
599
+ function isComponentType(value) {
600
+ return VALID_TYPES.has(value);
601
+ }
602
+ function toRuntime(value) {
603
+ return value && isRuntime(value) ? value : "webpack";
604
+ }
605
+ function toComponentType(value) {
606
+ return value && isComponentType(value) ? value : "unknown";
607
+ }
608
+ function buildMetadata(attrs, url) {
609
+ const id = attrs.id || DEFAULT_COMPONENT_NAME;
610
+ const bundle = attrs.bundle || process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION || DEFAULT_BUNDLE_NAME;
611
+ return {
612
+ name: attrs.name || id.replace(/_ssr$/, ""),
613
+ bundle,
614
+ route: attrs.route || url.pathname || DEFAULT_ROUTE,
615
+ runtime: toRuntime(attrs.runtime),
616
+ id,
617
+ type: toComponentType(attrs.type)
618
+ };
619
+ }
620
+
605
621
  // src/runtime/html/parse-remote-html.ts
606
622
  function validateSingleComponent(doc, name, url) {
607
623
  if (doc.querySelectorAll("div[data-bundle][data-route]").length > 1 && !doc.querySelector(`div[data-bundle][data-route][id^="${name}"]`) || doc.querySelectorAll("remote-component:not([src])").length > 1 && !doc.querySelector(`remote-component[name="${name}"]`)) {
@@ -621,14 +637,6 @@ function resolveComponentName(component, nextData, fallbackName) {
621
637
  const name = component?.getAttribute("id")?.replace(/_ssr$/, "") || isRemoteComponent && component?.getAttribute("name") || (nextData ? "__next" : fallbackName);
622
638
  return { name, isRemoteComponent };
623
639
  }
624
- function extractComponentMetadata(component, nextData, name, url) {
625
- return {
626
- name,
627
- bundle: component?.getAttribute("data-bundle") || nextData?.props.__REMOTE_COMPONENT__?.bundle || "default",
628
- route: component?.getAttribute("data-route") ?? nextData?.page ?? (url.pathname || DEFAULT_ROUTE),
629
- runtime: component?.getAttribute("data-runtime") ?? (nextData?.props.__REMOTE_COMPONENT__?.runtime || RUNTIME_SCRIPT)
630
- };
631
- }
632
640
  function extractRemoteShared(doc, name, nextData) {
633
641
  const remoteSharedEl = doc.querySelector(
634
642
  `#${name}_shared[data-remote-components-shared]`
@@ -640,7 +648,7 @@ function extractRemoteShared(doc, name, nextData) {
640
648
  function validateComponentFound(component, rsc, nextData, isRemoteComponent, url, name) {
641
649
  if (!component || !(rsc || nextData || isRemoteComponent)) {
642
650
  throw new RemoteComponentsError(
643
- `Remote Component not found on ${url}.${name !== "__vercel_remote_component" ? ` The name for the <RemoteComponent> is "${name}". Check <RemoteComponent> usage.` : ""} Did you forget to wrap the content in <RemoteComponent>?`
651
+ `Remote Component not found on ${url}.${name !== DEFAULT_COMPONENT_NAME ? ` The name for the <RemoteComponent> is "${name}". Check <RemoteComponent> usage.` : ""} Did you forget to wrap the content in <RemoteComponent>?`
644
652
  );
645
653
  }
646
654
  }
@@ -666,10 +674,15 @@ function parseRemoteComponentDocument(doc, name, url) {
666
674
  name
667
675
  );
668
676
  const rsc = doc.querySelector(`#${resolvedName}_rsc`);
669
- const metadata = extractComponentMetadata(
670
- component,
671
- nextData,
672
- resolvedName,
677
+ const metadata = buildMetadata(
678
+ {
679
+ name: resolvedName,
680
+ bundle: component?.getAttribute("data-bundle") || nextData?.props.__REMOTE_COMPONENT__?.bundle,
681
+ route: component?.getAttribute("data-route") ?? nextData?.page,
682
+ runtime: component?.getAttribute("data-runtime") ?? nextData?.props.__REMOTE_COMPONENT__?.runtime ?? RUNTIME_SCRIPT,
683
+ id: component?.getAttribute("id"),
684
+ type: component?.getAttribute("data-type")
685
+ },
673
686
  url
674
687
  );
675
688
  const remoteShared = extractRemoteShared(doc, resolvedName, nextData);
@@ -985,6 +998,14 @@ function createRSCStream(rscName, data) {
985
998
  });
986
999
  }
987
1000
 
1001
+ // src/runtime/patterns.ts
1002
+ var REMOTE_COMPONENT_REGEX = /(?<prefix>.*?)\[(?<bundle>[^\]]+)\](?:%20| )(?<id>.+)/;
1003
+ var NEXT_BUNDLE_PATH_RE = /\/_next\/\[.+\](?:%20| )/;
1004
+ var DOUBLE_SLASH_RE = /(?<!:)\/\//g;
1005
+ function collapseDoubleSlashes(path) {
1006
+ return path.replace(DOUBLE_SLASH_RE, "/");
1007
+ }
1008
+
988
1009
  // src/runtime/turbopack/patterns.ts
989
1010
  var REMOTE_SHARED_MARKER_RE = /(?:self|[a-z])\.TURBOPACK_REMOTE_SHARED/;
990
1011
  var REMOTE_SHARED_ASSIGNMENT_RE = /\.TURBOPACK_REMOTE_SHARED=await (?:__turbopack_context__|[a-z])\.A\((?<sharedModuleId>[0-9]+)\)/;
@@ -1574,7 +1595,7 @@ async function setupWebpackRuntime(runtime, scripts = [], url = new URL(location
1574
1595
  }
1575
1596
  }
1576
1597
  if (runtime === RUNTIME_TURBOPACK) {
1577
- await Promise.all(
1598
+ const results = await Promise.allSettled(
1578
1599
  scripts.map((script) => {
1579
1600
  if (script.src) {
1580
1601
  return self.__webpack_chunk_load__?.(script.src, bundle);
@@ -1582,6 +1603,14 @@ async function setupWebpackRuntime(runtime, scripts = [], url = new URL(location
1582
1603
  return Promise.resolve(void 0);
1583
1604
  })
1584
1605
  );
1606
+ for (const result of results) {
1607
+ if (result.status === "rejected") {
1608
+ logWarn(
1609
+ "WebpackRuntime",
1610
+ `Initial chunk load failed: ${String(result.reason)}`
1611
+ );
1612
+ }
1613
+ }
1585
1614
  }
1586
1615
  const coreShared = {
1587
1616
  react: async () => (await import("react")).default,
@@ -1969,40 +1998,10 @@ async function loadStaticRemoteComponent(scripts, url, resolveClientUrl) {
1969
1998
  // src/host/react/hooks/use-resolve-client-url.ts
1970
1999
  import { useMemo } from "react";
1971
2000
  import { useRemoteComponentsContext } from "#internal/host/react/context";
1972
-
1973
- // src/runtime/url/resolve-client-url.ts
1974
- function withRemoteSrc(resolveClientUrl, remoteSrc) {
1975
- const remoteOrigin = parseOrigin(remoteSrc);
1976
- return (url) => {
1977
- const urlOrigin = parseOrigin(url);
1978
- if (remoteOrigin && urlOrigin && urlOrigin !== remoteOrigin) {
1979
- return void 0;
1980
- }
1981
- return resolveClientUrl(remoteSrc, url);
1982
- };
1983
- }
1984
- function parseOrigin(url) {
1985
- try {
1986
- return new URL(url).origin;
1987
- } catch {
1988
- return void 0;
1989
- }
1990
- }
1991
-
1992
- // src/runtime/url/default-resolve-client-url.ts
1993
- function bindResolveClientUrl(prop, remoteSrc) {
1994
- return prop ? withRemoteSrc(prop, remoteSrc) : void 0;
1995
- }
1996
-
1997
- // src/host/react/hooks/use-resolve-client-url.ts
1998
2001
  function useResolveClientUrl(prop, urlHref) {
1999
2002
  const { resolveClientUrl: contextValue } = useRemoteComponentsContext();
2000
2003
  const raw = prop ?? contextValue;
2001
- const bound = useMemo(
2002
- () => bindResolveClientUrl(raw, urlHref),
2003
- [raw, urlHref]
2004
- );
2005
- return { bound, raw };
2004
+ return useMemo(() => bindResolveClientUrl(raw, urlHref), [raw, urlHref]);
2006
2005
  }
2007
2006
 
2008
2007
  // src/host/react/hooks/use-shadow-root.ts
@@ -2068,7 +2067,7 @@ function getRemoteComponentHtml(html) {
2068
2067
  return ssrRemoteComponentContainer.innerHTML;
2069
2068
  }
2070
2069
  const remoteComponentContainer = temp.querySelectorAll(
2071
- `div[data-bundle][data-route][data-runtime][id^="__vercel_remote_component"],div[data-bundle][data-route],div#__next,remote-component:not([src])`
2070
+ `div[data-bundle][data-route][data-runtime][id^="${DEFAULT_COMPONENT_NAME}"],div[data-bundle][data-route],div#__next,remote-component:not([src])`
2072
2071
  );
2073
2072
  if (remoteComponentContainer.length > 0) {
2074
2073
  return `${Array.from(temp.querySelectorAll("link,script")).map((link) => link.outerHTML).join("")}${Array.from(remoteComponentContainer).map((container) => container.outerHTML).join("")}`;
@@ -2077,7 +2076,7 @@ function getRemoteComponentHtml(html) {
2077
2076
  }
2078
2077
 
2079
2078
  // src/host/react/index.tsx
2080
- import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
2079
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
2081
2080
  import { createElement as createElement2 } from "react";
2082
2081
  function ConsumeRemoteComponent({
2083
2082
  src,
@@ -2085,7 +2084,7 @@ function ConsumeRemoteComponent({
2085
2084
  mode = "open",
2086
2085
  reset,
2087
2086
  credentials: credentialsProp,
2088
- name: nameProp = "__vercel_remote_component",
2087
+ name: nameProp = DEFAULT_COMPONENT_NAME,
2089
2088
  shared: sharedProp,
2090
2089
  children,
2091
2090
  onBeforeLoad,
@@ -2108,10 +2107,7 @@ function ConsumeRemoteComponent({
2108
2107
  null
2109
2108
  );
2110
2109
  const url = useMemo2(() => getClientOrServerUrl(src, DUMMY_FALLBACK), [src]);
2111
- const { bound: resolveClientUrl } = useResolveClientUrl(
2112
- resolveClientUrlProp,
2113
- url.href
2114
- );
2110
+ const resolveClientUrl = useResolveClientUrl(resolveClientUrlProp, url.href);
2115
2111
  const id = url.origin === (typeof location !== "undefined" ? location.origin : DUMMY_FALLBACK) ? url.pathname : url.href;
2116
2112
  const keySuffix = `${escapeString(id)}_${escapeString(
2117
2113
  data?.name ?? name
@@ -2385,7 +2381,7 @@ function ConsumeRemoteComponent({
2385
2381
  } else if (isolate === false) {
2386
2382
  setRemoteComponent(
2387
2383
  // TODO: remove wrapper div by converting HTML to RSC or React tree
2388
- /* @__PURE__ */ jsx3(
2384
+ /* @__PURE__ */ jsx2(
2389
2385
  "div",
2390
2386
  {
2391
2387
  dangerouslySetInnerHTML: { __html: component.innerHTML },
@@ -2428,10 +2424,7 @@ function ConsumeRemoteComponent({
2428
2424
  };
2429
2425
  return {
2430
2426
  src: new URL(
2431
- `${prefix ?? ""}${path}`.replace(
2432
- /(?<char>[^:])(?<double>\/\/)/g,
2433
- "$1/"
2434
- ),
2427
+ collapseDoubleSlashes(`${prefix ?? ""}${path}`),
2435
2428
  url
2436
2429
  ).href
2437
2430
  };
@@ -2498,13 +2491,13 @@ function ConsumeRemoteComponent({
2498
2491
  if (remoteComponent instanceof Error) {
2499
2492
  throw remoteComponent;
2500
2493
  }
2501
- const metadataJson = /* @__PURE__ */ jsx3("script", { "data-remote-component": true, type: "application/json", children: JSON.stringify({
2494
+ const metadataJson = /* @__PURE__ */ jsx2("script", { "data-remote-component": true, type: "application/json", children: JSON.stringify({
2502
2495
  name: data?.name || name,
2503
2496
  bundle: data?.bundle || "default",
2504
2497
  route: data?.route || DEFAULT_ROUTE,
2505
2498
  runtime: hostStateRef.current.prevIsRemoteComponent ? RUNTIME_SCRIPT : data?.runtime || RUNTIME_WEBPACK
2506
2499
  }) });
2507
- const resetStyle = reset ? /* @__PURE__ */ jsx3("style", { "data-remote-components-reset": "react", children: `:host { all: initial; }` }) : null;
2500
+ const resetStyle = reset ? /* @__PURE__ */ jsx2("style", { "data-remote-components-reset": "react", children: `:host { all: initial; }` }) : null;
2508
2501
  const linksToRender = data?.links?.map((link) => /* @__PURE__ */ createElement2(
2509
2502
  "link",
2510
2503
  {
@@ -2563,7 +2556,7 @@ function ConsumeRemoteComponent({
2563
2556
  typeof document === "undefined" ? (
2564
2557
  // eslint-disable-next-line react/no-unknown-property
2565
2558
  /* @__PURE__ */ jsxs("template", { shadowrootmode: mode, children: [
2566
- typeof document === "undefined" ? /* @__PURE__ */ jsx3(
2559
+ typeof document === "undefined" ? /* @__PURE__ */ jsx2(
2567
2560
  "div",
2568
2561
  {
2569
2562
  dangerouslySetInnerHTML: {
@@ -2586,11 +2579,11 @@ function ConsumeRemoteComponent({
2586
2579
  ) : null,
2587
2580
  shadowRoot && remoteComponent ? createPortal(
2588
2581
  /* @__PURE__ */ jsxs(Fragment, { children: [
2589
- /* @__PURE__ */ jsx3("template", { id: `${name}_start` }),
2582
+ /* @__PURE__ */ jsx2("template", { id: `${name}_start` }),
2590
2583
  resetStyle,
2591
2584
  linksToRender,
2592
2585
  remoteComponent,
2593
- /* @__PURE__ */ jsx3("template", { id: `${name}_end`, ref: endTemplateRef })
2586
+ /* @__PURE__ */ jsx2("template", { id: `${name}_end`, ref: endTemplateRef })
2594
2587
  ] }),
2595
2588
  shadowRoot
2596
2589
  ) : null
@@ -2601,10 +2594,10 @@ function ConsumeRemoteComponent({
2601
2594
  }
2602
2595
  htmlRef.current = null;
2603
2596
  return /* @__PURE__ */ jsxs(Fragment, { children: [
2604
- /* @__PURE__ */ jsx3("template", { id: `${name}_start` }),
2597
+ /* @__PURE__ */ jsx2("template", { id: `${name}_start` }),
2605
2598
  metadataJson,
2606
2599
  componentToRender,
2607
- /* @__PURE__ */ jsx3("template", { id: `${name}_end`, ref: endTemplateRef })
2600
+ /* @__PURE__ */ jsx2("template", { id: `${name}_end`, ref: endTemplateRef })
2608
2601
  ] });
2609
2602
  }
2610
2603
 
@@ -2673,25 +2666,8 @@ var routerImpl = async () => {
2673
2666
  });
2674
2667
  };
2675
2668
 
2676
- // src/host/nextjs/image-shared.ts
2677
- function createNextImageSharedEntries(getWrappedImage, options) {
2678
- const entries = {
2679
- "next/image": (bundle) => Promise.resolve(getWrappedImage(bundle)),
2680
- "next/dist/client/image-component": (bundle) => Promise.resolve({
2681
- Image: getWrappedImage(bundle)
2682
- })
2683
- };
2684
- if (options?.getImageProps) {
2685
- entries["next/dist/api/image"] = (bundle) => Promise.resolve({
2686
- default: getWrappedImage(bundle),
2687
- getImageProps: options.getImageProps
2688
- });
2689
- }
2690
- return entries;
2691
- }
2692
-
2693
2669
  // src/host/nextjs/app-client-only.tsx
2694
- import { jsx as jsx4 } from "react/jsx-runtime";
2670
+ import { jsx as jsx3 } from "react/jsx-runtime";
2695
2671
  async function tryImportShared() {
2696
2672
  try {
2697
2673
  const { shared: shared2 } = await Promise.resolve().then(() => (init_app(), app_exports));
@@ -2708,9 +2684,7 @@ var sharedModules = async (userShared, resolveClientUrl) => {
2708
2684
  return {
2709
2685
  ...resolvedShared,
2710
2686
  "next/router": routerImpl,
2711
- ...createNextImageSharedEntries(
2712
- (bundle) => imageImpl2(Image.default, bundle ?? "default", resolveClientUrl)
2713
- ),
2687
+ ...createImageLoaderSharedEntries({ unbound: resolveClientUrl }),
2714
2688
  ...resolvedUserShared
2715
2689
  };
2716
2690
  };
@@ -2724,7 +2698,7 @@ function RemoteComponentsClientProvider({
2724
2698
  () => sharedModules(shared2, resolveClientUrl),
2725
2699
  [shared2, resolveClientUrl]
2726
2700
  );
2727
- return /* @__PURE__ */ jsx4(
2701
+ return /* @__PURE__ */ jsx3(
2728
2702
  RemoteComponentsContext,
2729
2703
  {
2730
2704
  value: { shared: mergedShared, resolveClientUrl, ...props },
@@ -2736,7 +2710,7 @@ function ConsumeRemoteComponent2(props) {
2736
2710
  if (typeof props.src !== "string" && !(props.src instanceof URL)) {
2737
2711
  return props.children ?? null;
2738
2712
  }
2739
- return /* @__PURE__ */ jsx4(
2713
+ return /* @__PURE__ */ jsx3(
2740
2714
  ConsumeRemoteComponent,
2741
2715
  {
2742
2716
  ...props,