From c087d356bf4851fbcdeea3816364004a7a18d515 Mon Sep 17 00:00:00 2001 From: hasundue Date: Sat, 21 Oct 2023 18:18:40 +0900 Subject: [PATCH] refactor(mod/dependency): use Dependency.name for key of LatestSemVerCache --- src/dependency.ts | 57 +++++++++++++++++++++-------------------------- src/semver.ts | 2 +- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/dependency.ts b/src/dependency.ts index 9a622c38..3cec507c 100644 --- a/src/dependency.ts +++ b/src/dependency.ts @@ -1,7 +1,7 @@ import type { Maybe } from "../lib/types.ts"; import { Mutex } from "../lib/x/async.ts"; import type { Path, SemVerString } from "./types.ts"; -import { parseSemVer, SEMVER_REGEXP } from "./semver.ts"; +import { parseSemVer } from "./semver.ts"; import { assertExists } from "../lib/std/assert.ts"; export interface Dependency { @@ -33,16 +33,22 @@ function parseProps( async function resolveLatestSemVer( url: URL, ): Promise> { - await LatestSemverCache.lock(url); - const result = await _resolve(url); - LatestSemverCache.unlock(url); + const props = parseProps(url); + if (!props) { + // The specifier is does not contain a semver. + return; + } + await LatestSemverCache.lock(props.name); + const result = await _resolve(url, props); + LatestSemverCache.unlock(props.name); return result; } async function _resolve( url: URL, + props: Dependency, ): Promise> { - const cached = LatestSemverCache.get(url); + const cached = LatestSemverCache.get(props.name); if (cached) { return cached; } @@ -50,11 +56,6 @@ async function _resolve( // The dependency is already found to be up to date. return; } - const props = parseProps(url); - if (!props) { - // The specifier is does not contain a semver. - return; - } switch (url.protocol) { case "npm:": { const response = await fetch( @@ -74,10 +75,10 @@ async function _resolve( const latestSemVer: string = json["dist-tags"].latest; if (latestSemVer === props.version) { // The dependency is up to date - LatestSemverCache.set(url, null); + LatestSemverCache.set(props.name, null); return; } - return LatestSemverCache.set(url, latestSemVer as SemVerString); + return LatestSemverCache.set(props.name, latestSemVer as SemVerString); } case "http:": case "https:": { @@ -88,17 +89,17 @@ async function _resolve( await response.arrayBuffer(); if (!response.redirected) { // The host did not redirect to a url with semver - LatestSemverCache.set(url, null); + LatestSemverCache.set(props.name, null); return; } const specifierWithLatestSemVer = response.url; if (specifierWithLatestSemVer === url.href) { // The dependency is up to date - LatestSemverCache.set(url, null); + LatestSemverCache.set(props.name, null); return; } return LatestSemverCache.set( - url, + props.name, parseSemVer(specifierWithLatestSemVer) as SemVerString, ); } @@ -115,35 +116,27 @@ class LatestSemverCache { static #mutex = new Map(); static #cache = new Map(); - static lock(url: URL): Promise { - const key = this.getKey(url); - const mutex = this.#mutex.get(key) ?? - this.#mutex.set(key, new Mutex()).get(key)!; + static lock(name: string): Promise { + const mutex = this.#mutex.get(name) ?? + this.#mutex.set(name, new Mutex()).get(name)!; return mutex.acquire(); } - static unlock(url: URL): void { - const key = this.getKey(url); - const mutex = this.#mutex.get(key); + static unlock(name: string): void { + const mutex = this.#mutex.get(name); assertExists(mutex); mutex.release(); } - static get(url: URL): SemVerString | null | undefined { - const key = this.getKey(url); - return this.#cache.get(key); + static get(name: string): SemVerString | null | undefined { + return this.#cache.get(name); } static set( - url: URL, + name: string, semver: T, ): T { - const key = this.getKey(url); - this.#cache.set(key, semver); + this.#cache.set(name, semver); return semver; } - - static getKey(url: URL): string { - return url.href.split(SEMVER_REGEXP)[0]; - } } diff --git a/src/semver.ts b/src/semver.ts index a51761c6..83a4b367 100644 --- a/src/semver.ts +++ b/src/semver.ts @@ -2,7 +2,7 @@ import type { Maybe } from "../lib/types.ts"; import type { SemVerString } from "./types.ts"; // Ref: https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string -export const SEMVER_REGEXP = +const SEMVER_REGEXP = /@v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?/g; export function parseSemVer(