11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst {
41cb0ef41Sopenharmony_ci  ArrayPrototypeJoin,
51cb0ef41Sopenharmony_ci  ArrayPrototypeMap,
61cb0ef41Sopenharmony_ci  JSONStringify,
71cb0ef41Sopenharmony_ci  ObjectCreate,
81cb0ef41Sopenharmony_ci  SafeSet,
91cb0ef41Sopenharmony_ci} = primordials;
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_cilet debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
121cb0ef41Sopenharmony_ci  debug = fn;
131cb0ef41Sopenharmony_ci});
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci/**
161cb0ef41Sopenharmony_ci * Creates an import statement for a given module path and index.
171cb0ef41Sopenharmony_ci * @param {string} impt - The module path to import.
181cb0ef41Sopenharmony_ci * @param {number} index - The index of the import statement.
191cb0ef41Sopenharmony_ci */
201cb0ef41Sopenharmony_cifunction createImport(impt, index) {
211cb0ef41Sopenharmony_ci  const imptPath = JSONStringify(impt);
221cb0ef41Sopenharmony_ci  return `import * as $import_${index} from ${imptPath};
231cb0ef41Sopenharmony_ciimport.meta.imports[${imptPath}] = $import_${index};`;
241cb0ef41Sopenharmony_ci}
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci/**
271cb0ef41Sopenharmony_ci * Creates an export for a given module.
281cb0ef41Sopenharmony_ci * @param {string} expt - The name of the export.
291cb0ef41Sopenharmony_ci * @param {number} index - The index of the export statement.
301cb0ef41Sopenharmony_ci */
311cb0ef41Sopenharmony_cifunction createExport(expt, index) {
321cb0ef41Sopenharmony_ci  const nameStringLit = JSONStringify(expt);
331cb0ef41Sopenharmony_ci  return `let $export_${index};
341cb0ef41Sopenharmony_ciexport { $export_${index} as ${nameStringLit} };
351cb0ef41Sopenharmony_ciimport.meta.exports[${nameStringLit}] = {
361cb0ef41Sopenharmony_ci  get: () => $export_${index},
371cb0ef41Sopenharmony_ci  set: (v) => $export_${index} = v,
381cb0ef41Sopenharmony_ci};`;
391cb0ef41Sopenharmony_ci}
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci/**
421cb0ef41Sopenharmony_ci * Creates a dynamic module with the given imports, exports, URL, and evaluate function.
431cb0ef41Sopenharmony_ci * @param {string[]} imports - An array of imports.
441cb0ef41Sopenharmony_ci * @param {string[]} exports - An array of exports.
451cb0ef41Sopenharmony_ci * @param {string} [url=''] - The URL of the module.
461cb0ef41Sopenharmony_ci * @param {(reflect: DynamicModuleReflect) => void} evaluate - The function to evaluate the module.
471cb0ef41Sopenharmony_ci * @typedef {object} DynamicModuleReflect
481cb0ef41Sopenharmony_ci * @property {string[]} imports - The imports of the module.
491cb0ef41Sopenharmony_ci * @property {string[]} exports - The exports of the module.
501cb0ef41Sopenharmony_ci * @property {(cb: (reflect: DynamicModuleReflect) => void) => void} onReady - Callback to evaluate the module.
511cb0ef41Sopenharmony_ci */
521cb0ef41Sopenharmony_ciconst createDynamicModule = (imports, exports, url = '', evaluate) => {
531cb0ef41Sopenharmony_ci  debug('creating ESM facade for %s with exports: %j', url, exports);
541cb0ef41Sopenharmony_ci  const source = `
551cb0ef41Sopenharmony_ci${ArrayPrototypeJoin(ArrayPrototypeMap(imports, createImport), '\n')}
561cb0ef41Sopenharmony_ci${ArrayPrototypeJoin(ArrayPrototypeMap(exports, createExport), '\n')}
571cb0ef41Sopenharmony_ciimport.meta.done();
581cb0ef41Sopenharmony_ci`;
591cb0ef41Sopenharmony_ci  const { ModuleWrap } = internalBinding('module_wrap');
601cb0ef41Sopenharmony_ci  const m = new ModuleWrap(`${url}`, undefined, source, 0, 0);
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  const readyfns = new SafeSet();
631cb0ef41Sopenharmony_ci  /** @type {DynamicModuleReflect} */
641cb0ef41Sopenharmony_ci  const reflect = {
651cb0ef41Sopenharmony_ci    exports: ObjectCreate(null),
661cb0ef41Sopenharmony_ci    onReady: (cb) => { readyfns.add(cb); },
671cb0ef41Sopenharmony_ci  };
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  if (imports.length) {
701cb0ef41Sopenharmony_ci    reflect.imports = { __proto__: null };
711cb0ef41Sopenharmony_ci  }
721cb0ef41Sopenharmony_ci  const { registerModule } = require('internal/modules/esm/utils');
731cb0ef41Sopenharmony_ci  registerModule(m, {
741cb0ef41Sopenharmony_ci    __proto__: null,
751cb0ef41Sopenharmony_ci    initializeImportMeta: (meta, wrap) => {
761cb0ef41Sopenharmony_ci      meta.exports = reflect.exports;
771cb0ef41Sopenharmony_ci      if (reflect.imports) {
781cb0ef41Sopenharmony_ci        meta.imports = reflect.imports;
791cb0ef41Sopenharmony_ci      }
801cb0ef41Sopenharmony_ci      meta.done = () => {
811cb0ef41Sopenharmony_ci        evaluate(reflect);
821cb0ef41Sopenharmony_ci        reflect.onReady = (cb) => cb(reflect);
831cb0ef41Sopenharmony_ci        for (const fn of readyfns) {
841cb0ef41Sopenharmony_ci          readyfns.delete(fn);
851cb0ef41Sopenharmony_ci          fn(reflect);
861cb0ef41Sopenharmony_ci        }
871cb0ef41Sopenharmony_ci      };
881cb0ef41Sopenharmony_ci    },
891cb0ef41Sopenharmony_ci  });
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  return {
921cb0ef41Sopenharmony_ci    module: m,
931cb0ef41Sopenharmony_ci    reflect,
941cb0ef41Sopenharmony_ci  };
951cb0ef41Sopenharmony_ci};
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_cimodule.exports = createDynamicModule;
98