1
1
'use strict' ;
2
2
3
- const { ModuleWrap } = internalBinding ( 'module_wrap' ) ;
3
+ const { ModuleWrap, callbackMap } = internalBinding ( 'module_wrap' ) ;
4
4
const debug = require ( 'util' ) . debuglog ( 'esm' ) ;
5
5
const ArrayJoin = Function . call . bind ( Array . prototype . join ) ;
6
6
const ArrayMap = Function . call . bind ( Array . prototype . map ) ;
@@ -10,50 +10,47 @@ const createDynamicModule = (exports, url = '', evaluate) => {
10
10
`creating ESM facade for ${ url } with exports: ${ ArrayJoin ( exports , ', ' ) } `
11
11
) ;
12
12
const names = ArrayMap ( exports , ( name ) => `${ name } ` ) ;
13
- // Create two modules: One whose exports are get- and set-able ('reflective'),
14
- // and one which re-exports all of these but additionally may
15
- // run an executor function once everything is set up.
16
- const src = `
17
- export let executor;
18
- ${ ArrayJoin ( ArrayMap ( names , ( name ) => `export let $${ name } ;` ) , '\n' ) }
19
- /* This function is implicitly returned as the module's completion value */
20
- (() => ({
21
- setExecutor: fn => executor = fn,
22
- reflect: {
23
- exports: { ${
24
- ArrayJoin ( ArrayMap ( names , ( name ) => `
25
- ${ name } : {
26
- get: () => $${ name } ,
27
- set: v => $${ name } = v
28
- }` ) , ', \n' ) }
29
- }
30
- }
31
- }));` ;
32
- const reflectiveModule = new ModuleWrap ( src , `cjs-facade:${ url } ` ) ;
33
- reflectiveModule . instantiate ( ) ;
34
- const { setExecutor, reflect } = reflectiveModule . evaluate ( - 1 , false ) ( ) ;
35
- // public exposed ESM
36
- const reexports = `
37
- import {
38
- executor,
39
- ${ ArrayMap ( names , ( name ) => `$${ name } ` ) }
40
- } from "";
41
- export {
42
- ${ ArrayJoin ( ArrayMap ( names , ( name ) => `$${ name } as ${ name } ` ) , ', ' ) }
43
- }
44
- if (typeof executor === "function") {
45
- // add await to this later if top level await comes along
46
- executor()
47
- }` ;
48
- if ( typeof evaluate === 'function' ) {
49
- setExecutor ( ( ) => evaluate ( reflect ) ) ;
50
- }
51
- const module = new ModuleWrap ( reexports , `${ url } ` ) ;
52
- module . link ( async ( ) => reflectiveModule ) ;
53
- module . instantiate ( ) ;
54
- reflect . namespace = module . namespace ( ) ;
13
+
14
+ const source = `
15
+ ${ ArrayJoin ( ArrayMap ( names , ( name ) =>
16
+ `let $${ name } ;
17
+ export { $${ name } as ${ name } };
18
+ import.meta.exports.${ name } = {
19
+ get: () => $${ name } ,
20
+ set: (v) => $${ name } = v,
21
+ };` ) , '\n' )
22
+ }
23
+
24
+ import.meta.done();
25
+ ` ;
26
+
27
+ const m = new ModuleWrap ( source , `${ url } ` ) ;
28
+ m . link ( ( ) => 0 ) ;
29
+ m . instantiate ( ) ;
30
+
31
+ const readyfns = new Set ( ) ;
32
+ const reflect = {
33
+ namespace : m . namespace ( ) ,
34
+ exports : { } ,
35
+ onReady : ( cb ) => { readyfns . add ( cb ) ; } ,
36
+ } ;
37
+
38
+ callbackMap . set ( m , {
39
+ initializeImportMeta : ( meta , wrap ) => {
40
+ meta . exports = reflect . exports ;
41
+ meta . done = ( ) => {
42
+ evaluate ( reflect ) ;
43
+ reflect . onReady = ( cb ) => cb ( reflect ) ;
44
+ for ( const fn of readyfns ) {
45
+ readyfns . delete ( fn ) ;
46
+ fn ( reflect ) ;
47
+ }
48
+ } ;
49
+ } ,
50
+ } ) ;
51
+
55
52
return {
56
- module,
53
+ module : m ,
57
54
reflect,
58
55
} ;
59
56
} ;
0 commit comments