From 3687db1463e6ab040b9ae956454546e113a2972a Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sun, 15 Sep 2024 00:08:12 +0200 Subject: [PATCH] fix: clear version cache on each generator instantiation (#382) --- src/providers/esmsh.ts | 2 +- src/providers/jsdelivr.ts | 2 +- src/providers/jspm.ts | 57 ++++++++++++++++++++++++--------------- src/providers/skypack.ts | 2 +- src/providers/unpkg.ts | 2 +- src/trace/resolver.ts | 6 +++-- 6 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/providers/esmsh.ts b/src/providers/esmsh.ts index 3d67bcc..5797595 100644 --- a/src/providers/esmsh.ts +++ b/src/providers/esmsh.ts @@ -85,7 +85,7 @@ export async function resolveLatestTarget( parentUrl: string ): Promise { const { registry, name, range, unstable } = target; - const versions = await fetchVersions(name); + const versions = await fetchVersions.call(this, name); const semverRange = new SemverRange(String(range) || "*", unstable); const version = semverRange.bestMatch(versions, unstable); if (version) { diff --git a/src/providers/jsdelivr.ts b/src/providers/jsdelivr.ts index 30ef209..78fc6fc 100644 --- a/src/providers/jsdelivr.ts +++ b/src/providers/jsdelivr.ts @@ -29,7 +29,7 @@ export async function resolveLatestTarget( parentUrl: string ): Promise { const { registry, name, range, unstable } = target; - const versions = await fetchVersions(name); + const versions = await fetchVersions.call(this, name); const semverRange = new SemverRange(String(range) || "*", unstable); const version = semverRange.bestMatch(versions, unstable); if (version) { diff --git a/src/providers/jspm.ts b/src/providers/jspm.ts index 2c0a6ac..f8754c2 100644 --- a/src/providers/jspm.ts +++ b/src/providers/jspm.ts @@ -16,6 +16,22 @@ const apiUrl = "https://api.jspm.io/"; const BUILD_POLL_TIME = 5 * 60 * 1000; const BUILD_POLL_INTERVAL = 5 * 1000; +interface JspmCache { + lookupCache: Map>; + versionsCacheMap: Map; + resolveCache: Record< + string, + { + latest: Promise; + majors: Record>; + minors: Record>; + tags: Record>; + } + >; + cachedErrors: Map>; + buildRequested: Map>; +} + export const supportedLayers = ["default", "system"]; export async function pkgToUrl( @@ -59,22 +75,20 @@ export function parseUrlPkg(url: string) { } } -let resolveCache: Record< - string, - { - latest: Promise; - majors: Record>; - minors: Record>; - tags: Record>; +function getJspmCache (resolver: Resolver): JspmCache { + const jspmCache = resolver.context.jspmCache; + if (!resolver.context.jspmCache) { + return resolver.context.jspmCache = { + lookupCache: new Map(), + versionsCacheMap: new Map(), + resolveCache: {}, + cachedErrors: new Map(), + buildRequested: new Map(), + }; } -> = {}; - -export function clearResolveCache() { - resolveCache = {}; + return jspmCache; } -const cachedErrors = new Map(); - async function checkBuildOrError( resolver: Resolver, pkgUrl: string, @@ -84,6 +98,7 @@ async function checkBuildOrError( if (pcfg) { return true; } + const { cachedErrors } = getJspmCache(resolver); // no package.json! Check if there's a build error: if (cachedErrors.has(pkgUrl)) return cachedErrors.get(pkgUrl); @@ -104,14 +119,14 @@ async function checkBuildOrError( return cachedErrorPromise; } -const buildRequested = new Map(); - async function ensureBuild(resolver: Resolver, pkg: ExactPackage, fetchOpts: any) { if (await checkBuildOrError(resolver, await pkgToUrl(pkg, "default"), fetchOpts)) return; const fullName = `${pkg.name}@${pkg.version}`; + const { buildRequested } = getJspmCache(resolver); + // no package.json AND no build error -> post a build request // once the build request has been posted, try polling for up to 2 mins if (buildRequested.has(fullName)) @@ -158,6 +173,8 @@ export async function resolveLatestTarget( return pkg; } + const { resolveCache } = getJspmCache(this); + const cache = (resolveCache[target.registry + ":" + target.name] = resolveCache[target.registry + ":" + target.name] || { latest: null, @@ -275,8 +292,6 @@ function pkgToLookupUrl(pkg: ExactPackage, edge = false) { }`; } -const lookupCache = new Map(); - async function lookupRange( this: Resolver, registry: string, @@ -285,6 +300,7 @@ async function lookupRange( unstable: boolean, parentUrl?: string ): Promise { + const { lookupCache } = getJspmCache(this); const url = pkgToLookupUrl({ registry, name, version: range }, unstable); if (lookupCache.has(url)) return lookupCache.get(url); @@ -294,7 +310,7 @@ async function lookupRange( return { registry, name, version: version.trim() }; } else { // not found - const versions = await fetchVersions(name); + const versions = await fetchVersions.call(this, name); const semverRange = new SemverRange(String(range) || "*", unstable); const version = semverRange.bestMatch(versions, unstable); @@ -312,9 +328,8 @@ async function lookupRange( return lookupPromise; } -const versionsCacheMap = new Map(); - -export async function fetchVersions(name: string): Promise { +export async function fetchVersions(this: Resolver, name: string): Promise { + const { versionsCacheMap } = getJspmCache(this); if (versionsCacheMap.has(name)) { return versionsCacheMap.get(name); } diff --git a/src/providers/skypack.ts b/src/providers/skypack.ts index ed5672a..5195ce7 100644 --- a/src/providers/skypack.ts +++ b/src/providers/skypack.ts @@ -28,7 +28,7 @@ export async function resolveLatestTarget( parentUrl: string ): Promise { const { registry, name, range, unstable } = target; - const versions = await fetchVersions(name); + const versions = await fetchVersions.call(this, name); const semverRange = new SemverRange(String(range) || "*", unstable); const version = semverRange.bestMatch(versions, unstable); if (version) { diff --git a/src/providers/unpkg.ts b/src/providers/unpkg.ts index aacd7e6..b15472a 100644 --- a/src/providers/unpkg.ts +++ b/src/providers/unpkg.ts @@ -29,7 +29,7 @@ export async function resolveLatestTarget( parentUrl: string ): Promise { const { registry, name, range, unstable } = target; - const versions = await fetchVersions(name); + const versions = await fetchVersions.call(this, name); const semverRange = new SemverRange(String(range) || "*", unstable); const version = semverRange.bestMatch(versions, unstable); if (version) { diff --git a/src/trace/resolver.ts b/src/trace/resolver.ts index ebc25bb..1c22f60 100644 --- a/src/trace/resolver.ts +++ b/src/trace/resolver.ts @@ -104,6 +104,7 @@ export class Resolver { traceCjs: boolean; traceTs: boolean; traceSystem: boolean; + context: Record; constructor({ env, log, @@ -132,6 +133,7 @@ export class Resolver { this.traceCjs = traceCjs; this.traceTs = traceTs; this.traceSystem = traceSystem; + this.context = {}; } addCustomProvider(name: string, provider: Provider) { @@ -359,8 +361,8 @@ export class Resolver { const resolveLatestTarget = getProvider( provider, this.providers - ).resolveLatestTarget.bind(this); - const pkg = await resolveLatestTarget(latestTarget, layer, parentUrl); + ).resolveLatestTarget; + const pkg = await resolveLatestTarget.call(this, latestTarget, layer, parentUrl); if (pkg) return pkg; if (provider === "nodemodules") {