@vitest/runner 4.1.0-beta.4 → 4.1.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -249,28 +249,45 @@ function limitConcurrency(concurrency = Infinity) {
249
249
  tail = head && tail;
250
250
  }
251
251
  };
252
- return (func, ...args) => {
253
- // Create a promise chain that:
254
- // 1. Waits for its turn in the task queue (if necessary).
255
- // 2. Runs the task.
256
- // 3. Allows the next pending task (if any) to run.
252
+ const acquire = () => {
253
+ let released = false;
254
+ const release = () => {
255
+ if (!released) {
256
+ released = true;
257
+ finish();
258
+ }
259
+ };
260
+ if (count++ < concurrency) {
261
+ return release;
262
+ }
257
263
  return new Promise((resolve) => {
258
- if (count++ < concurrency) {
259
- // No need to queue if fewer than maxConcurrency tasks are running.
260
- resolve();
261
- } else if (tail) {
264
+ if (tail) {
262
265
  // There are pending tasks, so append to the queue.
263
- tail = tail[1] = [resolve];
266
+ tail = tail[1] = [() => resolve(release)];
264
267
  } else {
265
268
  // No other pending tasks, initialize the queue with a new tail and head.
266
- head = tail = [resolve];
269
+ head = tail = [() => resolve(release)];
270
+ }
271
+ });
272
+ };
273
+ const limiterFn = (func, ...args) => {
274
+ function run(release) {
275
+ try {
276
+ const result = func(...args);
277
+ if (result instanceof Promise) {
278
+ return result.finally(release);
279
+ }
280
+ release();
281
+ return Promise.resolve(result);
282
+ } catch (error) {
283
+ release();
284
+ return Promise.reject(error);
267
285
  }
268
- }).then(() => {
269
- // Running func here ensures that even a non-thenable result or an
270
- // immediately thrown error gets wrapped into a Promise.
271
- return func(...args);
272
- }).finally(finish);
286
+ }
287
+ const release = acquire();
288
+ return release instanceof Promise ? release.then(run) : run(release);
273
289
  };
290
+ return Object.assign(limiterFn, { acquire });
274
291
  }
275
292
 
276
293
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as TestArtifact, a as Test, S as Suite, b as SuiteHooks, F as FileSpecification, V as VitestRunner, c as File, d as TaskUpdateEvent, e as Task, f as TestAPI, g as SuiteAPI, h as SuiteCollector } from './tasks.d-C-iOiT8j.js';
2
- export { A as AfterAllListener, i as AfterEachListener, j as AroundAllListener, k as AroundEachListener, B as BeforeAllListener, l as BeforeEachListener, C as CancelReason, m as FailureScreenshotArtifact, n as Fixture, o as FixtureFn, p as FixtureOptions, q as Fixtures, I as ImportDuration, r as InferFixturesTypes, O as OnTestFailedHandler, s as OnTestFinishedHandler, R as Retry, t as RunMode, u as RuntimeContext, v as SequenceHooks, w as SequenceSetupFiles, x as SerializableRetry, y as SuiteFactory, z as SuiteOptions, D as TaskBase, E as TaskCustomOptions, G as TaskEventPack, H as TaskHook, J as TaskMeta, K as TaskPopulated, L as TaskResult, M as TaskResultPack, N as TaskState, P as TestAnnotation, Q as TestAnnotationArtifact, U as TestAnnotationLocation, W as TestArtifactBase, X as TestArtifactLocation, Y as TestArtifactRegistry, Z as TestAttachment, _ as TestContext, $ as TestFunction, a0 as TestOptions, a1 as TestTagDefinition, a2 as TestTags, a3 as Use, a4 as VisualRegressionArtifact, a5 as VitestRunnerConfig, a6 as VitestRunnerConstructor, a7 as VitestRunnerImportSource, a8 as afterAll, a9 as afterEach, aa as aroundAll, ab as aroundEach, ac as beforeAll, ad as beforeEach, ae as onTestFailed, af as onTestFinished } from './tasks.d-C-iOiT8j.js';
1
+ import { T as TestArtifact, a as Test, S as Suite, b as SuiteHooks, F as FileSpecification, V as VitestRunner, c as File, d as TaskUpdateEvent, e as Task, f as TestAPI, g as SuiteAPI, h as SuiteCollector } from './tasks.d-D2GKpdwQ.js';
2
+ export { A as AfterAllListener, i as AfterEachListener, j as AroundAllListener, k as AroundEachListener, B as BeforeAllListener, l as BeforeEachListener, C as CancelReason, m as FailureScreenshotArtifact, n as Fixture, o as FixtureFn, p as FixtureOptions, q as Fixtures, I as ImportDuration, r as InferFixturesTypes, O as OnTestFailedHandler, s as OnTestFinishedHandler, R as Retry, t as RunMode, u as RuntimeContext, v as SequenceHooks, w as SequenceSetupFiles, x as SerializableRetry, y as SuiteFactory, z as SuiteOptions, D as TaskBase, E as TaskCustomOptions, G as TaskEventPack, H as TaskHook, J as TaskMeta, K as TaskPopulated, L as TaskResult, M as TaskResultPack, N as TaskState, P as TestAnnotation, Q as TestAnnotationArtifact, U as TestAnnotationLocation, W as TestArtifactBase, X as TestArtifactLocation, Y as TestArtifactRegistry, Z as TestAttachment, _ as TestContext, $ as TestFunction, a0 as TestOptions, a1 as TestTagDefinition, a2 as TestTags, a3 as Use, a4 as VisualRegressionArtifact, a5 as VitestRunnerConfig, a6 as VitestRunnerConstructor, a7 as VitestRunnerImportSource, a8 as afterAll, a9 as afterEach, aa as aroundAll, ab as aroundEach, ac as beforeAll, ad as beforeEach, ae as onTestFailed, af as onTestFinished } from './tasks.d-D2GKpdwQ.js';
3
3
  import { Awaitable } from '@vitest/utils';
4
4
  import '@vitest/utils/diff';
5
5
 
package/dist/index.js CHANGED
@@ -83,7 +83,7 @@ class TestFixtures {
83
83
  "file",
84
84
  "worker"
85
85
  ];
86
- static _workerContextSymbol = Symbol("workerContext");
86
+ static _workerContextSuite = { type: "worker" };
87
87
  static clearDefinitions() {
88
88
  TestFixtures._definitions.length = 0;
89
89
  }
@@ -142,10 +142,10 @@ class TestFixtures {
142
142
  return this._suiteContexts.get(file);
143
143
  }
144
144
  getWorkerContext() {
145
- if (!this._suiteContexts.has(TestFixtures._workerContextSymbol)) {
146
- this._suiteContexts.set(TestFixtures._workerContextSymbol, Object.create(null));
145
+ if (!this._suiteContexts.has(TestFixtures._workerContextSuite)) {
146
+ this._suiteContexts.set(TestFixtures._workerContextSuite, Object.create(null));
147
147
  }
148
- return this._suiteContexts.get(TestFixtures._workerContextSymbol);
148
+ return this._suiteContexts.get(TestFixtures._workerContextSuite);
149
149
  }
150
150
  parseUserFixtures(runner, userFixtures, supportNonTest, registrations = new Map(this._registrations)) {
151
151
  const errors = [];
@@ -1106,7 +1106,7 @@ function createSuiteCollector(name, factory = () => {}, mode, each, suiteOptions
1106
1106
  const stackTraceError = new Error("STACK_TRACE_ERROR");
1107
1107
  Error.stackTraceLimit = limit;
1108
1108
  if (handler) {
1109
- setFn(task, withTimeout(withAwaitAsyncAssertions(withFixtures(handler, { context }), task), timeout, false, stackTraceError, (_, error) => abortIfTimeout([context], error)));
1109
+ setFn(task, withTimeout(withCancel(withAwaitAsyncAssertions(withFixtures(handler, { context }), task), task.context.signal), timeout, false, stackTraceError, (_, error) => abortIfTimeout([context], error)));
1110
1110
  }
1111
1111
  if (runner.config.includeTaskLocation) {
1112
1112
  const error = stackTraceError.stack;
@@ -1640,6 +1640,23 @@ catch (error) {
1640
1640
  });
1641
1641
  });
1642
1642
  }
1643
+ function withCancel(fn, signal) {
1644
+ return (function runWithCancel(...args) {
1645
+ return new Promise((resolve, reject) => {
1646
+ signal.addEventListener("abort", () => reject(signal.reason));
1647
+ try {
1648
+ const result = fn(...args);
1649
+ if (typeof result === "object" && result != null && typeof result.then === "function") {
1650
+ result.then(resolve, reject);
1651
+ } else {
1652
+ resolve(result);
1653
+ }
1654
+ } catch (error) {
1655
+ reject(error);
1656
+ }
1657
+ });
1658
+ });
1659
+ }
1643
1660
  const abortControllers = new WeakMap();
1644
1661
  function abortIfTimeout([context], error) {
1645
1662
  if (context) {
@@ -1818,6 +1835,7 @@ function mergeHooks(baseHooks, hooks) {
1818
1835
  const now = globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
1819
1836
  const unixNow = Date.now;
1820
1837
  const { clearTimeout, setTimeout } = getSafeTimers();
1838
+ let limitMaxConcurrency;
1821
1839
  /**
1822
1840
  * Normalizes retry configuration to extract individual values.
1823
1841
  * Handles both number and object forms.
@@ -1891,14 +1909,14 @@ async function callTestHooks(runner, test, hooks, sequence) {
1891
1909
  };
1892
1910
  if (sequence === "parallel") {
1893
1911
  try {
1894
- await Promise.all(hooks.map((fn) => fn(test.context)));
1912
+ await Promise.all(hooks.map((fn) => limitMaxConcurrency(() => fn(test.context))));
1895
1913
  } catch (e) {
1896
1914
  failTask(test.result, e, runner.config.diffOptions);
1897
1915
  }
1898
1916
  } else {
1899
1917
  for (const fn of hooks) {
1900
1918
  try {
1901
- await fn(test.context);
1919
+ await limitMaxConcurrency(() => fn(test.context));
1902
1920
  } catch (e) {
1903
1921
  failTask(test.result, e, runner.config.diffOptions);
1904
1922
  }
@@ -1920,7 +1938,9 @@ async function callSuiteHook(suite, currentTask, name, runner, args) {
1920
1938
  updateSuiteHookState(currentTask, name, "run", runner);
1921
1939
  }
1922
1940
  async function runHook(hook) {
1923
- return getBeforeHookCleanupCallback(hook, await hook(...args), name === "beforeEach" ? args[0] : undefined);
1941
+ return limitMaxConcurrency(async () => {
1942
+ return getBeforeHookCleanupCallback(hook, await hook(...args), name === "beforeEach" ? args[0] : undefined);
1943
+ });
1924
1944
  }
1925
1945
  if (sequence === "parallel") {
1926
1946
  callbacks.push(...await Promise.all(hooks.map((hook) => runHook(hook))));
@@ -1964,6 +1984,7 @@ async function callAroundHooks(runInner, options) {
1964
1984
  await runInner();
1965
1985
  return;
1966
1986
  }
1987
+ const hookErrors = [];
1967
1988
  const createTimeoutPromise = (timeout, phase, stackTraceError) => {
1968
1989
  let timer;
1969
1990
  let timedout = false;
@@ -2000,6 +2021,8 @@ async function callAroundHooks(runInner, options) {
2000
2021
  let useCalled = false;
2001
2022
  let setupTimeout;
2002
2023
  let teardownTimeout;
2024
+ let setupLimitConcurrencyRelease;
2025
+ let teardownLimitConcurrencyRelease;
2003
2026
  // Promise that resolves when use() is called (setup phase complete)
2004
2027
  let resolveUseCalled;
2005
2028
  const useCalledPromise = new Promise((resolve) => {
@@ -2032,21 +2055,16 @@ async function callAroundHooks(runInner, options) {
2032
2055
  resolveUseCalled();
2033
2056
  // Setup phase completed - clear setup timer
2034
2057
  setupTimeout.clear();
2058
+ setupLimitConcurrencyRelease?.();
2035
2059
  // Run inner hooks - don't time this against our teardown timeout
2036
- let nextError;
2037
- try {
2038
- await runNextHook(index + 1);
2039
- } catch (value) {
2040
- nextError = { value };
2041
- }
2060
+ await runNextHook(index + 1).catch((e) => hookErrors.push(e));
2061
+ teardownLimitConcurrencyRelease = await limitMaxConcurrency.acquire();
2042
2062
  // Start teardown timer after inner hooks complete - only times this hook's teardown code
2043
2063
  teardownTimeout = createTimeoutPromise(timeout, "teardown", stackTraceError);
2044
2064
  // Signal that use() is returning (teardown phase starting)
2045
2065
  resolveUseReturned();
2046
- if (nextError) {
2047
- throw nextError.value;
2048
- }
2049
2066
  };
2067
+ setupLimitConcurrencyRelease = await limitMaxConcurrency.acquire();
2050
2068
  // Start setup timeout
2051
2069
  setupTimeout = createTimeoutPromise(timeout, "setup", stackTraceError);
2052
2070
  (async () => {
@@ -2058,6 +2076,9 @@ async function callAroundHooks(runInner, options) {
2058
2076
  resolveHookComplete();
2059
2077
  } catch (error) {
2060
2078
  rejectHookComplete(error);
2079
+ } finally {
2080
+ setupLimitConcurrencyRelease?.();
2081
+ teardownLimitConcurrencyRelease?.();
2061
2082
  }
2062
2083
  })();
2063
2084
  // Wait for either: use() to be called OR hook to complete (error) OR setup timeout
@@ -2068,6 +2089,7 @@ async function callAroundHooks(runInner, options) {
2068
2089
  setupTimeout.promise
2069
2090
  ]);
2070
2091
  } finally {
2092
+ setupLimitConcurrencyRelease?.();
2071
2093
  setupTimeout.clear();
2072
2094
  }
2073
2095
  // Wait for use() to return (inner hooks complete) OR hook to complete (error during inner hooks)
@@ -2077,10 +2099,14 @@ async function callAroundHooks(runInner, options) {
2077
2099
  try {
2078
2100
  await Promise.race([hookCompletePromise, teardownTimeout?.promise]);
2079
2101
  } finally {
2102
+ teardownLimitConcurrencyRelease?.();
2080
2103
  teardownTimeout?.clear();
2081
2104
  }
2082
2105
  };
2083
- await runNextHook(0);
2106
+ await runNextHook(0).catch((e) => hookErrors.push(e));
2107
+ if (hookErrors.length > 0) {
2108
+ throw hookErrors;
2109
+ }
2084
2110
  }
2085
2111
  async function callAroundAllHooks(suite, runSuiteInner) {
2086
2112
  await callAroundHooks(runSuiteInner, {
@@ -2168,14 +2194,14 @@ async function callCleanupHooks(runner, cleanups) {
2168
2194
  if (typeof fn !== "function") {
2169
2195
  return;
2170
2196
  }
2171
- await fn();
2197
+ await limitMaxConcurrency(() => fn());
2172
2198
  }));
2173
2199
  } else {
2174
2200
  for (const fn of cleanups) {
2175
2201
  if (typeof fn !== "function") {
2176
2202
  continue;
2177
2203
  }
2178
- await fn();
2204
+ await limitMaxConcurrency(() => fn());
2179
2205
  }
2180
2206
  }
2181
2207
  }
@@ -2241,24 +2267,20 @@ async function runTest(test, runner) {
2241
2267
  test.result.repeatCount = repeatCount;
2242
2268
  beforeEachCleanups = await $("test.beforeEach", () => callSuiteHook(suite, test, "beforeEach", runner, [test.context, suite]));
2243
2269
  if (runner.runTask) {
2244
- await $("test.callback", () => runner.runTask(test));
2270
+ await $("test.callback", () => limitMaxConcurrency(() => runner.runTask(test)));
2245
2271
  } else {
2246
2272
  const fn = getFn(test);
2247
2273
  if (!fn) {
2248
2274
  throw new Error("Test function is not found. Did you add it using `setFn`?");
2249
2275
  }
2250
- await $("test.callback", () => fn());
2276
+ await $("test.callback", () => limitMaxConcurrency(() => fn()));
2251
2277
  }
2252
2278
  await runner.onAfterTryTask?.(test, {
2253
2279
  retry: retryCount,
2254
2280
  repeats: repeatCount
2255
2281
  });
2256
2282
  if (test.result.state !== "fail") {
2257
- if (!test.repeats) {
2258
- test.result.state = "pass";
2259
- } else if (test.repeats && retry === retryCount) {
2260
- test.result.state = "pass";
2261
- }
2283
+ test.result.state = "pass";
2262
2284
  }
2263
2285
  } catch (e) {
2264
2286
  failTask(test.result, e, runner.config.diffOptions);
@@ -2358,6 +2380,11 @@ function failTask(result, err, diffOptions) {
2358
2380
  result.pending = true;
2359
2381
  return;
2360
2382
  }
2383
+ if (err instanceof TestRunAbortError) {
2384
+ result.state = "skip";
2385
+ result.note = err.message;
2386
+ return;
2387
+ }
2361
2388
  result.state = "fail";
2362
2389
  const errors = Array.isArray(err) ? err : [err];
2363
2390
  for (const e of errors) {
@@ -2379,6 +2406,22 @@ function markTasksAsSkipped(suite, runner) {
2379
2406
  }
2380
2407
  });
2381
2408
  }
2409
+ function markPendingTasksAsSkipped(suite, runner, note) {
2410
+ suite.tasks.forEach((t) => {
2411
+ if (!t.result || t.result.state === "run") {
2412
+ t.mode = "skip";
2413
+ t.result = {
2414
+ ...t.result,
2415
+ state: "skip",
2416
+ note
2417
+ };
2418
+ updateTask("test-cancel", t, runner);
2419
+ }
2420
+ if (t.type === "suite") {
2421
+ markPendingTasksAsSkipped(t, runner, note);
2422
+ }
2423
+ });
2424
+ }
2382
2425
  async function runSuite(suite, runner) {
2383
2426
  await runner.onBeforeRunSuite?.(suite);
2384
2427
  if (suite.result?.state === "fail") {
@@ -2479,11 +2522,10 @@ async function runSuite(suite, runner) {
2479
2522
  updateTask("suite-finished", suite, runner);
2480
2523
  }
2481
2524
  }
2482
- let limitMaxConcurrency;
2483
2525
  async function runSuiteChild(c, runner) {
2484
2526
  const $ = runner.trace;
2485
2527
  if (c.type === "test") {
2486
- return limitMaxConcurrency(() => $("run.test", {
2528
+ return $("run.test", {
2487
2529
  "vitest.test.id": c.id,
2488
2530
  "vitest.test.name": c.name,
2489
2531
  "vitest.test.mode": c.mode,
@@ -2491,7 +2533,7 @@ async function runSuiteChild(c, runner) {
2491
2533
  "code.file.path": c.file.filepath,
2492
2534
  "code.line.number": c.location?.line,
2493
2535
  "code.column.number": c.location?.column
2494
- }, () => runTest(c, runner)));
2536
+ }, () => runTest(c, runner));
2495
2537
  } else if (c.type === "suite") {
2496
2538
  return $("run.suite", {
2497
2539
  "vitest.suite.id": c.id,
@@ -2536,7 +2578,10 @@ async function startTests(specs, runner) {
2536
2578
  runner.cancel = (reason) => {
2537
2579
  // We intentionally create only one error since there is only one test run that can be cancelled
2538
2580
  const error = new TestRunAbortError("The test run was aborted by the user.", reason);
2539
- getRunningTests().forEach((test) => abortContextSignal(test.context, error));
2581
+ getRunningTests().forEach((test) => {
2582
+ abortContextSignal(test.context, error);
2583
+ markPendingTasksAsSkipped(test.file, runner, error.message);
2584
+ });
2540
2585
  return cancel?.(reason);
2541
2586
  };
2542
2587
  if (!workerRunners.has(runner)) {
@@ -213,7 +213,7 @@ declare class TestFixtures {
213
213
  private static _builtinFixtures;
214
214
  private static _fixtureOptionKeys;
215
215
  private static _fixtureScopes;
216
- private static _workerContextSymbol;
216
+ private static _workerContextSuite;
217
217
  static clearDefinitions(): void;
218
218
  static getWorkerContexts(): Record<string, any>[];
219
219
  static getFileContexts(file: File): Record<string, any>[];
@@ -605,7 +605,7 @@ interface TaskEventData {
605
605
  artifact?: TestArtifact | undefined;
606
606
  }
607
607
  type TaskEventPack = [id: string, event: TaskUpdateEvent, data: TaskEventData | undefined];
608
- type TaskUpdateEvent = "test-failed-early" | "suite-failed-early" | "test-prepare" | "test-finished" | "test-retried" | "suite-prepare" | "suite-finished" | "before-hook-start" | "before-hook-end" | "after-hook-start" | "after-hook-end" | "test-annotation" | "test-artifact";
608
+ type TaskUpdateEvent = "test-failed-early" | "suite-failed-early" | "test-prepare" | "test-finished" | "test-retried" | "test-cancel" | "suite-prepare" | "suite-finished" | "before-hook-start" | "before-hook-end" | "after-hook-start" | "after-hook-end" | "test-annotation" | "test-artifact";
609
609
  interface Suite extends TaskBase {
610
610
  type: "suite";
611
611
  /**
package/dist/types.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { A as AfterAllListener, i as AfterEachListener, j as AroundAllListener, k as AroundEachListener, B as BeforeAllListener, l as BeforeEachListener, C as CancelReason, m as FailureScreenshotArtifact, c as File, F as FileSpecification, n as Fixture, o as FixtureFn, p as FixtureOptions, q as Fixtures, I as ImportDuration, r as InferFixturesTypes, O as OnTestFailedHandler, s as OnTestFinishedHandler, R as Retry, t as RunMode, u as RuntimeContext, v as SequenceHooks, w as SequenceSetupFiles, x as SerializableRetry, S as Suite, g as SuiteAPI, h as SuiteCollector, y as SuiteFactory, b as SuiteHooks, z as SuiteOptions, e as Task, D as TaskBase, E as TaskCustomOptions, G as TaskEventPack, H as TaskHook, J as TaskMeta, K as TaskPopulated, L as TaskResult, M as TaskResultPack, N as TaskState, d as TaskUpdateEvent, a as Test, f as TestAPI, P as TestAnnotation, Q as TestAnnotationArtifact, U as TestAnnotationLocation, T as TestArtifact, W as TestArtifactBase, X as TestArtifactLocation, Y as TestArtifactRegistry, Z as TestAttachment, _ as TestContext, $ as TestFunction, a0 as TestOptions, a1 as TestTagDefinition, a2 as TestTags, a3 as Use, a4 as VisualRegressionArtifact, V as VitestRunner, a5 as VitestRunnerConfig, a6 as VitestRunnerConstructor, a7 as VitestRunnerImportSource } from './tasks.d-C-iOiT8j.js';
1
+ export { A as AfterAllListener, i as AfterEachListener, j as AroundAllListener, k as AroundEachListener, B as BeforeAllListener, l as BeforeEachListener, C as CancelReason, m as FailureScreenshotArtifact, c as File, F as FileSpecification, n as Fixture, o as FixtureFn, p as FixtureOptions, q as Fixtures, I as ImportDuration, r as InferFixturesTypes, O as OnTestFailedHandler, s as OnTestFinishedHandler, R as Retry, t as RunMode, u as RuntimeContext, v as SequenceHooks, w as SequenceSetupFiles, x as SerializableRetry, S as Suite, g as SuiteAPI, h as SuiteCollector, y as SuiteFactory, b as SuiteHooks, z as SuiteOptions, e as Task, D as TaskBase, E as TaskCustomOptions, G as TaskEventPack, H as TaskHook, J as TaskMeta, K as TaskPopulated, L as TaskResult, M as TaskResultPack, N as TaskState, d as TaskUpdateEvent, a as Test, f as TestAPI, P as TestAnnotation, Q as TestAnnotationArtifact, U as TestAnnotationLocation, T as TestArtifact, W as TestArtifactBase, X as TestArtifactLocation, Y as TestArtifactRegistry, Z as TestAttachment, _ as TestContext, $ as TestFunction, a0 as TestOptions, a1 as TestTagDefinition, a2 as TestTags, a3 as Use, a4 as VisualRegressionArtifact, V as VitestRunner, a5 as VitestRunnerConfig, a6 as VitestRunnerConstructor, a7 as VitestRunnerImportSource } from './tasks.d-D2GKpdwQ.js';
2
2
  import '@vitest/utils';
3
3
  import '@vitest/utils/diff';
package/dist/utils.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as Suite, c as File, e as Task, a1 as TestTagDefinition, a5 as VitestRunnerConfig, a as Test } from './tasks.d-C-iOiT8j.js';
2
- export { ag as ChainableFunction, ah as createChainable } from './tasks.d-C-iOiT8j.js';
1
+ import { S as Suite, c as File, e as Task, a1 as TestTagDefinition, a5 as VitestRunnerConfig, a as Test } from './tasks.d-D2GKpdwQ.js';
2
+ export { ag as ChainableFunction, ah as createChainable } from './tasks.d-D2GKpdwQ.js';
3
3
  import { ParsedStack, Arrayable } from '@vitest/utils';
4
4
  import '@vitest/utils/diff';
5
5
 
@@ -19,13 +19,17 @@ declare function createFileTask(filepath: string, root: string, projectName: str
19
19
  declare function generateFileHash(file: string, projectName: string | undefined): string;
20
20
  declare function findTestFileStackTrace(testFilePath: string, error: string): ParsedStack | undefined;
21
21
 
22
- /**
23
- * Return a function for running multiple async operations with limited concurrency.
24
- */
25
- declare function limitConcurrency(concurrency?: number): <
22
+ interface ConcurrencyLimiter extends ConcurrencyLimiterFn {
23
+ acquire: () => (() => void) | Promise<() => void>;
24
+ }
25
+ type ConcurrencyLimiterFn = <
26
26
  Args extends unknown[],
27
27
  T
28
28
  >(func: (...args: Args) => PromiseLike<T> | T, ...args: Args) => Promise<T>;
29
+ /**
30
+ * Return a function for running multiple async operations with limited concurrency.
31
+ */
32
+ declare function limitConcurrency(concurrency?: number): ConcurrencyLimiter;
29
33
 
30
34
  /**
31
35
  * Partition in tasks groups by consecutive concurrent
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/runner",
3
3
  "type": "module",
4
- "version": "4.1.0-beta.4",
4
+ "version": "4.1.0-beta.5",
5
5
  "description": "Vitest test runner",
6
6
  "license": "MIT",
7
7
  "funding": "https://opencollective.com/vitest",
@@ -39,7 +39,7 @@
39
39
  ],
40
40
  "dependencies": {
41
41
  "pathe": "^2.0.3",
42
- "@vitest/utils": "4.1.0-beta.4"
42
+ "@vitest/utils": "4.1.0-beta.5"
43
43
  },
44
44
  "scripts": {
45
45
  "build": "premove dist && rollup -c",