remote-components 0.0.23 → 0.0.24
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.
- package/dist/html/host.cjs +297 -82
- package/dist/html/host.cjs.map +1 -1
- package/dist/html/host.js +300 -82
- package/dist/html/host.js.map +1 -1
- package/dist/internal/next/host/app-router-client.cjs +176 -70
- package/dist/internal/next/host/app-router-client.cjs.map +1 -1
- package/dist/internal/next/host/app-router-client.js +184 -71
- package/dist/internal/next/host/app-router-client.js.map +1 -1
- package/dist/internal/next/host/app-router-compat.cjs +114 -0
- package/dist/internal/next/host/app-router-compat.cjs.map +1 -0
- package/dist/internal/next/host/app-router-compat.d.ts +31 -0
- package/dist/internal/next/host/app-router-compat.js +79 -0
- package/dist/internal/next/host/app-router-compat.js.map +1 -0
- package/dist/internal/next/remote/render-client.cjs +10 -2
- package/dist/internal/next/remote/render-client.cjs.map +1 -1
- package/dist/internal/next/remote/render-client.js +10 -2
- package/dist/internal/next/remote/render-client.js.map +1 -1
- package/dist/internal/shared/client/apply-origin.cjs +61 -0
- package/dist/internal/shared/client/apply-origin.cjs.map +1 -0
- package/dist/internal/shared/client/apply-origin.d.ts +3 -0
- package/dist/internal/shared/client/apply-origin.js +37 -0
- package/dist/internal/shared/client/apply-origin.js.map +1 -0
- package/dist/internal/shared/client/polyfill.cjs +149 -0
- package/dist/internal/shared/client/polyfill.cjs.map +1 -0
- package/dist/internal/shared/client/polyfill.d.ts +6 -0
- package/dist/internal/shared/client/polyfill.js +124 -0
- package/dist/internal/shared/client/polyfill.js.map +1 -0
- package/dist/internal/shared/client/remote-component.cjs +3 -3
- package/dist/internal/shared/client/remote-component.cjs.map +1 -1
- package/dist/internal/shared/client/remote-component.d.ts +1 -1
- package/dist/internal/shared/client/remote-component.js +3 -3
- package/dist/internal/shared/client/remote-component.js.map +1 -1
- package/dist/internal/shared/ssr/dom-flight.cjs +40 -0
- package/dist/internal/shared/ssr/dom-flight.cjs.map +1 -1
- package/dist/internal/shared/ssr/dom-flight.js +40 -0
- package/dist/internal/shared/ssr/dom-flight.js.map +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.cjs +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.cjs.map +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.d.ts +6 -0
- package/dist/internal/shared/ssr/fetch-remote-component.js +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.js.map +1 -1
- package/dist/next/config.cjs +50 -28
- package/dist/next/config.cjs.map +1 -1
- package/dist/next/config.js +50 -28
- package/dist/next/config.js.map +1 -1
- package/dist/next/host/client/index.cjs +16 -1
- package/dist/next/host/client/index.cjs.map +1 -1
- package/dist/next/host/client/index.js +16 -1
- package/dist/next/host/client/index.js.map +1 -1
- package/dist/next/host/pages-router-server.cjs +27 -13
- package/dist/next/host/pages-router-server.cjs.map +1 -1
- package/dist/next/host/pages-router-server.js +27 -13
- package/dist/next/host/pages-router-server.js.map +1 -1
- package/dist/next/middleware.cjs +5 -2
- package/dist/next/middleware.cjs.map +1 -1
- package/dist/next/middleware.d.ts +1 -0
- package/dist/next/middleware.js +5 -2
- package/dist/next/middleware.js.map +1 -1
- package/dist/next/remote/pages-router.cjs +3 -1
- package/dist/next/remote/pages-router.cjs.map +1 -1
- package/dist/next/remote/pages-router.d.ts +1 -0
- package/dist/next/remote/pages-router.js +3 -1
- package/dist/next/remote/pages-router.js.map +1 -1
- package/dist/react/index.cjs +203 -159
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +192 -148
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/html/host.cjs
CHANGED
|
@@ -395,7 +395,7 @@ function initializeSharedModules(bundle, shared = {}, remoteShared = {}) {
|
|
|
395
395
|
Object.entries(remoteShared).map(async ([id, module2]) => {
|
|
396
396
|
if (self.__remote_shared_modules__?.[bundle]) {
|
|
397
397
|
if (shared[module2]) {
|
|
398
|
-
self.__remote_shared_modules__[bundle][id.replace("[app-ssr]", "[app-client]")] = await shared[module2]();
|
|
398
|
+
self.__remote_shared_modules__[bundle][id.replace("[app-ssr]", "[app-client]")] = await shared[module2](bundle);
|
|
399
399
|
} else {
|
|
400
400
|
console.error(`Shared module "${module2}" not found for "${bundle}".`);
|
|
401
401
|
}
|
|
@@ -408,7 +408,7 @@ function getSharedModule(bundle, id) {
|
|
|
408
408
|
for (const [key, value] of Object.entries(
|
|
409
409
|
self.__remote_shared_modules__?.[bundle] ?? {}
|
|
410
410
|
)) {
|
|
411
|
-
if (typeof id === "string" && id.includes(key) || id === key) {
|
|
411
|
+
if (typeof value !== "undefined" && (typeof id === "string" && id.includes(key) || id === key)) {
|
|
412
412
|
return value;
|
|
413
413
|
}
|
|
414
414
|
}
|
|
@@ -541,6 +541,24 @@ var init_webpack_adapter = __esm({
|
|
|
541
541
|
});
|
|
542
542
|
|
|
543
543
|
// src/shared/client/polyfill.tsx
|
|
544
|
+
function applyBundleUrlToSrc(bundle, src) {
|
|
545
|
+
const self = globalThis;
|
|
546
|
+
if (self.__remote_bundle_url__?.[bundle]?.origin === location.origin) {
|
|
547
|
+
return src;
|
|
548
|
+
}
|
|
549
|
+
const { assetPrefix, path } = /^(?<assetPrefix>.*?)\/_next\/(?<path>.*)/.exec(src)?.groups ?? {};
|
|
550
|
+
if (!path) {
|
|
551
|
+
return new URL(src, self.__remote_bundle_url__?.[bundle]?.origin).href;
|
|
552
|
+
}
|
|
553
|
+
return `${self.__remote_bundle_url__?.[bundle]?.origin ?? ""}${assetPrefix}/_next/${path}`;
|
|
554
|
+
}
|
|
555
|
+
function applyBundleUrlToImagePropsSrc(bundle, src) {
|
|
556
|
+
if (typeof src === "string") {
|
|
557
|
+
return applyBundleUrlToSrc(bundle, src);
|
|
558
|
+
}
|
|
559
|
+
const propSrc = src;
|
|
560
|
+
return applyBundleUrlToSrc(bundle, propSrc.src);
|
|
561
|
+
}
|
|
544
562
|
function sharedPolyfills(shared) {
|
|
545
563
|
const self = globalThis;
|
|
546
564
|
const polyfill = {
|
|
@@ -576,18 +594,17 @@ function sharedPolyfills(shared) {
|
|
|
576
594
|
},
|
|
577
595
|
__esModule: true
|
|
578
596
|
})),
|
|
579
|
-
"next/dist/client/image-component": self.__remote_component_host_shared_modules__?.["next/image"] ?? shared?.["next/image"] ?? (() => Promise.resolve({
|
|
580
|
-
Image: (
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
),
|
|
597
|
+
"next/dist/client/image-component": self.__remote_component_host_shared_modules__?.["next/image"] ?? shared?.["next/image"] ?? ((bundle) => Promise.resolve({
|
|
598
|
+
Image: imageImpl(bundle),
|
|
599
|
+
__esModule: true
|
|
600
|
+
})),
|
|
601
|
+
"next/image": self.__remote_component_host_shared_modules__?.["next/image"] ?? shared?.["next/image"] ?? ((bundle) => Promise.resolve({
|
|
602
|
+
default: imageImpl(bundle),
|
|
603
|
+
getImageProps: (_imgProps) => {
|
|
604
|
+
throw new Error(
|
|
605
|
+
"Next.js getImageProps() is not implemented in remote components"
|
|
606
|
+
);
|
|
607
|
+
},
|
|
591
608
|
__esModule: true
|
|
592
609
|
})),
|
|
593
610
|
"next/dist/client/script": self.__remote_component_host_shared_modules__?.["next/script"] ?? shared?.["next/script"] ?? (() => Promise.resolve({
|
|
@@ -595,21 +612,56 @@ function sharedPolyfills(shared) {
|
|
|
595
612
|
// do not throw an error for now
|
|
596
613
|
default: () => null,
|
|
597
614
|
__esModule: true
|
|
598
|
-
}))
|
|
615
|
+
})),
|
|
616
|
+
"next/router": self.__remote_component_host_shared_modules__?.["next/router"] ?? shared?.["next/router"] ?? (() => (
|
|
617
|
+
// TODO: incomplete implementation
|
|
618
|
+
Promise.resolve({
|
|
619
|
+
useRouter() {
|
|
620
|
+
return {
|
|
621
|
+
push: (routerUrl) => {
|
|
622
|
+
history.pushState({}, "", routerUrl);
|
|
623
|
+
},
|
|
624
|
+
replace: (routerUrl) => {
|
|
625
|
+
history.replaceState({}, "", routerUrl);
|
|
626
|
+
},
|
|
627
|
+
back: () => {
|
|
628
|
+
history.back();
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
},
|
|
632
|
+
__esModule: true
|
|
633
|
+
})
|
|
634
|
+
))
|
|
599
635
|
};
|
|
600
636
|
polyfill["next/navigation"] = polyfill["next/dist/client/components/navigation"];
|
|
601
637
|
polyfill["next/link"] = polyfill["next/dist/client/app-dir/link"];
|
|
602
638
|
polyfill["next/form"] = polyfill["next/dist/client/app-dir/form"];
|
|
603
|
-
polyfill["next/image"] = polyfill["next/dist/client/image-component"];
|
|
604
639
|
polyfill["next/dist/api/image"] = polyfill["next/dist/client/image-component"];
|
|
605
640
|
polyfill["next/script"] = polyfill["next/dist/client/script"];
|
|
606
641
|
return polyfill;
|
|
607
642
|
}
|
|
608
|
-
var import_jsx_runtime;
|
|
643
|
+
var import_jsx_runtime, imageImpl;
|
|
609
644
|
var init_polyfill = __esm({
|
|
610
645
|
"src/shared/client/polyfill.tsx"() {
|
|
611
646
|
"use strict";
|
|
647
|
+
// eslint-disable-next-line @next/next/no-img-element, jsx-a11y/alt-text
|
|
612
648
|
import_jsx_runtime = require("react/jsx-runtime");
|
|
649
|
+
imageImpl = (bundle) => function RemoteImage({ priority: _, ...props }) {
|
|
650
|
+
const newSrc = applyBundleUrlToImagePropsSrc(
|
|
651
|
+
bundle,
|
|
652
|
+
typeof props.src === "string" ? props.src : props.src.src
|
|
653
|
+
);
|
|
654
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
655
|
+
"img",
|
|
656
|
+
{
|
|
657
|
+
decoding: "async",
|
|
658
|
+
style: { color: "transparent" },
|
|
659
|
+
...props,
|
|
660
|
+
src: newSrc,
|
|
661
|
+
suppressHydrationWarning: true
|
|
662
|
+
}
|
|
663
|
+
);
|
|
664
|
+
};
|
|
613
665
|
}
|
|
614
666
|
});
|
|
615
667
|
|
|
@@ -652,6 +704,7 @@ async function webpackRuntime(bundle, shared, remoteShared) {
|
|
|
652
704
|
const newScript = document.createElement("script");
|
|
653
705
|
newScript.onload = () => {
|
|
654
706
|
resolve2();
|
|
707
|
+
newScript.remove();
|
|
655
708
|
};
|
|
656
709
|
newScript.onerror = () => {
|
|
657
710
|
reject(
|
|
@@ -659,6 +712,7 @@ async function webpackRuntime(bundle, shared, remoteShared) {
|
|
|
659
712
|
`Failed to load script ${script.src} for remote component`
|
|
660
713
|
)
|
|
661
714
|
);
|
|
715
|
+
newScript.remove();
|
|
662
716
|
};
|
|
663
717
|
const scriptSrc = script.getAttribute("src") || script.getAttribute("data-src");
|
|
664
718
|
if (scriptSrc) {
|
|
@@ -697,7 +751,7 @@ async function webpackRuntime(bundle, shared, remoteShared) {
|
|
|
697
751
|
await Promise.all(
|
|
698
752
|
Object.entries(resolve).map(async ([key, value]) => {
|
|
699
753
|
if (typeof value === "function") {
|
|
700
|
-
resolve[key] = await value();
|
|
754
|
+
resolve[key] = await value(remoteBundle);
|
|
701
755
|
}
|
|
702
756
|
return Promise.resolve(value);
|
|
703
757
|
})
|
|
@@ -863,6 +917,41 @@ function createRSCStream(name, data) {
|
|
|
863
917
|
init_webpack_adapter();
|
|
864
918
|
init_const();
|
|
865
919
|
|
|
920
|
+
// src/shared/client/apply-origin.ts
|
|
921
|
+
var tagNames = [
|
|
922
|
+
"img",
|
|
923
|
+
"source",
|
|
924
|
+
"video",
|
|
925
|
+
"audio",
|
|
926
|
+
"track",
|
|
927
|
+
"iframe",
|
|
928
|
+
"embed",
|
|
929
|
+
"script",
|
|
930
|
+
"link"
|
|
931
|
+
];
|
|
932
|
+
function applyOriginToNodes(doc, url) {
|
|
933
|
+
const nodes = doc.querySelectorAll(
|
|
934
|
+
tagNames.map((type) => `${type}[src],${type}[srcset]`).join(",")
|
|
935
|
+
);
|
|
936
|
+
nodes.forEach((node) => {
|
|
937
|
+
if (node.hasAttribute("src") && /^[./]+\/?/.test(node.getAttribute("src") ?? "")) {
|
|
938
|
+
node.src = new URL(node.getAttribute("src") ?? "/", url).href;
|
|
939
|
+
}
|
|
940
|
+
if (node.hasAttribute("srcset")) {
|
|
941
|
+
const srcSet = node.getAttribute("srcset")?.split(",").map((entry) => {
|
|
942
|
+
const [urlPart, descriptor] = entry.trim().split(/\s+/);
|
|
943
|
+
if (!urlPart)
|
|
944
|
+
return entry;
|
|
945
|
+
const absoluteUrl = new URL(urlPart, url).href;
|
|
946
|
+
return descriptor ? `${absoluteUrl} ${descriptor}` : absoluteUrl;
|
|
947
|
+
}).join(", ");
|
|
948
|
+
if (srcSet) {
|
|
949
|
+
node.setAttribute("srcset", srcSet);
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
|
|
866
955
|
// src/html/host/runtime/index.ts
|
|
867
956
|
async function getRuntime(type, url, bundle, shared, remoteShared) {
|
|
868
957
|
if (typeof globalThis.process === "undefined") {
|
|
@@ -885,44 +974,64 @@ var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
|
885
974
|
if (typeof HTMLElement !== "undefined") {
|
|
886
975
|
class RemoteComponent extends HTMLElement {
|
|
887
976
|
constructor() {
|
|
888
|
-
super();
|
|
977
|
+
super(...arguments);
|
|
889
978
|
this.__next = null;
|
|
890
979
|
this.fouc = null;
|
|
891
980
|
this.isLoading = false;
|
|
892
981
|
this.root = null;
|
|
893
|
-
this.root = this.attachShadow({
|
|
894
|
-
mode: this.getAttribute("mode") === "closed" ? "closed" : "open"
|
|
895
|
-
});
|
|
896
|
-
this.fallbackSlot = document.createElement("slot");
|
|
897
|
-
this.root.appendChild(this.fallbackSlot);
|
|
898
|
-
this.name = this.getAttribute("name") || "__vercel_remote_component";
|
|
899
|
-
this.bundle = "default";
|
|
900
|
-
if (this.hasAttribute("src") || this.querySelector("div#__REMOTE_COMPONENT__") || this.hasAttribute("data-ssr")) {
|
|
901
|
-
this.load().catch((e) => {
|
|
902
|
-
throw new Error(`Failed to load remote component: ${e}`);
|
|
903
|
-
});
|
|
904
|
-
}
|
|
905
982
|
}
|
|
906
983
|
static get observedAttributes() {
|
|
907
|
-
return ["src", "name"];
|
|
984
|
+
return ["src", "name", "mode"];
|
|
908
985
|
}
|
|
909
986
|
// watch for src attribute changes
|
|
910
987
|
// this is required to reload the remote component when the src attribute is added later
|
|
911
988
|
// this is for rendering the custom element using React
|
|
912
989
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
913
990
|
if ((name === "src" || name === "name") && oldValue !== newValue) {
|
|
991
|
+
if (this.getAttribute("src")) {
|
|
992
|
+
this.load().catch((e) => {
|
|
993
|
+
console.error(e);
|
|
994
|
+
throw new Error(
|
|
995
|
+
`Failed to load remote component: ${this.bundle ?? this.name ?? this.getAttribute("src")}`
|
|
996
|
+
);
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
} else if (name === "mode" && oldValue !== newValue && this.root) {
|
|
1000
|
+
const newRoot = this.attachShadow({
|
|
1001
|
+
mode: newValue === "closed" ? "closed" : "open"
|
|
1002
|
+
});
|
|
1003
|
+
Array.from(this.root.children).forEach((child) => {
|
|
1004
|
+
newRoot.appendChild(child);
|
|
1005
|
+
});
|
|
1006
|
+
this.root = newRoot;
|
|
914
1007
|
this.load().catch((e) => {
|
|
915
|
-
|
|
916
|
-
throw new Error(
|
|
917
|
-
`Failed to load remote component: ${this.bundle ?? this.name ?? this.getAttribute("src")}`
|
|
918
|
-
);
|
|
1008
|
+
throw new Error(`Failed to load remote component: ${e}`);
|
|
919
1009
|
});
|
|
920
1010
|
}
|
|
921
1011
|
}
|
|
922
1012
|
async load() {
|
|
1013
|
+
await new Promise((resolve) => {
|
|
1014
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : requestAnimationFrame)(() => {
|
|
1015
|
+
resolve(void 0);
|
|
1016
|
+
});
|
|
1017
|
+
});
|
|
923
1018
|
if (this.isLoading) {
|
|
924
1019
|
return;
|
|
925
1020
|
}
|
|
1021
|
+
if (!this.root) {
|
|
1022
|
+
this.root = this.attachShadow({
|
|
1023
|
+
mode: this.getAttribute("mode") === "closed" ? "closed" : "open"
|
|
1024
|
+
});
|
|
1025
|
+
this.fallbackSlot = document.createElement("slot");
|
|
1026
|
+
this.root.appendChild(this.fallbackSlot);
|
|
1027
|
+
}
|
|
1028
|
+
this.name = this.getAttribute("name") || "__vercel_remote_component";
|
|
1029
|
+
this.bundle = "default";
|
|
1030
|
+
if (this.hasAttribute("src") || this.querySelector("div#__REMOTE_COMPONENT__") || this.hasAttribute("data-ssr")) {
|
|
1031
|
+
this.load().catch((e) => {
|
|
1032
|
+
throw new Error(`Failed to load remote component: ${e}`);
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
926
1035
|
this.isLoading = true;
|
|
927
1036
|
const src = this.getAttribute("src");
|
|
928
1037
|
const remoteComponentChild = this.querySelector("div#__REMOTE_COMPONENT__") || this.querySelector("div[data-bundle][data-route]");
|
|
@@ -953,8 +1062,8 @@ if (typeof HTMLElement !== "undefined") {
|
|
|
953
1062
|
}
|
|
954
1063
|
html = await res.text();
|
|
955
1064
|
}
|
|
956
|
-
const
|
|
957
|
-
doc
|
|
1065
|
+
const parser = new DOMParser();
|
|
1066
|
+
const doc = parser.parseFromString(html, "text/html");
|
|
958
1067
|
const component = doc.querySelector(`div[data-bundle][data-route][id^="${this.name}"]`) ?? // fallback to the first element with the data-bundle and data-route attributes when not using a named remote component
|
|
959
1068
|
doc.querySelector("div[data-bundle][data-route]") ?? // fallback to Next.js Pages Router
|
|
960
1069
|
doc.querySelector("div#__next");
|
|
@@ -964,11 +1073,18 @@ if (typeof HTMLElement !== "undefined") {
|
|
|
964
1073
|
if (nextData && nextData.buildId === "development" && !this.reactRoot) {
|
|
965
1074
|
this.fouc = document.createElement("style");
|
|
966
1075
|
this.fouc.textContent = `:host { display: none; }`;
|
|
967
|
-
this.root
|
|
1076
|
+
this.root.appendChild(this.fouc);
|
|
968
1077
|
}
|
|
969
1078
|
this.name = component?.getAttribute("id")?.replace(/_ssr$/, "") || (nextData ? "__next" : this.name);
|
|
970
1079
|
const rsc = doc.querySelector(`#${this.name}_rsc`);
|
|
971
1080
|
this.bundle = component?.getAttribute("data-bundle") || nextData?.props.__REMOTE_COMPONENT__?.bundle || this.bundle;
|
|
1081
|
+
if (url) {
|
|
1082
|
+
const self2 = globalThis;
|
|
1083
|
+
if (!self2.__remote_bundle_url__) {
|
|
1084
|
+
self2.__remote_bundle_url__ = {};
|
|
1085
|
+
}
|
|
1086
|
+
self2.__remote_bundle_url__[this.bundle ?? "default"] = url;
|
|
1087
|
+
}
|
|
972
1088
|
const metadata = document.createElement("script");
|
|
973
1089
|
metadata.type = "application/json";
|
|
974
1090
|
metadata.setAttribute("data-remote-component", "");
|
|
@@ -978,47 +1094,81 @@ if (typeof HTMLElement !== "undefined") {
|
|
|
978
1094
|
route: component?.getAttribute("data-route") ?? nextData?.page ?? "/",
|
|
979
1095
|
runtime: component?.getAttribute("data-runtime") ?? nextData?.props.__REMOTE_COMPONENT__?.runtime
|
|
980
1096
|
});
|
|
981
|
-
this.
|
|
982
|
-
|
|
983
|
-
|
|
1097
|
+
if (this.previousElementSibling?.getAttribute("data-remote-component") !== null) {
|
|
1098
|
+
this.previousElementSibling?.remove();
|
|
1099
|
+
}
|
|
1100
|
+
this.parentElement?.insertBefore(metadata, this);
|
|
1101
|
+
const remoteSharedEl = doc.querySelector(
|
|
1102
|
+
`#${this.name}_shared[data-remote-components-shared]`
|
|
1103
|
+
);
|
|
1104
|
+
const remoteShared = nextData?.props.__REMOTE_COMPONENT__?.shared ?? (JSON.parse(remoteSharedEl?.textContent ?? "{}") ?? {});
|
|
984
1105
|
remoteSharedEl?.parentElement?.removeChild(remoteSharedEl);
|
|
985
1106
|
if (!component || !(rsc || nextData)) {
|
|
986
1107
|
throw new Error(`Failed to find component with id "${this.name}"`);
|
|
987
1108
|
}
|
|
988
1109
|
const removable = Array.from(this.childNodes);
|
|
989
1110
|
const links = doc.querySelectorAll("link[href]");
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1111
|
+
const remoteComponentSrc = this.getAttribute("src");
|
|
1112
|
+
const attachLinks = async () => {
|
|
1113
|
+
await Promise.all(
|
|
1114
|
+
Array.from(links).filter((link) => {
|
|
1115
|
+
return !component.contains(link);
|
|
1116
|
+
}).map((link) => {
|
|
1117
|
+
return new Promise((resolve, reject) => {
|
|
1118
|
+
const newLink = document.createElement("link");
|
|
1119
|
+
if (link.rel === "stylesheet") {
|
|
1120
|
+
newLink.onload = () => {
|
|
1121
|
+
resolve();
|
|
1122
|
+
};
|
|
1123
|
+
newLink.onerror = () => {
|
|
1124
|
+
reject(
|
|
1125
|
+
new Error(
|
|
1126
|
+
`Failed to load link ${link.href} for remote component`
|
|
1127
|
+
)
|
|
1128
|
+
);
|
|
1129
|
+
};
|
|
1130
|
+
} else {
|
|
996
1131
|
resolve();
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
if (attr.name === "href") {
|
|
1132
|
+
}
|
|
1133
|
+
for (const attr of link.attributes) {
|
|
1134
|
+
if (attr.name === "href") {
|
|
1135
|
+
newLink.setAttribute(
|
|
1136
|
+
attr.name,
|
|
1137
|
+
new URL(attr.value, url ?? location.origin).href
|
|
1138
|
+
);
|
|
1139
|
+
} else {
|
|
1140
|
+
newLink.setAttribute(attr.name, attr.value);
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
if (remoteComponentSrc) {
|
|
1010
1144
|
newLink.setAttribute(
|
|
1011
|
-
|
|
1012
|
-
|
|
1145
|
+
"data-remote-component-src",
|
|
1146
|
+
remoteComponentSrc
|
|
1013
1147
|
);
|
|
1014
|
-
} else {
|
|
1015
|
-
newLink.setAttribute(attr.name, attr.value);
|
|
1016
1148
|
}
|
|
1149
|
+
this.root?.appendChild(newLink);
|
|
1150
|
+
});
|
|
1151
|
+
})
|
|
1152
|
+
);
|
|
1153
|
+
const styles = doc.querySelectorAll("style");
|
|
1154
|
+
styles.forEach((style) => {
|
|
1155
|
+
if (style.parentElement?.tagName.toLowerCase() === "head") {
|
|
1156
|
+
const newStyle = document.createElement("style");
|
|
1157
|
+
newStyle.textContent = style.textContent;
|
|
1158
|
+
if (remoteComponentSrc) {
|
|
1159
|
+
newStyle.setAttribute(
|
|
1160
|
+
"data-remote-component-src",
|
|
1161
|
+
remoteComponentSrc
|
|
1162
|
+
);
|
|
1017
1163
|
}
|
|
1018
|
-
this.root?.appendChild(
|
|
1019
|
-
}
|
|
1020
|
-
})
|
|
1021
|
-
|
|
1164
|
+
this.root?.appendChild(newStyle);
|
|
1165
|
+
}
|
|
1166
|
+
});
|
|
1167
|
+
};
|
|
1168
|
+
if (!this.reactRoot) {
|
|
1169
|
+
await attachLinks();
|
|
1170
|
+
}
|
|
1171
|
+
applyOriginToNodes(doc, url ?? new URL(location.href));
|
|
1022
1172
|
if (!this.reactRoot) {
|
|
1023
1173
|
Array.from(component.children).forEach((el) => {
|
|
1024
1174
|
this.root?.appendChild(el);
|
|
@@ -1027,12 +1177,32 @@ if (typeof HTMLElement !== "undefined") {
|
|
|
1027
1177
|
for (const el of removable) {
|
|
1028
1178
|
el.parentElement?.removeChild(el);
|
|
1029
1179
|
}
|
|
1030
|
-
this.fallbackSlot
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1180
|
+
this.fallbackSlot?.remove();
|
|
1181
|
+
const applyReset = () => {
|
|
1182
|
+
if (this.getAttribute("reset") !== null && !this.root?.querySelector("link[data-remote-components-reset]")) {
|
|
1183
|
+
const allInitial = document.createElement("link");
|
|
1184
|
+
allInitial.setAttribute("data-remote-components-reset", "");
|
|
1185
|
+
const css = `:host { all: initial; }`;
|
|
1186
|
+
const allInitialHref = URL.createObjectURL(
|
|
1187
|
+
new Blob([css], { type: "text/css" })
|
|
1188
|
+
);
|
|
1189
|
+
allInitial.href = allInitialHref;
|
|
1190
|
+
allInitial.rel = "stylesheet";
|
|
1191
|
+
allInitial.onload = () => {
|
|
1192
|
+
URL.revokeObjectURL(allInitialHref);
|
|
1193
|
+
allInitial.removeAttribute("onload");
|
|
1194
|
+
};
|
|
1195
|
+
allInitial.onerror = () => {
|
|
1196
|
+
URL.revokeObjectURL(allInitialHref);
|
|
1197
|
+
allInitial.removeAttribute("onload");
|
|
1198
|
+
};
|
|
1199
|
+
this.root?.prepend(allInitial);
|
|
1200
|
+
} else if (this.getAttribute("reset") === null && this.root?.querySelector("link[data-remote-components-reset]")) {
|
|
1201
|
+
this.root.querySelector("link[data-remote-components-reset]")?.remove();
|
|
1202
|
+
}
|
|
1203
|
+
};
|
|
1204
|
+
if (!this.reactRoot) {
|
|
1205
|
+
applyReset();
|
|
1036
1206
|
}
|
|
1037
1207
|
const {
|
|
1038
1208
|
self,
|
|
@@ -1067,6 +1237,20 @@ if (typeof HTMLElement !== "undefined") {
|
|
|
1067
1237
|
this.bundle ?? "default",
|
|
1068
1238
|
this.name ?? "__vercel_remote_component"
|
|
1069
1239
|
);
|
|
1240
|
+
const doCleanup = () => {
|
|
1241
|
+
if (this.root && remoteComponentSrc) {
|
|
1242
|
+
const selector = `[data-remote-component-src]:not([data-remote-component-src="${remoteComponentSrc}"])`;
|
|
1243
|
+
const prevCleanup = [
|
|
1244
|
+
...this.root.querySelectorAll(selector),
|
|
1245
|
+
...document.body.querySelectorAll(selector)
|
|
1246
|
+
];
|
|
1247
|
+
if (prevCleanup.length > 0) {
|
|
1248
|
+
prevCleanup.forEach((prev) => {
|
|
1249
|
+
prev.remove();
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1070
1254
|
if (rsc) {
|
|
1071
1255
|
rsc.parentElement?.removeChild(rsc);
|
|
1072
1256
|
const rscClone = document.createElement("script");
|
|
@@ -1075,12 +1259,30 @@ if (typeof HTMLElement !== "undefined") {
|
|
|
1075
1259
|
document.body.appendChild(rscClone);
|
|
1076
1260
|
let cache;
|
|
1077
1261
|
const RemoteComponentFromReadableStream = ({
|
|
1078
|
-
name
|
|
1262
|
+
name,
|
|
1263
|
+
initial
|
|
1079
1264
|
}) => {
|
|
1080
1265
|
const stream = createRSCStream(name, self[name] ?? [`0:[null]
|
|
1081
1266
|
`]);
|
|
1082
1267
|
const Component = cache ?? // cache the component to avoid reloading the RSC flight data
|
|
1083
1268
|
(cache = createFromReadableStream(stream));
|
|
1269
|
+
(0, import_react.useLayoutEffect)(() => {
|
|
1270
|
+
if (self[name]) {
|
|
1271
|
+
delete self[name];
|
|
1272
|
+
}
|
|
1273
|
+
const rscScript = document.getElementById(`${name}_rsc`);
|
|
1274
|
+
if (rscScript) {
|
|
1275
|
+
rscScript.remove();
|
|
1276
|
+
}
|
|
1277
|
+
doCleanup();
|
|
1278
|
+
applyReset();
|
|
1279
|
+
if (!initial) {
|
|
1280
|
+
attachLinks().catch((e) => {
|
|
1281
|
+
console.error(e);
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
this.isLoading = false;
|
|
1285
|
+
}, [initial, name]);
|
|
1084
1286
|
return Component;
|
|
1085
1287
|
};
|
|
1086
1288
|
if (this.reactRoot) {
|
|
@@ -1090,11 +1292,11 @@ if (typeof HTMLElement !== "undefined") {
|
|
|
1090
1292
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1091
1293
|
RemoteComponentFromReadableStream,
|
|
1092
1294
|
{
|
|
1295
|
+
initial: false,
|
|
1093
1296
|
name: this.name ?? "__vercel_remote_component"
|
|
1094
1297
|
}
|
|
1095
1298
|
)
|
|
1096
1299
|
);
|
|
1097
|
-
this.isLoading = false;
|
|
1098
1300
|
});
|
|
1099
1301
|
return;
|
|
1100
1302
|
}
|
|
@@ -1105,6 +1307,7 @@ if (typeof HTMLElement !== "undefined") {
|
|
|
1105
1307
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1106
1308
|
RemoteComponentFromReadableStream,
|
|
1107
1309
|
{
|
|
1310
|
+
initial: true,
|
|
1108
1311
|
name: this.name ?? "__vercel_remote_component"
|
|
1109
1312
|
}
|
|
1110
1313
|
)
|
|
@@ -1116,12 +1319,24 @@ if (typeof HTMLElement !== "undefined") {
|
|
|
1116
1319
|
this.root
|
|
1117
1320
|
);
|
|
1118
1321
|
if (Component) {
|
|
1322
|
+
const RemoteComponentFromNext = ((NextApp, NextComponent, remoteComponent = this) => function RemoteComponentNext({ initial }) {
|
|
1323
|
+
(0, import_react.useLayoutEffect)(() => {
|
|
1324
|
+
doCleanup();
|
|
1325
|
+
if (!initial) {
|
|
1326
|
+
applyReset();
|
|
1327
|
+
attachLinks().catch((e) => {
|
|
1328
|
+
console.error(e);
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
1331
|
+
remoteComponent.isLoading = false;
|
|
1332
|
+
}, [initial]);
|
|
1333
|
+
return NextApp ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(NextApp, { Component: NextComponent, ...nextData.props }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(NextComponent, { ...nextData.props });
|
|
1334
|
+
})(App, Component, this);
|
|
1119
1335
|
if (this.reactRoot) {
|
|
1120
1336
|
const root = this.reactRoot;
|
|
1121
1337
|
(0, import_react.startTransition)(() => {
|
|
1122
|
-
root.render(
|
|
1123
|
-
|
|
1124
|
-
);
|
|
1338
|
+
root.render(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RemoteComponentFromNext, { initial: false }));
|
|
1339
|
+
doCleanup();
|
|
1125
1340
|
this.isLoading = false;
|
|
1126
1341
|
});
|
|
1127
1342
|
return;
|
|
@@ -1130,11 +1345,11 @@ if (typeof HTMLElement !== "undefined") {
|
|
|
1130
1345
|
// hydrateRoot expects a document or element, but it works for the shadow DOM too
|
|
1131
1346
|
// @ts-expect-error support for shadow DOM
|
|
1132
1347
|
this.root,
|
|
1133
|
-
|
|
1348
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RemoteComponentFromNext, { initial: true })
|
|
1134
1349
|
);
|
|
1135
1350
|
}
|
|
1136
1351
|
if (this.fouc) {
|
|
1137
|
-
this.root
|
|
1352
|
+
this.root.removeChild(this.fouc);
|
|
1138
1353
|
}
|
|
1139
1354
|
}
|
|
1140
1355
|
this.isLoading = false;
|