11'use strict' ;
22
3- const { ModuleWrap } = internalBinding ( 'module_wrap' ) ;
3+ const { ModuleWrap, callbackMap } = internalBinding ( 'module_wrap' ) ;
44const debug = require ( 'util' ) . debuglog ( 'esm' ) ;
55const ArrayJoin = Function . call . bind ( Array . prototype . join ) ;
66const ArrayMap = Function . call . bind ( Array . prototype . map ) ;
@@ -10,50 +10,47 @@ const createDynamicModule = (exports, url = '', evaluate) => {
1010 `creating ESM facade for ${ url } with exports: ${ ArrayJoin ( exports , ', ' ) } `
1111 ) ;
1212 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+
5552 return {
56- module,
53+ module : m ,
5754 reflect,
5855 } ;
5956} ;
0 commit comments