@@ -7,6 +7,21 @@ type Container = {
7
7
get ( module : string ) : Factory ;
8
8
} ;
9
9
10
+ let config : ParsedMfConfigFile = { } ;
11
+
12
+ export type DynamicMfConfigFile = {
13
+ [ key : string ] : string | DynamicMfConfig
14
+ } ;
15
+
16
+ export type ParsedMfConfigFile = {
17
+ [ key : string ] : DynamicMfConfig
18
+ } ;
19
+
20
+ export type DynamicMfConfig = {
21
+ type : 'module' | 'script' ,
22
+ remoteEntry : string
23
+ } ;
24
+
10
25
declare const __webpack_init_sharing__ : ( shareScope : string ) => Promise < void > ;
11
26
declare const __webpack_share_scopes__ : { default : Scope } ;
12
27
@@ -108,7 +123,7 @@ async function loadRemoteScriptEntry(remoteEntry: string, remoteName: string): P
108
123
} ) ;
109
124
}
110
125
111
- export type LoadRemoteModuleOptions = LoadRemoteModuleScriptOptions | LoadRemoteModuleEsmOptions ;
126
+ export type LoadRemoteModuleOptions = LoadRemoteModuleScriptOptions | LoadRemoteModuleEsmOptions | LoadRemoteModuleManifestOptions ;
112
127
113
128
export type LoadRemoteModuleScriptOptions = {
114
129
type ?: 'script' ;
@@ -123,17 +138,41 @@ export type LoadRemoteModuleEsmOptions = {
123
138
exposedModule : string ;
124
139
}
125
140
141
+ export type LoadRemoteModuleManifestOptions = {
142
+ type : 'manifest' ;
143
+ remoteName : string ;
144
+ exposedModule : string ;
145
+ }
146
+
126
147
// eslint-disable-next-line @typescript-eslint/no-explicit-any
127
148
export async function loadRemoteModule < T = any > ( options : LoadRemoteModuleOptions ) : Promise < T > {
128
149
129
150
let loadRemoteEntryOptions : LoadRemoteEntryOptions ;
130
151
let key : string ;
152
+ let remoteEntry : string ;
131
153
132
154
// To support legacy API (< ng 13)
133
155
if ( ! options . type ) {
134
156
options . type = 'script' ;
135
157
}
136
158
159
+ if ( options . type === 'manifest' ) {
160
+ const manifestEntry = config [ options . remoteName ] ;
161
+ if ( ! manifestEntry ) {
162
+ throw new Error ( 'Manifest does not contain ' + options . remoteName ) ;
163
+ }
164
+ options = {
165
+ type : manifestEntry . type ,
166
+ exposedModule : options . exposedModule ,
167
+ remoteEntry : manifestEntry . remoteEntry ,
168
+ remoteName : ( manifestEntry . type === 'script' ) ? options . remoteName : undefined
169
+ }
170
+ remoteEntry = manifestEntry . remoteEntry ;
171
+ }
172
+ else {
173
+ remoteEntry = options . remoteEntry ;
174
+ }
175
+
137
176
if ( options . type === 'script' ) {
138
177
loadRemoteEntryOptions = {
139
178
type : 'script' ,
@@ -150,9 +189,58 @@ export async function loadRemoteModule<T = any>(options: LoadRemoteModuleOptions
150
189
key = options . remoteEntry ;
151
190
}
152
191
153
- if ( options . remoteEntry ) {
192
+ if ( remoteEntry ) {
154
193
await loadRemoteEntry ( loadRemoteEntryOptions ) ;
155
194
}
156
195
157
196
return await lookupExposedModule < T > ( key , options . exposedModule ) ;
158
197
}
198
+
199
+ export async function loadManifest ( configFile : string , skipRemoteEntries = false ) : Promise < void > {
200
+
201
+ const result = await fetch ( configFile ) ;
202
+
203
+ if ( ! result . ok ) {
204
+ throw Error ( 'could not load configFile: ' + configFile ) ;
205
+ }
206
+
207
+ config = parseConfig ( await result . json ( ) ) ;
208
+
209
+ if ( ! skipRemoteEntries ) {
210
+ await loadRemoteEntries ( ) ;
211
+ }
212
+ }
213
+
214
+ function parseConfig ( config : DynamicMfConfigFile ) : ParsedMfConfigFile {
215
+ const result : ParsedMfConfigFile = { } ;
216
+ for ( let key in config ) {
217
+ const value = config [ key ] ;
218
+
219
+ let entry : DynamicMfConfig ;
220
+ if ( typeof value === 'string' ) {
221
+ entry = {
222
+ remoteEntry : value ,
223
+ type : 'module'
224
+ } ;
225
+ }
226
+ else {
227
+ entry = value ;
228
+ }
229
+
230
+ result [ key ] = entry ;
231
+ }
232
+ return result ;
233
+ }
234
+
235
+ async function loadRemoteEntries ( ) {
236
+ for ( let key in config ) {
237
+ const entry = config [ key ] ;
238
+
239
+ if ( entry . type === 'module' ) {
240
+ await loadRemoteEntry ( { type : 'module' , remoteEntry : entry . remoteEntry } ) ;
241
+ }
242
+ else {
243
+ await loadRemoteEntry ( { type : 'script' , remoteEntry : entry . remoteEntry , remoteName : key } ) ;
244
+ }
245
+ }
246
+ }
0 commit comments