traceperf 0.1.1 → 0.1.2
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 +79 -1
- package/dist/browser.d.ts +58 -2
- package/dist/browser.js +179 -28
- package/dist/browser.js.map +1 -1
- package/dist/esm/browser.d.ts +58 -2
- package/dist/esm/browser.js +179 -28
- package/dist/esm/browser.js.map +1 -1
- package/dist/esm/trackers/execution.d.ts +23 -7
- package/dist/esm/trackers/execution.js +100 -29
- package/dist/esm/trackers/execution.js.map +1 -1
- package/dist/esm/types/index.d.ts +32 -0
- package/dist/trackers/execution.d.ts +23 -7
- package/dist/trackers/execution.js +100 -29
- package/dist/trackers/execution.js.map +1 -1
- package/dist/types/index.d.ts +32 -0
- package/package.json +1 -1
|
@@ -17,6 +17,8 @@ class ExecutionTracker {
|
|
|
17
17
|
var _a;
|
|
18
18
|
this._executions = [];
|
|
19
19
|
this._currentExecution = null;
|
|
20
|
+
this._instrumentedFunctions = new Map();
|
|
21
|
+
this._isInstrumented = false;
|
|
20
22
|
this._callStack = new stack_1.CallStackManager();
|
|
21
23
|
this._asciiGenerator = new ascii_1.AsciiArtGenerator({ boxWidth: options.boxWidth });
|
|
22
24
|
this._defaultThreshold = (_a = options.defaultThreshold) !== null && _a !== void 0 ? _a : 100; // ms
|
|
@@ -29,10 +31,11 @@ class ExecutionTracker {
|
|
|
29
31
|
* @returns The return value of the tracked function
|
|
30
32
|
*/
|
|
31
33
|
track(fn, options) {
|
|
32
|
-
var _a, _b;
|
|
34
|
+
var _a, _b, _c;
|
|
33
35
|
const fnName = (options === null || options === void 0 ? void 0 : options.label) || (0, stack_1.getFunctionName)(fn);
|
|
34
36
|
const threshold = (_a = options === null || options === void 0 ? void 0 : options.threshold) !== null && _a !== void 0 ? _a : this._defaultThreshold;
|
|
35
37
|
const includeMemory = (_b = options === null || options === void 0 ? void 0 : options.includeMemory) !== null && _b !== void 0 ? _b : true;
|
|
38
|
+
const enableNestedTracking = (_c = options === null || options === void 0 ? void 0 : options.enableNestedTracking) !== null && _c !== void 0 ? _c : true;
|
|
36
39
|
// Get memory usage before execution
|
|
37
40
|
const startMemory = includeMemory ? process.memoryUsage().heapUsed : undefined;
|
|
38
41
|
// Start timing
|
|
@@ -61,9 +64,20 @@ class ExecutionTracker {
|
|
|
61
64
|
const previousExecution = this._currentExecution;
|
|
62
65
|
// Set this as the current execution
|
|
63
66
|
this._currentExecution = execution;
|
|
67
|
+
// Flag to track if we're already instrumenting to avoid recursion
|
|
68
|
+
const wasInstrumented = this._isInstrumented;
|
|
64
69
|
try {
|
|
65
|
-
//
|
|
66
|
-
|
|
70
|
+
// If this is the top-level call and nested tracking is enabled, instrument the function
|
|
71
|
+
if (enableNestedTracking && !wasInstrumented) {
|
|
72
|
+
this._isInstrumented = true;
|
|
73
|
+
// Instrument the function to track nested calls
|
|
74
|
+
const instrumentedFn = this.instrumentFunction(fn);
|
|
75
|
+
return instrumentedFn();
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
// Execute the function normally
|
|
79
|
+
return fn();
|
|
80
|
+
}
|
|
67
81
|
}
|
|
68
82
|
finally {
|
|
69
83
|
// End timing
|
|
@@ -81,8 +95,45 @@ class ExecutionTracker {
|
|
|
81
95
|
this._currentExecution = previousExecution;
|
|
82
96
|
// Remove from call stack
|
|
83
97
|
this._callStack.pop();
|
|
98
|
+
// Reset instrumentation flag if this was the top-level call
|
|
99
|
+
if (!wasInstrumented) {
|
|
100
|
+
this._isInstrumented = false;
|
|
101
|
+
}
|
|
84
102
|
}
|
|
85
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Instrument a function to track nested function calls
|
|
106
|
+
*
|
|
107
|
+
* @param fn - The function to instrument
|
|
108
|
+
* @returns The instrumented function
|
|
109
|
+
*/
|
|
110
|
+
instrumentFunction(fn) {
|
|
111
|
+
// If we've already instrumented this function, return the instrumented version
|
|
112
|
+
if (this._instrumentedFunctions.has(fn)) {
|
|
113
|
+
return this._instrumentedFunctions.get(fn);
|
|
114
|
+
}
|
|
115
|
+
// Create a new instrumented function
|
|
116
|
+
const instrumentedFn = () => {
|
|
117
|
+
try {
|
|
118
|
+
// We can't actually modify the function at runtime to track nested calls
|
|
119
|
+
// in a generic way. The best we can do is execute the function and rely
|
|
120
|
+
// on the call stack for visualization.
|
|
121
|
+
//
|
|
122
|
+
// For proper nested function tracking, users should wrap each function
|
|
123
|
+
// they want to track with tracePerf.track() or use a more advanced
|
|
124
|
+
// instrumentation approach like aspect-oriented programming or
|
|
125
|
+
// code transformation.
|
|
126
|
+
return fn();
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
// Re-throw any errors
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
// Cache the instrumented function
|
|
134
|
+
this._instrumentedFunctions.set(fn, instrumentedFn);
|
|
135
|
+
return instrumentedFn;
|
|
136
|
+
}
|
|
86
137
|
/**
|
|
87
138
|
* Get the current call stack
|
|
88
139
|
*
|
|
@@ -98,9 +149,52 @@ class ExecutionTracker {
|
|
|
98
149
|
*/
|
|
99
150
|
generateFlowChart() {
|
|
100
151
|
// Convert execution records to execution data for the ASCII generator
|
|
101
|
-
const
|
|
152
|
+
const executionData = this.prepareExecutionData(this._executions);
|
|
102
153
|
// Generate the flow chart
|
|
103
|
-
return this._asciiGenerator.generateFlowChart(
|
|
154
|
+
return this._asciiGenerator.generateFlowChart(executionData);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Prepare execution data for the ASCII generator
|
|
158
|
+
*
|
|
159
|
+
* @param executions - The execution records to prepare
|
|
160
|
+
* @returns A list of execution data
|
|
161
|
+
*/
|
|
162
|
+
prepareExecutionData(executions) {
|
|
163
|
+
const result = [];
|
|
164
|
+
// Process each root execution
|
|
165
|
+
executions.forEach(execution => {
|
|
166
|
+
// Add the root execution
|
|
167
|
+
result.push({
|
|
168
|
+
name: execution.name,
|
|
169
|
+
duration: execution.duration,
|
|
170
|
+
isSlow: execution.isSlow,
|
|
171
|
+
memoryUsage: execution.memoryUsage,
|
|
172
|
+
level: execution.level,
|
|
173
|
+
});
|
|
174
|
+
// Add children recursively
|
|
175
|
+
this.addChildrenToResult(execution.children, result);
|
|
176
|
+
});
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Add children to the result list
|
|
181
|
+
*
|
|
182
|
+
* @param children - The children to add
|
|
183
|
+
* @param result - The result list
|
|
184
|
+
*/
|
|
185
|
+
addChildrenToResult(children, result) {
|
|
186
|
+
children.forEach(child => {
|
|
187
|
+
// Add the child
|
|
188
|
+
result.push({
|
|
189
|
+
name: child.name,
|
|
190
|
+
duration: child.duration,
|
|
191
|
+
isSlow: child.isSlow,
|
|
192
|
+
memoryUsage: child.memoryUsage,
|
|
193
|
+
level: child.level,
|
|
194
|
+
});
|
|
195
|
+
// Add grandchildren recursively
|
|
196
|
+
this.addChildrenToResult(child.children, result);
|
|
197
|
+
});
|
|
104
198
|
}
|
|
105
199
|
/**
|
|
106
200
|
* Clear all execution records
|
|
@@ -109,6 +203,7 @@ class ExecutionTracker {
|
|
|
109
203
|
this._executions = [];
|
|
110
204
|
this._currentExecution = null;
|
|
111
205
|
this._callStack.clear();
|
|
206
|
+
this._instrumentedFunctions.clear();
|
|
112
207
|
}
|
|
113
208
|
/**
|
|
114
209
|
* Get all execution records
|
|
@@ -118,30 +213,6 @@ class ExecutionTracker {
|
|
|
118
213
|
getExecutions() {
|
|
119
214
|
return [...this._executions];
|
|
120
215
|
}
|
|
121
|
-
/**
|
|
122
|
-
* Flatten the execution tree into a list
|
|
123
|
-
*
|
|
124
|
-
* @param executions - The execution records to flatten
|
|
125
|
-
* @returns A flat list of execution data
|
|
126
|
-
*/
|
|
127
|
-
flattenExecutions(executions) {
|
|
128
|
-
const result = [];
|
|
129
|
-
// Helper function to recursively flatten the tree
|
|
130
|
-
const flatten = (record) => {
|
|
131
|
-
result.push({
|
|
132
|
-
name: record.name,
|
|
133
|
-
duration: record.duration,
|
|
134
|
-
isSlow: record.isSlow,
|
|
135
|
-
memoryUsage: record.memoryUsage,
|
|
136
|
-
level: record.level,
|
|
137
|
-
});
|
|
138
|
-
// Process children
|
|
139
|
-
record.children.forEach(child => flatten(child));
|
|
140
|
-
};
|
|
141
|
-
// Flatten each root execution
|
|
142
|
-
executions.forEach(execution => flatten(execution));
|
|
143
|
-
return result;
|
|
144
|
-
}
|
|
145
216
|
}
|
|
146
217
|
exports.ExecutionTracker = ExecutionTracker;
|
|
147
218
|
//# sourceMappingURL=execution.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/trackers/execution.ts"],"names":[],"mappings":";;;AACA,0CAAmE;AACnE,4CAA8D;AAC9D,+CAAuE;AAiBvE;;GAEG;AACH,MAAa,gBAAgB;
|
|
1
|
+
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/trackers/execution.ts"],"names":[],"mappings":"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"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,2 +1,34 @@
|
|
|
1
1
|
export * from './config';
|
|
2
2
|
export * from './logger';
|
|
3
|
+
/**
|
|
4
|
+
* Options for tracking function execution
|
|
5
|
+
*/
|
|
6
|
+
export interface ITrackOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Custom label for the function
|
|
9
|
+
*/
|
|
10
|
+
label?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Performance threshold in milliseconds
|
|
13
|
+
*/
|
|
14
|
+
threshold?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Whether to include memory usage in the tracking
|
|
17
|
+
*/
|
|
18
|
+
includeMemory?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Whether to track nested function calls
|
|
21
|
+
*
|
|
22
|
+
* Note: This option doesn't automatically track all nested function calls.
|
|
23
|
+
* It only enables the infrastructure for tracking nested calls, but you still
|
|
24
|
+
* need to manually track each nested function using one of the approaches
|
|
25
|
+
* described in the documentation.
|
|
26
|
+
*
|
|
27
|
+
* @default true
|
|
28
|
+
*/
|
|
29
|
+
enableNestedTracking?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Whether to suppress logging
|
|
32
|
+
*/
|
|
33
|
+
silent?: boolean;
|
|
34
|
+
}
|