Skip to content

Commit

Permalink
fix: auto-install-peers in a workspace
Browse files Browse the repository at this point in the history
wip
  • Loading branch information
zkochan committed Sep 17, 2022
1 parent 13fccba commit 371431d
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 36 deletions.
5 changes: 5 additions & 0 deletions packages/resolve-dependencies/src/nodeIdUtils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
export function nodeIdContains (nodeId: string, pkgId: string) {
const pkgIds = splitNodeId(nodeId)
return pkgIds.includes(pkgId)
}

export function nodeIdContainsSequence (nodeId: string, pkgId1: string, pkgId2: string) {
const pkgIds = splitNodeId(nodeId)
pkgIds.pop()
Expand Down
118 changes: 82 additions & 36 deletions packages/resolve-dependencies/src/resolveDependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import { safeIntersect } from './mergePeers'
import {
createNodeId,
nodeIdContainsSequence,
nodeIdContains,
splitNodeId,
} from './nodeIdUtils'
import wantedDepIsLocallyAvailable from './wantedDepIsLocallyAvailable'
Expand Down Expand Up @@ -156,7 +157,7 @@ export interface ResolutionContext {
virtualStoreDir: string
updateMatching?: (pkgName: string) => boolean
workspacePackages?: WorkspacePackages
missingPeersOfChildrenByPkgId: Record<string, pDefer.DeferredPromise<MissingPeers>>
missingPeersOfChildrenByPkgId: Record<string, { parentNodeId: string, missingPeers: pDefer.DeferredPromise<MissingPeers> }>
}

export type MissingPeers = Record<string, string>
Expand All @@ -178,7 +179,7 @@ export type PkgAddress = {
updated: boolean
rootDir: string
missingPeers: MissingPeers
missingPeersOfChildren: pDefer.DeferredPromise<MissingPeers>
missingPeersOfChildren?: pDefer.DeferredPromise<MissingPeers>
resolvedPeers: ResolvedPeers
publishedAt?: string
} & ({
Expand Down Expand Up @@ -285,11 +286,16 @@ export async function resolveRootDependencies (
if (!Object.keys(importerResolutionResult.missingPeers).length) break
const wantedDependencies = getNonDevWantedDependencies({ dependencies: importerResolutionResult.missingPeers })

importerResolutionResult = await resolveDependencies(ctx, preferredVersions, wantedDependencies, {
const importerResolutionResultt = await resolveDependencies(ctx, preferredVersions, wantedDependencies, {
...options,
parentPkgAliases,
publishedBy,
})
importerResolutionResult = {
pkgAddresses: importerResolutionResultt.pkgAddresses,
missingPeers: (await importerResolutionResultt.peers).missingPeers,
resolvedPeers: (await importerResolutionResultt.peers).resolvedPeers,
}
pkgAddresses.push(...importerResolutionResult.pkgAddresses)
}
return pkgAddresses
Expand All @@ -298,6 +304,14 @@ export async function resolveRootDependencies (
}

interface ResolvedDependenciesResult {
pkgAddresses: Array<PkgAddress | LinkedDependency>
peers: Promise<{
missingPeers: MissingPeers
resolvedPeers: ResolvedPeers
}>
}

interface ResolvedDependenciesResultWithoutPromise {
pkgAddresses: Array<PkgAddress | LinkedDependency>
missingPeers: MissingPeers
resolvedPeers: ResolvedPeers
Expand All @@ -312,7 +326,7 @@ export interface ImporterToResolve {
}

interface ResolveDependenciesOfImportersResult {
pkgAddressesByImportersWithoutPeers: ResolvedDependenciesResult[]
pkgAddressesByImportersWithoutPeers: ResolvedDependenciesResultWithoutPromise[]
publishedBy?: Date
time?: Record<string, string>
}
Expand All @@ -332,6 +346,7 @@ async function resolveDependenciesOfImporters (
const resolveResults = await Promise.all(
zipWith(async (extendedWantedDeps, importer) => {
const postponedResolutionsQueue: PostponedResolutionFunction[] = []
const postponedMissingPeersQueue: PostponedResolutionFunction[] = []
const pkgAddresses: PkgAddress[] = []
;(await Promise.all(
extendedWantedDeps.map((extendedWantedDep) => resolveDependenciesOfDependency(
Expand All @@ -344,15 +359,18 @@ async function resolveDependenciesOfImporters (
},
extendedWantedDep
))
)).forEach(({ resolveDependencyResult, postponedResolution }) => {
)).forEach(({ resolveDependencyResult, missingPeersPromise, postponedResolution }) => {
if (resolveDependencyResult) {
pkgAddresses.push(resolveDependencyResult as PkgAddress)
}
if (postponedResolution) {
postponedResolutionsQueue.push(postponedResolution)
}
if (missingPeersPromise) {
postponedMissingPeersQueue.push(missingPeersPromise)
}
})
return { pkgAddresses, postponedResolutionsQueue }
return { pkgAddresses, postponedResolutionsQueue, postponedMissingPeersQueue }
}, extendedWantedDepsByImporters, importers)
)
let publishedBy: Date | undefined
Expand All @@ -364,7 +382,7 @@ async function resolveDependenciesOfImporters (
time = result.newTime
}
}
const pkgAddressesByImportersWithoutPeers = await Promise.all(zipWith(async (importer, { pkgAddresses, postponedResolutionsQueue }) => {
const pkgAddressesByImportersWithoutPeers = await Promise.all(zipWith(async (importer, { pkgAddresses, postponedResolutionsQueue, postponedMissingPeersQueue }) => {
const newPreferredVersions = { ...importer.preferredVersions }
const newParentPkgAliases = { ...importer.parentPkgAliases }
for (const pkgAddress of pkgAddresses) {
Expand Down Expand Up @@ -396,16 +414,20 @@ async function resolveDependenciesOfImporters (
resolvedPeers: {},
}
}
const missingPeersPromise = await Promise.all(
postponedMissingPeersQueue.map((postponedMissingPeers) => postponedMissingPeers(postponedResolutionOpts))
)
const allMissingPeers = mergePkgsDeps(
[
...pkgAddresses,
...childrenResults,
...missingPeersPromise,
].map(({ missingPeers }) => missingPeers).filter(Boolean)
)
return {
missingPeers: allMissingPeers,
pkgAddresses,
resolvedPeers: [...pkgAddresses, ...childrenResults].reduce((acc, { resolvedPeers }) => Object.assign(acc, resolvedPeers), {}),
resolvedPeers: [...pkgAddresses, ...childrenResults, ...missingPeersPromise].reduce((acc, { resolvedPeers }) => Object.assign(acc, resolvedPeers), {}),
}
}, importers, resolveResults))
return {
Expand Down Expand Up @@ -444,6 +466,7 @@ export async function resolveDependencies (
resolvedDependencies: options.resolvedDependencies,
})
const postponedResolutionsQueue: PostponedResolutionFunction[] = []
const postponedMissingPeersQueue: PostponedResolutionFunction[] = []
const pkgAddresses: PkgAddress[] = []
;(await Promise.all(
extendedWantedDeps.map((extendedWantedDep) => resolveDependenciesOfDependency(
Expand All @@ -452,13 +475,16 @@ export async function resolveDependencies (
options,
extendedWantedDep
))
)).forEach(({ resolveDependencyResult, postponedResolution }) => {
)).forEach(({ resolveDependencyResult, postponedResolution, missingPeersPromise }) => {
if (resolveDependencyResult) {
pkgAddresses.push(resolveDependencyResult as PkgAddress)
}
if (postponedResolution) {
postponedResolutionsQueue.push(postponedResolution)
}
if (missingPeersPromise) {
postponedMissingPeersQueue.push(missingPeersPromise)
}
})
const newPreferredVersions = { ...preferredVersions }
const newNewParentPkgAliases = {}
Expand Down Expand Up @@ -490,24 +516,35 @@ export async function resolveDependencies (
)
if (!ctx.autoInstallPeers) {
return {
missingPeers: {},
peers: Promise.resolve({
missingPeers: {},
resolvedPeers: {},
}),
pkgAddresses,
resolvedPeers: {},
}
}
const allMissingPeers = mergePkgsDeps(
[
...pkgAddresses.map((pkgAddress) => ({
...pkgAddress,
missingPeers: fromPairs(Object.entries(pkgAddress.missingPeers || {}).filter(([peerName]) => !newNewParentPkgAliases[peerName])),
})),
...childrenResults,
].map(({ missingPeers }) => missingPeers).filter(Boolean)
)
const peers = (async () => {
const results = await Promise.all(
postponedMissingPeersQueue.map((postponedMissingPeers) => postponedMissingPeers(postponedResolutionOpts))
)
const allMissingPeers = mergePkgsDeps(
[
...pkgAddresses.map((pkgAddress) => ({
...pkgAddress,
missingPeers: fromPairs(Object.entries(pkgAddress.missingPeers || {}).filter(([peerName]) => !newNewParentPkgAliases[peerName])),
})),
...childrenResults,
...results,
].map(({ missingPeers }) => missingPeers).filter(Boolean)
)
return {
missingPeers: allMissingPeers,
resolvedPeers: [...pkgAddresses, ...childrenResults, ...results].reduce((acc, { resolvedPeers }) => Object.assign(acc, resolvedPeers), {}),
}
})()
return {
missingPeers: allMissingPeers,
pkgAddresses,
resolvedPeers: [...pkgAddresses, ...childrenResults].reduce((acc, { resolvedPeers }) => Object.assign(acc, resolvedPeers), {}),
peers,
}
}

Expand Down Expand Up @@ -539,6 +576,7 @@ interface ExtendedWantedDependency {

interface ResolveDependenciesOfDependency {
postponedResolution?: PostponedResolutionFunction
missingPeersPromise?: PostponedResolutionFunction
resolveDependencyResult: ResolveDependencyResult
}

Expand Down Expand Up @@ -599,8 +637,8 @@ async function resolveDependenciesOfDependency (
if (!resolveDependencyResult.isNew) {
return {
resolveDependencyResult,
postponedResolution: async (postponedResolutionOpts) => {
const missingPeers = await resolveDependencyResult.missingPeersOfChildren.promise
missingPeersPromise: resolveDependencyResult.missingPeersOfChildren != null ? async (postponedResolutionOpts) => {
const missingPeers = await resolveDependencyResult.missingPeersOfChildren!.promise
const newMissing = {} as MissingPeers
const resolvedPeers = {} as ResolvedPeers
for (const [peerName, peerVersion] of Object.entries(missingPeers)) {
Expand All @@ -616,7 +654,7 @@ async function resolveDependenciesOfDependency (
missingPeers: newMissing,
resolvedPeers,
}
},
} : undefined,
}
}

Expand All @@ -632,10 +670,11 @@ async function resolveDependenciesOfDependency (
postponedResolution: async (postponedResolutionOpts) => {
try {
const result = await postponedResolution(postponedResolutionOpts)
resolveDependencyResult.missingPeersOfChildren.resolve(result.missingPeers)
const missingPeers = (await result.peers).missingPeers
resolveDependencyResult.missingPeersOfChildren!.resolve(missingPeers)
const newMissing = {} as MissingPeers
const resolvedPeers = {} as ResolvedPeers
for (const [peerName, peerVersion] of Object.entries(result.missingPeers)) {
for (const [peerName, peerVersion] of Object.entries(missingPeers)) {
if (postponedResolutionOpts.parentPkgAliases[peerName]) {
if (postponedResolutionOpts.parentPkgAliases[peerName] !== true) {
resolvedPeers[peerName] = postponedResolutionOpts.parentPkgAliases[peerName] as PkgAddress
Expand All @@ -649,7 +688,7 @@ async function resolveDependenciesOfDependency (
missingPeers: newMissing,
}
} catch (err) {
resolveDependencyResult.missingPeersOfChildren.reject(err)
resolveDependencyResult.missingPeersOfChildren!.reject(err)
throw err
}
},
Expand Down Expand Up @@ -700,8 +739,7 @@ async function resolveChildren (
const wantedDependencies = getNonDevWantedDependencies(parentPkg.pkg)
const {
pkgAddresses,
missingPeers,
resolvedPeers,
peers,
} = await resolveDependencies(ctx, preferredVersions, wantedDependencies,
{
currentDepth: parentDepth + 1,
Expand Down Expand Up @@ -731,8 +769,7 @@ async function resolveChildren (
resolvedPackage: ctx.resolvedPackagesByDepPath[parentPkg.depPath],
}
return {
missingPeers,
resolvedPeers,
peers,
}
}

Expand Down Expand Up @@ -1215,12 +1252,21 @@ async function resolveDependency (
const rootDir = pkgResponse.body.resolution.type === 'directory'
? path.resolve(ctx.lockfileDir, pkgResponse.body.resolution['directory'])
: options.prefix
let missingPeersOfChildren!: pDefer.DeferredPromise<MissingPeers>
if (ctx.missingPeersOfChildrenByPkgId[pkgResponse.body.id]) {
missingPeersOfChildren = ctx.missingPeersOfChildrenByPkgId[pkgResponse.body.id]
let missingPeersOfChildren!: pDefer.DeferredPromise<MissingPeers> | undefined
if (nodeIdContains(options.parentPkg.nodeId, depPath)) {
} else if (ctx.missingPeersOfChildrenByPkgId[pkgResponse.body.id]) {
if (!options.parentPkg.nodeId.startsWith(ctx.missingPeersOfChildrenByPkgId[pkgResponse.body.id].parentNodeId)) {
missingPeersOfChildren = ctx.missingPeersOfChildrenByPkgId[pkgResponse.body.id].missingPeers
} else {
// console.log('current', options.parentPkg.nodeId)
// console.log('in cache', ctx.missingPeersOfChildrenByPkgId[pkgResponse.body.id].parentNodeId)
}
} else {
missingPeersOfChildren = pDefer<MissingPeers>()
ctx.missingPeersOfChildrenByPkgId[pkgResponse.body.id] = missingPeersOfChildren
ctx.missingPeersOfChildrenByPkgId[pkgResponse.body.id] = {
parentNodeId: options.parentPkg.nodeId,
missingPeers: missingPeersOfChildren,
}
}
return {
alias: wantedDependency.alias || pkg.name,
Expand Down

0 comments on commit 371431d

Please sign in to comment.