remote-components 0.0.47 → 0.0.49

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 (64) hide show
  1. package/dist/{component-loader-26b1f55e.d.ts → component-loader-1838f572.d.ts} +62 -8
  2. package/dist/html/host.cjs +165 -70
  3. package/dist/html/host.cjs.map +1 -1
  4. package/dist/html/host.js +165 -70
  5. package/dist/html/host.js.map +1 -1
  6. package/dist/internal/next/host/app-router-client.cjs +13 -50
  7. package/dist/internal/next/host/app-router-client.cjs.map +1 -1
  8. package/dist/internal/next/host/app-router-client.d.ts +1 -1
  9. package/dist/internal/next/host/app-router-client.js +14 -51
  10. package/dist/internal/next/host/app-router-client.js.map +1 -1
  11. package/dist/internal/next/host/remote-component-links.cjs +96 -0
  12. package/dist/internal/next/host/remote-component-links.cjs.map +1 -0
  13. package/dist/internal/next/host/remote-component-links.d.ts +25 -0
  14. package/dist/internal/next/host/remote-component-links.js +72 -0
  15. package/dist/internal/next/host/remote-component-links.js.map +1 -0
  16. package/dist/internal/shared/client/remote-component.cjs +17 -1
  17. package/dist/internal/shared/client/remote-component.cjs.map +1 -1
  18. package/dist/internal/shared/client/remote-component.d.ts +2 -2
  19. package/dist/internal/shared/client/remote-component.js +17 -1
  20. package/dist/internal/shared/client/remote-component.js.map +1 -1
  21. package/dist/internal/shared/ssr/dom-flight.d.ts +1 -1
  22. package/dist/internal/shared/ssr/fetch-remote-component.d.ts +1 -1
  23. package/dist/internal/shared/ssr/fetch-with-hooks.cjs +13 -3
  24. package/dist/internal/shared/ssr/fetch-with-hooks.cjs.map +1 -1
  25. package/dist/internal/shared/ssr/fetch-with-hooks.d.ts +24 -13
  26. package/dist/internal/shared/ssr/fetch-with-hooks.js +13 -3
  27. package/dist/internal/shared/ssr/fetch-with-hooks.js.map +1 -1
  28. package/dist/internal/shared/ssr/fetch-with-protected-rc-fallback.cjs +6 -1
  29. package/dist/internal/shared/ssr/fetch-with-protected-rc-fallback.cjs.map +1 -1
  30. package/dist/internal/shared/ssr/fetch-with-protected-rc-fallback.d.ts +3 -0
  31. package/dist/internal/shared/ssr/fetch-with-protected-rc-fallback.js +6 -1
  32. package/dist/internal/shared/ssr/fetch-with-protected-rc-fallback.js.map +1 -1
  33. package/dist/internal/shared/utils/abort.cjs +38 -0
  34. package/dist/internal/shared/utils/abort.cjs.map +1 -0
  35. package/dist/internal/shared/utils/abort.d.ts +7 -0
  36. package/dist/internal/shared/utils/abort.js +14 -0
  37. package/dist/internal/shared/utils/abort.js.map +1 -0
  38. package/dist/next/config.cjs +4 -2
  39. package/dist/next/config.cjs.map +1 -1
  40. package/dist/next/config.js +4 -2
  41. package/dist/next/config.js.map +1 -1
  42. package/dist/next/host/app-router-server.d.ts +1 -1
  43. package/dist/next/host/client/index.cjs +41 -8
  44. package/dist/next/host/client/index.cjs.map +1 -1
  45. package/dist/next/host/client/index.d.ts +1 -1
  46. package/dist/next/host/client/index.js +41 -8
  47. package/dist/next/host/client/index.js.map +1 -1
  48. package/dist/next/host/pages-router-client.d.ts +1 -1
  49. package/dist/next/host/pages-router-server.d.ts +1 -1
  50. package/dist/next/index.d.ts +1 -1
  51. package/dist/next/proxy.cjs.map +1 -1
  52. package/dist/next/proxy.js.map +1 -1
  53. package/dist/react/index.cjs +41 -8
  54. package/dist/react/index.cjs.map +1 -1
  55. package/dist/react/index.d.ts +2 -1
  56. package/dist/react/index.js +41 -8
  57. package/dist/react/index.js.map +1 -1
  58. package/dist/{types-6e4ba234.d.ts → types-cbe44b51.d.ts} +61 -7
  59. package/dist/webpack.cjs +274 -0
  60. package/dist/webpack.cjs.map +1 -0
  61. package/dist/webpack.d.ts +14 -0
  62. package/dist/webpack.js +247 -0
  63. package/dist/webpack.js.map +1 -0
  64. package/package.json +9 -1
@@ -7,17 +7,51 @@ interface RemoteComponentMetadata {
7
7
  id: string;
8
8
  type: 'nextjs' | 'remote-component' | 'unknown';
9
9
  }
10
+ /**
11
+ * Options object passed to hook functions containing abort capabilities.
12
+ * Uses standard AbortController/AbortSignal for compatibility with Web APIs.
13
+ *
14
+ * @example
15
+ * // Abort on redirect
16
+ * component.onResponse = (url, response, { signal, abort }) => {
17
+ * if (response.redirected) {
18
+ * abort();
19
+ * }
20
+ * };
21
+ *
22
+ * @example
23
+ * // Check if already aborted
24
+ * component.onRequest = (url, init, { signal }) => {
25
+ * if (signal.aborted) return;
26
+ * // ...
27
+ * };
28
+ *
29
+ * @example
30
+ * // Pass signal to fetch or other APIs
31
+ * component.onRequest = async (url, init, { signal }) => {
32
+ * const data = await fetch('/api/check', { signal });
33
+ * // ...
34
+ * };
35
+ */
36
+ interface HookOptions {
37
+ /** Standard AbortSignal - can be passed to fetch and other Web APIs */
38
+ signal: AbortSignal;
39
+ /** Abort loading - prevents further processing and DOM attachment */
40
+ abort(reason?: unknown): void;
41
+ }
10
42
  /**
11
43
  * Hook function that intercepts remote component fetch requests.
12
- * Can be used to modify request options, provide a custom response, or inspect the request.
44
+ * Can be used to modify request options, provide a custom response, inspect the request,
45
+ * or abort loading.
13
46
  *
14
47
  * @param url - The URL being fetched
15
48
  * @param init - The fetch init options being used
49
+ * @param options - Options object containing the abort signal
16
50
  * @returns Optional Response to use instead of fetching, or void/undefined to proceed with normal fetch
17
51
  *
18
52
  * @example
19
53
  * // Log all remote component requests
20
- * const onRequest = async (url, init) => {
54
+ * const onRequest = async (url, init, { abort }) => {
21
55
  * console.log('Fetching remote component from:', url.href);
22
56
  * };
23
57
  *
@@ -35,21 +69,32 @@ interface RemoteComponentMetadata {
35
69
  * return new Response(cached);
36
70
  * }
37
71
  * };
72
+ *
73
+ * @example
74
+ * // Block certain domains
75
+ * const onRequest = async (url, init, { abort }) => {
76
+ * if (isBlockedDomain(url)) {
77
+ * abort('Domain is blocked');
78
+ * }
79
+ * };
38
80
  */
39
- type OnRequestHook = (url: URL, init: RequestInit) => Promise<Response | undefined> | Response | undefined;
81
+ type OnRequestHook = (url: URL, init: RequestInit, options: HookOptions) => Promise<Response | undefined> | Response | undefined;
40
82
  /**
41
83
  * Hook function that is called after a remote component fetch completes.
42
- * Can be used to inspect the response, check for redirects, or transform the response.
84
+ * Can be used to inspect the response, check for redirects, transform the response,
85
+ * or abort loading.
43
86
  *
44
87
  * @param url - The original URL that was requested
45
88
  * @param response - The Response object from the fetch
89
+ * @param options - Options object containing the abort signal
46
90
  * @returns Optional Response to use instead of the original, or void/undefined to use the original response
47
91
  *
48
92
  * @example
49
- * // Check for redirects
50
- * const onResponse = async (url, response) => {
93
+ * // Check for redirects and abort
94
+ * const onResponse = async (url, response, { abort }) => {
51
95
  * if (response.redirected) {
52
96
  * console.log(`Redirected from ${url.href} to ${response.url}`);
97
+ * abort();
53
98
  * }
54
99
  * };
55
100
  *
@@ -67,8 +112,17 @@ type OnRequestHook = (url: URL, init: RequestInit) => Promise<Response | undefin
67
112
  * const modified = text.replace(/foo/g, 'bar');
68
113
  * return new Response(modified, response);
69
114
  * };
115
+ *
116
+ * @example
117
+ * // Abort on redirect to legacy routes
118
+ * const onResponse = async (url, response, { abort }) => {
119
+ * if (response.redirected && isLegacyRoute(response.url)) {
120
+ * window.location.href = toLegacyUrl(response.url);
121
+ * abort(); // Abort rendering - no flash!
122
+ * }
123
+ * };
70
124
  */
71
- type OnResponseHook = (url: URL, response: Response) => Promise<Response | undefined> | Response | undefined;
125
+ type OnResponseHook = (url: URL, response: Response, options: HookOptions) => Promise<Response | undefined> | Response | undefined;
72
126
 
73
127
  interface RemoteComponentProps {
74
128
  /** The src provided to the `<RemoteComponent>` component. May be relative or absolute URL. */
@@ -141,4 +195,4 @@ type LoadRemoteComponentProps = Pick<RemoteComponentProps, 'name' | 'bundle' | '
141
195
  */
142
196
  declare function loadRemoteComponent({ url, name, rscName, bundle, route, runtime, data, nextData, scripts, shared, remoteShared, container, }: LoadRemoteComponentProps): Promise<LoaderResult>;
143
197
 
144
- export { GlobalScope as G, LoadRemoteComponentProps as L, MountOrUnmountFunction as M, OnRequestHook as O, RemoteComponentProps as R, OnResponseHook as a, LoaderResult as b, loadRemoteComponent as l };
198
+ export { GlobalScope as G, HookOptions as H, LoadRemoteComponentProps as L, MountOrUnmountFunction as M, OnRequestHook as O, RemoteComponentProps as R, OnResponseHook as a, LoaderResult as b, loadRemoteComponent as l };
@@ -270,19 +270,40 @@ var init_shared_modules = __esm({
270
270
  }
271
271
  });
272
272
 
273
+ // src/shared/utils/abort.ts
274
+ function isAbortError(error) {
275
+ if (error instanceof DOMException && error.name === "AbortError") {
276
+ return true;
277
+ }
278
+ if (error !== null && typeof error === "object" && "name" in error && error.name === "AbortError" && "message" in error && typeof error.message === "string") {
279
+ const e = error;
280
+ return typeof e.code === "number" || e.constructor?.name === "DOMException";
281
+ }
282
+ return false;
283
+ }
284
+ var init_abort = __esm({
285
+ "src/shared/utils/abort.ts"() {
286
+ "use strict";
287
+ }
288
+ });
289
+
273
290
  // src/shared/ssr/fetch-with-protected-rc-fallback.ts
274
291
  async function fetchWithProtectedRcFallback(url, init) {
275
292
  try {
276
293
  const res = await fetch(url, init);
277
294
  return res;
278
295
  } catch (error) {
296
+ if (isAbortError(error)) {
297
+ throw error;
298
+ }
279
299
  if (typeof document === "object" && typeof document.location === "object" && document.location.origin !== new URL(url).origin) {
280
300
  logInfo(
281
301
  "FetchRemoteComponent",
282
302
  "Request failed due to CORS, attempting to fetch it via the withRemoteComponentsHost proxy."
283
303
  );
284
304
  const proxiedRes = await fetch(
285
- `${RC_PROTECTED_REMOTE_FETCH_PATHNAME}?url=${url}`
305
+ `${RC_PROTECTED_REMOTE_FETCH_PATHNAME}?url=${url}`,
306
+ init?.signal ? { signal: init.signal } : void 0
286
307
  );
287
308
  if (proxiedRes.status === 200) {
288
309
  return proxiedRes;
@@ -300,6 +321,7 @@ var RC_PROTECTED_REMOTE_FETCH_PATHNAME;
300
321
  var init_fetch_with_protected_rc_fallback = __esm({
301
322
  "src/shared/ssr/fetch-with-protected-rc-fallback.ts"() {
302
323
  "use strict";
324
+ init_abort();
303
325
  init_logger();
304
326
  RC_PROTECTED_REMOTE_FETCH_PATHNAME = "/rc-fetch-protected-remote";
305
327
  }
@@ -1703,17 +1725,27 @@ function remoteFetchHeaders() {
1703
1725
  // src/shared/ssr/fetch-with-hooks.ts
1704
1726
  init_fetch_with_protected_rc_fallback();
1705
1727
  async function fetchWithHooks(url, additionalInit, options = {}) {
1706
- const { onRequest, onResponse } = options;
1728
+ const {
1729
+ onRequest,
1730
+ onResponse,
1731
+ abortController = new AbortController()
1732
+ } = options;
1733
+ const signal = abortController.signal;
1734
+ const hookOptions = {
1735
+ signal,
1736
+ abort: (reason) => abortController.abort(reason)
1737
+ };
1707
1738
  const init = {
1708
1739
  method: "GET",
1709
1740
  headers: remoteFetchHeaders(),
1741
+ signal,
1710
1742
  ...additionalInit
1711
1743
  };
1712
- let res = await onRequest?.(url, init);
1744
+ let res = await onRequest?.(url, init, hookOptions);
1713
1745
  if (!res) {
1714
1746
  res = await fetchWithProtectedRcFallback(url, init);
1715
1747
  }
1716
- const transformedRes = await onResponse?.(url, res);
1748
+ const transformedRes = await onResponse?.(url, res, hookOptions);
1717
1749
  if (transformedRes) {
1718
1750
  res = transformedRes;
1719
1751
  }
@@ -1722,8 +1754,87 @@ async function fetchWithHooks(url, additionalInit, options = {}) {
1722
1754
 
1723
1755
  // src/html/host/index.tsx
1724
1756
  init_utils();
1757
+ init_abort();
1725
1758
  init_logger();
1726
1759
 
1760
+ // src/html/host/attach-styles.ts
1761
+ init_error();
1762
+ async function attachStyles({
1763
+ doc,
1764
+ component,
1765
+ links,
1766
+ signal,
1767
+ baseUrl,
1768
+ remoteComponentSrc,
1769
+ root
1770
+ }) {
1771
+ const appendedLinks = [];
1772
+ let abortReject = null;
1773
+ const abortPromise = new Promise((_, reject) => {
1774
+ abortReject = reject;
1775
+ });
1776
+ const abortHandler = () => {
1777
+ for (const link of appendedLinks) {
1778
+ link.onload = null;
1779
+ link.onerror = null;
1780
+ link.remove();
1781
+ }
1782
+ abortReject?.(new DOMException("Aborted", "AbortError"));
1783
+ };
1784
+ signal?.addEventListener("abort", abortHandler, { once: true });
1785
+ try {
1786
+ await Promise.all(
1787
+ Array.from(links).filter((link) => !component.contains(link)).map((link) => {
1788
+ const newLink = document.createElement("link");
1789
+ appendedLinks.push(newLink);
1790
+ const loadPromise = new Promise((resolve, reject) => {
1791
+ if (link.rel === "stylesheet") {
1792
+ newLink.onload = () => resolve();
1793
+ newLink.onerror = () => reject(
1794
+ new RemoteComponentsError(
1795
+ `Failed to load <link href="${link.href}"> for Remote Component. Check the URL is correct.`
1796
+ )
1797
+ );
1798
+ } else {
1799
+ resolve();
1800
+ }
1801
+ });
1802
+ for (const attr of link.attributes) {
1803
+ if (attr.name === "href") {
1804
+ newLink.setAttribute(
1805
+ attr.name,
1806
+ new URL(attr.value, baseUrl ?? location.origin).href
1807
+ );
1808
+ } else {
1809
+ newLink.setAttribute(attr.name, attr.value);
1810
+ }
1811
+ }
1812
+ if (remoteComponentSrc) {
1813
+ newLink.setAttribute(
1814
+ "data-remote-component-src",
1815
+ remoteComponentSrc
1816
+ );
1817
+ }
1818
+ root?.appendChild(newLink);
1819
+ return Promise.race([loadPromise, abortPromise]);
1820
+ })
1821
+ );
1822
+ } finally {
1823
+ signal?.removeEventListener("abort", abortHandler);
1824
+ }
1825
+ const styles = doc.querySelectorAll("style");
1826
+ for (const style of styles) {
1827
+ if (style.parentElement?.tagName.toLowerCase() === "head") {
1828
+ const newStyle = document.createElement("style");
1829
+ newStyle.textContent = style.textContent;
1830
+ if (remoteComponentSrc) {
1831
+ newStyle.setAttribute("data-remote-component-src", remoteComponentSrc);
1832
+ }
1833
+ root?.appendChild(newStyle);
1834
+ }
1835
+ }
1836
+ }
1837
+
1727
1838
  // src/html/host/runtime/index.ts
1728
1839
  init_error();
1729
1840
  async function getRuntime(type, url, bundle, shared, remoteShared) {
@@ -1765,6 +1876,8 @@ if (typeof HTMLElement !== "undefined") {
1765
1876
  reactRoot;
1766
1877
  onRequest;
1767
1878
  onResponse;
1879
+ /** Current AbortController for the loading operation - can be used to cancel loading via controller.abort() */
1880
+ abortController;
1768
1881
  static get observedAttributes() {
1769
1882
  return ["src", "name", "mode"];
1770
1883
  }
@@ -1775,6 +1888,10 @@ if (typeof HTMLElement !== "undefined") {
1775
1888
  if ((name === "src" || name === "name") && oldValue !== newValue) {
1776
1889
  if (this.getAttribute("src")) {
1777
1890
  this.load().catch((e) => {
1891
+ if (isAbortError(e)) {
1892
+ this.isLoading = false;
1893
+ return;
1894
+ }
1778
1895
  logError("HtmlHost", "Error loading remote component.", e);
1779
1896
  const errorEvent = new Event("error", {
1780
1897
  bubbles: true,
@@ -1797,6 +1914,10 @@ if (typeof HTMLElement !== "undefined") {
1797
1914
  });
1798
1915
  this.root = newRoot;
1799
1916
  this.load().catch((e) => {
1917
+ if (isAbortError(e)) {
1918
+ this.isLoading = false;
1919
+ return;
1920
+ }
1800
1921
  logError("HtmlHost", "Error reloading remote component.", e);
1801
1922
  const errorEvent = new Event("error", {
1802
1923
  bubbles: true,
@@ -1830,6 +1951,10 @@ if (typeof HTMLElement !== "undefined") {
1830
1951
  this.bundle = "default";
1831
1952
  if (this.hasAttribute("src") || this.querySelector("div#__REMOTE_COMPONENT__") || this.hasAttribute("data-ssr")) {
1832
1953
  this.load().catch((e) => {
1954
+ if (isAbortError(e)) {
1955
+ this.isLoading = false;
1956
+ return;
1957
+ }
1833
1958
  logError("HtmlHost", "Error loading remote component.", e);
1834
1959
  const errorEvent = new Event("error", {
1835
1960
  bubbles: true,
@@ -1844,6 +1969,8 @@ if (typeof HTMLElement !== "undefined") {
1844
1969
  }
1845
1970
  this.isLoading = true;
1846
1971
  const src = this.getAttribute("src");
1972
+ this.abortController = new AbortController();
1973
+ const signal = this.abortController.signal;
1847
1974
  const beforeLoadEvent = new Event("beforeload", {
1848
1975
  bubbles: true,
1849
1976
  composed: true
@@ -1868,12 +1995,16 @@ if (typeof HTMLElement !== "undefined") {
1868
1995
  };
1869
1996
  const res = await fetchWithHooks(url, fetchInit, {
1870
1997
  onRequest: this.onRequest,
1871
- onResponse: this.onResponse
1998
+ onResponse: this.onResponse,
1999
+ abortController: this.abortController
1872
2000
  });
1873
- if (!res.ok) {
1874
- let error = failedToFetchRemoteComponentError(url.href, res);
2001
+ if (!res || !res.ok) {
2002
+ let error = failedToFetchRemoteComponentError(
2003
+ url.href,
2004
+ res ?? new Response(null, { status: 0 })
2005
+ );
1875
2006
  try {
1876
- const body = await res.text();
2007
+ const body = res ? await res.text() : "";
1877
2008
  const parser2 = new DOMParser();
1878
2009
  const doc2 = parser2.parseFromString(body, "text/html");
1879
2010
  const errorTemplate = doc2.querySelector(
@@ -1891,7 +2022,9 @@ if (typeof HTMLElement !== "undefined") {
1891
2022
  error.stack = errorStack;
1892
2023
  }
1893
2024
  }
1894
- } catch {
2025
+ } catch (parseError) {
2026
+ if (isAbortError(parseError))
2027
+ throw parseError;
1895
2028
  }
1896
2029
  throw error;
1897
2030
  }
@@ -2002,64 +2135,26 @@ if (typeof HTMLElement !== "undefined") {
2002
2135
  const removable = Array.from(this.childNodes);
2003
2136
  const links = doc.querySelectorAll("link[href]");
2004
2137
  const remoteComponentSrc = this.getAttribute("src");
2005
- const attachLinks = async () => {
2006
- await Promise.all(
2007
- Array.from(links).filter((link) => {
2008
- return !component.contains(link);
2009
- }).map((link) => {
2010
- return new Promise((resolve, reject) => {
2011
- const newLink = document.createElement("link");
2012
- if (link.rel === "stylesheet") {
2013
- newLink.onload = () => {
2014
- resolve();
2015
- };
2016
- newLink.onerror = () => {
2017
- reject(
2018
- new RemoteComponentsError(
2019
- `Failed to load <link href="${link.href}"> for Remote Component. Check the URL is correct.`
2020
- )
2021
- );
2022
- };
2023
- } else {
2024
- resolve();
2025
- }
2026
- for (const attr of link.attributes) {
2027
- if (attr.name === "href") {
2028
- newLink.setAttribute(
2029
- attr.name,
2030
- new URL(attr.value, url ?? location.origin).href
2031
- );
2032
- } else {
2033
- newLink.setAttribute(attr.name, attr.value);
2034
- }
2035
- }
2036
- if (remoteComponentSrc) {
2037
- newLink.setAttribute(
2038
- "data-remote-component-src",
2039
- remoteComponentSrc
2040
- );
2041
- }
2042
- this.root?.appendChild(newLink);
2043
- });
2044
- })
2045
- );
2046
- const styles = doc.querySelectorAll("style");
2047
- styles.forEach((style) => {
2048
- if (style.parentElement?.tagName.toLowerCase() === "head") {
2049
- const newStyle = document.createElement("style");
2050
- newStyle.textContent = style.textContent;
2051
- if (remoteComponentSrc) {
2052
- newStyle.setAttribute(
2053
- "data-remote-component-src",
2054
- remoteComponentSrc
2055
- );
2056
- }
2057
- this.root?.appendChild(newStyle);
2058
- }
2059
- });
2060
- };
2138
+ const doAttachStyles = () => attachStyles({
2139
+ doc,
2140
+ component,
2141
+ links,
2142
+ signal: void 0,
2143
+ // Effects run after load, no abort needed
2144
+ baseUrl: url?.href,
2145
+ remoteComponentSrc,
2146
+ root: this.root ?? null
2147
+ });
2061
2148
  if (!this.reactRoot) {
2062
- await attachLinks();
2149
+ await attachStyles({
2150
+ doc,
2151
+ component,
2152
+ links,
2153
+ signal,
2154
+ baseUrl: url?.href,
2155
+ remoteComponentSrc,
2156
+ root: this.root
2157
+ });
2063
2158
  }
2064
2159
  applyOriginToNodes(doc, url ?? new URL(location.href));
2065
2160
  if (!this.reactRoot) {
@@ -2214,8 +2309,8 @@ if (typeof HTMLElement !== "undefined") {
2214
2309
  doCleanup();
2215
2310
  applyReset();
2216
2311
  if (!initial) {
2217
- attachLinks().catch((e) => {
2218
- logError("HtmlHost", "Error attaching links.", e);
2312
+ doAttachStyles().catch((e) => {
2313
+ logError("HtmlHost", "Error attaching styles.", e);
2219
2314
  });
2220
2315
  }
2221
2316
  this.isLoading = false;
@@ -2267,8 +2362,8 @@ if (typeof HTMLElement !== "undefined") {
2267
2362
  doCleanup();
2268
2363
  if (!initial) {
2269
2364
  applyReset();
2270
- attachLinks().catch((e) => {
2271
- logError("HtmlHost", "Error attaching links.", e);
2365
+ doAttachStyles().catch((e) => {
2366
+ logError("HtmlHost", "Error attaching styles.", e);
2272
2367
  });
2273
2368
  }
2274
2369
  remoteComponent.isLoading = false;