function ModuleSource(source, opts = {}) {
  if (new.target === undefined) {
    throw TypeError(
      "Class constructor ModuleSource cannot be invoked without 'new'",
    );
  }
  if (typeof opts === 'string') {
    opts = { sourceUrl: opts };
  }
  const {
    imports,
    functorSource,
    liveExportMap,
    reexportMap,
    fixedExportMap,
    exportAlls,
    needsImport,
    needsImportMeta,
  } = analyzeModule(source, opts);
  this.imports = freeze([...keys(imports)]);
  this.exports = freeze(
    [
      ...keys(liveExportMap),
      ...keys(fixedExportMap),
      ...values(reexportMap).flatMap(([_, exportName]) => exportName),
    ].sort(),
  );
  this.reexports = freeze([...exportAlls].sort());
  this.__syncModuleProgram__ = functorSource;
  this.__liveExportMap__ = liveExportMap;
  this.__reexportMap__ = reexportMap;
  this.__fixedExportMap__ = fixedExportMap;
  this.__needsImport__ = needsImport;
  this.__needsImportMeta__ = needsImportMeta;
  freeze(this);
}
ModuleSource captures the effort of parsing and analyzing module text
so a cache of ModuleSources may be shared by multiple Compartments.

@class
@param {string} source
@param {string | Options} [opts]