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

95.71% Statements 67/70
85.71% Branches 6/7
71.43% Functions 5/7
95.71% Lines 67/70

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 71142x 142x 142x 142x 142x 142x 142x 142x 142x 142x 142x 142x 5x 5x 5x 5x 5x 142x 4x 4x 4x 4x 4x 4x 4x 4x 4x 142x 142x 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 142x 142x 142x  
'use strict';
 
const {
  ArrayPrototypeJoin,
  ArrayPrototypeMap,
  JSONStringify,
  ObjectCreate,
  Set,
} = primordials;
 
const debug = require('internal/util/debuglog').debuglog('esm');
 
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 Set();
  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;