123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- 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());
- }
- }
- export { CoverageProviderMap as C, getCoverageProvider as g, pLimit as p, takeCoverageInsideWorker as t };
|