remote-components 0.1.0 → 0.1.2
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/{component-loader-76eb1b8b.d.ts → component-loader-21865da3.d.ts} +140 -16
- package/dist/host-config-58cdccea.d.ts +87 -0
- package/dist/html/host.cjs +294 -162
- package/dist/html/host.cjs.map +1 -1
- package/dist/html/host.js +294 -162
- package/dist/html/host.js.map +1 -1
- package/dist/internal/next/host/app-router-client.cjs +9 -7
- package/dist/internal/next/host/app-router-client.cjs.map +1 -1
- package/dist/internal/next/host/app-router-client.d.ts +32 -19
- package/dist/internal/next/host/app-router-client.js +9 -7
- package/dist/internal/next/host/app-router-client.js.map +1 -1
- package/dist/internal/next/remote/render-server.cjs.map +1 -1
- package/dist/internal/next/remote/render-server.d.ts +13 -14
- package/dist/internal/next/remote/render-server.js.map +1 -1
- package/dist/internal/shared/client/proxy-through-host.cjs +15 -1
- package/dist/internal/shared/client/proxy-through-host.cjs.map +1 -1
- package/dist/internal/shared/client/proxy-through-host.d.ts +5 -0
- package/dist/internal/shared/client/proxy-through-host.js +15 -1
- package/dist/internal/shared/client/proxy-through-host.js.map +1 -1
- package/dist/internal/shared/client/remote-component.cjs.map +1 -1
- package/dist/internal/shared/client/remote-component.d.ts +2 -2
- package/dist/internal/shared/client/remote-component.js.map +1 -1
- package/dist/internal/shared/contract/host-state.cjs +38 -0
- package/dist/internal/shared/contract/host-state.cjs.map +1 -0
- package/dist/internal/shared/contract/host-state.d.ts +53 -0
- package/dist/internal/shared/contract/host-state.js +14 -0
- package/dist/internal/shared/contract/host-state.js.map +1 -0
- package/dist/internal/shared/contract/resolve-name-from-src.cjs +40 -0
- package/dist/internal/shared/contract/resolve-name-from-src.cjs.map +1 -0
- package/dist/internal/shared/contract/resolve-name-from-src.d.ts +13 -0
- package/dist/internal/shared/contract/resolve-name-from-src.js +16 -0
- package/dist/internal/shared/contract/resolve-name-from-src.js.map +1 -0
- package/dist/internal/shared/ssr/dom-flight.d.ts +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.cjs.map +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.d.ts +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.js.map +1 -1
- package/dist/internal/shared/ssr/fetch-with-hooks.d.ts +1 -1
- package/dist/next/host/app-router-server.cjs.map +1 -1
- package/dist/next/host/app-router-server.d.ts +11 -41
- package/dist/next/host/app-router-server.js.map +1 -1
- package/dist/next/host/client/index.cjs +203 -95
- package/dist/next/host/client/index.cjs.map +1 -1
- package/dist/next/host/client/index.d.ts +1 -1
- package/dist/next/host/client/index.js +203 -95
- package/dist/next/host/client/index.js.map +1 -1
- package/dist/next/host/pages-router-client.cjs.map +1 -1
- package/dist/next/host/pages-router-client.d.ts +13 -36
- package/dist/next/host/pages-router-client.js.map +1 -1
- package/dist/next/host/pages-router-server.cjs.map +1 -1
- package/dist/next/host/pages-router-server.d.ts +17 -42
- package/dist/next/host/pages-router-server.js.map +1 -1
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.ts +13 -39
- package/dist/next/index.js.map +1 -1
- package/dist/next/remote/server.d.ts +4 -0
- package/dist/react/index.cjs +203 -95
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.ts +12 -49
- package/dist/react/index.js +203 -95
- package/dist/react/index.js.map +1 -1
- package/dist/{types-cbe44b51.d.ts → types-2b26a246.d.ts} +23 -6
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import * as react from 'react';
|
|
|
3
3
|
import { RemoteComponentProps } from '../../../react/index.js';
|
|
4
4
|
export { RemoteComponentsProvider } from '../../../react/index.js';
|
|
5
5
|
import '../../../proxy-through-host-a676a522.js';
|
|
6
|
-
import '../../../component-loader-
|
|
6
|
+
import '../../../component-loader-21865da3.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* RemoteComponent - Client-side component for rendering remote components
|
|
@@ -185,6 +185,122 @@ Docs: ${CORS_DOCS_URL}`
|
|
|
185
185
|
);
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
// src/shared/utils/index.ts
|
|
189
|
+
function escapeString(str) {
|
|
190
|
+
return str.replace(/[^a-z0-9]/g, "_");
|
|
191
|
+
}
|
|
192
|
+
var attrToProp = {
|
|
193
|
+
fetchpriority: "fetchPriority",
|
|
194
|
+
crossorigin: "crossOrigin",
|
|
195
|
+
imagesrcset: "imageSrcSet",
|
|
196
|
+
imagesizes: "imageSizes",
|
|
197
|
+
srcset: "srcSet"
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
// src/shared/client/const.ts
|
|
201
|
+
var DEFAULT_ROUTE = "/";
|
|
202
|
+
var RUNTIME_WEBPACK = "webpack";
|
|
203
|
+
var RUNTIME_TURBOPACK = "turbopack";
|
|
204
|
+
var RUNTIME_SCRIPT = "script";
|
|
205
|
+
var REMOTE_COMPONENT_REGEX = /(?<prefix>.*?)\[(?<bundle>[^\]]+)\](?:%20| )(?<id>.+)/;
|
|
206
|
+
function getBundleKey(bundle) {
|
|
207
|
+
return escapeString(bundle);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// src/shared/client/parse-remote-html.ts
|
|
211
|
+
function validateSingleComponent(doc, name, url) {
|
|
212
|
+
if (doc.querySelectorAll("div[data-bundle][data-route]").length > 1 && !doc.querySelector(`div[data-bundle][data-route][id^="${name}"]`) || doc.querySelectorAll("remote-component:not([src])").length > 1 && !doc.querySelector(`remote-component[name="${name}"]`)) {
|
|
213
|
+
throw multipleRemoteComponentsError(url);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function findComponentElement(doc, name) {
|
|
217
|
+
return doc.querySelector(`div[data-bundle][data-route][id^="${name}"]`) ?? doc.querySelector("div[data-bundle][data-route]") ?? doc.querySelector("div#__next") ?? doc.querySelector(`remote-component[name="${name}"]:not([src])`) ?? doc.querySelector("remote-component:not([src])");
|
|
218
|
+
}
|
|
219
|
+
function parseNextData(doc) {
|
|
220
|
+
return JSON.parse(
|
|
221
|
+
(doc.querySelector("#__NEXT_DATA__") ?? doc.querySelector("#__REMOTE_NEXT_DATA__"))?.textContent ?? "null"
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
function resolveComponentName(component, nextData, fallbackName) {
|
|
225
|
+
const isRemoteComponent = component?.tagName.toLowerCase() === "remote-component";
|
|
226
|
+
const name = component?.getAttribute("id")?.replace(/_ssr$/, "") || isRemoteComponent && component?.getAttribute("name") || (nextData ? "__next" : fallbackName);
|
|
227
|
+
return { name, isRemoteComponent };
|
|
228
|
+
}
|
|
229
|
+
function extractComponentMetadata(component, nextData, name, url) {
|
|
230
|
+
return {
|
|
231
|
+
name,
|
|
232
|
+
bundle: component?.getAttribute("data-bundle") || nextData?.props.__REMOTE_COMPONENT__?.bundle || "default",
|
|
233
|
+
route: component?.getAttribute("data-route") ?? nextData?.page ?? (url.pathname || DEFAULT_ROUTE),
|
|
234
|
+
runtime: component?.getAttribute("data-runtime") ?? (nextData?.props.__REMOTE_COMPONENT__?.runtime || RUNTIME_SCRIPT)
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
function extractRemoteShared(doc, name, nextData) {
|
|
238
|
+
const remoteSharedEl = doc.querySelector(
|
|
239
|
+
`#${name}_shared[data-remote-components-shared]`
|
|
240
|
+
);
|
|
241
|
+
const remoteShared = nextData?.props.__REMOTE_COMPONENT__?.shared ?? (JSON.parse(remoteSharedEl?.textContent ?? "{}") ?? {});
|
|
242
|
+
remoteSharedEl?.remove();
|
|
243
|
+
return remoteShared;
|
|
244
|
+
}
|
|
245
|
+
function validateComponentFound(component, rsc, nextData, isRemoteComponent, url, name) {
|
|
246
|
+
if (!component || !(rsc || nextData || isRemoteComponent)) {
|
|
247
|
+
throw new RemoteComponentsError(
|
|
248
|
+
`Remote Component not found on ${url}.${name !== "__vercel_remote_component" ? ` The name for the <RemoteComponent> is "${name}". Check <RemoteComponent> usage.` : ""} Did you forget to wrap the content in <RemoteComponent>?`
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
function extractLinks(doc, component) {
|
|
253
|
+
return Array.from(doc.querySelectorAll("link[href]")).filter(
|
|
254
|
+
(link) => !component.contains(link)
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
function extractScripts(doc, component, isRemoteComponent) {
|
|
258
|
+
return Array.from(
|
|
259
|
+
(isRemoteComponent ? component : doc).querySelectorAll(
|
|
260
|
+
"script[src],script[data-src]"
|
|
261
|
+
)
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
function parseRemoteComponentDocument(doc, name, url) {
|
|
265
|
+
validateSingleComponent(doc, name, url.href);
|
|
266
|
+
const component = findComponentElement(doc, name);
|
|
267
|
+
const nextData = parseNextData(doc);
|
|
268
|
+
const { name: resolvedName, isRemoteComponent } = resolveComponentName(
|
|
269
|
+
component,
|
|
270
|
+
nextData,
|
|
271
|
+
name
|
|
272
|
+
);
|
|
273
|
+
const rsc = doc.querySelector(`#${resolvedName}_rsc`);
|
|
274
|
+
const metadata = extractComponentMetadata(
|
|
275
|
+
component,
|
|
276
|
+
nextData,
|
|
277
|
+
resolvedName,
|
|
278
|
+
url
|
|
279
|
+
);
|
|
280
|
+
const remoteShared = extractRemoteShared(doc, resolvedName, nextData);
|
|
281
|
+
validateComponentFound(
|
|
282
|
+
component,
|
|
283
|
+
rsc,
|
|
284
|
+
nextData,
|
|
285
|
+
isRemoteComponent,
|
|
286
|
+
url.href,
|
|
287
|
+
resolvedName
|
|
288
|
+
);
|
|
289
|
+
const links = extractLinks(doc, component);
|
|
290
|
+
const scripts = extractScripts(doc, component, isRemoteComponent);
|
|
291
|
+
return {
|
|
292
|
+
component,
|
|
293
|
+
name: resolvedName,
|
|
294
|
+
isRemoteComponent,
|
|
295
|
+
metadata,
|
|
296
|
+
nextData,
|
|
297
|
+
rsc,
|
|
298
|
+
remoteShared,
|
|
299
|
+
links,
|
|
300
|
+
scripts
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
188
304
|
// src/shared/utils/logger.ts
|
|
189
305
|
var PREFIX = "remote-components";
|
|
190
306
|
var DEBUG = typeof window !== "undefined" && localStorage.getItem("RC_DEBUG") === "true";
|
|
@@ -700,28 +816,6 @@ async function loadScripts(scripts, resolveClientUrl) {
|
|
|
700
816
|
);
|
|
701
817
|
}
|
|
702
818
|
|
|
703
|
-
// src/shared/utils/index.ts
|
|
704
|
-
function escapeString(str) {
|
|
705
|
-
return str.replace(/[^a-z0-9]/g, "_");
|
|
706
|
-
}
|
|
707
|
-
var attrToProp = {
|
|
708
|
-
fetchpriority: "fetchPriority",
|
|
709
|
-
crossorigin: "crossOrigin",
|
|
710
|
-
imagesrcset: "imageSrcSet",
|
|
711
|
-
imagesizes: "imageSizes",
|
|
712
|
-
srcset: "srcSet"
|
|
713
|
-
};
|
|
714
|
-
|
|
715
|
-
// src/shared/client/const.ts
|
|
716
|
-
var DEFAULT_ROUTE = "/";
|
|
717
|
-
var RUNTIME_WEBPACK = "webpack";
|
|
718
|
-
var RUNTIME_TURBOPACK = "turbopack";
|
|
719
|
-
var RUNTIME_SCRIPT = "script";
|
|
720
|
-
var REMOTE_COMPONENT_REGEX = /(?<prefix>.*?)\[(?<bundle>[^\]]+)\](?:%20| )(?<id>.+)/;
|
|
721
|
-
function getBundleKey(bundle) {
|
|
722
|
-
return escapeString(bundle);
|
|
723
|
-
}
|
|
724
|
-
|
|
725
819
|
// src/shared/client/turbopack-patterns.ts
|
|
726
820
|
var REMOTE_SHARED_MARKER_RE = /(?:self|[a-z])\.TURBOPACK_REMOTE_SHARED/;
|
|
727
821
|
var REMOTE_SHARED_ASSIGNMENT_RE = /\.TURBOPACK_REMOTE_SHARED=await (?:__turbopack_context__|e)\.A\((?<sharedModuleId>[0-9]+)\)/;
|
|
@@ -1522,7 +1616,21 @@ function loadNextPagesComponent(bundle, route, nextData, name, container) {
|
|
|
1522
1616
|
|
|
1523
1617
|
// src/shared/client/proxy-through-host.ts
|
|
1524
1618
|
function withRemoteSrc(resolveClientUrl, remoteSrc) {
|
|
1525
|
-
|
|
1619
|
+
const remoteOrigin = parseOrigin(remoteSrc);
|
|
1620
|
+
return (url) => {
|
|
1621
|
+
const urlOrigin = parseOrigin(url);
|
|
1622
|
+
if (remoteOrigin && urlOrigin && urlOrigin !== remoteOrigin) {
|
|
1623
|
+
return void 0;
|
|
1624
|
+
}
|
|
1625
|
+
return resolveClientUrl(remoteSrc, url);
|
|
1626
|
+
};
|
|
1627
|
+
}
|
|
1628
|
+
function parseOrigin(url) {
|
|
1629
|
+
try {
|
|
1630
|
+
return new URL(url).origin;
|
|
1631
|
+
} catch {
|
|
1632
|
+
return void 0;
|
|
1633
|
+
}
|
|
1526
1634
|
}
|
|
1527
1635
|
|
|
1528
1636
|
// src/shared/client/set-attributes-from-props.ts
|
|
@@ -1717,6 +1825,32 @@ async function loadStaticRemoteComponent(scripts, url, resolveClientUrl) {
|
|
|
1717
1825
|
);
|
|
1718
1826
|
}
|
|
1719
1827
|
|
|
1828
|
+
// src/shared/contract/host-state.ts
|
|
1829
|
+
function createHostState() {
|
|
1830
|
+
return {
|
|
1831
|
+
stage: "idle",
|
|
1832
|
+
prevSrc: void 0,
|
|
1833
|
+
prevUrl: void 0,
|
|
1834
|
+
prevName: void 0,
|
|
1835
|
+
prevIsRemoteComponent: false,
|
|
1836
|
+
abortController: void 0
|
|
1837
|
+
};
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
// src/shared/contract/resolve-name-from-src.ts
|
|
1841
|
+
function resolveNameFromSrc(src, defaultName) {
|
|
1842
|
+
if (!src) {
|
|
1843
|
+
return defaultName;
|
|
1844
|
+
}
|
|
1845
|
+
const hash = typeof src === "string" ? src : src.hash;
|
|
1846
|
+
const hashIndex = hash.indexOf("#");
|
|
1847
|
+
if (hashIndex < 0) {
|
|
1848
|
+
return defaultName;
|
|
1849
|
+
}
|
|
1850
|
+
const name = hash.slice(hashIndex + 1);
|
|
1851
|
+
return name || defaultName;
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1720
1854
|
// src/shared/ssr/fetch-headers.ts
|
|
1721
1855
|
function remoteFetchHeaders() {
|
|
1722
1856
|
return {
|
|
@@ -1844,7 +1978,7 @@ function useShadowRoot({
|
|
|
1844
1978
|
return { shadowRoot, shadowRootContainerRef };
|
|
1845
1979
|
}
|
|
1846
1980
|
|
|
1847
|
-
// src/react/utils/
|
|
1981
|
+
// src/react/utils/extract-remote-html.ts
|
|
1848
1982
|
var DUMMY_FALLBACK = "http://remote-components-dummy-fallback";
|
|
1849
1983
|
function getRemoteComponentHtml(html) {
|
|
1850
1984
|
if (typeof document === "undefined")
|
|
@@ -1888,20 +2022,10 @@ function RemoteComponent({
|
|
|
1888
2022
|
resolveClientUrl: _resolveClientUrl
|
|
1889
2023
|
}) {
|
|
1890
2024
|
const instanceId = useId();
|
|
1891
|
-
const name = useMemo2(
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
typeof document !== "undefined" ? location.href : DUMMY_FALLBACK
|
|
1896
|
-
);
|
|
1897
|
-
if (url2.hash) {
|
|
1898
|
-
return url2.hash.slice(1);
|
|
1899
|
-
}
|
|
1900
|
-
} else if (typeof src === "object" && "hash" in src && src.hash) {
|
|
1901
|
-
return src.hash.slice(1) || nameProp;
|
|
1902
|
-
}
|
|
1903
|
-
return nameProp;
|
|
1904
|
-
}, [src, nameProp]);
|
|
2025
|
+
const name = useMemo2(
|
|
2026
|
+
() => resolveNameFromSrc(src, nameProp),
|
|
2027
|
+
[src, nameProp]
|
|
2028
|
+
);
|
|
1905
2029
|
const [data, setData] = useState2(null);
|
|
1906
2030
|
const url = useMemo2(() => getClientOrServerUrl(src, DUMMY_FALLBACK), [src]);
|
|
1907
2031
|
const resolveClientUrl = useResolveClientUrl(_resolveClientUrl, url.href);
|
|
@@ -1934,13 +2058,10 @@ function RemoteComponent({
|
|
|
1934
2058
|
return elements;
|
|
1935
2059
|
})() : []
|
|
1936
2060
|
);
|
|
1937
|
-
const
|
|
2061
|
+
const hostStateRef = useRef2(createHostState());
|
|
1938
2062
|
const componentHydrationHtml = useRef2(null);
|
|
1939
|
-
const prevIsRemoteComponentRef = useRef2(false);
|
|
1940
|
-
const prevUrlRef = useRef2(null);
|
|
1941
2063
|
const prevRemoteComponentContainerRef = useRef2(null);
|
|
1942
2064
|
const unmountRef = useRef2(null);
|
|
1943
|
-
const prevNameRef = useRef2(void 0);
|
|
1944
2065
|
useLayoutEffect2(() => {
|
|
1945
2066
|
const shadowRootKey = `__remote_components_shadowroot_${keySuffix}`;
|
|
1946
2067
|
return () => {
|
|
@@ -1979,14 +2100,18 @@ function RemoteComponent({
|
|
|
1979
2100
|
}
|
|
1980
2101
|
}, [shadowRoot, remoteComponent, name]);
|
|
1981
2102
|
useEffect(() => {
|
|
1982
|
-
if (src && src !==
|
|
1983
|
-
const previousSrc =
|
|
1984
|
-
const previousName =
|
|
1985
|
-
|
|
2103
|
+
if (src && src !== hostStateRef.current.prevSrc) {
|
|
2104
|
+
const previousSrc = hostStateRef.current.prevSrc;
|
|
2105
|
+
const previousName = hostStateRef.current.prevName;
|
|
2106
|
+
hostStateRef.current.prevSrc = src;
|
|
1986
2107
|
if (previousSrc !== null) {
|
|
1987
2108
|
htmlRef.current = null;
|
|
1988
2109
|
}
|
|
2110
|
+
hostStateRef.current.abortController?.abort();
|
|
2111
|
+
hostStateRef.current.abortController = new AbortController();
|
|
2112
|
+
const { signal } = hostStateRef.current.abortController;
|
|
1989
2113
|
onBeforeLoad?.(src);
|
|
2114
|
+
hostStateRef.current.stage = "loading";
|
|
1990
2115
|
startTransition(async () => {
|
|
1991
2116
|
try {
|
|
1992
2117
|
let html = getRemoteComponentHtml(
|
|
@@ -2000,59 +2125,41 @@ function RemoteComponent({
|
|
|
2000
2125
|
resolveClientUrl?.(url.href) ?? url.href,
|
|
2001
2126
|
location.href
|
|
2002
2127
|
);
|
|
2003
|
-
const abortController = new AbortController();
|
|
2004
2128
|
const res = await fetchWithHooks(resolvedUrl, fetchInit, {
|
|
2005
2129
|
onRequest,
|
|
2006
2130
|
onResponse,
|
|
2007
|
-
abortController
|
|
2131
|
+
abortController: hostStateRef.current.abortController
|
|
2008
2132
|
});
|
|
2009
2133
|
if (!res || !res.ok) {
|
|
2010
2134
|
throw await errorFromFailedFetch(url.href, resolvedUrl, res);
|
|
2011
2135
|
}
|
|
2012
2136
|
const remoteHtml = await res.text();
|
|
2137
|
+
if (signal.aborted)
|
|
2138
|
+
return;
|
|
2013
2139
|
htmlRef.current = remoteHtml;
|
|
2014
2140
|
html = getRemoteComponentHtml(remoteHtml);
|
|
2015
2141
|
}
|
|
2142
|
+
if (signal.aborted)
|
|
2143
|
+
return;
|
|
2016
2144
|
const parser = new DOMParser();
|
|
2017
2145
|
const doc = parser.parseFromString(html, "text/html");
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
) || doc.querySelectorAll("remote-component:not([src])").length > 1 && !doc.querySelector(`remote-component[name="${name}"]`)) {
|
|
2021
|
-
throw multipleRemoteComponentsError(url.href);
|
|
2022
|
-
}
|
|
2023
|
-
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
|
|
2024
|
-
doc.querySelector("div[data-bundle][data-route]") ?? // fallback to Next.js Pages Router
|
|
2025
|
-
doc.querySelector("div#__next") ?? // fallback to the remote-component web component
|
|
2026
|
-
doc.querySelector(`remote-component[name="${name}"]:not([src])`) ?? doc.querySelector("remote-component:not([src])");
|
|
2027
|
-
const nextData = JSON.parse(
|
|
2028
|
-
(doc.querySelector("#__NEXT_DATA__") ?? doc.querySelector("#__REMOTE_NEXT_DATA__"))?.textContent ?? "null"
|
|
2029
|
-
);
|
|
2030
|
-
const remoteName = component?.getAttribute("id")?.replace(/_ssr$/, "") || (nextData ? "__next" : name);
|
|
2031
|
-
const rsc = doc.querySelector(`#${remoteName}_rsc`);
|
|
2032
|
-
const bundle = component?.getAttribute("data-bundle") || nextData?.props.__REMOTE_COMPONENT__?.bundle || "default";
|
|
2033
|
-
const isRemoteComponent = component?.tagName.toLowerCase() === "remote-component";
|
|
2034
|
-
const metadata = {
|
|
2146
|
+
const {
|
|
2147
|
+
component,
|
|
2035
2148
|
name: remoteName,
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
if (!component || !(rsc || nextData || isRemoteComponent)) {
|
|
2046
|
-
throw new RemoteComponentsError(
|
|
2047
|
-
`Remote Component not found on ${url.href}.${remoteName !== "__vercel_remote_component" ? `The name for the <RemoteComponent> is "${remoteName}". Check <RemoteComponent> usage.` : ""} Did you forget to wrap the content in <RemoteComponent>?`
|
|
2048
|
-
);
|
|
2049
|
-
}
|
|
2050
|
-
if (prevIsRemoteComponentRef.current) {
|
|
2149
|
+
isRemoteComponent,
|
|
2150
|
+
metadata,
|
|
2151
|
+
nextData,
|
|
2152
|
+
rsc,
|
|
2153
|
+
remoteShared,
|
|
2154
|
+
links: linkElements,
|
|
2155
|
+
scripts: scriptElements
|
|
2156
|
+
} = parseRemoteComponentDocument(doc, name, url);
|
|
2157
|
+
if (hostStateRef.current.prevIsRemoteComponent) {
|
|
2051
2158
|
if (shadowRoot) {
|
|
2052
2159
|
shadowRoot.innerHTML = "";
|
|
2053
2160
|
}
|
|
2054
2161
|
const self = globalThis;
|
|
2055
|
-
const prevUrl =
|
|
2162
|
+
const prevUrl = hostStateRef.current.prevUrl;
|
|
2056
2163
|
if (prevUrl && self.__remote_script_entrypoint_unmount__?.[prevUrl.href]) {
|
|
2057
2164
|
const unmountPromises = Promise.all(
|
|
2058
2165
|
Array.from(unmountRef.current ?? []).map(
|
|
@@ -2065,15 +2172,11 @@ function RemoteComponent({
|
|
|
2065
2172
|
await unmountPromises;
|
|
2066
2173
|
}
|
|
2067
2174
|
}
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2175
|
+
hostStateRef.current.prevIsRemoteComponent = isRemoteComponent;
|
|
2176
|
+
hostStateRef.current.prevUrl = url;
|
|
2177
|
+
hostStateRef.current.prevName = remoteName;
|
|
2071
2178
|
applyOriginToNodes(doc, url, resolveClientUrl);
|
|
2072
|
-
const links =
|
|
2073
|
-
doc.querySelectorAll("link[href]")
|
|
2074
|
-
).filter((link) => {
|
|
2075
|
-
return !component.contains(link);
|
|
2076
|
-
}).map((link) => ({
|
|
2179
|
+
const links = linkElements.map((link) => ({
|
|
2077
2180
|
href: new URL(link.getAttribute("href") ?? link.href, url).href,
|
|
2078
2181
|
...link.getAttributeNames().reduce((acc, key) => {
|
|
2079
2182
|
if (key !== "href") {
|
|
@@ -2082,7 +2185,7 @@ function RemoteComponent({
|
|
|
2082
2185
|
return acc;
|
|
2083
2186
|
}, {})
|
|
2084
2187
|
}));
|
|
2085
|
-
const scripts =
|
|
2188
|
+
const scripts = scriptElements;
|
|
2086
2189
|
const inlineScripts = (isRemoteComponent ? component : doc).querySelectorAll(
|
|
2087
2190
|
"script:not([src]):not([data-src]):not([id*='_rsc']):not([id='__NEXT_DATA__']):not([id='__REMOTE_NEXT_DATA__'])"
|
|
2088
2191
|
);
|
|
@@ -2173,7 +2276,7 @@ function RemoteComponent({
|
|
|
2173
2276
|
);
|
|
2174
2277
|
}
|
|
2175
2278
|
if (isRemoteComponent) {
|
|
2176
|
-
if (previousSrc !==
|
|
2279
|
+
if (previousSrc !== void 0) {
|
|
2177
2280
|
onChange?.({
|
|
2178
2281
|
previousSrc,
|
|
2179
2282
|
nextSrc: src,
|
|
@@ -2225,12 +2328,13 @@ function RemoteComponent({
|
|
|
2225
2328
|
);
|
|
2226
2329
|
onLoad?.(src);
|
|
2227
2330
|
}
|
|
2331
|
+
hostStateRef.current.stage = "loaded";
|
|
2228
2332
|
} else {
|
|
2229
2333
|
const result = await loadRemoteComponent({
|
|
2230
2334
|
url,
|
|
2231
2335
|
name: remoteName,
|
|
2232
2336
|
rscName,
|
|
2233
|
-
bundle,
|
|
2337
|
+
bundle: metadata.bundle,
|
|
2234
2338
|
route: metadata.route,
|
|
2235
2339
|
runtime: metadata.runtime,
|
|
2236
2340
|
data: newData.data,
|
|
@@ -2265,7 +2369,7 @@ function RemoteComponent({
|
|
|
2265
2369
|
rsc.remove();
|
|
2266
2370
|
}
|
|
2267
2371
|
setData(newData);
|
|
2268
|
-
if (previousSrc !==
|
|
2372
|
+
if (previousSrc !== void 0) {
|
|
2269
2373
|
onChange?.({
|
|
2270
2374
|
previousSrc,
|
|
2271
2375
|
nextSrc: src,
|
|
@@ -2274,17 +2378,21 @@ function RemoteComponent({
|
|
|
2274
2378
|
});
|
|
2275
2379
|
}
|
|
2276
2380
|
if (result.error) {
|
|
2381
|
+
hostStateRef.current.stage = "error";
|
|
2277
2382
|
setRemoteComponent(result.error);
|
|
2278
2383
|
onError?.(result.error);
|
|
2279
2384
|
} else {
|
|
2385
|
+
hostStateRef.current.stage = "loaded";
|
|
2280
2386
|
setRemoteComponent(result.component);
|
|
2281
2387
|
onLoad?.(src);
|
|
2282
2388
|
}
|
|
2283
2389
|
}
|
|
2284
2390
|
} catch (error) {
|
|
2285
2391
|
if (isAbortError(error)) {
|
|
2392
|
+
hostStateRef.current.stage = "idle";
|
|
2286
2393
|
return;
|
|
2287
2394
|
}
|
|
2395
|
+
hostStateRef.current.stage = "error";
|
|
2288
2396
|
setRemoteComponent(error);
|
|
2289
2397
|
onError?.(error);
|
|
2290
2398
|
}
|
|
@@ -2315,7 +2423,7 @@ function RemoteComponent({
|
|
|
2315
2423
|
name: data?.name || name,
|
|
2316
2424
|
bundle: data?.bundle || "default",
|
|
2317
2425
|
route: data?.route || DEFAULT_ROUTE,
|
|
2318
|
-
runtime:
|
|
2426
|
+
runtime: hostStateRef.current.prevIsRemoteComponent ? RUNTIME_SCRIPT : data?.runtime || RUNTIME_WEBPACK
|
|
2319
2427
|
}) });
|
|
2320
2428
|
const resetStyle = reset ? /* @__PURE__ */ jsx2("style", { "data-remote-components-reset": "react", children: `:host { all: initial; }` }) : null;
|
|
2321
2429
|
const linksToRender = data?.links?.map((link) => /* @__PURE__ */ createElement2(
|
|
@@ -2334,7 +2442,7 @@ function RemoteComponent({
|
|
|
2334
2442
|
if (componentHydrationHtml.current && shadowRoot && !shadowRoot.innerHTML) {
|
|
2335
2443
|
shadowRoot.innerHTML = componentHydrationHtml.current;
|
|
2336
2444
|
componentHydrationHtml.current = null;
|
|
2337
|
-
if (
|
|
2445
|
+
if (hostStateRef.current.prevIsRemoteComponent) {
|
|
2338
2446
|
loadStaticRemoteComponent(
|
|
2339
2447
|
Array.from(shadowRoot.querySelectorAll("script")),
|
|
2340
2448
|
url,
|