@@ -21,6 +21,16 @@ function createVirtualModuleId(kind, key) {
2121 return `mf_rsc_${ kind } _${ stableHash ( key ) } ` ;
2222}
2323
24+ function toUniqueStringArray ( items ) {
25+ const deduped = new Set ( ) ;
26+ for ( const item of items ) {
27+ if ( typeof item === 'string' && item ) {
28+ deduped . add ( item ) ;
29+ }
30+ }
31+ return [ ...deduped ] ;
32+ }
33+
2434function normalizeExportedModule ( moduleValue ) {
2535 if (
2636 moduleValue &&
@@ -72,6 +82,98 @@ function normalizeServerActions(value) {
7282 return actions ;
7383}
7484
85+ function createRscRegistrationPayload ( manifestJson ) {
86+ const exposes = Array . isArray ( manifestJson ?. exposes )
87+ ? manifestJson . exposes
88+ : [ ] ;
89+ const shared = Array . isArray ( manifestJson ?. shared ) ? manifestJson . shared : [ ] ;
90+ const exposePayload = [ ] ;
91+ const sharedPayload = [ ] ;
92+
93+ for ( const expose of exposes ) {
94+ const rscMeta = expose ?. rsc ;
95+ if ( ! rscMeta ) {
96+ continue ;
97+ }
98+ const clientReferences = normalizeStringArray ( rscMeta . clientReferences ) ;
99+ const serverActions = normalizeServerActions ( rscMeta . serverActions ) ;
100+ if ( clientReferences . length === 0 && serverActions . length === 0 ) {
101+ continue ;
102+ }
103+ const moduleIdentity =
104+ rscMeta . lookup || rscMeta . resource || expose . path || expose . name || '.' ;
105+ exposePayload . push ( {
106+ exposePath : expose . path ,
107+ moduleIdentity,
108+ manifestKeys : toUniqueStringArray ( [
109+ rscMeta . resource ,
110+ rscMeta . lookup ,
111+ moduleIdentity ,
112+ ] ) ,
113+ clientReferences,
114+ serverActions,
115+ } ) ;
116+ }
117+
118+ for ( const sharedItem of shared ) {
119+ const rscMeta = sharedItem ?. rsc ;
120+ if ( ! rscMeta || typeof sharedItem ?. name !== 'string' || ! sharedItem . name ) {
121+ continue ;
122+ }
123+ const clientReferences = normalizeStringArray ( rscMeta . clientReferences ) ;
124+ const serverActions = normalizeServerActions ( rscMeta . serverActions ) ;
125+ if ( clientReferences . length === 0 && serverActions . length === 0 ) {
126+ continue ;
127+ }
128+ const moduleIdentity = rscMeta . lookup || rscMeta . resource || sharedItem . name ;
129+ sharedPayload . push ( {
130+ shareKey : sharedItem . name ,
131+ moduleIdentity,
132+ manifestKeys : toUniqueStringArray ( [
133+ rscMeta . resource ,
134+ rscMeta . lookup ,
135+ moduleIdentity ,
136+ ] ) ,
137+ clientReferences,
138+ serverActions,
139+ } ) ;
140+ }
141+
142+ return {
143+ sourceId : manifestJson ?. id || manifestJson ?. name || '' ,
144+ buildVersion : manifestJson ?. metaData ?. buildInfo ?. buildVersion || '' ,
145+ exposePayload,
146+ sharedPayload,
147+ } ;
148+ }
149+
150+ function buildManifestIdentityKeys ( {
151+ remoteAlias,
152+ remoteName,
153+ remoteEntry,
154+ remoteVersion,
155+ remoteBuildVersion,
156+ manifestUrl,
157+ manifestJson,
158+ } ) {
159+ const keys = [
160+ remoteAlias && `alias:${ remoteAlias } ` ,
161+ remoteName && `name:${ remoteName } ` ,
162+ remoteEntry && `entry:${ remoteEntry } ` ,
163+ remoteVersion && remoteName && `version:${ remoteName } :${ remoteVersion } ` ,
164+ remoteBuildVersion &&
165+ remoteName &&
166+ `build:${ remoteName } :${ remoteBuildVersion } ` ,
167+ manifestUrl && `manifestUrl:${ manifestUrl } ` ,
168+ manifestJson ?. id && `manifestId:${ manifestJson . id } ` ,
169+ manifestJson ?. name && `manifestName:${ manifestJson . name } ` ,
170+ manifestJson ?. metaData ?. buildInfo ?. buildVersion &&
171+ manifestJson ?. name &&
172+ `manifestBuild:${ manifestJson . name } :${ manifestJson . metaData . buildInfo . buildVersion } ` ,
173+ ] ;
174+ return toUniqueStringArray ( keys ) ;
175+ }
176+
75177function ensureRscManifest ( ) {
76178 const existing = __webpack_require__ . rscM ;
77179 if ( existing ) {
@@ -178,6 +280,7 @@ function toExposeRequest(remoteAlias, exposePath) {
178280
179281export default function mfRscRegistrationRuntimePlugin ( ) {
180282 const registrationFingerprintByAlias = new Map ( ) ;
283+ const stagedPayloadByIdentity = new Map ( ) ;
181284
182285 const loadRemoteModule = ( request ) =>
183286 __webpack_require__ . federation . instance
@@ -242,102 +345,89 @@ export default function mfRscRegistrationRuntimePlugin() {
242345 } ) ;
243346 } ;
244347
245- const registerRscDataFromManifest = ( remoteAlias , manifestJson ) => {
246- const exposes = Array . isArray ( manifestJson ?. exposes )
247- ? manifestJson . exposes
248- : [ ] ;
249- const shared = Array . isArray ( manifestJson ?. shared ) ? manifestJson . shared : [ ] ;
348+ const cacheStagedPayload = ( identityKeys , payload ) => {
349+ for ( const key of identityKeys ) {
350+ stagedPayloadByIdentity . set ( key , payload ) ;
351+ }
352+ } ;
353+
354+ const getStagedPayload = ( identityKeys ) => {
355+ for ( const key of identityKeys ) {
356+ const stagedPayload = stagedPayloadByIdentity . get ( key ) ;
357+ if ( stagedPayload ) {
358+ return stagedPayload ;
359+ }
360+ }
361+ return undefined ;
362+ } ;
363+
364+ const registerRscPayload = ( remoteAlias , payload ) => {
250365 const fingerprint = JSON . stringify ( {
251- id : manifestJson ?. id || manifestJson ?. name || '' ,
252- buildVersion : manifestJson ?. metaData ?. buildInfo ?. buildVersion || '' ,
253- exposeRscKeys : exposes
254- . filter ( ( item ) => item ?. rsc )
255- . map ( ( item ) => item . rsc . lookup || item . rsc . resource || item . path || '' ) ,
256- sharedRscKeys : shared
257- . filter ( ( item ) => item ?. rsc )
258- . map ( ( item ) => item . rsc . lookup || item . rsc . resource || item . name || '' ) ,
366+ id : payload . sourceId ,
367+ buildVersion : payload . buildVersion ,
368+ exposeRscKeys : payload . exposePayload . map (
369+ ( item ) => item . moduleIdentity || '' ,
370+ ) ,
371+ sharedRscKeys : payload . sharedPayload . map (
372+ ( item ) => item . moduleIdentity || '' ,
373+ ) ,
259374 } ) ;
260375 if ( registrationFingerprintByAlias . get ( remoteAlias ) === fingerprint ) {
261376 return ;
262377 }
263378
264- for ( const expose of exposes ) {
265- const rscMeta = expose ?. rsc ;
266- if ( ! rscMeta ) {
267- continue ;
268- }
269-
270- const clientReferences = normalizeStringArray ( rscMeta . clientReferences ) ;
271- const serverActions = normalizeServerActions ( rscMeta . serverActions ) ;
272- const exposeRequest = toExposeRequest ( remoteAlias , expose . path ) ;
273- const moduleIdentity = rscMeta . lookup || rscMeta . resource || exposeRequest ;
274- const manifestKeys = new Set (
275- [ rscMeta . resource , rscMeta . lookup , moduleIdentity ] . filter ( Boolean ) ,
276- ) ;
277-
278- if ( clientReferences . length > 0 ) {
379+ for ( const expose of payload . exposePayload ) {
380+ const exposeRequest = toExposeRequest ( remoteAlias , expose . exposePath ) ;
381+ if ( expose . clientReferences . length > 0 ) {
279382 const moduleId = createVirtualModuleId (
280383 'client_expose' ,
281- `${ remoteAlias } :${ moduleIdentity } ` ,
384+ `${ remoteAlias } :${ expose . moduleIdentity } ` ,
282385 ) ;
283- registerClientReferenceModule ( moduleId , clientReferences , ( ) =>
386+ registerClientReferenceModule ( moduleId , expose . clientReferences , ( ) =>
284387 loadRemoteModule ( exposeRequest ) ,
285388 ) ;
286- for ( const moduleKey of manifestKeys ) {
389+ for ( const moduleKey of expose . manifestKeys ) {
287390 ensureClientManifestEntry ( moduleKey , moduleId ) ;
288391 }
289392 }
290393
291- if ( serverActions . length > 0 ) {
394+ if ( expose . serverActions . length > 0 ) {
292395 const moduleId = createVirtualModuleId (
293396 'action_expose' ,
294- `${ remoteAlias } :${ moduleIdentity } ` ,
397+ `${ remoteAlias } :${ expose . moduleIdentity } ` ,
295398 ) ;
296- registerServerActionModule ( moduleId , serverActions , ( ) =>
399+ registerServerActionModule ( moduleId , expose . serverActions , ( ) =>
297400 loadRemoteModule ( exposeRequest ) ,
298401 ) ;
299- for ( const action of serverActions ) {
402+ for ( const action of expose . serverActions ) {
300403 ensureServerActionManifestEntry ( action . id , moduleId ) ;
301404 }
302405 }
303406 }
304407
305- for ( const sharedItem of shared ) {
306- const rscMeta = sharedItem ?. rsc ;
307- if ( ! rscMeta || typeof sharedItem ?. name !== 'string' || ! sharedItem . name ) {
308- continue ;
309- }
310-
311- const shareKey = sharedItem . name ;
312- const clientReferences = normalizeStringArray ( rscMeta . clientReferences ) ;
313- const serverActions = normalizeServerActions ( rscMeta . serverActions ) ;
314- const moduleIdentity = rscMeta . lookup || rscMeta . resource || shareKey ;
315- const manifestKeys = new Set (
316- [ rscMeta . resource , rscMeta . lookup , moduleIdentity ] . filter ( Boolean ) ,
317- ) ;
318-
319- if ( clientReferences . length > 0 ) {
408+ for ( const sharedItem of payload . sharedPayload ) {
409+ if ( sharedItem . clientReferences . length > 0 ) {
320410 const moduleId = createVirtualModuleId (
321411 'client_shared' ,
322- `${ remoteAlias } :${ moduleIdentity } ` ,
412+ `${ remoteAlias } :${ sharedItem . moduleIdentity } ` ,
323413 ) ;
324- registerClientReferenceModule ( moduleId , clientReferences , ( ) =>
325- loadSharedModule ( shareKey ) ,
414+ registerClientReferenceModule ( moduleId , sharedItem . clientReferences , ( ) =>
415+ loadSharedModule ( sharedItem . shareKey ) ,
326416 ) ;
327- for ( const moduleKey of manifestKeys ) {
417+ for ( const moduleKey of sharedItem . manifestKeys ) {
328418 ensureClientManifestEntry ( moduleKey , moduleId ) ;
329419 }
330420 }
331421
332- if ( serverActions . length > 0 ) {
422+ if ( sharedItem . serverActions . length > 0 ) {
333423 const moduleId = createVirtualModuleId (
334424 'action_shared' ,
335- `${ remoteAlias } :${ moduleIdentity } ` ,
425+ `${ remoteAlias } :${ sharedItem . moduleIdentity } ` ,
336426 ) ;
337- registerServerActionModule ( moduleId , serverActions , ( ) =>
338- loadSharedModule ( shareKey ) ,
427+ registerServerActionModule ( moduleId , sharedItem . serverActions , ( ) =>
428+ loadSharedModule ( sharedItem . shareKey ) ,
339429 ) ;
340- for ( const action of serverActions ) {
430+ for ( const action of sharedItem . serverActions ) {
341431 ensureServerActionManifestEntry ( action . id , moduleId ) ;
342432 }
343433 }
@@ -352,6 +442,7 @@ export default function mfRscRegistrationRuntimePlugin() {
352442 args ?. remote ?. alias ||
353443 args ?. remoteInfo ?. alias ||
354444 args ?. remote ?. name ;
445+ const remoteName = args ?. remoteInfo ?. name || args ?. remote ?. name ;
355446 if ( ! remoteAlias ) {
356447 return ;
357448 }
@@ -361,19 +452,69 @@ export default function mfRscRegistrationRuntimePlugin() {
361452 typeof configuredEntry === 'string' && configuredEntry . endsWith ( '.json' )
362453 ? configuredEntry
363454 : undefined ;
364- const manifestJson =
365- ( manifestUrl && ( await readManifestJson ( args . origin , manifestUrl ) ) ) ||
366- pickManifestFromSnapshotCache ( args . origin , args ?. remoteInfo ?. name ) ;
455+ const identityKeys = buildManifestIdentityKeys ( {
456+ remoteAlias,
457+ remoteName,
458+ remoteEntry : configuredEntry ,
459+ remoteVersion : args ?. remoteSnapshot ?. version || args ?. remoteInfo ?. version ,
460+ remoteBuildVersion :
461+ args ?. remoteSnapshot ?. buildVersion || args ?. remoteInfo ?. buildVersion ,
462+ manifestUrl,
463+ } ) ;
464+
465+ let payload = getStagedPayload ( identityKeys ) ;
466+ if ( ! payload ) {
467+ const manifestJson =
468+ ( manifestUrl && ( await readManifestJson ( args . origin , manifestUrl ) ) ) ||
469+ pickManifestFromSnapshotCache ( args . origin , args ?. remoteInfo ?. name ) ;
470+ if ( ! manifestJson ) {
471+ return ;
472+ }
473+ payload = createRscRegistrationPayload ( manifestJson ) ;
474+ const manifestIdentityKeys = buildManifestIdentityKeys ( {
475+ remoteAlias,
476+ remoteName,
477+ remoteEntry : configuredEntry ,
478+ remoteVersion :
479+ args ?. remoteSnapshot ?. version || args ?. remoteInfo ?. version ,
480+ remoteBuildVersion :
481+ args ?. remoteSnapshot ?. buildVersion || args ?. remoteInfo ?. buildVersion ,
482+ manifestUrl,
483+ manifestJson,
484+ } ) ;
485+ cacheStagedPayload ( manifestIdentityKeys , payload ) ;
486+ }
367487
368- if ( ! manifestJson ) {
488+ if ( ! payload ) {
369489 return ;
370490 }
371491
372- registerRscDataFromManifest ( remoteAlias , manifestJson ) ;
492+ registerRscPayload ( remoteAlias , payload ) ;
373493 } ;
374494
375495 return {
376496 name : 'mf-rsc-registration-runtime-plugin' ,
497+ async loadRemoteSnapshot ( args ) {
498+ if ( args ?. from !== 'manifest' || ! args ?. manifestJson ) {
499+ return args ;
500+ }
501+ const remoteAlias = args ?. moduleInfo ?. alias || args ?. moduleInfo ?. name ;
502+ const remoteName = args ?. moduleInfo ?. name ;
503+ const payload = createRscRegistrationPayload ( args . manifestJson ) ;
504+ const identityKeys = buildManifestIdentityKeys ( {
505+ remoteAlias,
506+ remoteName,
507+ remoteEntry : args ?. moduleInfo ?. entry ,
508+ remoteVersion : args ?. remoteSnapshot ?. version || args ?. moduleInfo ?. version ,
509+ remoteBuildVersion :
510+ args ?. remoteSnapshot ?. buildVersion ||
511+ args ?. manifestJson ?. metaData ?. buildInfo ?. buildVersion ,
512+ manifestUrl : args ?. manifestUrl ,
513+ manifestJson : args ?. manifestJson ,
514+ } ) ;
515+ cacheStagedPayload ( identityKeys , payload ) ;
516+ return args ;
517+ } ,
377518 async afterResolve ( args ) {
378519 await tryRegisterManifest ( args ) ;
379520 return args ;
0 commit comments