Comparing version 1.1.0 to 1.2.0
@@ -23,5 +23,5 @@ import mri from 'mri'; | ||
}; | ||
export declare const arg: <T extends readonly Option[]>(options: T) => { | ||
export declare const arg: <T extends Readonly<Option[]>>(options: T) => { | ||
parse: (args: string[]) => mri.Argv<UnionToIntersection<Parsed<T[number]>> extends infer T_1 ? { [K in keyof T_1]: UnionToIntersection<Parsed<T[number]>>[K]; } : never>; | ||
}; | ||
export {}; |
@@ -7,8 +7,8 @@ import ts from 'typescript'; | ||
fileService: FileService; | ||
enableCodeFix?: boolean | undefined; | ||
deleteUnusedFile?: boolean | undefined; | ||
output?: Output | undefined; | ||
options?: ts.CompilerOptions | undefined; | ||
projectRoot?: string | undefined; | ||
enableCodeFix?: boolean; | ||
deleteUnusedFile?: boolean; | ||
output?: Output; | ||
options?: ts.CompilerOptions; | ||
projectRoot?: string; | ||
recursive: boolean; | ||
}) => Promise<void>; |
@@ -10,3 +10,2 @@ import ts from "typescript"; | ||
import { MemoryFileService } from "./MemoryFileService.js"; | ||
import { TaskManager } from "./TaskManager.js"; | ||
import { findFileUsage } from "./findFileUsage.js"; | ||
@@ -484,61 +483,77 @@ import { parseFile } from "./parseFile.js"; | ||
initialFiles.sort((a, b) => a.depth - b.depth); | ||
const taskManager = new TaskManager(async (c) => { | ||
if (!fileService.exists(c.file)) { | ||
return; | ||
const queue = [initialFiles]; | ||
while (queue.length > 0) { | ||
const first = queue.shift(); | ||
if (!first) { | ||
break; | ||
} | ||
const vertex = dependencyGraph.vertexes.get(c.file); | ||
await Promise.resolve(); | ||
if (c.signal.aborted) { | ||
return; | ||
} | ||
const result = processFile({ | ||
targetFile: c.file, | ||
vertexes: dependencyGraph.eject(), | ||
const current = { | ||
vertexes: dependencyGraph.vertexes, | ||
files: fileService.eject(), | ||
fileNames: fileService.getFileNames(), | ||
deleteUnusedFile, | ||
enableCodeFix, | ||
options, | ||
projectRoot | ||
}); | ||
if (c.signal.aborted) { | ||
return; | ||
} | ||
switch (result.operation) { | ||
case "delete": { | ||
if (entrypoints.includes(c.file)) { | ||
break; | ||
fileNames: fileService.getFileNames() | ||
}; | ||
const next = first.map((v) => { | ||
if (!fileService.exists(v.file)) { | ||
return; | ||
} | ||
const result = processFile({ | ||
targetFile: v.file, | ||
vertexes: current.vertexes, | ||
files: current.files, | ||
fileNames: current.fileNames, | ||
deleteUnusedFile, | ||
enableCodeFix, | ||
options, | ||
projectRoot | ||
}); | ||
return { result, ...v }; | ||
}).filter((r) => !!r).map(({ result, file }) => { | ||
const vertex = dependencyGraph.vertexes.get(file); | ||
switch (result.operation) { | ||
case "delete": { | ||
if (entrypoints.includes(file)) { | ||
return []; | ||
} | ||
output.deleteFile(file); | ||
fileService.delete(file); | ||
if (vertex) { | ||
dependencyGraph.deleteVertex(file); | ||
if (recursive) { | ||
return Array.from(vertex.to).filter( | ||
(f) => !entrypoints.includes(f) | ||
); | ||
} | ||
} | ||
return []; | ||
} | ||
output.deleteFile(c.file); | ||
fileService.delete(c.file); | ||
if (vertex) { | ||
dependencyGraph.deleteVertex(c.file); | ||
if (recursive) { | ||
c.add( | ||
...Array.from(vertex.to).filter((f) => !entrypoints.includes(f)) | ||
case "edit": { | ||
for (const item of result.removedExports) { | ||
output.removeExport({ | ||
file: item.fileName, | ||
content: fileService.get(item.fileName), | ||
code: item.code, | ||
position: item.position | ||
}); | ||
} | ||
fileService.set(file, result.content); | ||
if (vertex && result.removedExports.length > 0 && recursive) { | ||
return Array.from(vertex.to).filter( | ||
(f) => !entrypoints.includes(f) | ||
); | ||
} | ||
return []; | ||
} | ||
break; | ||
} | ||
case "edit": { | ||
for (const item of result.removedExports) { | ||
output.removeExport({ | ||
file: item.fileName, | ||
content: fileService.get(item.fileName), | ||
code: item.code, | ||
position: item.position | ||
}); | ||
} | ||
fileService.set(c.file, result.content); | ||
if (vertex && result.removedExports.length > 0 && recursive) { | ||
c.add( | ||
...Array.from(vertex.to).filter((f) => !entrypoints.includes(f)) | ||
); | ||
} | ||
break; | ||
} | ||
}); | ||
const files = Array.from(new Set(next.flat())); | ||
if (files.length > 0) { | ||
queue.push( | ||
files.map((file) => ({ | ||
file, | ||
depth: dependencyGraph.vertexes.get(file)?.data.depth || Infinity | ||
})) | ||
); | ||
} | ||
}); | ||
await taskManager.execute(initialFiles.map((v) => v.file)); | ||
} | ||
return Promise.resolve(); | ||
}; | ||
@@ -545,0 +560,0 @@ export { |
@@ -5,9 +5,3 @@ import ts from 'typescript'; | ||
targetFile: string; | ||
vertexes: Map<string, { | ||
to: Set<string>; | ||
from: Set<string>; | ||
data: { | ||
depth: number; | ||
}; | ||
}>; | ||
vertexes: Vertexes; | ||
files: Map<string, string>; | ||
@@ -14,0 +8,0 @@ fileNames: Set<string>; |
@@ -134,7 +134,7 @@ import ts from 'typescript'; | ||
destFiles: Set<string>; | ||
options?: ts.CompilerOptions | undefined; | ||
options?: ts.CompilerOptions; | ||
}) => { | ||
imports: { | ||
[file: string]: (string | { | ||
type: 'wholeReexport'; | ||
type: "wholeReexport"; | ||
file: string; | ||
@@ -141,0 +141,0 @@ })[]; |
import ts from "typescript"; | ||
import { memoize } from "./memoize.js"; | ||
import { namespaceUsage } from "./namespaceUsage.js"; | ||
const getLeadingComment = (node) => { | ||
@@ -282,3 +283,6 @@ const fullText = node.getSourceFile().getFullText(); | ||
imports[resolved] ||= []; | ||
imports[resolved]?.push("*"); | ||
const usage = namespaceUsage({ sourceFile }); | ||
imports[resolved]?.push( | ||
...usage.get(node.importClause.namedBindings.name.text) | ||
); | ||
return; | ||
@@ -285,0 +289,0 @@ } |
@@ -45,3 +45,3 @@ { | ||
}, | ||
"version": "1.1.0" | ||
"version": "1.2.0" | ||
} |
@@ -221,4 +221,4 @@ # tsr | ||
| tsr | Knip | | ||
| ----- | ------ | | ||
| tsr | Knip | | ||
| ---- | ------ | | ||
| 98kB | 5.86MB | | ||
@@ -228,3 +228,3 @@ | ||
Our benchmark shows that tsr is 2.5x faster compared to Knip 🚀 (see `benchmark/vue_core.sh` for details) | ||
Our benchmark shows that tsr is 2.14x faster compared to Knip 🚀 (see `benchmark/vue_core.sh` for details) | ||
@@ -239,10 +239,10 @@ <img width="400" src="./media/comparison.png" alt="benchmark of tsr and Knip" /> | ||
| Feature | tsr | Knip | | ||
| ------------------------ | ------------------------------ | ------------------------------------------ | | ||
| **Automatic Editing** | ✅ Comprehensive | Limited | | ||
| **Zero Configuration** | ✅ Works with `tsconfig.json` | Requires a config file for correct results | | ||
| **Predictable Behavior** | ✅ TypeScript-based logic | Assumptions for project structure | | ||
| Feature | tsr | Knip | | ||
| ------------------------ | ----------------------------- | ------------------------------------------ | | ||
| **Automatic Editing** | ✅ Comprehensive | Limited | | ||
| **Zero Configuration** | ✅ Works with `tsconfig.json` | Requires a config file for correct results | | ||
| **Predictable Behavior** | ✅ TypeScript-based logic | Assumptions for project structure | | ||
| **Install Size** | ✅ 98kB, minimal dependencies | 5.86MB, requires `@types/node` | | ||
| **Performance** | ✅ 2.5x faster | | | ||
| **Recursive Editing** | ✅ `--recursive` option | | | ||
| **Performance** | ✅ 2.14x faster | | | ||
| **Recursive Editing** | ✅ `--recursive` option | | | ||
@@ -249,0 +249,0 @@ ## Examples |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
79302
2034