All files / lib/internal/modules/esm create_dynamic_module.js

95.83% Statements 69/72
87.5% Branches 7/8
71.43% Functions 5/7
95.83% Lines 69/72

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73135x 135x 135x 135x 135x 135x 135x 135x 135x 135x 135x 3x 135x 135x 5x 5x 5x 5x 5x 135x 4x 4x 4x 4x 4x 4x 4x 4x 4x 135x 135x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 2x 2x 2x 2x 2x 2x 2x       2x 3x 3x 3x 3x 3x 3x 3x 135x 135x 135x  
'use strict';
 
const {
  ArrayPrototypeJoin,
  ArrayPrototypeMap,
  JSONStringify,
  ObjectCreate,
  SafeSet,
} = primordials;
 
let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
  debug = fn;
});
 
function createImport(impt, index) {
  const imptPath = JSONStringify(impt);
  return `import * as $import_${index} from ${imptPath};
import.meta.imports[${imptPath}] = $import_${index};`;
}
 
function createExport(expt) {
  const name = `${expt}`;
  return `let $${name};
export { $${name} as ${name} };
import.meta.exports.${name} = {
  get: () => $${name},
  set: (v) => $${name} = v,
};`;
}
 
const createDynamicModule = (imports, exports, url = '', evaluate) => {
  debug('creating ESM facade for %s with exports: %j', url, exports);
  const source = `
${ArrayPrototypeJoin(ArrayPrototypeMap(imports, createImport), '\n')}
${ArrayPrototypeJoin(ArrayPrototypeMap(exports, createExport), '\n')}
import.meta.done();
`;
  const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
  const m = new ModuleWrap(`${url}`, undefined, source, 0, 0);
 
  const readyfns = new SafeSet();
  const reflect = {
    exports: ObjectCreate(null),
    onReady: (cb) => { readyfns.add(cb); },
  };
 
  if (imports.length)
    reflect.imports = ObjectCreate(null);
 
  callbackMap.set(m, {
    initializeImportMeta: (meta, wrap) => {
      meta.exports = reflect.exports;
      if (reflect.imports)
        meta.imports = reflect.imports;
      meta.done = () => {
        evaluate(reflect);
        reflect.onReady = (cb) => cb(reflect);
        for (const fn of readyfns) {
          readyfns.delete(fn);
          fn(reflect);
        }
      };
    },
  });
 
  return {
    module: m,
    reflect,
  };
};
 
module.exports = createDynamicModule;