async function loadCanonicalNameMap({
  rootDir,
  includeDevDeps,
  resolve = performantResolve,
}) {
  const canonicalNameMap = /** @type {CanonicalNameMap} */ (new Map())
  // walk tree
  const logicalPathMap = walkDependencyTreeForBestLogicalPaths({
    packageDir: rootDir,
    includeDevDeps,
    resolve,
  })
  //convert dependency paths to canonical package names
  for (const [packageDir, logicalPathParts] of logicalPathMap.entries()) {
    const logicalPathString = logicalPathParts.join('>')
    canonicalNameMap.set(packageDir, logicalPathString)
  }
  // add root dir as "app"
  canonicalNameMap.set(rootDir, '$root$')
  Reflect.defineProperty(canonicalNameMap, 'rootDir', { value: rootDir })
  return canonicalNameMap
}
@param {LoadCanonicalNameMapOpts} options
@returns {Promise<CanonicalNameMap>}