@@ -169,6 +169,13 @@ export const Loader = {
169169 */
170170 versions : new Map < string , string > ( ) ,
171171
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+
172179 /**
173180 * Get a promise that is resolved when all the named packages have been loaded.
174181 *
@@ -191,37 +198,83 @@ export const Loader = {
191198 * Load the named packages and return a promise that is resolved when they are all loaded
192199 *
193200 * @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
195202 */
196203 load ( ...names : string [ ] ) : Promise < any [ ] > {
197204 if ( names . length === 0 ) {
198205 return Promise . resolve ( [ ] ) ;
199206 }
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+ ) ;
206243 }
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 ;
225278 } ,
226279
227280 /**
0 commit comments