@forgehive/task 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/index.d.ts +12 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +66 -13
  4. package/dist/index.js.map +1 -1
  5. package/dist/test/add-listener-with-boundaries.test.js +78 -7
  6. package/dist/test/add-listener-with-boundaries.test.js.map +1 -1
  7. package/dist/test/add-listener.test.js +36 -0
  8. package/dist/test/add-listener.test.js.map +1 -1
  9. package/dist/test/boundary-modes.test.js +45 -5
  10. package/dist/test/boundary-modes.test.js.map +1 -1
  11. package/dist/test/execution-record-boundaries.test.js +12 -2
  12. package/dist/test/execution-record-boundaries.test.js.map +1 -1
  13. package/dist/test/integration-enhanced-records.test.d.ts +2 -0
  14. package/dist/test/integration-enhanced-records.test.d.ts.map +1 -0
  15. package/dist/test/integration-enhanced-records.test.js +467 -0
  16. package/dist/test/integration-enhanced-records.test.js.map +1 -0
  17. package/dist/test/listen-execution-records.test.d.ts +2 -0
  18. package/dist/test/listen-execution-records.test.d.ts.map +1 -0
  19. package/dist/test/listen-execution-records.test.js +223 -0
  20. package/dist/test/listen-execution-records.test.js.map +1 -0
  21. package/dist/test/metrics-collection.test.d.ts +2 -0
  22. package/dist/test/metrics-collection.test.d.ts.map +1 -0
  23. package/dist/test/metrics-collection.test.js +409 -0
  24. package/dist/test/metrics-collection.test.js.map +1 -0
  25. package/dist/test/performance-edge-cases.test.d.ts +2 -0
  26. package/dist/test/performance-edge-cases.test.d.ts.map +1 -0
  27. package/dist/test/performance-edge-cases.test.js +502 -0
  28. package/dist/test/performance-edge-cases.test.js.map +1 -0
  29. package/dist/test/run-boundary.test.js +27 -3
  30. package/dist/test/run-boundary.test.js.map +1 -1
  31. package/dist/test/safe-replay-complex-boundary.test.js +110 -9
  32. package/dist/test/safe-replay-complex-boundary.test.js.map +1 -1
  33. package/dist/test/safe-replay.test.js +35 -5
  34. package/dist/test/safe-replay.test.js.map +1 -1
  35. package/dist/test/safe-run.test.js +46 -4
  36. package/dist/test/safe-run.test.js.map +1 -1
  37. package/dist/test/setmetrics-boundary.test.d.ts +2 -0
  38. package/dist/test/setmetrics-boundary.test.d.ts.map +1 -0
  39. package/dist/test/setmetrics-boundary.test.js +195 -0
  40. package/dist/test/setmetrics-boundary.test.js.map +1 -0
  41. package/dist/test/task-with-boundaries.test.js +63 -2
  42. package/dist/test/task-with-boundaries.test.js.map +1 -1
  43. package/dist/test/timing-capture.test.d.ts +2 -0
  44. package/dist/test/timing-capture.test.d.ts.map +1 -0
  45. package/dist/test/timing-capture.test.js +304 -0
  46. package/dist/test/timing-capture.test.js.map +1 -0
  47. package/dist/test/timing-utilities.test.d.ts +2 -0
  48. package/dist/test/timing-utilities.test.d.ts.map +1 -0
  49. package/dist/test/timing-utilities.test.js +127 -0
  50. package/dist/test/timing-utilities.test.js.map +1 -0
  51. package/dist/types.d.ts +93 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +78 -0
  54. package/dist/types.js.map +1 -0
  55. package/dist/utils/boundary.d.ts +3 -0
  56. package/dist/utils/boundary.d.ts.map +1 -1
  57. package/dist/utils/boundary.js +11 -2
  58. package/dist/utils/boundary.js.map +1 -1
  59. package/package.json +3 -2
  60. package/src/index.ts +97 -14
  61. package/src/test/add-listener-with-boundaries.test.ts +78 -7
  62. package/src/test/add-listener.test.ts +36 -0
  63. package/src/test/boundary-modes.test.ts +45 -5
  64. package/src/test/execution-record-boundaries.test.ts +12 -2
  65. package/src/test/listen-execution-records.test.ts +295 -0
  66. package/src/test/metrics-collection.test.ts +476 -0
  67. package/src/test/performance-edge-cases.test.ts +596 -0
  68. package/src/test/run-boundary.test.ts +27 -3
  69. package/src/test/safe-replay-complex-boundary.test.ts +115 -10
  70. package/src/test/safe-replay.test.ts +35 -5
  71. package/src/test/safe-run.test.ts +46 -4
  72. package/src/test/setmetrics-boundary.test.ts +223 -0
  73. package/src/test/task-with-boundaries.test.ts +71 -5
  74. package/src/test/timing-capture.test.ts +348 -0
  75. package/src/test/timing-utilities.test.ts +145 -0
  76. package/src/types.ts +139 -0
  77. package/src/utils/boundary.ts +15 -2
@@ -1,3 +1,4 @@
1
+ import { TimingInfo } from '../types';
1
2
  type BaseBoundary = (...args: unknown[]) => unknown;
2
3
  export type Mode = 'proxy' | 'proxy-pass' | 'proxy-catch' | 'replay';
3
4
  /**
@@ -15,6 +16,7 @@ export type BoundarySuccessRecord<TInput = unknown[], TOutput = unknown> = {
15
16
  input: TInput;
16
17
  output: TOutput;
17
18
  error?: null;
19
+ timing: TimingInfo;
18
20
  };
19
21
  /**
20
22
  * Error record for a boundary function call
@@ -24,6 +26,7 @@ export type BoundaryErrorRecord<TInput = unknown[]> = {
24
26
  input: TInput;
25
27
  output?: null;
26
28
  error: string;
29
+ timing: TimingInfo;
27
30
  };
28
31
  /**
29
32
  * Represents a record of a boundary function call - either success or error
@@ -1 +1 @@
1
- {"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../../src/utils/boundary.ts"],"names":[],"mappings":"AAGA,KAAK,YAAY,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAA;AAEnD,MAAM,MAAM,IAAI,GAAG,OAAO,GAAG,YAAY,GAAG,aAAa,GAAG,QAAQ,CAAA;AAEpE;;;;GAIG;AAEH,MAAM,MAAM,gBAAgB,CAAC,OAAO,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAElF;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,CAAC,MAAM,GAAG,OAAO,EAAE,EAAE,OAAO,GAAG,OAAO,IAAI;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,IAAI,CAAC;CACd,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,CAAC,MAAM,GAAG,OAAO,EAAE,IAAI;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,CAAC,MAAM,GAAG,OAAO,EAAE,EAAE,OAAO,GAAG,OAAO,IAC9D,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAEvE;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,uBAAuB,CAAC,IAAI,SAAS,gBAAgB,GAAG,gBAAgB;IACvF,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;IACtD,OAAO,EAAE,MAAM,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACjF,OAAO,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IAC9F,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,OAAO,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,IAAI,CAAA;IAChC,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,UAAU,EAAE,MAAM,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;CACrF;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;AAEzD;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,IAAI;KAChE,CAAC,IAAI,MAAM,CAAC,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC9C,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,IAAI,SAAS,YAAY,EAAE,IAAI,IAAI,KAAG,uBAAuB,CAAC,IAAI,SAAS,gBAAgB,GAAG,IAAI,GAAG,KAAK,CAiIxI,CAAA"}
1
+ {"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../../src/utils/boundary.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAiB,MAAM,UAAU,CAAA;AAGpD,KAAK,YAAY,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAA;AAEnD,MAAM,MAAM,IAAI,GAAG,OAAO,GAAG,YAAY,GAAG,aAAa,GAAG,QAAQ,CAAA;AAEpE;;;;GAIG;AAEH,MAAM,MAAM,gBAAgB,CAAC,OAAO,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAElF;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,CAAC,MAAM,GAAG,OAAO,EAAE,EAAE,OAAO,GAAG,OAAO,IAAI;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;CACpB,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,CAAC,MAAM,GAAG,OAAO,EAAE,IAAI;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;CACpB,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,CAAC,MAAM,GAAG,OAAO,EAAE,EAAE,OAAO,GAAG,OAAO,IAC9D,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAEvE;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,uBAAuB,CAAC,IAAI,SAAS,gBAAgB,GAAG,gBAAgB;IACvF,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;IACtD,OAAO,EAAE,MAAM,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACjF,OAAO,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IAC9F,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,OAAO,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,IAAI,CAAA;IAChC,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,UAAU,EAAE,MAAM,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;CACrF;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;AAEzD;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,IAAI;KAChE,CAAC,IAAI,MAAM,CAAC,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC9C,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,IAAI,SAAS,YAAY,EAAE,IAAI,IAAI,KAAG,uBAAuB,CAAC,IAAI,SAAS,gBAAgB,GAAG,IAAI,GAAG,KAAK,CA2IxI,CAAA"}
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.createBoundary = void 0;
37
37
  const assert = __importStar(require("assert"));
38
+ const types_1 = require("../types");
38
39
  const createBoundary = (fn) => {
39
40
  let runLog = [];
40
41
  let cacheTape = [];
@@ -79,6 +80,8 @@ const createBoundary = (fn) => {
79
80
  })();
80
81
  }
81
82
  return await (async () => {
83
+ const timer = types_1.TimingTracker.create();
84
+ timer.start();
82
85
  let result, error;
83
86
  try {
84
87
  result = await fn(...args);
@@ -86,6 +89,10 @@ const createBoundary = (fn) => {
86
89
  catch (e) {
87
90
  error = e;
88
91
  }
92
+ const timing = timer.end();
93
+ if (!timing) {
94
+ throw new Error('Failed to capture timing information');
95
+ }
89
96
  if (typeof error !== 'undefined') {
90
97
  const prevRecord = findRecord(args, cacheTape);
91
98
  if (mode === 'proxy-catch' && typeof prevRecord !== 'undefined') {
@@ -97,7 +104,8 @@ const createBoundary = (fn) => {
97
104
  // Create an error record
98
105
  const errorRecord = {
99
106
  input: args,
100
- error: error.message
107
+ error: error.message,
108
+ timing
101
109
  };
102
110
  if (hasRun) {
103
111
  runLog.push(errorRecord);
@@ -110,7 +118,8 @@ const createBoundary = (fn) => {
110
118
  // Create a success record
111
119
  const successRecord = {
112
120
  input: args,
113
- output: result
121
+ output: result,
122
+ timing
114
123
  };
115
124
  if (hasRun) {
116
125
  runLog.push(successRecord);
@@ -1 +1 @@
1
- {"version":3,"file":"boundary.js","sourceRoot":"","sources":["../../src/utils/boundary.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"boundary.js","sourceRoot":"","sources":["../../src/utils/boundary.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgehive/task",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "license": "MIT",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -25,6 +25,7 @@
25
25
  "build": "tsc",
26
26
  "dev": "tsc --watch",
27
27
  "clean": "rm -rf dist",
28
- "test": "jest"
28
+ "test": "jest",
29
+ "lint:fix": "eslint src --ext .ts --fix"
29
30
  }
30
31
  }
package/src/index.ts CHANGED
@@ -8,6 +8,13 @@ import {
8
8
  type BoundaryRecord,
9
9
  type BoundaryTapeData
10
10
  } from './utils/boundary'
11
+ import {
12
+ TimingTracker,
13
+ type Metric,
14
+ type TimingInfo,
15
+ validateMetric,
16
+ createMetric
17
+ } from './types'
11
18
 
12
19
  export interface Task {
13
20
  id: string;
@@ -31,6 +38,17 @@ export type {
31
38
  BoundaryTapeData
32
39
  } from './utils/boundary'
33
40
 
41
+ // Re-export timing and metrics types for external use
42
+ export type {
43
+ TimingInfo,
44
+ Metric,
45
+ BoundaryTimingRecord,
46
+ BaseExecutionRecord
47
+ } from './types'
48
+
49
+ // Re-export timing and metrics utilities for external use
50
+ export { TimingTracker, validateMetric, createMetric }
51
+
34
52
  // Re-export Schema for external use
35
53
  export { Schema }
36
54
 
@@ -50,9 +68,6 @@ export interface ReplayConfig<B extends Boundaries = Boundaries> {
50
68
  }
51
69
  }
52
70
 
53
- // ToDo: Add a type for the boundaries data
54
-
55
-
56
71
  // Make BoundaryLog generic
57
72
  export type BoundaryLog<I extends unknown[] = unknown[], O = unknown> = BoundaryRecord<I, O>;
58
73
 
@@ -79,6 +94,10 @@ export interface ExecutionRecord<InputType = unknown, OutputType = unknown, B ex
79
94
  taskName?: string
80
95
  /** Additional context metadata */
81
96
  metadata?: Record<string, string>
97
+ /** Array of collected metrics */
98
+ metrics?: Metric[]
99
+ /** Main function execution timing */
100
+ timing?: TimingInfo
82
101
  /** The type of execution record - computed from output/error state */
83
102
  type: 'success' | 'error' | 'pending'
84
103
  }
@@ -143,6 +162,7 @@ export type InferSchemaType<S> = S extends Schema<any> ? InferSchema<S> : Record
143
162
  // When adding new execution boundaries, add their types here
144
163
  export type ExecutionRecordBoundaries = {
145
164
  setMetadata: (key: string, value: string) => Promise<void>
165
+ setMetrics: (metric: Metric) => Promise<void>
146
166
  // Future execution boundaries can be added here:
147
167
  // setContext: (context: Record<string, unknown>) => Promise<void>
148
168
  // addTag: (tag: string) => Promise<void>
@@ -172,7 +192,11 @@ export const Task = class Task<
172
192
  B extends Boundaries = Boundaries,
173
193
  Func extends BaseFunction = BaseFunction
174
194
  > implements TaskInstanceType<Func, B> {
175
- public version: string = '0.1.7'
195
+ public version: string = '0.1.8'
196
+
197
+ // Static property for global listener
198
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
199
+ static globalListener?: (record: ExecutionRecord<any, any, any>) => Promise<void>
176
200
 
177
201
  _fn: Func
178
202
  _mode: Mode
@@ -190,6 +214,29 @@ export const Task = class Task<
190
214
  _schema: Schema<Record<string, SchemaType>> | undefined
191
215
  _listener?: ((record: ExecutionRecord<Parameters<Func>[0], ReturnType<Func>, B>) => void) | undefined
192
216
 
217
+ // Static method to set global listener
218
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
219
+ static listenExecutionRecords(listener: (record: ExecutionRecord<any, any, any>) => Promise<void>): void {
220
+ this.globalListener = listener
221
+ }
222
+
223
+ // Static method to emit to global listener with error handling
224
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
225
+ static emitExecutionRecord(record: ExecutionRecord<any, any, any>): void {
226
+ if (this.globalListener) {
227
+ // Call listener on next tick to avoid blocking task execution
228
+ process.nextTick(async () => {
229
+ try {
230
+ await this.globalListener!(record)
231
+ } catch (error) {
232
+ // Log error but don't affect task execution
233
+ // eslint-disable-next-line no-console
234
+ console.error('ExecutionRecord listener error:', error)
235
+ }
236
+ })
237
+ }
238
+ }
239
+
193
240
  constructor (fn: Func, conf: TaskConfig<B> = {
194
241
  name: undefined,
195
242
  description: undefined,
@@ -306,9 +353,13 @@ export const Task = class Task<
306
353
  Plus all the boundary data
307
354
  */
308
355
  emit (data: ExecutionRecord<Parameters<Func>[0], ReturnType<Func>, B>): void {
309
- if (typeof this._listener === 'undefined') { return }
356
+ // Emit to instance listener
357
+ if (typeof this._listener !== 'undefined') {
358
+ this._listener(data)
359
+ }
310
360
 
311
- this._listener(data)
361
+ // Emit to global listener (non-blocking)
362
+ Task.emitExecutionRecord(data)
312
363
  }
313
364
 
314
365
  getBoundaries (): WrappedBoundaries<B> {
@@ -373,16 +424,29 @@ export const Task = class Task<
373
424
  * 2. Update the ExecutionRecordBoundaries type to include the new boundary
374
425
  * 3. That's it! The boundary will be available in all tasks automatically
375
426
  */
376
- _createExecutionBoundaries(metadata: Record<string, string>): Record<string, WrappedBoundaryFunction> {
427
+ _createExecutionBoundaries(metadata: Record<string, string>, metrics: Metric[]): Record<string, WrappedBoundaryFunction> {
377
428
  return {
378
429
  // Allows setting metadata key-value pairs from within task execution
379
430
  setMetadata: createBoundary(async (...args: unknown[]): Promise<void> => {
380
431
  const [key, value] = args as [string, string]
381
432
  metadata[key] = value
433
+ }),
434
+
435
+ // Allows setting metrics from within task execution
436
+ setMetrics: createBoundary(async (...args: unknown[]): Promise<void> => {
437
+ const [metric] = args as [Metric]
438
+
439
+ // Validate the metric
440
+ if (!validateMetric(metric)) {
441
+ throw new Error(`Invalid metric provided: ${JSON.stringify(metric)}`)
442
+ }
443
+
444
+ // Add to metrics array
445
+ metrics.push(metric)
382
446
  })
383
447
 
384
448
  // Future execution boundaries can be added here:
385
- // addMetrics: createBoundary(async (...args: unknown[]): Promise<void> => { ... }),
449
+ // setContext: createBoundary(async (...args: unknown[]): Promise<void> => { ... }),
386
450
  }
387
451
  }
388
452
 
@@ -441,12 +505,16 @@ export const Task = class Task<
441
505
  // Need to implement that task have a ctx and setMetadata({key, value}) boundary
442
506
  const metadata = {} as Record<string, string>
443
507
 
508
+ // Metrics array is empty at start. Then will be populated during task execution
509
+ const metrics: Metric[] = []
510
+
444
511
  // Initialize log item (without type initially)
445
512
  const logItemBase = {
446
513
  input: argv as Parameters<Func>[0],
447
514
  boundaries: {} as BoundaryLogsFor<B>,
448
515
  taskName: this._name,
449
- metadata: metadata || {}
516
+ metadata: metadata || {},
517
+ metrics
450
518
  }
451
519
 
452
520
  // Create the log item with computed type
@@ -462,8 +530,8 @@ export const Task = class Task<
462
530
  mode: this._mode
463
531
  })
464
532
 
465
- // Create and inject execution record boundaries (setMetadata, etc.)
466
- const executionRecordBoundaries = this._createExecutionBoundaries(metadata)
533
+ // Create and inject execution record boundaries (setMetadata, setMetrics, etc.)
534
+ const executionRecordBoundaries = this._createExecutionBoundaries(metadata, metrics)
467
535
  const allBoundaries = {
468
536
  ...executionBoundaries,
469
537
  ...executionRecordBoundaries
@@ -504,6 +572,10 @@ export const Task = class Task<
504
572
  let output: Awaited<ReturnType<Func>> | null = null
505
573
  let error: Error | null = null
506
574
 
575
+ // Start timing for main function execution
576
+ const timer = TimingTracker.create()
577
+ timer.start()
578
+
507
579
  try {
508
580
  // Execute the task function
509
581
  output = await this._fn(
@@ -520,6 +592,12 @@ export const Task = class Task<
520
592
  error = new Error(errorMessage)
521
593
  }
522
594
 
595
+ // Capture timing for main function execution
596
+ const timing = timer.end()
597
+ if (timing) {
598
+ logItem.timing = timing
599
+ }
600
+
523
601
  // Process boundary data after execution (both success and error cases)
524
602
  const boundariesRunLog: BoundaryLogsFor<B> = {} as BoundaryLogsFor<B>
525
603
 
@@ -571,12 +649,17 @@ export const Task = class Task<
571
649
  // Extract the input from the execution log
572
650
  const argv = executionLog.input
573
651
 
652
+ // Initialize metrics array for replay - start with original metrics if any
653
+ const metrics: Metric[] = executionLog.metrics ? [...executionLog.metrics] : []
654
+
574
655
  // Initialize log item for this replay (without type initially)
575
656
  const logItemBase = {
576
657
  input: argv,
577
658
  boundaries: {} as BoundaryLogsFor<B>,
578
659
  taskName: this._name,
579
- metadata: executionLog.metadata || {}
660
+ metadata: executionLog.metadata || {},
661
+ metrics,
662
+ timing: executionLog.timing // Preserve original timing
580
663
  }
581
664
 
582
665
  // Create the log item with computed type
@@ -607,10 +690,10 @@ export const Task = class Task<
607
690
  boundaryModes: config.boundaries
608
691
  })
609
692
 
610
- // Create and inject execution record boundaries (setMetadata, etc.)
693
+ // Create and inject execution record boundaries (setMetadata, setMetrics, etc.)
611
694
  // Clone the metadata to avoid mutating the original metadata
612
695
  const replayMetadata = { ...(logItem.metadata || {}) }
613
- const executionRecordBoundaries = this._createExecutionBoundaries(replayMetadata)
696
+ const executionRecordBoundaries = this._createExecutionBoundaries(replayMetadata, metrics)
614
697
  const allBoundaries = {
615
698
  ...executionBoundaries,
616
699
  ...executionRecordBoundaries
@@ -30,11 +30,22 @@ describe('Listener with boundaries', () => {
30
30
  boundaries: {
31
31
  getTen: [{
32
32
  input: [],
33
- output: 10
33
+ output: 10,
34
+ timing: expect.objectContaining({
35
+ startTime: expect.any(Number),
36
+ endTime: expect.any(Number),
37
+ duration: expect.any(Number)
38
+ })
34
39
  }]
35
40
  },
36
41
  taskName: 'test',
37
42
  metadata: {},
43
+ metrics: [],
44
+ timing: expect.objectContaining({
45
+ startTime: expect.any(Number),
46
+ endTime: expect.any(Number),
47
+ duration: expect.any(Number)
48
+ }),
38
49
  type: 'success'
39
50
  }])
40
51
  })
@@ -73,11 +84,22 @@ describe('Listener with boundaries', () => {
73
84
  boundaries: {
74
85
  getTen: [{
75
86
  input: [],
76
- error: 'Network error'
87
+ error: 'Network error',
88
+ timing: expect.objectContaining({
89
+ startTime: expect.any(Number),
90
+ endTime: expect.any(Number),
91
+ duration: expect.any(Number)
92
+ })
77
93
  }]
78
94
  },
79
95
  taskName: 'test',
80
96
  metadata: {},
97
+ metrics: [],
98
+ timing: expect.objectContaining({
99
+ startTime: expect.any(Number),
100
+ endTime: expect.any(Number),
101
+ duration: expect.any(Number)
102
+ }),
81
103
  type: 'error'
82
104
  }])
83
105
  })
@@ -109,11 +131,22 @@ describe('Listener with boundaries', () => {
109
131
  boundaries: {
110
132
  addNumbers: [{
111
133
  input: [3, 7],
112
- output: 10
134
+ output: 10,
135
+ timing: expect.objectContaining({
136
+ startTime: expect.any(Number),
137
+ endTime: expect.any(Number),
138
+ duration: expect.any(Number)
139
+ })
113
140
  }]
114
141
  },
115
142
  taskName: 'test',
116
143
  metadata: {},
144
+ metrics: [],
145
+ timing: expect.objectContaining({
146
+ startTime: expect.any(Number),
147
+ endTime: expect.any(Number),
148
+ duration: expect.any(Number)
149
+ }),
117
150
  type: 'success'
118
151
  }])
119
152
  })
@@ -147,11 +180,22 @@ describe('Listener with boundaries', () => {
147
180
  boundaries: {
148
181
  processValue: [{
149
182
  input: [undefined],
150
- output: 0
183
+ output: 0,
184
+ timing: expect.objectContaining({
185
+ startTime: expect.any(Number),
186
+ endTime: expect.any(Number),
187
+ duration: expect.any(Number)
188
+ })
151
189
  }]
152
190
  },
153
191
  taskName: 'test',
154
192
  metadata: {},
193
+ metrics: [],
194
+ timing: expect.objectContaining({
195
+ startTime: expect.any(Number),
196
+ endTime: expect.any(Number),
197
+ duration: expect.any(Number)
198
+ }),
155
199
  type: 'success'
156
200
  }])
157
201
  })
@@ -187,16 +231,32 @@ describe('Listener with boundaries', () => {
187
231
  multiplyByTwo: [
188
232
  {
189
233
  input: [3],
190
- output: 6
234
+ output: 6,
235
+ timing: expect.objectContaining({
236
+ startTime: expect.any(Number),
237
+ endTime: expect.any(Number),
238
+ duration: expect.any(Number)
239
+ })
191
240
  },
192
241
  {
193
242
  input: [6],
194
- output: 12
243
+ output: 12,
244
+ timing: expect.objectContaining({
245
+ startTime: expect.any(Number),
246
+ endTime: expect.any(Number),
247
+ duration: expect.any(Number)
248
+ })
195
249
  }
196
250
  ]
197
251
  },
198
252
  taskName: 'test',
199
253
  metadata: {},
254
+ metrics: [],
255
+ timing: expect.objectContaining({
256
+ startTime: expect.any(Number),
257
+ endTime: expect.any(Number),
258
+ duration: expect.any(Number)
259
+ }),
200
260
  type: 'success'
201
261
  }])
202
262
  })
@@ -238,11 +298,22 @@ describe('Listener with boundaries', () => {
238
298
  boundaries: {
239
299
  getResult: [{
240
300
  input: [3],
241
- error: 'Number too small'
301
+ error: 'Number too small',
302
+ timing: expect.objectContaining({
303
+ startTime: expect.any(Number),
304
+ endTime: expect.any(Number),
305
+ duration: expect.any(Number)
306
+ })
242
307
  }]
243
308
  },
244
309
  taskName: 'test',
245
310
  metadata: {},
311
+ metrics: [],
312
+ timing: expect.objectContaining({
313
+ startTime: expect.any(Number),
314
+ endTime: expect.any(Number),
315
+ duration: expect.any(Number)
316
+ }),
246
317
  type: 'success'
247
318
  }])
248
319
  })
@@ -18,6 +18,12 @@ describe('Add listener', () => {
18
18
  boundaries: {},
19
19
  taskName: undefined,
20
20
  metadata: {},
21
+ metrics: [],
22
+ timing: expect.objectContaining({
23
+ startTime: expect.any(Number),
24
+ endTime: expect.any(Number),
25
+ duration: expect.any(Number)
26
+ }),
21
27
  type: 'success'
22
28
  }])
23
29
  })
@@ -44,6 +50,12 @@ describe('Add listener', () => {
44
50
  boundaries: {},
45
51
  taskName: undefined,
46
52
  metadata: {},
53
+ metrics: [],
54
+ timing: expect.objectContaining({
55
+ startTime: expect.any(Number),
56
+ endTime: expect.any(Number),
57
+ duration: expect.any(Number)
58
+ }),
47
59
  type: 'error'
48
60
  }])
49
61
  })
@@ -73,6 +85,12 @@ describe('Add listener', () => {
73
85
  boundaries: {},
74
86
  taskName: undefined,
75
87
  metadata: {},
88
+ metrics: [],
89
+ timing: expect.objectContaining({
90
+ startTime: expect.any(Number),
91
+ endTime: expect.any(Number),
92
+ duration: expect.any(Number)
93
+ }),
76
94
  type: 'error'
77
95
  }])
78
96
  })
@@ -97,6 +115,12 @@ describe('Add listener', () => {
97
115
  boundaries: {},
98
116
  taskName: undefined,
99
117
  metadata: {},
118
+ metrics: [],
119
+ timing: expect.objectContaining({
120
+ startTime: expect.any(Number),
121
+ endTime: expect.any(Number),
122
+ duration: expect.any(Number)
123
+ }),
100
124
  type: 'success'
101
125
  },
102
126
  {
@@ -105,6 +129,12 @@ describe('Add listener', () => {
105
129
  boundaries: {},
106
130
  taskName: undefined,
107
131
  metadata: {},
132
+ metrics: [],
133
+ timing: expect.objectContaining({
134
+ startTime: expect.any(Number),
135
+ endTime: expect.any(Number),
136
+ duration: expect.any(Number)
137
+ }),
108
138
  type: 'success'
109
139
  }
110
140
  ])
@@ -132,6 +162,12 @@ describe('Add listener', () => {
132
162
  boundaries: {},
133
163
  taskName: undefined,
134
164
  metadata: {},
165
+ metrics: [],
166
+ timing: expect.objectContaining({
167
+ startTime: expect.any(Number),
168
+ endTime: expect.any(Number),
169
+ duration: expect.any(Number)
170
+ }),
135
171
  type: 'success'
136
172
  }])
137
173
  })
@@ -47,7 +47,15 @@ describe('Proxy pass mode', function () {
47
47
  },
48
48
  boundariesData: {
49
49
  fetchIncrement: [
50
- { input: [{ value: 5 }], output: 5 }
50
+ {
51
+ input: [{ value: 5 }],
52
+ output: 5,
53
+ timing: {
54
+ startTime: 1000,
55
+ endTime: 1100,
56
+ duration: 100
57
+ }
58
+ }
51
59
  ]
52
60
  },
53
61
  mode: 'proxy-pass'
@@ -76,7 +84,15 @@ describe('Proxy pass mode', function () {
76
84
  },
77
85
  boundariesData: {
78
86
  fetchIncrement: [
79
- { input: [{ value: 6 }], output: 5 }
87
+ {
88
+ input: [{ value: 6 }],
89
+ output: 5,
90
+ timing: {
91
+ startTime: 1000,
92
+ endTime: 1100,
93
+ duration: 100
94
+ }
95
+ }
80
96
  ]
81
97
  },
82
98
  mode: 'proxy-pass'
@@ -108,7 +124,15 @@ describe('Proxy catch mode', function () {
108
124
  },
109
125
  boundariesData: {
110
126
  fetchIncrement: [
111
- { input: [{ value: 5 }], output: 5 }
127
+ {
128
+ input: [{ value: 5 }],
129
+ output: 5,
130
+ timing: {
131
+ startTime: 1000,
132
+ endTime: 1100,
133
+ duration: 100
134
+ }
135
+ }
112
136
  ]
113
137
  },
114
138
  mode: 'proxy-catch'
@@ -137,7 +161,15 @@ describe('Proxy catch mode', function () {
137
161
  },
138
162
  boundariesData: {
139
163
  fetchIncrement: [
140
- { input: [{ value: 5 }], output: 5 }
164
+ {
165
+ input: [{ value: 5 }],
166
+ output: 5,
167
+ timing: {
168
+ startTime: 1000,
169
+ endTime: 1100,
170
+ duration: 100
171
+ }
172
+ }
141
173
  ]
142
174
  },
143
175
  mode: 'proxy-catch'
@@ -169,7 +201,15 @@ describe('Replay mode', function () {
169
201
  },
170
202
  boundariesData: {
171
203
  fetchIncrement: [
172
- { input: [{ value: 5 }], output: 5 }
204
+ {
205
+ input: [{ value: 5 }],
206
+ output: 5,
207
+ timing: {
208
+ startTime: 1000,
209
+ endTime: 1100,
210
+ duration: 100
211
+ }
212
+ }
173
213
  ]
174
214
  },
175
215
  mode: 'replay'
@@ -92,13 +92,23 @@ describe('execution-record-boundaries', () => {
92
92
  expect(record.boundaries.multiply).toHaveLength(1)
93
93
  expect(record.boundaries.multiply[0]).toEqual({
94
94
  input: [3],
95
- output: 6
95
+ output: 6,
96
+ timing: expect.objectContaining({
97
+ startTime: expect.any(Number),
98
+ endTime: expect.any(Number),
99
+ duration: expect.any(Number)
100
+ })
96
101
  })
97
102
 
98
103
  expect(record.boundaries.fetchData).toHaveLength(1)
99
104
  expect(record.boundaries.fetchData[0]).toEqual({
100
105
  input: ['test'],
101
- output: 'fetched-test'
106
+ output: 'fetched-test',
107
+ timing: expect.objectContaining({
108
+ startTime: expect.any(Number),
109
+ endTime: expect.any(Number),
110
+ duration: expect.any(Number)
111
+ })
102
112
  })
103
113
  })
104
114