remote-components 0.2.1 → 0.3.0
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/config/nextjs.cjs +2 -4
- package/dist/config/nextjs.cjs.map +1 -1
- package/dist/config/nextjs.d.ts +1 -1
- package/dist/config/nextjs.js +2 -4
- package/dist/config/nextjs.js.map +1 -1
- package/dist/host/html.cjs +40 -59
- package/dist/host/html.cjs.map +1 -1
- package/dist/host/html.js +40 -62
- package/dist/host/html.js.map +1 -1
- package/dist/host/nextjs/app/client-only.cjs +199 -231
- package/dist/host/nextjs/app/client-only.cjs.map +1 -1
- package/dist/host/nextjs/app/client-only.d.ts +28 -9
- package/dist/host/nextjs/app/client-only.js +198 -231
- package/dist/host/nextjs/app/client-only.js.map +1 -1
- package/dist/host/nextjs/pages.cjs +5 -12
- package/dist/host/nextjs/pages.cjs.map +1 -1
- package/dist/host/nextjs/pages.js +6 -13
- package/dist/host/nextjs/pages.js.map +1 -1
- package/dist/host/react.cjs +45 -71
- package/dist/host/react.cjs.map +1 -1
- package/dist/host/react.d.ts +2 -366
- package/dist/host/react.js +45 -71
- package/dist/host/react.js.map +1 -1
- package/dist/index-4c65355c.d.ts +298 -0
- package/dist/internal/config/webpack/next-client-pages-loader.d.ts +3 -3
- package/dist/internal/host/nextjs/app-client.cjs +1 -5
- package/dist/internal/host/nextjs/app-client.cjs.map +1 -1
- package/dist/internal/host/nextjs/app-client.d.ts +1 -1
- package/dist/internal/host/nextjs/app-client.js +2 -6
- package/dist/internal/host/nextjs/app-client.js.map +1 -1
- package/dist/internal/host/nextjs/image-shared.cjs +25 -15
- package/dist/internal/host/nextjs/image-shared.cjs.map +1 -1
- package/dist/internal/host/nextjs/image-shared.d.ts +19 -6
- package/dist/internal/host/nextjs/image-shared.js +24 -14
- package/dist/internal/host/nextjs/image-shared.js.map +1 -1
- package/dist/internal/host/react/context.cjs +5 -10
- package/dist/internal/host/react/context.cjs.map +1 -1
- package/dist/internal/host/react/context.d.ts +7 -18
- package/dist/internal/host/react/context.js +4 -9
- package/dist/internal/host/react/context.js.map +1 -1
- package/dist/internal/host/react/hooks/use-resolve-client-url.cjs +2 -5
- package/dist/internal/host/react/hooks/use-resolve-client-url.cjs.map +1 -1
- package/dist/internal/host/react/hooks/use-resolve-client-url.js +2 -5
- package/dist/internal/host/react/hooks/use-resolve-client-url.js.map +1 -1
- package/dist/internal/host/shared/config.cjs.map +1 -1
- package/dist/internal/host/shared/config.d.ts +7 -0
- package/dist/internal/host/shared/polyfill.cjs +10 -65
- package/dist/internal/host/shared/polyfill.cjs.map +1 -1
- package/dist/internal/host/shared/polyfill.d.ts +1 -3
- package/dist/internal/host/shared/polyfill.js +9 -63
- package/dist/internal/host/shared/polyfill.js.map +1 -1
- package/dist/internal/host/shared/remote-image-loader.cjs +53 -0
- package/dist/internal/host/shared/remote-image-loader.cjs.map +1 -0
- package/dist/internal/host/shared/remote-image-loader.d.ts +30 -0
- package/dist/internal/host/shared/remote-image-loader.js +29 -0
- package/dist/internal/host/shared/remote-image-loader.js.map +1 -0
- package/dist/internal/host/shared/resolved-data.d.ts +2 -2
- package/dist/internal/runtime/loaders/component-loader.d.ts +1 -1
- package/dist/{server-handoff-8c89b856.d.ts → server-handoff-ce13bebc.d.ts} +2 -2
- package/package.json +1 -9
- package/dist/internal/host/nextjs/image-impl.cjs +0 -60
- package/dist/internal/host/nextjs/image-impl.cjs.map +0 -1
- package/dist/internal/host/nextjs/image-impl.d.ts +0 -10
- package/dist/internal/host/nextjs/image-impl.js +0 -36
- package/dist/internal/host/nextjs/image-impl.js.map +0 -1
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Intercepts client-side URL resolution for remote component resources.
|
|
5
|
+
* Called before each asset (script, stylesheet, chunk, module, image) is fetched.
|
|
6
|
+
*
|
|
7
|
+
* Return a new URL string to redirect the fetch (e.g., through a proxy),
|
|
8
|
+
* or undefined to use the original URL.
|
|
9
|
+
*
|
|
10
|
+
* @param remoteSrc - The `src` of the remote component being loaded
|
|
11
|
+
* @param url - The asset URL about to be fetched
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* // Proxy all assets from the remote's origin through the host
|
|
15
|
+
* const resolveClientUrl = (remoteSrc, url) => {
|
|
16
|
+
* const remoteOrigin = new URL(remoteSrc).origin;
|
|
17
|
+
* const parsed = new URL(url);
|
|
18
|
+
* if (parsed.origin !== location.origin && parsed.origin === remoteOrigin) {
|
|
19
|
+
* return `/rc-fetch-protected-remote?url=${encodeURIComponent(url)}`;
|
|
20
|
+
* }
|
|
21
|
+
* };
|
|
22
|
+
*/
|
|
23
|
+
type ResolveClientUrl = (remoteSrc: string, url: string) => string | undefined;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Hook types for intercepting remote component fetch requests and responses.
|
|
27
|
+
*
|
|
28
|
+
* These are part of the public host configuration surface ({@link ConsumeServerConfig})
|
|
29
|
+
* and are used by both SSR and client-side host implementations.
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* Options object passed to hook functions containing abort capabilities.
|
|
33
|
+
* Uses standard AbortController/AbortSignal for compatibility with Web APIs.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* // Abort on redirect
|
|
37
|
+
* component.onResponse = (url, response, { signal, abort }) => {
|
|
38
|
+
* if (response.redirected) {
|
|
39
|
+
* abort();
|
|
40
|
+
* }
|
|
41
|
+
* };
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* // Check if already aborted
|
|
45
|
+
* component.onRequest = (url, init, { signal }) => {
|
|
46
|
+
* if (signal.aborted) return;
|
|
47
|
+
* // ...
|
|
48
|
+
* };
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* // Pass signal to fetch or other APIs
|
|
52
|
+
* component.onRequest = async (url, init, { signal }) => {
|
|
53
|
+
* const data = await fetch('/api/check', { signal });
|
|
54
|
+
* // ...
|
|
55
|
+
* };
|
|
56
|
+
*/
|
|
57
|
+
interface HookOptions {
|
|
58
|
+
/** Standard AbortSignal - can be passed to fetch and other Web APIs */
|
|
59
|
+
signal: AbortSignal;
|
|
60
|
+
/** Abort loading - prevents further processing and DOM attachment */
|
|
61
|
+
abort(reason?: unknown): void;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Hook function that intercepts remote component fetch requests.
|
|
65
|
+
* Can be used to modify request options, provide a custom response, inspect the request,
|
|
66
|
+
* or abort loading.
|
|
67
|
+
*
|
|
68
|
+
* @param url - The URL being fetched
|
|
69
|
+
* @param init - The fetch init options being used
|
|
70
|
+
* @param options - Options object containing the abort signal
|
|
71
|
+
* @returns Optional Response to use instead of fetching, or void/undefined to proceed with normal fetch
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* // Log all remote component requests
|
|
75
|
+
* const onRequest = async (url, init, { abort }) => {
|
|
76
|
+
* console.log('Fetching remote component from:', url.href);
|
|
77
|
+
* };
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* // Add custom headers
|
|
81
|
+
* const onRequest = async (url, init) => {
|
|
82
|
+
* (init.headers as Headers).set('X-Custom-Header', 'value');
|
|
83
|
+
* };
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* // Provide a cached response
|
|
87
|
+
* const onRequest = async (url) => {
|
|
88
|
+
* const cached = cache.get(url.href);
|
|
89
|
+
* if (cached) {
|
|
90
|
+
* return new Response(cached);
|
|
91
|
+
* }
|
|
92
|
+
* };
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* // Block certain domains
|
|
96
|
+
* const onRequest = async (url, init, { abort }) => {
|
|
97
|
+
* if (isBlockedDomain(url)) {
|
|
98
|
+
* abort('Domain is blocked');
|
|
99
|
+
* }
|
|
100
|
+
* };
|
|
101
|
+
*/
|
|
102
|
+
type OnRequestHook = (url: URL, init: RequestInit, options: HookOptions) => Promise<Response | undefined> | Response | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Hook function that is called after a remote component fetch completes.
|
|
105
|
+
* Can be used to inspect the response, check for redirects, transform the response,
|
|
106
|
+
* or abort loading.
|
|
107
|
+
*
|
|
108
|
+
* @param url - The original URL that was requested
|
|
109
|
+
* @param response - The Response object from the fetch
|
|
110
|
+
* @param options - Options object containing the abort signal
|
|
111
|
+
* @returns Optional Response to use instead of the original, or void/undefined to use the original response
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* // Check for redirects and abort
|
|
115
|
+
* const onResponse = async (url, response, { abort }) => {
|
|
116
|
+
* if (response.redirected) {
|
|
117
|
+
* console.log(`Redirected from ${url.href} to ${response.url}`);
|
|
118
|
+
* abort();
|
|
119
|
+
* }
|
|
120
|
+
* };
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* // Cache the response
|
|
124
|
+
* const onResponse = async (url, response) => {
|
|
125
|
+
* const cloned = response.clone();
|
|
126
|
+
* cache.set(url.href, await cloned.text());
|
|
127
|
+
* };
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* // Transform the response
|
|
131
|
+
* const onResponse = async (url, response) => {
|
|
132
|
+
* const text = await response.text();
|
|
133
|
+
* const modified = text.replace(/foo/g, 'bar');
|
|
134
|
+
* return new Response(modified, response);
|
|
135
|
+
* };
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* // Abort on redirect to legacy routes
|
|
139
|
+
* const onResponse = async (url, response, { abort }) => {
|
|
140
|
+
* if (response.redirected && isLegacyRoute(response.url)) {
|
|
141
|
+
* window.location.href = toLegacyUrl(response.url);
|
|
142
|
+
* abort(); // Abort rendering - no flash!
|
|
143
|
+
* }
|
|
144
|
+
* };
|
|
145
|
+
*/
|
|
146
|
+
type OnResponseHook = (url: URL, response: Response, options: HookOptions) => Promise<Response | undefined> | Response | undefined;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Configuration for Shadow DOM isolation of a remote component.
|
|
150
|
+
*
|
|
151
|
+
* Used by both the public {@link ConsumeRemoteComponentConfig} (user-facing props) and
|
|
152
|
+
* {@link ConsumeServerData} (internal runtime data) to control
|
|
153
|
+
* whether and how the remote component is wrapped in a shadow root.
|
|
154
|
+
*/
|
|
155
|
+
interface ShadowDomConfig {
|
|
156
|
+
/** Whether to isolate the remote component using a Shadow DOM wrapper. */
|
|
157
|
+
isolate?: boolean;
|
|
158
|
+
/** The Shadow DOM mode. Defaults to `'open'`. */
|
|
159
|
+
mode?: 'open' | 'closed';
|
|
160
|
+
/** Whether to include a CSS reset style in the Shadow DOM. Defaults to `false`. */
|
|
161
|
+
reset?: boolean;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Configuration accepted by server-rendered embed hosts (e.g. the Next.js App Router
|
|
165
|
+
* `<ConsumeRemoteComponent>`). This is the minimal, serializable subset — no client-side
|
|
166
|
+
* asset fetching fields, no lifecycle callbacks.
|
|
167
|
+
*
|
|
168
|
+
* `src` is optional here because not every host has a source at construction
|
|
169
|
+
* time (e.g. the React host during SSR hydration, or a `<remote-component>`
|
|
170
|
+
* element before its `src` attribute is set). Frameworks that require `src`
|
|
171
|
+
* narrow it to required in their own props type.
|
|
172
|
+
*/
|
|
173
|
+
interface ConsumeServerConfig extends ShadowDomConfig {
|
|
174
|
+
/** The source URL of the remote component. Relative or absolute. */
|
|
175
|
+
src?: string | URL;
|
|
176
|
+
/** Selects a named remote component when multiple are exposed on a single page. */
|
|
177
|
+
name?: string;
|
|
178
|
+
/** Intercepts fetch requests before they are sent. */
|
|
179
|
+
onRequest?: OnRequestHook;
|
|
180
|
+
/** Inspects or transforms fetch responses after they arrive. */
|
|
181
|
+
onResponse?: OnResponseHook;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Client-only configuration fields — the subset of {@link ConsumeClientConfig}
|
|
185
|
+
* that applies only to client-side asset fetching. Used directly in contexts where
|
|
186
|
+
* the full server config is already present (e.g. {@link ConsumeRemoteComponentClient}).
|
|
187
|
+
*/
|
|
188
|
+
interface ConsumeClientOnlyConfig {
|
|
189
|
+
/** The credentials mode for the fetch request. Defaults to `'same-origin'`. */
|
|
190
|
+
credentials?: RequestCredentials;
|
|
191
|
+
/**
|
|
192
|
+
* Rewrites client-side asset URLs (scripts, stylesheets, chunks, modules, images).
|
|
193
|
+
* Return a new URL string to redirect the request (e.g. through a proxy),
|
|
194
|
+
* or `undefined` to use the original URL.
|
|
195
|
+
*/
|
|
196
|
+
resolveClientUrl?: ResolveClientUrl;
|
|
197
|
+
/**
|
|
198
|
+
* Shared module factories provided to the remote component's module system.
|
|
199
|
+
* Each key is a module specifier; the value is a factory function that returns
|
|
200
|
+
* the module. Since factories are functions, this can only be supplied from
|
|
201
|
+
* client-side code and cannot be passed through Server Component boundaries.
|
|
202
|
+
*/
|
|
203
|
+
shared?: Promise<Record<string, (bundle?: string) => Promise<unknown>>> | Record<string, (bundle?: string) => Promise<unknown>>;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Configuration accepted by client-side embed hosts (React host, Pages Router host,
|
|
207
|
+
* HTML host). Extends {@link ConsumeServerConfig} with fields for
|
|
208
|
+
* client-side asset fetching (`credentials`, `resolveClientUrl`).
|
|
209
|
+
*/
|
|
210
|
+
interface ConsumeClientConfig extends ConsumeServerConfig, ConsumeClientOnlyConfig {
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Complete configuration for client-side embed hosts (React host, Pages Router host).
|
|
214
|
+
* Combines {@link ConsumeClientConfig} with {@link ConsumeLifecycleCallbacks}.
|
|
215
|
+
*
|
|
216
|
+
* This is the base type for public-facing props on hosts that fetch and mount
|
|
217
|
+
* remote components on the client. The App Router server host uses only
|
|
218
|
+
* {@link ConsumeServerConfig} since RSC cannot accept function callbacks.
|
|
219
|
+
*/
|
|
220
|
+
interface ConsumeRemoteComponentConfig extends ConsumeClientConfig, ConsumeLifecycleCallbacks {
|
|
221
|
+
}
|
|
222
|
+
/** Information provided to the `onChange` lifecycle callback. */
|
|
223
|
+
interface ChangeInfo {
|
|
224
|
+
previousSrc: string | URL | null;
|
|
225
|
+
nextSrc: string | URL | null;
|
|
226
|
+
previousName: string | undefined;
|
|
227
|
+
nextName: string | undefined;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Lifecycle callbacks shared by host and remote component implementations.
|
|
231
|
+
*
|
|
232
|
+
* On the host side, these fire during client-side loading (the React host
|
|
233
|
+
* exposes them as callback props; the HTML host dispatches DOM events).
|
|
234
|
+
* On the remote side (Next.js `<ExposeRemoteComponent>` wrapper), the callbacks
|
|
235
|
+
* are forwarded as `data-on-*` attributes so the host can wire them up.
|
|
236
|
+
*
|
|
237
|
+
* Server-only components (e.g. Next.js App Router server host) do not
|
|
238
|
+
* support these callbacks since they render once on the server.
|
|
239
|
+
*/
|
|
240
|
+
interface ConsumeLifecycleCallbacks {
|
|
241
|
+
/** Called right before a new remote component load starts. */
|
|
242
|
+
onBeforeLoad?: (src: string | URL) => void;
|
|
243
|
+
/** Called when the remote component has been successfully loaded and mounted. */
|
|
244
|
+
onLoad?: (src: string | URL) => void;
|
|
245
|
+
/** Called when an error occurs while loading or mounting the remote component. */
|
|
246
|
+
onError?: (error: unknown) => void;
|
|
247
|
+
/** Called when a different remote component is loaded into the same wrapper. */
|
|
248
|
+
onChange?: (info: ChangeInfo) => void;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Props for the React remote component host.
|
|
253
|
+
*
|
|
254
|
+
* Extends {@link ConsumeRemoteComponentConfig} with `children` for loading fallback content.
|
|
255
|
+
*/
|
|
256
|
+
interface ConsumeRemoteComponentProps extends ConsumeRemoteComponentConfig {
|
|
257
|
+
/** Loading fallback content displayed while the remote component is being fetched. */
|
|
258
|
+
children?: React.ReactNode;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* ConsumeRemoteComponent is a React component that fetches and renders a remote component.
|
|
262
|
+
* It supports SSR and can isolate the remote component in a shadow DOM.
|
|
263
|
+
*
|
|
264
|
+
* @param props - The properties for the remote component.
|
|
265
|
+
* @returns A React component that renders the remote component.
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
*
|
|
269
|
+
* Use the `<ConsumeRemoteComponent>` in your React application to consume a remote component from a remote application:
|
|
270
|
+
*
|
|
271
|
+
* ```tsx
|
|
272
|
+
* import { ConsumeRemoteComponent } from 'remote-components/host/react';
|
|
273
|
+
*
|
|
274
|
+
* export default function App() {
|
|
275
|
+
* return (
|
|
276
|
+
* <>
|
|
277
|
+
* <h1>Welcome to My App</h1>
|
|
278
|
+
* <p>This page consumes a remote component from another application.</p>
|
|
279
|
+
* <ConsumeRemoteComponent src="/nextjs-app-remote/components/header" />
|
|
280
|
+
* </>
|
|
281
|
+
* );
|
|
282
|
+
* }
|
|
283
|
+
* ```
|
|
284
|
+
*
|
|
285
|
+
* To share modules, you can provide a shared module map with references to the shared modules:
|
|
286
|
+
*
|
|
287
|
+
* ```tsx
|
|
288
|
+
* <ConsumeRemoteComponent
|
|
289
|
+
* src="/nextjs-app-remote/components/header"
|
|
290
|
+
* shared={{
|
|
291
|
+
* '@/components/provider': () => import('@/components/host-provider')
|
|
292
|
+
* }}
|
|
293
|
+
* />
|
|
294
|
+
* ```
|
|
295
|
+
*/
|
|
296
|
+
declare function ConsumeRemoteComponent({ src, isolate, mode, reset, credentials: credentialsProp, name: nameProp, shared: sharedProp, children, onBeforeLoad, onLoad, onError, onChange, onRequest, onResponse, resolveClientUrl: resolveClientUrlProp, }: ConsumeRemoteComponentProps): react_jsx_runtime.JSX.Element;
|
|
297
|
+
|
|
298
|
+
export { ConsumeClientOnlyConfig as C, HookOptions as H, OnRequestHook as O, ConsumeRemoteComponentProps as a, ConsumeRemoteComponent as b, OnResponseHook as c };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
|
|
3
3
|
declare function nextClientPagesLoader(bundle: string, route: string, styleContainer?: HTMLHeadElement | ShadowRoot | null): {
|
|
4
|
-
Component:
|
|
5
|
-
App:
|
|
4
|
+
Component: react.ComponentType<Record<string, unknown>> | null | undefined;
|
|
5
|
+
App: react.ComponentType<{
|
|
6
6
|
Component: React.ComponentType<Record<string, unknown>>;
|
|
7
7
|
} & Record<string, unknown>> | null | undefined;
|
|
8
8
|
};
|
|
@@ -33,10 +33,8 @@ __export(app_client_exports, {
|
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(app_client_exports);
|
|
35
35
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
36
|
-
var Image = __toESM(require("next/image"), 1);
|
|
37
36
|
var import_react = require("react");
|
|
38
37
|
var import_react_dom = require("react-dom");
|
|
39
|
-
var import_image_impl = require("#internal/host/nextjs/image-impl");
|
|
40
38
|
var import_image_shared = require("#internal/host/nextjs/image-shared");
|
|
41
39
|
var import_use_resolve_client_url = require("#internal/host/react/hooks/use-resolve-client-url");
|
|
42
40
|
var import_get_client_or_server_url = require("#internal/host/server/get-client-or-server-url");
|
|
@@ -253,9 +251,7 @@ function ConsumeRemoteComponentClient({
|
|
|
253
251
|
return {
|
|
254
252
|
"next/router": import_app_compat.routerImpl,
|
|
255
253
|
...shared,
|
|
256
|
-
...(0, import_image_shared.
|
|
257
|
-
() => (0, import_image_impl.imageImpl)(Image.default, bundle, resolveClientUrl)
|
|
258
|
-
)
|
|
254
|
+
...(0, import_image_shared.createImageLoaderSharedEntries)({ bound: resolveClientUrl })
|
|
259
255
|
};
|
|
260
256
|
})(),
|
|
261
257
|
remoteShared,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/host/nextjs/app-client.tsx"],"sourcesContent":["'use client';\n\nimport * as Image from 'next/image';\nimport {\n startTransition,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { imageImpl } from '#internal/host/nextjs/image-impl';\nimport { createNextImageSharedEntries } from '#internal/host/nextjs/image-shared';\nimport { useResolveClientUrl } from '#internal/host/react/hooks/use-resolve-client-url';\nimport { getClientOrServerUrl } from '#internal/host/server/get-client-or-server-url';\nimport type { ConsumeClientOnlyConfig } from '#internal/host/shared/config';\nimport type { ConsumeServerData } from '#internal/host/shared/server-handoff';\nimport { createHostState } from '#internal/host/shared/state';\nimport { DEFAULT_ROUTE, RUNTIME_WEBPACK } from '#internal/runtime/constants';\nimport { loadRemoteComponent } from '#internal/runtime/loaders/component-loader';\nimport { loadStaticRemoteComponent } from '#internal/runtime/loaders/static-loader';\nimport type { MountOrUnmountFunction } from '#internal/runtime/types';\nimport { escapeString } from '#internal/utils';\nimport { logError } from '#internal/utils/logger';\nimport { routerImpl } from './app-compat';\nimport { RemoteComponentLinks } from './remote-component-links';\n\n/**\n * Extends the RSC-serializable data with {@link ConsumeClientConfig} fields\n * (like `resolveClientUrl`) that can't cross the server→client boundary\n * but are accepted when this component is used directly as a client import.\n */\ninterface ConsumeRemoteComponentClientProps\n extends ConsumeServerData,\n ConsumeClientOnlyConfig {}\n\n// import { shared } from 'remote-components/shared/host';\nasync function tryImportShared() {\n try {\n const { shared } = await import('#remote-components/host/defaults/app');\n return shared;\n } catch {\n return {};\n }\n}\n\n/**\n * ConsumeRemoteComponentClient - Main component for rendering remote components\n *\n * This component handles the loading and rendering of remote microfrontends.\n * It supports both RSC (React Server Components) and Next.js Pages Router based components.\n */\nexport function ConsumeRemoteComponentClient({\n src,\n serverUrl,\n name,\n bundle,\n route = DEFAULT_ROUTE,\n runtime = RUNTIME_WEBPACK,\n data,\n nextData,\n scripts = [],\n links = [],\n remoteShared = {},\n isolate,\n mode = 'open',\n resolveClientUrl: resolveClientUrlProp,\n reset,\n type,\n children,\n}: ConsumeRemoteComponentClientProps) {\n const remoteComponentId = useId();\n const [component, setComponent] = useState<React.ReactNode | Error>(null);\n const url = getClientOrServerUrl(src, serverUrl);\n const resolveClientUrl = useResolveClientUrl(resolveClientUrlProp, url.href);\n // TODO: prev* fields and abortController are not populated — the App Router\n // client doesn't support onChange or abort yet. Populate these when adding\n // onChange lifecycle support to match the HTML and React hosts.\n const hostStateRef = useRef(createHostState());\n const metadataRef = useRef<{\n name: string;\n bundle: string;\n route: string;\n url: string;\n }>({\n name,\n bundle,\n route,\n url: url.href,\n });\n const startRef = useRef<HTMLTemplateElement | null>(null);\n const endRef = useRef<HTMLTemplateElement | null>(null);\n const prevRemoteComponentUnmountRef = useRef<{\n unmount: Set<MountOrUnmountFunction>;\n root: ShadowRoot | DocumentFragment | null;\n } | null>(null);\n\n // Handle errors by re-throwing them\n if (component instanceof Error) {\n throw component;\n }\n\n // determine whether to use children or loaded component\n const shouldUseChildren =\n (!component ||\n (component &&\n !nextData &&\n type !== 'remote-component' &&\n typeof (component as unknown as Promise<unknown>).then !==\n 'function')) &&\n // if the remote Next.js Pages Router application is in development mode\n // we don't use the provided static HTML\n // to mitigate layout shift when loading CSS using JavaScript on the client\n nextData?.buildId !== 'development';\n\n // The pathname is used so this URL is the same across server and client requests for relative src's\n const keySuffix = `${escapeString(bundle)}_${escapeString(\n url.pathname,\n )}_${escapeString(name)}`;\n\n const self = globalThis as Record<\n `__remote_components_shadowroot_${string}`,\n ShadowRoot | null\n > &\n Record<`__remote_components_container_${string}`, HTMLDivElement | null>;\n const shadowRootKey = `__remote_components_shadowroot_${keySuffix}` as const;\n const shadowContainerRef = useRef<HTMLDivElement | null>(\n typeof document === 'undefined'\n ? null\n : document.querySelector(\n `[data-remote-component-id=\"shadowroot_${remoteComponentId}\"]`,\n ),\n );\n const shadowRootRef = useRef<ShadowRoot | null>(\n self[shadowRootKey] ?? shadowContainerRef.current?.shadowRoot ?? null,\n );\n const ssrShadowRootContentRef = useRef<NodeListOf<ChildNode> | null>(\n shadowRootRef.current?.querySelectorAll('*') ?? null,\n );\n const ssrLinksStylesRef = useRef<(HTMLLinkElement | HTMLStyleElement)[]>([]);\n\n if (self[shadowRootKey] && shadowRootRef.current) {\n self[shadowRootKey] = null;\n }\n\n useLayoutEffect(() => {\n if (\n !shadowContainerRef.current ||\n shadowContainerRef.current !== shadowRootRef.current?.host\n ) {\n shadowRootRef.current = null;\n }\n\n if (\n isolate !== false &&\n typeof document !== 'undefined' &&\n !shadowRootRef.current\n ) {\n let shadowRootElement: ShadowRoot | null = null;\n const element = shadowContainerRef.current;\n\n shadowRootElement = self[shadowRootKey] ?? element?.shadowRoot ?? null;\n self[shadowRootKey] = null;\n\n if (!shadowRootElement && element) {\n // create a shadow root if it doesn't exist\n // this is a fallback for browsers that don't support declarative shadow DOM\n try {\n shadowRootElement = element.attachShadow({ mode });\n } catch {\n // do nothing if attachShadow fails because of existing shadow root\n }\n }\n\n if (shadowRootElement) {\n shadowRootRef.current = shadowRootElement;\n }\n }\n\n if (\n shadowRootRef.current &&\n ssrShadowRootContentRef.current &&\n !shouldUseChildren\n ) {\n // remove all nodes from the shadow root except links\n ssrShadowRootContentRef.current.forEach((node) => {\n if (node.nodeName !== 'LINK' && node.nodeName !== 'STYLE') {\n node.parentNode?.removeChild(node);\n } else {\n ssrLinksStylesRef.current.push(\n node as HTMLLinkElement | HTMLStyleElement,\n );\n }\n });\n ssrShadowRootContentRef.current = null;\n }\n\n if (ssrLinksStylesRef.current.length > 0 && shadowRootRef.current) {\n const waitForLoad =\n shadowRootRef.current.querySelectorAll('link[data-wait]');\n if (waitForLoad.length > 0) {\n Promise.all(\n Array.from(waitForLoad).map(\n (link) =>\n new Promise<void>((resolve) => {\n link.addEventListener('load', () => resolve());\n link.addEventListener('error', () => resolve());\n }),\n ),\n )\n .then(() => {\n waitForLoad.forEach((el) => {\n el.removeAttribute('data-wait');\n });\n\n // remove SSR injected styles and links\n ssrLinksStylesRef.current.forEach((el) => {\n el.parentNode?.removeChild(el);\n });\n ssrLinksStylesRef.current = [];\n })\n .catch((e) => {\n logError('NextAppRouter', 'Error in cleanup.', e);\n });\n }\n }\n }, [isolate, mode, self, shadowRootKey, shouldUseChildren]);\n\n useEffect(() => {\n // run unmount functions when the component changes or unmounts\n if (prevRemoteComponentUnmountRef.current && component !== children) {\n const { unmount, root } = prevRemoteComponentUnmountRef.current;\n prevRemoteComponentUnmountRef.current = null;\n Promise.all(\n Array.from(unmount).map(async (unmountFn) => {\n try {\n await unmountFn(root);\n } catch (e) {\n logError('NextAppRouter', 'Error in unmount.', e);\n }\n }),\n ).catch((e) => {\n logError('NextAppRouter', 'Error in unmount cleanup.', e);\n });\n }\n }, [component, children]);\n\n useEffect(() => {\n startTransition(async () => {\n try {\n // if we have a component, we don't need to load it again\n if (\n (hostStateRef.current.stage !== 'loading' &&\n !component &&\n (isolate === false || shadowRootRef.current)) ||\n metadataRef.current.url !== url.href ||\n metadataRef.current.name !== name ||\n metadataRef.current.bundle !== bundle ||\n metadataRef.current.route !== route\n ) {\n hostStateRef.current.stage = 'loading';\n metadataRef.current = {\n name,\n bundle,\n route,\n url: url.href,\n };\n\n // use the children as the component when type is remote-component\n if (type === 'remote-component') {\n setComponent(children);\n // load static scripts and execute mount functions\n // run this async but don't await it as we render children immediately\n loadStaticRemoteComponent(\n scripts as HTMLScriptElement[],\n url,\n resolveClientUrl,\n )\n .then(({ mount, unmount }) => {\n if (mount.size > 0) {\n let root: ShadowRoot | DocumentFragment | null =\n shadowRootRef.current;\n try {\n if (!root && startRef.current && endRef.current) {\n root = document.querySelectorAll(\n `#${startRef.current.id} ~ *:not(#${endRef.current.id}):has(~ #${endRef.current.id})`,\n ) as unknown as DocumentFragment;\n }\n } catch (e) {\n logError('NextAppRouter', 'Error finding root element.', e);\n }\n if (unmount.size > 0) {\n prevRemoteComponentUnmountRef.current = { unmount, root };\n }\n return Promise.all(\n Array.from(mount).map((mountFn) => mountFn(root)),\n );\n }\n })\n .catch((e) => {\n logError(\n 'NextAppRouter',\n 'Error loading static remote component.',\n e,\n );\n setComponent(e as Error);\n });\n return;\n }\n\n const rscName = `__remote_components_rsc_${keySuffix}`;\n const result = await loadRemoteComponent({\n url,\n name,\n bundle,\n route,\n runtime,\n rscName,\n data,\n nextData,\n scripts,\n shared: (async () => {\n const shared = await tryImportShared();\n\n if ('__remote_components_missing_shared__' in shared) {\n await shared.__remote_components_missing_shared__();\n }\n return {\n 'next/router': routerImpl,\n ...shared,\n ...createNextImageSharedEntries(() =>\n imageImpl(Image.default, bundle, resolveClientUrl),\n ),\n };\n })(),\n remoteShared,\n container: shadowRootRef.current,\n resolveClientUrl,\n });\n if (result.error) {\n hostStateRef.current.stage = 'error';\n setComponent(result.error);\n } else {\n hostStateRef.current.stage = 'loaded';\n setComponent(result.component);\n }\n }\n } catch (error: unknown) {\n hostStateRef.current.stage = 'error';\n setComponent(error as Error);\n }\n });\n }, [\n component,\n name,\n bundle,\n route,\n runtime,\n scripts,\n data,\n nextData,\n remoteShared,\n children,\n isolate,\n type,\n keySuffix,\n url,\n resolveClientUrl,\n ]);\n\n if (\n nextData?.buildId === 'development' &&\n shadowRootRef.current &&\n isolate !== false &&\n reset &&\n !shadowRootRef.current.querySelector('[data-remote-components-reset]')\n ) {\n // inject reset styles into the shadow root\n const style = document.createElement('style');\n style.setAttribute('data-remote-components-reset', '');\n style.textContent = `:host { all: initial; }`;\n shadowRootRef.current.insertBefore(style, shadowRootRef.current.firstChild);\n } else if (\n shadowRootRef.current &&\n isolate !== false &&\n !reset &&\n shadowRootRef.current.querySelector('[data-remote-components-reset]')\n ) {\n // ensure reset styles are the first child in the shadow root\n const style = shadowRootRef.current.querySelector(\n '[data-remote-components-reset]',\n );\n if (style && shadowRootRef.current.firstChild !== style) {\n shadowRootRef.current.removeChild(style);\n }\n }\n\n const linksToRender = (\n <RemoteComponentLinks\n links={links}\n url={url}\n serverUrl={serverUrl}\n bundle={bundle}\n isolate={isolate}\n reset={reset}\n isDevelopment={nextData?.buildId === 'development'}\n />\n );\n\n let componentToRender = shouldUseChildren\n ? children\n : (component as React.ReactNode);\n\n if (isolate !== false) {\n componentToRender = (\n <div\n data-remote-component-id={`shadowroot_${remoteComponentId}`}\n data-remote-component-isolation-root=\"\"\n id={`shadowroot_${name}`}\n ref={shadowContainerRef}\n >\n {typeof document === 'undefined' ? (\n // eslint-disable-next-line react/no-unknown-property\n <template shadowrootmode={mode}>\n {mode === 'closed' ? (\n <div\n dangerouslySetInnerHTML={{\n __html: `<img\n alt=\"\" decoding=\"async\" style=\"display:none\"\n src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==\"\n onload=\"(function(el){\n const root = el.getRootNode();\n globalThis.${shadowRootKey} = root;\n el.parentElement.remove();\n })(this)\"\n />`,\n }}\n />\n ) : null}\n {linksToRender}\n {shouldUseChildren ? children : null}\n </template>\n ) : null}\n {typeof document !== 'undefined' &&\n shadowRootRef.current &&\n !shouldUseChildren\n ? createPortal(\n <>\n {linksToRender}\n {componentToRender}\n </>,\n shadowRootRef.current,\n )\n : null}\n </div>\n );\n }\n\n return (\n <>\n {isolate === false ? (\n <template id={`${name}_start`} ref={startRef} />\n ) : null}\n <script data-remote-component type=\"application/json\">\n {JSON.stringify({\n name,\n bundle,\n route,\n runtime,\n })}\n </script>\n {isolate === false ? linksToRender : null}\n {componentToRender}\n {nextData ? (\n <script\n id={`${bundle}_${route.replace(\n /[^a-zA-Z0-9]+/g,\n '_',\n )}${name}_next_data`}\n type=\"application/json\"\n >\n {JSON.stringify(nextData)}\n </script>\n ) : null}\n {isolate === false ? <template id={`${name}_end`} ref={endRef} /> : null}\n </>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/nextjs/app-client.tsx"],"sourcesContent":["'use client';\n\nimport {\n startTransition,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { createImageLoaderSharedEntries } from '#internal/host/nextjs/image-shared';\nimport { useResolveClientUrl } from '#internal/host/react/hooks/use-resolve-client-url';\nimport { getClientOrServerUrl } from '#internal/host/server/get-client-or-server-url';\nimport type { ConsumeClientOnlyConfig } from '#internal/host/shared/config';\nimport type { ConsumeServerData } from '#internal/host/shared/server-handoff';\nimport { createHostState } from '#internal/host/shared/state';\nimport { DEFAULT_ROUTE, RUNTIME_WEBPACK } from '#internal/runtime/constants';\nimport { loadRemoteComponent } from '#internal/runtime/loaders/component-loader';\nimport { loadStaticRemoteComponent } from '#internal/runtime/loaders/static-loader';\nimport type { MountOrUnmountFunction } from '#internal/runtime/types';\nimport { escapeString } from '#internal/utils';\nimport { logError } from '#internal/utils/logger';\nimport { routerImpl } from './app-compat';\nimport { RemoteComponentLinks } from './remote-component-links';\n\n/**\n * Extends the RSC-serializable data with {@link ConsumeClientConfig} fields\n * (like `resolveClientUrl`) that can't cross the server→client boundary\n * but are accepted when this component is used directly as a client import.\n */\ninterface ConsumeRemoteComponentClientProps\n extends ConsumeServerData,\n ConsumeClientOnlyConfig {}\n\n// import { shared } from 'remote-components/shared/host';\nasync function tryImportShared() {\n try {\n const { shared } = await import('#remote-components/host/defaults/app');\n return shared;\n } catch {\n return {};\n }\n}\n\n/**\n * ConsumeRemoteComponentClient - Main component for rendering remote components\n *\n * This component handles the loading and rendering of remote microfrontends.\n * It supports both RSC (React Server Components) and Next.js Pages Router based components.\n */\nexport function ConsumeRemoteComponentClient({\n src,\n serverUrl,\n name,\n bundle,\n route = DEFAULT_ROUTE,\n runtime = RUNTIME_WEBPACK,\n data,\n nextData,\n scripts = [],\n links = [],\n remoteShared = {},\n isolate,\n mode = 'open',\n resolveClientUrl: resolveClientUrlProp,\n reset,\n type,\n children,\n}: ConsumeRemoteComponentClientProps) {\n const remoteComponentId = useId();\n const [component, setComponent] = useState<React.ReactNode | Error>(null);\n const url = getClientOrServerUrl(src, serverUrl);\n const resolveClientUrl = useResolveClientUrl(resolveClientUrlProp, url.href);\n // TODO: prev* fields and abortController are not populated — the App Router\n // client doesn't support onChange or abort yet. Populate these when adding\n // onChange lifecycle support to match the HTML and React hosts.\n const hostStateRef = useRef(createHostState());\n const metadataRef = useRef<{\n name: string;\n bundle: string;\n route: string;\n url: string;\n }>({\n name,\n bundle,\n route,\n url: url.href,\n });\n const startRef = useRef<HTMLTemplateElement | null>(null);\n const endRef = useRef<HTMLTemplateElement | null>(null);\n const prevRemoteComponentUnmountRef = useRef<{\n unmount: Set<MountOrUnmountFunction>;\n root: ShadowRoot | DocumentFragment | null;\n } | null>(null);\n\n // Handle errors by re-throwing them\n if (component instanceof Error) {\n throw component;\n }\n\n // determine whether to use children or loaded component\n const shouldUseChildren =\n (!component ||\n (component &&\n !nextData &&\n type !== 'remote-component' &&\n typeof (component as unknown as Promise<unknown>).then !==\n 'function')) &&\n // if the remote Next.js Pages Router application is in development mode\n // we don't use the provided static HTML\n // to mitigate layout shift when loading CSS using JavaScript on the client\n nextData?.buildId !== 'development';\n\n // The pathname is used so this URL is the same across server and client requests for relative src's\n const keySuffix = `${escapeString(bundle)}_${escapeString(\n url.pathname,\n )}_${escapeString(name)}`;\n\n const self = globalThis as Record<\n `__remote_components_shadowroot_${string}`,\n ShadowRoot | null\n > &\n Record<`__remote_components_container_${string}`, HTMLDivElement | null>;\n const shadowRootKey = `__remote_components_shadowroot_${keySuffix}` as const;\n const shadowContainerRef = useRef<HTMLDivElement | null>(\n typeof document === 'undefined'\n ? null\n : document.querySelector(\n `[data-remote-component-id=\"shadowroot_${remoteComponentId}\"]`,\n ),\n );\n const shadowRootRef = useRef<ShadowRoot | null>(\n self[shadowRootKey] ?? shadowContainerRef.current?.shadowRoot ?? null,\n );\n const ssrShadowRootContentRef = useRef<NodeListOf<ChildNode> | null>(\n shadowRootRef.current?.querySelectorAll('*') ?? null,\n );\n const ssrLinksStylesRef = useRef<(HTMLLinkElement | HTMLStyleElement)[]>([]);\n\n if (self[shadowRootKey] && shadowRootRef.current) {\n self[shadowRootKey] = null;\n }\n\n useLayoutEffect(() => {\n if (\n !shadowContainerRef.current ||\n shadowContainerRef.current !== shadowRootRef.current?.host\n ) {\n shadowRootRef.current = null;\n }\n\n if (\n isolate !== false &&\n typeof document !== 'undefined' &&\n !shadowRootRef.current\n ) {\n let shadowRootElement: ShadowRoot | null = null;\n const element = shadowContainerRef.current;\n\n shadowRootElement = self[shadowRootKey] ?? element?.shadowRoot ?? null;\n self[shadowRootKey] = null;\n\n if (!shadowRootElement && element) {\n // create a shadow root if it doesn't exist\n // this is a fallback for browsers that don't support declarative shadow DOM\n try {\n shadowRootElement = element.attachShadow({ mode });\n } catch {\n // do nothing if attachShadow fails because of existing shadow root\n }\n }\n\n if (shadowRootElement) {\n shadowRootRef.current = shadowRootElement;\n }\n }\n\n if (\n shadowRootRef.current &&\n ssrShadowRootContentRef.current &&\n !shouldUseChildren\n ) {\n // remove all nodes from the shadow root except links\n ssrShadowRootContentRef.current.forEach((node) => {\n if (node.nodeName !== 'LINK' && node.nodeName !== 'STYLE') {\n node.parentNode?.removeChild(node);\n } else {\n ssrLinksStylesRef.current.push(\n node as HTMLLinkElement | HTMLStyleElement,\n );\n }\n });\n ssrShadowRootContentRef.current = null;\n }\n\n if (ssrLinksStylesRef.current.length > 0 && shadowRootRef.current) {\n const waitForLoad =\n shadowRootRef.current.querySelectorAll('link[data-wait]');\n if (waitForLoad.length > 0) {\n Promise.all(\n Array.from(waitForLoad).map(\n (link) =>\n new Promise<void>((resolve) => {\n link.addEventListener('load', () => resolve());\n link.addEventListener('error', () => resolve());\n }),\n ),\n )\n .then(() => {\n waitForLoad.forEach((el) => {\n el.removeAttribute('data-wait');\n });\n\n // remove SSR injected styles and links\n ssrLinksStylesRef.current.forEach((el) => {\n el.parentNode?.removeChild(el);\n });\n ssrLinksStylesRef.current = [];\n })\n .catch((e) => {\n logError('NextAppRouter', 'Error in cleanup.', e);\n });\n }\n }\n }, [isolate, mode, self, shadowRootKey, shouldUseChildren]);\n\n useEffect(() => {\n // run unmount functions when the component changes or unmounts\n if (prevRemoteComponentUnmountRef.current && component !== children) {\n const { unmount, root } = prevRemoteComponentUnmountRef.current;\n prevRemoteComponentUnmountRef.current = null;\n Promise.all(\n Array.from(unmount).map(async (unmountFn) => {\n try {\n await unmountFn(root);\n } catch (e) {\n logError('NextAppRouter', 'Error in unmount.', e);\n }\n }),\n ).catch((e) => {\n logError('NextAppRouter', 'Error in unmount cleanup.', e);\n });\n }\n }, [component, children]);\n\n useEffect(() => {\n startTransition(async () => {\n try {\n // if we have a component, we don't need to load it again\n if (\n (hostStateRef.current.stage !== 'loading' &&\n !component &&\n (isolate === false || shadowRootRef.current)) ||\n metadataRef.current.url !== url.href ||\n metadataRef.current.name !== name ||\n metadataRef.current.bundle !== bundle ||\n metadataRef.current.route !== route\n ) {\n hostStateRef.current.stage = 'loading';\n metadataRef.current = {\n name,\n bundle,\n route,\n url: url.href,\n };\n\n // use the children as the component when type is remote-component\n if (type === 'remote-component') {\n setComponent(children);\n // load static scripts and execute mount functions\n // run this async but don't await it as we render children immediately\n loadStaticRemoteComponent(\n scripts as HTMLScriptElement[],\n url,\n resolveClientUrl,\n )\n .then(({ mount, unmount }) => {\n if (mount.size > 0) {\n let root: ShadowRoot | DocumentFragment | null =\n shadowRootRef.current;\n try {\n if (!root && startRef.current && endRef.current) {\n root = document.querySelectorAll(\n `#${startRef.current.id} ~ *:not(#${endRef.current.id}):has(~ #${endRef.current.id})`,\n ) as unknown as DocumentFragment;\n }\n } catch (e) {\n logError('NextAppRouter', 'Error finding root element.', e);\n }\n if (unmount.size > 0) {\n prevRemoteComponentUnmountRef.current = { unmount, root };\n }\n return Promise.all(\n Array.from(mount).map((mountFn) => mountFn(root)),\n );\n }\n })\n .catch((e) => {\n logError(\n 'NextAppRouter',\n 'Error loading static remote component.',\n e,\n );\n setComponent(e as Error);\n });\n return;\n }\n\n const rscName = `__remote_components_rsc_${keySuffix}`;\n const result = await loadRemoteComponent({\n url,\n name,\n bundle,\n route,\n runtime,\n rscName,\n data,\n nextData,\n scripts,\n shared: (async () => {\n const shared = await tryImportShared();\n\n if ('__remote_components_missing_shared__' in shared) {\n await shared.__remote_components_missing_shared__();\n }\n return {\n 'next/router': routerImpl,\n ...shared,\n ...createImageLoaderSharedEntries({ bound: resolveClientUrl }),\n };\n })(),\n remoteShared,\n container: shadowRootRef.current,\n resolveClientUrl,\n });\n if (result.error) {\n hostStateRef.current.stage = 'error';\n setComponent(result.error);\n } else {\n hostStateRef.current.stage = 'loaded';\n setComponent(result.component);\n }\n }\n } catch (error: unknown) {\n hostStateRef.current.stage = 'error';\n setComponent(error as Error);\n }\n });\n }, [\n component,\n name,\n bundle,\n route,\n runtime,\n scripts,\n data,\n nextData,\n remoteShared,\n children,\n isolate,\n type,\n keySuffix,\n url,\n resolveClientUrl,\n ]);\n\n if (\n nextData?.buildId === 'development' &&\n shadowRootRef.current &&\n isolate !== false &&\n reset &&\n !shadowRootRef.current.querySelector('[data-remote-components-reset]')\n ) {\n // inject reset styles into the shadow root\n const style = document.createElement('style');\n style.setAttribute('data-remote-components-reset', '');\n style.textContent = `:host { all: initial; }`;\n shadowRootRef.current.insertBefore(style, shadowRootRef.current.firstChild);\n } else if (\n shadowRootRef.current &&\n isolate !== false &&\n !reset &&\n shadowRootRef.current.querySelector('[data-remote-components-reset]')\n ) {\n // ensure reset styles are the first child in the shadow root\n const style = shadowRootRef.current.querySelector(\n '[data-remote-components-reset]',\n );\n if (style && shadowRootRef.current.firstChild !== style) {\n shadowRootRef.current.removeChild(style);\n }\n }\n\n const linksToRender = (\n <RemoteComponentLinks\n links={links}\n url={url}\n serverUrl={serverUrl}\n bundle={bundle}\n isolate={isolate}\n reset={reset}\n isDevelopment={nextData?.buildId === 'development'}\n />\n );\n\n let componentToRender = shouldUseChildren\n ? children\n : (component as React.ReactNode);\n\n if (isolate !== false) {\n componentToRender = (\n <div\n data-remote-component-id={`shadowroot_${remoteComponentId}`}\n data-remote-component-isolation-root=\"\"\n id={`shadowroot_${name}`}\n ref={shadowContainerRef}\n >\n {typeof document === 'undefined' ? (\n // eslint-disable-next-line react/no-unknown-property\n <template shadowrootmode={mode}>\n {mode === 'closed' ? (\n <div\n dangerouslySetInnerHTML={{\n __html: `<img\n alt=\"\" decoding=\"async\" style=\"display:none\"\n src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==\"\n onload=\"(function(el){\n const root = el.getRootNode();\n globalThis.${shadowRootKey} = root;\n el.parentElement.remove();\n })(this)\"\n />`,\n }}\n />\n ) : null}\n {linksToRender}\n {shouldUseChildren ? children : null}\n </template>\n ) : null}\n {typeof document !== 'undefined' &&\n shadowRootRef.current &&\n !shouldUseChildren\n ? createPortal(\n <>\n {linksToRender}\n {componentToRender}\n </>,\n shadowRootRef.current,\n )\n : null}\n </div>\n );\n }\n\n return (\n <>\n {isolate === false ? (\n <template id={`${name}_start`} ref={startRef} />\n ) : null}\n <script data-remote-component type=\"application/json\">\n {JSON.stringify({\n name,\n bundle,\n route,\n runtime,\n })}\n </script>\n {isolate === false ? linksToRender : null}\n {componentToRender}\n {nextData ? (\n <script\n id={`${bundle}_${route.replace(\n /[^a-zA-Z0-9]+/g,\n '_',\n )}${name}_next_data`}\n type=\"application/json\"\n >\n {JSON.stringify(nextData)}\n </script>\n ) : null}\n {isolate === false ? <template id={`${name}_end`} ref={endRef} /> : null}\n </>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ConsumeClientOnlyConfig } from '../shared/config.js';
|
|
3
|
-
import { C as ConsumeServerData } from '../../../server-handoff-
|
|
3
|
+
import { C as ConsumeServerData } from '../../../server-handoff-ce13bebc.js';
|
|
4
4
|
import '../../runtime/url/resolve-client-url.js';
|
|
5
5
|
import '../shared/fetch-interceptors.js';
|
|
6
6
|
import 'react';
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import * as Image from "next/image";
|
|
4
3
|
import {
|
|
5
4
|
startTransition,
|
|
6
5
|
useEffect,
|
|
@@ -10,8 +9,7 @@ import {
|
|
|
10
9
|
useState
|
|
11
10
|
} from "react";
|
|
12
11
|
import { createPortal } from "react-dom";
|
|
13
|
-
import {
|
|
14
|
-
import { createNextImageSharedEntries } from "#internal/host/nextjs/image-shared";
|
|
12
|
+
import { createImageLoaderSharedEntries } from "#internal/host/nextjs/image-shared";
|
|
15
13
|
import { useResolveClientUrl } from "#internal/host/react/hooks/use-resolve-client-url";
|
|
16
14
|
import { getClientOrServerUrl } from "#internal/host/server/get-client-or-server-url";
|
|
17
15
|
import { createHostState } from "#internal/host/shared/state";
|
|
@@ -227,9 +225,7 @@ function ConsumeRemoteComponentClient({
|
|
|
227
225
|
return {
|
|
228
226
|
"next/router": routerImpl,
|
|
229
227
|
...shared,
|
|
230
|
-
...
|
|
231
|
-
() => imageImpl(Image.default, bundle, resolveClientUrl)
|
|
232
|
-
)
|
|
228
|
+
...createImageLoaderSharedEntries({ bound: resolveClientUrl })
|
|
233
229
|
};
|
|
234
230
|
})(),
|
|
235
231
|
remoteShared,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/host/nextjs/app-client.tsx"],"sourcesContent":["'use client';\n\nimport * as Image from 'next/image';\nimport {\n startTransition,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { imageImpl } from '#internal/host/nextjs/image-impl';\nimport { createNextImageSharedEntries } from '#internal/host/nextjs/image-shared';\nimport { useResolveClientUrl } from '#internal/host/react/hooks/use-resolve-client-url';\nimport { getClientOrServerUrl } from '#internal/host/server/get-client-or-server-url';\nimport type { ConsumeClientOnlyConfig } from '#internal/host/shared/config';\nimport type { ConsumeServerData } from '#internal/host/shared/server-handoff';\nimport { createHostState } from '#internal/host/shared/state';\nimport { DEFAULT_ROUTE, RUNTIME_WEBPACK } from '#internal/runtime/constants';\nimport { loadRemoteComponent } from '#internal/runtime/loaders/component-loader';\nimport { loadStaticRemoteComponent } from '#internal/runtime/loaders/static-loader';\nimport type { MountOrUnmountFunction } from '#internal/runtime/types';\nimport { escapeString } from '#internal/utils';\nimport { logError } from '#internal/utils/logger';\nimport { routerImpl } from './app-compat';\nimport { RemoteComponentLinks } from './remote-component-links';\n\n/**\n * Extends the RSC-serializable data with {@link ConsumeClientConfig} fields\n * (like `resolveClientUrl`) that can't cross the server→client boundary\n * but are accepted when this component is used directly as a client import.\n */\ninterface ConsumeRemoteComponentClientProps\n extends ConsumeServerData,\n ConsumeClientOnlyConfig {}\n\n// import { shared } from 'remote-components/shared/host';\nasync function tryImportShared() {\n try {\n const { shared } = await import('#remote-components/host/defaults/app');\n return shared;\n } catch {\n return {};\n }\n}\n\n/**\n * ConsumeRemoteComponentClient - Main component for rendering remote components\n *\n * This component handles the loading and rendering of remote microfrontends.\n * It supports both RSC (React Server Components) and Next.js Pages Router based components.\n */\nexport function ConsumeRemoteComponentClient({\n src,\n serverUrl,\n name,\n bundle,\n route = DEFAULT_ROUTE,\n runtime = RUNTIME_WEBPACK,\n data,\n nextData,\n scripts = [],\n links = [],\n remoteShared = {},\n isolate,\n mode = 'open',\n resolveClientUrl: resolveClientUrlProp,\n reset,\n type,\n children,\n}: ConsumeRemoteComponentClientProps) {\n const remoteComponentId = useId();\n const [component, setComponent] = useState<React.ReactNode | Error>(null);\n const url = getClientOrServerUrl(src, serverUrl);\n const resolveClientUrl = useResolveClientUrl(resolveClientUrlProp, url.href);\n // TODO: prev* fields and abortController are not populated — the App Router\n // client doesn't support onChange or abort yet. Populate these when adding\n // onChange lifecycle support to match the HTML and React hosts.\n const hostStateRef = useRef(createHostState());\n const metadataRef = useRef<{\n name: string;\n bundle: string;\n route: string;\n url: string;\n }>({\n name,\n bundle,\n route,\n url: url.href,\n });\n const startRef = useRef<HTMLTemplateElement | null>(null);\n const endRef = useRef<HTMLTemplateElement | null>(null);\n const prevRemoteComponentUnmountRef = useRef<{\n unmount: Set<MountOrUnmountFunction>;\n root: ShadowRoot | DocumentFragment | null;\n } | null>(null);\n\n // Handle errors by re-throwing them\n if (component instanceof Error) {\n throw component;\n }\n\n // determine whether to use children or loaded component\n const shouldUseChildren =\n (!component ||\n (component &&\n !nextData &&\n type !== 'remote-component' &&\n typeof (component as unknown as Promise<unknown>).then !==\n 'function')) &&\n // if the remote Next.js Pages Router application is in development mode\n // we don't use the provided static HTML\n // to mitigate layout shift when loading CSS using JavaScript on the client\n nextData?.buildId !== 'development';\n\n // The pathname is used so this URL is the same across server and client requests for relative src's\n const keySuffix = `${escapeString(bundle)}_${escapeString(\n url.pathname,\n )}_${escapeString(name)}`;\n\n const self = globalThis as Record<\n `__remote_components_shadowroot_${string}`,\n ShadowRoot | null\n > &\n Record<`__remote_components_container_${string}`, HTMLDivElement | null>;\n const shadowRootKey = `__remote_components_shadowroot_${keySuffix}` as const;\n const shadowContainerRef = useRef<HTMLDivElement | null>(\n typeof document === 'undefined'\n ? null\n : document.querySelector(\n `[data-remote-component-id=\"shadowroot_${remoteComponentId}\"]`,\n ),\n );\n const shadowRootRef = useRef<ShadowRoot | null>(\n self[shadowRootKey] ?? shadowContainerRef.current?.shadowRoot ?? null,\n );\n const ssrShadowRootContentRef = useRef<NodeListOf<ChildNode> | null>(\n shadowRootRef.current?.querySelectorAll('*') ?? null,\n );\n const ssrLinksStylesRef = useRef<(HTMLLinkElement | HTMLStyleElement)[]>([]);\n\n if (self[shadowRootKey] && shadowRootRef.current) {\n self[shadowRootKey] = null;\n }\n\n useLayoutEffect(() => {\n if (\n !shadowContainerRef.current ||\n shadowContainerRef.current !== shadowRootRef.current?.host\n ) {\n shadowRootRef.current = null;\n }\n\n if (\n isolate !== false &&\n typeof document !== 'undefined' &&\n !shadowRootRef.current\n ) {\n let shadowRootElement: ShadowRoot | null = null;\n const element = shadowContainerRef.current;\n\n shadowRootElement = self[shadowRootKey] ?? element?.shadowRoot ?? null;\n self[shadowRootKey] = null;\n\n if (!shadowRootElement && element) {\n // create a shadow root if it doesn't exist\n // this is a fallback for browsers that don't support declarative shadow DOM\n try {\n shadowRootElement = element.attachShadow({ mode });\n } catch {\n // do nothing if attachShadow fails because of existing shadow root\n }\n }\n\n if (shadowRootElement) {\n shadowRootRef.current = shadowRootElement;\n }\n }\n\n if (\n shadowRootRef.current &&\n ssrShadowRootContentRef.current &&\n !shouldUseChildren\n ) {\n // remove all nodes from the shadow root except links\n ssrShadowRootContentRef.current.forEach((node) => {\n if (node.nodeName !== 'LINK' && node.nodeName !== 'STYLE') {\n node.parentNode?.removeChild(node);\n } else {\n ssrLinksStylesRef.current.push(\n node as HTMLLinkElement | HTMLStyleElement,\n );\n }\n });\n ssrShadowRootContentRef.current = null;\n }\n\n if (ssrLinksStylesRef.current.length > 0 && shadowRootRef.current) {\n const waitForLoad =\n shadowRootRef.current.querySelectorAll('link[data-wait]');\n if (waitForLoad.length > 0) {\n Promise.all(\n Array.from(waitForLoad).map(\n (link) =>\n new Promise<void>((resolve) => {\n link.addEventListener('load', () => resolve());\n link.addEventListener('error', () => resolve());\n }),\n ),\n )\n .then(() => {\n waitForLoad.forEach((el) => {\n el.removeAttribute('data-wait');\n });\n\n // remove SSR injected styles and links\n ssrLinksStylesRef.current.forEach((el) => {\n el.parentNode?.removeChild(el);\n });\n ssrLinksStylesRef.current = [];\n })\n .catch((e) => {\n logError('NextAppRouter', 'Error in cleanup.', e);\n });\n }\n }\n }, [isolate, mode, self, shadowRootKey, shouldUseChildren]);\n\n useEffect(() => {\n // run unmount functions when the component changes or unmounts\n if (prevRemoteComponentUnmountRef.current && component !== children) {\n const { unmount, root } = prevRemoteComponentUnmountRef.current;\n prevRemoteComponentUnmountRef.current = null;\n Promise.all(\n Array.from(unmount).map(async (unmountFn) => {\n try {\n await unmountFn(root);\n } catch (e) {\n logError('NextAppRouter', 'Error in unmount.', e);\n }\n }),\n ).catch((e) => {\n logError('NextAppRouter', 'Error in unmount cleanup.', e);\n });\n }\n }, [component, children]);\n\n useEffect(() => {\n startTransition(async () => {\n try {\n // if we have a component, we don't need to load it again\n if (\n (hostStateRef.current.stage !== 'loading' &&\n !component &&\n (isolate === false || shadowRootRef.current)) ||\n metadataRef.current.url !== url.href ||\n metadataRef.current.name !== name ||\n metadataRef.current.bundle !== bundle ||\n metadataRef.current.route !== route\n ) {\n hostStateRef.current.stage = 'loading';\n metadataRef.current = {\n name,\n bundle,\n route,\n url: url.href,\n };\n\n // use the children as the component when type is remote-component\n if (type === 'remote-component') {\n setComponent(children);\n // load static scripts and execute mount functions\n // run this async but don't await it as we render children immediately\n loadStaticRemoteComponent(\n scripts as HTMLScriptElement[],\n url,\n resolveClientUrl,\n )\n .then(({ mount, unmount }) => {\n if (mount.size > 0) {\n let root: ShadowRoot | DocumentFragment | null =\n shadowRootRef.current;\n try {\n if (!root && startRef.current && endRef.current) {\n root = document.querySelectorAll(\n `#${startRef.current.id} ~ *:not(#${endRef.current.id}):has(~ #${endRef.current.id})`,\n ) as unknown as DocumentFragment;\n }\n } catch (e) {\n logError('NextAppRouter', 'Error finding root element.', e);\n }\n if (unmount.size > 0) {\n prevRemoteComponentUnmountRef.current = { unmount, root };\n }\n return Promise.all(\n Array.from(mount).map((mountFn) => mountFn(root)),\n );\n }\n })\n .catch((e) => {\n logError(\n 'NextAppRouter',\n 'Error loading static remote component.',\n e,\n );\n setComponent(e as Error);\n });\n return;\n }\n\n const rscName = `__remote_components_rsc_${keySuffix}`;\n const result = await loadRemoteComponent({\n url,\n name,\n bundle,\n route,\n runtime,\n rscName,\n data,\n nextData,\n scripts,\n shared: (async () => {\n const shared = await tryImportShared();\n\n if ('__remote_components_missing_shared__' in shared) {\n await shared.__remote_components_missing_shared__();\n }\n return {\n 'next/router': routerImpl,\n ...shared,\n ...createNextImageSharedEntries(() =>\n imageImpl(Image.default, bundle, resolveClientUrl),\n ),\n };\n })(),\n remoteShared,\n container: shadowRootRef.current,\n resolveClientUrl,\n });\n if (result.error) {\n hostStateRef.current.stage = 'error';\n setComponent(result.error);\n } else {\n hostStateRef.current.stage = 'loaded';\n setComponent(result.component);\n }\n }\n } catch (error: unknown) {\n hostStateRef.current.stage = 'error';\n setComponent(error as Error);\n }\n });\n }, [\n component,\n name,\n bundle,\n route,\n runtime,\n scripts,\n data,\n nextData,\n remoteShared,\n children,\n isolate,\n type,\n keySuffix,\n url,\n resolveClientUrl,\n ]);\n\n if (\n nextData?.buildId === 'development' &&\n shadowRootRef.current &&\n isolate !== false &&\n reset &&\n !shadowRootRef.current.querySelector('[data-remote-components-reset]')\n ) {\n // inject reset styles into the shadow root\n const style = document.createElement('style');\n style.setAttribute('data-remote-components-reset', '');\n style.textContent = `:host { all: initial; }`;\n shadowRootRef.current.insertBefore(style, shadowRootRef.current.firstChild);\n } else if (\n shadowRootRef.current &&\n isolate !== false &&\n !reset &&\n shadowRootRef.current.querySelector('[data-remote-components-reset]')\n ) {\n // ensure reset styles are the first child in the shadow root\n const style = shadowRootRef.current.querySelector(\n '[data-remote-components-reset]',\n );\n if (style && shadowRootRef.current.firstChild !== style) {\n shadowRootRef.current.removeChild(style);\n }\n }\n\n const linksToRender = (\n <RemoteComponentLinks\n links={links}\n url={url}\n serverUrl={serverUrl}\n bundle={bundle}\n isolate={isolate}\n reset={reset}\n isDevelopment={nextData?.buildId === 'development'}\n />\n );\n\n let componentToRender = shouldUseChildren\n ? children\n : (component as React.ReactNode);\n\n if (isolate !== false) {\n componentToRender = (\n <div\n data-remote-component-id={`shadowroot_${remoteComponentId}`}\n data-remote-component-isolation-root=\"\"\n id={`shadowroot_${name}`}\n ref={shadowContainerRef}\n >\n {typeof document === 'undefined' ? (\n // eslint-disable-next-line react/no-unknown-property\n <template shadowrootmode={mode}>\n {mode === 'closed' ? (\n <div\n dangerouslySetInnerHTML={{\n __html: `<img\n alt=\"\" decoding=\"async\" style=\"display:none\"\n src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==\"\n onload=\"(function(el){\n const root = el.getRootNode();\n globalThis.${shadowRootKey} = root;\n el.parentElement.remove();\n })(this)\"\n />`,\n }}\n />\n ) : null}\n {linksToRender}\n {shouldUseChildren ? children : null}\n </template>\n ) : null}\n {typeof document !== 'undefined' &&\n shadowRootRef.current &&\n !shouldUseChildren\n ? createPortal(\n <>\n {linksToRender}\n {componentToRender}\n </>,\n shadowRootRef.current,\n )\n : null}\n </div>\n );\n }\n\n return (\n <>\n {isolate === false ? (\n <template id={`${name}_start`} ref={startRef} />\n ) : null}\n <script data-remote-component type=\"application/json\">\n {JSON.stringify({\n name,\n bundle,\n route,\n runtime,\n })}\n </script>\n {isolate === false ? linksToRender : null}\n {componentToRender}\n {nextData ? (\n <script\n id={`${bundle}_${route.replace(\n /[^a-zA-Z0-9]+/g,\n '_',\n )}${name}_next_data`}\n type=\"application/json\"\n >\n {JSON.stringify(nextData)}\n </script>\n ) : null}\n {isolate === false ? <template id={`${name}_end`} ref={endRef} /> : null}\n </>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/host/nextjs/app-client.tsx"],"sourcesContent":["'use client';\n\nimport {\n startTransition,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { createImageLoaderSharedEntries } from '#internal/host/nextjs/image-shared';\nimport { useResolveClientUrl } from '#internal/host/react/hooks/use-resolve-client-url';\nimport { getClientOrServerUrl } from '#internal/host/server/get-client-or-server-url';\nimport type { ConsumeClientOnlyConfig } from '#internal/host/shared/config';\nimport type { ConsumeServerData } from '#internal/host/shared/server-handoff';\nimport { createHostState } from '#internal/host/shared/state';\nimport { DEFAULT_ROUTE, RUNTIME_WEBPACK } from '#internal/runtime/constants';\nimport { loadRemoteComponent } from '#internal/runtime/loaders/component-loader';\nimport { loadStaticRemoteComponent } from '#internal/runtime/loaders/static-loader';\nimport type { MountOrUnmountFunction } from '#internal/runtime/types';\nimport { escapeString } from '#internal/utils';\nimport { logError } from '#internal/utils/logger';\nimport { routerImpl } from './app-compat';\nimport { RemoteComponentLinks } from './remote-component-links';\n\n/**\n * Extends the RSC-serializable data with {@link ConsumeClientConfig} fields\n * (like `resolveClientUrl`) that can't cross the server→client boundary\n * but are accepted when this component is used directly as a client import.\n */\ninterface ConsumeRemoteComponentClientProps\n extends ConsumeServerData,\n ConsumeClientOnlyConfig {}\n\n// import { shared } from 'remote-components/shared/host';\nasync function tryImportShared() {\n try {\n const { shared } = await import('#remote-components/host/defaults/app');\n return shared;\n } catch {\n return {};\n }\n}\n\n/**\n * ConsumeRemoteComponentClient - Main component for rendering remote components\n *\n * This component handles the loading and rendering of remote microfrontends.\n * It supports both RSC (React Server Components) and Next.js Pages Router based components.\n */\nexport function ConsumeRemoteComponentClient({\n src,\n serverUrl,\n name,\n bundle,\n route = DEFAULT_ROUTE,\n runtime = RUNTIME_WEBPACK,\n data,\n nextData,\n scripts = [],\n links = [],\n remoteShared = {},\n isolate,\n mode = 'open',\n resolveClientUrl: resolveClientUrlProp,\n reset,\n type,\n children,\n}: ConsumeRemoteComponentClientProps) {\n const remoteComponentId = useId();\n const [component, setComponent] = useState<React.ReactNode | Error>(null);\n const url = getClientOrServerUrl(src, serverUrl);\n const resolveClientUrl = useResolveClientUrl(resolveClientUrlProp, url.href);\n // TODO: prev* fields and abortController are not populated — the App Router\n // client doesn't support onChange or abort yet. Populate these when adding\n // onChange lifecycle support to match the HTML and React hosts.\n const hostStateRef = useRef(createHostState());\n const metadataRef = useRef<{\n name: string;\n bundle: string;\n route: string;\n url: string;\n }>({\n name,\n bundle,\n route,\n url: url.href,\n });\n const startRef = useRef<HTMLTemplateElement | null>(null);\n const endRef = useRef<HTMLTemplateElement | null>(null);\n const prevRemoteComponentUnmountRef = useRef<{\n unmount: Set<MountOrUnmountFunction>;\n root: ShadowRoot | DocumentFragment | null;\n } | null>(null);\n\n // Handle errors by re-throwing them\n if (component instanceof Error) {\n throw component;\n }\n\n // determine whether to use children or loaded component\n const shouldUseChildren =\n (!component ||\n (component &&\n !nextData &&\n type !== 'remote-component' &&\n typeof (component as unknown as Promise<unknown>).then !==\n 'function')) &&\n // if the remote Next.js Pages Router application is in development mode\n // we don't use the provided static HTML\n // to mitigate layout shift when loading CSS using JavaScript on the client\n nextData?.buildId !== 'development';\n\n // The pathname is used so this URL is the same across server and client requests for relative src's\n const keySuffix = `${escapeString(bundle)}_${escapeString(\n url.pathname,\n )}_${escapeString(name)}`;\n\n const self = globalThis as Record<\n `__remote_components_shadowroot_${string}`,\n ShadowRoot | null\n > &\n Record<`__remote_components_container_${string}`, HTMLDivElement | null>;\n const shadowRootKey = `__remote_components_shadowroot_${keySuffix}` as const;\n const shadowContainerRef = useRef<HTMLDivElement | null>(\n typeof document === 'undefined'\n ? null\n : document.querySelector(\n `[data-remote-component-id=\"shadowroot_${remoteComponentId}\"]`,\n ),\n );\n const shadowRootRef = useRef<ShadowRoot | null>(\n self[shadowRootKey] ?? shadowContainerRef.current?.shadowRoot ?? null,\n );\n const ssrShadowRootContentRef = useRef<NodeListOf<ChildNode> | null>(\n shadowRootRef.current?.querySelectorAll('*') ?? null,\n );\n const ssrLinksStylesRef = useRef<(HTMLLinkElement | HTMLStyleElement)[]>([]);\n\n if (self[shadowRootKey] && shadowRootRef.current) {\n self[shadowRootKey] = null;\n }\n\n useLayoutEffect(() => {\n if (\n !shadowContainerRef.current ||\n shadowContainerRef.current !== shadowRootRef.current?.host\n ) {\n shadowRootRef.current = null;\n }\n\n if (\n isolate !== false &&\n typeof document !== 'undefined' &&\n !shadowRootRef.current\n ) {\n let shadowRootElement: ShadowRoot | null = null;\n const element = shadowContainerRef.current;\n\n shadowRootElement = self[shadowRootKey] ?? element?.shadowRoot ?? null;\n self[shadowRootKey] = null;\n\n if (!shadowRootElement && element) {\n // create a shadow root if it doesn't exist\n // this is a fallback for browsers that don't support declarative shadow DOM\n try {\n shadowRootElement = element.attachShadow({ mode });\n } catch {\n // do nothing if attachShadow fails because of existing shadow root\n }\n }\n\n if (shadowRootElement) {\n shadowRootRef.current = shadowRootElement;\n }\n }\n\n if (\n shadowRootRef.current &&\n ssrShadowRootContentRef.current &&\n !shouldUseChildren\n ) {\n // remove all nodes from the shadow root except links\n ssrShadowRootContentRef.current.forEach((node) => {\n if (node.nodeName !== 'LINK' && node.nodeName !== 'STYLE') {\n node.parentNode?.removeChild(node);\n } else {\n ssrLinksStylesRef.current.push(\n node as HTMLLinkElement | HTMLStyleElement,\n );\n }\n });\n ssrShadowRootContentRef.current = null;\n }\n\n if (ssrLinksStylesRef.current.length > 0 && shadowRootRef.current) {\n const waitForLoad =\n shadowRootRef.current.querySelectorAll('link[data-wait]');\n if (waitForLoad.length > 0) {\n Promise.all(\n Array.from(waitForLoad).map(\n (link) =>\n new Promise<void>((resolve) => {\n link.addEventListener('load', () => resolve());\n link.addEventListener('error', () => resolve());\n }),\n ),\n )\n .then(() => {\n waitForLoad.forEach((el) => {\n el.removeAttribute('data-wait');\n });\n\n // remove SSR injected styles and links\n ssrLinksStylesRef.current.forEach((el) => {\n el.parentNode?.removeChild(el);\n });\n ssrLinksStylesRef.current = [];\n })\n .catch((e) => {\n logError('NextAppRouter', 'Error in cleanup.', e);\n });\n }\n }\n }, [isolate, mode, self, shadowRootKey, shouldUseChildren]);\n\n useEffect(() => {\n // run unmount functions when the component changes or unmounts\n if (prevRemoteComponentUnmountRef.current && component !== children) {\n const { unmount, root } = prevRemoteComponentUnmountRef.current;\n prevRemoteComponentUnmountRef.current = null;\n Promise.all(\n Array.from(unmount).map(async (unmountFn) => {\n try {\n await unmountFn(root);\n } catch (e) {\n logError('NextAppRouter', 'Error in unmount.', e);\n }\n }),\n ).catch((e) => {\n logError('NextAppRouter', 'Error in unmount cleanup.', e);\n });\n }\n }, [component, children]);\n\n useEffect(() => {\n startTransition(async () => {\n try {\n // if we have a component, we don't need to load it again\n if (\n (hostStateRef.current.stage !== 'loading' &&\n !component &&\n (isolate === false || shadowRootRef.current)) ||\n metadataRef.current.url !== url.href ||\n metadataRef.current.name !== name ||\n metadataRef.current.bundle !== bundle ||\n metadataRef.current.route !== route\n ) {\n hostStateRef.current.stage = 'loading';\n metadataRef.current = {\n name,\n bundle,\n route,\n url: url.href,\n };\n\n // use the children as the component when type is remote-component\n if (type === 'remote-component') {\n setComponent(children);\n // load static scripts and execute mount functions\n // run this async but don't await it as we render children immediately\n loadStaticRemoteComponent(\n scripts as HTMLScriptElement[],\n url,\n resolveClientUrl,\n )\n .then(({ mount, unmount }) => {\n if (mount.size > 0) {\n let root: ShadowRoot | DocumentFragment | null =\n shadowRootRef.current;\n try {\n if (!root && startRef.current && endRef.current) {\n root = document.querySelectorAll(\n `#${startRef.current.id} ~ *:not(#${endRef.current.id}):has(~ #${endRef.current.id})`,\n ) as unknown as DocumentFragment;\n }\n } catch (e) {\n logError('NextAppRouter', 'Error finding root element.', e);\n }\n if (unmount.size > 0) {\n prevRemoteComponentUnmountRef.current = { unmount, root };\n }\n return Promise.all(\n Array.from(mount).map((mountFn) => mountFn(root)),\n );\n }\n })\n .catch((e) => {\n logError(\n 'NextAppRouter',\n 'Error loading static remote component.',\n e,\n );\n setComponent(e as Error);\n });\n return;\n }\n\n const rscName = `__remote_components_rsc_${keySuffix}`;\n const result = await loadRemoteComponent({\n url,\n name,\n bundle,\n route,\n runtime,\n rscName,\n data,\n nextData,\n scripts,\n shared: (async () => {\n const shared = await tryImportShared();\n\n if ('__remote_components_missing_shared__' in shared) {\n await shared.__remote_components_missing_shared__();\n }\n return {\n 'next/router': routerImpl,\n ...shared,\n ...createImageLoaderSharedEntries({ bound: resolveClientUrl }),\n };\n })(),\n remoteShared,\n container: shadowRootRef.current,\n resolveClientUrl,\n });\n if (result.error) {\n hostStateRef.current.stage = 'error';\n setComponent(result.error);\n } else {\n hostStateRef.current.stage = 'loaded';\n setComponent(result.component);\n }\n }\n } catch (error: unknown) {\n hostStateRef.current.stage = 'error';\n setComponent(error as Error);\n }\n });\n }, [\n component,\n name,\n bundle,\n route,\n runtime,\n scripts,\n data,\n nextData,\n remoteShared,\n children,\n isolate,\n type,\n keySuffix,\n url,\n resolveClientUrl,\n ]);\n\n if (\n nextData?.buildId === 'development' &&\n shadowRootRef.current &&\n isolate !== false &&\n reset &&\n !shadowRootRef.current.querySelector('[data-remote-components-reset]')\n ) {\n // inject reset styles into the shadow root\n const style = document.createElement('style');\n style.setAttribute('data-remote-components-reset', '');\n style.textContent = `:host { all: initial; }`;\n shadowRootRef.current.insertBefore(style, shadowRootRef.current.firstChild);\n } else if (\n shadowRootRef.current &&\n isolate !== false &&\n !reset &&\n shadowRootRef.current.querySelector('[data-remote-components-reset]')\n ) {\n // ensure reset styles are the first child in the shadow root\n const style = shadowRootRef.current.querySelector(\n '[data-remote-components-reset]',\n );\n if (style && shadowRootRef.current.firstChild !== style) {\n shadowRootRef.current.removeChild(style);\n }\n }\n\n const linksToRender = (\n <RemoteComponentLinks\n links={links}\n url={url}\n serverUrl={serverUrl}\n bundle={bundle}\n isolate={isolate}\n reset={reset}\n isDevelopment={nextData?.buildId === 'development'}\n />\n );\n\n let componentToRender = shouldUseChildren\n ? children\n : (component as React.ReactNode);\n\n if (isolate !== false) {\n componentToRender = (\n <div\n data-remote-component-id={`shadowroot_${remoteComponentId}`}\n data-remote-component-isolation-root=\"\"\n id={`shadowroot_${name}`}\n ref={shadowContainerRef}\n >\n {typeof document === 'undefined' ? (\n // eslint-disable-next-line react/no-unknown-property\n <template shadowrootmode={mode}>\n {mode === 'closed' ? (\n <div\n dangerouslySetInnerHTML={{\n __html: `<img\n alt=\"\" decoding=\"async\" style=\"display:none\"\n src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==\"\n onload=\"(function(el){\n const root = el.getRootNode();\n globalThis.${shadowRootKey} = root;\n el.parentElement.remove();\n })(this)\"\n />`,\n }}\n />\n ) : null}\n {linksToRender}\n {shouldUseChildren ? children : null}\n </template>\n ) : null}\n {typeof document !== 'undefined' &&\n shadowRootRef.current &&\n !shouldUseChildren\n ? createPortal(\n <>\n {linksToRender}\n {componentToRender}\n </>,\n shadowRootRef.current,\n )\n : null}\n </div>\n );\n }\n\n return (\n <>\n {isolate === false ? (\n <template id={`${name}_start`} ref={startRef} />\n ) : null}\n <script data-remote-component type=\"application/json\">\n {JSON.stringify({\n name,\n bundle,\n route,\n runtime,\n })}\n </script>\n {isolate === false ? linksToRender : null}\n {componentToRender}\n {nextData ? (\n <script\n id={`${bundle}_${route.replace(\n /[^a-zA-Z0-9]+/g,\n '_',\n )}${name}_next_data`}\n type=\"application/json\"\n >\n {JSON.stringify(nextData)}\n </script>\n ) : null}\n {isolate === false ? <template id={`${name}_end`} ref={endRef} /> : null}\n </>\n );\n}\n"],"mappings":"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","names":[]}
|