graphPackages = async (
  maybeRead,
  canonical,
  packageLocation,
  conditions,
  mainPackageDescriptor,
  dev,
  commonDependencies,
  languageOptions,
  strict,
  { log = noop } = {},
) => {
  const memo = create(null);
  /**
   * @param {string} packageLocation
   * @returns {Promise<PackageDescriptor>}
   */
  const readDescriptor = packageLocation =>
    readDescriptorWithMemo(memo, maybeRead, packageLocation);

  if (mainPackageDescriptor !== undefined) {
    memo[packageLocation] = Promise.resolve(mainPackageDescriptor);
  }

  const packageDescriptor = await readDescriptor(packageLocation);

  conditions = new Set(conditions || []);
  conditions.add('import');
  conditions.add('default');
  conditions.add('endo');

  if (packageDescriptor === undefined) {
    throw Error(
      `Cannot find package.json for application at ${packageLocation}`,
    );
  }

  // Resolve common dependencies.
  /** @type {CommonDependencyDescriptors} */
  const commonDependencyDescriptors = {};
  const packageDescriptorDependencies = packageDescriptor.dependencies || {};
  for (const [alias, dependencyName] of entries(commonDependencies)) {
    const spec = packageDescriptorDependencies[dependencyName];
    if (spec === undefined) {
      throw Error(
        `Cannot find dependency ${dependencyName} for ${packageLocation} from common dependencies`,
      );
    }
    commonDependencyDescriptors[dependencyName] = {
      spec,
      alias,
    };
  }

  const graph = create(null);
  await graphPackage(
    packageDescriptor.name,
    readDescriptor,
    canonical,
    graph,
    {
      packageLocation,
      packageDescriptor,
    },
    conditions,
    dev,
    languageOptions,
    strict,
    {
      commonDependencyDescriptors,
      log,
    },
  );
  return graph;
}
Resolves with a {@link Graph} representing the packages for which
{@link CompartmentDescriptor CompartmentDescriptors} will be created.

@param {MaybeReadFn} maybeRead
@param {CanonicalFn} canonical
@param {string} packageLocation - location of the main package.
@param {Set<string>} conditions
@param {PackageDescriptor} mainPackageDescriptor - the parsed contents of the
main `package.json`, which was already read when searching for the
`package.json`.
@param {boolean|undefined} dev - whether to use devDependencies from this
package (and only this package).
@param {Record<string,string>} commonDependencies - dependencies to be added
to all packages
@param {LanguageOptions} languageOptions
@param {boolean} strict
@param {GraphPackagesOptions} options