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.
Files changed (69) hide show
  1. package/dist/html/host.cjs +297 -82
  2. package/dist/html/host.cjs.map +1 -1
  3. package/dist/html/host.js +300 -82
  4. package/dist/html/host.js.map +1 -1
  5. package/dist/internal/next/host/app-router-client.cjs +176 -70
  6. package/dist/internal/next/host/app-router-client.cjs.map +1 -1
  7. package/dist/internal/next/host/app-router-client.js +184 -71
  8. package/dist/internal/next/host/app-router-client.js.map +1 -1
  9. package/dist/internal/next/host/app-router-compat.cjs +114 -0
  10. package/dist/internal/next/host/app-router-compat.cjs.map +1 -0
  11. package/dist/internal/next/host/app-router-compat.d.ts +31 -0
  12. package/dist/internal/next/host/app-router-compat.js +79 -0
  13. package/dist/internal/next/host/app-router-compat.js.map +1 -0
  14. package/dist/internal/next/remote/render-client.cjs +10 -2
  15. package/dist/internal/next/remote/render-client.cjs.map +1 -1
  16. package/dist/internal/next/remote/render-client.js +10 -2
  17. package/dist/internal/next/remote/render-client.js.map +1 -1
  18. package/dist/internal/shared/client/apply-origin.cjs +61 -0
  19. package/dist/internal/shared/client/apply-origin.cjs.map +1 -0
  20. package/dist/internal/shared/client/apply-origin.d.ts +3 -0
  21. package/dist/internal/shared/client/apply-origin.js +37 -0
  22. package/dist/internal/shared/client/apply-origin.js.map +1 -0
  23. package/dist/internal/shared/client/polyfill.cjs +149 -0
  24. package/dist/internal/shared/client/polyfill.cjs.map +1 -0
  25. package/dist/internal/shared/client/polyfill.d.ts +6 -0
  26. package/dist/internal/shared/client/polyfill.js +124 -0
  27. package/dist/internal/shared/client/polyfill.js.map +1 -0
  28. package/dist/internal/shared/client/remote-component.cjs +3 -3
  29. package/dist/internal/shared/client/remote-component.cjs.map +1 -1
  30. package/dist/internal/shared/client/remote-component.d.ts +1 -1
  31. package/dist/internal/shared/client/remote-component.js +3 -3
  32. package/dist/internal/shared/client/remote-component.js.map +1 -1
  33. package/dist/internal/shared/ssr/dom-flight.cjs +40 -0
  34. package/dist/internal/shared/ssr/dom-flight.cjs.map +1 -1
  35. package/dist/internal/shared/ssr/dom-flight.js +40 -0
  36. package/dist/internal/shared/ssr/dom-flight.js.map +1 -1
  37. package/dist/internal/shared/ssr/fetch-remote-component.cjs +1 -1
  38. package/dist/internal/shared/ssr/fetch-remote-component.cjs.map +1 -1
  39. package/dist/internal/shared/ssr/fetch-remote-component.d.ts +6 -0
  40. package/dist/internal/shared/ssr/fetch-remote-component.js +1 -1
  41. package/dist/internal/shared/ssr/fetch-remote-component.js.map +1 -1
  42. package/dist/next/config.cjs +50 -28
  43. package/dist/next/config.cjs.map +1 -1
  44. package/dist/next/config.js +50 -28
  45. package/dist/next/config.js.map +1 -1
  46. package/dist/next/host/client/index.cjs +16 -1
  47. package/dist/next/host/client/index.cjs.map +1 -1
  48. package/dist/next/host/client/index.js +16 -1
  49. package/dist/next/host/client/index.js.map +1 -1
  50. package/dist/next/host/pages-router-server.cjs +27 -13
  51. package/dist/next/host/pages-router-server.cjs.map +1 -1
  52. package/dist/next/host/pages-router-server.js +27 -13
  53. package/dist/next/host/pages-router-server.js.map +1 -1
  54. package/dist/next/middleware.cjs +5 -2
  55. package/dist/next/middleware.cjs.map +1 -1
  56. package/dist/next/middleware.d.ts +1 -0
  57. package/dist/next/middleware.js +5 -2
  58. package/dist/next/middleware.js.map +1 -1
  59. package/dist/next/remote/pages-router.cjs +3 -1
  60. package/dist/next/remote/pages-router.cjs.map +1 -1
  61. package/dist/next/remote/pages-router.d.ts +1 -0
  62. package/dist/next/remote/pages-router.js +3 -1
  63. package/dist/next/remote/pages-router.js.map +1 -1
  64. package/dist/react/index.cjs +203 -159
  65. package/dist/react/index.cjs.map +1 -1
  66. package/dist/react/index.d.ts +1 -1
  67. package/dist/react/index.js +192 -148
  68. package/dist/react/index.js.map +1 -1
  69. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { createElement } from "react";
2
3
  import {
3
4
  useState,
4
5
  useEffect,
@@ -15,11 +16,13 @@ import {
15
16
  RUNTIME_WEBPACK,
16
17
  REMOTE_COMPONENT_REGEX
17
18
  } from "#internal/shared/client/remote-component";
19
+ import { sharedPolyfills } from "#internal/shared/client/polyfill";
20
+ import { applyOriginToNodes } from "#internal/shared/client/apply-origin";
18
21
  function getRemoteComponentHtml(html) {
19
22
  if (typeof document === "undefined")
20
23
  return html;
21
- const temp = document.createElement("div");
22
- temp.innerHTML = html;
24
+ const parser = new DOMParser();
25
+ const temp = parser.parseFromString(html, "text/html");
23
26
  const ssrRemoteComponentContainer = temp.querySelector(
24
27
  'div[id^="__REMOTE_COMPONENT"]'
25
28
  );
@@ -34,6 +37,10 @@ function getRemoteComponentHtml(html) {
34
37
  }
35
38
  return "";
36
39
  }
40
+ const attrToProp = {
41
+ fetchpriority: "fetchPriority",
42
+ crossorigin: "crossOrigin"
43
+ };
37
44
  function RemoteComponent({
38
45
  src,
39
46
  isolate,
@@ -64,18 +71,17 @@ function RemoteComponent({
64
71
  const [shadowRoot, setShadowRoot] = useState(() => {
65
72
  const self = globalThis;
66
73
  const shadowRootKey = `__remote_components_shadowroot_${src ? new URL(src, typeof location !== "undefined" ? location.origin : "http://localhost").href.replace(/[^a-z0-9]/g, "_") : ""}_${(data?.name ?? name).replace(/[^a-z0-9]/g, "_")}`;
67
- const ssrShadowRoot = typeof document !== "undefined" ? document.getElementById(
68
- `shadowroot_${src ? new URL(src, typeof location !== "undefined" ? location.origin : "http://localhost").href.replace(/[^a-z0-9]/g, "_") : ""}_${(data?.name ?? name).replace(/[^a-z0-9]/g, "_")}`
74
+ const ssrShadowRoot = typeof document !== "undefined" ? document.querySelector(
75
+ `[data-remote-component-id="shadowroot_${src ? new URL(src, typeof location !== "undefined" ? location.origin : "http://localhost").href.replace(/[^a-z0-9]/g, "_") : ""}_${(data?.name ?? name).replace(/[^a-z0-9]/g, "_")}"]`
69
76
  )?.shadowRoot ?? self[shadowRootKey] ?? null : null;
70
77
  self[shadowRootKey] = null;
71
78
  return ssrShadowRoot;
72
79
  });
73
80
  const htmlRef = useRef(
74
- typeof document !== "undefined" ? document.getElementById(
75
- `shadowroot_${src ? new URL(src, typeof location !== "undefined" ? location.origin : "http://localhost").href.replace(/[^a-z0-9]/g, "_") : ""}_${(data?.name ?? name).replace(/[^a-z0-9]/g, "_")}`
81
+ typeof document !== "undefined" ? document.querySelector(
82
+ `[data-remote-component-id="shadowroot_${src ? new URL(src, typeof location !== "undefined" ? location.origin : "http://localhost").href.replace(/[^a-z0-9]/g, "_") : ""}_${(data?.name ?? name).replace(/[^a-z0-9]/g, "_")}"]`
76
83
  )?.shadowRoot?.innerHTML ?? document.getElementById(`__REMOTE_COMPONENT${name}`)?.innerHTML ?? document.querySelector(`div[data-bundle][data-route][id^="${name}"]`)?.innerHTML ?? document.querySelector("div[data-bundle][data-route]")?.innerHTML : null
77
84
  );
78
- const ssrHtmlRef = useRef(htmlRef.current);
79
85
  const endTemplateRef = useRef(null);
80
86
  const childrenRef = useRef(
81
87
  typeof document !== "undefined" ? (() => {
@@ -90,6 +96,7 @@ function RemoteComponent({
90
96
  return elements;
91
97
  })() : []
92
98
  );
99
+ const prevSrcRef = useRef(null);
93
100
  useLayoutEffect(() => {
94
101
  if (childrenRef.current.length > 0 && remoteComponent) {
95
102
  childrenRef.current.forEach((el) => {
@@ -98,14 +105,17 @@ function RemoteComponent({
98
105
  childrenRef.current = [];
99
106
  }
100
107
  if (isolate !== false && typeof document !== "undefined" && !shadowRoot) {
108
+ const self = globalThis;
109
+ const shadowRootKey = `__remote_components_shadowroot_${src ? new URL(src, typeof location !== "undefined" ? location.origin : "http://localhost").href.replace(/[^a-z0-9]/g, "_") : ""}_${(data?.name ?? name).replace(/[^a-z0-9]/g, "_")}`;
101
110
  let shadowRootElement = null;
102
- const element = document.getElementById(
103
- `shadowroot_${src ? new URL(src, typeof location !== "undefined" ? location.origin : "http://localhost").href.replace(/[^a-z0-9]/g, "_") : ""}_${(data?.name ?? name).replace(/[^a-z0-9]/g, "_")}`
111
+ const element = document.querySelector(
112
+ `[data-remote-component-id="shadowroot_${src ? new URL(src, typeof location !== "undefined" ? location.origin : "http://localhost").href.replace(/[^a-z0-9]/g, "_") : ""}_${(data?.name ?? name).replace(/[^a-z0-9]/g, "_")}"]`
104
113
  );
105
- shadowRootElement = element?.shadowRoot ?? null;
114
+ shadowRootElement = self[shadowRootKey] ?? element?.shadowRoot ?? null;
106
115
  if (!shadowRootElement && element) {
107
116
  try {
108
117
  shadowRootElement = element.attachShadow({ mode });
118
+ self[shadowRootKey] = shadowRootElement;
109
119
  } catch {
110
120
  }
111
121
  }
@@ -116,7 +126,30 @@ function RemoteComponent({
116
126
  setShadowRoot(shadowRootElement);
117
127
  }
118
128
  }
119
- }, [name, isolate, shadowRoot, remoteComponent, mode]);
129
+ }, [name, isolate, shadowRoot, remoteComponent, mode, src, data]);
130
+ useLayoutEffect(() => {
131
+ if (shadowRoot && remoteComponent) {
132
+ const resetStyles = shadowRoot.querySelectorAll(
133
+ "style[data-remote-components-reset]"
134
+ );
135
+ if (resetStyles.length > 1) {
136
+ resetStyles.forEach((style, index) => {
137
+ if (index > 0) {
138
+ style.remove();
139
+ }
140
+ });
141
+ }
142
+ htmlRef.current = null;
143
+ let el = shadowRoot.childNodes[0] ?? null;
144
+ while (el && (!("id" in el) || el.id !== `${name}_start`)) {
145
+ const nextEl = el.nextSibling;
146
+ if (el.nodeName !== "LINK" && el.nodeName !== "STYLE") {
147
+ el.parentNode?.removeChild(el);
148
+ }
149
+ el = nextEl;
150
+ }
151
+ }
152
+ }, [shadowRoot, remoteComponent, name]);
120
153
  const url = useMemo(() => {
121
154
  if (typeof src !== "string")
122
155
  return new URL(
@@ -130,114 +163,128 @@ function RemoteComponent({
130
163
  }, [src]);
131
164
  useEffect(() => {
132
165
  let mounted = true;
133
- startTransition(async () => {
134
- try {
135
- let html = getRemoteComponentHtml(
136
- htmlRef.current ?? (endTemplateRef.current?.previousElementSibling?.tagName === "div" ? endTemplateRef.current.previousElementSibling.innerHTML : "")
137
- );
138
- if (!html && src) {
139
- const fetchInit = {
140
- method: "GET",
141
- headers: {
142
- Accept: "text/html"
143
- },
144
- credentials
166
+ if (src && src !== prevSrcRef.current) {
167
+ prevSrcRef.current = src;
168
+ startTransition(async () => {
169
+ try {
170
+ let html = getRemoteComponentHtml(
171
+ htmlRef.current ?? (endTemplateRef.current?.previousElementSibling?.tagName === "div" ? endTemplateRef.current.previousElementSibling.innerHTML : "")
172
+ );
173
+ if (!html && src) {
174
+ const fetchInit = {
175
+ method: "GET",
176
+ headers: {
177
+ Accept: "text/html"
178
+ },
179
+ credentials
180
+ };
181
+ const res = await fetch(url, fetchInit);
182
+ if (!res.ok) {
183
+ throw new Error(
184
+ `Failed to fetch remote component "${name}": ${res.status}`
185
+ );
186
+ }
187
+ const remoteHtml = await res.text();
188
+ htmlRef.current = remoteHtml;
189
+ html = getRemoteComponentHtml(remoteHtml);
190
+ }
191
+ const parser = new DOMParser();
192
+ const doc = parser.parseFromString(html, "text/html");
193
+ 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
194
+ doc.querySelector("div[data-bundle][data-route]") ?? // fallback to Next.js Pages Router
195
+ doc.querySelector("div#__next");
196
+ const nextData = JSON.parse(
197
+ (doc.querySelector("#__NEXT_DATA__") ?? doc.querySelector("#__REMOTE_NEXT_DATA__"))?.textContent ?? "null"
198
+ );
199
+ const remoteName = component?.getAttribute("id")?.replace(/_ssr$/, "") || (nextData ? "__next" : name);
200
+ const rsc = doc.querySelector(`#${remoteName}_rsc`);
201
+ const bundle = component?.getAttribute("data-bundle") || nextData?.props.__REMOTE_COMPONENT__?.bundle || "default";
202
+ const metadata = {
203
+ name: remoteName,
204
+ bundle,
205
+ route: component?.getAttribute("data-route") ?? nextData?.page ?? DEFAULT_ROUTE,
206
+ runtime: component?.getAttribute("data-runtime") ?? (nextData?.props.__REMOTE_COMPONENT__?.runtime || RUNTIME_WEBPACK)
145
207
  };
146
- const res = await fetch(url, fetchInit);
147
- if (!res.ok) {
148
- throw new Error(
149
- `Failed to fetch remote component "${name}": ${res.status}`
150
- );
208
+ const remoteSharedEl = doc.querySelector(
209
+ `#${remoteName}_shared[data-remote-components-shared]`
210
+ );
211
+ const remoteShared = nextData?.props.__REMOTE_COMPONENT__?.shared ?? (JSON.parse(remoteSharedEl?.textContent ?? "{}") ?? {});
212
+ remoteSharedEl?.remove();
213
+ if (!component || !(rsc || nextData)) {
214
+ throw new Error(`Failed to find component with id "${remoteName}"`);
151
215
  }
152
- const remoteHtml = await res.text();
153
- htmlRef.current = remoteHtml;
154
- html = getRemoteComponentHtml(remoteHtml);
155
- }
156
- const doc = document.createElement("div");
157
- doc.innerHTML = html;
158
- 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
159
- doc.querySelector("div[data-bundle][data-route]") ?? // fallback to Next.js Pages Router
160
- doc.querySelector("div#__next");
161
- const nextData = JSON.parse(
162
- (doc.querySelector("#__NEXT_DATA__") ?? doc.querySelector("#__REMOTE_NEXT_DATA__"))?.textContent ?? "null"
163
- );
164
- const remoteName = component?.getAttribute("id")?.replace(/_ssr$/, "") || (nextData ? "__next" : name);
165
- const rsc = doc.querySelector(`#${remoteName}_rsc`);
166
- const bundle = component?.getAttribute("data-bundle") || nextData?.props.__REMOTE_COMPONENT__?.bundle || "default";
167
- const metadata = {
168
- name: remoteName,
169
- bundle,
170
- route: component?.getAttribute("data-route") ?? nextData?.page ?? DEFAULT_ROUTE,
171
- runtime: component?.getAttribute("data-runtime") ?? (nextData?.props.__REMOTE_COMPONENT__?.runtime || RUNTIME_WEBPACK)
172
- };
173
- const remoteSharedEl = doc.querySelector(`#${remoteName}_shared`);
174
- const remoteShared = JSON.parse(remoteSharedEl?.textContent ?? "{}") ?? {};
175
- remoteSharedEl?.parentElement?.removeChild(remoteSharedEl);
176
- if (!component || !(rsc || nextData)) {
177
- throw new Error(`Failed to find component with id "${remoteName}"`);
178
- }
179
- const links = Array.from(
180
- doc.querySelectorAll("link[href]")
181
- ).map((link) => ({
182
- rel: link.rel,
183
- href: new URL(link.getAttribute("href") ?? link.href, url).href,
184
- as: link.getAttribute("as") || void 0
185
- }));
186
- const scripts = doc.querySelectorAll(
187
- "script[src],script[data-src]"
188
- );
189
- const inlineScripts = doc.querySelectorAll(
190
- "script:not([src]):not([data-src]):not([id*='_rsc']):not([id='__NEXT_DATA__']):not([id='__REMOTE_NEXT_DATA__'])"
191
- );
192
- const self = globalThis;
193
- const prevNextScripts = self.__next_s;
194
- const nextScripts = [];
195
- self.__next_s = nextScripts;
196
- await Promise.all(
197
- Array.from(inlineScripts).map((script) => {
198
- return new Promise((resolve) => {
199
- if (script.textContent && !script.textContent.includes("self.__next_f=") && !script.textContent.includes("self.__next_f.push")) {
200
- if (!script.getAttribute("type") || script.getAttribute("type") === "text/javascript" || script.getAttribute("type") === "application/javascript") {
201
- const newScript = document.createElement("script");
202
- const blob = new Blob([script.textContent], {
203
- type: "application/javascript"
204
- });
205
- const blobUrl = URL.createObjectURL(blob);
206
- newScript.onload = () => {
207
- resolve(void 0);
208
- URL.revokeObjectURL(blobUrl);
209
- newScript.remove();
210
- };
211
- newScript.onerror = () => {
212
- URL.revokeObjectURL(blobUrl);
213
- newScript.remove();
216
+ applyOriginToNodes(doc, url);
217
+ const links = Array.from(
218
+ doc.querySelectorAll("link[href]")
219
+ ).filter((link) => {
220
+ return !component.contains(link);
221
+ }).map((link) => ({
222
+ href: new URL(link.getAttribute("href") ?? link.href, url).href,
223
+ ...link.getAttributeNames().reduce((acc, key) => {
224
+ if (key !== "href") {
225
+ acc[attrToProp[key] ?? key] = link.getAttribute(key) ?? "";
226
+ }
227
+ return acc;
228
+ }, {})
229
+ }));
230
+ const scripts = doc.querySelectorAll(
231
+ "script[src],script[data-src]"
232
+ );
233
+ const inlineScripts = doc.querySelectorAll(
234
+ "script:not([src]):not([data-src]):not([id*='_rsc']):not([id='__NEXT_DATA__']):not([id='__REMOTE_NEXT_DATA__'])"
235
+ );
236
+ const self = globalThis;
237
+ const prevNextScripts = self.__next_s;
238
+ const nextScripts = [];
239
+ self.__next_s = nextScripts;
240
+ await Promise.all(
241
+ Array.from(inlineScripts).filter(
242
+ (script) => !(script.id.endsWith("_shared") && script.getAttribute("type") === "application/json" && typeof script.getAttribute(
243
+ "data-remote-components-shared"
244
+ ) === "string")
245
+ ).map((script) => {
246
+ return new Promise((resolve) => {
247
+ if (script.textContent && !script.textContent.includes("self.__next_f=") && !script.textContent.includes("self.__next_f.push")) {
248
+ if (!script.getAttribute("type") || script.getAttribute("type") === "text/javascript" || script.getAttribute("type") === "application/javascript") {
249
+ const newScript = document.createElement("script");
250
+ const blob = new Blob([script.textContent], {
251
+ type: "application/javascript"
252
+ });
253
+ const blobUrl = URL.createObjectURL(blob);
254
+ newScript.onload = () => {
255
+ resolve(void 0);
256
+ URL.revokeObjectURL(blobUrl);
257
+ newScript.remove();
258
+ };
259
+ newScript.onerror = () => {
260
+ URL.revokeObjectURL(blobUrl);
261
+ newScript.remove();
262
+ resolve(void 0);
263
+ };
264
+ newScript.src = blobUrl;
265
+ document.body.appendChild(newScript);
266
+ } else {
214
267
  resolve(void 0);
215
- };
216
- newScript.src = blobUrl;
217
- document.body.appendChild(newScript);
268
+ document.body.appendChild(script);
269
+ }
218
270
  } else {
219
271
  resolve(void 0);
220
- document.body.appendChild(script);
221
272
  }
222
- } else {
223
- resolve(void 0);
224
- }
225
- });
226
- })
227
- );
228
- nextScripts.forEach(([scriptSrc, props]) => {
229
- const script = document.createElement("script");
230
- if (scriptSrc) {
231
- script.src = scriptSrc;
232
- }
233
- if (typeof props.children === "string") {
234
- script.textContent = props.children;
235
- }
236
- setAttributesFromProps(script, props);
237
- document.head.appendChild(script);
238
- });
239
- self.__next_s = prevNextScripts;
240
- if (mounted) {
273
+ });
274
+ })
275
+ );
276
+ nextScripts.forEach(([scriptSrc, props]) => {
277
+ const script = document.createElement("script");
278
+ if (scriptSrc) {
279
+ script.src = scriptSrc;
280
+ }
281
+ if (typeof props.children === "string") {
282
+ script.textContent = props.children;
283
+ }
284
+ setAttributesFromProps(script, props);
285
+ document.head.appendChild(script);
286
+ });
287
+ self.__next_s = prevNextScripts;
241
288
  if (rsc) {
242
289
  document.body.appendChild(rsc);
243
290
  }
@@ -248,6 +295,7 @@ function RemoteComponent({
248
295
  url: url.href,
249
296
  data: rsc ? (rsc.textContent || "").split("\n").filter(Boolean) : []
250
297
  };
298
+ const userShared = await shared;
251
299
  const result = await loadRemoteComponent({
252
300
  url: new URL(url, location.origin),
253
301
  name: remoteName,
@@ -274,25 +322,29 @@ function RemoteComponent({
274
322
  ).href
275
323
  };
276
324
  }),
277
- shared,
325
+ shared: {
326
+ ...sharedPolyfills(userShared),
327
+ ...userShared
328
+ },
278
329
  remoteShared,
279
330
  container: shadowRoot
280
331
  });
332
+ if (rsc) {
333
+ rsc.remove();
334
+ }
335
+ setData(newData);
336
+ if (result.error) {
337
+ setRemoteComponent(result.error);
338
+ } else {
339
+ setRemoteComponent(result.component);
340
+ }
341
+ } catch (error) {
281
342
  if (mounted) {
282
- setData(newData);
283
- if (result.error) {
284
- setRemoteComponent(result.error);
285
- } else {
286
- setRemoteComponent(result.component);
287
- }
343
+ setRemoteComponent(error);
288
344
  }
289
345
  }
290
- } catch (error) {
291
- if (mounted) {
292
- setRemoteComponent(error);
293
- }
294
- }
295
- });
346
+ });
347
+ }
296
348
  return () => {
297
349
  mounted = false;
298
350
  };
@@ -306,16 +358,17 @@ function RemoteComponent({
306
358
  route: data?.route || DEFAULT_ROUTE,
307
359
  runtime: data?.runtime || RUNTIME_WEBPACK
308
360
  }) });
309
- const linksToRender = data?.links?.map((link) => /* @__PURE__ */ jsx(
361
+ const resetStyle = reset ? /* @__PURE__ */ jsx("style", { "data-remote-components-reset": "", children: `:host { all: initial; }` }) : null;
362
+ const linksToRender = data?.links?.map((link) => /* @__PURE__ */ createElement(
310
363
  "link",
311
364
  {
312
- as: link.as,
365
+ ...link,
313
366
  href: new URL(link.href, url).href,
314
- rel: link.rel
315
- },
316
- `${link.href}_${link.rel}`
367
+ key: JSON.stringify(link)
368
+ }
317
369
  )) || null;
318
370
  const componentToRender = /* @__PURE__ */ jsxs(Fragment, { children: [
371
+ resetStyle,
319
372
  linksToRender,
320
373
  remoteComponent ?? children
321
374
  ] });
@@ -324,20 +377,13 @@ function RemoteComponent({
324
377
  if (shadowRemoteComponentHtml) {
325
378
  shadowRemoteComponentHtml.remove();
326
379
  }
327
- if (shadowRoot && remoteComponent && htmlRef.current) {
328
- if (ssrHtmlRef.current) {
329
- const content = shadowRoot.querySelectorAll(":not(link,style)");
330
- content.forEach((node) => node.remove());
331
- ssrHtmlRef.current = null;
332
- }
333
- htmlRef.current = null;
334
- }
335
380
  return /* @__PURE__ */ jsxs(Fragment, { children: [
336
381
  metadataJson,
337
382
  /* @__PURE__ */ jsxs(
338
383
  "div",
339
384
  {
340
- id: `shadowroot_${src ? new URL(src, typeof location !== "undefined" ? location.origin : "http://localhost").href.replace(/[^a-z0-9]/g, "_") : ""}_${(data?.name ?? name).replace(/[^a-z0-9]/g, "_")}`,
385
+ "data-remote-component-id": `shadowroot_${src ? new URL(src, typeof location !== "undefined" ? location.origin : "http://localhost").href.replace(/[^a-z0-9]/g, "_") : ""}_${(data?.name ?? name).replace(/[^a-z0-9]/g, "_")}`,
386
+ id: `shadowroot_${data?.name ?? name}`,
341
387
  ref: shadowRootContainerRef,
342
388
  children: [
343
389
  typeof document === "undefined" ? (
@@ -359,21 +405,18 @@ function RemoteComponent({
359
405
  }
360
406
  }
361
407
  ) : null,
362
- reset ? /* @__PURE__ */ jsx(
363
- "style",
364
- {
365
- "data-remote-components-reset": true,
366
- children: `:host { all: initial; }`
367
- }
368
- ) : null,
408
+ resetStyle,
369
409
  linksToRender,
370
410
  children
371
411
  ] })
372
412
  ) : null,
373
413
  shadowRoot && remoteComponent ? createPortal(
374
414
  /* @__PURE__ */ jsxs(Fragment, { children: [
415
+ /* @__PURE__ */ jsx("template", { id: `${name}_start` }),
416
+ resetStyle,
375
417
  linksToRender,
376
- remoteComponent
418
+ remoteComponent,
419
+ /* @__PURE__ */ jsx("template", { id: `${name}_end`, ref: endTemplateRef })
377
420
  ] }),
378
421
  shadowRoot
379
422
  ) : null
@@ -382,6 +425,7 @@ function RemoteComponent({
382
425
  )
383
426
  ] });
384
427
  }
428
+ htmlRef.current = null;
385
429
  return /* @__PURE__ */ jsxs(Fragment, { children: [
386
430
  /* @__PURE__ */ jsx("template", { id: `${name}_start` }),
387
431
  metadataJson,