remote-components 0.0.4 → 0.0.6

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 (55) hide show
  1. package/dist/html/host.cjs +84 -28
  2. package/dist/html/host.cjs.map +1 -1
  3. package/dist/html/host.js +84 -28
  4. package/dist/html/host.js.map +1 -1
  5. package/dist/next/client.cjs +738 -0
  6. package/dist/next/client.cjs.map +1 -0
  7. package/dist/next/client.d.ts +11 -0
  8. package/dist/next/client.js +704 -0
  9. package/dist/next/client.js.map +1 -0
  10. package/dist/next/remote/render-client.cjs +19 -2
  11. package/dist/next/remote/render-client.cjs.map +1 -1
  12. package/dist/next/remote/render-client.js +10 -3
  13. package/dist/next/remote/render-client.js.map +1 -1
  14. package/dist/next/remote/render-server.cjs +1 -2
  15. package/dist/next/remote/render-server.cjs.map +1 -1
  16. package/dist/next/remote/render-server.js +1 -2
  17. package/dist/next/remote/render-server.js.map +1 -1
  18. package/dist/next/{host → server}/app-client.cjs +19 -3
  19. package/dist/next/server/app-client.cjs.map +1 -0
  20. package/dist/next/{host → server}/app-client.d.ts +1 -1
  21. package/dist/next/{host → server}/app-client.js +9 -3
  22. package/dist/next/server/app-client.js.map +1 -0
  23. package/dist/next/server/app-server.cjs.map +1 -0
  24. package/dist/next/server/app-server.js.map +1 -0
  25. package/dist/next/server/pages-client.cjs.map +1 -0
  26. package/dist/next/server/pages-client.js.map +1 -0
  27. package/dist/next/server/pages-server.cjs.map +1 -0
  28. package/dist/next/server/pages-server.js.map +1 -0
  29. package/dist/shared/client/remote-component.cjs +27 -19
  30. package/dist/shared/client/remote-component.cjs.map +1 -1
  31. package/dist/shared/client/remote-component.d.ts +2 -2
  32. package/dist/shared/client/remote-component.js +27 -19
  33. package/dist/shared/client/remote-component.js.map +1 -1
  34. package/dist/shared/ssr/fetch-remote-component.cjs +3 -1
  35. package/dist/shared/ssr/fetch-remote-component.cjs.map +1 -1
  36. package/dist/shared/ssr/fetch-remote-component.js +3 -1
  37. package/dist/shared/ssr/fetch-remote-component.js.map +1 -1
  38. package/package.json +37 -9
  39. package/dist/next/host/app-client.cjs.map +0 -1
  40. package/dist/next/host/app-client.js.map +0 -1
  41. package/dist/next/host/app-server.cjs.map +0 -1
  42. package/dist/next/host/app-server.js.map +0 -1
  43. package/dist/next/host/pages-client.cjs.map +0 -1
  44. package/dist/next/host/pages-client.js.map +0 -1
  45. package/dist/next/host/pages-server.cjs.map +0 -1
  46. package/dist/next/host/pages-server.js.map +0 -1
  47. /package/dist/next/{host → server}/app-server.cjs +0 -0
  48. /package/dist/next/{host → server}/app-server.d.ts +0 -0
  49. /package/dist/next/{host → server}/app-server.js +0 -0
  50. /package/dist/next/{host → server}/pages-client.cjs +0 -0
  51. /package/dist/next/{host → server}/pages-client.d.ts +0 -0
  52. /package/dist/next/{host → server}/pages-client.js +0 -0
  53. /package/dist/next/{host → server}/pages-server.cjs +0 -0
  54. /package/dist/next/{host → server}/pages-server.d.ts +0 -0
  55. /package/dist/next/{host → server}/pages-server.js +0 -0
@@ -0,0 +1,704 @@
1
+ "use client";
2
+
3
+ // src/next/client/index.tsx
4
+ import { useEffect, useMemo, useRef, useState } from "react";
5
+ import { createPortal } from "react-dom";
6
+
7
+ // src/shared/client/component-loader.ts
8
+ import * as React from "react";
9
+ import * as ReactDOM from "react-dom";
10
+ import * as ReactDOMClient from "react-dom/client";
11
+ import * as JSXDevRuntime from "react/jsx-dev-runtime";
12
+ import * as JSXRuntime from "react/jsx-runtime";
13
+
14
+ // src/shared/webpack/shared-modules.ts
15
+ function applySharedModules(bundle, resolve) {
16
+ const self = globalThis;
17
+ if (self.__remote_webpack_require__?.[bundle]) {
18
+ const modulePaths = Object.keys(
19
+ self.__remote_webpack_module_map__?.[bundle] ?? self.__remote_webpack_require__[bundle].m ?? {}
20
+ );
21
+ for (const [key, value] of Object.entries(resolve)) {
22
+ const ids = modulePaths.filter((p) => p.includes(key));
23
+ for (let id of ids) {
24
+ const webpackBundle = self.__remote_webpack_require__[bundle];
25
+ if (webpackBundle.m) {
26
+ if (self.__remote_webpack_module_map__?.[bundle]?.[id]) {
27
+ id = `${self.__remote_webpack_module_map__[bundle][id]}`;
28
+ }
29
+ webpackBundle.m[id] = (module) => {
30
+ module.exports = value;
31
+ };
32
+ }
33
+ }
34
+ }
35
+ }
36
+ }
37
+
38
+ // src/shared/webpack/next-client-pages-loader.ts
39
+ function nextClientPagesLoader(bundle, route, styleContainer = document.head) {
40
+ const self = globalThis;
41
+ const nextCssOriginal = document.getElementById("__next_css__DO_NOT_USE__");
42
+ if (nextCssOriginal) {
43
+ nextCssOriginal.parentNode?.removeChild(nextCssOriginal);
44
+ }
45
+ const nextCss = document.createElement("noscript");
46
+ nextCss.id = "__next_css__DO_NOT_USE__";
47
+ const lastNode = document.head.childNodes[document.head.childNodes.length - 1];
48
+ document.head.appendChild(nextCss);
49
+ const componentLoaderChunk = Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(
50
+ (key) => key.includes("/webpack/loaders/next-client-pages-loader.js") && key.includes(`page=${encodeURIComponent(route)}`)
51
+ ) ?? Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(
52
+ (key) => key.includes("/next/dist/client/page-loader.js")
53
+ ) ?? self.__remote_webpack_module_map__?.[bundle]?.[Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(
54
+ (key) => key.includes("/webpack/loaders/next-client-pages-loader.js") && key.includes(`page=${encodeURIComponent(route)}`)
55
+ ) ?? Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(
56
+ (key) => key.includes("/next/dist/client/page-loader.js")
57
+ ) ?? ""] ?? -1;
58
+ const appLoaderChunk = Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(
59
+ (key) => key.includes("/webpack/loaders/next-client-pages-loader.js") && key.includes(`page=%2F_app`)
60
+ ) ?? Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(
61
+ (key) => key.includes("/next/dist/client/page-loader.js")
62
+ ) ?? self.__remote_webpack_module_map__?.[bundle]?.[Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(
63
+ (key) => key.includes("/webpack/loaders/next-client-pages-loader.js") && key.includes(`page=%2F_app`)
64
+ ) ?? Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(
65
+ (key) => key.includes("/next/dist/client/page-loader.js")
66
+ ) ?? ""] ?? -1;
67
+ if (!(componentLoaderChunk && appLoaderChunk)) {
68
+ throw new Error(
69
+ `Next.js client pages loader not found in bundle "${bundle}"`
70
+ );
71
+ }
72
+ const __NEXT_P_ORIGINAL = self.__NEXT_P;
73
+ const selfOriginal = self;
74
+ delete selfOriginal.__NEXT_P;
75
+ self.__remote_webpack_require__?.[bundle]?.(
76
+ self.__remote_webpack_require__[bundle].type !== "turbopack" ? componentLoaderChunk : `[${bundle}] ${componentLoaderChunk}`
77
+ );
78
+ if (typeof appLoaderChunk === "string" || typeof appLoaderChunk === "number" && appLoaderChunk !== -1) {
79
+ self.__remote_webpack_require__?.[bundle]?.(
80
+ self.__remote_webpack_require__[bundle].type !== "turbopack" ? appLoaderChunk : `[${bundle}] ${appLoaderChunk}`
81
+ );
82
+ }
83
+ if (self.__NEXT_P) {
84
+ const [, componentLoader] = self.__NEXT_P[0] ?? [
85
+ void 0,
86
+ () => ({ default: null })
87
+ ];
88
+ const [, appLoader] = self.__NEXT_P[2] ?? [
89
+ void 0,
90
+ () => ({
91
+ default: null
92
+ })
93
+ ];
94
+ const { default: Component } = componentLoader();
95
+ const { default: App } = appLoader();
96
+ const cssRE = /\.s?css$/;
97
+ Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).filter((id) => cssRE.test(id)).forEach((id) => {
98
+ self.__remote_webpack_require__?.[bundle]?.(id);
99
+ });
100
+ Object.keys(self.__remote_webpack_module_map__?.[bundle] ?? {}).filter((path) => cssRE.test(path)).forEach((path) => {
101
+ const id = self.__remote_webpack_module_map__?.[bundle]?.[path];
102
+ if (id) {
103
+ self.__remote_webpack_require__?.[bundle]?.(id);
104
+ }
105
+ });
106
+ if (styleContainer) {
107
+ let node = nextCss.previousSibling;
108
+ while (node && node !== lastNode) {
109
+ styleContainer.appendChild(node);
110
+ node = nextCss.previousSibling;
111
+ }
112
+ }
113
+ delete self.__NEXT_P;
114
+ self.__NEXT_P = __NEXT_P_ORIGINAL;
115
+ if (nextCssOriginal) {
116
+ nextCssOriginal.parentNode?.appendChild(nextCssOriginal);
117
+ }
118
+ return { Component, App };
119
+ }
120
+ return { Component: null, App: null };
121
+ }
122
+
123
+ // src/shared/client/const.ts
124
+ var DEFAULT_ROUTE = "/";
125
+ var RUNTIME_WEBPACK = "webpack";
126
+ var RUNTIME_TURBOPACK = "turbopack";
127
+ var REMOTE_COMPONENT_REGEX = /(?<prefix>.*?)\[(?<bundle>[^\]]+)\](?:%20| )(?<id>.+)/;
128
+ function getBundleKey(bundle) {
129
+ return bundle.replace(/-/g, "_");
130
+ }
131
+
132
+ // src/shared/client/webpack-adapter.ts
133
+ async function setupWebpackRuntime(runtime, scripts = [], url = new URL(location.href), bundle, shared = {}, remoteShared = {}) {
134
+ const self = globalThis;
135
+ if (!self.__remote_bundle_url__) {
136
+ self.__remote_bundle_url__ = {};
137
+ }
138
+ self.__remote_bundle_url__[bundle ?? "default"] = url;
139
+ await initializeSharedModules(bundle ?? "default", shared, remoteShared);
140
+ if (typeof self.__webpack_require__ !== "function" || self.__webpack_require_type__ !== "turbopack") {
141
+ if (!self.__original_webpack_require__ && !self.__original_webpack_chunk_load__) {
142
+ self.__original_webpack_chunk_load__ = self.__webpack_chunk_load__;
143
+ self.__original_webpack_require__ = self.__webpack_require__;
144
+ }
145
+ self.__webpack_chunk_load__ = createChunkLoader(runtime);
146
+ self.__webpack_require__ = createModuleRequire(runtime);
147
+ self.__webpack_require_type__ = runtime;
148
+ if (self.__remote_webpack_require__ && runtime === RUNTIME_TURBOPACK) {
149
+ const remoteBundle = bundle ?? "default";
150
+ self.__remote_webpack_require__[remoteBundle] = self.__webpack_require__;
151
+ self.__remote_webpack_require__[remoteBundle].type = "turbopack";
152
+ }
153
+ }
154
+ if (runtime === RUNTIME_TURBOPACK) {
155
+ await Promise.all(
156
+ scripts.map((script) => {
157
+ if (script.src) {
158
+ return self.__webpack_chunk_load__?.(script.src, bundle);
159
+ }
160
+ return Promise.resolve(void 0);
161
+ })
162
+ );
163
+ }
164
+ }
165
+ function createChunkLoader(runtime) {
166
+ return function __turbopack_chunk_load__(chunkId, scriptBundle) {
167
+ const self = globalThis;
168
+ const {
169
+ bundle,
170
+ id: path,
171
+ prefix
172
+ } = REMOTE_COMPONENT_REGEX.exec(chunkId)?.groups ?? {
173
+ bundle: scriptBundle ?? "",
174
+ id: chunkId
175
+ };
176
+ const remoteRuntime = self.__remote_webpack_require__?.[bundle ?? "default"] ? self.__remote_webpack_require__[bundle ?? "default"]?.type || "webpack" : runtime;
177
+ if (remoteRuntime === RUNTIME_WEBPACK) {
178
+ return Promise.resolve(void 0);
179
+ }
180
+ const url = new URL(
181
+ path ? `${prefix ?? ""}${path}`.replace(
182
+ /(?<char>[^:])(?<double>\/\/)/g,
183
+ "$1/"
184
+ ) : "/",
185
+ self.__remote_bundle_url__?.[bundle ?? "default"] ?? new URL(location.origin)
186
+ ).href;
187
+ if (url.endsWith(".css")) {
188
+ return;
189
+ }
190
+ return new Promise((resolve, reject) => {
191
+ fetch(url).then((res) => res.text()).then((code) => {
192
+ if (code.includes("globalThis.TURBOPACK")) {
193
+ return handleTurbopackChunk(code, bundle ?? "", url);
194
+ }
195
+ }).then(resolve).catch(reject);
196
+ });
197
+ };
198
+ }
199
+ async function handleTurbopackChunk(code, bundle, url) {
200
+ if (code.includes("/next/dist/client/app-next-turbopack.js") && code.includes("importScripts(...self.TURBOPACK_NEXT_CHUNK_URLS")) {
201
+ const preloadLinks = document.querySelectorAll(
202
+ `link[rel="preload"][href="${new URL(url).pathname}"]`
203
+ );
204
+ preloadLinks.forEach((preloadLink) => preloadLink.remove());
205
+ return;
206
+ }
207
+ const self = globalThis;
208
+ const bundleKey = getBundleKey(bundle);
209
+ const transformedCode = code.replace(/globalThis\.TURBOPACK/g, `globalThis.TURBOPACK_${bundleKey}`).replace(
210
+ /TURBOPACK_WORKER_LOCATION/g,
211
+ `TURBOPACK_WORKER_LOCATION_${bundleKey}`
212
+ ).replace(
213
+ /TURBOPACK_NEXT_CHUNK_URLS/g,
214
+ `TURBOPACK_NEXT_CHUNK_URLS_${bundleKey}`
215
+ ).replace(
216
+ /TURBOPACK_CHUNK_UPDATE_LISTENERS/g,
217
+ `TURBOPACK_CHUNK_UPDATE_LISTENERS_${bundleKey}`
218
+ ).replace(/__next_require__/g, `__${bundleKey}_next_require__`).replace(
219
+ /\/\/# sourceMappingURL=(?<name>.+)(?<optional>\._)?\.js\.map/g,
220
+ `//# sourceMappingURL=${new URL(
221
+ ".",
222
+ new URL(
223
+ url,
224
+ self.__remote_bundle_url__?.[bundle] ?? new URL(location.origin)
225
+ )
226
+ ).href}$1$2.js.map`
227
+ );
228
+ await new Promise((scriptResolve, scriptReject) => {
229
+ const blob = new Blob([transformedCode], {
230
+ type: "application/javascript; charset=UTF-8"
231
+ });
232
+ const scriptUrl = URL.createObjectURL(blob);
233
+ const script = document.createElement("script");
234
+ script.src = scriptUrl;
235
+ script.async = true;
236
+ script.onload = () => {
237
+ URL.revokeObjectURL(scriptUrl);
238
+ scriptResolve(void 0);
239
+ };
240
+ script.onerror = (error) => {
241
+ URL.revokeObjectURL(scriptUrl);
242
+ scriptReject(
243
+ new Error(
244
+ `Failed to load script: ${error instanceof Error ? error.message : String(error)}`
245
+ )
246
+ );
247
+ };
248
+ document.head.appendChild(script);
249
+ });
250
+ const chunkLists = self[`TURBOPACK_${bundleKey}_CHUNK_LISTS`];
251
+ const loadChunkLists = [];
252
+ while (chunkLists?.length) {
253
+ const { chunks } = chunkLists.shift() ?? { chunks: [] };
254
+ if (chunks.length > 0) {
255
+ chunks.forEach((id) => {
256
+ const chunkLoadResult = self.__webpack_chunk_load__?.(
257
+ `[${bundle}] ${url.slice(0, url.indexOf("/_next"))}/_next/${id}`
258
+ );
259
+ if (chunkLoadResult) {
260
+ loadChunkLists.push(chunkLoadResult);
261
+ }
262
+ });
263
+ }
264
+ }
265
+ if (loadChunkLists.length > 0) {
266
+ await Promise.all(loadChunkLists);
267
+ }
268
+ }
269
+ function createModuleRequire(runtime) {
270
+ return (id) => {
271
+ const self = globalThis;
272
+ const { bundle, id: moduleId } = id.match(REMOTE_COMPONENT_REGEX)?.groups ?? { bundle: "default", id };
273
+ const remoteRuntime = self.__remote_webpack_require__?.[bundle ?? "default"] ? self.__remote_webpack_require__[bundle ?? "default"]?.type || "webpack" : runtime;
274
+ try {
275
+ if (remoteRuntime === RUNTIME_WEBPACK && bundle && moduleId) {
276
+ return self.__remote_webpack_require__?.[bundle]?.(moduleId);
277
+ }
278
+ const sharedModule = getSharedModule(bundle ?? "default", moduleId ?? id);
279
+ if (sharedModule) {
280
+ return sharedModule;
281
+ }
282
+ if (bundle && moduleId) {
283
+ return handleTurbopackModule(bundle, moduleId, id);
284
+ }
285
+ throw new Error(`Module ${id} not found`);
286
+ } catch {
287
+ try {
288
+ return self.__original_webpack_require__?.(id);
289
+ } catch {
290
+ throw new Error(
291
+ `Module ${id} not found in remote component bundle ${bundle}`
292
+ );
293
+ }
294
+ }
295
+ };
296
+ }
297
+ function initializeSharedModules(bundle, shared = {}, remoteShared = {}) {
298
+ const self = globalThis;
299
+ self.__remote_shared_modules__ = self.__remote_shared_modules__ ?? {};
300
+ if (!self.__remote_shared_modules__[bundle]) {
301
+ self.__remote_shared_modules__[bundle] = {};
302
+ }
303
+ return Promise.all(
304
+ Object.entries(remoteShared).map(async ([id, module]) => {
305
+ if (self.__remote_shared_modules__?.[bundle]) {
306
+ self.__remote_shared_modules__[bundle][id.replace("[app-ssr]", "[app-client]")] = await (shared[module] ?? (() => Promise.resolve(
307
+ new Proxy(
308
+ {},
309
+ {
310
+ get(_, prop) {
311
+ if (prop !== "then") {
312
+ console.warn(
313
+ `Shared dependency "${module}" not found for "${bundle}" when trying to import "${prop}".`
314
+ );
315
+ }
316
+ }
317
+ }
318
+ )
319
+ )))();
320
+ }
321
+ })
322
+ );
323
+ }
324
+ function getSharedModule(bundle, id) {
325
+ const self = globalThis;
326
+ for (const [key, value] of Object.entries(
327
+ self.__remote_shared_modules__?.[bundle] ?? {}
328
+ )) {
329
+ if (id.includes(key)) {
330
+ return value;
331
+ }
332
+ }
333
+ return null;
334
+ }
335
+ function handleTurbopackModule(bundle, moduleId, id) {
336
+ const self = globalThis;
337
+ const bundleKey = getBundleKey(bundle);
338
+ const modules = self[`TURBOPACK_${bundleKey}`]?.find((mod) => moduleId in mod[1])?.[1];
339
+ const moduleInit = modules?.[moduleId];
340
+ if (typeof moduleInit !== "function") {
341
+ throw new Error(
342
+ `Module ${id} not found in bundle ${bundle} with id ${moduleId}`
343
+ );
344
+ }
345
+ const exports = {};
346
+ moduleInit({
347
+ // HMR not implemented for Remote Components
348
+ k: {
349
+ register() {
350
+ },
351
+ registerExports() {
352
+ },
353
+ signature() {
354
+ return () => {
355
+ };
356
+ }
357
+ },
358
+ s(m) {
359
+ for (const [key, value] of Object.entries(m)) {
360
+ exports[key] = value;
361
+ }
362
+ },
363
+ i(iid) {
364
+ return self.__webpack_require__?.(`[${bundle}] ${iid}`);
365
+ },
366
+ r(rid) {
367
+ return self.__webpack_require__?.(`[${bundle}] ${rid}`);
368
+ },
369
+ m: {
370
+ exports
371
+ }
372
+ });
373
+ for (const [key, value] of Object.entries(exports)) {
374
+ if (typeof value === "function") {
375
+ exports[key] = value();
376
+ }
377
+ }
378
+ return exports;
379
+ }
380
+
381
+ // src/shared/client/script-loader.ts
382
+ async function loadScripts(scripts) {
383
+ await Promise.all(
384
+ scripts.map((script) => {
385
+ return new Promise((resolve, reject) => {
386
+ const newSrc = new URL(
387
+ // remove the remote component bundle name identifier from the script src
388
+ script.src.replace(/\/_next\/\[.+\](?<whitespace>%20| )/, "/_next/"),
389
+ location.origin
390
+ ).href;
391
+ const newScript = document.createElement("script");
392
+ newScript.onload = () => {
393
+ resolve();
394
+ };
395
+ newScript.onerror = () => {
396
+ reject(
397
+ new Error(
398
+ `Failed to load script ${script.src} for remote component`
399
+ )
400
+ );
401
+ };
402
+ newScript.src = newSrc;
403
+ newScript.async = true;
404
+ document.head.appendChild(newScript);
405
+ });
406
+ })
407
+ );
408
+ }
409
+
410
+ // src/shared/client/rsc.ts
411
+ function fixPayload(payload) {
412
+ if (Array.isArray(payload)) {
413
+ if (payload[0] === "$") {
414
+ fixPayload(payload[3]);
415
+ if (payload.length === 4) {
416
+ payload.push(null, null, 1);
417
+ }
418
+ } else {
419
+ for (const item of payload) {
420
+ fixPayload(item);
421
+ }
422
+ }
423
+ } else if (typeof payload === "object" && payload !== null) {
424
+ for (const key in payload) {
425
+ fixPayload(payload[key]);
426
+ }
427
+ }
428
+ }
429
+ function createRSCStream(name, data) {
430
+ return new ReadableStream({
431
+ type: "bytes",
432
+ start(controller) {
433
+ const encoder = new TextEncoder();
434
+ const self = globalThis;
435
+ if (!self[name] && data.length > 0) {
436
+ data.forEach((chunk) => {
437
+ const lines = chunk.split("\n");
438
+ for (const line of lines) {
439
+ const match = /\.push\("(?<rsc>.*)"\);$/.exec(line);
440
+ if (match?.groups?.rsc) {
441
+ self[name] = self[name] ?? [];
442
+ self[name].push(JSON.parse(`"${match.groups.rsc}"`));
443
+ }
444
+ }
445
+ });
446
+ }
447
+ const allChunks = (self[name] ?? [`0:[null]
448
+ `]).join("");
449
+ allChunks.split("\n").forEach((chunk) => {
450
+ if (chunk.length > 0) {
451
+ const { id, prefix, payload } = /(?<id>[0-9a-zA-Z]+):(?<prefix>[A-Z])?(?<payload>\[.*\])/.exec(
452
+ chunk
453
+ )?.groups ?? {};
454
+ if (payload) {
455
+ const jsonPayload = JSON.parse(payload);
456
+ fixPayload(jsonPayload);
457
+ const reconstruct = `${id}:${prefix ?? ""}${JSON.stringify(jsonPayload)}`;
458
+ controller.enqueue(encoder.encode(`${reconstruct}
459
+ `));
460
+ } else {
461
+ controller.enqueue(encoder.encode(`${chunk}
462
+ `));
463
+ }
464
+ } else {
465
+ controller.enqueue(encoder.encode(`${chunk}
466
+ `));
467
+ }
468
+ });
469
+ controller.close();
470
+ }
471
+ });
472
+ }
473
+
474
+ // src/shared/client/component-loader.ts
475
+ async function loadRemoteComponent({
476
+ url,
477
+ name,
478
+ bundle,
479
+ route = "/",
480
+ runtime = "webpack",
481
+ data,
482
+ nextData,
483
+ scripts = [],
484
+ shared = Promise.resolve({}),
485
+ remoteShared = {},
486
+ container
487
+ }) {
488
+ try {
489
+ if (runtime === "webpack") {
490
+ const self = globalThis;
491
+ self.__DISABLE_WEBPACK_EXEC__ = true;
492
+ await loadScripts(scripts);
493
+ }
494
+ await setupWebpackRuntime(
495
+ runtime,
496
+ scripts,
497
+ url,
498
+ bundle,
499
+ await shared,
500
+ remoteShared
501
+ );
502
+ if (bundle) {
503
+ const resolve = {
504
+ "/react/index.js": React,
505
+ "/react/jsx-dev-runtime.js": JSXDevRuntime,
506
+ "/react/jsx-runtime.js": JSXRuntime,
507
+ "/react-dom/index.js": ReactDOM,
508
+ "/react-dom/client.js": ReactDOMClient
509
+ };
510
+ applySharedModules(bundle, resolve);
511
+ }
512
+ if (data.length > 0) {
513
+ return await loadRSCComponent(name, data);
514
+ } else if (nextData) {
515
+ return loadNextPagesComponent(bundle, route, nextData, name, container);
516
+ }
517
+ return loadRSCComponent(name, [`0:[null]
518
+ `]);
519
+ } catch (error) {
520
+ return {
521
+ component: null,
522
+ error: error instanceof Error ? error : new Error(String(error))
523
+ };
524
+ }
525
+ }
526
+ async function loadRSCComponent(name, data) {
527
+ const { createFromReadableStream } = await import("next/dist/compiled/react-server-dom-webpack/client.browser");
528
+ const stream = createRSCStream(name, data);
529
+ const component = createFromReadableStream(stream);
530
+ return { component };
531
+ }
532
+ function loadNextPagesComponent(bundle, route, nextData, name, container) {
533
+ const { Component, App } = nextClientPagesLoader(bundle, route, container);
534
+ if (!Component) {
535
+ throw new Error(
536
+ `Remote component ${name} is trying to load the component for route ${route} but it is not available.`
537
+ );
538
+ }
539
+ const component = App ? React.createElement(App, { Component, ...nextData.props }) : React.createElement(Component, nextData.props);
540
+ return { component };
541
+ }
542
+
543
+ // src/next/client/index.tsx
544
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
545
+ async function tryImportShared() {
546
+ try {
547
+ const { shared } = await import("@remote-component/shared/host");
548
+ return shared;
549
+ } catch {
550
+ return {};
551
+ }
552
+ }
553
+ function RemoteComponent({
554
+ src,
555
+ isolate,
556
+ credentials = "same-origin",
557
+ name = "__vercel_remote_component",
558
+ children
559
+ }) {
560
+ const [data, setData] = useState(null);
561
+ const [remoteComponent, setRemoteComponent] = useState(null);
562
+ const shadowRootContainerRef = useRef(null);
563
+ const [shadowRoot, setShadowRoot] = useState(null);
564
+ useEffect(() => {
565
+ if (shadowRootContainerRef.current) {
566
+ const shadow = shadowRootContainerRef.current.attachShadow({
567
+ mode: "open"
568
+ });
569
+ setShadowRoot(shadow);
570
+ }
571
+ }, [shadowRootContainerRef]);
572
+ const url = useMemo(
573
+ () => typeof document !== "undefined" ? new URL(src, location.href) : new URL(src),
574
+ [src]
575
+ );
576
+ useEffect(() => {
577
+ let mounted = true;
578
+ (async () => {
579
+ const fetchInit = {
580
+ method: "GET",
581
+ headers: {
582
+ Accept: "text/html",
583
+ // pass the public address of the remote component to the server used for module map mutation
584
+ "Vercel-Remote-Component-Url": url.href
585
+ },
586
+ credentials
587
+ };
588
+ const res = await fetch(url, fetchInit);
589
+ if (!res.ok) {
590
+ throw new Error(
591
+ `Failed to fetch remote component "${name}": ${res.status}`
592
+ );
593
+ }
594
+ const html = await res.text();
595
+ const doc = document.createElement("div");
596
+ doc.innerHTML = html;
597
+ const component = doc.querySelector(`div[data-bundle][data-route][id^="${name}"]`) ?? // fallback to the first element with the data-bundle and data-route attributes when not using a named remote component
598
+ doc.querySelector("div[data-bundle][data-route]") ?? // fallback to Next.js Pages Router
599
+ doc.querySelector("div#__next");
600
+ const nextData = JSON.parse(
601
+ (doc.querySelector("#__NEXT_DATA__") ?? doc.querySelector("#__REMOTE_NEXT_DATA__"))?.textContent ?? "null"
602
+ );
603
+ const remoteName = component?.getAttribute("id")?.replace(/_ssr$/, "") || (nextData ? "__next" : name);
604
+ const rsc = doc.querySelector(`#${remoteName}_rsc`);
605
+ const bundle = component?.getAttribute("data-bundle") || nextData?.props.__REMOTE_COMPONENT__?.bundle || "default";
606
+ const metadata = {
607
+ name: remoteName,
608
+ bundle,
609
+ route: component?.getAttribute("data-route") ?? nextData?.page ?? DEFAULT_ROUTE,
610
+ runtime: component?.getAttribute("data-runtime") ?? (nextData?.props.__REMOTE_COMPONENT__?.runtime || RUNTIME_WEBPACK)
611
+ };
612
+ const remoteSharedEl = doc.querySelector(`#${remoteName}_shared`);
613
+ const remoteShared = JSON.parse(remoteSharedEl?.textContent ?? "{}") ?? {};
614
+ remoteSharedEl?.parentElement?.removeChild(remoteSharedEl);
615
+ if (!component || !(rsc || nextData)) {
616
+ throw new Error(`Failed to find component with id "${remoteName}"`);
617
+ }
618
+ const links = Array.from(
619
+ doc.querySelectorAll("link[href]")
620
+ ).map((link) => ({
621
+ rel: link.rel,
622
+ href: new URL(link.getAttribute("href") ?? link.href, url).href,
623
+ as: link.getAttribute("as") || void 0
624
+ }));
625
+ const scripts = doc.querySelectorAll(
626
+ "script[src],script[data-src]"
627
+ );
628
+ if (mounted) {
629
+ if (rsc) {
630
+ document.body.appendChild(rsc);
631
+ }
632
+ const newData = {
633
+ ...metadata,
634
+ links,
635
+ remoteShared,
636
+ url: url.href,
637
+ data: rsc ? (rsc.textContent ?? "").split("\n").filter(Boolean) : []
638
+ };
639
+ setData(newData);
640
+ loadRemoteComponent({
641
+ url: new URL(url, location.origin),
642
+ name,
643
+ bundle,
644
+ route: metadata.route,
645
+ runtime: metadata.runtime,
646
+ data: newData.data,
647
+ nextData: void 0,
648
+ scripts: Array.from(scripts).map((script) => ({
649
+ src: new URL(
650
+ script.getAttribute("data-src") || script.getAttribute("src") || script.src,
651
+ url
652
+ ).href
653
+ })),
654
+ shared: tryImportShared(),
655
+ remoteShared,
656
+ container: void 0
657
+ }).then((result) => {
658
+ if (mounted) {
659
+ if (result.error) {
660
+ setRemoteComponent(result.error);
661
+ } else {
662
+ setRemoteComponent(result.component);
663
+ }
664
+ }
665
+ }).catch((error) => {
666
+ if (mounted) {
667
+ setRemoteComponent(error);
668
+ }
669
+ });
670
+ }
671
+ })().catch((error) => {
672
+ if (mounted) {
673
+ setRemoteComponent(error);
674
+ }
675
+ });
676
+ return () => {
677
+ mounted = false;
678
+ };
679
+ }, [url, src, isolate, credentials, name]);
680
+ if (remoteComponent instanceof Error) {
681
+ throw remoteComponent;
682
+ }
683
+ const linksToRender = data?.links?.map((link) => /* @__PURE__ */ jsx(
684
+ "link",
685
+ {
686
+ as: link.as,
687
+ href: new URL(link.href, url).href,
688
+ rel: link.rel
689
+ },
690
+ `${link.href}_${link.rel}`
691
+ )) || null;
692
+ const componentToRender = /* @__PURE__ */ jsxs(Fragment, { children: [
693
+ linksToRender,
694
+ remoteComponent ?? children
695
+ ] });
696
+ if (isolate !== false) {
697
+ return /* @__PURE__ */ jsx("div", { id: `shadowroot_${name}`, ref: shadowRootContainerRef, children: shadowRoot ? createPortal(componentToRender, shadowRoot) : null });
698
+ }
699
+ return componentToRender;
700
+ }
701
+ export {
702
+ RemoteComponent
703
+ };
704
+ //# sourceMappingURL=client.js.map