@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 +27 -0
- package/dist/{UM2SFHAT.js → 23A5VAYC.js} +121 -77
- package/dist/tsbuild.js +2 -2
- package/dist/type-script-project.js +1 -1
- package/package.json +2 -1
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,
|
|
152
|
-
return index < 0 ? `${
|
|
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 = (
|
|
155
|
-
return (text) => text.length ? clearBleed(text.indexOf(close, at), text,
|
|
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 = (
|
|
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
|
-
|
|
832
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
*
|
|
964
|
-
*
|
|
965
|
-
* @param patterns -
|
|
966
|
-
* @returns
|
|
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
|
-
|
|
979
|
-
|
|
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.
|
|
1058
|
+
if (this.matchExternal(specifier)) {
|
|
1030
1059
|
continue;
|
|
1031
1060
|
}
|
|
1032
1061
|
const resolvedPath = this.resolveModule(specifier, path);
|
|
1033
|
-
if (resolvedPath?.includes(nodeModules) && !this.
|
|
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.
|
|
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 -
|
|
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.
|
|
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
|
-
|
|
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}.
|
|
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
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
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
|
-
|
|
1408
|
-
|
|
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
|
-
*
|
|
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 ({
|
|
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
|
|
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 ({
|
|
1564
|
-
if (!
|
|
1599
|
+
build.onEnd(async ({ metafile }) => {
|
|
1600
|
+
if (!metafile || entryPointNames.length === 0) {
|
|
1565
1601
|
return;
|
|
1566
1602
|
}
|
|
1567
|
-
const written = await buildIife(
|
|
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(
|
|
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
|
|
1627
|
-
if (
|
|
1628
|
-
fileContents.set(
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
|
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.
|
|
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:
|
|
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 "./
|
|
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.
|
|
33
|
+
console.log("1.8.4");
|
|
34
34
|
process.exit(0);
|
|
35
35
|
}
|
|
36
36
|
var typeScriptOptions = {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@d1g1tal/tsbuild",
|
|
3
3
|
"author": "D1g1talEntr0py",
|
|
4
|
-
"version": "1.8.
|
|
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",
|