updateModuleSource = (moduleDescriptor, canonicalName) => {
  let moduleSource = isRecordModuleDescriptor(moduleDescriptor)
    ? moduleDescriptor.record
    : isSourceModuleDescriptor(moduleDescriptor)
      ? moduleDescriptor.source
      : undefined

  if (!moduleSource) {
    throw new GenerationError(
      `Unsupported module descriptor type; this is a bug`
    )
  }

  // this just avoids adding duplicates. shouldn't happen, but who knows
  if (moduleSource.imports.includes(canonicalName)) {
    return
  }

  if (isFrozen(moduleSource)) {
    moduleSource = { ...moduleSource }
  }

  const imports = isFrozen(moduleSource.imports)
    ? [...moduleSource.imports]
    : moduleSource.imports
  imports.push(canonicalName)

  moduleSource.imports = imports

  if (isRecordModuleDescriptor(moduleDescriptor)) {
    moduleDescriptor.record = moduleSource
  } else if (isSourceModuleDescriptor(moduleDescriptor)) {
    moduleDescriptor.source = moduleSource
  } else {
    throw new GenerationError(
      `Unsupported module descriptor type; this is a bug`
    )
  }
}
Append `canonicalName` to the {@link ModuleSource.imports} field within a
{@link ModuleDescriptor}.

This mutates `moduleDescriptor` by overwriting its `ModuleSource` object
(which could be in either `source` or the deprecated `record` prop). It also
overwrites the `ModuleSource.imports` array. Overwritten objects are
originally non-extensible (frozen), so we must replace them outright.

Once we have overwritten these objects, we should not overwrite them again;
instead, mutate them in-place to avoid potentially losing object references
elsewhere in `@endo/compartment-mapper`. This is a precautionary measure.

@template {SourceModuleDescriptor | RecordModuleDescriptor} T
@param {T} moduleDescriptor - Module descriptor to update
@param {string} canonicalName - Canonical name to append to
  {@link ModuleSource.imports}