hunk.code_window:   pkgId: string,
     pkgVersion: string,
   }
   export type StatsMessage = {
     added: number,
   } | {
     removed: number,
  
hunk.labels: keep keep keep keep add keep keep keep
hunk.after_edit:   prefix: string,
   } & ({
  
hunk.file_path: src/loggers.ts
hunk.type: add
file: import * as dp from 'dependency-path'
  import {StoreController} from 'package-store'
  import path = require('path')
  import {ResolvedPackages, Shrinkwrap} from 'pnpm-shrinkwrap'
  import R = require('ramda')
  import rimraf = require('rimraf-then')
  import {dependenciesTypes} from '../getSaveType'
  import {statsLogger} from '../loggers'
  import removeTopDependency from '../removeTopDependency'
  
  export default async function removeOrphanPkgs (
    opts: {
      bin: string,
      dryRun?: boolean,
      hoistedAliases: {[depPath: string]: string[]},
      newShrinkwrap: Shrinkwrap,
      oldShrinkwrap: Shrinkwrap,
      prefix: string,
      pruneStore?: boolean,
      shamefullyFlatten: boolean,
      storeController: StoreController,
    },
  ): Promise<Set<string>> {
    const oldPkgs = R.toPairs(R.mergeAll(R.map((depType) => opts.oldShrinkwrap[depType], dependenciesTypes)))
    const newPkgs = R.toPairs(R.mergeAll(R.map((depType) => opts.newShrinkwrap[depType], dependenciesTypes)))
  
    const removedTopDeps: Array<[string, string]> = R.difference(oldPkgs, newPkgs) as Array<[string, string]>
  
    const rootModules = path.join(opts.prefix, 'node_modules')
    await Promise.all(removedTopDeps.map((depName) => {
      return removeTopDependency({
        dev: Boolean(opts.oldShrinkwrap.devDependencies && opts.oldShrinkwrap.devDependencies[depName[0]]),
        name: depName[0],
        optional: Boolean(opts.oldShrinkwrap.optionalDependencies && opts.oldShrinkwrap.optionalDependencies[depName[0]]),
      }, {
        bin: opts.bin,
        dryRun: opts.dryRun,
        modules: rootModules,
      })
    }))
  
    const oldPkgIdsByDepPaths = getPkgsDepPaths(opts.oldShrinkwrap.registry, opts.oldShrinkwrap.packages || {})
    const newPkgIdsByDepPaths = getPkgsDepPaths(opts.newShrinkwrap.registry, opts.newShrinkwrap.packages || {})
  
    const oldDepPaths = Object.keys(oldPkgIdsByDepPaths)
    const newDepPaths = Object.keys(newPkgIdsByDepPaths)
  
    const orphanDepPaths = R.difference(oldDepPaths, newDepPaths)
    const orphanPkgIds = new Set(R.props<string, string>(orphanDepPaths, oldPkgIdsByDepPaths))
  
    statsLogger.debug({removed: orphanPkgIds.size})
  
    if (!opts.dryRun) {
      if (orphanDepPaths.length) {
  
        if (opts.shamefullyFlatten && opts.oldShrinkwrap.packages) {
          await Promise.all(orphanDepPaths.map(async (orphanDepPath) => {
            if (opts.hoistedAliases[orphanDepPath]) {
              await Promise.all(opts.hoistedAliases[orphanDepPath].map(async (alias) => {
                await removeTopDependency({
                  dev: false,
                  name: alias,
                  optional: false,
                }, {
                  bin: opts.bin,
                  modules: rootModules,
                  muteLogs: true,
                })
              }))
            }
            delete opts.hoistedAliases[orphanDepPath]
          }))
        }
  
        await Promise.all(orphanDepPaths.map(async (orphanDepPath) => {
          await rimraf(path.join(rootModules, `.${orphanDepPath}`))
        }))
      }
  
      const addedDepPaths = R.difference(newDepPaths, oldDepPaths)
      const addedPkgIds = new Set(R.props<string, string>(addedDepPaths, newPkgIdsByDepPaths))
  
      await opts.storeController.updateConnections(opts.prefix, {
        addDependencies: Array.from(addedPkgIds),
        prune: opts.pruneStore || false,
        removeDependencies: Array.from(orphanPkgIds),
      })
  
      await opts.storeController.saveState()
    }
  
    return new Set(orphanDepPaths)
  }
  
  function getPkgsDepPaths (
    registry: string,
    packages: ResolvedPackages,
  ): {[depPath: string]: string} {
    const pkgIdsByDepPath = {}
    for (const relDepPath of Object.keys(packages)) {
      const depPath = dp.resolve(registry, relDepPath)
      pkgIdsByDepPath[depPath] = packages[relDepPath].id
        ? packages[relDepPath].id
        : depPath
    }
    return pkgIdsByDepPath
  }
  