function initialize(t, source, options = {}) {
  const { endowments, imports = new Map() } = options;
  const record = new ModuleSource(source);
  // t.log(record.__syncModuleProgram__);
  const liveUpdaters = {};
  const onceUpdaters = {};
  const namespace = {};
  const log = [];

  const compartment = new Compartment(endowments);

  Object.entries(record.__liveExportMap__).forEach(
    ([exportedName, [localName]]) => {
      /** @param {any} value */
      const set = value => {
        namespace[exportedName] = value;
        log.push(`${exportedName}: ${JSON.stringify(value)}`);
      };
      const get = () => namespace[exportedName];

      // Initialization uses the fast local variable.
      liveUpdaters[localName] = set;

      // Live updates fall through to the scope proxy.
      // Live updates could be accomodated with an invasive rewrite of all
      // references to the variable in scope, but we elected to avoid
      // transforming code except for import and export statements, in order to
      // minimize surprise in debugging.
      Object.defineProperty(compartment.globalThis, localName, { get, set });
    },
  );

  Object.entries(record.__fixedExportMap__).forEach(
    ([exportedName, [localName]]) => {
      /** @param {any} value */
      onceUpdaters[localName] = value => {
        t.assert(!(exportedName in namespace));
        namespace[exportedName] = value;
        log.push(`${exportedName}: ${JSON.stringify(value)}`);
      };
    },
  );
  const functor = compartment.evaluate(record.__syncModuleProgram__);

  /** @type {Map<string, Map<string, Updater>>} */
  const updaters = new Map();

  /**
   * @param {ImportUpdaters} newUpdaters
   */
  function updateImports(newUpdaters) {
    for (const [module, moduleUpdaters] of newUpdaters) {
      const moduleImports = imports.get(module);
      const testUpdaters = new Map();
      updaters.set(module, testUpdaters);
      if (moduleImports) {
        for (const [importName, importUpdaters] of moduleUpdaters) {
          /** @param {any} value */
          const updateImport = value => {
            for (const importUpdater of importUpdaters) {
              importUpdater(value);
            }
          };
          testUpdaters.set(importName, updateImport);
          if (moduleImports.has(importName)) {
            updateImport(moduleImports.get(importName));
          }
        }
      }
    }

    // Reexports are by convention facilitated outside the function source.
    for (const module of record.reexports || []) {
      const moduleImports = imports.get(module);
      if (moduleImports === undefined) {
        t.fail(`link error for reexported module ${module}`);
      } else {
        for (const [importName, importValue] of moduleImports.entries()) {
          namespace[importName] = importValue;
        }
      }
    }
    for (const [module, items] of Object.entries(record.__reexportMap__)) {
      const moduleImports = imports.get(module);
      if (moduleImports === undefined) {
        t.fail(`link error for named reexports from module ${module}`);
      } else {
        for (const [localName, exportedName] of items) {
          namespace[exportedName] = moduleImports.get(localName);
        }
      }
    }
  }

  functor({
    imports: updateImports,
    liveVar: liveUpdaters,
    onceVar: onceUpdaters,
    importMeta: { url: 'file://meta.url' },
  });

  return { record, namespace, log, updaters };
}
@param {ExecutionContext} t
@param {string} source
@param {object} [options]
@param {object} [options.endowments]
@param {Map<string, Map<string, any>>} [options.imports]