@forgehive/record-tape 0.1.6 → 0.2.1

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.
@@ -5,18 +5,20 @@ const index_1 = require("../index");
5
5
  describe('Task listener', () => {
6
6
  it('Should listen to task events', async () => {
7
7
  const tape = new index_1.RecordTape({});
8
- const task = new task_1.Task(async (_input) => {
9
- return { value: 1, foo: true };
8
+ const task = (0, task_1.createTask)({
9
+ name: 'test',
10
+ schema: new task_1.Schema({}),
11
+ boundaries: {},
12
+ fn: async (_input) => {
13
+ return { value: 1, foo: true };
14
+ }
10
15
  });
11
16
  task.addListener((record) => {
12
- const logItem = record.error
13
- ? { input: record.input, error: record.error, boundaries: record.boundaries }
14
- : { input: record.input, output: record.output, boundaries: record.boundaries };
15
- tape.addLogItem('test', logItem);
17
+ tape.push(record);
16
18
  });
17
19
  await task.run({});
18
20
  expect(tape.getLog()).toEqual([
19
- { name: 'test', type: 'success', input: {}, output: { value: 1, foo: true }, boundaries: {} }
21
+ { type: 'success', input: {}, output: { value: 1, foo: true }, boundaries: {}, metadata: {}, taskName: 'test' }
20
22
  ]);
21
23
  });
22
24
  it('Should has errors and sucess items', async () => {
@@ -27,11 +29,9 @@ describe('Task listener', () => {
27
29
  return { result: input.value * 2 };
28
30
  });
29
31
  const tape = new index_1.RecordTape({});
32
+ task.setName('test');
30
33
  task.addListener((record) => {
31
- const logItem = record.error
32
- ? { input: record.input, error: record.error, boundaries: record.boundaries }
33
- : { input: record.input, output: record.output, boundaries: record.boundaries };
34
- tape.addLogItem('test', logItem);
34
+ tape.push(record);
35
35
  });
36
36
  try {
37
37
  await task.run({ value: 5 });
@@ -42,8 +42,8 @@ describe('Task listener', () => {
42
42
  await task.run({ value: 15 });
43
43
  const log = tape.getLog();
44
44
  expect(log).toEqual([
45
- { name: 'test', type: 'error', input: { value: 5 }, error: 'Value is not between 10 and 20', boundaries: {} },
46
- { name: 'test', type: 'success', input: { value: 15 }, output: { result: 30 }, boundaries: {} }
45
+ { type: 'error', input: { value: 5 }, error: 'Value is not between 10 and 20', boundaries: {}, metadata: {}, output: undefined, taskName: 'test' },
46
+ { type: 'success', input: { value: 15 }, output: { result: 30 }, boundaries: {}, metadata: {}, taskName: 'test' }
47
47
  ]);
48
48
  });
49
49
  it('Should get types from task', async () => {
@@ -58,27 +58,29 @@ describe('Task listener', () => {
58
58
  }
59
59
  };
60
60
  // Create the task using createTask
61
- const task = (0, task_1.createTask)(schema, boundaries, async (input, { multiply }) => {
62
- const result = await multiply(input.value);
63
- return { result };
61
+ const task = (0, task_1.createTask)({
62
+ schema,
63
+ boundaries,
64
+ fn: async (input, { multiply }) => {
65
+ const result = await multiply(input.value);
66
+ return { result };
67
+ }
64
68
  });
65
69
  const tape = new index_1.RecordTape({});
66
70
  task.addListener((record) => {
67
- const logItem = record.error
68
- ? { input: record.input, error: record.error, boundaries: record.boundaries }
69
- : { input: record.input, output: record.output, boundaries: record.boundaries };
70
- tape.addLogItem('test', logItem);
71
+ tape.push(record);
71
72
  });
72
73
  await task.run({ value: 5 });
73
74
  expect(tape.getLog()).toEqual([
74
75
  {
75
- name: 'test',
76
76
  type: 'success',
77
77
  input: { value: 5 },
78
78
  output: { result: 10 },
79
79
  boundaries: {
80
80
  multiply: [{ input: [5], output: 10 }]
81
- }
81
+ },
82
+ metadata: {},
83
+ taskName: undefined
82
84
  }
83
85
  ]);
84
86
  });
@@ -95,26 +97,28 @@ describe('Task listener', () => {
95
97
  }
96
98
  };
97
99
  // Create the task using createTask
98
- const task = (0, task_1.createTask)(schema, boundaries, async (input, { multiply }) => {
99
- const result = await multiply(input.value);
100
- return { result };
100
+ const task = (0, task_1.createTask)({
101
+ schema,
102
+ boundaries,
103
+ fn: async (input, { multiply }) => {
104
+ const result = await multiply(input.value);
105
+ return { result };
106
+ }
101
107
  });
102
108
  task.addListener((record) => {
103
- const logItem = record.error
104
- ? { input: record.input, error: record.error, boundaries: record.boundaries }
105
- : { input: record.input, output: record.output, boundaries: record.boundaries };
106
- tape.addLogItem('test', logItem);
109
+ tape.push(record);
107
110
  });
108
111
  await task.run({ value: 5 });
109
112
  expect(tape.getLog()).toEqual([
110
113
  {
111
- name: 'test',
112
114
  type: 'success',
113
115
  input: { value: 5 },
114
116
  output: { result: 10 },
115
117
  boundaries: {
116
118
  multiply: [{ input: [5], output: 10 }]
117
- }
119
+ },
120
+ metadata: {},
121
+ taskName: undefined
118
122
  }
119
123
  ]);
120
124
  });
@@ -1 +1 @@
1
- {"version":3,"file":"task-listener.test.js","sourceRoot":"","sources":["../../src/tests/task-listener.test.ts"],"names":[],"mappings":";;AAAA,0CAA0D;AAC1D,oCAA8C;AAE9C,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAI5C,MAAM,IAAI,GAAG,IAAI,kBAAU,CAAwB,EAAE,CAAC,CAAA;QACtD,MAAM,IAAI,GAAG,IAAI,WAAI,CACnB,KAAK,EAAE,MAAiB,EAAuB,EAAE;YAC/C,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;QAChC,CAAC,CACF,CAAA;QAED,IAAI,CAAC,WAAW,CAAwB,CAAC,MAAM,EAAE,EAAE;YACjD,MAAM,OAAO,GAAmC,MAAM,CAAC,KAAK;gBAC1D,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE;gBAC7E,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAoB,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAA;YAE/F,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAElB,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;YAC5B,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;SAC9F,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,IAAI,GAAG,IAAI,WAAI,CACnB,KAAK,EAAE,KAAwB,EAA+B,EAAE;YAC9D,IAAI,KAAK,CAAC,KAAK,GAAG,EAAE,IAAI,KAAK,CAAC,KAAK,GAAG,EAAE,EAAE,CAAC;gBACzC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;YACnD,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,CAAA;QACpC,CAAC,CACF,CAAA;QAED,MAAM,IAAI,GAAG,IAAI,kBAAU,CAAwC,EAAE,CAAC,CAAA;QAEtE,IAAI,CAAC,WAAW,CAAwC,CAAC,MAAM,EAAE,EAAE;YACjE,MAAM,OAAO,GAAmD,MAAM,CAAC,KAAK;gBAC1E,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE;gBAC7E,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAA4B,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAA;YAEvG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;QAC9B,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YAChB,mBAAmB;QACrB,CAAC;QAED,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAA;QAE7B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAA;QAEzB,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;YAClB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,gCAAgC,EAAE,UAAU,EAAE,EAAE,EAAE;YAC7G,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;SAChG,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,+BAA+B;QAC/B,MAAM,MAAM,GAAG,IAAI,aAAM,CAAC;YACxB,KAAK,EAAE,aAAM,CAAC,MAAM,EAAE;SACvB,CAAC,CAAA;QAEF,wBAAwB;QACxB,MAAM,UAAU,GAAG;YACjB,QAAQ,EAAE,KAAK,EAAE,KAAa,EAAmB,EAAE;gBACjD,OAAO,KAAK,GAAG,CAAC,CAAA;YAClB,CAAC;SACF,CAAA;QAED,mCAAmC;QACnC,MAAM,IAAI,GAAG,IAAA,iBAAU,EACrB,MAAM,EACN,UAAU,EACV,KAAK,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;YAC5B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YAC1C,OAAO,EAAE,MAAM,EAAE,CAAA;QACnB,CAAC,CACF,CAAA;QAKD,MAAM,IAAI,GAAG,IAAI,kBAAU,CAAwB,EAAE,CAAC,CAAA;QAEtD,IAAI,CAAC,WAAW,CAAwB,CAAC,MAAM,EAAE,EAAE;YACjD,MAAM,OAAO,GAAmC,MAAM,CAAC,KAAK;gBAC1D,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE;gBAC7E,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAoB,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAA;YAE/F,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;QAE5B,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;YAC5B;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;gBACnB,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;gBACtB,UAAU,EAAE;oBACV,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;iBACvC;aACF;SACF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAI5D,MAAM,IAAI,GAAG,IAAI,kBAAU,CAAwB,EAAE,CAAC,CAAA;QAEtD,+BAA+B;QAC/B,MAAM,MAAM,GAAG,IAAI,aAAM,CAAC;YACxB,KAAK,EAAE,aAAM,CAAC,MAAM,EAAE;SACvB,CAAC,CAAA;QAEF,wBAAwB;QACxB,MAAM,UAAU,GAAG;YACjB,QAAQ,EAAE,KAAK,EAAE,KAAa,EAAmB,EAAE;gBACjD,OAAO,KAAK,GAAG,CAAC,CAAA;YAClB,CAAC;SACF,CAAA;QAED,mCAAmC;QACnC,MAAM,IAAI,GAAG,IAAA,iBAAU,EACrB,MAAM,EACN,UAAU,EACV,KAAK,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;YAC5B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YAC1C,OAAO,EAAE,MAAM,EAAE,CAAA;QACnB,CAAC,CACF,CAAA;QAED,IAAI,CAAC,WAAW,CAAwB,CAAC,MAAM,EAAE,EAAE;YACjD,MAAM,OAAO,GAAmC,MAAM,CAAC,KAAK;gBAC1D,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE;gBAC7E,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAoB,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAA;YAE/F,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;QAE5B,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;YAC5B;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;gBACnB,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;gBACtB,UAAU,EAAE;oBACV,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;iBACvC;aACF;SACF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"task-listener.test.js","sourceRoot":"","sources":["../../src/tests/task-listener.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgehive/record-tape",
3
- "version": "0.1.6",
3
+ "version": "0.2.1",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -8,7 +8,7 @@
8
8
  "access": "public",
9
9
  "dependencies": {
10
10
  "@forgehive/schema": "^0.1.4",
11
- "@forgehive/task": "^0.1.13"
11
+ "@forgehive/task": "^0.2.0"
12
12
  }
13
13
  },
14
14
  "devDependencies": {
@@ -19,8 +19,8 @@
19
19
  "typescript": "^5.3.3"
20
20
  },
21
21
  "dependencies": {
22
- "@forgehive/schema": "0.1.4",
23
- "@forgehive/task": "0.1.13"
22
+ "@forgehive/task": "0.2.1",
23
+ "@forgehive/schema": "0.1.4"
24
24
  },
25
25
  "scripts": {
26
26
  "build": "tsc",
package/src/index.ts CHANGED
@@ -2,185 +2,60 @@ import fs from 'fs'
2
2
  import path from 'path'
3
3
  import { type ExecutionRecord, type Boundaries } from '@forgehive/task'
4
4
 
5
- export interface LogRecord<TInput = unknown, TOutput = unknown, B extends Boundaries = Boundaries> extends ExecutionRecord<TInput, TOutput, B> {
6
- name: string
7
- type: 'success' | 'error'
8
- context?: Record<string, string>
9
- }
10
-
11
- export interface SuccessLogItem<TInput = unknown, TOutput = unknown> {
12
- input: TInput
13
- output: TOutput
14
- boundaries?: Record<string, unknown>
15
- }
16
-
17
- export interface ErrorLogItem<TInput = unknown> {
18
- input: TInput
19
- error: unknown
20
- boundaries?: Record<string, unknown>
21
- }
22
-
23
- export type LogItem<TInput = unknown, TOutput = unknown> = SuccessLogItem<TInput, TOutput> | ErrorLogItem<TInput>
24
-
25
- // Additional type to handle TaskRecord compatibility
26
- export type TaskLogItem<TInput = unknown, TOutput = unknown> = LogItem<TInput, TOutput> | {
27
- input: TInput;
28
- output?: TOutput;
29
- error?: unknown;
30
- boundaries?: Record<string, unknown>;
5
+ export interface GenericExecutionRecord<TInput = unknown, TOutput = unknown, B extends Boundaries = Boundaries> extends ExecutionRecord<TInput, TOutput, B> {
31
6
  }
32
7
 
33
8
  interface Config<TInput = unknown, TOutput = unknown, B extends Boundaries = Boundaries> {
34
9
  path?: fs.PathLike
35
- log?: LogRecord<TInput, TOutput, B>[]
10
+ log?: GenericExecutionRecord<TInput, TOutput, B>[]
36
11
  boundaries?: Record<string, unknown>
37
12
  }
38
13
 
39
- export type Mode = 'record' | 'replay'
40
-
41
14
  export class RecordTape<TInput = unknown, TOutput = unknown, B extends Boundaries = Boundaries> {
42
15
  private _path: fs.PathLike | undefined
43
- private _mode: Mode
44
- private _log: LogRecord<TInput, TOutput, B>[]
16
+ private _log: GenericExecutionRecord<TInput, TOutput, B>[]
45
17
 
46
18
  constructor(config: Config<TInput, TOutput, B> = {}) {
47
19
  this._path = typeof config.path === 'string' ? `${config.path}.log` : undefined
48
20
  this._log = config.log ?? []
49
- this._mode = 'record'
50
21
  }
51
22
 
52
23
  // Data functions
53
- getLog(): LogRecord<TInput, TOutput, B>[] {
24
+ getLog(): GenericExecutionRecord<TInput, TOutput, B>[] {
54
25
  return this._log
55
26
  }
56
27
 
57
- getMode(): Mode {
58
- return this._mode
28
+ getLength(): number {
29
+ return this._log.length
59
30
  }
60
31
 
61
- setMode(mode: Mode): void {
62
- this._mode = mode
63
- }
64
-
65
- addLogItem(name: string, logItem: LogItem<TInput, TOutput>): void {
66
- if (this._mode === 'replay') {
67
- return
68
- }
69
-
70
- // Format boundaries to ensure both error and output fields are set if needed
71
- const formattedBoundaries: Record<string, unknown> = {}
72
- if (logItem.boundaries) {
73
- for (const key in logItem.boundaries) {
74
- // Check if the source is from safe-run (if it has error field in entries)
75
- const boundaryEntries = logItem.boundaries[key] as Array<Record<string, unknown>>
76
- const isSafeRun = boundaryEntries.some(entry => entry.error !== undefined)
77
-
78
- formattedBoundaries[key] = boundaryEntries.map(entry => {
79
- // Only add error field if it's from safe-run
80
- return isSafeRun ?
81
- {
82
- input: entry.input,
83
- output: entry.output ?? null,
84
- error: entry.error ?? null
85
- } :
86
- {
87
- input: entry.input,
88
- output: entry.output
89
- }
90
- })
91
- }
92
- }
93
-
94
- // Handle LogItem interface - need to type cast to access properties safely
95
- const typedLogItem = logItem as (SuccessLogItem<TInput, TOutput> | ErrorLogItem<TInput>)
96
-
97
- if ('output' in typedLogItem && typedLogItem.output !== undefined) {
98
- const { input, output } = typedLogItem
99
- this._log.push({
100
- name,
101
- type: 'success',
102
- input,
103
- output,
104
- boundaries: formattedBoundaries
105
- } as LogRecord<TInput, TOutput, B>)
106
- } else if ('error' in typedLogItem && typedLogItem.error !== undefined) {
107
- const { input, error } = typedLogItem
108
- this._log.push({
109
- name,
110
- type: 'error',
111
- input,
112
- error,
113
- boundaries: formattedBoundaries
114
- } as LogRecord<TInput, TOutput, B>)
115
- } else {
116
- throw new Error('invalid log item')
117
- }
32
+ shift(): GenericExecutionRecord<TInput, TOutput, B> | undefined {
33
+ return this._log.shift()
118
34
  }
119
35
 
120
36
  push(
121
- name: string,
122
37
  record: ExecutionRecord<TInput, unknown, B>,
123
- context?: Record<string, string>
124
- ): LogRecord<TInput, TOutput, B> {
125
- if (this._mode === 'replay') {
126
- return {} as LogRecord<TInput, TOutput, B>
127
- }
128
-
129
- // For safeRun records, always include both error and output fields
130
- const formattedBoundaries: Record<string, unknown> = {}
131
- if (record.boundaries) {
132
- for (const key in record.boundaries) {
133
- const boundaryArray = record.boundaries[key] as Array<Record<string, unknown>>
134
- formattedBoundaries[key] = boundaryArray.map(entry => {
135
- return {
136
- input: entry.input,
137
- output: entry.output ?? null,
138
- error: entry.error ?? null
139
- }
140
- })
141
- }
142
- }
38
+ metadata?: Record<string, string>
39
+ ): GenericExecutionRecord<TInput, TOutput, B> {
40
+ // Add type if missing
41
+ const recordType = ('type' in record && record.type) ? record.type :
42
+ (record.output !== undefined && record.output !== null) ? 'success' :
43
+ (record.error !== undefined) ? 'error' : 'pending'
44
+
45
+ // Merge metadata from record and parameter (parameter takes precedence)
46
+ const mergedMetadata = { ...record.metadata, ...metadata }
47
+
48
+ const logRecord = {
49
+ ...record,
50
+ type: recordType,
51
+ metadata: mergedMetadata
52
+ } as GenericExecutionRecord<TInput, TOutput, B>
143
53
 
144
- let logRecord: LogRecord<TInput, TOutput, B>
145
-
146
- if ('output' in record && record.output !== undefined) {
147
- const input = record.input
148
- // Handle Promise outputs by setting to null in the log
149
- const output = record.output instanceof Promise ? null : record.output
150
-
151
- logRecord = {
152
- name,
153
- type: 'success',
154
- input,
155
- output,
156
- boundaries: formattedBoundaries,
157
- context
158
- } as LogRecord<TInput, TOutput, B>
159
- this._log.push(logRecord)
160
- } else if ('error' in record && record.error !== undefined) {
161
- const input = record.input
162
- const error = record.error
163
-
164
- logRecord = {
165
- name,
166
- type: 'error',
167
- input,
168
- error,
169
- boundaries: formattedBoundaries,
170
- context
171
- } as LogRecord<TInput, TOutput, B>
172
- this._log.push(logRecord)
173
- } else {
174
- throw new Error('invalid record type')
175
- }
54
+ this._log.push(logRecord)
176
55
 
177
56
  return logRecord
178
57
  }
179
58
 
180
- addLogRecord(logRecord: LogRecord<TInput, TOutput, B>): void {
181
- this._log.push(logRecord)
182
- }
183
-
184
59
  stringify(): string {
185
60
  let log = ''
186
61
  for (const logItem of this._log) {
@@ -190,12 +65,12 @@ export class RecordTape<TInput = unknown, TOutput = unknown, B extends Boundarie
190
65
  return log
191
66
  }
192
67
 
193
- parse(content: string): LogRecord<TInput, TOutput, B>[] {
68
+ parse(content: string): GenericExecutionRecord<TInput, TOutput, B>[] {
194
69
  const items = content.split('\n')
195
- const log: LogRecord<TInput, TOutput, B>[] = []
70
+ const log: GenericExecutionRecord<TInput, TOutput, B>[] = []
196
71
  for (const item of items) {
197
72
  if (item !== '') {
198
- const data = JSON.parse(item) as LogRecord<TInput, TOutput, B>
73
+ const data = JSON.parse(item) as GenericExecutionRecord<TInput, TOutput, B>
199
74
  log.push(data)
200
75
  }
201
76
  }
@@ -218,21 +93,15 @@ export class RecordTape<TInput = unknown, TOutput = unknown, B extends Boundarie
218
93
  return cache
219
94
  }
220
95
 
221
- recordFrom(name: string, task: { _listener?: unknown; setBoundariesData: (data: Record<string, unknown>) => void }): void {
222
- // Add listner
223
- task._listener = async (logItem: LogItem<TInput, TOutput>, _boundaries: Record<string, unknown>): Promise<void> => {
224
- // Only update if mode is record
225
- if (this.getMode() === 'record') {
226
- this.addLogItem(name, logItem)
227
- }
96
+ recordFrom(task: { _listener?: unknown }): void {
97
+ // Add listener for ExecutionRecord
98
+ task._listener = async (executionRecord: ExecutionRecord<TInput, TOutput, B>): Promise<void> => {
99
+ this.push(executionRecord)
228
100
  }
229
-
230
- // Add cache
231
- task.setBoundariesData(this.compileCache())
232
101
  }
233
102
 
234
103
  // Load save functions
235
- async load(): Promise<LogRecord<TInput, TOutput, B>[]> {
104
+ async load(): Promise<GenericExecutionRecord<TInput, TOutput, B>[]> {
236
105
  if (typeof this._path === 'undefined') {
237
106
  return []
238
107
  }
@@ -262,7 +131,7 @@ export class RecordTape<TInput = unknown, TOutput = unknown, B extends Boundarie
262
131
  return this._log
263
132
  }
264
133
 
265
- loadSync(): LogRecord<TInput, TOutput, B>[] {
134
+ loadSync(): GenericExecutionRecord<TInput, TOutput, B>[] {
266
135
  if (typeof this._path === 'undefined') { return [] }
267
136
 
268
137
  const dirpath = path.dirname(this._path.toString())
@@ -281,6 +150,7 @@ export class RecordTape<TInput = unknown, TOutput = unknown, B extends Boundarie
281
150
  return this._log
282
151
  }
283
152
 
153
+ // Save functions
284
154
  async save(): Promise<void> {
285
155
  if (typeof this._path === 'undefined') { return }
286
156
 
@@ -0,0 +1,150 @@
1
+ import { RecordTape } from '../index'
2
+
3
+ describe('RecordTape Data Methods', () => {
4
+ let tape: RecordTape
5
+
6
+ beforeEach(() => {
7
+ tape = new RecordTape()
8
+ })
9
+
10
+ describe('getLength', () => {
11
+ test('should return 0 for empty tape', () => {
12
+ expect(tape.getLength()).toBe(0)
13
+ })
14
+
15
+ test('should return correct length after adding records', () => {
16
+ const record1 = {
17
+ input: { userId: 1 },
18
+ output: { name: 'John' },
19
+ taskName: 'getUser',
20
+ boundaries: {},
21
+ type: 'success' as const
22
+ }
23
+
24
+ const record2 = {
25
+ input: { userId: 2 },
26
+ output: { name: 'Jane' },
27
+ taskName: 'getUser',
28
+ boundaries: {},
29
+ type: 'success' as const
30
+ }
31
+
32
+ tape.push(record1)
33
+ expect(tape.getLength()).toBe(1)
34
+
35
+ tape.push(record2)
36
+ expect(tape.getLength()).toBe(2)
37
+ })
38
+
39
+ test('should return correct length after removing records', () => {
40
+ const record = {
41
+ input: { userId: 1 },
42
+ output: { name: 'John' },
43
+ taskName: 'getUser',
44
+ boundaries: {},
45
+ type: 'success' as const
46
+ }
47
+
48
+ tape.push(record)
49
+ tape.push(record)
50
+ expect(tape.getLength()).toBe(2)
51
+
52
+ tape.shift()
53
+ expect(tape.getLength()).toBe(1)
54
+
55
+ tape.shift()
56
+ expect(tape.getLength()).toBe(0)
57
+ })
58
+ })
59
+
60
+ describe('shift', () => {
61
+ test('should return undefined for empty tape', () => {
62
+ expect(tape.shift()).toBeUndefined()
63
+ })
64
+
65
+ test('should return and remove first record', () => {
66
+ const record1 = {
67
+ input: { userId: 1 },
68
+ output: { name: 'John' },
69
+ taskName: 'getUser',
70
+ boundaries: {},
71
+ type: 'success' as const
72
+ }
73
+
74
+ const record2 = {
75
+ input: { userId: 2 },
76
+ output: { name: 'Jane' },
77
+ taskName: 'getUser',
78
+ boundaries: {},
79
+ type: 'success' as const
80
+ }
81
+
82
+ tape.push(record1)
83
+ tape.push(record2)
84
+
85
+ const shiftedRecord = tape.shift()
86
+
87
+ // Should return the first record
88
+ expect(shiftedRecord).toEqual(expect.objectContaining({
89
+ taskName: 'getUser',
90
+ input: { userId: 1 },
91
+ output: { name: 'John' },
92
+ type: 'success'
93
+ }))
94
+
95
+ // Should have removed the first record
96
+ expect(tape.getLength()).toBe(1)
97
+ expect(tape.getLog()[0]).toEqual(expect.objectContaining({
98
+ taskName: 'getUser',
99
+ input: { userId: 2 },
100
+ output: { name: 'Jane' },
101
+ type: 'success'
102
+ }))
103
+ })
104
+
105
+ test('should work correctly with multiple shifts', () => {
106
+ const records = [
107
+ {
108
+ input: { userId: 1 },
109
+ output: { name: 'John' },
110
+ taskName: 'getUser',
111
+ boundaries: {},
112
+ type: 'success' as const
113
+ },
114
+ {
115
+ input: { userId: 2 },
116
+ output: { name: 'Jane' },
117
+ taskName: 'getUser',
118
+ boundaries: {},
119
+ type: 'success' as const
120
+ },
121
+ {
122
+ input: { userId: 3 },
123
+ output: { name: 'Bob' },
124
+ taskName: 'getUser',
125
+ boundaries: {},
126
+ type: 'success' as const
127
+ }
128
+ ]
129
+
130
+ records.forEach(record => tape.push(record))
131
+ expect(tape.getLength()).toBe(3)
132
+
133
+ const first = tape.shift()
134
+ expect(first?.input).toEqual({ userId: 1 })
135
+ expect(tape.getLength()).toBe(2)
136
+
137
+ const second = tape.shift()
138
+ expect(second?.input).toEqual({ userId: 2 })
139
+ expect(tape.getLength()).toBe(1)
140
+
141
+ const third = tape.shift()
142
+ expect(third?.input).toEqual({ userId: 3 })
143
+ expect(tape.getLength()).toBe(0)
144
+
145
+ const fourth = tape.shift()
146
+ expect(fourth).toBeUndefined()
147
+ expect(tape.getLength()).toBe(0)
148
+ })
149
+ })
150
+ })
@@ -53,14 +53,9 @@ describe('Base tests', () => {
53
53
  })
54
54
 
55
55
  it('Should create a new tape with generic types', () => {
56
- type InputType = [{ name: string }]
57
- type OutputType = {
58
- age: number
59
- }
60
-
61
- const tape = new RecordTape<InputType, OutputType>({ path: emptyPath })
62
- tape.addLogItem('test', { input: [{name: 'test'}], output: { age: 1 } })
63
- tape.addLogItem('test', { input: [{name: 'test'}], error: new Error('test') })
56
+ const tape = new RecordTape({ path: emptyPath })
57
+ tape.push({ input: [{name: 'test'}], output: { age: 1 }, type: 'success', boundaries: {}, taskName: 'test' })
58
+ tape.push({ input: [{name: 'test'}], error: 'test', type: 'error', boundaries: {}, taskName: 'test' })
64
59
 
65
60
  const data = tape.getLog()
66
61
  expect(data.length).toBe(2)
@@ -82,7 +77,7 @@ describe('Base tests', () => {
82
77
 
83
78
  expect(input2).toEqual([{name: 'test'}])
84
79
  expect(output2).toBeUndefined()
85
- expect(error2).toEqual(new Error('test'))
80
+ expect(error2).toEqual('test')
86
81
  expect(type2).toBe('error')
87
82
  })
88
83
  })