@typeslayer/analyze-trace 0.1.25 → 0.1.27

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.
@@ -1,4 +1,6 @@
1
1
  import { EventChecktypes__CheckCrossProductUnion_DepthLimit, EventChecktypes__CheckTypeRelatedTo_DepthLimit, EventChecktypes__GetTypeAtFlowNode_DepthLimit, EventChecktypes__InstantiateType_DepthLimit, EventChecktypes__RecursiveTypeRelatedTo_DepthLimit, EventChecktypes__RemoveSubtypes_DepthLimit, EventChecktypes__TraceUnionsOrIntersectionsTooLarge_DepthLimit, EventChecktypes__TypeRelatedToDiscriminatedType_DepthLimit, TraceJsonSchema, TypesJsonSchema } from "@typeslayer/validate";
2
+ import * as _mui_material_SvgIcon0 from "@mui/material/SvgIcon";
3
+ import * as _mui_material_OverridableComponent0 from "@mui/material/OverridableComponent";
2
4
  import { z } from "zod/v4";
3
5
 
4
6
  //#region src/constants.d.ts
@@ -16,6 +18,26 @@ type DepthLimitsRecord = {
16
18
  typeRelatedToDiscriminatedType_DepthLimit: EventChecktypes__TypeRelatedToDiscriminatedType_DepthLimit[];
17
19
  };
18
20
  //#endregion
21
+ //#region src/info.d.ts
22
+ declare const analyzeTraceInfo: {
23
+ readonly hotSpots: {
24
+ readonly title: "Hot Spots";
25
+ readonly description: "Files or paths where the TypeScript compiler spent the most cumulative time. Use these to target expensive type-checking work for refactors.";
26
+ readonly icon: _mui_material_OverridableComponent0.OverridableComponent<_mui_material_SvgIcon0.SvgIconTypeMap<{}, "svg">> & {
27
+ muiName: string;
28
+ };
29
+ readonly route: "hot-spots";
30
+ };
31
+ readonly duplicatePackages: {
32
+ readonly title: "Duplicate Packages";
33
+ readonly description: "Packages that appear multiple times in the bundle (different install paths / versions). Consolidate to reduce size & divergence.";
34
+ readonly icon: _mui_material_OverridableComponent0.OverridableComponent<_mui_material_SvgIcon0.SvgIconTypeMap<{}, "svg">> & {
35
+ muiName: string;
36
+ };
37
+ readonly route: "duplicate-packages";
38
+ };
39
+ };
40
+ //#endregion
19
41
  //#region src/utils.d.ts
20
42
  declare const absolutePath: z.ZodString;
21
43
  type AbsolutePath = z.infer<typeof absolutePath>;
@@ -74,6 +96,8 @@ declare const hotSpot: z.ZodObject<{
74
96
  reverseMappedConstraintType: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>>;
75
97
  id: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
76
98
  flags: z.ZodArray<z.ZodEnum<{
99
+ Union: "Union";
100
+ Intersection: "Intersection";
77
101
  Any: "Any";
78
102
  Unknown: "Unknown";
79
103
  String: "String";
@@ -94,8 +118,6 @@ declare const hotSpot: z.ZodObject<{
94
118
  Never: "Never";
95
119
  TypeParameter: "TypeParameter";
96
120
  Object: "Object";
97
- Union: "Union";
98
- Intersection: "Intersection";
99
121
  Index: "Index";
100
122
  IndexedAccess: "IndexedAccess";
101
123
  Conditional: "Conditional";
@@ -2920,6 +2942,8 @@ declare const analyzeTraceResult: z.ZodObject<{
2920
2942
  reverseMappedConstraintType: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>>;
2921
2943
  id: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
2922
2944
  flags: z.ZodArray<z.ZodEnum<{
2945
+ Union: "Union";
2946
+ Intersection: "Intersection";
2923
2947
  Any: "Any";
2924
2948
  Unknown: "Unknown";
2925
2949
  String: "String";
@@ -2940,8 +2964,6 @@ declare const analyzeTraceResult: z.ZodObject<{
2940
2964
  Never: "Never";
2941
2965
  TypeParameter: "TypeParameter";
2942
2966
  Object: "Object";
2943
- Union: "Union";
2944
- Intersection: "Intersection";
2945
2967
  Index: "Index";
2946
2968
  IndexedAccess: "IndexedAccess";
2947
2969
  Conditional: "Conditional";
@@ -3182,5 +3204,5 @@ declare const analyzeTraceResult: z.ZodObject<{
3182
3204
  }, z.core.$strip>;
3183
3205
  type AnalyzeTraceResult = z.infer<typeof analyzeTraceResult>;
3184
3206
  //#endregion
3185
- export { ANALYZE_TRACE_FILENAME, type AbsolutePath, type AnalyzeTraceOptions, type AnalyzeTraceResult, type DepthLimitsRecord, type DuplicatedPackage, type DuplicatedPackageInstance, type EventSpan, type HotSpot, type Microseconds, type NodeModulePaths, type ParseResult, type Project, type ProjectResult, type RootSpan, type TraceJsonSchema, type TypesJsonSchema };
3207
+ export { ANALYZE_TRACE_FILENAME, type AbsolutePath, type AnalyzeTraceOptions, type AnalyzeTraceResult, type DepthLimitsRecord, type DuplicatedPackage, type DuplicatedPackageInstance, type EventSpan, type HotSpot, type Microseconds, type NodeModulePaths, type ParseResult, type Project, type ProjectResult, type RootSpan, type TraceJsonSchema, type TypesJsonSchema, analyzeTraceInfo };
3186
3208
  //# sourceMappingURL=browser.d.mts.map
package/dist/browser.mjs CHANGED
@@ -1,6 +1,26 @@
1
+ import CopyAll from "@mui/icons-material/CopyAll";
2
+ import Whatshot from "@mui/icons-material/Whatshot";
3
+
1
4
  //#region src/constants.ts
2
5
  const ANALYZE_TRACE_FILENAME = "analyze-trace.json";
3
6
 
4
7
  //#endregion
5
- export { ANALYZE_TRACE_FILENAME };
8
+ //#region src/info.ts
9
+ const analyzeTraceInfo = {
10
+ hotSpots: {
11
+ title: "Hot Spots",
12
+ description: "Files or paths where the TypeScript compiler spent the most cumulative time. Use these to target expensive type-checking work for refactors.",
13
+ icon: Whatshot,
14
+ route: "hot-spots"
15
+ },
16
+ duplicatePackages: {
17
+ title: "Duplicate Packages",
18
+ description: "Packages that appear multiple times in the bundle (different install paths / versions). Consolidate to reduce size & divergence.",
19
+ icon: CopyAll,
20
+ route: "duplicate-packages"
21
+ }
22
+ };
23
+
24
+ //#endregion
25
+ export { ANALYZE_TRACE_FILENAME, analyzeTraceInfo };
6
26
  //# sourceMappingURL=browser.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.mjs","names":[],"sources":["../src/constants.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"],"mappings":";AACA,MAAa,yBAAyB"}
1
+ {"version":3,"file":"browser.mjs","names":[],"sources":["../src/constants.ts","../src/info.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 type { SvgIconComponent } from \"@mui/icons-material\";\nimport CopyAll from \"@mui/icons-material/CopyAll\";\nimport Whatshot from \"@mui/icons-material/Whatshot\";\n\nexport const analyzeTraceInfo = {\n hotSpots: {\n title: \"Hot Spots\",\n description:\n \"Files or paths where the TypeScript compiler spent the most cumulative time. Use these to target expensive type-checking work for refactors.\",\n icon: Whatshot,\n route: \"hot-spots\",\n },\n duplicatePackages: {\n title: \"Duplicate Packages\",\n description:\n \"Packages that appear multiple times in the bundle (different install paths / versions). Consolidate to reduce size & divergence.\",\n icon: CopyAll,\n route: \"duplicate-packages\",\n },\n} as const satisfies Record<\n string,\n {\n title: string;\n description: string;\n icon: SvgIconComponent;\n route: string;\n }\n>;\n"],"mappings":";;;;AACA,MAAa,yBAAyB;;;;ACGtC,MAAa,mBAAmB;CAC9B,UAAU;EACR,OAAO;EACP,aACE;EACF,MAAM;EACN,OAAO;EACR;CACD,mBAAmB;EACjB,OAAO;EACP,aACE;EACF,MAAM;EACN,OAAO;EACR;CACF"}
package/dist/index.d.mts CHANGED
@@ -52,6 +52,8 @@ declare const hotType: z.ZodObject<{
52
52
  reverseMappedConstraintType: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>>;
53
53
  id: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
54
54
  flags: z.ZodArray<z.ZodEnum<{
55
+ Union: "Union";
56
+ Intersection: "Intersection";
55
57
  Any: "Any";
56
58
  Unknown: "Unknown";
57
59
  String: "String";
@@ -72,8 +74,6 @@ declare const hotType: z.ZodObject<{
72
74
  Never: "Never";
73
75
  TypeParameter: "TypeParameter";
74
76
  Object: "Object";
75
- Union: "Union";
76
- Intersection: "Intersection";
77
77
  Index: "Index";
78
78
  IndexedAccess: "IndexedAccess";
79
79
  Conditional: "Conditional";
@@ -215,6 +215,8 @@ declare const hotSpot: z.ZodObject<{
215
215
  reverseMappedConstraintType: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>>;
216
216
  id: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
217
217
  flags: z.ZodArray<z.ZodEnum<{
218
+ Union: "Union";
219
+ Intersection: "Intersection";
218
220
  Any: "Any";
219
221
  Unknown: "Unknown";
220
222
  String: "String";
@@ -235,8 +237,6 @@ declare const hotSpot: z.ZodObject<{
235
237
  Never: "Never";
236
238
  TypeParameter: "TypeParameter";
237
239
  Object: "Object";
238
- Union: "Union";
239
- Intersection: "Intersection";
240
240
  Index: "Index";
241
241
  IndexedAccess: "IndexedAccess";
242
242
  Conditional: "Conditional";
@@ -3065,6 +3065,8 @@ declare const analyzeTraceResult: z.ZodObject<{
3065
3065
  reverseMappedConstraintType: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>>;
3066
3066
  id: z.ZodUnion<[z.ZodNumber, z.ZodLiteral<-1>]>;
3067
3067
  flags: z.ZodArray<z.ZodEnum<{
3068
+ Union: "Union";
3069
+ Intersection: "Intersection";
3068
3070
  Any: "Any";
3069
3071
  Unknown: "Unknown";
3070
3072
  String: "String";
@@ -3085,8 +3087,6 @@ declare const analyzeTraceResult: z.ZodObject<{
3085
3087
  Never: "Never";
3086
3088
  TypeParameter: "TypeParameter";
3087
3089
  Object: "Object";
3088
- Union: "Union";
3089
- Intersection: "Intersection";
3090
3090
  Index: "Index";
3091
3091
  IndexedAccess: "IndexedAccess";
3092
3092
  Conditional: "Conditional";
@@ -4002,7 +4002,7 @@ declare const analyzeTrace: ({
4002
4002
  types?: {
4003
4003
  resolvedType: {
4004
4004
  id: number;
4005
- flags: ("Any" | "Unknown" | "String" | "Number" | "Boolean" | "Enum" | "BigInt" | "StringLiteral" | "NumberLiteral" | "BooleanLiteral" | "EnumLiteral" | "BigIntLiteral" | "ESSymbol" | "UniqueESSymbol" | "Void" | "Undefined" | "Null" | "Never" | "TypeParameter" | "Object" | "Union" | "Intersection" | "Index" | "IndexedAccess" | "Conditional" | "Substitution" | "NonPrimitive" | "TemplateLiteral" | "StringMapping" | "Reserved1" | "Reserved2" | "AnyOrUnknown" | "Nullable" | "Literal" | "Unit" | "Freshable" | "StringOrNumberLiteral" | "StringOrNumberLiteralOrUnique" | "DefinitelyFalsy" | "PossiblyFalsy" | "Intrinsic" | "StringLike" | "NumberLike" | "BigIntLike" | "BooleanLike" | "EnumLike" | "ESSymbolLike" | "VoidLike" | "Primitive" | "DefinitelyNonNullable" | "DisjointDomains" | "UnionOrIntersection" | "StructuredType" | "TypeVariable" | "InstantiableNonPrimitive" | "InstantiablePrimitive" | "Instantiable" | "StructuredOrInstantiable" | "ObjectFlagsType" | "Simplifiable" | "Singleton" | "Narrowable" | "IncludesMask" | "IncludesMissingType" | "IncludesNonWideningType" | "IncludesWildcard" | "IncludesEmptyObject" | "IncludesInstantiable" | "IncludesConstrainedTypeVariable" | "IncludesError" | "NotPrimitiveUnion")[];
4005
+ flags: ("Union" | "Intersection" | "Any" | "Unknown" | "String" | "Number" | "Boolean" | "Enum" | "BigInt" | "StringLiteral" | "NumberLiteral" | "BooleanLiteral" | "EnumLiteral" | "BigIntLiteral" | "ESSymbol" | "UniqueESSymbol" | "Void" | "Undefined" | "Null" | "Never" | "TypeParameter" | "Object" | "Index" | "IndexedAccess" | "Conditional" | "Substitution" | "NonPrimitive" | "TemplateLiteral" | "StringMapping" | "Reserved1" | "Reserved2" | "AnyOrUnknown" | "Nullable" | "Literal" | "Unit" | "Freshable" | "StringOrNumberLiteral" | "StringOrNumberLiteralOrUnique" | "DefinitelyFalsy" | "PossiblyFalsy" | "Intrinsic" | "StringLike" | "NumberLike" | "BigIntLike" | "BooleanLike" | "EnumLike" | "ESSymbolLike" | "VoidLike" | "Primitive" | "DefinitelyNonNullable" | "DisjointDomains" | "UnionOrIntersection" | "StructuredType" | "TypeVariable" | "InstantiableNonPrimitive" | "InstantiablePrimitive" | "Instantiable" | "StructuredOrInstantiable" | "ObjectFlagsType" | "Simplifiable" | "Singleton" | "Narrowable" | "IncludesMask" | "IncludesMissingType" | "IncludesNonWideningType" | "IncludesWildcard" | "IncludesEmptyObject" | "IncludesInstantiable" | "IncludesConstrainedTypeVariable" | "IncludesError" | "NotPrimitiveUnion")[];
4006
4006
  isTuple?: true | undefined;
4007
4007
  symbolName?: string | undefined;
4008
4008
  display?: string | undefined;
@@ -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 // TODO (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":";;;;;;;AACA,MAAa,yBAAyB;;;;AC+BtC,MAAa,qBAAqB,cAA+B;CAC/D,MAAM,gBAAgB,IAAI,IACxB,YAAY,KAAI,MAAK,EAAE,MAAM,KAAK,CACnC;CACD,MAAM,cAAc,UAAU,QAAO,UAAS,cAAc,IAAI,MAAM,KAAK,CAAC;AAE5E,QAAO;EACL,mCACE,YAAY,QACV,UACE,oDAAoD,UAAU,MAAM,CACjE,QACN,CACD,MAAM,GAAG,MAAM,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK;EAE3C,+BACE,YAAY,QACV,UACE,gDAAgD,UAAU,MAAM,CAC7D,QACN,CACD,MAAM,GAAG,MAAM,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM;EAE7C,8BACE,YAAY,QACV,UACE,+CAA+C,UAAU,MAAM,CAC5D,QACN,CACD,MAAM,GAAG,MAAM,EAAE,KAAK,SAAS,EAAE,KAAK,OAAO;EAE/C,4BACE,YAAY,QACV,UACE,6CAA6C,UAAU,MAAM,CAAC,QACjE,CACD,MAAM,GAAG,MAAM,EAAE,KAAK,qBAAqB,EAAE,KAAK,mBAAmB;EAEvE,mCACE,YAAY,QACV,UACE,oDAAoD,UAAU,MAAM,CACjE,QACN,CACD,MAAM,GAAG,MAAM,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM;EAE7C,2BAA2B,YAAY,QACrC,UACE,4CAA4C,UAAU,MAAM,CAAC,QAChE;EAED,+CACE,YAAY,QACV,UACE,gEAAgE,UAC9D,MACD,CAAC,QACL,CACD,MACC,GAAG,MACF,EAAE,KAAK,aAAa,EAAE,KAAK,aAC3B,EAAE,KAAK,aAAa,EAAE,KAAK,WAC9B;EAED,2CACE,YAAY,QACV,UACE,4DAA4D,UAC1D,MACD,CAAC,QACL,CACD,MAAM,GAAG,MAAM,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB;EAClE;;;;;AC/FH,eAAsB,kBAAkB,eAAqB;CAC3D,MAAM,kBAAkB,KAAKA,eAAa,eAAe;AACzD,SAAQ,IAAI,mBAAmB,gBAAgB;AAC/C,KAAI,CAAC,WAAW,gBAAgB,EAAE;AAChC,UAAQ,KACN,6BAA6B,gBAAgB,kCAC9C;AACD,SAAO;;CAET,MAAM,aAAa,MAAM,SAAS,iBAAiB,QAAQ;AAE3D,QADgB,KAAK,MAAM,WAAW,CACvB;;AAGjB,MAAa,0BAA0B,OACrC,sBACG;CACH,MAAMC,aAAkC,EAAE;AAC1C,MAAK,MAAM,CAACC,eAAa,iBAAiB,OAAO,QAAQC,kBAAgB,EAAE;AACzE,MAAI,aAAa,SAAS,EACxB;EAEF,MAAMC,YAAyC,EAAE;AACjD,OAAK,MAAMJ,iBAAe,aACxB,WAAU,KAAK;GACb,MAAMA;GACN,SAAS,MAAM,kBAAkBA,cAAY;GAC9C,CAAC;AAEJ,aAAW,KAAK;GACd,MAAME;GACN;GACD,CAAC;;AAGJ,QAAO;;;;;AClCT,MAAa,cAAc,OACzB,cACA,WACA,YAEA,kBAAkB;CAChB,MAAM;CACN,aAAa;CACb,cAAc,mBAAmB,UAAU;CAC3C;CACD,CAAC;AAEJ,eAAe,kBAAkB,EAC/B,MACA,aACA,cACA,WAMqB;AACrB,KAAI,KAAK,MAAM,QAAQ,QACrB,eAAc,KAAK,MAAM,KAAK;CAGhC,MAAMG,WAAsB,EAAE;AAC9B,KAAI,KAAK,SAAS,QAAQ;EAExB,MAAM,iBAAiB,KAAK,SAAS,MAClC,GAAG,MAAM,EAAE,WAAW,EAAE,SAC1B;AACD,OAAK,MAAM,SAAS,eAClB,UAAS,KACP,GAAI,MAAM,kBAAkB;GAC1B,MAAM;GACN;GACA;GACA;GACD,CAAC,CACH;;AAIL,KAAI,KAAK,MAAM,SAAS,QAAQ;EAC9B,MAAM,WAAW,MAAM,aAAa;GAClC;GACA;GACA;GACD,CAAC;AACF,MAAI,SACF,QAAO,CAAC,SAAS;;AAIrB,QAAO;;AAGT,MAAM,WAAW;CACf,UAAU,EAAE;CACZ,cAAc;EACZ,IAAI;EACJ,SAAS;EACT,OAAO,EAAE;EACV;CACF;AAED,SAAS,WAAW,EAClB,IACA,gBAIU;CACV,SAAS,OAAO,MAAY,aAAgC;AAC1D,MAAIC,SAAO,GACT,QAAO;EAGT,MAAMC,iBAAe,aAAaD;AAElC,MAAI,CAACC,eACH,OAAM,IAAI,MAAM,QAAQD,KAAG,YAAY;EAGzC,MAAME,WAAsB,EAAE;AAG9B,MAAI,YAAY,QAAQF,KAAG,GAAG,GAAG;AAC/B,eAAY,KAAKA,KAAG;GAEpB,MAAM,aAAa,OAAO,KAAKC,eAAa;AAC5C,QAAK,MAAM,YAAY,WACrB,SAAQ,UAAR;IACE,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK,cAAc;KACjB,MAAM,UAAUA,eAAa;AAC7B,SAAI,CAAC,MAAM,QAAQ,QAAQ,CACzB,OAAM,IAAI,MAAM,sBAAsB,WAAW;AAEnD,UAAK,MAAM,UAAU,SAAS;MAC5B,MAAM,QAAQ,OAAO,QAAQ,YAAY;AACzC,UAAI,MACF,UAAS,KAAK,MAAM;;AAGxB;;IAGF,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK,wBAAwB;KAC3B,MAAM,SAASA,eAAa;KAC5B,MAAM,QAAQ,OAAO,QAAQ,YAAY;AACzC,SAAI,MACF,UAAS,KAAK,MAAM;AAEtB;;IAGF,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK,aACH;IAEF,QAEE,OAAM,IAAI,MAAM,uBAAuB,WAAW;;AAGxD,eAAY,KAAK;;AAGnB,SAAO;GACL;GACA;GACD;;AAGH,QAAO,OAAO,IAAI,EAAE,CAAC;;AAGvB,eAAe,aAAa,EAC1B,MACA,UACA,gBAK+B;CAC/B,MAAM,EAAE,OAAO,UAAU,OAAO,QAAQ;AAExC,SAAQ,MAAM,MAAd;EAIE,KAAK,mBAAmB;GACtB,MAAM,WAAW,MAAM,KAAK;GAC5B,MAAM,iBAAiB,UAAU,SAAS;AAC1C,UAAO;IACL,aAAa,cAAc;IAC3B;IACA;IACA;IACA,MAAM;IAEN;IACD;;EAGH,KAAK,0BACH,QAAO;GACL,aAAa,iBAAiB,MAAM,KAAK,SAAS,OAAO,MAAM,KAAK;GACpE;GACA;GACA;GACA;GACA,OAAO,CACL,WAAW;IACT,IAAI,MAAM,KAAK;IACf;IACD,CAAC,EACF,WAAW;IACT,IAAI,MAAM,KAAK;IACf;IACD,CAAC,CACH;GACF;EAEH,KAAK,qBACH,QAAO;GACL,aAAa,8BAA8B,MAAM,KAAK;GACtD;GACA;GACA;GACA;GACA,OAAO,CAAC,WAAW;IAAE,IAAI,MAAM,KAAK;IAAI;IAAc,CAAC,CAAC;GACzD;EAEH,KAAK;EACL,KAAK,4BAA4B;GAC/B,MAAM,WAAW,MAAM,KAAK;GAC5B,MAAM,OAAO,WAAW,EAAE,MAAM,UAAU,SAAS,EAAE,GAAG,EAAE;AAS1D,UARuB;IACrB,aAAa,MAAM;IACnB;IACA;IACA;IACA,GAAG;IACH,UAAU,EAAE;IACb;;EAIH,QACE;;;;;;AClPN,SAAgB,mBACd,WACiB;CACjB,MAAME,oBAAmC,EAAE;AAC3C,WAAU,SAAS,UAAsB;AACvC,MAAI,MAAM,SAAS,iBACjB;EAEF,MAAM,OAAO,MAAM,KAAK;AACxB,MAAI,KACF,QAAO,MAAM;GACX,MAAM,QAAQ,iBAAiB,KAAK,KAAK;AACzC,OAAI,CAAC,MACH;GAEF,MAAMC,gBAAc,MAAM;GAE1B,MAAMC,gBAAc,MAAM,MAAM,UAC9B,GACA,MAAM,QAAQ,MAAM,GAAG,OACxB;AAED,OAAID,iBAAeE,mBAAiB;IAClC,MAAM,QAAQA,kBAAgBF;AAC9B,QAAI,SAAS,MAAM,QAAQC,cAAY,GAAG,EAExC,OAAM,KAAKA,cAAY;SAGzB,mBAAgBD,iBAAe,CAACC,cAAY;;GAIlD;AAEF,QAAOC;;;;;AC3BT,SAAgB,YAAY,WAAyC;CAEnE,MAAMC,gBAA8B,EAAE;CAGtC,MAAMC,QAAqB,EAAE;AAE7B,WAAU,SAAS,UAAsB;AACvC,UAAQ,MAAM,IAAd;GACE,KAAK,WAAW;AACd,kBAAc,KAAK,MAAM;AACzB;GAEF,KAAK,WAAW,KAAK;IACnB,MAAM,aAAa,cAAc,KAAK;AACtC,QAAI,CAAC,WACH,OAAM,IAAI,MAAM,sBAAsB;AAExC,UAAM,KAAK;KACT,OAAO;KACP,OAAO,WAAW;KAClB,KAAK,MAAM;KACX,UAAU,MAAM,KAAK,WAAW;KAChC,UAAU,EAAE;KACb,CAAC;AACF;;GAGF,KAAK,WAAW,UAAU;IACxB,MAAM,QAAQ,MAAM;IACpB,MAAM,WAAW,MAAM,OAAO;AAC9B,UAAM,KAAK;KACT;KACA;KACA,KAAK,QAAQ;KACb;KACA,UAAU,EAAE;KACb,CAAC;AACF;;GAGF,KAAK,WAAW;GAChB,KAAK,WAAW,SACd;GAEF;;GAGF;AAQF,QANiC;EAC/B,gBAAgB,KAAK,IAAI,GAAG,MAAM,KAAI,SAAQ,KAAK,MAAM,CAAC;EAC1D,aAAa,KAAK,IAAI,GAAG,MAAM,KAAI,SAAQ,KAAK,IAAI,CAAC;EACrD;EACA;EACD;;AAIH,SAAgB,eACd,eACA,SACW;CACX,MAAM,EAAE,gBAAgB,aAAa,OAAO,kBAAkBC;AAG9D,MAAK,IAAI,IAAI,cAAc,SAAS,GAAG,KAAK,GAAG,KAAK;EAClD,MAAM,QAAQ,cAAc;EAC5B,MAAM,QAAQ,MAAM;EACpB,MAAM,MAAM;AACZ,QAAM,KAAK;GACT;GACA;GACA;GACA,UAAU,MAAM;GAChB,UAAU,EAAE;GACb,CAAC;;AAGJ,OAAM,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM;CAEvC,MAAMC,OAAkB;EACtB,OAAO;GACL,MAAM;GACN,KAAK;GACN;EACD,OAAO;EACP,KAAK;EACL,UAAU,cAAc;EACxB,UAAU,EAAE;EACb;CACD,MAAM,QAAQ,CAAC,KAAK;AAEpB,MAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,IAAI,MAAM,SAAS;AACvB,SAAO,IAAI,GAAG,IAGZ,KADa,MAAM,GACV,MAAM,KAAK,OAAO;AAEzB,SAAM,SAAS,IAAI;AACnB;;;EAKJ,MAAMC,oBAAkC,QAAQ,cAAc;EAC9D,MAAM,2BAA2B,KAAK,YAAY;EAElD,MAAM,SAAS,MAAM;EACrB,MAAM,iBAAiB,OAAO,MAAM,OAAO;EAC3C,MAAM,+BACJ,KAAK,YAAY,iBAAiB,QAAQ;AAE5C,MAAI,4BAA4B,8BAA8B;AAC5D,UAAO,SAAS,KAAK,KAAK;AAC1B,SAAM,KAAK,KAAK;;;AAIpB,QAAO;;;;;ACvHT,MAAa,eAAe,EAAE,QAAQ,CAAC,QACrC,SAAQ;AACN,QACE,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,OAAO,IAAI,KAAK,WAAW,OAAO;GAG9E,EACE,SAAS,yBACV,CACF;AAGD,MAAa,UAAU,EAAE,OAAO;CAC9B,gBAAgB,aAAa,UAAU;CACvC,WAAW;CACX,WAAW;CACZ,CAAC;AAGF,MAAa,gBAAgB,EAAE,OAAO;CAC3B;CACT,QAAQ,EAAE,QAAQ;CAClB,QAAQ,EAAE,QAAQ;CAClB,UAAU,EAAE,QAAQ,CAAC,UAAU;CAC/B,QAAQ,EAAE,KAAK,CAAC,UAAU,UAAU,CAAC,CAAC,UAAU;CACjD,CAAC;AAGF,MAAa,UAAU,EAAE,OAAO;CAChB;CACd,IAAI,WAAW;AACb,SAAO,EAAE,MAAM,QAAQ;;CAE1B,CAAC;AAGF,MAAa,UAAU,EAAE,OAAO;CAC9B,aAAa,EAAE,QAAQ;CACvB,UAAU,EAAE,QAAQ;CACpB,OAAO,EAAE,QAAQ;CACjB,KAAK,EAAE,QAAQ;CACf,IAAI,WAAW;AACb,SAAO,EAAE,MAAM,QAAQ;;CAGzB,MAAM,aAAa,UAAU;CAC7B,OAAO,EAAE,MAAM,QAAQ,CAAC,UAAU;CAClC,WAAW,EAAE,QAAQ,CAAC,UAAU;CAChC,WAAW,EAAE,QAAQ,CAAC,UAAU;CAChC,aAAa,EAAE,QAAQ,CAAC,UAAU;CAClC,SAAS,EAAE,QAAQ,CAAC,UAAU;CAC9B,SAAS,EAAE,QAAQ,CAAC,UAAU;CAC9B,WAAW,EAAE,QAAQ,CAAC,UAAU;CACjC,CAAC;AAGF,MAAa,4BAA4B,EAAE,OAAO;CAChD,MAAM;CACN,SAAS,EAAE,QAAQ;CACpB,CAAC;AAKF,MAAa,oBAAoB,EAAE,OAAO;CACxC,MAAM,EAAE,QAAQ;CAChB,WAAW,EAAE,MAAM,0BAA0B;CAC9C,CAAC;AAGF,MAAa,WAAW,EAAE,OAAO;CAC/B,MAAM,EAAE,QAAQ,OAAO;CACvB,KAAK,EAAE,QAAQ,UAAU;CAC1B,CAAC;AAGF,MAAa,YAAY,EAAE,OAAO;CAChC,OAAO,EAAE,MAAM,CAAC,YAAY,SAAS,CAAC;CACtC,OAAO,EAAE,QAAQ;CACjB,KAAK,EAAE,QAAQ;CACf,UAAU,EAAE,QAAQ;CACpB,IAAI,WAAW;AACb,SAAO,EAAE,MAAM,UAAU;;CAE5B,CAAC;AAGF,MAAa,eAAe,EAAE,QAAQ;AAGtC,MAAa,cAAc,EAAE,QAAQ;AAErC,MAAa,cAAc,EAAE,QAAQ;AAErC,MAAa,kBAAkB,EAAE,OAAO,aAAa,EAAE,MAAM,YAAY,CAAC;AAI1E,MAAa,cAAc,EAAE,OAAO;CAClC,gBAAgB,EAAE,QAAQ;CAC1B,aAAa,EAAE,QAAQ;CACvB,OAAO,EAAE,MAAM,UAAU;CACzB,eAAe,EAAE,MAAM,WAAW;CACnC,CAAC;AAGF,MAAa,sBAAsB,EAAE,OAAO;CAE1C,aAAa,EAAE,QAAQ;CAEvB,YAAY,EAAE,QAAQ;CAEtB,aAAa,EAAE,SAAS;CAExB,yBAAyB,EAAE,QAAQ;CAEnC,2BAA2B,EAAE,QAAQ;CACtC,CAAC;AAGF,MAAa,SAAS,OAAO,SAAiB;AAC5C,QAAO,KAAK,KAAK,CACd,MAAK,UAAS,MAAM,QAAQ,CAAC,CAC7B,OAAM,MAAK,MAAM;;AAGtB,MAAa,sBAAsB,OAAO,SAAiB;AACzD,KAAI,CAAC,WAAW,KAAK,IAAI,EAAE,MAAM,KAAK,KAAK,GAAG,aAAa,CACzD,OAAM,IAAI,MAAM,GAAG,KAAK,qBAAqB;AAE/C,QAAO;;AAGT,MAAa,qBAAqB,EAAE,OAAO;CAEzC,oBAAoB,EAAE,MAAM,WAAW;CAEvC,UAAU,EAAE,MAAM,QAAQ;CAE1B,mBAAmB,EAAE,MAAM,kBAAkB;CAE5B;CAEjB,aAAa,EAAE,OAAO;EACpB,mCAAmC,EAAE,MACnC,oDACD;EACD,+BAA+B,EAAE,MAC/B,gDACD;EACD,8BAA8B,EAAE,MAC9B,+CACD;EACD,4BAA4B,EAAE,MAC5B,6CACD;EACD,mCAAmC,EAAE,MACnC,oDACD;EACD,2BAA2B,EAAE,MAC3B,4CACD;EACD,+CAA+C,EAAE,MAC/C,gEACD;EACD,2CAA2C,EAAE,MAC3C,4DACD;EACF,CAAC;CACH,CAAC;;;;ACjKF,SAAgB,gBAAgB,SAA8B;AAC5D,KAAI,QAAQ,cAAc,QAAQ,WAChC,OAAM,IAAI,MAAM,6CAA6C;;AAIjE,MAAM,mBAAmB,OACvB,aAII;AACJ,OAAM,oBAAoB,SAAS;CAEnC,MAAM,gBAAgB,KAAK,UAAU,oBAAoB;AACzD,KAAI,CAAC,WAAW,cAAc,CAC5B,OAAM,IAAI,MACR,4BAA4B,SAAS,6BACtC;CAEH,MAAM,gBAAgB,KAAK,MAAM,MAAM,SAAS,eAAe,OAAO,CAAC;CACvE,MAAM,YAAY,gBAAgB,MAAM,cAAc;CAEtD,MAAM,gBAAgB,KAAK,UAAU,oBAAoB;AACzD,KAAI,CAAC,WAAW,cAAc,CAC5B,OAAM,IAAI,MACR,4BAA4B,SAAS,6BACtC;CAEH,MAAM,gBAAgB,KAAK,MAAM,MAAM,SAAS,eAAe,OAAO,CAAC;AAGvE,QAAO;EACL,WAHgB,gBAAgB,MAAM,cAAc;EAIpD;EACD;;AAGH,MAAaC,iBAAsC;CACjD,aAAa;CACb,YAAY;CACZ,aAAa;CACb,yBAAyB;CACzB,2BAA2B;CAC5B;AAED,MAAa,eAAe,OAAO,EACjC,UACA,UAAU,qBAIN;AACJ,iBAAgB,QAAQ;CACxB,MAAM,EAAE,WAAW,cAAc,MAAM,iBAAiB,SAAS;CAEjE,MAAMC,oBAAkB,mBAAmB,UAAU;CAErD,MAAM,QAAQ,YAAY,UAAU;CACpC,MAAM,eAAe,eAAe,OAAO,QAAQ;CAEnD,MAAMC,SAA6B;EACjC;EACA,oBAAoB,MAAM,cAAc,SAAS;EACjD,UAAU,MAAM,YAAY,cAAc,WAAW,QAAQ;EAC7D,mBAAmB,MAAM,wBAAwBD,kBAAgB;EACjE,aAAa,kBAAkB,UAAU;EAC1C;AACD,OAAM,UACJ,KAAK,UAAU,uBAAuB,EACtC,KAAK,UAAU,QAAQ,MAAM,EAAE,CAChC;AAED,QAAO"}
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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typeslayer/analyze-trace",
3
- "version": "0.1.25",
3
+ "version": "0.1.27",
4
4
  "description": "Analyze TypeScript compiler trace events to identify performance bottlenecks",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -34,13 +34,15 @@
34
34
  "typeslayer-analyze-trace": "./bin/typeslayer-analyze-trace.mjs"
35
35
  },
36
36
  "dependencies": {
37
- "zod": "4.1.13",
38
- "@typeslayer/validate": "0.1.25"
37
+ "@mui/icons-material": "7.3.6",
38
+ "@mui/material": "7.3.6",
39
+ "zod": "4.2.1",
40
+ "@typeslayer/validate": "0.1.27"
39
41
  },
40
42
  "devDependencies": {
41
43
  "@arethetypeswrong/cli": "^0.18.2",
42
- "@types/node": "24.10.1",
43
- "tsdown": "^0.17.2",
44
+ "@types/node": "25.0.3",
45
+ "tsdown": "0.18.3",
44
46
  "typescript": "5.9.3"
45
47
  },
46
48
  "scripts": {
package/src/browser.ts CHANGED
@@ -5,6 +5,7 @@ export type {
5
5
  } from "@typeslayer/validate";
6
6
  export { ANALYZE_TRACE_FILENAME } from "./constants";
7
7
  export type { DepthLimitsRecord } from "./depth-limits";
8
+ export * from "./info";
8
9
  export type {
9
10
  AbsolutePath,
10
11
  AnalyzeTraceOptions,
@@ -186,7 +186,7 @@ async function makeHotFrame({
186
186
 
187
187
  switch (event.name) {
188
188
  // case "findSourceFile":
189
- // TODO (https://github.com/microsoft/typescript-analyze-trace/issues/2)
189
+ // (https://github.com/microsoft/typescript-analyze-trace/issues/2)
190
190
 
191
191
  case "checkSourceFile": {
192
192
  const filePath = event.args.path;
package/src/info.ts ADDED
@@ -0,0 +1,28 @@
1
+ import type { SvgIconComponent } from "@mui/icons-material";
2
+ import CopyAll from "@mui/icons-material/CopyAll";
3
+ import Whatshot from "@mui/icons-material/Whatshot";
4
+
5
+ export const analyzeTraceInfo = {
6
+ hotSpots: {
7
+ title: "Hot Spots",
8
+ description:
9
+ "Files or paths where the TypeScript compiler spent the most cumulative time. Use these to target expensive type-checking work for refactors.",
10
+ icon: Whatshot,
11
+ route: "hot-spots",
12
+ },
13
+ duplicatePackages: {
14
+ title: "Duplicate Packages",
15
+ description:
16
+ "Packages that appear multiple times in the bundle (different install paths / versions). Consolidate to reduce size & divergence.",
17
+ icon: CopyAll,
18
+ route: "duplicate-packages",
19
+ },
20
+ } as const satisfies Record<
21
+ string,
22
+ {
23
+ title: string;
24
+ description: string;
25
+ icon: SvgIconComponent;
26
+ route: string;
27
+ }
28
+ >;