import { importModule } from 'local-pkg'; /* How it works: `this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value. */ class Node { value; next; constructor(value) { this.value = value; } } class Queue { #head; #tail; #size; constructor() { this.clear(); } enqueue(value) { const node = new Node(value); if (this.#head) { this.#tail.next = node; this.#tail = node; } else { this.#head = node; this.#tail = node; } this.#size++; } dequeue() { const current = this.#head; if (!current) { return; } this.#head = this.#head.next; this.#size--; return current.value; } clear() { this.#head = undefined; this.#tail = undefined; this.#size = 0; } get size() { return this.#size; } * [Symbol.iterator]() { let current = this.#head; while (current) { yield current.value; current = current.next; } } } function pLimit(concurrency) { if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) { throw new TypeError('Expected `concurrency` to be a number from 1 and up'); } const queue = new Queue(); let activeCount = 0; const next = () => { activeCount--; if (queue.size > 0) { queue.dequeue()(); } }; const run = async (fn, resolve, args) => { activeCount++; const result = (async () => fn(...args))(); resolve(result); try { await result; } catch {} next(); }; const enqueue = (fn, resolve, args) => { queue.enqueue(run.bind(undefined, fn, resolve, args)); (async () => { // This function needs to wait until the next microtask before comparing // `activeCount` to `concurrency`, because `activeCount` is updated asynchronously // when the run function is dequeued and called. The comparison in the if-statement // needs to happen asynchronously as well to get an up-to-date value for `activeCount`. await Promise.resolve(); if (activeCount < concurrency && queue.size > 0) { queue.dequeue()(); } })(); }; const generator = (fn, ...args) => new Promise(resolve => { enqueue(fn, resolve, args); }); Object.defineProperties(generator, { activeCount: { get: () => activeCount, }, pendingCount: { get: () => queue.size, }, clearQueue: { value: () => { queue.clear(); }, }, }); return generator; } const CoverageProviderMap = { c8: "@vitest/coverage-c8", istanbul: "@vitest/coverage-istanbul" }; async function resolveCoverageProvider(provider) { if (typeof provider === "string") { const pkg = CoverageProviderMap[provider]; if (!pkg) throw new Error(`Unknown coverage provider: ${provider}`); return await importModule(pkg); } else { return provider; } } async function getCoverageProvider(options) { if ((options == null ? void 0 : options.enabled) && (options == null ? void 0 : options.provider)) { const { getProvider } = await resolveCoverageProvider(options.provider); return await getProvider(); } return null; } async function takeCoverageInsideWorker(options) { if (options.enabled && options.provider) { const { takeCoverage } = await resolveCoverageProvider(options.provider); return await (takeCoverage == null ? void 0 : takeCoverage()); } } function interpretTaskModes(suite, namePattern, onlyMode, parentIsOnly, allowOnly) { const suiteIsOnly = parentIsOnly || suite.mode === "only"; suite.tasks.forEach((t) => { const includeTask = suiteIsOnly || t.mode === "only"; if (onlyMode) { if (t.type === "suite" && (includeTask || someTasksAreOnly(t))) { if (t.mode === "only") { checkAllowOnly(t, allowOnly); t.mode = "run"; } } else if (t.mode === "run" && !includeTask) { t.mode = "skip"; } else if (t.mode === "only") { checkAllowOnly(t, allowOnly); t.mode = "run"; } } if (t.type === "test") { if (namePattern && !getTaskFullName(t).match(namePattern)) t.mode = "skip"; } else if (t.type === "suite") { if (t.mode === "skip") skipAllTasks(t); else interpretTaskModes(t, namePattern, onlyMode, includeTask, allowOnly); } }); if (suite.mode === "run") { if (suite.tasks.length && suite.tasks.every((i) => i.mode !== "run")) suite.mode = "skip"; } } function getTaskFullName(task) { return `${task.suite ? `${getTaskFullName(task.suite)} ` : ""}${task.name}`; } function someTasksAreOnly(suite) { return suite.tasks.some((t) => t.mode === "only" || t.type === "suite" && someTasksAreOnly(t)); } function skipAllTasks(suite) { suite.tasks.forEach((t) => { if (t.mode === "run") { t.mode = "skip"; if (t.type === "suite") skipAllTasks(t); } }); } function checkAllowOnly(task, allowOnly) { if (allowOnly) return; task.result = { state: "fail", error: new Error("[Vitest] Unexpected .only modifier. Remove it or pass --allowOnly argument to bypass this error") }; } function generateHash(str) { let hash = 0; if (str.length === 0) return `${hash}`; for (let i = 0; i < str.length; i++) { const char = str.charCodeAt(i); hash = (hash << 5) - hash + char; hash = hash & hash; } return `${hash}`; } function calculateSuiteHash(parent) { parent.tasks.forEach((t, idx) => { t.id = `${parent.id}_${idx}`; if (t.type === "suite") calculateSuiteHash(t); }); } export { CoverageProviderMap as C, getCoverageProvider as a, calculateSuiteHash as c, generateHash as g, interpretTaskModes as i, pLimit as p, someTasksAreOnly as s, takeCoverageInsideWorker as t };