vitest 3.1.0-beta.2 → 3.1.0

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.
Files changed (31) hide show
  1. package/LICENSE.md +29 -0
  2. package/dist/chunks/{base.CylSMlTD.js → base.bV8rwssx.js} +1 -1
  3. package/dist/chunks/{cac.JtTXbKz0.js → cac.1WcTh-zl.js} +10 -6
  4. package/dist/chunks/{cli-api.BTtPTYMs.js → cli-api.2yb7XCwB.js} +39 -37
  5. package/dist/chunks/{coverage.C2ohxaN0.js → coverage.SfnlalVs.js} +213 -8
  6. package/dist/chunks/{creator.BEXek7yQ.js → creator.CuL7xDWI.js} +65 -0
  7. package/dist/chunks/{execute.DZKwfrTs.js → execute.CwmnH2oH.js} +6 -6
  8. package/dist/chunks/{index.ZIOEXBQB.js → index.CwHmn5H5.js} +140 -100
  9. package/dist/chunks/{reporters.d.5g6jXhoW.d.ts → reporters.d.CfRkRKN2.d.ts} +39 -18
  10. package/dist/chunks/{typechecker.C2IpOhid.js → typechecker.CG0zmr19.js} +6 -6
  11. package/dist/chunks/{utils.OLmtDstN.js → utils.Lot3J_8U.js} +1 -1
  12. package/dist/chunks/{vite.d.Dh1jE-_V.d.ts → vite.d.4pkSbgmp.d.ts} +1 -1
  13. package/dist/chunks/{vm.BW5voG-u.js → vm.Lp7mPCVW.js} +91 -84
  14. package/dist/cli.js +1 -1
  15. package/dist/config.d.ts +6 -4
  16. package/dist/coverage.d.ts +2 -1
  17. package/dist/coverage.js +3 -3
  18. package/dist/execute.d.ts +0 -2
  19. package/dist/execute.js +1 -1
  20. package/dist/index.d.ts +6 -5
  21. package/dist/node.d.ts +17 -6
  22. package/dist/node.js +8 -8
  23. package/dist/reporters.d.ts +2 -1
  24. package/dist/reporters.js +3 -3
  25. package/dist/workers/forks.js +2 -2
  26. package/dist/workers/threads.js +2 -2
  27. package/dist/workers/vmForks.js +2 -2
  28. package/dist/workers/vmThreads.js +2 -2
  29. package/dist/workers.d.ts +2 -1
  30. package/dist/workers.js +3 -3
  31. package/package.json +17 -17
package/LICENSE.md CHANGED
@@ -681,6 +681,35 @@ Repository: terkelg/prompts
681
681
 
682
682
  ---------------------------------------
683
683
 
684
+ ## quansync
685
+ License: MIT
686
+ By: Anthony Fu, 三咲智子 Kevin Deng
687
+ Repository: git+https://github.com/quansync-dev/quansync.git
688
+
689
+ > MIT License
690
+ >
691
+ > Copyright (c) 2025-PRESENT Anthony Fu <https://github.com/antfu> and Kevin Deng <https://github.com/sxzz>
692
+ >
693
+ > Permission is hereby granted, free of charge, to any person obtaining a copy
694
+ > of this software and associated documentation files (the "Software"), to deal
695
+ > in the Software without restriction, including without limitation the rights
696
+ > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
697
+ > copies of the Software, and to permit persons to whom the Software is
698
+ > furnished to do so, subject to the following conditions:
699
+ >
700
+ > The above copyright notice and this permission notice shall be included in all
701
+ > copies or substantial portions of the Software.
702
+ >
703
+ > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
704
+ > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
705
+ > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
706
+ > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
707
+ > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
708
+ > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
709
+ > SOFTWARE.
710
+
711
+ ---------------------------------------
712
+
684
713
  ## resolve-pkg-maps
685
714
  License: MIT
686
715
  By: Hiroki Osame
@@ -1,5 +1,5 @@
1
1
  import { ModuleCacheMap } from 'vite-node/client';
2
- import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.DZKwfrTs.js';
2
+ import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.CwmnH2oH.js';
3
3
  import { p as provideWorkerState } from './utils.CtocqOoE.js';
4
4
 
5
5
  let _viteNode;
@@ -618,7 +618,7 @@ class CAC extends EventEmitter {
618
618
 
619
619
  const cac = (name = "") => new CAC(name);
620
620
 
621
- var version = "3.1.0-beta.2";
621
+ var version = "3.1.0";
622
622
 
623
623
  const apiConfig = (port) => ({
624
624
  port: {
@@ -1203,6 +1203,10 @@ const cliOptionsConfig = {
1203
1203
  alias: "no-color"
1204
1204
  },
1205
1205
  clearScreen: { description: "Clear terminal screen when re-running tests during watch mode (default: `true`)" },
1206
+ configLoader: {
1207
+ description: "Use `bundle` to bundle the config with esbuild or `runner` (experimental) to process it on the fly. This is only available in vite version 6.1.0 and above. (default: `bundle`)",
1208
+ argument: "<loader>"
1209
+ },
1206
1210
  standalone: { description: "Start Vitest without running tests. File filters will be ignored, tests will be running only on change (default: `false`)" },
1207
1211
  mergeReports: {
1208
1212
  description: "Path to a blob reports directory. If this options is used, Vitest won't run any tests, it will only report previously recorded tests",
@@ -1460,13 +1464,13 @@ async function start(mode, cliFilters, options) {
1460
1464
  process.title = "node (vitest)";
1461
1465
  } catch {}
1462
1466
  try {
1463
- const { startVitest } = await import('./cli-api.BTtPTYMs.js').then(function (n) { return n.f; });
1467
+ const { startVitest } = await import('./cli-api.2yb7XCwB.js').then(function (n) { return n.f; });
1464
1468
  const ctx = await startVitest(mode, cliFilters.map(normalize), normalizeCliOptions(cliFilters, options));
1465
1469
  if (!ctx.shouldKeepServer()) {
1466
1470
  await ctx.exit();
1467
1471
  }
1468
1472
  } catch (e) {
1469
- const { divider } = await import('./utils.OLmtDstN.js').then(function (n) { return n.u; });
1473
+ const { divider } = await import('./utils.Lot3J_8U.js').then(function (n) { return n.u; });
1470
1474
  console.error(`\n${c.red(divider(c.bold(c.inverse(" Startup Error "))))}`);
1471
1475
  console.error(e);
1472
1476
  console.error("\n\n");
@@ -1481,7 +1485,7 @@ async function init(project) {
1481
1485
  console.error(new Error("Only the \"browser\" project is supported. Use \"vitest init browser\" to create a new project."));
1482
1486
  process.exit(1);
1483
1487
  }
1484
- const { create } = await import('./creator.BEXek7yQ.js');
1488
+ const { create } = await import('./creator.CuL7xDWI.js');
1485
1489
  await create();
1486
1490
  }
1487
1491
  async function collect(mode, cliFilters, options) {
@@ -1489,7 +1493,7 @@ async function collect(mode, cliFilters, options) {
1489
1493
  process.title = "node (vitest)";
1490
1494
  } catch {}
1491
1495
  try {
1492
- const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.BTtPTYMs.js').then(function (n) { return n.f; });
1496
+ const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.2yb7XCwB.js').then(function (n) { return n.f; });
1493
1497
  const ctx = await prepareVitest(mode, {
1494
1498
  ...normalizeCliOptions(cliFilters, options),
1495
1499
  watch: false,
@@ -1511,7 +1515,7 @@ async function collect(mode, cliFilters, options) {
1511
1515
  }
1512
1516
  await ctx.close();
1513
1517
  } catch (e) {
1514
- const { divider } = await import('./utils.OLmtDstN.js').then(function (n) { return n.u; });
1518
+ const { divider } = await import('./utils.Lot3J_8U.js').then(function (n) { return n.u; });
1515
1519
  console.error(`\n${c.red(divider(c.bold(c.inverse(" Collect Error "))))}`);
1516
1520
  console.error(e);
1517
1521
  console.error("\n\n");
@@ -11,9 +11,9 @@ import { generateFileHash, createFileTask, limitConcurrency, hasFailed, getTasks
11
11
  import { SnapshotManager } from '@vitest/snapshot/manager';
12
12
  import { ViteNodeRunner } from 'vite-node/client';
13
13
  import { ViteNodeServer } from 'vite-node/server';
14
- import { v as version$1 } from './cac.JtTXbKz0.js';
14
+ import { v as version$1 } from './cac.1WcTh-zl.js';
15
15
  import { c as createBirpc } from './index.68735LiX.js';
16
- import { p as parse, s as stringify, g as printError, h as generateCodeFrame, b as BenchmarkReportsMap, R as ReportersMap, i as BlobReporter, r as readBlobs, H as HangingProcessReporter } from './index.ZIOEXBQB.js';
16
+ import { p as parse, s as stringify, g as printError, h as generateCodeFrame, b as BenchmarkReportsMap, R as ReportersMap, i as BlobReporter, r as readBlobs, H as HangingProcessReporter } from './index.CwHmn5H5.js';
17
17
  import require$$0$3 from 'events';
18
18
  import require$$1$1 from 'https';
19
19
  import require$$2 from 'http';
@@ -28,11 +28,11 @@ import { g as getDefaultExportFromCjs } from './_commonjsHelpers.BFTU3MAI.js';
28
28
  import { parseErrorStacktrace } from '@vitest/utils/source-map';
29
29
  import crypto from 'node:crypto';
30
30
  import { distDir, rootDir } from '../path.js';
31
- import { R as RandomSequencer, i as isPackageExists, h as hash, V as VitestCache, g as getFilePoolName, d as isBrowserEnabled, m as mm, r as resolveConfig, e as groupBy, f as getCoverageProvider, j as createPool, w as wildcardPatternToRegExp, a as resolveApiServerConfig, s as stdout } from './coverage.C2ohxaN0.js';
32
- import { c as convertTasksToEvents } from './typechecker.C2IpOhid.js';
31
+ import { R as RandomSequencer, i as isPackageExists, h as hash, V as VitestCache, g as getFilePoolName, d as isBrowserEnabled, m as mm, r as resolveConfig, e as groupBy, f as getCoverageProvider, j as createPool, w as wildcardPatternToRegExp, a as resolveApiServerConfig, s as stdout } from './coverage.SfnlalVs.js';
32
+ import { c as convertTasksToEvents } from './typechecker.CG0zmr19.js';
33
33
  import { Console } from 'node:console';
34
34
  import c from 'tinyrainbow';
35
- import { a as formatProjectName, w as withLabel, d as divider } from './utils.OLmtDstN.js';
35
+ import { c as formatProjectName, w as withLabel, d as divider } from './utils.Lot3J_8U.js';
36
36
  import { createRequire } from 'node:module';
37
37
  import url from 'node:url';
38
38
  import { i as isTTY, a as isWindows } from './env.Dq0hM4Xv.js';
@@ -9755,7 +9755,7 @@ function NormalizeURLPlugin() {
9755
9755
  return;
9756
9756
  }
9757
9757
  const cleanString = stripLiteral(code);
9758
- const assetImportMetaUrlRE = /\bnew\s+URL\s*\(\s*(?:'[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*(?:,\s*)?\)/g;
9758
+ const assetImportMetaUrlRE = /\bnew\s+URL\s*\(\s*(?:'[^']+'|"[^"]+"|`[^`]+`)\s*,\s*(?:'' \+ )?import\.meta\.url\s*(?:,\s*)?\)/g;
9759
9759
  let updatedCode = code;
9760
9760
  let match;
9761
9761
  while (match = assetImportMetaUrlRE.exec(cleanString)) {
@@ -10464,6 +10464,7 @@ class TestProject {
10464
10464
  return testFiles;
10465
10465
  }
10466
10466
  _parentBrowser;
10467
+ /** @internal */
10467
10468
  _parent;
10468
10469
  /** @internal */
10469
10470
  _initParentBrowser = deduped(async () => {
@@ -10473,7 +10474,7 @@ class TestProject {
10473
10474
  await this.vitest.packageInstaller.ensureInstalled("@vitest/browser", this.config.root, this.vitest.version);
10474
10475
  const { createBrowserServer, distRoot } = await import('@vitest/browser');
10475
10476
  const browser = await createBrowserServer(this, this.vite.config.configFile, [...MocksPlugins({ filter(id) {
10476
- if (id.includes(distRoot)) {
10477
+ if (id.includes(distRoot) || id.includes(browser.vite.config.cacheDir)) {
10477
10478
  return false;
10478
10479
  }
10479
10480
  return true;
@@ -10621,6 +10622,7 @@ async function initializeProject(workspacePath, ctx, options) {
10621
10622
  const config = {
10622
10623
  ...restOptions,
10623
10624
  configFile,
10625
+ configLoader: ctx.vite.config.inlineConfig.configLoader,
10624
10626
  mode: options.test?.mode || options.mode || ctx.config.mode,
10625
10627
  plugins: [...options.plugins || [], WorkspaceVitestPlugin(project, {
10626
10628
  ...options,
@@ -10885,6 +10887,12 @@ class ReportedTaskImplementation {
10885
10887
  return !result || result.state !== "fail";
10886
10888
  }
10887
10889
  /**
10890
+ * Custom metadata that was attached to the test during its execution.
10891
+ */
10892
+ meta() {
10893
+ return this.task.meta;
10894
+ }
10895
+ /**
10888
10896
  * Creates a new reported task instance and stores it in the project's state for future use.
10889
10897
  * @internal
10890
10898
  */
@@ -10982,12 +10990,6 @@ class TestCase extends ReportedTaskImplementation {
10982
10990
  };
10983
10991
  }
10984
10992
  /**
10985
- * Custom metadata that was attached to the test during its execution.
10986
- */
10987
- meta() {
10988
- return this.task.meta;
10989
- }
10990
- /**
10991
10993
  * Useful information about the test like duration, memory usage, etc.
10992
10994
  * Diagnostic is only available after the test has finished.
10993
10995
  */
@@ -11201,12 +11203,14 @@ class TestModule extends SuiteImplementation {
11201
11203
  const prepareDuration = this.task.prepareDuration || 0;
11202
11204
  const environmentSetupDuration = this.task.environmentLoad || 0;
11203
11205
  const duration = this.task.result?.duration || 0;
11206
+ const heap = this.task.result?.heap;
11204
11207
  return {
11205
11208
  environmentSetupDuration,
11206
11209
  prepareDuration,
11207
11210
  collectDuration,
11208
11211
  setupDuration,
11209
- duration
11212
+ duration,
11213
+ heap
11210
11214
  };
11211
11215
  }
11212
11216
  }
@@ -11478,14 +11482,6 @@ class TestRun {
11478
11482
  assert$1(entity.type === "suite" || entity.type === "module", "Entity type must be suite or module");
11479
11483
  if (entity.state() === "skipped") {
11480
11484
  await this.reportChildren(entity.children);
11481
- } else {
11482
- for (const test of entity.children.tests("skipped")) {
11483
- if (test.task.result?.pending) {
11484
- continue;
11485
- }
11486
- await this.vitest.report("onTestCaseReady", test);
11487
- await this.vitest.report("onTestCaseResult", test);
11488
- }
11489
11485
  }
11490
11486
  if (entity.type === "module") {
11491
11487
  await this.vitest.report("onTestModuleEnd", entity);
@@ -12336,20 +12332,7 @@ class Vitest {
12336
12332
  await this.report("onSpecsCollected", specifications.map((spec) => spec.toJSON()));
12337
12333
  await this._testRun.start(specifications).catch(noop);
12338
12334
  for (const file of files) {
12339
- const project = this.getProjectByName(file.projectName || "");
12340
- await this._testRun.enqueued(project, file).catch(noop);
12341
- await this._testRun.collected(project, [file]).catch(noop);
12342
- const logs = [];
12343
- const { packs, events } = convertTasksToEvents(file, (task) => {
12344
- if (task.logs) {
12345
- logs.push(...task.logs);
12346
- }
12347
- });
12348
- logs.sort((log1, log2) => log1.time - log2.time);
12349
- for (const log of logs) {
12350
- await this._testRun.log(log).catch(noop);
12351
- }
12352
- await this._testRun.updated(packs, events).catch(noop);
12335
+ await this._reportFileTask(file);
12353
12336
  }
12354
12337
  if (hasFailed(files)) {
12355
12338
  process.exitCode = 1;
@@ -12363,6 +12346,23 @@ class Vitest {
12363
12346
  unhandledErrors: this.state.getUnhandledErrors()
12364
12347
  };
12365
12348
  }
12349
+ /** @internal */
12350
+ async _reportFileTask(file) {
12351
+ const project = this.getProjectByName(file.projectName || "");
12352
+ await this._testRun.enqueued(project, file).catch(noop);
12353
+ await this._testRun.collected(project, [file]).catch(noop);
12354
+ const logs = [];
12355
+ const { packs, events } = convertTasksToEvents(file, (task) => {
12356
+ if (task.logs) {
12357
+ logs.push(...task.logs);
12358
+ }
12359
+ });
12360
+ logs.sort((log1, log2) => log1.time - log2.time);
12361
+ for (const log of logs) {
12362
+ await this._testRun.log(log).catch(noop);
12363
+ }
12364
+ await this._testRun.updated(packs, events).catch(noop);
12365
+ }
12366
12366
  async collect(filters) {
12367
12367
  const files = await this.specifications.getRelevantTestSpecifications(filters);
12368
12368
  if (!files.length) {
@@ -12621,7 +12621,8 @@ class Vitest {
12621
12621
  if (!task) {
12622
12622
  throw new Error(`Task ${id} was not found`);
12623
12623
  }
12624
- await this.changeNamePattern(task.name, [task.file.filepath], "tasks" in task ? "rerun suite" : "rerun test");
12624
+ const taskNamePattern = task.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
12625
+ await this.changeNamePattern(taskNamePattern, [task.file.filepath], "tasks" in task ? "rerun suite" : "rerun test");
12625
12626
  }
12626
12627
  /** @internal */
12627
12628
  async changeProjectName(pattern) {
@@ -13122,6 +13123,7 @@ async function createVitest(mode, options, viteOverrides = {}, vitestOptions = {
13122
13123
  options.config = configPath;
13123
13124
  const config = {
13124
13125
  configFile: configPath,
13126
+ configLoader: options.configLoader,
13125
13127
  mode: options.mode || mode,
13126
13128
  plugins: await VitestPlugin(options, ctx)
13127
13129
  };
@@ -2,15 +2,15 @@ import fs, { statSync, realpathSync, promises as promises$1, mkdirSync, existsSy
2
2
  import { g as getDefaultExportFromCjs } from './_commonjsHelpers.BFTU3MAI.js';
3
3
  import require$$0 from 'util';
4
4
  import require$$0$1 from 'path';
5
- import { relative, resolve, dirname, isAbsolute, join, normalize } from 'pathe';
5
+ import { relative, resolve, dirname, isAbsolute, join as join$1, normalize } from 'pathe';
6
6
  import c from 'tinyrainbow';
7
7
  import { c as configDefaults, e as benchmarkConfigDefaults, a as coverageConfigDefaults } from './defaults.DmfNPoe5.js';
8
8
  import crypto from 'node:crypto';
9
9
  import { slash, createDefer, shuffle, toArray } from '@vitest/utils';
10
- import { writeFile, rename, stat, unlink } from 'node:fs/promises';
11
10
  import { builtinModules, createRequire } from 'node:module';
12
- import p, { win32, resolve as resolve$1 } from 'node:path';
11
+ import p, { win32, dirname as dirname$1, join, resolve as resolve$1 } from 'node:path';
13
12
  import process$1 from 'node:process';
13
+ import fsPromises, { writeFile, rename, stat, unlink } from 'node:fs/promises';
14
14
  import { fileURLToPath as fileURLToPath$1, pathToFileURL as pathToFileURL$1, URL as URL$1 } from 'node:url';
15
15
  import assert from 'node:assert';
16
16
  import v8 from 'node:v8';
@@ -24,7 +24,7 @@ import { version } from 'vite';
24
24
  import EventEmitter from 'node:events';
25
25
  import { c as createBirpc } from './index.68735LiX.js';
26
26
  import Tinypool$1, { Tinypool } from 'tinypool';
27
- import { w as wrapSerializableConfig, a as Typechecker } from './typechecker.C2IpOhid.js';
27
+ import { w as wrapSerializableConfig, a as Typechecker } from './typechecker.CG0zmr19.js';
28
28
  import { MessageChannel } from 'node:worker_threads';
29
29
  import { hasFailed } from '@vitest/runner/utils';
30
30
  import { rootDir } from '../path.js';
@@ -2257,6 +2257,156 @@ function resolvePathSync(id, options) {
2257
2257
  return fileURLToPath(resolveSync(id, options));
2258
2258
  }
2259
2259
 
2260
+ const GET_IS_ASYNC = Symbol.for("quansync.getIsAsync");
2261
+ class QuansyncError extends Error {
2262
+ constructor(message = "Unexpected promise in sync context") {
2263
+ super(message);
2264
+ this.name = "QuansyncError";
2265
+ }
2266
+ }
2267
+ function isThenable(value) {
2268
+ return value && typeof value === "object" && typeof value.then === "function";
2269
+ }
2270
+ function isQuansyncGenerator(value) {
2271
+ return value && typeof value === "object" && typeof value[Symbol.iterator] === "function" && "__quansync" in value;
2272
+ }
2273
+ function fromObject(options) {
2274
+ const generator = function* (...args) {
2275
+ const isAsync = yield GET_IS_ASYNC;
2276
+ if (isAsync)
2277
+ return yield options.async.apply(this, args);
2278
+ return options.sync.apply(this, args);
2279
+ };
2280
+ function fn(...args) {
2281
+ const iter = generator.apply(this, args);
2282
+ iter.then = (...thenArgs) => options.async.apply(this, args).then(...thenArgs);
2283
+ iter.__quansync = true;
2284
+ return iter;
2285
+ }
2286
+ fn.sync = options.sync;
2287
+ fn.async = options.async;
2288
+ return fn;
2289
+ }
2290
+ function fromPromise(promise) {
2291
+ return fromObject({
2292
+ async: () => Promise.resolve(promise),
2293
+ sync: () => {
2294
+ if (isThenable(promise))
2295
+ throw new QuansyncError();
2296
+ return promise;
2297
+ }
2298
+ });
2299
+ }
2300
+ function unwrapYield(value, isAsync) {
2301
+ if (value === GET_IS_ASYNC)
2302
+ return isAsync;
2303
+ if (isQuansyncGenerator(value))
2304
+ return isAsync ? iterateAsync(value) : iterateSync(value);
2305
+ if (!isAsync && isThenable(value))
2306
+ throw new QuansyncError();
2307
+ return value;
2308
+ }
2309
+ function iterateSync(generator) {
2310
+ let current = generator.next();
2311
+ while (!current.done) {
2312
+ try {
2313
+ current = generator.next(unwrapYield(current.value));
2314
+ } catch (err) {
2315
+ current = generator.throw(err);
2316
+ }
2317
+ }
2318
+ return unwrapYield(current.value);
2319
+ }
2320
+ async function iterateAsync(generator) {
2321
+ let current = generator.next();
2322
+ while (!current.done) {
2323
+ try {
2324
+ current = generator.next(await unwrapYield(current.value, true));
2325
+ } catch (err) {
2326
+ current = generator.throw(err);
2327
+ }
2328
+ }
2329
+ return current.value;
2330
+ }
2331
+ function fromGeneratorFn(generatorFn) {
2332
+ return fromObject({
2333
+ name: generatorFn.name,
2334
+ async(...args) {
2335
+ return iterateAsync(generatorFn.apply(this, args));
2336
+ },
2337
+ sync(...args) {
2338
+ return iterateSync(generatorFn.apply(this, args));
2339
+ }
2340
+ });
2341
+ }
2342
+ function quansync$1(options) {
2343
+ if (isThenable(options))
2344
+ return fromPromise(options);
2345
+ if (typeof options === "function")
2346
+ return fromGeneratorFn(options);
2347
+ else
2348
+ return fromObject(options);
2349
+ }
2350
+
2351
+ const quansync = quansync$1;
2352
+
2353
+ const toPath = urlOrPath => urlOrPath instanceof URL ? fileURLToPath$1(urlOrPath) : urlOrPath;
2354
+
2355
+ async function findUp$1(name, {
2356
+ cwd = process$1.cwd(),
2357
+ type = 'file',
2358
+ stopAt,
2359
+ } = {}) {
2360
+ let directory = p.resolve(toPath(cwd) ?? '');
2361
+ const {root} = p.parse(directory);
2362
+ stopAt = p.resolve(directory, toPath(stopAt ?? root));
2363
+ const isAbsoluteName = p.isAbsolute(name);
2364
+
2365
+ while (directory) {
2366
+ const filePath = isAbsoluteName ? name : p.join(directory, name);
2367
+ try {
2368
+ const stats = await fsPromises.stat(filePath); // eslint-disable-line no-await-in-loop
2369
+ if ((type === 'file' && stats.isFile()) || (type === 'directory' && stats.isDirectory())) {
2370
+ return filePath;
2371
+ }
2372
+ } catch {}
2373
+
2374
+ if (directory === stopAt || directory === root) {
2375
+ break;
2376
+ }
2377
+
2378
+ directory = p.dirname(directory);
2379
+ }
2380
+ }
2381
+
2382
+ function findUpSync(name, {
2383
+ cwd = process$1.cwd(),
2384
+ type = 'file',
2385
+ stopAt,
2386
+ } = {}) {
2387
+ let directory = p.resolve(toPath(cwd) ?? '');
2388
+ const {root} = p.parse(directory);
2389
+ stopAt = p.resolve(directory, toPath(stopAt) ?? root);
2390
+ const isAbsoluteName = p.isAbsolute(name);
2391
+
2392
+ while (directory) {
2393
+ const filePath = isAbsoluteName ? name : p.join(directory, name);
2394
+
2395
+ try {
2396
+ const stats = fs.statSync(filePath, {throwIfNoEntry: false});
2397
+ if ((type === 'file' && stats?.isFile()) || (type === 'directory' && stats?.isDirectory())) {
2398
+ return filePath;
2399
+ }
2400
+ } catch {}
2401
+
2402
+ if (directory === stopAt || directory === root) {
2403
+ break;
2404
+ }
2405
+
2406
+ directory = p.dirname(directory);
2407
+ }
2408
+ }
2409
+
2260
2410
  function _resolve(path, options = {}) {
2261
2411
  if (options.platform === "auto" || !options.platform)
2262
2412
  options.platform = process$1.platform === "win32" ? "win32" : "posix";
@@ -2281,12 +2431,36 @@ function resolveModule(name, options = {}) {
2281
2431
  try {
2282
2432
  return _resolve(name, options);
2283
2433
  } catch {
2284
- return undefined;
2434
+ return void 0;
2285
2435
  }
2286
2436
  }
2287
2437
  function isPackageExists(name, options = {}) {
2288
2438
  return !!resolvePackage(name, options);
2289
2439
  }
2440
+ function getPackageJsonPath(name, options = {}) {
2441
+ const entry = resolvePackage(name, options);
2442
+ if (!entry)
2443
+ return;
2444
+ return searchPackageJSON(entry);
2445
+ }
2446
+ const readFile = quansync({
2447
+ async: (id) => fs.promises.readFile(id, "utf8"),
2448
+ sync: (id) => fs.readFileSync(id, "utf8")
2449
+ });
2450
+ const getPackageInfo = quansync(function* (name, options = {}) {
2451
+ const packageJsonPath = getPackageJsonPath(name, options);
2452
+ if (!packageJsonPath)
2453
+ return;
2454
+ const packageJson = JSON.parse(yield readFile(packageJsonPath));
2455
+ return {
2456
+ name,
2457
+ version: packageJson.version,
2458
+ rootPath: dirname$1(packageJsonPath),
2459
+ packageJsonPath,
2460
+ packageJson
2461
+ };
2462
+ });
2463
+ getPackageInfo.sync;
2290
2464
  function resolvePackage(name, options = {}) {
2291
2465
  try {
2292
2466
  return _resolve(`${name}/package.json`, options);
@@ -2300,6 +2474,37 @@ function resolvePackage(name, options = {}) {
2300
2474
  return false;
2301
2475
  }
2302
2476
  }
2477
+ function searchPackageJSON(dir) {
2478
+ let packageJsonPath;
2479
+ while (true) {
2480
+ if (!dir)
2481
+ return;
2482
+ const newDir = dirname$1(dir);
2483
+ if (newDir === dir)
2484
+ return;
2485
+ dir = newDir;
2486
+ packageJsonPath = join(dir, "package.json");
2487
+ if (fs.existsSync(packageJsonPath))
2488
+ break;
2489
+ }
2490
+ return packageJsonPath;
2491
+ }
2492
+ const findUp = quansync({
2493
+ sync: findUpSync,
2494
+ async: findUp$1
2495
+ });
2496
+ const loadPackageJSON = quansync(function* (cwd = process$1.cwd()) {
2497
+ const path = yield findUp("package.json", { cwd });
2498
+ if (!path || !fs.existsSync(path))
2499
+ return null;
2500
+ return JSON.parse(yield readFile(path));
2501
+ });
2502
+ loadPackageJSON.sync;
2503
+ const isPackageListed = quansync(function* (name, cwd) {
2504
+ const pkg = (yield loadPackageJSON(cwd)) || {};
2505
+ return name in (pkg.dependencies || {}) || name in (pkg.devDependencies || {});
2506
+ });
2507
+ isPackageListed.sync;
2303
2508
 
2304
2509
  function getWorkersCountByPercentage(percent) {
2305
2510
  const maxWorkersCount = nodeos__default.availableParallelism?.() ?? nodeos__default.cpus().length;
@@ -6520,9 +6725,9 @@ function createMethodsRPC(project, options = {}) {
6520
6725
  if (code == null) {
6521
6726
  throw new Error(`Failed to fetch module ${id}`);
6522
6727
  }
6523
- const dir = join(project.tmpDir, transformMode);
6728
+ const dir = join$1(project.tmpDir, transformMode);
6524
6729
  const name = hash("sha1", id, "hex");
6525
- const tmp = join(dir, name);
6730
+ const tmp = join$1(dir, name);
6526
6731
  if (!created.has(dir)) {
6527
6732
  mkdirSync(dir, { recursive: true });
6528
6733
  created.add(dir);
@@ -6617,7 +6822,7 @@ function handleRollupError(e) {
6617
6822
  */
6618
6823
  async function atomicWriteFile(realFilePath, data) {
6619
6824
  const dir = dirname(realFilePath);
6620
- const tmpFilePath = join(dir, `.tmp-${Date.now()}-${Math.random().toString(36).slice(2)}`);
6825
+ const tmpFilePath = join$1(dir, `.tmp-${Date.now()}-${Math.random().toString(36).slice(2)}`);
6621
6826
  try {
6622
6827
  await writeFile(tmpFilePath, data, "utf-8");
6623
6828
  await rename(tmpFilePath, realFilePath);
@@ -141,6 +141,61 @@ test('renders name', async () => {
141
141
  })
142
142
  `
143
143
  };
144
+ const litExample = {
145
+ name: "HelloWorld.js",
146
+ js: `
147
+ import { html, LitElement } from 'lit'
148
+
149
+ export class HelloWorld extends LitElement {
150
+ static properties = {
151
+ name: { type: String },
152
+ }
153
+
154
+ constructor() {
155
+ super()
156
+ this.name = 'World'
157
+ }
158
+
159
+ render() {
160
+ return html\`<h1>Hello \${this.name}!</h1>\`
161
+ }
162
+ }
163
+
164
+ customElements.define('hello-world', HelloWorld)
165
+ `,
166
+ ts: `
167
+ import { html, LitElement } from 'lit'
168
+ import { customElement, property } from 'lit/decorators.js'
169
+
170
+ @customElement('hello-world')
171
+ export class HelloWorld extends LitElement {
172
+ @property({ type: String })
173
+ name = 'World'
174
+
175
+ render() {
176
+ return html\`<h1>Hello \${this.name}!</h1>\`
177
+ }
178
+ }
179
+
180
+ declare global {
181
+ interface HTMLElementTagNameMap {
182
+ 'hello-world': HelloWorld
183
+ }
184
+ }
185
+ `,
186
+ test: `
187
+ import { expect, test } from 'vitest'
188
+ import { render } from 'vitest-browser-lit'
189
+ import { html } from 'lit'
190
+ import './HelloWorld.js'
191
+
192
+ test('renders name', async () => {
193
+ const screen = render(html\`<hello-world name="Vitest"></hello-world>\`)
194
+ const element = screen.getByText('Hello Vitest!')
195
+ await expect.element(element).toBeInTheDocument()
196
+ })
197
+ `
198
+ };
144
199
  const vanillaExample = {
145
200
  name: "HelloWorld.js",
146
201
  js: `
@@ -192,6 +247,7 @@ function getExampleTest(framework) {
192
247
  };
193
248
  case "vue": return vueExample;
194
249
  case "svelte": return svelteExample;
250
+ case "lit": return litExample;
195
251
  case "marko": return markoExample;
196
252
  default: return vanillaExample;
197
253
  }
@@ -291,6 +347,11 @@ function getFramework() {
291
347
  value: "react",
292
348
  description: "\"The library for web and native user interfaces\""
293
349
  },
350
+ {
351
+ title: "lit",
352
+ value: "lit",
353
+ description: "\"A simple library for building fast, lightweight web components.\""
354
+ },
294
355
  {
295
356
  title: "preact",
296
357
  value: "preact",
@@ -314,6 +375,7 @@ function getFrameworkTestPackage(framework) {
314
375
  case "vue": return "vitest-browser-vue";
315
376
  case "svelte": return "vitest-browser-svelte";
316
377
  case "react": return "vitest-browser-react";
378
+ case "lit": return "vitest-browser-lit";
317
379
  case "preact": return "@testing-library/preact";
318
380
  case "solid": return "@solidjs/testing-library";
319
381
  case "marko": return "@marko/testing-library";
@@ -389,6 +451,9 @@ function getPossibleFramework(dependencies) {
389
451
  if (dependencies.svelte || dependencies["@sveltejs/kit"]) {
390
452
  return "svelte";
391
453
  }
454
+ if (dependencies.lit || dependencies["lit-html"]) {
455
+ return "lit";
456
+ }
392
457
  if (dependencies.preact) {
393
458
  return "preact";
394
459
  }