@@ -100,6 +100,9 @@ function createLoadRecord (state, key, registration) {
100
100
// will be the array of dependency load record or a module namespace
101
101
dependencyInstantiations : undefined ,
102
102
103
+ // top-level await!
104
+ evaluatePromise : undefined ,
105
+
103
106
// NB optimization and way of ensuring module objects in setters
104
107
// indicates setters which should run pre-execution of that dependency
105
108
// setters is then just for completely executed module objects
@@ -117,7 +120,7 @@ RegisterLoader.prototype[Loader.resolveInstantiate] = function (key, parentKey)
117
120
118
121
return resolveInstantiate ( loader , key , parentKey , registry , state )
119
122
. then ( function ( instantiated ) {
120
- if ( instantiated instanceof ModuleNamespace )
123
+ if ( instantiated instanceof ModuleNamespace || instantiated [ toStringTag ] === 'module' )
121
124
return instantiated ;
122
125
123
126
// resolveInstantiate always returns a load record with a link record and no module value
@@ -132,7 +135,7 @@ RegisterLoader.prototype[Loader.resolveInstantiate] = function (key, parentKey)
132
135
133
136
return deepInstantiateDeps ( loader , instantiated , link , registry , state )
134
137
. then ( function ( ) {
135
- return ensureEvaluate ( loader , instantiated , link , registry , state , undefined ) ;
138
+ return ensureEvaluate ( loader , instantiated , link , registry , state ) ;
136
139
} ) ;
137
140
} ) ;
138
141
} ;
@@ -496,23 +499,22 @@ ContextualLoader.prototype.import = function (key) {
496
499
return this.loader.resolve(key, this.key);
497
500
};*/
498
501
499
- // this is the execution function bound to the Module namespace record
500
- function ensureEvaluate ( loader , load , link , registry , state , seen ) {
502
+ function ensureEvaluate ( loader , load , link , registry , state ) {
501
503
if ( load . module )
502
504
return load . module ;
503
-
504
505
if ( load . evalError )
505
506
throw load . evalError ;
507
+ if ( link . evaluatePromise )
508
+ return link . evaluatePromise ;
506
509
507
- if ( seen && seen . indexOf ( load ) !== - 1 )
508
- return load . linkRecord . moduleObj ;
509
-
510
- // for ES loads we always run ensureEvaluate on top-level, so empty seen is passed regardless
511
- // for dynamic loads, we pass seen if also dynamic
512
- var err = doEvaluate ( loader , load , link , registry , state , link . setters ? [ ] : seen || [ ] ) ;
513
- if ( err )
514
- throw err ;
515
-
510
+ if ( link . setters ) {
511
+ var evaluatePromise = doEvaluateDeclarative ( loader , load , link , registry , state , [ load ] ) ;
512
+ if ( evaluatePromise )
513
+ return evaluatePromise ;
514
+ }
515
+ else {
516
+ doEvaluateDynamic ( loader , load , link , registry , state , [ load ] ) ;
517
+ }
516
518
return load . module ;
517
519
}
518
520
@@ -524,10 +526,23 @@ function makeDynamicRequire (loader, key, dependencies, dependencyInstantiations
524
526
var depLoad = dependencyInstantiations [ i ] ;
525
527
var module ;
526
528
527
- if ( depLoad instanceof ModuleNamespace || depLoad [ toStringTag ] === 'module' )
529
+ if ( depLoad instanceof ModuleNamespace || depLoad [ toStringTag ] === 'module' ) {
528
530
module = depLoad ;
529
- else
530
- module = ensureEvaluate ( loader , depLoad , depLoad . linkRecord , registry , state , seen ) ;
531
+ }
532
+ else {
533
+ if ( depLoad . evalError )
534
+ throw depLoad . evalError ;
535
+ if ( depLoad . module === undefined && seen . indexOf ( depLoad ) === - 1 && ! depLoad . linkRecord . evaluatePromise ) {
536
+ if ( depLoad . linkRecord . setters ) {
537
+ doEvaluateDeclarative ( loader , depLoad , depLoad . linkRecord , registry , state , [ depLoad ] ) ;
538
+ }
539
+ else {
540
+ seen . push ( depLoad ) ;
541
+ doEvaluateDynamic ( loader , depLoad , depLoad . linkRecord , registry , state , seen ) ;
542
+ }
543
+ }
544
+ module = depLoad . module || depLoad . linkRecord . moduleObj ;
545
+ }
531
546
532
547
return '__useDefault' in module ? module . __useDefault : module ;
533
548
}
@@ -536,129 +551,161 @@ function makeDynamicRequire (loader, key, dependencies, dependencyInstantiations
536
551
} ;
537
552
}
538
553
539
- // ensures the given es load is evaluated
540
- // returns the error if any
541
- function doEvaluate ( loader , load , link , registry , state , seen ) {
542
- seen . push ( load ) ;
543
-
544
- var err ;
554
+ function evalError ( load , err ) {
555
+ load . linkRecord = undefined ;
556
+ var evalError = addToError ( err , 'Evaluating ' + load . key ) ;
557
+ if ( load . evalError === undefined )
558
+ load . evalError = evalError ;
559
+ throw evalError ;
560
+ }
545
561
546
- // es modules evaluate dependencies first
547
- // non es modules explicitly call moduleEvaluate through require
548
- if ( link . setters ) {
549
- var depLoad , depLink ;
550
- for ( var i = 0 ; i < link . dependencies . length ; i ++ ) {
551
- depLoad = link . dependencyInstantiations [ i ] ;
552
-
553
- if ( depLoad instanceof ModuleNamespace || depLoad [ toStringTag ] === 'module' )
554
- continue ;
555
-
556
- // custom Module returned from instantiate
557
- depLink = depLoad . linkRecord ;
558
- if ( depLink && seen . indexOf ( depLoad ) === - 1 ) {
559
- if ( depLoad . evalError )
560
- err = depLoad . evalError ;
561
- else
562
- // dynamic / declarative boundaries clear the "seen" list
563
- // we just let cross format circular throw as would happen in real implementations
564
- err = doEvaluate ( loader , depLoad , depLink , registry , state , depLink . setters ? seen : [ ] ) ;
562
+ // es modules evaluate dependencies first
563
+ // returns the error if any
564
+ function doEvaluateDeclarative ( loader , load , link , registry , state , seen ) {
565
+ var depLoad , depLink ;
566
+ var depLoadPromises ;
567
+ for ( var i = 0 ; i < link . dependencies . length ; i ++ ) {
568
+ var depLoad = link . dependencyInstantiations [ i ] ;
569
+ if ( depLoad instanceof ModuleNamespace || depLoad [ toStringTag ] === 'module' )
570
+ continue ;
571
+
572
+ // custom Module returned from instantiate
573
+ depLink = depLoad . linkRecord ;
574
+ if ( depLink ) {
575
+ if ( depLoad . evalError ) {
576
+ evalError ( load , depLoad . evalError ) ;
565
577
}
566
-
567
- if ( err ) {
568
- load . linkRecord = undefined ;
569
- load . evalError = addToError ( err , 'Evaluating ' + load . key ) ;
570
- return load . evalError ;
578
+ else if ( depLink . setters ) {
579
+ if ( seen . indexOf ( depLoad ) === - 1 ) {
580
+ seen . push ( depLoad ) ;
581
+ try {
582
+ var depLoadPromise = doEvaluateDeclarative ( loader , depLoad , depLink , registry , state , seen ) ;
583
+ }
584
+ catch ( e ) {
585
+ evalError ( load , e ) ;
586
+ }
587
+ if ( depLoadPromise ) {
588
+ depLoadPromises = depLoadPromises || [ ] ;
589
+ depLoadPromises . push ( depLoadPromise . catch ( function ( err ) {
590
+ evalError ( load , err ) ;
591
+ } ) ) ;
592
+ }
593
+ }
594
+ }
595
+ else {
596
+ try {
597
+ doEvaluateDynamic ( loader , depLoad , depLink , registry , state , [ depLoad ] ) ;
598
+ }
599
+ catch ( e ) {
600
+ evalError ( load , e ) ;
601
+ }
571
602
}
572
603
}
573
604
}
574
605
575
- // link.execute won't exist for Module returns from instantiate on top-level load
606
+ if ( depLoadPromises )
607
+ return Promise . all ( depLoadPromises )
608
+ . then ( function ( ) {
609
+ if ( link . execute ) {
610
+ // ES System.register execute
611
+ // "this" is null in ES
612
+ try {
613
+ var execPromise = link . execute . call ( nullContext ) ;
614
+ }
615
+ catch ( e ) {
616
+ evalError ( load , e ) ;
617
+ }
618
+ if ( execPromise )
619
+ return execPromise . catch ( function ( e ) {
620
+ evalError ( load , e ) ;
621
+ } ) ;
622
+ }
623
+
624
+ // dispose link record
625
+ load . linkRecord = undefined ;
626
+ registry [ load . key ] = load . module = new ModuleNamespace ( link . moduleObj ) ;
627
+ } ) ;
628
+
576
629
if ( link . execute ) {
577
630
// ES System.register execute
578
631
// "this" is null in ES
579
- if ( link . setters ) {
580
- err = declarativeExecute ( link . execute ) ;
632
+ try {
633
+ var execPromise = link . execute . call ( nullContext ) ;
581
634
}
582
- // System.registerDynamic execute
583
- // "this" is "exports" in CJS
584
- else {
585
- var module = { id : load . key } ;
586
- var moduleObj = link . moduleObj ;
587
- Object . defineProperty ( module , 'exports' , {
588
- configurable : true ,
589
- set : function ( exports ) {
590
- moduleObj . default = moduleObj . __useDefault = exports ;
591
- } ,
592
- get : function ( ) {
593
- return moduleObj . __useDefault ;
594
- }
635
+ catch ( e ) {
636
+ evalError ( load , e ) ;
637
+ }
638
+ if ( execPromise )
639
+ return execPromise . catch ( function ( e ) {
640
+ evalError ( load , e ) ;
595
641
} ) ;
642
+ }
596
643
597
- var require = makeDynamicRequire ( loader , load . key , link . dependencies , link . dependencyInstantiations , registry , state , seen ) ;
598
-
599
- // evaluate deps first
600
- if ( ! link . executingRequire )
601
- for ( var i = 0 ; i < link . dependencies . length ; i ++ )
602
- require ( link . dependencies [ i ] ) ;
644
+ // dispose link record
645
+ load . linkRecord = undefined ;
646
+ registry [ load . key ] = load . module = new ModuleNamespace ( link . moduleObj ) ;
647
+ }
603
648
604
- err = dynamicExecute ( link . execute , require , moduleObj . default , module ) ;
649
+ // non es modules explicitly call moduleEvaluate through require
650
+ function doEvaluateDynamic ( loader , load , link , registry , state , seen ) {
651
+ // System.registerDynamic execute
652
+ // "this" is "exports" in CJS
653
+ var module = { id : load . key } ;
654
+ var moduleObj = link . moduleObj ;
655
+ Object . defineProperty ( module , 'exports' , {
656
+ configurable : true ,
657
+ set : function ( exports ) {
658
+ moduleObj . default = moduleObj . __useDefault = exports ;
659
+ } ,
660
+ get : function ( ) {
661
+ return moduleObj . __useDefault ;
662
+ }
663
+ } ) ;
605
664
606
- // pick up defineProperty calls to module.exports when we can
607
- if ( module . exports !== moduleObj . __useDefault )
608
- moduleObj . default = moduleObj . __useDefault = module . exports ;
665
+ var require = makeDynamicRequire ( loader , load . key , link . dependencies , link . dependencyInstantiations , registry , state , seen ) ;
609
666
610
- var moduleDefault = moduleObj . default ;
667
+ // evaluate deps first
668
+ if ( ! link . executingRequire )
669
+ for ( var i = 0 ; i < link . dependencies . length ; i ++ )
670
+ require ( link . dependencies [ i ] ) ;
611
671
612
- // __esModule flag extension support via lifting
613
- if ( moduleDefault && moduleDefault . __esModule ) {
614
- for ( var p in moduleDefault ) {
615
- if ( Object . hasOwnProperty . call ( moduleDefault , p ) )
616
- moduleObj [ p ] = moduleDefault [ p ] ;
617
- }
618
- }
619
- }
672
+ try {
673
+ var output = link . execute . call ( global , require , moduleObj . default , module ) ;
674
+ if ( output !== undefined )
675
+ module . exports = output ;
676
+ }
677
+ catch ( e ) {
678
+ evalError ( load , e ) ;
620
679
}
621
680
622
- // dispose link record
623
681
load . linkRecord = undefined ;
624
682
625
- if ( err )
626
- return load . evalError = addToError ( err , 'Evaluating ' + load . key ) ;
683
+ // pick up defineProperty calls to module.exports when we can
684
+ if ( module . exports !== moduleObj . __useDefault )
685
+ moduleObj . default = moduleObj . __useDefault = module . exports ;
686
+
687
+ var moduleDefault = moduleObj . default ;
688
+
689
+ // __esModule flag extension support via lifting
690
+ if ( moduleDefault && moduleDefault . __esModule ) {
691
+ for ( var p in moduleDefault ) {
692
+ if ( Object . hasOwnProperty . call ( moduleDefault , p ) )
693
+ moduleObj [ p ] = moduleDefault [ p ] ;
694
+ }
695
+ }
627
696
628
697
registry [ load . key ] = load . module = new ModuleNamespace ( link . moduleObj ) ;
629
698
630
- // if not an esm module, run importer setters and clear them
699
+ // run importer setters and clear them
631
700
// this allows dynamic modules to update themselves into es modules
632
701
// as soon as execution has completed
633
- if ( ! link . setters ) {
634
- if ( load . importerSetters )
635
- for ( var i = 0 ; i < load . importerSetters . length ; i ++ )
636
- load . importerSetters [ i ] ( load . module ) ;
637
- load . importerSetters = undefined ;
638
- }
702
+ if ( load . importerSetters )
703
+ for ( var i = 0 ; i < load . importerSetters . length ; i ++ )
704
+ load . importerSetters [ i ] ( load . module ) ;
705
+ load . importerSetters = undefined ;
639
706
}
640
707
641
- // {} is the closest we can get to call(undefined)
642
- var nullContext = { } ;
708
+ // the closest we can get to call(undefined)
709
+ var nullContext = Object . create ( null ) ;
643
710
if ( Object . freeze )
644
711
Object . freeze ( nullContext ) ;
645
-
646
- function declarativeExecute ( execute ) {
647
- try {
648
- execute . call ( nullContext ) ;
649
- }
650
- catch ( e ) {
651
- return e ;
652
- }
653
- }
654
-
655
- function dynamicExecute ( execute , require , exports , module ) {
656
- try {
657
- var output = execute . call ( global , require , exports , module ) ;
658
- if ( output !== undefined )
659
- module . exports = output ;
660
- }
661
- catch ( e ) {
662
- return e ;
663
- }
664
- }
0 commit comments