@typeslayer/analyze-trace 0.1.30 → 0.1.32

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/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  Analyze TypeScript compiler trace events to identify performance bottlenecks and compilation hot spots.
4
4
 
5
- Initially, this started as a full rewrite of [@typescript/analyze-trace](https://github.com/microsoft/typescript-analyze-trace)*. That rewrite was successful, and new features were added during the development of [TypeSlayer](https://github.com/dimitropoulos/typeslayer) (where it was rewritten a second time in Rust).
5
+ Initially, this started as a full rewrite of [@typescript/analyze-trace](https://github.com/microsoft/typescript-analyze-trace)\*. That rewrite was successful, and new features were added during the development of [TypeSlayer](https://github.com/dimitropoulos/typeslayer) (where it was rewritten a second time in Rust).
6
6
 
7
- > \* <sub>why did it need a full rewrite?<br /><br />well.. it's been unmaintained for many years and also I <a href="https://github.com/dimitropoulos">dimitropoulos</a> wanted to learn every detail of how it works. academically speaking, rewrites are great for that. when I looked deeper, though I saw some exceedingly interesting things (like some of the instantaneous events for type limits) that the original tool completely ignores (<a href="https://github.com/microsoft/typescript-analyze-trace/issues/1">sometimes intentionally</a>), yet some are actually quite fundamental to the goal of TypeSlayer!<br /><br /> also the original was intended as a end-of-the-pipeline CLI tool (giving nice human readable format, but only experimental JSON support) and the rewrite is though of as a middle-of-the-pipeline tool (1st-class JSON support). </sub>
7
+ > \* <sub>why did it need a full rewrite?<br /><br />well.. it's been unmaintained for many years and also I <a href="https://github.com/dimitropoulos">dimitropoulos</a> wanted to learn every detail of how it works. academically speaking, rewrites are great for that. when I looked deeper, though I saw some exceedingly interesting things (like some of the instantaneous events for type limits) that the original tool completely ignores (<a href="https://github.com/microsoft/typescript-analyze-trace/issues/1">sometimes intentionally</a>), yet some are actually quite fundamental to the goal of TypeSlayer!<br /><br /> also the original was intended as a end-of-the-pipeline CLI tool (giving nice human readable format, but only experimental JSON support) and the rewrite is though of as a middle-of-the-pipeline tool (1st-class JSON support). </sub>
8
8
 
9
9
  ## CLI Usage
10
10
 
@@ -26,18 +26,18 @@ typeslayer-analyze-trace ./dist/trace.json > analysis.json
26
26
  ## Programmatic Usage
27
27
 
28
28
  ```ts
29
- import { analyzeTrace } from '@typeslayer/analyze-trace';
30
- import { readFileSync } from 'fs';
29
+ import { analyzeTrace } from "@typeslayer/analyze-trace";
30
+ import { readFileSync } from "fs";
31
31
 
32
32
  // Read and parse trace
33
- const traceJson = JSON.parse(readFileSync('trace.json', 'utf-8'));
33
+ const traceJson = JSON.parse(readFileSync("trace.json", "utf-8"));
34
34
 
35
35
  // Analyze
36
36
  const result = analyzeTrace(traceJson);
37
37
 
38
- console.log('Hot spots:', result.hotSpots);
39
- console.log('Depth limits:', result.depthLimits);
40
- console.log('Duplicate packages:', result.duplicatePackages);
38
+ console.log("Hot spots:", result.hotSpots);
39
+ console.log("Depth limits:", result.depthLimits);
40
+ console.log("Duplicate packages:", result.duplicatePackages);
41
41
  ```
42
42
 
43
43
  ## Analysis Output
@@ -46,36 +46,36 @@ The analyzer provides:
46
46
 
47
47
  ### Hot Spot Detection
48
48
 
49
- This is a sliding scale that looks at the events that consumed the most time during compilation. It's not a given that because something is hot it's necessarily _bad_. But, the thinking is, if you see something that's much more intensive than something else, it's worth flagging. So. There you go.
49
+ This is a sliding scale that looks at the events that consumed the most time during compilation. It's not a given that because something is hot it's necessarily _bad_. But, the thinking is, if you see something that's much more intensive than something else, it's worth flagging. So. There you go.
50
50
 
51
51
  ### Duplicate Package Detection
52
52
 
53
- Package versions appearing in multiple locations from the same package. This is one of those things that people often have no idea is going on, but in reality most projects have this problem. Well. "problem" might be a strong word. Similar to [Hot Spot Detection](#hot-spot-detection), you'll have to use your judgement here to decide whether it's a big deal or not. That's largely going to depend on the size/scale/usage of the thing that's duplicated.
53
+ Package versions appearing in multiple locations from the same package. This is one of those things that people often have no idea is going on, but in reality most projects have this problem. Well. "problem" might be a strong word. Similar to [Hot Spot Detection](#hot-spot-detection), you'll have to use your judgement here to decide whether it's a big deal or not. That's largely going to depend on the size/scale/usage of the thing that's duplicated.
54
54
 
55
55
  ### Unterminated Events
56
56
 
57
- In a perfect world, all events created by TypeScript's trace machinery should be terminated. What's that mean? Think of it like a missing JSX closing tag. The thinking here is that if that ever happens, it's guaranteed to be a symptom of something else being wrong - so the tool flags it.
57
+ In a perfect world, all events created by TypeScript's trace machinery should be terminated. What's that mean? Think of it like a missing JSX closing tag. The thinking here is that if that ever happens, it's guaranteed to be a symptom of something else being wrong - so the tool flags it.
58
58
 
59
59
  ### Depth Limits (unique to `@typeslayer/analyze-trace`)
60
60
 
61
61
  Type-level limits that were hit during the type checking, including:
62
62
 
63
- | Depth Limit | Error Triggered |
64
- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
65
- | `checkCrossProductUnion_DepthLimit` | triggers `TS(2590) Expression produces a union type that is too complex to represent.` |
66
- | `checkTypeRelatedTo_DepthLimit` | triggers `TS(2859) Excessive complexity comparing types '{0}' and '{1}'.` or `TS(2321) Excessive stack depth comparing types '{0}' and '{1}'.` |
67
- | `getTypeAtFlowNode_DepthLimit` | triggers `TS(2563) The containing function or module body is too large for control flow analysis.` |
68
- | `instantiateType_DepthLimit` | triggers `TS(2589) Type instantiation is excessively deep and possibly infinite.` |
63
+ | Depth Limit | Error Triggered |
64
+ | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
65
+ | `checkCrossProductUnion_DepthLimit` | triggers `TS(2590) Expression produces a union type that is too complex to represent.` |
66
+ | `checkTypeRelatedTo_DepthLimit` | triggers `TS(2859) Excessive complexity comparing types '{0}' and '{1}'.` or `TS(2321) Excessive stack depth comparing types '{0}' and '{1}'.` |
67
+ | `getTypeAtFlowNode_DepthLimit` | triggers `TS(2563) The containing function or module body is too large for control flow analysis.` |
68
+ | `instantiateType_DepthLimit` | triggers `TS(2589) Type instantiation is excessively deep and possibly infinite.` |
69
69
  | `recursiveTypeRelatedTo_DepthLimit` | This is not currently considered a hard error by the compiler and therefore does not report to the user (unless you're a [TypeSlayer](https://github.com/dimitropoulos/typeslayer) user 😉). |
70
- | `removeSubtypes_DepthLimit` | triggers `TS(2590) Expression produces a union type that is too complex to represent.` |
70
+ | `removeSubtypes_DepthLimit` | triggers `TS(2590) Expression produces a union type that is too complex to represent.` |
71
71
  | `traceUnionsOrIntersectionsTooLarge_DepthLimit` | This is not currently considered a hard error by the compiler and therefore does not report to the user (unless you're a [TypeSlayer](https://github.com/dimitropoulos/typeslayer) user 😉). |
72
72
  | `typeRelatedToDiscriminatedType_DepthLimit` | This is not currently considered a hard error by the compiler and therefore does not report to the user (unless you're a [TypeSlayer](https://github.com/dimitropoulos/typeslayer) user 😉). |
73
73
 
74
74
  ### Type Graph
75
75
 
76
76
  > _note_:
77
- > As fate would have it, when [TypeSlayer](https://github.com/dimitropoulos/typeslayer) moved from Node.js to Rust to be a Tauri app, this entire package was _again_ rewritten in Rust. Since this version was fully up-and-running first, and the original has some issues, I decided to just not delete this and publish it in case others stuck in the Node ecosystem (ðŸŠĶ) find it useful.
77
+ > As fate would have it, when [TypeSlayer](https://github.com/dimitropoulos/typeslayer) moved from Node.js to Rust to be a Tauri app, this entire package was _again_ rewritten in Rust. Since this version was fully up-and-running first, and the original has some issues, I decided to just not delete this and publish it in case others stuck in the Node ecosystem (ðŸŠĶ) find it useful.
78
78
  >
79
- > This particular feature is only in the Rust version. If you'd like a wasm-build of it or something lemme know.
79
+ > This particular feature is only in the Rust version. If you'd like a wasm-build of it or something lemme know.
80
80
 
81
- This is the thing that powers the [TypeSlayer](https://github.com/dimitropoulos/typeslayer) "Type Graph". It basically takes the `types.json` output and combines it with the information in the `trace.json` to create a list of relations (of various sorts) between all the types in your project. It also compiles stats for records like "biggest union" and "most commonly included in an intersection" and literally over a doze more like that.
81
+ This is the thing that powers the [TypeSlayer](https://github.com/dimitropoulos/typeslayer) "Type Graph". It basically takes the `types.json` output and combines it with the information in the `trace.json` to create a list of relations (of various sorts) between all the types in your project. It also compiles stats for records like "biggest union" and "most commonly included in an intersection" and literally over a doze more like that.
@@ -3,38 +3,42 @@
3
3
  import { statSync, writeFileSync } from "node:fs";
4
4
  import { resolve } from "node:path";
5
5
  import process, { exit } from "node:process";
6
- import { ANALYZE_TRACE_FILENAME, analyzeTrace, defaultOptions } from "../dist/index.mjs";
6
+ import {
7
+ ANALYZE_TRACE_FILENAME,
8
+ analyzeTrace,
9
+ defaultOptions,
10
+ } from "../dist/index.mjs";
7
11
 
8
12
  const { argv } = process;
9
13
 
10
14
  const traceDirArg = argv[2];
11
15
 
12
16
  if (!traceDirArg) {
13
- console.error("Gotta give a trace directory, brah.");
14
- exit(1);
17
+ console.error("Gotta give a trace directory, brah.");
18
+ exit(1);
15
19
  }
16
20
 
17
21
  const traceDir = resolve(traceDirArg);
18
22
 
19
23
  try {
20
- const stat = statSync(traceDir);
21
- if (!stat.isDirectory()) {
22
- console.error(`Trace directory "${traceDir}" is not a directory.`);
23
- exit(1);
24
- }
24
+ const stat = statSync(traceDir);
25
+ if (!stat.isDirectory()) {
26
+ console.error(`Trace directory "${traceDir}" is not a directory.`);
27
+ exit(1);
28
+ }
25
29
  } catch (err) {
26
- if (err.code === "ENOENT") {
27
- console.error(`Trace directory "${traceDir}" does not exist.`);
28
- } else {
29
- console.error(
30
- `Error checking trace directory "${traceDir}": ${err.message}`,
31
- );
32
- }
33
- exit(1);
30
+ if (err.code === "ENOENT") {
31
+ console.error(`Trace directory "${traceDir}" does not exist.`);
32
+ } else {
33
+ console.error(
34
+ `Error checking trace directory "${traceDir}": ${err.message}`,
35
+ );
36
+ }
37
+ exit(1);
34
38
  }
35
39
 
36
- analyzeTrace({ traceDir, options: defaultOptions }).then((result) => {
37
- const destination = resolve(traceDir, ANALYZE_TRACE_FILENAME);
38
- writeFileSync(destination, JSON.stringify(result, null, 2), "utf-8");
39
- console.log("Analysis result:", result);
40
+ analyzeTrace({ traceDir, options: defaultOptions }).then(result => {
41
+ const destination = resolve(traceDir, ANALYZE_TRACE_FILENAME);
42
+ writeFileSync(destination, JSON.stringify(result, null, 2), "utf-8");
43
+ console.log("Analysis result:", result);
40
44
  });
@@ -193,34 +193,34 @@ declare const hotSpot: z.ZodObject<{
193
193
  start: z.ZodObject<{
194
194
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
195
195
  character: z.ZodNumber;
196
- }, z.core.$strip>;
196
+ }, z.core.$strict>;
197
197
  end: z.ZodObject<{
198
198
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
199
199
  character: z.ZodNumber;
200
- }, z.core.$strip>;
201
- }, z.core.$strip>>;
200
+ }, z.core.$strict>;
201
+ }, z.core.$strict>>;
202
202
  referenceLocation: z.ZodOptional<z.ZodObject<{
203
203
  path: z.ZodString;
204
204
  start: z.ZodObject<{
205
205
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
206
206
  character: z.ZodNumber;
207
- }, z.core.$strip>;
207
+ }, z.core.$strict>;
208
208
  end: z.ZodObject<{
209
209
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
210
210
  character: z.ZodNumber;
211
- }, z.core.$strip>;
212
- }, z.core.$strip>>;
211
+ }, z.core.$strict>;
212
+ }, z.core.$strict>>;
213
213
  destructuringPattern: z.ZodOptional<z.ZodObject<{
214
214
  path: z.ZodString;
215
215
  start: z.ZodObject<{
216
216
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
217
217
  character: z.ZodNumber;
218
- }, z.core.$strip>;
218
+ }, z.core.$strict>;
219
219
  end: z.ZodObject<{
220
220
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
221
221
  character: z.ZodNumber;
222
- }, z.core.$strip>;
223
- }, z.core.$strip>>;
222
+ }, z.core.$strict>;
223
+ }, z.core.$strict>>;
224
224
  }, z.core.$strict>;
225
225
  children: z.ZodArray<z.ZodObject< /*elided*/any, z.core.$strip>>;
226
226
  }, z.core.$strip>>>;
@@ -3039,34 +3039,34 @@ declare const analyzeTraceResult: z.ZodObject<{
3039
3039
  start: z.ZodObject<{
3040
3040
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
3041
3041
  character: z.ZodNumber;
3042
- }, z.core.$strip>;
3042
+ }, z.core.$strict>;
3043
3043
  end: z.ZodObject<{
3044
3044
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
3045
3045
  character: z.ZodNumber;
3046
- }, z.core.$strip>;
3047
- }, z.core.$strip>>;
3046
+ }, z.core.$strict>;
3047
+ }, z.core.$strict>>;
3048
3048
  referenceLocation: z.ZodOptional<z.ZodObject<{
3049
3049
  path: z.ZodString;
3050
3050
  start: z.ZodObject<{
3051
3051
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
3052
3052
  character: z.ZodNumber;
3053
- }, z.core.$strip>;
3053
+ }, z.core.$strict>;
3054
3054
  end: z.ZodObject<{
3055
3055
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
3056
3056
  character: z.ZodNumber;
3057
- }, z.core.$strip>;
3058
- }, z.core.$strip>>;
3057
+ }, z.core.$strict>;
3058
+ }, z.core.$strict>>;
3059
3059
  destructuringPattern: z.ZodOptional<z.ZodObject<{
3060
3060
  path: z.ZodString;
3061
3061
  start: z.ZodObject<{
3062
3062
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
3063
3063
  character: z.ZodNumber;
3064
- }, z.core.$strip>;
3064
+ }, z.core.$strict>;
3065
3065
  end: z.ZodObject<{
3066
3066
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
3067
3067
  character: z.ZodNumber;
3068
- }, z.core.$strip>;
3069
- }, z.core.$strip>>;
3068
+ }, z.core.$strict>;
3069
+ }, z.core.$strict>>;
3070
3070
  }, z.core.$strict>;
3071
3071
  children: z.ZodArray<z.ZodObject< /*elided*/any, z.core.$strip>>;
3072
3072
  }, z.core.$strip>>>;
package/dist/index.d.mts CHANGED
@@ -149,34 +149,34 @@ declare const hotType: z.ZodObject<{
149
149
  start: z.ZodObject<{
150
150
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
151
151
  character: z.ZodNumber;
152
- }, z.core.$strip>;
152
+ }, z.core.$strict>;
153
153
  end: z.ZodObject<{
154
154
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
155
155
  character: z.ZodNumber;
156
- }, z.core.$strip>;
157
- }, z.core.$strip>>;
156
+ }, z.core.$strict>;
157
+ }, z.core.$strict>>;
158
158
  referenceLocation: z.ZodOptional<z.ZodObject<{
159
159
  path: z.ZodString;
160
160
  start: z.ZodObject<{
161
161
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
162
162
  character: z.ZodNumber;
163
- }, z.core.$strip>;
163
+ }, z.core.$strict>;
164
164
  end: z.ZodObject<{
165
165
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
166
166
  character: z.ZodNumber;
167
- }, z.core.$strip>;
168
- }, z.core.$strip>>;
167
+ }, z.core.$strict>;
168
+ }, z.core.$strict>>;
169
169
  destructuringPattern: z.ZodOptional<z.ZodObject<{
170
170
  path: z.ZodString;
171
171
  start: z.ZodObject<{
172
172
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
173
173
  character: z.ZodNumber;
174
- }, z.core.$strip>;
174
+ }, z.core.$strict>;
175
175
  end: z.ZodObject<{
176
176
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
177
177
  character: z.ZodNumber;
178
- }, z.core.$strip>;
179
- }, z.core.$strip>>;
178
+ }, z.core.$strict>;
179
+ }, z.core.$strict>>;
180
180
  }, z.core.$strict>;
181
181
  children: z.ZodArray<z.ZodObject< /*elided*/any, z.core.$strip>>;
182
182
  }, z.core.$strip>;
@@ -312,34 +312,34 @@ declare const hotSpot: z.ZodObject<{
312
312
  start: z.ZodObject<{
313
313
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
314
314
  character: z.ZodNumber;
315
- }, z.core.$strip>;
315
+ }, z.core.$strict>;
316
316
  end: z.ZodObject<{
317
317
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
318
318
  character: z.ZodNumber;
319
- }, z.core.$strip>;
320
- }, z.core.$strip>>;
319
+ }, z.core.$strict>;
320
+ }, z.core.$strict>>;
321
321
  referenceLocation: z.ZodOptional<z.ZodObject<{
322
322
  path: z.ZodString;
323
323
  start: z.ZodObject<{
324
324
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
325
325
  character: z.ZodNumber;
326
- }, z.core.$strip>;
326
+ }, z.core.$strict>;
327
327
  end: z.ZodObject<{
328
328
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
329
329
  character: z.ZodNumber;
330
- }, z.core.$strip>;
331
- }, z.core.$strip>>;
330
+ }, z.core.$strict>;
331
+ }, z.core.$strict>>;
332
332
  destructuringPattern: z.ZodOptional<z.ZodObject<{
333
333
  path: z.ZodString;
334
334
  start: z.ZodObject<{
335
335
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
336
336
  character: z.ZodNumber;
337
- }, z.core.$strip>;
337
+ }, z.core.$strict>;
338
338
  end: z.ZodObject<{
339
339
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
340
340
  character: z.ZodNumber;
341
- }, z.core.$strip>;
342
- }, z.core.$strip>>;
341
+ }, z.core.$strict>;
342
+ }, z.core.$strict>>;
343
343
  }, z.core.$strict>;
344
344
  children: z.ZodArray<z.ZodObject< /*elided*/any, z.core.$strip>>;
345
345
  }, z.core.$strip>>>;
@@ -3162,34 +3162,34 @@ declare const analyzeTraceResult: z.ZodObject<{
3162
3162
  start: z.ZodObject<{
3163
3163
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
3164
3164
  character: z.ZodNumber;
3165
- }, z.core.$strip>;
3165
+ }, z.core.$strict>;
3166
3166
  end: z.ZodObject<{
3167
3167
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
3168
3168
  character: z.ZodNumber;
3169
- }, z.core.$strip>;
3170
- }, z.core.$strip>>;
3169
+ }, z.core.$strict>;
3170
+ }, z.core.$strict>>;
3171
3171
  referenceLocation: z.ZodOptional<z.ZodObject<{
3172
3172
  path: z.ZodString;
3173
3173
  start: z.ZodObject<{
3174
3174
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
3175
3175
  character: z.ZodNumber;
3176
- }, z.core.$strip>;
3176
+ }, z.core.$strict>;
3177
3177
  end: z.ZodObject<{
3178
3178
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
3179
3179
  character: z.ZodNumber;
3180
- }, z.core.$strip>;
3181
- }, z.core.$strip>>;
3180
+ }, z.core.$strict>;
3181
+ }, z.core.$strict>>;
3182
3182
  destructuringPattern: z.ZodOptional<z.ZodObject<{
3183
3183
  path: z.ZodString;
3184
3184
  start: z.ZodObject<{
3185
3185
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
3186
3186
  character: z.ZodNumber;
3187
- }, z.core.$strip>;
3187
+ }, z.core.$strict>;
3188
3188
  end: z.ZodObject<{
3189
3189
  line: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
3190
3190
  character: z.ZodNumber;
3191
- }, z.core.$strip>;
3192
- }, z.core.$strip>>;
3191
+ }, z.core.$strict>;
3192
+ }, z.core.$strict>>;
3193
3193
  }, z.core.$strict>;
3194
3194
  children: z.ZodArray<z.ZodObject< /*elided*/any, z.core.$strip>>;
3195
3195
  }, z.core.$strip>>>;
package/dist/index.mjs CHANGED
@@ -26,8 +26,8 @@ const createDepthLimits = (traceFile) => {
26
26
 
27
27
  //#endregion
28
28
  //#region src/get-duplicate-node-modules.ts
29
- async function getPackageVersion(packagePath$1) {
30
- const packageJsonPath = join(packagePath$1, "package.json");
29
+ async function getPackageVersion(packagePath) {
30
+ const packageJsonPath = join(packagePath, "package.json");
31
31
  console.log("packageJsonPath", packageJsonPath);
32
32
  if (!existsSync(packageJsonPath)) {
33
33
  console.warn(`Package.json not found at ${packageJsonPath}. This may not be a node module.`);
@@ -36,17 +36,17 @@ async function getPackageVersion(packagePath$1) {
36
36
  const jsonString = await readFile(packageJsonPath, "utf-8");
37
37
  return JSON.parse(jsonString).version;
38
38
  }
39
- const getDuplicateNodeModules = async (nodeModulePaths$1) => {
39
+ const getDuplicateNodeModules = async (nodeModulePaths) => {
40
40
  const duplicates = [];
41
- for (const [packageName$1, packagePaths] of Object.entries(nodeModulePaths$1)) {
41
+ for (const [packageName, packagePaths] of Object.entries(nodeModulePaths)) {
42
42
  if (packagePaths.length < 2) continue;
43
43
  const instances = [];
44
- for (const packagePath$1 of packagePaths) instances.push({
45
- path: packagePath$1,
46
- version: await getPackageVersion(packagePath$1)
44
+ for (const packagePath of packagePaths) instances.push({
45
+ path: packagePath,
46
+ version: await getPackageVersion(packagePath)
47
47
  });
48
48
  duplicates.push({
49
- name: packageName$1,
49
+ name: packageName,
50
50
  instances
51
51
  });
52
52
  }
@@ -92,20 +92,20 @@ const notFound = {
92
92
  }
93
93
  };
94
94
  function getHotType({ id, typeRegistry }) {
95
- function worker(id$1, ancestorIds) {
96
- if (id$1 === -1) return notFound;
97
- const resolvedType$1 = typeRegistry[id$1];
98
- if (!resolvedType$1) throw new Error(`Type ${id$1} not found`);
95
+ function worker(id, ancestorIds) {
96
+ if (id === -1) return notFound;
97
+ const resolvedType = typeRegistry[id];
98
+ if (!resolvedType) throw new Error(`Type ${id} not found`);
99
99
  const children = [];
100
- if (ancestorIds.indexOf(id$1) < 0) {
101
- ancestorIds.push(id$1);
102
- const properties = Object.keys(resolvedType$1);
100
+ if (ancestorIds.indexOf(id) < 0) {
101
+ ancestorIds.push(id);
102
+ const properties = Object.keys(resolvedType);
103
103
  for (const property of properties) switch (property) {
104
104
  case "aliasTypeArguments":
105
105
  case "intersectionTypes":
106
106
  case "typeArguments":
107
107
  case "unionTypes": {
108
- const typeIds = resolvedType$1[property];
108
+ const typeIds = resolvedType[property];
109
109
  if (!Array.isArray(typeIds)) throw new Error(`Expected array for ${property}`);
110
110
  for (const typeId of typeIds) {
111
111
  const child = worker(typeId, ancestorIds);
@@ -129,7 +129,7 @@ function getHotType({ id, typeRegistry }) {
129
129
  case "reverseMappedMappedType":
130
130
  case "reverseMappedSourceType":
131
131
  case "substitutionBaseType": {
132
- const typeId = resolvedType$1[property];
132
+ const typeId = resolvedType[property];
133
133
  const child = worker(typeId, ancestorIds);
134
134
  if (child) children.push(child);
135
135
  break;
@@ -149,7 +149,7 @@ function getHotType({ id, typeRegistry }) {
149
149
  ancestorIds.pop();
150
150
  }
151
151
  return {
152
- resolvedType: resolvedType$1,
152
+ resolvedType,
153
153
  children
154
154
  };
155
155
  }
@@ -215,22 +215,22 @@ async function makeHotFrame({ span, children, typeRegistry }) {
215
215
  //#endregion
216
216
  //#region src/node-module-paths.ts
217
217
  function getNodeModulePaths(traceJson) {
218
- const nodeModulePaths$1 = {};
218
+ const nodeModulePaths = {};
219
219
  traceJson.forEach((event) => {
220
220
  if (event.name !== "findSourceFile") return;
221
221
  const path = event.args.fileName;
222
222
  if (path) while (true) {
223
223
  const match = packageNameRegex.exec(path);
224
224
  if (!match) break;
225
- const packageName$1 = match[1];
226
- const packagePath$1 = match.input.substring(0, match.index + match[0].length);
227
- if (packageName$1 in nodeModulePaths$1) {
228
- const paths = nodeModulePaths$1[packageName$1];
229
- if (paths && paths.indexOf(packagePath$1) < 0) paths.push(packagePath$1);
230
- } else nodeModulePaths$1[packageName$1] = [packagePath$1];
225
+ const packageName = match[1];
226
+ const packagePath = match.input.substring(0, match.index + match[0].length);
227
+ if (packageName in nodeModulePaths) {
228
+ const paths = nodeModulePaths[packageName];
229
+ if (paths && paths.indexOf(packagePath) < 0) paths.push(packagePath);
230
+ } else nodeModulePaths[packageName] = [packagePath];
231
231
  }
232
232
  });
233
- return nodeModulePaths$1;
233
+ return nodeModulePaths;
234
234
  }
235
235
 
236
236
  //#endregion
@@ -279,8 +279,8 @@ function createSpans(traceFile) {
279
279
  unclosedStack
280
280
  };
281
281
  }
282
- function createSpanTree(parseResult$1, options) {
283
- const { firstSpanStart, lastSpanEnd, spans, unclosedStack } = parseResult$1;
282
+ function createSpanTree(parseResult, options) {
283
+ const { firstSpanStart, lastSpanEnd, spans, unclosedStack } = parseResult;
284
284
  for (let i = unclosedStack.length - 1; i >= 0; i--) {
285
285
  const event = unclosedStack[i];
286
286
  const start = event.ts;
@@ -456,14 +456,14 @@ const defaultOptions = {
456
456
  const analyzeTrace = async ({ traceDir, options = defaultOptions }) => {
457
457
  validateOptions(options);
458
458
  const { traceFile, typesFile } = await validateTraceDir(traceDir);
459
- const nodeModulePaths$1 = getNodeModulePaths(traceFile);
459
+ const nodeModulePaths = getNodeModulePaths(traceFile);
460
460
  const spans = createSpans(traceFile);
461
461
  const hotPathsTree = createSpanTree(spans, options);
462
462
  const result = {
463
- nodeModulePaths: nodeModulePaths$1,
463
+ nodeModulePaths,
464
464
  unterminatedEvents: spans.unclosedStack.reverse(),
465
465
  hotSpots: await getHotspots(hotPathsTree, typesFile, options),
466
- duplicatePackages: await getDuplicateNodeModules(nodeModulePaths$1),
466
+ duplicatePackages: await getDuplicateNodeModules(nodeModulePaths),
467
467
  depthLimits: createDepthLimits(traceFile)
468
468
  };
469
469
  await writeFile(join(traceDir, ANALYZE_TRACE_FILENAME), JSON.stringify(result, null, 2));
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["packagePath","duplicates: DuplicatedPackage[]","packageName","nodeModulePaths","instances: DuplicatedPackageInstance[]","children: HotSpot[]","id","resolvedType","children: HotType[]","nodeModulePaths: NodeModulePaths","packageName","packagePath","nodeModulePaths","unclosedStack: TraceEvent[]","spans: EventSpan[]","parseResult","root: EventSpan","thresholdDuration: Microseconds","defaultOptions: AnalyzeTraceOptions","nodeModulePaths","result: AnalyzeTraceResult"],"sources":["../src/constants.ts","../src/depth-limits.ts","../src/get-duplicate-node-modules.ts","../src/get-hotspots.ts","../src/node-module-paths.ts","../src/spans.ts","../src/utils.ts","../src/analyze-trace.ts"],"sourcesContent":["// you may need to import this directly via ESM, otherwise Vite will complain about externalized fs dependencies\nexport const ANALYZE_TRACE_FILENAME = \"analyze-trace.json\";\n","import {\n depthLimits,\n type EventChecktypes__CheckCrossProductUnion_DepthLimit,\n type EventChecktypes__CheckTypeRelatedTo_DepthLimit,\n type EventChecktypes__GetTypeAtFlowNode_DepthLimit,\n type EventChecktypes__InstantiateType_DepthLimit,\n type EventChecktypes__RecursiveTypeRelatedTo_DepthLimit,\n type EventChecktypes__RemoveSubtypes_DepthLimit,\n type EventChecktypes__TraceUnionsOrIntersectionsTooLarge_DepthLimit,\n type EventChecktypes__TypeRelatedToDiscriminatedType_DepthLimit,\n event_checktypes__checkCrossProductUnion_DepthLimit,\n event_checktypes__checkTypeRelatedTo_DepthLimit,\n event_checktypes__getTypeAtFlowNode_DepthLimit,\n event_checktypes__instantiateType_DepthLimit,\n event_checktypes__recursiveTypeRelatedTo_DepthLimit,\n event_checktypes__removeSubtypes_DepthLimit,\n event_checktypes__traceUnionsOrIntersectionsTooLarge_DepthLimit,\n event_checktypes__typeRelatedToDiscriminatedType_DepthLimit,\n type TraceJsonSchema,\n} from \"@typeslayer/validate\";\n\nexport type DepthLimitsRecord = {\n checkCrossProductUnion_DepthLimit: EventChecktypes__CheckCrossProductUnion_DepthLimit[];\n checkTypeRelatedTo_DepthLimit: EventChecktypes__CheckTypeRelatedTo_DepthLimit[];\n getTypeAtFlowNode_DepthLimit: EventChecktypes__GetTypeAtFlowNode_DepthLimit[];\n instantiateType_DepthLimit: EventChecktypes__InstantiateType_DepthLimit[];\n recursiveTypeRelatedTo_DepthLimit: EventChecktypes__RecursiveTypeRelatedTo_DepthLimit[];\n removeSubtypes_DepthLimit: EventChecktypes__RemoveSubtypes_DepthLimit[];\n traceUnionsOrIntersectionsTooLarge_DepthLimit: EventChecktypes__TraceUnionsOrIntersectionsTooLarge_DepthLimit[];\n typeRelatedToDiscriminatedType_DepthLimit: EventChecktypes__TypeRelatedToDiscriminatedType_DepthLimit[];\n};\n\nexport const createDepthLimits = (traceFile: TraceJsonSchema) => {\n const limitNamesSet = new Set(\n depthLimits.map(d => d.shape.name),\n ) as unknown as Set<string>;\n const limitEvents = traceFile.filter(event => limitNamesSet.has(event.name));\n\n return {\n checkCrossProductUnion_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__checkCrossProductUnion_DepthLimit.safeParse(event)\n .success,\n ) as EventChecktypes__CheckCrossProductUnion_DepthLimit[]\n ).sort((a, b) => a.args.size - b.args.size),\n\n checkTypeRelatedTo_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__checkTypeRelatedTo_DepthLimit.safeParse(event)\n .success,\n ) as EventChecktypes__CheckTypeRelatedTo_DepthLimit[]\n ).sort((a, b) => a.args.depth - b.args.depth),\n\n getTypeAtFlowNode_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__getTypeAtFlowNode_DepthLimit.safeParse(event)\n .success,\n ) as EventChecktypes__GetTypeAtFlowNode_DepthLimit[]\n ).sort((a, b) => a.args.flowId - b.args.flowId),\n\n instantiateType_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__instantiateType_DepthLimit.safeParse(event).success,\n ) as EventChecktypes__InstantiateType_DepthLimit[]\n ).sort((a, b) => a.args.instantiationDepth - b.args.instantiationDepth),\n\n recursiveTypeRelatedTo_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__recursiveTypeRelatedTo_DepthLimit.safeParse(event)\n .success,\n ) as EventChecktypes__RecursiveTypeRelatedTo_DepthLimit[]\n ).sort((a, b) => a.args.depth - b.args.depth),\n\n removeSubtypes_DepthLimit: limitEvents.filter(\n event =>\n event_checktypes__removeSubtypes_DepthLimit.safeParse(event).success,\n ) as EventChecktypes__RemoveSubtypes_DepthLimit[],\n\n traceUnionsOrIntersectionsTooLarge_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__traceUnionsOrIntersectionsTooLarge_DepthLimit.safeParse(\n event,\n ).success,\n ) as EventChecktypes__TraceUnionsOrIntersectionsTooLarge_DepthLimit[]\n ).sort(\n (a, b) =>\n a.args.sourceSize * a.args.targetSize -\n b.args.sourceSize * b.args.targetSize,\n ),\n\n typeRelatedToDiscriminatedType_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__typeRelatedToDiscriminatedType_DepthLimit.safeParse(\n event,\n ).success,\n ) as EventChecktypes__TypeRelatedToDiscriminatedType_DepthLimit[]\n ).sort((a, b) => a.args.numCombinations - b.args.numCombinations),\n } satisfies DepthLimitsRecord;\n};\n","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n DuplicatedPackage,\n DuplicatedPackageInstance,\n NodeModulePaths,\n} from \"./utils\";\n\nexport async function getPackageVersion(packagePath: string) {\n const packageJsonPath = join(packagePath, \"package.json\");\n console.log(\"packageJsonPath\", packageJsonPath);\n if (!existsSync(packageJsonPath)) {\n console.warn(\n `Package.json not found at ${packageJsonPath}. This may not be a node module.`,\n );\n return \"unknown\";\n }\n const jsonString = await readFile(packageJsonPath, \"utf-8\");\n const jsonObj = JSON.parse(jsonString);\n return jsonObj.version;\n}\n\nexport const getDuplicateNodeModules = async (\n nodeModulePaths: NodeModulePaths,\n) => {\n const duplicates: DuplicatedPackage[] = [];\n for (const [packageName, packagePaths] of Object.entries(nodeModulePaths)) {\n if (packagePaths.length < 2) {\n continue;\n }\n const instances: DuplicatedPackageInstance[] = [];\n for (const packagePath of packagePaths) {\n instances.push({\n path: packagePath,\n version: await getPackageVersion(packagePath),\n });\n }\n duplicates.push({\n name: packageName,\n instances,\n });\n }\n\n return duplicates;\n};\n","import { normalize } from \"node:path\";\nimport {\n createTypeRegistry,\n type ResolvedType,\n type TypeId,\n type TypeRegistry,\n type TypesJsonSchema,\n} from \"@typeslayer/validate\";\nimport type { AnalyzeTraceOptions, EventSpan, HotSpot, HotType } from \"./utils\";\n\nexport const getHotspots = async (\n hotPathsTree: EventSpan,\n typesFile: TypesJsonSchema,\n options: AnalyzeTraceOptions,\n): Promise<HotSpot[]> =>\n getHotspotsWorker({\n span: hotPathsTree,\n currentFile: undefined,\n typeRegistry: createTypeRegistry(typesFile),\n options,\n });\n\nasync function getHotspotsWorker({\n span,\n currentFile,\n typeRegistry,\n options,\n}: {\n span: EventSpan;\n currentFile: string | undefined;\n typeRegistry: TypeRegistry;\n options: AnalyzeTraceOptions;\n}): Promise<HotSpot[]> {\n if (span.event.cat === \"check\") {\n currentFile = span.event.args.path;\n }\n\n const children: HotSpot[] = [];\n if (span.children.length) {\n // Sort slow to fast\n const sortedChildren = span.children.sort(\n (a, b) => b.duration - a.duration,\n );\n for (const child of sortedChildren) {\n children.push(\n ...(await getHotspotsWorker({\n span: child,\n currentFile,\n typeRegistry,\n options,\n })),\n );\n }\n }\n\n if (span.event.name !== \"root\") {\n const hotFrame = await makeHotFrame({\n span,\n children,\n typeRegistry,\n });\n if (hotFrame) {\n return [hotFrame];\n }\n }\n\n return children;\n}\n\nconst notFound = {\n children: [],\n resolvedType: {\n id: -1,\n display: \"[Type Not Found]\",\n flags: [],\n },\n} satisfies HotType;\n\nfunction getHotType({\n id,\n typeRegistry,\n}: {\n id: number;\n typeRegistry: TypeRegistry;\n}): HotType {\n function worker(id: TypeId, ancestorIds: TypeId[]): HotType {\n if (id === -1) {\n return notFound;\n }\n\n const resolvedType = typeRegistry[id];\n\n if (!resolvedType) {\n throw new Error(`Type ${id} not found`);\n }\n\n const children: HotType[] = [];\n\n // If there's a cycle, suppress the children, but not the type itself\n if (ancestorIds.indexOf(id) < 0) {\n ancestorIds.push(id);\n\n const properties = Object.keys(resolvedType) as (keyof ResolvedType)[];\n for (const property of properties) {\n switch (property) {\n case \"aliasTypeArguments\":\n case \"intersectionTypes\":\n case \"typeArguments\":\n case \"unionTypes\": {\n const typeIds = resolvedType[property];\n if (!Array.isArray(typeIds)) {\n throw new Error(`Expected array for ${property}`);\n }\n for (const typeId of typeIds) {\n const child = worker(typeId, ancestorIds);\n if (child) {\n children.push(child);\n }\n }\n continue;\n }\n\n case \"aliasType\":\n case \"conditionalCheckType\":\n case \"conditionalExtendsType\":\n case \"conditionalFalseType\":\n case \"conditionalTrueType\":\n case \"constraintType\":\n case \"evolvingArrayElementType\":\n case \"evolvingArrayFinalType\":\n case \"indexedAccessIndexType\":\n case \"indexedAccessObjectType\":\n case \"instantiatedType\":\n case \"keyofType\":\n case \"reverseMappedConstraintType\":\n case \"reverseMappedMappedType\":\n case \"reverseMappedSourceType\":\n case \"substitutionBaseType\": {\n const typeId = resolvedType[property] as TypeId;\n const child = worker(typeId, ancestorIds);\n if (child) {\n children.push(child);\n }\n break;\n }\n\n case \"destructuringPattern\":\n case \"display\":\n case \"firstDeclaration\":\n case \"flags\":\n case \"id\":\n case \"intrinsicName\":\n case \"isTuple\":\n case \"recursionId\":\n case \"referenceLocation\":\n case \"symbolName\":\n break;\n\n default:\n property satisfies never;\n throw new Error(`Unexpected property ${property}`);\n }\n }\n ancestorIds.pop();\n }\n\n return {\n resolvedType,\n children,\n };\n }\n\n return worker(id, []);\n}\n\nasync function makeHotFrame({\n span,\n children,\n typeRegistry,\n}: {\n span: EventSpan;\n children: HotSpot[];\n typeRegistry: TypeRegistry;\n}): Promise<HotSpot | undefined> {\n const { event, duration, start, end } = span;\n\n switch (event.name) {\n // case \"findSourceFile\":\n // (https://github.com/microsoft/typescript-analyze-trace/issues/2)\n\n case \"checkSourceFile\": {\n const filePath = event.args.path;\n const normalizedPath = normalize(filePath);\n return {\n description: `Check file ${normalizedPath}`,\n start,\n end,\n duration,\n path: normalizedPath,\n\n children,\n };\n }\n\n case \"structuredTypeRelatedTo\":\n return {\n description: `Compare types ${event.args.sourceId} and ${event.args.targetId}`,\n start,\n end,\n duration,\n children,\n types: [\n getHotType({\n id: event.args.sourceId,\n typeRegistry,\n }),\n getHotType({\n id: event.args.targetId,\n typeRegistry,\n }),\n ],\n };\n\n case \"getVariancesWorker\":\n return {\n description: `Determine variance of type ${event.args.id}`,\n start,\n end,\n duration,\n children,\n types: [getHotType({ id: event.args.id, typeRegistry })],\n };\n\n case \"checkExpression\":\n case \"checkVariableDeclaration\": {\n const filePath = event.args.path;\n const path = filePath ? { path: normalize(filePath) } : {};\n const frame: HotSpot = {\n description: event.name,\n start,\n end,\n duration,\n ...path,\n children: [],\n };\n return frame;\n }\n\n default:\n return undefined;\n }\n}\n","import {\n packageNameRegex,\n type TraceEvent,\n type TraceJsonSchema,\n} from \"@typeslayer/validate\";\nimport type { NodeModulePaths } from \"./utils\";\n\nexport function getNodeModulePaths(\n traceJson: TraceJsonSchema,\n): NodeModulePaths {\n const nodeModulePaths: NodeModulePaths = {};\n traceJson.forEach((event: TraceEvent) => {\n if (event.name !== \"findSourceFile\") {\n return;\n }\n const path = event.args.fileName;\n if (path) {\n while (true) {\n const match = packageNameRegex.exec(path);\n if (!match) {\n break;\n }\n const packageName = match[1];\n\n const packagePath = match.input.substring(\n 0,\n match.index + match[0].length,\n );\n\n if (packageName in nodeModulePaths) {\n const paths = nodeModulePaths[packageName];\n if (paths && paths.indexOf(packagePath) < 0) {\n // Usually contains exactly one element\n paths.push(packagePath);\n }\n } else {\n nodeModulePaths[packageName] = [packagePath];\n }\n }\n }\n });\n\n return nodeModulePaths;\n}\n","import {\n eventPhase,\n type TraceEvent,\n type TraceJsonSchema,\n} from \"@typeslayer/validate\";\nimport type {\n AnalyzeTraceOptions,\n EventSpan,\n Microseconds,\n ParseResult,\n} from \"./utils\";\n\n/*\n * This function takes an array of trace events and converts them into spans.\n */\nexport function createSpans(traceFile: TraceJsonSchema): ParseResult {\n // Sorted in increasing order of start time (even when below timestamp resolution)\n const unclosedStack: TraceEvent[] = [];\n\n // Sorted in increasing order of end time, then increasing order of start time (even when below timestamp resolution)\n const spans: EventSpan[] = [];\n\n traceFile.forEach((event: TraceEvent) => {\n switch (event.ph) {\n case eventPhase.begin:\n unclosedStack.push(event);\n return;\n\n case eventPhase.end: {\n const beginEvent = unclosedStack.pop();\n if (!beginEvent) {\n throw new Error(\"Unmatched end event\");\n }\n spans.push({\n event: beginEvent,\n start: beginEvent.ts,\n end: event.ts,\n duration: event.ts - beginEvent.ts,\n children: [],\n });\n break;\n }\n\n case eventPhase.complete: {\n const start = event.ts;\n const duration = event.dur ?? 0;\n spans.push({\n event,\n start,\n end: start + duration,\n duration,\n children: [],\n });\n break;\n }\n\n case eventPhase.instantGlobal:\n case eventPhase.metadata:\n return;\n\n default:\n event satisfies never;\n }\n });\n\n const parseResult: ParseResult = {\n firstSpanStart: Math.min(...spans.map(span => span.start)),\n lastSpanEnd: Math.max(...spans.map(span => span.end)),\n spans,\n unclosedStack,\n };\n return parseResult;\n}\n\nexport function createSpanTree(\n parseResult: ParseResult,\n options: AnalyzeTraceOptions,\n): EventSpan {\n const { firstSpanStart, lastSpanEnd, spans, unclosedStack } = parseResult;\n\n // Add unclosed events to the spans\n for (let i = unclosedStack.length - 1; i >= 0; i--) {\n const event = unclosedStack[i];\n const start = event.ts;\n const end = lastSpanEnd;\n spans.push({\n event,\n start,\n end,\n duration: end - start,\n children: [],\n });\n }\n\n spans.sort((a, b) => a.start - b.start);\n\n const root: EventSpan = {\n event: {\n name: \"root\",\n cat: \"program\",\n },\n start: firstSpanStart,\n end: lastSpanEnd,\n duration: lastSpanEnd - firstSpanStart,\n children: [],\n };\n const stack = [root];\n\n for (const span of spans) {\n let i = stack.length - 1;\n for (; i > 0; i--) {\n // No need to check root at stack[0]\n const curr = stack[i];\n if (curr.end > span.start) {\n // Pop down to parent\n stack.length = i + 1;\n break;\n }\n }\n\n /** Microseconds */\n const thresholdDuration: Microseconds = options.forceMillis * 1000;\n const isAboveThresholdDuration = span.duration >= thresholdDuration;\n\n const parent = stack[i];\n const parentDuration = parent.end - parent.start;\n const isSignificantPortionOfParent =\n span.duration >= parentDuration * options.minSpanParentPercentage;\n\n if (isAboveThresholdDuration || isSignificantPortionOfParent) {\n parent.children.push(span);\n stack.push(span);\n }\n }\n\n return root;\n}\n","import { existsSync } from \"node:fs\";\nimport { stat } from \"node:fs/promises\";\nimport {\n event_checktypes__checkCrossProductUnion_DepthLimit,\n event_checktypes__checkTypeRelatedTo_DepthLimit,\n event_checktypes__getTypeAtFlowNode_DepthLimit,\n event_checktypes__instantiateType_DepthLimit,\n event_checktypes__recursiveTypeRelatedTo_DepthLimit,\n event_checktypes__removeSubtypes_DepthLimit,\n event_checktypes__traceUnionsOrIntersectionsTooLarge_DepthLimit,\n event_checktypes__typeRelatedToDiscriminatedType_DepthLimit,\n resolvedType,\n traceEvent,\n} from \"@typeslayer/validate\";\nimport { z } from \"zod/v4\";\n\nexport const absolutePath = z.string().refine(\n path => {\n return (\n path.startsWith(\"/\") || path.startsWith(\"C:\\\\\") || path.startsWith(\"D:\\\\\")\n );\n },\n {\n message: \"Path must be absolute\",\n },\n);\nexport type AbsolutePath = z.infer<typeof absolutePath>;\n\nexport const project = z.object({\n configFilePath: absolutePath.optional(),\n tracePath: absolutePath,\n typesPath: absolutePath,\n});\nexport type Project = z.infer<typeof project>;\n\nexport const projectResult = z.object({\n project: project,\n stdout: z.string(),\n stderr: z.string(),\n exitCode: z.number().optional(),\n signal: z.enum([\"SIGINT\", \"SIGTERM\"]).optional(),\n});\nexport type ProjectResult = z.infer<typeof projectResult>;\n\nexport const hotType = z.object({\n resolvedType: resolvedType,\n get children() {\n return z.array(hotType);\n },\n});\nexport type HotType = z.infer<typeof hotType>;\n\nexport const hotSpot = z.object({\n description: z.string(),\n duration: z.number(),\n start: z.number(),\n end: z.number(),\n get children() {\n return z.array(hotSpot);\n },\n\n path: absolutePath.optional(),\n types: z.array(hotType).optional(),\n startLine: z.number().optional(),\n startChar: z.number().optional(),\n startOffset: z.number().optional(),\n endLine: z.number().optional(),\n endChar: z.number().optional(),\n endOffset: z.number().optional(),\n});\nexport type HotSpot = z.infer<typeof hotSpot>;\n\nexport const duplicatedPackageInstance = z.object({\n path: absolutePath,\n version: z.string(),\n});\nexport type DuplicatedPackageInstance = z.infer<\n typeof duplicatedPackageInstance\n>;\n\nexport const duplicatedPackage = z.object({\n name: z.string(),\n instances: z.array(duplicatedPackageInstance),\n});\nexport type DuplicatedPackage = z.infer<typeof duplicatedPackage>;\n\nexport const rootSpan = z.object({\n name: z.literal(\"root\"),\n cat: z.literal(\"program\"),\n});\nexport type RootSpan = z.infer<typeof rootSpan>;\n\nexport const eventSpan = z.object({\n event: z.union([traceEvent, rootSpan]),\n start: z.number(),\n end: z.number(),\n duration: z.number(),\n get children() {\n return z.array(eventSpan);\n },\n});\nexport type EventSpan = z.infer<typeof eventSpan>;\n\nexport const microseconds = z.number();\nexport type Microseconds = z.infer<typeof microseconds>;\n\nexport const packageName = z.string();\n\nexport const packagePath = z.string();\n\nexport const nodeModulePaths = z.record(packageName, z.array(packagePath));\n/** This is a map where the key corresponds to an NPM package and the value is an array of all files in that package that were used */\nexport type NodeModulePaths = z.infer<typeof nodeModulePaths>;\n\nexport const parseResult = z.object({\n firstSpanStart: z.number(),\n lastSpanEnd: z.number(),\n spans: z.array(eventSpan),\n unclosedStack: z.array(traceEvent),\n});\nexport type ParseResult = z.infer<typeof parseResult>;\n\nexport const analyzeTraceOptions = z.object({\n /** Events of at least this duration (in milliseconds) will reported unconditionally */\n forceMillis: z.number(),\n /** Events of less than this duration (in milliseconds) will suppressed unconditionally */\n skipMillis: z.number(),\n /** Expand types when printing */\n expandTypes: z.boolean(),\n /** force showing spans that are some percentage of their parent, independent of parent time */\n minSpanParentPercentage: z.number(),\n /** the minimum number of emitted imports from a declaration file or bundle */\n importExpressionThreshold: z.number(),\n});\nexport type AnalyzeTraceOptions = z.infer<typeof analyzeTraceOptions>;\n\nexport const isFile = async (path: string) => {\n return stat(path)\n .then(stats => stats.isFile())\n .catch(_ => false);\n};\n\nexport const throwIfNotDirectory = async (path: string) => {\n if (!existsSync(path) || !(await stat(path))?.isDirectory()) {\n throw new Error(`${path} is not a directory`);\n }\n return path;\n};\n\nexport const analyzeTraceResult = z.object({\n /** Events that were not closed */\n unterminatedEvents: z.array(traceEvent),\n /** Hot spots in the trace */\n hotSpots: z.array(hotSpot),\n /** Packages that are duplicated in the trace */\n duplicatePackages: z.array(duplicatedPackage),\n /** Paths to all node modules used in the trace */\n nodeModulePaths: nodeModulePaths,\n /** Depth limit events grouped by their event name */\n depthLimits: z.object({\n checkCrossProductUnion_DepthLimit: z.array(\n event_checktypes__checkCrossProductUnion_DepthLimit,\n ),\n checkTypeRelatedTo_DepthLimit: z.array(\n event_checktypes__checkTypeRelatedTo_DepthLimit,\n ),\n getTypeAtFlowNode_DepthLimit: z.array(\n event_checktypes__getTypeAtFlowNode_DepthLimit,\n ),\n instantiateType_DepthLimit: z.array(\n event_checktypes__instantiateType_DepthLimit,\n ),\n recursiveTypeRelatedTo_DepthLimit: z.array(\n event_checktypes__recursiveTypeRelatedTo_DepthLimit,\n ),\n removeSubtypes_DepthLimit: z.array(\n event_checktypes__removeSubtypes_DepthLimit,\n ),\n traceUnionsOrIntersectionsTooLarge_DepthLimit: z.array(\n event_checktypes__traceUnionsOrIntersectionsTooLarge_DepthLimit,\n ),\n typeRelatedToDiscriminatedType_DepthLimit: z.array(\n event_checktypes__typeRelatedToDiscriminatedType_DepthLimit,\n ),\n }),\n});\nexport type AnalyzeTraceResult = z.infer<typeof analyzeTraceResult>;\n","import { existsSync } from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n TRACE_JSON_FILENAME,\n type TraceJsonSchema,\n TYPES_JSON_FILENAME,\n type TypesJsonSchema,\n traceJsonSchema,\n typesJsonSchema,\n} from \"@typeslayer/validate\";\nimport { ANALYZE_TRACE_FILENAME } from \"./constants\";\nimport { createDepthLimits } from \"./depth-limits\";\nimport { getDuplicateNodeModules } from \"./get-duplicate-node-modules\";\nimport { getHotspots } from \"./get-hotspots\";\nimport { getNodeModulePaths } from \"./node-module-paths\";\nimport { createSpans, createSpanTree } from \"./spans\";\nimport type { AnalyzeTraceResult } from \"./utils\";\nimport {\n type AbsolutePath,\n type AnalyzeTraceOptions,\n throwIfNotDirectory,\n} from \"./utils\";\n\nexport function validateOptions(options: AnalyzeTraceOptions) {\n if (options.forceMillis < options.skipMillis) {\n throw new Error(\"forceMillis cannot be less than skipMillis\");\n }\n}\n\nconst validateTraceDir = async (\n traceDir: AbsolutePath,\n): Promise<{\n traceFile: TraceJsonSchema;\n typesFile: TypesJsonSchema;\n}> => {\n await throwIfNotDirectory(traceDir);\n\n const typesFilePath = join(traceDir, TYPES_JSON_FILENAME);\n if (!existsSync(typesFilePath)) {\n throw new Error(\n `types.json must exist in ${traceDir}. first run --generateTrace`,\n );\n }\n const typesFileJson = JSON.parse(await readFile(typesFilePath, \"utf8\"));\n const typesFile = typesJsonSchema.parse(typesFileJson);\n\n const traceFilePath = join(traceDir, TRACE_JSON_FILENAME);\n if (!existsSync(traceFilePath)) {\n throw new Error(\n `trace.json must exist in ${traceDir}. first run --generateTrace`,\n );\n }\n const traceFileJson = JSON.parse(await readFile(traceFilePath, \"utf8\"));\n const traceFile = traceJsonSchema.parse(traceFileJson);\n\n return {\n traceFile,\n typesFile,\n };\n};\n\nexport const defaultOptions: AnalyzeTraceOptions = {\n forceMillis: 500,\n skipMillis: 100,\n expandTypes: true,\n minSpanParentPercentage: 0.6,\n importExpressionThreshold: 10,\n};\n\nexport const analyzeTrace = async ({\n traceDir,\n options = defaultOptions,\n}: {\n traceDir: AbsolutePath;\n options?: AnalyzeTraceOptions;\n}) => {\n validateOptions(options);\n const { traceFile, typesFile } = await validateTraceDir(traceDir);\n\n const nodeModulePaths = getNodeModulePaths(traceFile);\n\n const spans = createSpans(traceFile);\n const hotPathsTree = createSpanTree(spans, options);\n\n const result: AnalyzeTraceResult = {\n nodeModulePaths,\n unterminatedEvents: spans.unclosedStack.reverse(),\n hotSpots: await getHotspots(hotPathsTree, typesFile, options),\n duplicatePackages: await getDuplicateNodeModules(nodeModulePaths),\n depthLimits: createDepthLimits(traceFile),\n };\n await writeFile(\n join(traceDir, ANALYZE_TRACE_FILENAME),\n JSON.stringify(result, null, 2),\n );\n\n return result;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/constants.ts","../src/depth-limits.ts","../src/get-duplicate-node-modules.ts","../src/get-hotspots.ts","../src/node-module-paths.ts","../src/spans.ts","../src/utils.ts","../src/analyze-trace.ts"],"sourcesContent":["// you may need to import this directly via ESM, otherwise Vite will complain about externalized fs dependencies\nexport const ANALYZE_TRACE_FILENAME = \"analyze-trace.json\";\n","import {\n depthLimits,\n type EventChecktypes__CheckCrossProductUnion_DepthLimit,\n type EventChecktypes__CheckTypeRelatedTo_DepthLimit,\n type EventChecktypes__GetTypeAtFlowNode_DepthLimit,\n type EventChecktypes__InstantiateType_DepthLimit,\n type EventChecktypes__RecursiveTypeRelatedTo_DepthLimit,\n type EventChecktypes__RemoveSubtypes_DepthLimit,\n type EventChecktypes__TraceUnionsOrIntersectionsTooLarge_DepthLimit,\n type EventChecktypes__TypeRelatedToDiscriminatedType_DepthLimit,\n event_checktypes__checkCrossProductUnion_DepthLimit,\n event_checktypes__checkTypeRelatedTo_DepthLimit,\n event_checktypes__getTypeAtFlowNode_DepthLimit,\n event_checktypes__instantiateType_DepthLimit,\n event_checktypes__recursiveTypeRelatedTo_DepthLimit,\n event_checktypes__removeSubtypes_DepthLimit,\n event_checktypes__traceUnionsOrIntersectionsTooLarge_DepthLimit,\n event_checktypes__typeRelatedToDiscriminatedType_DepthLimit,\n type TraceJsonSchema,\n} from \"@typeslayer/validate\";\n\nexport type DepthLimitsRecord = {\n checkCrossProductUnion_DepthLimit: EventChecktypes__CheckCrossProductUnion_DepthLimit[];\n checkTypeRelatedTo_DepthLimit: EventChecktypes__CheckTypeRelatedTo_DepthLimit[];\n getTypeAtFlowNode_DepthLimit: EventChecktypes__GetTypeAtFlowNode_DepthLimit[];\n instantiateType_DepthLimit: EventChecktypes__InstantiateType_DepthLimit[];\n recursiveTypeRelatedTo_DepthLimit: EventChecktypes__RecursiveTypeRelatedTo_DepthLimit[];\n removeSubtypes_DepthLimit: EventChecktypes__RemoveSubtypes_DepthLimit[];\n traceUnionsOrIntersectionsTooLarge_DepthLimit: EventChecktypes__TraceUnionsOrIntersectionsTooLarge_DepthLimit[];\n typeRelatedToDiscriminatedType_DepthLimit: EventChecktypes__TypeRelatedToDiscriminatedType_DepthLimit[];\n};\n\nexport const createDepthLimits = (traceFile: TraceJsonSchema) => {\n const limitNamesSet = new Set(\n depthLimits.map(d => d.shape.name),\n ) as unknown as Set<string>;\n const limitEvents = traceFile.filter(event => limitNamesSet.has(event.name));\n\n return {\n checkCrossProductUnion_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__checkCrossProductUnion_DepthLimit.safeParse(event)\n .success,\n ) as EventChecktypes__CheckCrossProductUnion_DepthLimit[]\n ).sort((a, b) => a.args.size - b.args.size),\n\n checkTypeRelatedTo_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__checkTypeRelatedTo_DepthLimit.safeParse(event)\n .success,\n ) as EventChecktypes__CheckTypeRelatedTo_DepthLimit[]\n ).sort((a, b) => a.args.depth - b.args.depth),\n\n getTypeAtFlowNode_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__getTypeAtFlowNode_DepthLimit.safeParse(event)\n .success,\n ) as EventChecktypes__GetTypeAtFlowNode_DepthLimit[]\n ).sort((a, b) => a.args.flowId - b.args.flowId),\n\n instantiateType_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__instantiateType_DepthLimit.safeParse(event).success,\n ) as EventChecktypes__InstantiateType_DepthLimit[]\n ).sort((a, b) => a.args.instantiationDepth - b.args.instantiationDepth),\n\n recursiveTypeRelatedTo_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__recursiveTypeRelatedTo_DepthLimit.safeParse(event)\n .success,\n ) as EventChecktypes__RecursiveTypeRelatedTo_DepthLimit[]\n ).sort((a, b) => a.args.depth - b.args.depth),\n\n removeSubtypes_DepthLimit: limitEvents.filter(\n event =>\n event_checktypes__removeSubtypes_DepthLimit.safeParse(event).success,\n ) as EventChecktypes__RemoveSubtypes_DepthLimit[],\n\n traceUnionsOrIntersectionsTooLarge_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__traceUnionsOrIntersectionsTooLarge_DepthLimit.safeParse(\n event,\n ).success,\n ) as EventChecktypes__TraceUnionsOrIntersectionsTooLarge_DepthLimit[]\n ).sort(\n (a, b) =>\n a.args.sourceSize * a.args.targetSize -\n b.args.sourceSize * b.args.targetSize,\n ),\n\n typeRelatedToDiscriminatedType_DepthLimit: (\n limitEvents.filter(\n event =>\n event_checktypes__typeRelatedToDiscriminatedType_DepthLimit.safeParse(\n event,\n ).success,\n ) as EventChecktypes__TypeRelatedToDiscriminatedType_DepthLimit[]\n ).sort((a, b) => a.args.numCombinations - b.args.numCombinations),\n } satisfies DepthLimitsRecord;\n};\n","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n DuplicatedPackage,\n DuplicatedPackageInstance,\n NodeModulePaths,\n} from \"./utils\";\n\nexport async function getPackageVersion(packagePath: string) {\n const packageJsonPath = join(packagePath, \"package.json\");\n console.log(\"packageJsonPath\", packageJsonPath);\n if (!existsSync(packageJsonPath)) {\n console.warn(\n `Package.json not found at ${packageJsonPath}. This may not be a node module.`,\n );\n return \"unknown\";\n }\n const jsonString = await readFile(packageJsonPath, \"utf-8\");\n const jsonObj = JSON.parse(jsonString);\n return jsonObj.version;\n}\n\nexport const getDuplicateNodeModules = async (\n nodeModulePaths: NodeModulePaths,\n) => {\n const duplicates: DuplicatedPackage[] = [];\n for (const [packageName, packagePaths] of Object.entries(nodeModulePaths)) {\n if (packagePaths.length < 2) {\n continue;\n }\n const instances: DuplicatedPackageInstance[] = [];\n for (const packagePath of packagePaths) {\n instances.push({\n path: packagePath,\n version: await getPackageVersion(packagePath),\n });\n }\n duplicates.push({\n name: packageName,\n instances,\n });\n }\n\n return duplicates;\n};\n","import { normalize } from \"node:path\";\nimport {\n createTypeRegistry,\n type ResolvedType,\n type TypeId,\n type TypeRegistry,\n type TypesJsonSchema,\n} from \"@typeslayer/validate\";\nimport type { AnalyzeTraceOptions, EventSpan, HotSpot, HotType } from \"./utils\";\n\nexport const getHotspots = async (\n hotPathsTree: EventSpan,\n typesFile: TypesJsonSchema,\n options: AnalyzeTraceOptions,\n): Promise<HotSpot[]> =>\n getHotspotsWorker({\n span: hotPathsTree,\n currentFile: undefined,\n typeRegistry: createTypeRegistry(typesFile),\n options,\n });\n\nasync function getHotspotsWorker({\n span,\n currentFile,\n typeRegistry,\n options,\n}: {\n span: EventSpan;\n currentFile: string | undefined;\n typeRegistry: TypeRegistry;\n options: AnalyzeTraceOptions;\n}): Promise<HotSpot[]> {\n if (span.event.cat === \"check\") {\n currentFile = span.event.args.path;\n }\n\n const children: HotSpot[] = [];\n if (span.children.length) {\n // Sort slow to fast\n const sortedChildren = span.children.sort(\n (a, b) => b.duration - a.duration,\n );\n for (const child of sortedChildren) {\n children.push(\n ...(await getHotspotsWorker({\n span: child,\n currentFile,\n typeRegistry,\n options,\n })),\n );\n }\n }\n\n if (span.event.name !== \"root\") {\n const hotFrame = await makeHotFrame({\n span,\n children,\n typeRegistry,\n });\n if (hotFrame) {\n return [hotFrame];\n }\n }\n\n return children;\n}\n\nconst notFound = {\n children: [],\n resolvedType: {\n id: -1,\n display: \"[Type Not Found]\",\n flags: [],\n },\n} satisfies HotType;\n\nfunction getHotType({\n id,\n typeRegistry,\n}: {\n id: number;\n typeRegistry: TypeRegistry;\n}): HotType {\n function worker(id: TypeId, ancestorIds: TypeId[]): HotType {\n if (id === -1) {\n return notFound;\n }\n\n const resolvedType = typeRegistry[id];\n\n if (!resolvedType) {\n throw new Error(`Type ${id} not found`);\n }\n\n const children: HotType[] = [];\n\n // If there's a cycle, suppress the children, but not the type itself\n if (ancestorIds.indexOf(id) < 0) {\n ancestorIds.push(id);\n\n const properties = Object.keys(resolvedType) as (keyof ResolvedType)[];\n for (const property of properties) {\n switch (property) {\n case \"aliasTypeArguments\":\n case \"intersectionTypes\":\n case \"typeArguments\":\n case \"unionTypes\": {\n const typeIds = resolvedType[property];\n if (!Array.isArray(typeIds)) {\n throw new Error(`Expected array for ${property}`);\n }\n for (const typeId of typeIds) {\n const child = worker(typeId, ancestorIds);\n if (child) {\n children.push(child);\n }\n }\n continue;\n }\n\n case \"aliasType\":\n case \"conditionalCheckType\":\n case \"conditionalExtendsType\":\n case \"conditionalFalseType\":\n case \"conditionalTrueType\":\n case \"constraintType\":\n case \"evolvingArrayElementType\":\n case \"evolvingArrayFinalType\":\n case \"indexedAccessIndexType\":\n case \"indexedAccessObjectType\":\n case \"instantiatedType\":\n case \"keyofType\":\n case \"reverseMappedConstraintType\":\n case \"reverseMappedMappedType\":\n case \"reverseMappedSourceType\":\n case \"substitutionBaseType\": {\n const typeId = resolvedType[property] as TypeId;\n const child = worker(typeId, ancestorIds);\n if (child) {\n children.push(child);\n }\n break;\n }\n\n case \"destructuringPattern\":\n case \"display\":\n case \"firstDeclaration\":\n case \"flags\":\n case \"id\":\n case \"intrinsicName\":\n case \"isTuple\":\n case \"recursionId\":\n case \"referenceLocation\":\n case \"symbolName\":\n break;\n\n default:\n property satisfies never;\n throw new Error(`Unexpected property ${property}`);\n }\n }\n ancestorIds.pop();\n }\n\n return {\n resolvedType,\n children,\n };\n }\n\n return worker(id, []);\n}\n\nasync function makeHotFrame({\n span,\n children,\n typeRegistry,\n}: {\n span: EventSpan;\n children: HotSpot[];\n typeRegistry: TypeRegistry;\n}): Promise<HotSpot | undefined> {\n const { event, duration, start, end } = span;\n\n switch (event.name) {\n // case \"findSourceFile\":\n // (https://github.com/microsoft/typescript-analyze-trace/issues/2)\n\n case \"checkSourceFile\": {\n const filePath = event.args.path;\n const normalizedPath = normalize(filePath);\n return {\n description: `Check file ${normalizedPath}`,\n start,\n end,\n duration,\n path: normalizedPath,\n\n children,\n };\n }\n\n case \"structuredTypeRelatedTo\":\n return {\n description: `Compare types ${event.args.sourceId} and ${event.args.targetId}`,\n start,\n end,\n duration,\n children,\n types: [\n getHotType({\n id: event.args.sourceId,\n typeRegistry,\n }),\n getHotType({\n id: event.args.targetId,\n typeRegistry,\n }),\n ],\n };\n\n case \"getVariancesWorker\":\n return {\n description: `Determine variance of type ${event.args.id}`,\n start,\n end,\n duration,\n children,\n types: [getHotType({ id: event.args.id, typeRegistry })],\n };\n\n case \"checkExpression\":\n case \"checkVariableDeclaration\": {\n const filePath = event.args.path;\n const path = filePath ? { path: normalize(filePath) } : {};\n const frame: HotSpot = {\n description: event.name,\n start,\n end,\n duration,\n ...path,\n children: [],\n };\n return frame;\n }\n\n default:\n return undefined;\n }\n}\n","import {\n packageNameRegex,\n type TraceEvent,\n type TraceJsonSchema,\n} from \"@typeslayer/validate\";\nimport type { NodeModulePaths } from \"./utils\";\n\nexport function getNodeModulePaths(\n traceJson: TraceJsonSchema,\n): NodeModulePaths {\n const nodeModulePaths: NodeModulePaths = {};\n traceJson.forEach((event: TraceEvent) => {\n if (event.name !== \"findSourceFile\") {\n return;\n }\n const path = event.args.fileName;\n if (path) {\n while (true) {\n const match = packageNameRegex.exec(path);\n if (!match) {\n break;\n }\n const packageName = match[1];\n\n const packagePath = match.input.substring(\n 0,\n match.index + match[0].length,\n );\n\n if (packageName in nodeModulePaths) {\n const paths = nodeModulePaths[packageName];\n if (paths && paths.indexOf(packagePath) < 0) {\n // Usually contains exactly one element\n paths.push(packagePath);\n }\n } else {\n nodeModulePaths[packageName] = [packagePath];\n }\n }\n }\n });\n\n return nodeModulePaths;\n}\n","import {\n eventPhase,\n type TraceEvent,\n type TraceJsonSchema,\n} from \"@typeslayer/validate\";\nimport type {\n AnalyzeTraceOptions,\n EventSpan,\n Microseconds,\n ParseResult,\n} from \"./utils\";\n\n/*\n * This function takes an array of trace events and converts them into spans.\n */\nexport function createSpans(traceFile: TraceJsonSchema): ParseResult {\n // Sorted in increasing order of start time (even when below timestamp resolution)\n const unclosedStack: TraceEvent[] = [];\n\n // Sorted in increasing order of end time, then increasing order of start time (even when below timestamp resolution)\n const spans: EventSpan[] = [];\n\n traceFile.forEach((event: TraceEvent) => {\n switch (event.ph) {\n case eventPhase.begin:\n unclosedStack.push(event);\n return;\n\n case eventPhase.end: {\n const beginEvent = unclosedStack.pop();\n if (!beginEvent) {\n throw new Error(\"Unmatched end event\");\n }\n spans.push({\n event: beginEvent,\n start: beginEvent.ts,\n end: event.ts,\n duration: event.ts - beginEvent.ts,\n children: [],\n });\n break;\n }\n\n case eventPhase.complete: {\n const start = event.ts;\n const duration = event.dur ?? 0;\n spans.push({\n event,\n start,\n end: start + duration,\n duration,\n children: [],\n });\n break;\n }\n\n case eventPhase.instantGlobal:\n case eventPhase.metadata:\n return;\n\n default:\n event satisfies never;\n }\n });\n\n const parseResult: ParseResult = {\n firstSpanStart: Math.min(...spans.map(span => span.start)),\n lastSpanEnd: Math.max(...spans.map(span => span.end)),\n spans,\n unclosedStack,\n };\n return parseResult;\n}\n\nexport function createSpanTree(\n parseResult: ParseResult,\n options: AnalyzeTraceOptions,\n): EventSpan {\n const { firstSpanStart, lastSpanEnd, spans, unclosedStack } = parseResult;\n\n // Add unclosed events to the spans\n for (let i = unclosedStack.length - 1; i >= 0; i--) {\n const event = unclosedStack[i];\n const start = event.ts;\n const end = lastSpanEnd;\n spans.push({\n event,\n start,\n end,\n duration: end - start,\n children: [],\n });\n }\n\n spans.sort((a, b) => a.start - b.start);\n\n const root: EventSpan = {\n event: {\n name: \"root\",\n cat: \"program\",\n },\n start: firstSpanStart,\n end: lastSpanEnd,\n duration: lastSpanEnd - firstSpanStart,\n children: [],\n };\n const stack = [root];\n\n for (const span of spans) {\n let i = stack.length - 1;\n for (; i > 0; i--) {\n // No need to check root at stack[0]\n const curr = stack[i];\n if (curr.end > span.start) {\n // Pop down to parent\n stack.length = i + 1;\n break;\n }\n }\n\n /** Microseconds */\n const thresholdDuration: Microseconds = options.forceMillis * 1000;\n const isAboveThresholdDuration = span.duration >= thresholdDuration;\n\n const parent = stack[i];\n const parentDuration = parent.end - parent.start;\n const isSignificantPortionOfParent =\n span.duration >= parentDuration * options.minSpanParentPercentage;\n\n if (isAboveThresholdDuration || isSignificantPortionOfParent) {\n parent.children.push(span);\n stack.push(span);\n }\n }\n\n return root;\n}\n","import { existsSync } from \"node:fs\";\nimport { stat } from \"node:fs/promises\";\nimport {\n event_checktypes__checkCrossProductUnion_DepthLimit,\n event_checktypes__checkTypeRelatedTo_DepthLimit,\n event_checktypes__getTypeAtFlowNode_DepthLimit,\n event_checktypes__instantiateType_DepthLimit,\n event_checktypes__recursiveTypeRelatedTo_DepthLimit,\n event_checktypes__removeSubtypes_DepthLimit,\n event_checktypes__traceUnionsOrIntersectionsTooLarge_DepthLimit,\n event_checktypes__typeRelatedToDiscriminatedType_DepthLimit,\n resolvedType,\n traceEvent,\n} from \"@typeslayer/validate\";\nimport { z } from \"zod/v4\";\n\nexport const absolutePath = z.string().refine(\n path => {\n return (\n path.startsWith(\"/\") || path.startsWith(\"C:\\\\\") || path.startsWith(\"D:\\\\\")\n );\n },\n {\n message: \"Path must be absolute\",\n },\n);\nexport type AbsolutePath = z.infer<typeof absolutePath>;\n\nexport const project = z.object({\n configFilePath: absolutePath.optional(),\n tracePath: absolutePath,\n typesPath: absolutePath,\n});\nexport type Project = z.infer<typeof project>;\n\nexport const projectResult = z.object({\n project: project,\n stdout: z.string(),\n stderr: z.string(),\n exitCode: z.number().optional(),\n signal: z.enum([\"SIGINT\", \"SIGTERM\"]).optional(),\n});\nexport type ProjectResult = z.infer<typeof projectResult>;\n\nexport const hotType = z.object({\n resolvedType: resolvedType,\n get children() {\n return z.array(hotType);\n },\n});\nexport type HotType = z.infer<typeof hotType>;\n\nexport const hotSpot = z.object({\n description: z.string(),\n duration: z.number(),\n start: z.number(),\n end: z.number(),\n get children() {\n return z.array(hotSpot);\n },\n\n path: absolutePath.optional(),\n types: z.array(hotType).optional(),\n startLine: z.number().optional(),\n startChar: z.number().optional(),\n startOffset: z.number().optional(),\n endLine: z.number().optional(),\n endChar: z.number().optional(),\n endOffset: z.number().optional(),\n});\nexport type HotSpot = z.infer<typeof hotSpot>;\n\nexport const duplicatedPackageInstance = z.object({\n path: absolutePath,\n version: z.string(),\n});\nexport type DuplicatedPackageInstance = z.infer<\n typeof duplicatedPackageInstance\n>;\n\nexport const duplicatedPackage = z.object({\n name: z.string(),\n instances: z.array(duplicatedPackageInstance),\n});\nexport type DuplicatedPackage = z.infer<typeof duplicatedPackage>;\n\nexport const rootSpan = z.object({\n name: z.literal(\"root\"),\n cat: z.literal(\"program\"),\n});\nexport type RootSpan = z.infer<typeof rootSpan>;\n\nexport const eventSpan = z.object({\n event: z.union([traceEvent, rootSpan]),\n start: z.number(),\n end: z.number(),\n duration: z.number(),\n get children() {\n return z.array(eventSpan);\n },\n});\nexport type EventSpan = z.infer<typeof eventSpan>;\n\nexport const microseconds = z.number();\nexport type Microseconds = z.infer<typeof microseconds>;\n\nexport const packageName = z.string();\n\nexport const packagePath = z.string();\n\nexport const nodeModulePaths = z.record(packageName, z.array(packagePath));\n/** This is a map where the key corresponds to an NPM package and the value is an array of all files in that package that were used */\nexport type NodeModulePaths = z.infer<typeof nodeModulePaths>;\n\nexport const parseResult = z.object({\n firstSpanStart: z.number(),\n lastSpanEnd: z.number(),\n spans: z.array(eventSpan),\n unclosedStack: z.array(traceEvent),\n});\nexport type ParseResult = z.infer<typeof parseResult>;\n\nexport const analyzeTraceOptions = z.object({\n /** Events of at least this duration (in milliseconds) will reported unconditionally */\n forceMillis: z.number(),\n /** Events of less than this duration (in milliseconds) will suppressed unconditionally */\n skipMillis: z.number(),\n /** Expand types when printing */\n expandTypes: z.boolean(),\n /** force showing spans that are some percentage of their parent, independent of parent time */\n minSpanParentPercentage: z.number(),\n /** the minimum number of emitted imports from a declaration file or bundle */\n importExpressionThreshold: z.number(),\n});\nexport type AnalyzeTraceOptions = z.infer<typeof analyzeTraceOptions>;\n\nexport const isFile = async (path: string) => {\n return stat(path)\n .then(stats => stats.isFile())\n .catch(_ => false);\n};\n\nexport const throwIfNotDirectory = async (path: string) => {\n if (!existsSync(path) || !(await stat(path))?.isDirectory()) {\n throw new Error(`${path} is not a directory`);\n }\n return path;\n};\n\nexport const analyzeTraceResult = z.object({\n /** Events that were not closed */\n unterminatedEvents: z.array(traceEvent),\n /** Hot spots in the trace */\n hotSpots: z.array(hotSpot),\n /** Packages that are duplicated in the trace */\n duplicatePackages: z.array(duplicatedPackage),\n /** Paths to all node modules used in the trace */\n nodeModulePaths: nodeModulePaths,\n /** Depth limit events grouped by their event name */\n depthLimits: z.object({\n checkCrossProductUnion_DepthLimit: z.array(\n event_checktypes__checkCrossProductUnion_DepthLimit,\n ),\n checkTypeRelatedTo_DepthLimit: z.array(\n event_checktypes__checkTypeRelatedTo_DepthLimit,\n ),\n getTypeAtFlowNode_DepthLimit: z.array(\n event_checktypes__getTypeAtFlowNode_DepthLimit,\n ),\n instantiateType_DepthLimit: z.array(\n event_checktypes__instantiateType_DepthLimit,\n ),\n recursiveTypeRelatedTo_DepthLimit: z.array(\n event_checktypes__recursiveTypeRelatedTo_DepthLimit,\n ),\n removeSubtypes_DepthLimit: z.array(\n event_checktypes__removeSubtypes_DepthLimit,\n ),\n traceUnionsOrIntersectionsTooLarge_DepthLimit: z.array(\n event_checktypes__traceUnionsOrIntersectionsTooLarge_DepthLimit,\n ),\n typeRelatedToDiscriminatedType_DepthLimit: z.array(\n event_checktypes__typeRelatedToDiscriminatedType_DepthLimit,\n ),\n }),\n});\nexport type AnalyzeTraceResult = z.infer<typeof analyzeTraceResult>;\n","import { existsSync } from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n TRACE_JSON_FILENAME,\n type TraceJsonSchema,\n TYPES_JSON_FILENAME,\n type TypesJsonSchema,\n traceJsonSchema,\n typesJsonSchema,\n} from \"@typeslayer/validate\";\nimport { ANALYZE_TRACE_FILENAME } from \"./constants\";\nimport { createDepthLimits } from \"./depth-limits\";\nimport { getDuplicateNodeModules } from \"./get-duplicate-node-modules\";\nimport { getHotspots } from \"./get-hotspots\";\nimport { getNodeModulePaths } from \"./node-module-paths\";\nimport { createSpans, createSpanTree } from \"./spans\";\nimport type { AnalyzeTraceResult } from \"./utils\";\nimport {\n type AbsolutePath,\n type AnalyzeTraceOptions,\n throwIfNotDirectory,\n} from \"./utils\";\n\nexport function validateOptions(options: AnalyzeTraceOptions) {\n if (options.forceMillis < options.skipMillis) {\n throw new Error(\"forceMillis cannot be less than skipMillis\");\n }\n}\n\nconst validateTraceDir = async (\n traceDir: AbsolutePath,\n): Promise<{\n traceFile: TraceJsonSchema;\n typesFile: TypesJsonSchema;\n}> => {\n await throwIfNotDirectory(traceDir);\n\n const typesFilePath = join(traceDir, TYPES_JSON_FILENAME);\n if (!existsSync(typesFilePath)) {\n throw new Error(\n `types.json must exist in ${traceDir}. first run --generateTrace`,\n );\n }\n const typesFileJson = JSON.parse(await readFile(typesFilePath, \"utf8\"));\n const typesFile = typesJsonSchema.parse(typesFileJson);\n\n const traceFilePath = join(traceDir, TRACE_JSON_FILENAME);\n if (!existsSync(traceFilePath)) {\n throw new Error(\n `trace.json must exist in ${traceDir}. first run --generateTrace`,\n );\n }\n const traceFileJson = JSON.parse(await readFile(traceFilePath, \"utf8\"));\n const traceFile = traceJsonSchema.parse(traceFileJson);\n\n return {\n traceFile,\n typesFile,\n };\n};\n\nexport const defaultOptions: AnalyzeTraceOptions = {\n forceMillis: 500,\n skipMillis: 100,\n expandTypes: true,\n minSpanParentPercentage: 0.6,\n importExpressionThreshold: 10,\n};\n\nexport const analyzeTrace = async ({\n traceDir,\n options = defaultOptions,\n}: {\n traceDir: AbsolutePath;\n options?: AnalyzeTraceOptions;\n}) => {\n validateOptions(options);\n const { traceFile, typesFile } = await validateTraceDir(traceDir);\n\n const nodeModulePaths = getNodeModulePaths(traceFile);\n\n const spans = createSpans(traceFile);\n const hotPathsTree = createSpanTree(spans, options);\n\n const result: AnalyzeTraceResult = {\n nodeModulePaths,\n unterminatedEvents: spans.unclosedStack.reverse(),\n hotSpots: await getHotspots(hotPathsTree, typesFile, options),\n duplicatePackages: await getDuplicateNodeModules(nodeModulePaths),\n depthLimits: createDepthLimits(traceFile),\n };\n await writeFile(\n join(traceDir, ANALYZE_TRACE_FILENAME),\n JSON.stringify(result, null, 2),\n );\n\n return result;\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typeslayer/analyze-trace",
3
- "version": "0.1.30",
3
+ "version": "0.1.32",
4
4
  "description": "Analyze TypeScript compiler trace events to identify performance bottlenecks",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -34,15 +34,15 @@
34
34
  "typeslayer-analyze-trace": "./bin/typeslayer-analyze-trace.mjs"
35
35
  },
36
36
  "dependencies": {
37
- "@mui/icons-material": "7.3.6",
38
- "@mui/material": "7.3.6",
39
- "zod": "4.2.1",
40
- "@typeslayer/validate": "0.1.30"
37
+ "@mui/icons-material": "7.3.8",
38
+ "@mui/material": "7.3.8",
39
+ "zod": "4.3.6",
40
+ "@typeslayer/validate": "0.1.32"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@arethetypeswrong/cli": "^0.18.2",
44
- "@types/node": "25.0.3",
45
- "tsdown": "0.18.3",
44
+ "@types/node": "25.3.0",
45
+ "tsdown": "0.20.3",
46
46
  "typescript": "5.9.3"
47
47
  },
48
48
  "scripts": {
package/src/browser.ts CHANGED
@@ -1,8 +1,5 @@
1
1
  // Browser-safe exports - only types and schemas, no Node.js APIs
2
- export type {
3
- TraceJsonSchema,
4
- TypesJsonSchema,
5
- } from "@typeslayer/validate";
2
+ export type { TraceJsonSchema, TypesJsonSchema } from "@typeslayer/validate";
6
3
  export { ANALYZE_TRACE_FILENAME } from "./constants";
7
4
  export type { DepthLimitsRecord } from "./depth-limits";
8
5
  export * from "./info";