@d1g1tal/tsbuild 1.8.7 → 1.8.9

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,58 @@
1
+ ## [1.8.9](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.8.8...v1.8.9) (2026-05-18)
2
+
3
+ ### Bug Fixes
4
+
5
+ * **diagnostics:** deduplicate type-checking errors (0732f6be4b4cf260d500602411781297b348fb29)
6
+ - Changes diagnostic array type to allow mutability
7
+ - Implements Map-based deduplication for semantic diagnostics
8
+ - Deduplicates errors based on file name, start position, and error code
9
+ - Adds comprehensive unit tests to verify deduplication behavior under various compiler configurations
10
+
11
+
12
+ ### Build System
13
+
14
+ * **config:** enable stricter typescript compiler options (9c51544b3d21df253beb5a31cd5e1559c9982044)
15
+ - Enables noUnusedLocals, noUnusedParameters, and noPropertyAccessFromIndexSignature in tsconfig
16
+ - Changes property access to index signatures for process.env and module default exports
17
+ - Removes unused TypeScript Node import from type definitions
18
+ - Removes unused elapsed performance measurement method from TypeScriptProject
19
+
20
+ ## [1.8.8](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.8.7...v1.8.8) (2026-05-17)
21
+
22
+ ### Bug Fixes
23
+
24
+ * **project:** do not auto-inject node types for non-node platforms (7e23a502d4fda7805fd0fd35081a1b3fdbdda160)
25
+ - Check if the target platform is Node before automatically applying 'node' to the compiler types array
26
+ - Ensure user-specified types arrays are properly respected on browser builds
27
+ - Include assertions and test coverage to verify DOM library types do not implicitly load @types/node
28
+
29
+
30
+ ### Performance Improvements
31
+
32
+ * **loader:** implement deterministic stat caching and stable path hashing (585b055934e61d6d8f6133b9a280658c1afbae57)
33
+ - Add a fast-path to skip caching logic for non-relative bare specifiers
34
+ - Snapshot the cache directory on startup to prevent repeated ENOENT lookups
35
+ - Hash the running Node version and esbuild version into the cache key for robust invalidation
36
+ - Implement a SHA-256 stable path hashing and share `statSync` calls between `resolve` and `load`
37
+
38
+
39
+ ### Code Refactoring
40
+
41
+ * simplify internals in declaration bundler and logger (70b91297a12138a35f45cb759ef65b53adf13b73)
42
+ - Remove redundant files existence check before creating the out directory in bundler
43
+ - Remove unneeded node module imports and process logic in logger
44
+ - Optimize declaration source collection loop in declaration bundler
45
+ - Ensure recursive mkdir handles already-existing folders safely
46
+
47
+
48
+ ### Miscellaneous Chores
49
+
50
+ * update dependencies and rewrite benchmarks with mitata (5ace062e6a5d8fa070493aadb12d4986a55df0c4)
51
+ - Update various dev dependencies including pnpm, vitest, eslint, and typescript-eslint
52
+ - Replace tinybench with mitata for benchmarking
53
+ - Rewrite the benchmark script to compare bundlers and measure artifact metadata
54
+ - Update the generated benchmarking docs with the new mitata measurements
55
+
1
56
  ## [1.8.7](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.8.6...v1.8.7) (2026-05-09)
2
57
 
3
58
  ### Performance Improvements
@@ -169,8 +169,8 @@ var Files = class {
169
169
  // src/text-formatter.ts
170
170
  import { isatty } from "node:tty";
171
171
  var { env = {}, platform = "" } = process;
172
- var isDumbTerminal = env.TERM === "dumb";
173
- var isCompatibleTerminal = isatty(1) && env.TERM && !isDumbTerminal;
172
+ var isDumbTerminal = env["TERM"] === "dumb";
173
+ var isCompatibleTerminal = isatty(1) && env["TERM"] && !isDumbTerminal;
174
174
  var isColorSupported = !("NO_COLOR" in env) && ("FORCE_COLOR" in env || platform === "win32" && !isDumbTerminal || isCompatibleTerminal);
175
175
  var replaceClose = (index, string, close, replace, head = string.substring(0, index) + replace, tail = string.substring(index + close.length), next = tail.indexOf(close)) => {
176
176
  return head + (next < 0 ? tail : replaceClose(next, tail, close, replace));
@@ -1301,9 +1301,8 @@ var DeclarationBundler = class _DeclarationBundler {
1301
1301
  }
1302
1302
  }
1303
1303
  const finalValueExportsSet = new Set(valueExports.map(exportsMapper));
1304
- const finalValueExports = [...finalValueExportsSet];
1305
- const finalTypeExports = [...new Set(typeExports.map(exportsMapper).filter((t) => !finalValueExportsSet.has(t)))];
1306
- return { code: magic.toString(), externalImports, typeExports: finalTypeExports, valueExports: finalValueExports };
1304
+ const finalTypeExports = [...new Set(typeExports.map(exportsMapper).filter((type2) => !finalValueExportsSet.has(type2)))];
1305
+ return { code: magic.toString(), externalImports, typeExports: finalTypeExports, valueExports: [...finalValueExportsSet] };
1307
1306
  }
1308
1307
  /**
1309
1308
  * Combine modules into a single output string
@@ -1322,15 +1321,15 @@ var DeclarationBundler = class _DeclarationBundler {
1322
1321
  const allDeclarations = /* @__PURE__ */ new Set();
1323
1322
  const declarationSources = /* @__PURE__ */ new Map();
1324
1323
  const renameMap = /* @__PURE__ */ new Map();
1325
- for (const { path, identifiers } of sortedModules) {
1326
- for (const name of identifiers.types) {
1324
+ for (const { path, identifiers: { types, values } } of sortedModules) {
1325
+ for (const name of types) {
1327
1326
  let set = declarationSources.get(name);
1328
1327
  if (set === void 0) {
1329
1328
  declarationSources.set(name, set = /* @__PURE__ */ new Set());
1330
1329
  }
1331
1330
  set.add(path);
1332
1331
  }
1333
- for (const name of identifiers.values) {
1332
+ for (const name of values) {
1334
1333
  let set = declarationSources.get(name);
1335
1334
  if (set === void 0) {
1336
1335
  declarationSources.set(name, set = /* @__PURE__ */ new Set());
@@ -1353,7 +1352,7 @@ var DeclarationBundler = class _DeclarationBundler {
1353
1352
  }
1354
1353
  }
1355
1354
  }
1356
- for (const { path, typeReferences, fileReferences, sourceFile, code, identifiers } of sortedModules) {
1355
+ for (const { path, typeReferences, fileReferences, sourceFile, code, identifiers: { types, values } } of sortedModules) {
1357
1356
  for (const r of typeReferences) {
1358
1357
  typeReferencesSet.add(r);
1359
1358
  }
@@ -1361,7 +1360,7 @@ var DeclarationBundler = class _DeclarationBundler {
1361
1360
  fileReferencesSet.add(r);
1362
1361
  }
1363
1362
  const bundledForThisModule = bundledSpecifiers.get(path) ?? emptySet;
1364
- const { code: strippedCode, externalImports, typeExports, valueExports } = this.stripImportsExports(code, sourceFile, identifiers, bundledForThisModule, renameMap, path);
1363
+ const { code: strippedCode, externalImports, typeExports, valueExports } = this.stripImportsExports(code, sourceFile, { types, values }, bundledForThisModule, renameMap, path);
1365
1364
  for (const imp of externalImports) {
1366
1365
  allExternalImports.push(imp);
1367
1366
  }
@@ -1375,10 +1374,10 @@ var DeclarationBundler = class _DeclarationBundler {
1375
1374
  orderedTypeExports.push(exp);
1376
1375
  }
1377
1376
  }
1378
- for (const name of identifiers.types) {
1377
+ for (const name of types) {
1379
1378
  allDeclarations.add(name);
1380
1379
  }
1381
- for (const name of identifiers.values) {
1380
+ for (const name of values) {
1382
1381
  allDeclarations.add(name);
1383
1382
  }
1384
1383
  }
@@ -1472,9 +1471,7 @@ Total available files: ${availableFiles.length}`
1472
1471
  }
1473
1472
  };
1474
1473
  async function bundleDeclarations(options) {
1475
- if (!await Files.exists(options.compilerOptions.outDir)) {
1476
- await mkdir2(options.compilerOptions.outDir, defaultDirOptions);
1477
- }
1474
+ await mkdir2(options.compilerOptions.outDir, defaultDirOptions);
1478
1475
  const dtsBundler = new DeclarationBundler(options);
1479
1476
  const bundleTasks = [];
1480
1477
  const bundleEntryPoint = (entryName, entryPoint) => {
@@ -1485,8 +1482,9 @@ async function bundleDeclarations(options) {
1485
1482
  }
1486
1483
  };
1487
1484
  if (options.parallelTranspile) {
1485
+ const queueImmediateTask = (resolve3) => void setImmediate(resolve3);
1488
1486
  for (const [entryName, entryPoint] of Object.entries(options.entryPoints)) {
1489
- await new Promise((resolve3) => void setImmediate(resolve3));
1487
+ await new Promise(queueImmediateTask);
1490
1488
  bundleEntryPoint(entryName, entryPoint);
1491
1489
  }
1492
1490
  } else {
@@ -1624,7 +1622,7 @@ async function resolveReference(reference, projectDir) {
1624
1622
  } catch (error) {
1625
1623
  throw new ConfigurationError(`Failed to load plugin "${specifier}": ${error instanceof Error ? error.message : String(error)}`);
1626
1624
  }
1627
- const defaultExport = module.default;
1625
+ const defaultExport = module["default"];
1628
1626
  if (defaultExport === void 0) {
1629
1627
  throw new ConfigurationError(`Plugin "${specifier}" has no default export. The module must export a plugin factory function or Plugin object as its default export.`);
1630
1628
  }
@@ -2652,7 +2650,7 @@ var _TypeScriptProject = class _TypeScriptProject {
2652
2650
  await this.pendingStaleOutputsCleanup;
2653
2651
  }
2654
2652
  async build() {
2655
- Logger.header(`${tsLogo} tsbuild v${"1.8.7"}${this.configuration.compilerOptions.incremental && this.configuration.buildCache?.isValid() ? " [incremental]" : ""}`);
2653
+ Logger.header(`${tsLogo} tsbuild v${"1.8.9"}${this.configuration.compilerOptions.incremental && this.configuration.buildCache?.isValid() ? " [incremental]" : ""}`);
2656
2654
  try {
2657
2655
  const processes = [];
2658
2656
  const buildCache = this.configuration.buildCache;
@@ -2737,7 +2735,14 @@ var _TypeScriptProject = class _TypeScriptProject {
2737
2735
  allDiagnostics = [...this.builderProgram.getSemanticDiagnostics(), ...diagnostics];
2738
2736
  }
2739
2737
  if (allDiagnostics.length > 0) {
2740
- _TypeScriptProject.handleTypeErrors("Type-checking failed", allDiagnostics, this.directory);
2738
+ const unique = /* @__PURE__ */ new Map();
2739
+ for (const diagnostic of allDiagnostics) {
2740
+ const key = `${diagnostic.file?.fileName ?? ""}:${diagnostic.start ?? -1}:${diagnostic.code}`;
2741
+ if (!unique.has(key)) {
2742
+ unique.set(key, diagnostic);
2743
+ }
2744
+ }
2745
+ _TypeScriptProject.handleTypeErrors("Type-checking failed", Array.from(unique.values()), this.directory);
2741
2746
  }
2742
2747
  return this.fileManager.finalize() || !this.configuration.compilerOptions.declaration;
2743
2748
  }
@@ -2974,8 +2979,10 @@ var _TypeScriptProject = class _TypeScriptProject {
2974
2979
  ...{ outDir: defaultOutDirectory, noEmit: false, sourceMap: false, incremental: true, tsBuildInfoFile: Paths.join(cacheDirectory, buildInfoFile), lib: [] },
2975
2980
  ...configResult.config.compilerOptions,
2976
2981
  ...typeScriptOptions.compilerOptions,
2977
- // Always include 'node' and merge with any user-specified types
2978
- types: [.../* @__PURE__ */ new Set(["node", ...configResult.config.compilerOptions?.types ?? [], ...typeScriptOptions.compilerOptions?.types ?? []])]
2982
+ // Auto-inject 'node' only on Node platform browser/neutral builds shouldn't pay the
2983
+ // cost of loading @types/node (~3 MB of declarations). Users can still opt in by
2984
+ // listing 'node' explicitly in their tsconfig types array.
2985
+ types: platform2 === Platform.NODE ? [.../* @__PURE__ */ new Set(["node", ...configResult.config.compilerOptions?.types ?? [], ...typeScriptOptions.compilerOptions?.types ?? []])] : [.../* @__PURE__ */ new Set([...configResult.config.compilerOptions?.types ?? [], ...typeScriptOptions.compilerOptions?.types ?? []])]
2979
2986
  }
2980
2987
  };
2981
2988
  const { options, fileNames, errors } = parseJsonConfigFileContent(baseConfig, sys2, directory);
@@ -3087,18 +3094,6 @@ var _TypeScriptProject = class _TypeScriptProject {
3087
3094
  }
3088
3095
  throw new TypeCheckError(message, formatDiagnostics(diagnostics, diagnosticsHost));
3089
3096
  }
3090
- /**
3091
- * Calculates elapsed time since a performance mark and clears the mark.
3092
- * @param markName - The name of the performance mark to measure from
3093
- * @returns Elapsed time in milliseconds
3094
- */
3095
- static elapsed(markName) {
3096
- const { name, startTime } = performance2.mark(`${markName}:end`);
3097
- const ms = ~~(startTime - performance2.getEntriesByName(markName, "mark")[0].startTime);
3098
- performance2.clearMarks(markName);
3099
- performance2.clearMarks(name);
3100
- return ms;
3101
- }
3102
3097
  };
3103
3098
  _init3 = __decoratorStart(null);
3104
3099
  __decorateElement(_init3, 1, "build", _build_dec, _TypeScriptProject);
package/dist/tsbuild.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  BuildError,
4
4
  TypeScriptProject
5
- } from "./GYI2SMUW.js";
5
+ } from "./QXXMXCRU.js";
6
6
  import "./QL4XMDMJ.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.7");
33
+ console.log("1.8.9");
34
34
  process.exit(0);
35
35
  }
36
36
  var typeScriptOptions = {
@@ -389,12 +389,6 @@ declare class TypeScriptProject implements Closable {
389
389
  * @param projectDirectory - The project directory.
390
390
  */
391
391
  private static handleTypeErrors;
392
- /**
393
- * Calculates elapsed time since a performance mark and clears the mark.
394
- * @param markName - The name of the performance mark to measure from
395
- * @returns Elapsed time in milliseconds
396
- */
397
- private static elapsed;
398
392
  }
399
393
 
400
394
  export { Plugin, TypeScriptProject };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  TypeScriptProject
3
- } from "./GYI2SMUW.js";
3
+ } from "./QXXMXCRU.js";
4
4
  import "./QL4XMDMJ.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.7",
4
+ "version": "1.8.9",
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",
@@ -50,18 +50,18 @@
50
50
  },
51
51
  "devDependencies": {
52
52
  "@eslint/js": "^10.0.1",
53
- "@types/node": "^25.6.0",
54
- "@typescript-eslint/eslint-plugin": "^8.59.2",
55
- "@typescript-eslint/parser": "^8.59.2",
56
- "@vitest/coverage-v8": "^4.1.5",
57
- "eslint": "^10.3.0",
53
+ "@types/node": "^25.8.0",
54
+ "@typescript-eslint/eslint-plugin": "^8.59.3",
55
+ "@typescript-eslint/parser": "^8.59.3",
56
+ "@vitest/coverage-v8": "^4.1.6",
57
+ "eslint": "^10.4.0",
58
58
  "eslint-plugin-jsdoc": "^62.9.0",
59
59
  "fs-monkey": "^1.1.0",
60
60
  "memfs": "^4.57.2",
61
- "tinybench": "^6.0.1",
61
+ "mitata": "^1.0.34",
62
62
  "typescript": "^6.0.3",
63
- "typescript-eslint": "^8.59.2",
64
- "vitest": "^4.1.5"
63
+ "typescript-eslint": "^8.59.3",
64
+ "vitest": "^4.1.6"
65
65
  },
66
66
  "peerDependencies": {
67
67
  "typescript": ">=5.6.3"