remote-components 0.2.1 → 0.3.0

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 (65) 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 +40 -59
  7. package/dist/host/html.cjs.map +1 -1
  8. package/dist/host/html.js +40 -62
  9. package/dist/host/html.js.map +1 -1
  10. package/dist/host/nextjs/app/client-only.cjs +199 -231
  11. package/dist/host/nextjs/app/client-only.cjs.map +1 -1
  12. package/dist/host/nextjs/app/client-only.d.ts +28 -9
  13. package/dist/host/nextjs/app/client-only.js +198 -231
  14. package/dist/host/nextjs/app/client-only.js.map +1 -1
  15. package/dist/host/nextjs/pages.cjs +5 -12
  16. package/dist/host/nextjs/pages.cjs.map +1 -1
  17. package/dist/host/nextjs/pages.js +6 -13
  18. package/dist/host/nextjs/pages.js.map +1 -1
  19. package/dist/host/react.cjs +45 -71
  20. package/dist/host/react.cjs.map +1 -1
  21. package/dist/host/react.d.ts +2 -366
  22. package/dist/host/react.js +45 -71
  23. package/dist/host/react.js.map +1 -1
  24. package/dist/index-4c65355c.d.ts +298 -0
  25. package/dist/internal/config/webpack/next-client-pages-loader.d.ts +3 -3
  26. package/dist/internal/host/nextjs/app-client.cjs +1 -5
  27. package/dist/internal/host/nextjs/app-client.cjs.map +1 -1
  28. package/dist/internal/host/nextjs/app-client.d.ts +1 -1
  29. package/dist/internal/host/nextjs/app-client.js +2 -6
  30. package/dist/internal/host/nextjs/app-client.js.map +1 -1
  31. package/dist/internal/host/nextjs/image-shared.cjs +25 -15
  32. package/dist/internal/host/nextjs/image-shared.cjs.map +1 -1
  33. package/dist/internal/host/nextjs/image-shared.d.ts +19 -6
  34. package/dist/internal/host/nextjs/image-shared.js +24 -14
  35. package/dist/internal/host/nextjs/image-shared.js.map +1 -1
  36. package/dist/internal/host/react/context.cjs +5 -10
  37. package/dist/internal/host/react/context.cjs.map +1 -1
  38. package/dist/internal/host/react/context.d.ts +7 -18
  39. package/dist/internal/host/react/context.js +4 -9
  40. package/dist/internal/host/react/context.js.map +1 -1
  41. package/dist/internal/host/react/hooks/use-resolve-client-url.cjs +2 -5
  42. package/dist/internal/host/react/hooks/use-resolve-client-url.cjs.map +1 -1
  43. package/dist/internal/host/react/hooks/use-resolve-client-url.js +2 -5
  44. package/dist/internal/host/react/hooks/use-resolve-client-url.js.map +1 -1
  45. package/dist/internal/host/shared/config.cjs.map +1 -1
  46. package/dist/internal/host/shared/config.d.ts +7 -0
  47. package/dist/internal/host/shared/polyfill.cjs +10 -65
  48. package/dist/internal/host/shared/polyfill.cjs.map +1 -1
  49. package/dist/internal/host/shared/polyfill.d.ts +1 -3
  50. package/dist/internal/host/shared/polyfill.js +9 -63
  51. package/dist/internal/host/shared/polyfill.js.map +1 -1
  52. package/dist/internal/host/shared/remote-image-loader.cjs +53 -0
  53. package/dist/internal/host/shared/remote-image-loader.cjs.map +1 -0
  54. package/dist/internal/host/shared/remote-image-loader.d.ts +30 -0
  55. package/dist/internal/host/shared/remote-image-loader.js +29 -0
  56. package/dist/internal/host/shared/remote-image-loader.js.map +1 -0
  57. package/dist/internal/host/shared/resolved-data.d.ts +2 -2
  58. package/dist/internal/runtime/loaders/component-loader.d.ts +1 -1
  59. package/dist/{server-handoff-8c89b856.d.ts → server-handoff-ce13bebc.d.ts} +2 -2
  60. package/package.json +1 -9
  61. package/dist/internal/host/nextjs/image-impl.cjs +0 -60
  62. package/dist/internal/host/nextjs/image-impl.cjs.map +0 -1
  63. package/dist/internal/host/nextjs/image-impl.d.ts +0 -10
  64. package/dist/internal/host/nextjs/image-impl.js +0 -36
  65. package/dist/internal/host/nextjs/image-impl.js.map +0 -1
@@ -1,16 +1,35 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as react from 'react';
3
- import { ConsumeRemoteComponentProps } from '../../react.js';
2
+ import React from 'react';
3
+ import { C as ConsumeClientOnlyConfig, a as ConsumeRemoteComponentProps } from '../../../index-4c65355c.js';
4
4
 
5
5
  /**
6
- * RemoteComponent - Client-side component for rendering remote components
6
+ * Provider for Next.js App Router hosts. Provides real Next.js implementations
7
+ * of `next/image`, `next/navigation`, `next/link`, etc. to all nested
8
+ * `<ConsumeRemoteComponent>` instances.
7
9
  *
8
- * This component is used in Next.js App Router to render remote components.
9
- * It supports both Next.js App Router and Pages Router based components.
10
+ * Works in both Server and Client Components set it up once in your layout
11
+ * and use `<ConsumeRemoteComponent>` from `remote-components/react` everywhere:
10
12
  *
11
- * @param props - The props for the remote component.
12
- * @returns The rendered remote component.
13
+ * ```tsx
14
+ * import { RemoteComponentsClientProvider } from 'remote-components/host/nextjs/app/client-only';
15
+ *
16
+ * <RemoteComponentsClientProvider resolveClientUrl={proxyClientRequestsThroughHost}>
17
+ * {children}
18
+ * </RemoteComponentsClientProvider>
19
+ * ```
20
+ */
21
+ declare function RemoteComponentsClientProvider({ shared, resolveClientUrl, children, ...props }: ConsumeClientOnlyConfig & {
22
+ children: React.ReactNode;
23
+ }): react_jsx_runtime.JSX.Element;
24
+ /**
25
+ * `ConsumeRemoteComponent` for Next.js App Router hosts. Provides real Next.js
26
+ * implementations of `next/image`, `next/navigation`, `next/link`, etc.
27
+ *
28
+ * The provider approach is recommended because it works in both Server and Client
29
+ * Components — set up `RemoteComponentsClientProvider` from this module once in
30
+ * your layout, and use `<ConsumeRemoteComponent>` from `remote-components/react`
31
+ * everywhere. Import this component only when adding a provider is not practical.
13
32
  */
14
- declare function ConsumeRemoteComponent(props: ConsumeRemoteComponentProps): string | number | bigint | boolean | Iterable<react.ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<react.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null;
33
+ declare function ConsumeRemoteComponent(props: ConsumeRemoteComponentProps): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null;
15
34
 
16
- export { ConsumeRemoteComponent };
35
+ export { ConsumeRemoteComponent, RemoteComponentsClientProvider };
@@ -37,7 +37,99 @@ var init_app = __esm({
37
37
  });
38
38
 
39
39
  // src/host/nextjs/app-client-only.tsx
40
- import * as Image from "next/image";
40
+ import { useMemo as useMemo3 } from "react";
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";
41
133
 
42
134
  // src/utils/logger.ts
43
135
  init_constants();
@@ -185,58 +277,63 @@ function warnCrossOriginFetchError(logLocation, url) {
185
277
  }
186
278
  }
187
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
+
188
335
  // src/host/shared/polyfill.tsx
189
336
  import { jsx } from "react/jsx-runtime";
190
- function applyBundleUrlToSrc(bundle, src) {
191
- const self = globalThis;
192
- if (self.__remote_bundle_url__?.[bundle]?.origin === location.origin) {
193
- return src;
194
- }
195
- const { assetPrefix, path } = /^(?<assetPrefix>.*?)\/_next\/(?<path>.*)/.exec(src)?.groups ?? {};
196
- if (!path) {
197
- return new URL(src, self.__remote_bundle_url__?.[bundle]?.origin).href;
198
- }
199
- return `${self.__remote_bundle_url__?.[bundle]?.origin ?? ""}${assetPrefix}/_next/${path}`;
200
- }
201
- function applyBundleUrlToImagePropsSrc(bundle, src) {
202
- if (typeof src === "string") {
203
- return applyBundleUrlToSrc(bundle, src);
204
- }
205
- const propSrc = src;
206
- return applyBundleUrlToSrc(bundle, propSrc.src);
207
- }
208
- var imageImpl = (bundle, resolveClientUrl) => function RemoteImage({
209
- fill: _fill,
210
- loader: _loader,
211
- quality: _quality,
212
- priority: _priority,
213
- loading: _loading,
214
- placeholder: _placeholder,
215
- blurDataURL: _blurDataURL,
216
- unoptimized: _unoptimized,
217
- overrideSrc: _overrideSrc,
218
- src,
219
- ...props
220
- }) {
221
- const newSrc = applyBundleUrlToImagePropsSrc(
222
- bundle,
223
- typeof src === "string" ? src : src.src
224
- );
225
- const proxiedSrc = resolveClientUrl?.(newSrc) ?? newSrc;
226
- return (
227
- // eslint-disable-next-line @next/next/no-img-element, jsx-a11y/alt-text
228
- /* @__PURE__ */ jsx(
229
- "img",
230
- {
231
- decoding: "async",
232
- style: { color: "transparent" },
233
- ...props,
234
- src: proxiedSrc,
235
- suppressHydrationWarning: true
236
- }
237
- )
238
- );
239
- };
240
337
  function sharedPolyfills(shared2, resolveClientUrl) {
241
338
  const self = globalThis;
242
339
  const polyfill = {
@@ -327,17 +424,13 @@ function sharedPolyfills(shared2, resolveClientUrl) {
327
424
  },
328
425
  __esModule: true
329
426
  })),
330
- "next/dist/client/image-component": self.__remote_component_host_shared_modules__?.["next/image"] ?? shared2?.["next/image"] ?? ((bundle) => Promise.resolve({
331
- Image: imageImpl(bundle, resolveClientUrl),
332
- __esModule: true
333
- })),
334
- "next/image": self.__remote_component_host_shared_modules__?.["next/image"] ?? shared2?.["next/image"] ?? ((bundle) => Promise.resolve({
335
- default: imageImpl(bundle, resolveClientUrl),
336
- getImageProps: (_imgProps) => {
337
- throw new Error(
338
- "Next.js getImageProps() is not implemented in remote components"
339
- );
340
- },
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),
341
434
  __esModule: true
342
435
  })),
343
436
  "next/dist/client/script": self.__remote_component_host_shared_modules__?.["next/script"] ?? shared2?.["next/script"] ?? (() => Promise.resolve({
@@ -377,135 +470,11 @@ function sharedPolyfills(shared2, resolveClientUrl) {
377
470
  polyfill["next/navigation"] = polyfill["next/dist/client/components/navigation"];
378
471
  polyfill["next/link"] = polyfill["next/dist/client/app-dir/link"];
379
472
  polyfill["next/form"] = polyfill["next/dist/client/app-dir/form"];
380
- 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"];
381
474
  polyfill["next/script"] = polyfill["next/dist/client/script"];
382
475
  return polyfill;
383
476
  }
384
477
 
385
- // src/host/nextjs/image-impl.tsx
386
- import { jsx as jsx2 } from "react/jsx-runtime";
387
- function createRemoteLoader(bundle, resolveClientUrl) {
388
- return ({ src, width, quality }) => {
389
- const self = globalThis;
390
- const origin = self.__remote_bundle_url__?.[bundle]?.origin ?? "";
391
- let imageUrl = src;
392
- try {
393
- const parsed = new URL(src);
394
- if (origin && parsed.origin === origin) {
395
- imageUrl = parsed.pathname + parsed.search;
396
- }
397
- } catch {
398
- }
399
- const { assetPrefix } = /^(?<assetPrefix>.*?)\/_next\//.exec(imageUrl)?.groups ?? {};
400
- const url = `${origin}${assetPrefix ?? ""}/_next/image?url=${encodeURIComponent(imageUrl)}&w=${width}&q=${quality ?? 75}`;
401
- return resolveClientUrl?.(url) ?? url;
402
- };
403
- }
404
- function imageImpl2(ImageComponent, bundle, resolveClientUrl, useRemoteLoader) {
405
- const remoteLoader = useRemoteLoader ? createRemoteLoader(bundle, resolveClientUrl) : void 0;
406
- const component = function RemoteImage(props) {
407
- if (remoteLoader) {
408
- return /* @__PURE__ */ jsx2(ImageComponent, { loader: remoteLoader, ...props });
409
- }
410
- const rawSrc = applyBundleUrlToImagePropsSrc(bundle, props.src);
411
- const src = resolveClientUrl?.(rawSrc) ?? rawSrc;
412
- return /* @__PURE__ */ jsx2(ImageComponent, { ...props, src });
413
- };
414
- component.default = component;
415
- return component;
416
- }
417
-
418
- // src/runtime/url/resolve-client-url.ts
419
- function withRemoteSrc(resolveClientUrl, remoteSrc) {
420
- const remoteOrigin = parseOrigin(remoteSrc);
421
- return (url) => {
422
- const urlOrigin = parseOrigin(url);
423
- if (remoteOrigin && urlOrigin && urlOrigin !== remoteOrigin) {
424
- return void 0;
425
- }
426
- return resolveClientUrl(remoteSrc, url);
427
- };
428
- }
429
- function parseOrigin(url) {
430
- try {
431
- return new URL(url).origin;
432
- } catch {
433
- return void 0;
434
- }
435
- }
436
-
437
- // src/runtime/url/default-resolve-client-url.ts
438
- function bindResolveClientUrl(prop, remoteSrc) {
439
- return prop ? withRemoteSrc(prop, remoteSrc) : void 0;
440
- }
441
-
442
- // src/host/react/index.tsx
443
- import {
444
- startTransition,
445
- useEffect,
446
- useId,
447
- useLayoutEffect as useLayoutEffect2,
448
- useMemo as useMemo2,
449
- useRef as useRef2,
450
- useState as useState2
451
- } from "react";
452
- import { createPortal } from "react-dom";
453
-
454
- // src/host/server/fetch-headers.ts
455
- function remoteFetchHeaders() {
456
- return {
457
- /**
458
- * Authenticates deployment protection for the remote. Needed for SSR and SSG clients.
459
- * If the remote component uses vercel deployment protection, ensure the host and remote vercel
460
- * projects share a common automation bypass secret, and the shared secret is used as the
461
- * VERCEL_AUTOMATION_BYPASS_SECRET env var in the host project.
462
- */
463
- ...typeof process === "object" && typeof process.env === "object" && typeof process.env.VERCEL_AUTOMATION_BYPASS_SECRET === "string" ? {
464
- "x-vercel-protection-bypass": process.env.VERCEL_AUTOMATION_BYPASS_SECRET
465
- } : {},
466
- Accept: "text/html"
467
- };
468
- }
469
-
470
- // src/host/server/fetch-with-hooks.ts
471
- async function fetchWithWarning(url, init) {
472
- try {
473
- return await fetch(url, init);
474
- } catch (error) {
475
- warnCrossOriginFetchError("FetchRemoteComponent", url);
476
- throw error;
477
- }
478
- }
479
- async function fetchWithHooks(url, additionalInit, options = {}) {
480
- const {
481
- onRequest,
482
- onResponse,
483
- abortController = new AbortController()
484
- } = options;
485
- const signal = abortController.signal;
486
- const hookOptions = {
487
- signal,
488
- abort: (reason) => abortController.abort(reason)
489
- };
490
- const init = {
491
- method: "GET",
492
- headers: remoteFetchHeaders(),
493
- signal,
494
- ...additionalInit
495
- };
496
- const res = await onRequest?.(url, init, hookOptions) ?? await fetchWithWarning(url, init);
497
- return await onResponse?.(url, res, hookOptions) ?? res;
498
- }
499
-
500
- // src/host/server/get-client-or-server-url.ts
501
- function getClientOrServerUrl(src, serverFallback) {
502
- const fallback = typeof location !== "undefined" ? location.href : serverFallback;
503
- if (!src) {
504
- return new URL(fallback);
505
- }
506
- return typeof src === "string" ? new URL(src, fallback) : src;
507
- }
508
-
509
478
  // src/host/shared/state.ts
510
479
  function createHostState() {
511
480
  return {
@@ -1986,11 +1955,8 @@ import { useMemo } from "react";
1986
1955
  import { useRemoteComponentsContext } from "#internal/host/react/context";
1987
1956
  function useResolveClientUrl(prop, urlHref) {
1988
1957
  const { resolveClientUrl: contextValue } = useRemoteComponentsContext();
1989
- const resolveClientUrl = prop ?? contextValue;
1990
- return useMemo(
1991
- () => bindResolveClientUrl(resolveClientUrl, urlHref),
1992
- [resolveClientUrl, urlHref]
1993
- );
1958
+ const raw = prop ?? contextValue;
1959
+ return useMemo(() => bindResolveClientUrl(raw, urlHref), [raw, urlHref]);
1994
1960
  }
1995
1961
 
1996
1962
  // src/host/react/hooks/use-shadow-root.ts
@@ -2065,16 +2031,16 @@ function getRemoteComponentHtml(html) {
2065
2031
  }
2066
2032
 
2067
2033
  // src/host/react/index.tsx
2068
- import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
2034
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
2069
2035
  import { createElement as createElement2 } from "react";
2070
2036
  function ConsumeRemoteComponent({
2071
2037
  src,
2072
2038
  isolate,
2073
2039
  mode = "open",
2074
2040
  reset,
2075
- credentials = "same-origin",
2041
+ credentials: credentialsProp,
2076
2042
  name: nameProp = "__vercel_remote_component",
2077
- shared: shared2 = {},
2043
+ shared: sharedProp,
2078
2044
  children,
2079
2045
  onBeforeLoad,
2080
2046
  onLoad,
@@ -2082,9 +2048,12 @@ function ConsumeRemoteComponent({
2082
2048
  onChange,
2083
2049
  onRequest,
2084
2050
  onResponse,
2085
- resolveClientUrl: _resolveClientUrl
2051
+ resolveClientUrl: resolveClientUrlProp
2086
2052
  }) {
2087
2053
  const instanceId = useId();
2054
+ const { credentials: contextCredentials, shared: contextShared } = useRemoteComponentsContext2();
2055
+ const credentials = credentialsProp ?? contextCredentials ?? "same-origin";
2056
+ const shared2 = sharedProp ?? contextShared ?? {};
2088
2057
  const name = useMemo2(
2089
2058
  () => resolveNameFromSrc(src, nameProp),
2090
2059
  [src, nameProp]
@@ -2093,7 +2062,7 @@ function ConsumeRemoteComponent({
2093
2062
  null
2094
2063
  );
2095
2064
  const url = useMemo2(() => getClientOrServerUrl(src, DUMMY_FALLBACK), [src]);
2096
- const resolveClientUrl = useResolveClientUrl(_resolveClientUrl, url.href);
2065
+ const resolveClientUrl = useResolveClientUrl(resolveClientUrlProp, url.href);
2097
2066
  const id = url.origin === (typeof location !== "undefined" ? location.origin : DUMMY_FALLBACK) ? url.pathname : url.href;
2098
2067
  const keySuffix = `${escapeString(id)}_${escapeString(
2099
2068
  data?.name ?? name
@@ -2367,7 +2336,7 @@ function ConsumeRemoteComponent({
2367
2336
  } else if (isolate === false) {
2368
2337
  setRemoteComponent(
2369
2338
  // TODO: remove wrapper div by converting HTML to RSC or React tree
2370
- /* @__PURE__ */ jsx3(
2339
+ /* @__PURE__ */ jsx2(
2371
2340
  "div",
2372
2341
  {
2373
2342
  dangerouslySetInnerHTML: { __html: component.innerHTML },
@@ -2480,13 +2449,13 @@ function ConsumeRemoteComponent({
2480
2449
  if (remoteComponent instanceof Error) {
2481
2450
  throw remoteComponent;
2482
2451
  }
2483
- const metadataJson = /* @__PURE__ */ jsx3("script", { "data-remote-component": true, type: "application/json", children: JSON.stringify({
2452
+ const metadataJson = /* @__PURE__ */ jsx2("script", { "data-remote-component": true, type: "application/json", children: JSON.stringify({
2484
2453
  name: data?.name || name,
2485
2454
  bundle: data?.bundle || "default",
2486
2455
  route: data?.route || DEFAULT_ROUTE,
2487
2456
  runtime: hostStateRef.current.prevIsRemoteComponent ? RUNTIME_SCRIPT : data?.runtime || RUNTIME_WEBPACK
2488
2457
  }) });
2489
- const resetStyle = reset ? /* @__PURE__ */ jsx3("style", { "data-remote-components-reset": "react", children: `:host { all: initial; }` }) : null;
2458
+ const resetStyle = reset ? /* @__PURE__ */ jsx2("style", { "data-remote-components-reset": "react", children: `:host { all: initial; }` }) : null;
2490
2459
  const linksToRender = data?.links?.map((link) => /* @__PURE__ */ createElement2(
2491
2460
  "link",
2492
2461
  {
@@ -2545,7 +2514,7 @@ function ConsumeRemoteComponent({
2545
2514
  typeof document === "undefined" ? (
2546
2515
  // eslint-disable-next-line react/no-unknown-property
2547
2516
  /* @__PURE__ */ jsxs("template", { shadowrootmode: mode, children: [
2548
- typeof document === "undefined" ? /* @__PURE__ */ jsx3(
2517
+ typeof document === "undefined" ? /* @__PURE__ */ jsx2(
2549
2518
  "div",
2550
2519
  {
2551
2520
  dangerouslySetInnerHTML: {
@@ -2568,11 +2537,11 @@ function ConsumeRemoteComponent({
2568
2537
  ) : null,
2569
2538
  shadowRoot && remoteComponent ? createPortal(
2570
2539
  /* @__PURE__ */ jsxs(Fragment, { children: [
2571
- /* @__PURE__ */ jsx3("template", { id: `${name}_start` }),
2540
+ /* @__PURE__ */ jsx2("template", { id: `${name}_start` }),
2572
2541
  resetStyle,
2573
2542
  linksToRender,
2574
2543
  remoteComponent,
2575
- /* @__PURE__ */ jsx3("template", { id: `${name}_end`, ref: endTemplateRef })
2544
+ /* @__PURE__ */ jsx2("template", { id: `${name}_end`, ref: endTemplateRef })
2576
2545
  ] }),
2577
2546
  shadowRoot
2578
2547
  ) : null
@@ -2583,10 +2552,10 @@ function ConsumeRemoteComponent({
2583
2552
  }
2584
2553
  htmlRef.current = null;
2585
2554
  return /* @__PURE__ */ jsxs(Fragment, { children: [
2586
- /* @__PURE__ */ jsx3("template", { id: `${name}_start` }),
2555
+ /* @__PURE__ */ jsx2("template", { id: `${name}_start` }),
2587
2556
  metadataJson,
2588
2557
  componentToRender,
2589
- /* @__PURE__ */ jsx3("template", { id: `${name}_end`, ref: endTemplateRef })
2558
+ /* @__PURE__ */ jsx2("template", { id: `${name}_end`, ref: endTemplateRef })
2590
2559
  ] });
2591
2560
  }
2592
2561
 
@@ -2655,25 +2624,8 @@ var routerImpl = async () => {
2655
2624
  });
2656
2625
  };
2657
2626
 
2658
- // src/host/nextjs/image-shared.ts
2659
- function createNextImageSharedEntries(getWrappedImage, options) {
2660
- const entries = {
2661
- "next/image": (bundle) => Promise.resolve(getWrappedImage(bundle)),
2662
- "next/dist/client/image-component": (bundle) => Promise.resolve({
2663
- Image: getWrappedImage(bundle)
2664
- })
2665
- };
2666
- if (options?.getImageProps) {
2667
- entries["next/dist/api/image"] = (bundle) => Promise.resolve({
2668
- default: getWrappedImage(bundle),
2669
- getImageProps: options.getImageProps
2670
- });
2671
- }
2672
- return entries;
2673
- }
2674
-
2675
2627
  // src/host/nextjs/app-client-only.tsx
2676
- import { jsx as jsx4 } from "react/jsx-runtime";
2628
+ import { jsx as jsx3 } from "react/jsx-runtime";
2677
2629
  async function tryImportShared() {
2678
2630
  try {
2679
2631
  const { shared: shared2 } = await Promise.resolve().then(() => (init_app(), app_exports));
@@ -2690,27 +2642,42 @@ var sharedModules = async (userShared, resolveClientUrl) => {
2690
2642
  return {
2691
2643
  ...resolvedShared,
2692
2644
  "next/router": routerImpl,
2693
- ...createNextImageSharedEntries(
2694
- (bundle) => imageImpl2(Image.default, bundle ?? "default", resolveClientUrl)
2695
- ),
2645
+ ...createImageLoaderSharedEntries({ unbound: resolveClientUrl }),
2696
2646
  ...resolvedUserShared
2697
2647
  };
2698
2648
  };
2649
+ function RemoteComponentsClientProvider({
2650
+ shared: shared2,
2651
+ resolveClientUrl,
2652
+ children,
2653
+ ...props
2654
+ }) {
2655
+ const mergedShared = useMemo3(
2656
+ () => sharedModules(shared2, resolveClientUrl),
2657
+ [shared2, resolveClientUrl]
2658
+ );
2659
+ return /* @__PURE__ */ jsx3(
2660
+ RemoteComponentsContext,
2661
+ {
2662
+ value: { shared: mergedShared, resolveClientUrl, ...props },
2663
+ children
2664
+ }
2665
+ );
2666
+ }
2699
2667
  function ConsumeRemoteComponent2(props) {
2700
2668
  if (typeof props.src !== "string" && !(props.src instanceof URL)) {
2701
2669
  return props.children ?? null;
2702
2670
  }
2703
- const src = typeof props.src === "string" ? props.src : props.src.href;
2704
- const resolveClientUrl = props.resolveClientUrl ? bindResolveClientUrl(props.resolveClientUrl, src) : void 0;
2705
- return /* @__PURE__ */ jsx4(
2671
+ return /* @__PURE__ */ jsx3(
2706
2672
  ConsumeRemoteComponent,
2707
2673
  {
2708
2674
  ...props,
2709
- shared: sharedModules(props.shared, resolveClientUrl)
2675
+ shared: sharedModules(props.shared, props.resolveClientUrl)
2710
2676
  }
2711
2677
  );
2712
2678
  }
2713
2679
  export {
2714
- ConsumeRemoteComponent2 as ConsumeRemoteComponent
2680
+ ConsumeRemoteComponent2 as ConsumeRemoteComponent,
2681
+ RemoteComponentsClientProvider
2715
2682
  };
2716
2683
  //# sourceMappingURL=client-only.js.map