remote-components 0.2.2 → 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 (51) 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 +169 -237
  11. package/dist/host/nextjs/app/client-only.cjs.map +1 -1
  12. package/dist/host/nextjs/app/client-only.js +170 -238
  13. package/dist/host/nextjs/app/client-only.js.map +1 -1
  14. package/dist/host/nextjs/pages.cjs +1 -8
  15. package/dist/host/nextjs/pages.cjs.map +1 -1
  16. package/dist/host/nextjs/pages.js +2 -9
  17. package/dist/host/nextjs/pages.js.map +1 -1
  18. package/dist/host/react.cjs +37 -71
  19. package/dist/host/react.cjs.map +1 -1
  20. package/dist/host/react.js +37 -71
  21. package/dist/host/react.js.map +1 -1
  22. package/dist/internal/host/nextjs/app-client.cjs +3 -8
  23. package/dist/internal/host/nextjs/app-client.cjs.map +1 -1
  24. package/dist/internal/host/nextjs/app-client.js +4 -9
  25. package/dist/internal/host/nextjs/app-client.js.map +1 -1
  26. package/dist/internal/host/nextjs/image-shared.cjs +25 -15
  27. package/dist/internal/host/nextjs/image-shared.cjs.map +1 -1
  28. package/dist/internal/host/nextjs/image-shared.d.ts +19 -6
  29. package/dist/internal/host/nextjs/image-shared.js +24 -14
  30. package/dist/internal/host/nextjs/image-shared.js.map +1 -1
  31. package/dist/internal/host/react/hooks/use-resolve-client-url.cjs +1 -5
  32. package/dist/internal/host/react/hooks/use-resolve-client-url.cjs.map +1 -1
  33. package/dist/internal/host/react/hooks/use-resolve-client-url.d.ts +1 -4
  34. package/dist/internal/host/react/hooks/use-resolve-client-url.js +1 -5
  35. package/dist/internal/host/react/hooks/use-resolve-client-url.js.map +1 -1
  36. package/dist/internal/host/shared/polyfill.cjs +10 -65
  37. package/dist/internal/host/shared/polyfill.cjs.map +1 -1
  38. package/dist/internal/host/shared/polyfill.d.ts +1 -3
  39. package/dist/internal/host/shared/polyfill.js +9 -63
  40. package/dist/internal/host/shared/polyfill.js.map +1 -1
  41. package/dist/internal/host/shared/remote-image-loader.cjs +53 -0
  42. package/dist/internal/host/shared/remote-image-loader.cjs.map +1 -0
  43. package/dist/internal/host/shared/remote-image-loader.d.ts +30 -0
  44. package/dist/internal/host/shared/remote-image-loader.js +29 -0
  45. package/dist/internal/host/shared/remote-image-loader.js.map +1 -0
  46. package/package.json +1 -1
  47. package/dist/internal/host/nextjs/image-impl.cjs +0 -64
  48. package/dist/internal/host/nextjs/image-impl.cjs.map +0 -1
  49. package/dist/internal/host/nextjs/image-impl.d.ts +0 -10
  50. package/dist/internal/host/nextjs/image-impl.js +0 -40
  51. package/dist/internal/host/nextjs/image-impl.js.map +0 -1
@@ -211,58 +211,35 @@ function getClientOrServerUrl(src, serverFallback) {
211
211
  return typeof src === "string" ? new URL(src, fallback) : src;
212
212
  }
213
213
 
214
- // src/host/shared/polyfill.tsx
215
- import { jsx } from "react/jsx-runtime";
216
- function applyBundleUrlToSrc(bundle, src) {
214
+ // src/host/shared/remote-image-loader.ts
215
+ function getRemoteBundleOrigin(bundle) {
217
216
  const self = globalThis;
218
- if (self.__remote_bundle_url__?.[bundle]?.origin === location.origin) {
219
- return src;
220
- }
221
- const { assetPrefix, path } = /^(?<assetPrefix>.*?)\/_next\/(?<path>.*)/.exec(src)?.groups ?? {};
222
- if (!path) {
223
- return new URL(src, self.__remote_bundle_url__?.[bundle]?.origin).href;
224
- }
225
- return `${self.__remote_bundle_url__?.[bundle]?.origin ?? ""}${assetPrefix}/_next/${path}`;
226
- }
227
- function applyBundleUrlToImagePropsSrc(bundle, src) {
228
- if (typeof src === "string") {
229
- return applyBundleUrlToSrc(bundle, src);
230
- }
231
- const propSrc = src;
232
- return applyBundleUrlToSrc(bundle, propSrc.src);
233
- }
234
- var imageImpl = (bundle, resolveClientUrl) => function RemoteImage({
235
- fill: _fill,
236
- loader: _loader,
237
- quality: _quality,
238
- priority: _priority,
239
- loading: _loading,
240
- placeholder: _placeholder,
241
- blurDataURL: _blurDataURL,
242
- unoptimized: _unoptimized,
243
- overrideSrc: _overrideSrc,
244
- src,
245
- ...props
246
- }) {
247
- const newSrc = applyBundleUrlToImagePropsSrc(
248
- bundle,
249
- typeof src === "string" ? src : src.src
250
- );
251
- const proxiedSrc = resolveClientUrl?.(newSrc) ?? newSrc;
252
- return (
253
- // eslint-disable-next-line @next/next/no-img-element, jsx-a11y/alt-text
254
- /* @__PURE__ */ jsx(
255
- "img",
256
- {
257
- decoding: "async",
258
- style: { color: "transparent" },
259
- ...props,
260
- src: proxiedSrc,
261
- suppressHydrationWarning: true
262
- }
263
- )
217
+ return self.__remote_bundle_url__?.[bundle]?.origin ?? "";
218
+ }
219
+ function createRemoteImageLoader(bundle, resolveClientUrl) {
220
+ const loader = Object.assign(
221
+ ({
222
+ config,
223
+ src,
224
+ width,
225
+ quality
226
+ }) => {
227
+ const q = quality ?? 75;
228
+ const remoteOrigin = getRemoteBundleOrigin(bundle);
229
+ const isCrossOrigin = remoteOrigin && remoteOrigin !== location.origin;
230
+ const basePath = isCrossOrigin ? `${remoteOrigin}${config.path ?? "/_next/image"}` : config.path ?? `${remoteOrigin}/_next/image`;
231
+ const url = `${basePath}?url=${encodeURIComponent(src)}&w=${width}&q=${q}`;
232
+ return resolveClientUrl?.(url) ?? url;
233
+ },
234
+ // Signals to getImgProps that this is a default loader (not a user-defined
235
+ // one), enabling srcSet generation with device/image sizes from the config.
236
+ { __next_img_default: true }
264
237
  );
265
- };
238
+ return loader;
239
+ }
240
+
241
+ // src/host/shared/polyfill.tsx
242
+ import { jsx } from "react/jsx-runtime";
266
243
  function sharedPolyfills(shared, resolveClientUrl) {
267
244
  const self = globalThis;
268
245
  const polyfill = {
@@ -353,17 +330,13 @@ function sharedPolyfills(shared, resolveClientUrl) {
353
330
  },
354
331
  __esModule: true
355
332
  })),
356
- "next/dist/client/image-component": self.__remote_component_host_shared_modules__?.["next/image"] ?? shared?.["next/image"] ?? ((bundle) => Promise.resolve({
357
- Image: imageImpl(bundle, resolveClientUrl),
358
- __esModule: true
359
- })),
360
- "next/image": self.__remote_component_host_shared_modules__?.["next/image"] ?? shared?.["next/image"] ?? ((bundle) => Promise.resolve({
361
- default: imageImpl(bundle, resolveClientUrl),
362
- getImageProps: (_imgProps) => {
363
- throw new Error(
364
- "Next.js getImageProps() is not implemented in remote components"
365
- );
366
- },
333
+ // Instead of replacing next/image entirely, we let the real Next.js Image
334
+ // component load from the remote bundle and only replace its default loader.
335
+ // This gives us full next/image fidelity (fill, priority, srcSet, blur
336
+ // placeholders, error handling) while routing image optimization through the
337
+ // remote app's /_next/image endpoint.
338
+ "next/dist/shared/lib/image-loader": self.__remote_component_host_shared_modules__?.["next/dist/shared/lib/image-loader"] ?? shared?.["next/dist/shared/lib/image-loader"] ?? ((bundle) => Promise.resolve({
339
+ default: createRemoteImageLoader(bundle, resolveClientUrl),
367
340
  __esModule: true
368
341
  })),
369
342
  "next/dist/client/script": self.__remote_component_host_shared_modules__?.["next/script"] ?? shared?.["next/script"] ?? (() => Promise.resolve({
@@ -403,7 +376,7 @@ function sharedPolyfills(shared, resolveClientUrl) {
403
376
  polyfill["next/navigation"] = polyfill["next/dist/client/components/navigation"];
404
377
  polyfill["next/link"] = polyfill["next/dist/client/app-dir/link"];
405
378
  polyfill["next/form"] = polyfill["next/dist/client/app-dir/form"];
406
- polyfill["next/dist/api/image"] = polyfill["next/dist/client/image-component"];
379
+ polyfill["next/dist/esm/shared/lib/image-loader"] = polyfill["next/dist/shared/lib/image-loader"];
407
380
  polyfill["next/script"] = polyfill["next/dist/client/script"];
408
381
  return polyfill;
409
382
  }
@@ -1915,11 +1888,7 @@ function bindResolveClientUrl(prop, remoteSrc) {
1915
1888
  function useResolveClientUrl(prop, urlHref) {
1916
1889
  const { resolveClientUrl: contextValue } = useRemoteComponentsContext();
1917
1890
  const raw = prop ?? contextValue;
1918
- const bound = useMemo(
1919
- () => bindResolveClientUrl(raw, urlHref),
1920
- [raw, urlHref]
1921
- );
1922
- return { bound, raw };
1891
+ return useMemo(() => bindResolveClientUrl(raw, urlHref), [raw, urlHref]);
1923
1892
  }
1924
1893
 
1925
1894
  // src/host/react/hooks/use-shadow-root.ts
@@ -2025,10 +1994,7 @@ function ConsumeRemoteComponent({
2025
1994
  null
2026
1995
  );
2027
1996
  const url = useMemo2(() => getClientOrServerUrl(src, DUMMY_FALLBACK), [src]);
2028
- const { bound: resolveClientUrl } = useResolveClientUrl(
2029
- resolveClientUrlProp,
2030
- url.href
2031
- );
1997
+ const resolveClientUrl = useResolveClientUrl(resolveClientUrlProp, url.href);
2032
1998
  const id = url.origin === (typeof location !== "undefined" ? location.origin : DUMMY_FALLBACK) ? url.pathname : url.href;
2033
1999
  const keySuffix = `${escapeString(id)}_${escapeString(
2034
2000
  data?.name ?? name