@d1g1tal/tsbuild 1.8.3 → 1.8.4

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ ## [1.8.4](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.8.3...v1.8.4) (2026-04-12)
2
+
3
+ ### Performance Improvements
4
+
5
+ * **build:** delegate file writing to esbuild (84a64e212a9dc7f309bb2dcbe74ffa990c06065b)
6
+ - Enables esbuild write option for direct-to-disk transpilation output
7
+ - Moves relative module specifier rewriting logic to FileManager
8
+ - Simplifies output plugin to only manage shebang executable permissions via chmod
9
+ - Adapts IIFE plugin to process metafile outputs instead of in-memory files
10
+ - Updates tests and mock helpers to align with file writing capabilities
11
+
12
+ * **dts:** optimize declaration bundler module resolution and graph traversal (59606c0ccfe54ac74068fe6ab8f6d26d7edd97b6)
13
+ - Optimizes module pattern matching by using Sets and RegEx arrays instead of iteration
14
+ - Refactors bundled specifiers state to use ReadonlySet for O(1) lookups
15
+ - Simplifies deduplication of non-mergeable imports using Sets
16
+ - Yields the event loop before cpu-intensive declaration bundling to prevent I/O blocking
17
+
18
+
19
+ ### Miscellaneous Chores
20
+
21
+ * **perf:** add performance baseline documentation and benchmark script (3e897aaa7a35022b8d9ec1d4222448973eb57a2b)
22
+ - Adds documentation detailing performance baselines and architectures
23
+ - Introduces performance measurements log
24
+ - Adds quick reference for performance monitoring
25
+ - Introduces new benchmark script for running automated metrics collection
26
+ - Registers bench script in package.json
27
+
1
28
  ## [1.8.3](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.8.2...v1.8.3) (2026-04-11)
2
29
 
3
30
  ### Performance Improvements
@@ -148,13 +148,13 @@ var isColorSupported = !("NO_COLOR" in env) && ("FORCE_COLOR" in env || platform
148
148
  var replaceClose = (index, string, close, replace, head = string.substring(0, index) + replace, tail = string.substring(index + close.length), next = tail.indexOf(close)) => {
149
149
  return head + (next < 0 ? tail : replaceClose(next, tail, close, replace));
150
150
  };
151
- var clearBleed = (index, string, open, close, replace) => {
152
- return index < 0 ? `${open}${string}${close}` : `${open}${replaceClose(index, string, close, replace)}${close}`;
151
+ var clearBleed = (index, string, open2, close, replace) => {
152
+ return index < 0 ? `${open2}${string}${close}` : `${open2}${replaceClose(index, string, close, replace)}${close}`;
153
153
  };
154
- var filterEmpty = (open, close, replace = open, at = open.length + 1) => {
155
- return (text) => text.length ? clearBleed(text.indexOf(close, at), text, open, close, replace) : "";
154
+ var filterEmpty = (open2, close, replace = open2, at = open2.length + 1) => {
155
+ return (text) => text.length ? clearBleed(text.indexOf(close, at), text, open2, close, replace) : "";
156
156
  };
157
- var generateTextFormatter = (open, close, replace) => filterEmpty(`\x1B[${open}m`, `\x1B[${close}m`, replace);
157
+ var generateTextFormatter = (open2, close, replace) => filterEmpty(`\x1B[${open2}m`, `\x1B[${close}m`, replace);
158
158
  var TextFormat = class {
159
159
  static enabled = isColorSupported;
160
160
  static reset = generateTextFormatter(0, 0);
@@ -817,36 +817,40 @@ import {
817
817
  forEachChild as forEachChild2
818
818
  } from "typescript";
819
819
  var nodeModules = "/node_modules/";
820
+ var emptySet = /* @__PURE__ */ new Set();
820
821
  var importPattern = /^import\s*(?:type\s*)?\{\s*([^}]+)\s*\}\s*from\s*['"]([^'"]+)['"]\s*;?\s*$/;
821
822
  var typePrefixPattern = /^type:/;
822
823
  function mergeImports(imports) {
823
824
  const moduleImports = /* @__PURE__ */ new Map();
824
- const nonMergeableImports = [];
825
+ const nonMergeableImports = /* @__PURE__ */ new Set();
825
826
  for (const importStatement of imports) {
826
827
  const match = importPattern.exec(importStatement);
827
828
  if (match) {
828
829
  const [, namesString, moduleSpecifier] = match;
829
830
  const isType = importStatement.includes("import type");
830
831
  const key = `${isType ? "type:" : ""}${moduleSpecifier}`;
831
- if (!moduleImports.has(key)) {
832
- moduleImports.set(key, { names: /* @__PURE__ */ new Set(), isType });
832
+ let entry = moduleImports.get(key);
833
+ if (entry === void 0) {
834
+ entry = { names: /* @__PURE__ */ new Set(), isType };
835
+ moduleImports.set(key, entry);
833
836
  }
834
- const entry = moduleImports.get(key);
835
837
  for (const name of namesString.split(",")) {
836
838
  entry.names.add(name.trim());
837
839
  }
838
840
  } else {
839
- nonMergeableImports.push(importStatement);
841
+ nonMergeableImports.add(importStatement);
840
842
  }
841
843
  }
842
844
  const result = [];
843
845
  for (const [key, { names, isType }] of moduleImports) {
844
846
  result.push(`${isType ? "import type" : "import"} { ${[...names].sort().join(", ")} } from "${key.replace(typePrefixPattern, "")}";`);
845
847
  }
846
- result.push(...[...new Set(nonMergeableImports)]);
848
+ for (const imp of nonMergeableImports) {
849
+ result.push(imp);
850
+ }
847
851
  return result;
848
852
  }
849
- var DeclarationBundler = class {
853
+ var DeclarationBundler = class _DeclarationBundler {
850
854
  /** Project declaration files from in-memory FileManager */
851
855
  declarationFiles = /* @__PURE__ */ new Map();
852
856
  /** External declaration files resolved from disk (node_modules) when resolve is enabled */
@@ -859,6 +863,10 @@ var DeclarationBundler = class {
859
863
  moduleResolutionCache = /* @__PURE__ */ new Map();
860
864
  /** Pre-computed set of directory prefixes from declaration file paths for O(1) directoryExists lookups */
861
865
  declarationDirs = /* @__PURE__ */ new Set();
866
+ /** Pre-built matcher for external patterns — O(1) string lookups + cached regex tests */
867
+ matchExternal;
868
+ /** Pre-built matcher for noExternal patterns — O(1) string lookups + cached regex tests */
869
+ matchNoExternal;
862
870
  // Create a proper module resolution host that supports both in-memory files and disk files
863
871
  moduleResolutionHost = {
864
872
  fileExists: (fileName) => {
@@ -908,6 +916,8 @@ var DeclarationBundler = class {
908
916
  }
909
917
  }
910
918
  this.options = dtsBundleOptions;
919
+ this.matchExternal = _DeclarationBundler.buildMatcher(dtsBundleOptions.external);
920
+ this.matchNoExternal = _DeclarationBundler.buildMatcher(dtsBundleOptions.noExternal);
911
921
  }
912
922
  /**
913
923
  * Clears external declaration files and module resolution cache to free memory.
@@ -960,23 +970,42 @@ var DeclarationBundler = class {
960
970
  return imports;
961
971
  }
962
972
  /**
963
- * Check if a module specifier matches a pattern list
964
- * @param moduleSpecifier - The module specifier to check
965
- * @param patterns - Array of patterns to match against
966
- * @returns True if the module matches any pattern
967
- */
968
- matchesPattern(moduleSpecifier, patterns) {
969
- return patterns.some((pattern) => {
970
- return typeof pattern === "string" ? moduleSpecifier === pattern || moduleSpecifier.startsWith(`${pattern}/`) : pattern.test(moduleSpecifier);
971
- });
972
- }
973
- /**
974
- * Check if a module specifier matches explicit external patterns
975
- * @param moduleSpecifier - The module specifier to check
976
- * @returns True if the module should be treated as external
973
+ * Builds an O(1) matcher from a mixed Pattern array by splitting into a Set<string> for
974
+ * exact/sub-path checks and a RegExp[] for regex tests. Called once per bundler instance.
975
+ * @param patterns - The array of string and RegExp patterns to match against module specifiers
976
+ * @returns A function that takes a module specifier and returns true if it matches any of the patterns
977
977
  */
978
- isExternal(moduleSpecifier) {
979
- return this.matchesPattern(moduleSpecifier, this.options.external);
978
+ static buildMatcher(patterns) {
979
+ const exact = /* @__PURE__ */ new Set();
980
+ const prefixes = [];
981
+ const regexps = [];
982
+ for (const p of patterns) {
983
+ if (typeof p === "string") {
984
+ exact.add(p);
985
+ prefixes.push(p + "/");
986
+ } else {
987
+ regexps.push(p);
988
+ }
989
+ }
990
+ if (exact.size === 0 && regexps.length === 0) {
991
+ return () => false;
992
+ }
993
+ return (id) => {
994
+ if (exact.has(id)) {
995
+ return true;
996
+ }
997
+ for (let i = 0; i < prefixes.length; i++) {
998
+ if (id.startsWith(prefixes[i])) {
999
+ return true;
1000
+ }
1001
+ }
1002
+ for (let i = 0; i < regexps.length; i++) {
1003
+ if (regexps[i].test(id)) {
1004
+ return true;
1005
+ }
1006
+ }
1007
+ return false;
1008
+ };
980
1009
  }
981
1010
  /**
982
1011
  * Resolve a module import using TypeScript's resolution algorithm with path mapping support
@@ -1024,18 +1053,18 @@ var DeclarationBundler = class {
1024
1053
  const sourceFile = createSourceFile(path, code, ScriptTarget.Latest, true);
1025
1054
  const identifiers = this.collectIdentifiers(sourceFile.statements, sourceFile);
1026
1055
  const module = { path, code, imports: /* @__PURE__ */ new Set(), typeReferences: new Set(typeReferences), fileReferences: new Set(fileReferences), sourceFile, identifiers };
1027
- const bundledSpecs = [];
1056
+ const bundledSpecs = /* @__PURE__ */ new Set();
1028
1057
  for (const specifier of this.extractImports(sourceFile)) {
1029
- if (this.isExternal(specifier)) {
1058
+ if (this.matchExternal(specifier)) {
1030
1059
  continue;
1031
1060
  }
1032
1061
  const resolvedPath = this.resolveModule(specifier, path);
1033
- if (resolvedPath?.includes(nodeModules) && !this.matchesPattern(specifier, this.options.noExternal)) {
1062
+ if (resolvedPath?.includes(nodeModules) && !this.matchNoExternal(specifier)) {
1034
1063
  continue;
1035
1064
  }
1036
1065
  if (resolvedPath && (this.declarationFiles.has(resolvedPath) || this.externalDeclarationFiles.has(resolvedPath))) {
1037
1066
  module.imports.add(resolvedPath);
1038
- bundledSpecs.push(specifier);
1067
+ bundledSpecs.add(specifier);
1039
1068
  visit(resolvedPath);
1040
1069
  }
1041
1070
  }
@@ -1146,7 +1175,7 @@ var DeclarationBundler = class {
1146
1175
  * @param code - Declaration file content
1147
1176
  * @param sourceFile - Parsed source file AST (required to avoid re-parsing)
1148
1177
  * @param identifiers - Pre-computed type and value identifiers (to avoid re-computation)
1149
- * @param bundledImportPaths - Array of resolved file paths that were bundled (to exclude from external imports)
1178
+ * @param bundledImportPaths - Set of resolved file paths that were bundled (to exclude from external imports)
1150
1179
  * @param renameMap - Map of renamed identifiers (name:path -> newName)
1151
1180
  * @param modulePath - Path of current module for looking up renames
1152
1181
  * @returns Object with processed code, collected external imports, and exported names (separated by type/value)
@@ -1169,7 +1198,7 @@ var DeclarationBundler = class {
1169
1198
  for (const statement of sourceFile.statements) {
1170
1199
  if (isImportDeclaration2(statement)) {
1171
1200
  const moduleSpecifier = statement.moduleSpecifier.text;
1172
- if (this.isExternal(moduleSpecifier) || !bundledImportPaths.includes(moduleSpecifier)) {
1201
+ if (this.matchExternal(moduleSpecifier) || !bundledImportPaths.has(moduleSpecifier)) {
1173
1202
  externalImports.push(code.substring(statement.pos, statement.end).trim());
1174
1203
  } else if (statement.importClause?.namedBindings && isNamespaceImport(statement.importClause.namedBindings)) {
1175
1204
  bundledNamespaceAliases.add(statement.importClause.namedBindings.name.text);
@@ -1262,7 +1291,9 @@ var DeclarationBundler = class {
1262
1291
  for (const [name, sourcesSet] of declarationSources) {
1263
1292
  if (sourcesSet.size > 1) {
1264
1293
  let suffix = 1;
1265
- for (const modulePath of Array.from(sourcesSet).slice(1)) {
1294
+ const modulePaths = sourcesSet.values();
1295
+ modulePaths.next();
1296
+ for (const modulePath of modulePaths) {
1266
1297
  let candidate = `${name}$${suffix}`;
1267
1298
  while (declarationSources.has(candidate)) {
1268
1299
  candidate = `${name}$${++suffix}`;
@@ -1275,7 +1306,7 @@ var DeclarationBundler = class {
1275
1306
  for (const { path, typeReferences, fileReferences, sourceFile, code, identifiers } of sortedModules) {
1276
1307
  allTypeReferences.push(...typeReferences);
1277
1308
  allFileReferences.push(...fileReferences);
1278
- const bundledForThisModule = bundledSpecifiers.get(path) || [];
1309
+ const bundledForThisModule = bundledSpecifiers.get(path) ?? emptySet;
1279
1310
  const { code: strippedCode, externalImports, typeExports, valueExports } = this.stripImportsExports(code, sourceFile, identifiers, bundledForThisModule, renameMap, path);
1280
1311
  allExternalImports.push(...externalImports);
1281
1312
  if (!path.includes(nodeModules)) {
@@ -1372,11 +1403,12 @@ async function bundleDeclarations(options) {
1372
1403
  await mkdir2(options.compilerOptions.outDir, defaultDirOptions);
1373
1404
  }
1374
1405
  const dtsBundler = new DeclarationBundler(options);
1406
+ await new Promise((resolve3) => void setImmediate(resolve3));
1375
1407
  const bundleTasks = [];
1376
1408
  for (const [entryName, entryPoint] of Object.entries(options.entryPoints)) {
1377
1409
  const content = dtsBundler.bundle(entryPoint);
1378
1410
  if (content.length > 0) {
1379
- const outPath = Paths.join(options.compilerOptions.outDir, `${entryName}.d.ts`);
1411
+ const outPath = Paths.join(options.compilerOptions.outDir, `${entryName}${FileExtension.DTS}`);
1380
1412
  bundleTasks.push(writeFile2(outPath, content, Encoding.utf8).then(() => ({ path: Paths.relative(options.currentDirectory, outPath), size: content.length })));
1381
1413
  }
1382
1414
  }
@@ -1386,38 +1418,42 @@ async function bundleDeclarations(options) {
1386
1418
  }
1387
1419
 
1388
1420
  // src/plugins/output.ts
1421
+ import { chmod, open } from "node:fs/promises";
1389
1422
  import { extname } from "node:path";
1390
- var textEncoder = new TextEncoder();
1391
- var textDecoder = new TextDecoder();
1392
- var localFileIdentifier = /\.[a-z]+$/i;
1393
- var relativeSpecifierPattern = /(from\s*['"])(\.\.?\/[^'"]*?)(['"])/g;
1394
- var FileMode = { READ_WRITE: 438, READ_WRITE_EXECUTE: 493 };
1395
- function rewriteRelativeSpecifiers(code) {
1396
- return code.replace(relativeSpecifierPattern, (_, before, path, after) => localFileIdentifier.test(path) ? before + path + after : `${before}${path}.js${after}`);
1397
- }
1398
- async function fileMapper({ path, contents }) {
1399
- if (extname(path) !== FileExtension.JS) {
1400
- return Files.write(path, contents, { mode: FileMode.READ_WRITE });
1401
- }
1402
- let rewritten = false;
1403
- const result = textDecoder.decode(contents).replace(relativeSpecifierPattern, (_, before, specPath, after) => {
1404
- if (localFileIdentifier.test(specPath)) {
1405
- return before + specPath + after;
1423
+ async function setShebangPermissions(filePath) {
1424
+ const handle = await open(filePath, "r");
1425
+ try {
1426
+ const buf = Buffer.alloc(2);
1427
+ await handle.read(buf, 0, 2, 0);
1428
+ if (buf[0] === 35 && buf[1] === 33) {
1429
+ await chmod(filePath, 493);
1406
1430
  }
1407
- rewritten = true;
1408
- return `${before}${specPath}.js${after}`;
1409
- });
1410
- return Files.write(path, rewritten ? textEncoder.encode(result) : contents, { mode: contents[0] === 35 && contents[1] === 33 ? FileMode.READ_WRITE_EXECUTE : FileMode.READ_WRITE });
1431
+ } finally {
1432
+ await handle.close();
1433
+ }
1411
1434
  }
1412
1435
  var outputPlugin = () => {
1413
1436
  return {
1414
1437
  name: "esbuild:output-plugin",
1415
1438
  /**
1416
- * Configures the esbuild build instance to write output files to disk
1439
+ * Checks JS entry points for shebangs and sets executable permissions
1417
1440
  * @param build The esbuild build instance
1418
1441
  */
1419
1442
  setup(build) {
1420
- build.onEnd(async ({ outputFiles }) => void await Promise.all(outputFiles.map(fileMapper)));
1443
+ build.onEnd(async ({ metafile }) => {
1444
+ if (!metafile) {
1445
+ return;
1446
+ }
1447
+ const tasks = [];
1448
+ for (const [outputPath, { entryPoint }] of Object.entries(metafile.outputs)) {
1449
+ if (entryPoint && extname(outputPath) === FileExtension.JS) {
1450
+ tasks.push(setShebangPermissions(outputPath));
1451
+ }
1452
+ }
1453
+ if (tasks.length > 0) {
1454
+ await Promise.all(tasks);
1455
+ }
1456
+ });
1421
1457
  }
1422
1458
  };
1423
1459
  };
@@ -1538,9 +1574,9 @@ async function resolvePlugins(plugins, projectDir) {
1538
1574
  }
1539
1575
 
1540
1576
  // src/plugins/iife.ts
1541
- import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
1577
+ import { mkdir as mkdir3, readFile as readFile2, writeFile as writeFile3 } from "node:fs/promises";
1542
1578
  import { basename as basename2, dirname as dirname2, join, resolve as resolve2 } from "node:path";
1543
- var textDecoder2 = new TextDecoder();
1579
+ var textDecoder = new TextDecoder();
1544
1580
  var jsExtension = ".js";
1545
1581
  function iifePlugin(options) {
1546
1582
  const globalName = options?.globalName;
@@ -1560,11 +1596,11 @@ function iifePlugin(options) {
1560
1596
  }
1561
1597
  const sourcemap = build.initialOptions.sourcemap;
1562
1598
  const entryPointNames = extractEntryNames(build.initialOptions.entryPoints);
1563
- build.onEnd(async ({ outputFiles }) => {
1564
- if (!outputFiles?.length || entryPointNames.length === 0) {
1599
+ build.onEnd(async ({ metafile }) => {
1600
+ if (!metafile || entryPointNames.length === 0) {
1565
1601
  return;
1566
1602
  }
1567
- const written = await buildIife(outputFiles, entryPointNames, outdir, globalName, sourcemap);
1603
+ const written = await buildIife(metafile.outputs, entryPointNames, outdir, globalName, sourcemap);
1568
1604
  files.push(...written);
1569
1605
  });
1570
1606
  }
@@ -1620,12 +1656,12 @@ ${body}
1620
1656
  ${assignment}
1621
1657
  })();${after}`;
1622
1658
  }
1623
- async function buildIife(outputFiles, entryPointNames, outdir, globalName, sourcemap) {
1659
+ async function buildIife(outputs, entryPointNames, outdir, globalName, sourcemap) {
1624
1660
  const { build: esbuild } = await import("esbuild");
1625
1661
  const fileContents = /* @__PURE__ */ new Map();
1626
- for (const { path, contents } of outputFiles) {
1627
- if (path.endsWith(jsExtension)) {
1628
- fileContents.set(path, textDecoder2.decode(contents));
1662
+ for (const outputPath of Object.keys(outputs)) {
1663
+ if (outputPath.endsWith(jsExtension)) {
1664
+ fileContents.set(outputPath, await readFile2(outputPath, "utf8"));
1629
1665
  }
1630
1666
  }
1631
1667
  const validEntries = [];
@@ -1661,7 +1697,7 @@ async function buildIife(outputFiles, entryPointNames, outdir, globalName, sourc
1661
1697
  for (const { outputFiles: iifeFiles } of results) {
1662
1698
  for (const { path, contents } of iifeFiles) {
1663
1699
  if (path.endsWith(jsExtension)) {
1664
- const text = wrapAsIife(textDecoder2.decode(contents), globalName);
1700
+ const text = wrapAsIife(textDecoder.decode(contents), globalName);
1665
1701
  writes.push(writeFile3(path, text));
1666
1702
  written.push({ path: Paths.relative(cwd, path), size: Buffer.byteLength(text) });
1667
1703
  } else {
@@ -1941,6 +1977,11 @@ function debounce(wait) {
1941
1977
 
1942
1978
  // src/file-manager.ts
1943
1979
  import { createSourceFile as createSourceFile2, ScriptTarget as ScriptTarget2 } from "typescript";
1980
+ var localFileIdentifier = /\.[a-z]+$/i;
1981
+ var relativeSpecifierPattern = /(from\s*['"])(\.\.?\/[^'"]*?)(['"])/g;
1982
+ function rewriteRelativeSpecifiers(code) {
1983
+ return code.replace(relativeSpecifierPattern, (_, before, path, after) => localFileIdentifier.test(path) ? before + path + after : `${before}${path}.js${after}`);
1984
+ }
1944
1985
  var FileManager = class {
1945
1986
  hasEmittedFiles = false;
1946
1987
  declarationFiles = /* @__PURE__ */ new Map();
@@ -1999,14 +2040,17 @@ var FileManager = class {
1999
2040
  */
2000
2041
  finalize() {
2001
2042
  this.processEmittedFiles();
2002
- const buildInfoWrite = this.pendingBuildInfo ? Files.write(this.pendingBuildInfo.path, this.pendingBuildInfo.text) : void 0;
2043
+ const tasks = [];
2044
+ if (this.pendingBuildInfo) {
2045
+ tasks.push(Files.write(this.pendingBuildInfo.path, this.pendingBuildInfo.text));
2046
+ }
2003
2047
  this.pendingBuildInfo = void 0;
2004
2048
  if (this.cache && this.hasEmittedFiles) {
2005
- this.pendingSave = Promise.all([buildInfoWrite, this.cache.save(this.declarationFiles)]).then(() => {
2006
- });
2007
- } else if (buildInfoWrite) {
2008
- this.pendingSave = buildInfoWrite;
2049
+ tasks.push(this.cache.save(this.declarationFiles));
2009
2050
  }
2051
+ this.pendingSave = Promise.all(tasks).then(() => {
2052
+ }, () => {
2053
+ });
2010
2054
  this.pendingSave?.catch(() => {
2011
2055
  });
2012
2056
  return this.cache === void 0 || this.hasEmittedFiles;
@@ -2038,7 +2082,7 @@ var FileManager = class {
2038
2082
  writeTasks.push(this.writeFile(projectDirectory, filePath, code));
2039
2083
  }
2040
2084
  }
2041
- return (await Promise.all(writeTasks)).filter((result) => result !== void 0);
2085
+ return Promise.all(writeTasks);
2042
2086
  }
2043
2087
  /**
2044
2088
  * Resolves entry points for declaration bundling.
@@ -2383,7 +2427,7 @@ var _TypeScriptProject = class _TypeScriptProject {
2383
2427
  return Files.empty(this.buildConfiguration.outDir);
2384
2428
  }
2385
2429
  async build() {
2386
- Logger.header(`${tsLogo} tsbuild v${"1.8.3"}${this.configuration.compilerOptions.incremental && this.configuration.buildCache?.isValid() ? " [incremental]" : ""}`);
2430
+ Logger.header(`${tsLogo} tsbuild v${"1.8.4"}${this.configuration.compilerOptions.incremental && this.configuration.buildCache?.isValid() ? " [incremental]" : ""}`);
2387
2431
  try {
2388
2432
  const processes = [];
2389
2433
  const filesWereEmitted = await this.typeCheck();
@@ -2486,7 +2530,7 @@ var _TypeScriptProject = class _TypeScriptProject {
2486
2530
  format,
2487
2531
  plugins,
2488
2532
  define,
2489
- write: false,
2533
+ write: true,
2490
2534
  metafile: true,
2491
2535
  treeShaking: true,
2492
2536
  logLevel: "warning",
package/dist/tsbuild.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  BuildError,
4
4
  TypeScriptProject
5
- } from "./UM2SFHAT.js";
5
+ } from "./23A5VAYC.js";
6
6
  import "./JKGYA2AW.js";
7
7
 
8
8
  // src/tsbuild.ts
@@ -30,7 +30,7 @@ if (help) {
30
30
  process.exit(0);
31
31
  }
32
32
  if (version) {
33
- console.log("1.8.3");
33
+ console.log("1.8.4");
34
34
  process.exit(0);
35
35
  }
36
36
  var typeScriptOptions = {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  TypeScriptProject
3
- } from "./UM2SFHAT.js";
3
+ } from "./23A5VAYC.js";
4
4
  import "./JKGYA2AW.js";
5
5
  export {
6
6
  TypeScriptProject
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@d1g1tal/tsbuild",
3
3
  "author": "D1g1talEntr0py",
4
- "version": "1.8.3",
4
+ "version": "1.8.4",
5
5
  "license": "MIT",
6
6
  "description": "A fast, ESM-only TypeScript build tool combining the TypeScript API for type checking and declaration generation, esbuild for bundling, and SWC for decorator metadata.",
7
7
  "homepage": "https://github.com/D1g1talEntr0py/tsbuild#readme",
@@ -81,6 +81,7 @@
81
81
  "scripts": {
82
82
  "build": "tsx ./src/tsbuild.ts",
83
83
  "build:watch": "tsx ./src/tsbuild.ts --watch",
84
+ "bench": "tsx ./scripts/benchmark.ts",
84
85
  "type-check": "tsx ./src/tsbuild.ts --noEmit",
85
86
  "lint": "eslint ./src",
86
87
  "test": "vitest run",