@@ -169,6 +169,13 @@ export const Loader = {
169
169
*/
170
170
versions : new Map < string , string > ( ) ,
171
171
172
+ /**
173
+ * Array of nested load promises so if component performs additional
174
+ * loads (like an output jax with an alternate font), then the
175
+ * outer load promises won't resolve until the inner ones are complete.
176
+ */
177
+ nestedLoads : [ ] as Promise < any [ ] > [ ] ,
178
+
172
179
/**
173
180
* Get a promise that is resolved when all the named packages have been loaded.
174
181
*
@@ -191,37 +198,83 @@ export const Loader = {
191
198
* Load the named packages and return a promise that is resolved when they are all loaded
192
199
*
193
200
* @param {string[] } names The packages to load
194
- * @returns {Promise } A promise that resolves when all the named packages are ready
201
+ * @returns {Promise<any[]> } A promise that resolves when all the named packages are ready
195
202
*/
196
203
load ( ...names : string [ ] ) : Promise < any [ ] > {
197
204
if ( names . length === 0 ) {
198
205
return Promise . resolve ( [ ] ) ;
199
206
}
200
- const promises = [ ] ;
201
- for ( const name of names ) {
202
- let extension = Package . packages . get ( name ) ;
203
- if ( ! extension ) {
204
- extension = new Package ( name ) ;
205
- extension . provides ( CONFIG . provides [ name ] ) ;
207
+ //
208
+ // Add a new array to store promises for this load() call
209
+ //
210
+ let nested = [ ] as Promise < any > [ ] ;
211
+ this . nestedLoads . unshift ( nested ) ;
212
+ //
213
+ // Create a promise for this load() call
214
+ //
215
+ const promise = Promise . resolve ( ) . then ( async ( ) => {
216
+ //
217
+ // Collect the promises for all the named packages,
218
+ // creating the package if needed, and add checks
219
+ // for the version numbers used in the components.
220
+ //
221
+ const promises = [ ] ;
222
+ for ( const name of names ) {
223
+ let extension = Package . packages . get ( name ) ;
224
+ if ( ! extension ) {
225
+ extension = new Package ( name ) ;
226
+ extension . provides ( CONFIG . provides [ name ] ) ;
227
+ }
228
+ extension . checkNoLoad ( ) ;
229
+ promises . push (
230
+ extension . promise . then ( ( ) => {
231
+ if (
232
+ CONFIG . versionWarnings &&
233
+ extension . isLoaded &&
234
+ ! Loader . versions . has ( Package . resolvePath ( name ) )
235
+ ) {
236
+ console . warn (
237
+ `No version information available for component ${ name } `
238
+ ) ;
239
+ }
240
+ return extension . result ;
241
+ } ) as Promise < any >
242
+ ) ;
206
243
}
207
- extension . checkNoLoad ( ) ;
208
- promises . push (
209
- extension . promise . then ( ( ) => {
210
- if (
211
- CONFIG . versionWarnings &&
212
- extension . isLoaded &&
213
- ! Loader . versions . has ( Package . resolvePath ( name ) )
214
- ) {
215
- console . warn (
216
- `No version information available for component ${ name } `
217
- ) ;
218
- }
219
- return extension . result ;
220
- } ) as Promise < any >
221
- ) ;
222
- }
223
- Package . loadAll ( ) ;
224
- return Promise . all ( promises ) ;
244
+ //
245
+ // Load everything that was requested and wait for
246
+ // them to be loaded.
247
+ //
248
+ Package . loadAll ( ) ;
249
+ const result = await Promise . all ( promises ) ;
250
+ //
251
+ // If any other loads occurred while we were waiting,
252
+ // Wait for those promises, and clear the list so that
253
+ // if even MORE loads occur while waiting for those,
254
+ // we can wait for them, too. Keep doing that until
255
+ // no additional loads occurred, in which case we are
256
+ // now done.
257
+ //
258
+ while ( nested . length ) {
259
+ const promise = Promise . all ( nested ) ;
260
+ nested = this . nestedLoads [ this . nestedLoads . indexOf ( nested ) ] = [ ] ;
261
+ await promise ;
262
+ }
263
+ //
264
+ // Remove the (empty) list from the nested list,
265
+ // and return the result.
266
+ //
267
+ this . nestedLoads . splice ( this . nestedLoads . indexOf ( nested ) , 1 ) ;
268
+ return result ;
269
+ } ) ;
270
+ //
271
+ // Add this load promise to the lists for any parent load() call that are
272
+ // pending when this load() was performed, then return the load promise.
273
+ //
274
+ this . nestedLoads
275
+ . slice ( 1 )
276
+ . forEach ( ( list : Promise < any > [ ] ) => list . push ( promise ) ) ;
277
+ return promise ;
225
278
} ,
226
279
227
280
/**
0 commit comments