@forgehive/record-tape 0.0.2 → 0.1.0

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/dist/index.d.ts CHANGED
@@ -1,49 +1,53 @@
1
1
  import fs from 'fs';
2
- export interface LogRecord<TInput = unknown[], TOutput = unknown> {
2
+ import { type ExecutionRecord, type Boundaries } from '@forgehive/task';
3
+ export interface LogRecord<TInput = unknown, TOutput = unknown, B extends Boundaries = Boundaries> extends ExecutionRecord<TInput, TOutput, B> {
3
4
  name: string;
4
5
  type: 'success' | 'error';
5
- input: TInput;
6
- output?: TOutput;
7
- error?: unknown;
8
- boundaries: Record<string, unknown>;
9
6
  }
10
- interface SuccessLogItem<TInput = unknown[], TOutput = unknown> {
7
+ export interface SuccessLogItem<TInput = unknown, TOutput = unknown> {
11
8
  input: TInput;
12
9
  output: TOutput;
13
10
  boundaries?: Record<string, unknown>;
14
11
  }
15
- interface ErrorLogItem<TInput = unknown[]> {
12
+ export interface ErrorLogItem<TInput = unknown> {
16
13
  input: TInput;
17
14
  error: unknown;
18
15
  boundaries?: Record<string, unknown>;
19
16
  }
20
- export type LogItem<TInput = unknown[], TOutput = unknown> = SuccessLogItem<TInput, TOutput> | ErrorLogItem<TInput>;
21
- interface Config<TInput = unknown[], TOutput = unknown> {
17
+ export type LogItem<TInput = unknown, TOutput = unknown> = SuccessLogItem<TInput, TOutput> | ErrorLogItem<TInput>;
18
+ export type TaskLogItem<TInput = unknown, TOutput = unknown> = LogItem<TInput, TOutput> | {
19
+ input: TInput;
20
+ output?: TOutput;
21
+ error?: unknown;
22
+ boundaries?: Record<string, unknown>;
23
+ };
24
+ interface Config<TInput = unknown, TOutput = unknown, B extends Boundaries = Boundaries> {
22
25
  path?: fs.PathLike;
23
- log?: LogRecord<TInput, TOutput>[];
26
+ log?: LogRecord<TInput, TOutput, B>[];
24
27
  boundaries?: Record<string, unknown>;
25
28
  }
26
29
  export type Mode = 'record' | 'replay';
27
- export declare class RecordTape<TInput = unknown[], TOutput = unknown> {
30
+ export declare class RecordTape<TInput = unknown, TOutput = unknown, B extends Boundaries = Boundaries> {
28
31
  private _path;
29
32
  private _mode;
30
33
  private _boundaries;
31
34
  private _log;
32
- constructor(config?: Config<TInput, TOutput>);
33
- getLog(): LogRecord<TInput, TOutput>[];
35
+ constructor(config?: Config<TInput, TOutput, B>);
36
+ getLog(): LogRecord<TInput, TOutput, B>[];
34
37
  getMode(): Mode;
35
38
  setMode(mode: Mode): void;
36
- addLogItem(name: string, logItem: LogItem<TInput, TOutput>): void;
37
- addLogRecord(logRecord: LogRecord<TInput, TOutput>): void;
39
+ addLogItem(name: string, logItem: any): void;
40
+ push(name: string, record: ExecutionRecord<TInput, any, B>): void;
41
+ addLogRecord(logRecord: LogRecord<TInput, TOutput, B>): void;
38
42
  stringify(): string;
39
- parse(content: string): LogRecord<TInput, TOutput>[];
43
+ parse(content: string): LogRecord<TInput, TOutput, B>[];
40
44
  compileCache(): Record<string, unknown>;
41
45
  recordFrom(name: string, task: {
42
46
  _listener?: unknown;
43
47
  setBoundariesData: (data: Record<string, unknown>) => void;
44
48
  }): void;
45
- load(): Promise<LogRecord<TInput, TOutput>[]>;
46
- loadSync(): LogRecord<TInput, TOutput>[];
49
+ load(): Promise<LogRecord<TInput, TOutput, B>[]>;
50
+ loadSync(): LogRecord<TInput, TOutput, B>[];
47
51
  save(): Promise<void>;
48
52
  saveSync(): void;
49
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AAGnB,MAAM,WAAW,SAAS,CAAC,MAAM,GAAG,OAAO,EAAE,EAAE,OAAO,GAAG,OAAO;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC;AAED,UAAU,cAAc,CAAC,MAAM,GAAG,OAAO,EAAE,EAAE,OAAO,GAAG,OAAO;IAC5D,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC;AAED,UAAU,YAAY,CAAC,MAAM,GAAG,OAAO,EAAE;IACvC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC;AAUD,MAAM,MAAM,OAAO,CAAC,MAAM,GAAG,OAAO,EAAE,EAAE,OAAO,GAAG,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;AAEnH,UAAU,MAAM,CAAC,MAAM,GAAG,OAAO,EAAE,EAAE,OAAO,GAAG,OAAO;IACpD,IAAI,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAA;IAClB,GAAG,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC;AAED,MAAM,MAAM,IAAI,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAEtC,qBAAa,UAAU,CAAC,MAAM,GAAG,OAAO,EAAE,EAAE,OAAO,GAAG,OAAO;IAC3D,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,IAAI,CAA8B;gBAE9B,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAQhD,MAAM,IAAI,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;IAItC,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAIzB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAgBjE,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIzD,SAAS,IAAI,MAAM;IASnB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;IAYpD,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAgBvC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;KAAE,GAAG,IAAI;IAcnH,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IA8BnD,QAAQ,IAAI,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;IAmBlC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B,QAAQ,IAAI,IAAI;CAajB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AAEnB,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEvE,MAAM,WAAW,SAAS,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,CAAC,SAAS,UAAU,GAAG,UAAU,CAAE,SAAQ,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IAC5I,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,cAAc,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO;IACjE,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC;AAED,MAAM,WAAW,YAAY,CAAC,MAAM,GAAG,OAAO;IAC5C,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC;AAUD,MAAM,MAAM,OAAO,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;AAGjH,MAAM,MAAM,WAAW,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACxF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC,CAAA;AAED,UAAU,MAAM,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,CAAC,SAAS,UAAU,GAAG,UAAU;IACrF,IAAI,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAA;IAClB,GAAG,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAA;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC;AAED,MAAM,MAAM,IAAI,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAEtC,qBAAa,UAAU,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,CAAC,SAAS,UAAU,GAAG,UAAU;IAC5F,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,IAAI,CAAiC;gBAEjC,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAM;IAQnD,MAAM,IAAI,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE;IAIzC,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAIzB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI;IAwE5C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI;IA0CjE,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,IAAI;IAI5D,SAAS,IAAI,MAAM;IASnB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE;IAYvD,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAgBvC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;KAAE,GAAG,IAAI;IAcnH,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC;IA8BtD,QAAQ,IAAI,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE;IAmBrC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B,QAAQ,IAAI,IAAI;CAajB"}
package/dist/index.js CHANGED
@@ -34,18 +34,116 @@ class RecordTape {
34
34
  if (this._mode === 'replay') {
35
35
  return;
36
36
  }
37
+ // Format boundaries to ensure both error and output fields are set if needed
38
+ const formattedBoundaries = {};
39
+ if (logItem.boundaries) {
40
+ for (const key in logItem.boundaries) {
41
+ // Check if the source is from safe-run (if it has error field in entries)
42
+ const isSafeRun = logItem.boundaries[key].some((entry) => entry.error !== undefined);
43
+ formattedBoundaries[key] = logItem.boundaries[key].map((entry) => {
44
+ var _a, _b;
45
+ // Only add error field if it's from safe-run
46
+ return isSafeRun ?
47
+ {
48
+ input: entry.input,
49
+ output: (_a = entry.output) !== null && _a !== void 0 ? _a : null,
50
+ error: (_b = entry.error) !== null && _b !== void 0 ? _b : null
51
+ } :
52
+ {
53
+ input: entry.input,
54
+ output: entry.output
55
+ };
56
+ });
57
+ }
58
+ }
59
+ // Handle LogItem interface
37
60
  if (isSuccessLogItem(logItem)) {
38
- const { input, output, boundaries = {} } = logItem;
39
- this._log.push({ name, type: 'success', input, output, boundaries });
61
+ const { input, output } = logItem;
62
+ this._log.push({
63
+ name,
64
+ type: 'success',
65
+ input,
66
+ output,
67
+ boundaries: formattedBoundaries
68
+ });
40
69
  }
41
70
  else if (isErrorLogItem(logItem)) {
42
- const { input, error, boundaries = {} } = logItem;
43
- this._log.push({ name, type: 'error', input, error, boundaries });
71
+ const { input, error } = logItem;
72
+ this._log.push({
73
+ name,
74
+ type: 'error',
75
+ input,
76
+ error,
77
+ boundaries: formattedBoundaries
78
+ });
79
+ }
80
+ // Handle TaskRecord interface
81
+ else if (logItem.output !== undefined) {
82
+ const { input, output } = logItem;
83
+ this._log.push({
84
+ name,
85
+ type: 'success',
86
+ input,
87
+ output,
88
+ boundaries: formattedBoundaries
89
+ });
90
+ }
91
+ else if (logItem.error !== undefined) {
92
+ const { input, error } = logItem;
93
+ this._log.push({
94
+ name,
95
+ type: 'error',
96
+ input,
97
+ error,
98
+ boundaries: formattedBoundaries
99
+ });
44
100
  }
45
101
  else {
46
102
  throw new Error('invalid log item');
47
103
  }
48
104
  }
105
+ push(name, record) {
106
+ if (this._mode === 'replay') {
107
+ return;
108
+ }
109
+ // For safeRun records, always include both error and output fields
110
+ const formattedBoundaries = {};
111
+ if (record.boundaries) {
112
+ for (const key in record.boundaries) {
113
+ formattedBoundaries[key] = record.boundaries[key].map((entry) => {
114
+ var _a, _b;
115
+ return {
116
+ input: entry.input,
117
+ output: (_a = entry.output) !== null && _a !== void 0 ? _a : null,
118
+ error: (_b = entry.error) !== null && _b !== void 0 ? _b : null
119
+ };
120
+ });
121
+ }
122
+ }
123
+ if (record.output !== undefined) {
124
+ const { input, output } = record;
125
+ this._log.push({
126
+ name,
127
+ type: 'success',
128
+ input,
129
+ output: output instanceof Promise ? null : output,
130
+ boundaries: formattedBoundaries
131
+ });
132
+ }
133
+ else if (record.error !== undefined) {
134
+ const { input, error } = record;
135
+ this._log.push({
136
+ name,
137
+ type: 'error',
138
+ input,
139
+ error,
140
+ boundaries: formattedBoundaries
141
+ });
142
+ }
143
+ else {
144
+ throw new Error('invalid record type');
145
+ }
146
+ }
49
147
  addLogRecord(logRecord) {
50
148
  this._log.push(logRecord);
51
149
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=safe-run.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-run.test.d.ts","sourceRoot":"","sources":["../../src/tests/safe-run.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,282 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_1 = require("../index");
4
+ const task_1 = require("@forgehive/task");
5
+ describe('RecordTape safeRun integration tests', () => {
6
+ it('should record log items directly from safeRun result', async () => {
7
+ // Create a schema
8
+ const schema = new task_1.Schema({
9
+ value: task_1.Schema.number()
10
+ });
11
+ // Define the boundaries
12
+ const boundaries = {
13
+ fetchData: async (value) => {
14
+ return value * 2;
15
+ }
16
+ };
17
+ // Create the task
18
+ const task = (0, task_1.createTask)(schema, boundaries, async function ({ value }, { fetchData }) {
19
+ const result = await fetchData(value);
20
+ return { result, success: true };
21
+ });
22
+ // Create a record tape
23
+ const tape = new index_1.RecordTape();
24
+ // Run the task with safeRun and directly use the logItem
25
+ const [result, error, record] = await task.safeRun({ value: 5 });
26
+ tape.push('test-task', record);
27
+ // Verify the execution was successful
28
+ expect(error).toBeNull();
29
+ expect(result).toEqual({ result: 10, success: true });
30
+ // Get the recorded log from the tape
31
+ const recordedLog = tape.getLog();
32
+ // Verify the log was recorded correctly
33
+ expect(recordedLog).toHaveLength(1);
34
+ expect(recordedLog[0]).toEqual({
35
+ name: 'test-task',
36
+ type: 'success',
37
+ input: { value: 5 },
38
+ output: { result: 10, success: true },
39
+ boundaries: {
40
+ fetchData: [{
41
+ input: [5],
42
+ output: 10,
43
+ error: null
44
+ }]
45
+ }
46
+ });
47
+ });
48
+ it('should record log items from safeRun successfully', async () => {
49
+ // Create a schema
50
+ const schema = new task_1.Schema({
51
+ value: task_1.Schema.number()
52
+ });
53
+ // Define the boundaries
54
+ const boundaries = {
55
+ fetchData: async (value) => {
56
+ return value * 2;
57
+ }
58
+ };
59
+ // Create the task
60
+ const task = (0, task_1.createTask)(schema, boundaries, async function ({ value }, { fetchData }) {
61
+ const result = await fetchData(value);
62
+ return { result, success: true };
63
+ });
64
+ // Create a record tape
65
+ const tape = new index_1.RecordTape();
66
+ // Add listener to record the log items
67
+ task.addListener((record) => {
68
+ // Manually ensure boundary records have error field for consistency with safeRun
69
+ if (record.boundaries && record.boundaries.fetchData && Array.isArray(record.boundaries.fetchData)) {
70
+ record.boundaries.fetchData = record.boundaries.fetchData.map((entry) => {
71
+ var _a, _b;
72
+ return (Object.assign(Object.assign({}, entry), { error: (_a = entry.error) !== null && _a !== void 0 ? _a : null, output: (_b = entry.output) !== null && _b !== void 0 ? _b : null }));
73
+ });
74
+ }
75
+ tape.addLogItem('test-task', record);
76
+ });
77
+ // Run the task with safeRun
78
+ const [result, error] = await task.safeRun({ value: 5 });
79
+ // Verify the execution was successful
80
+ expect(error).toBeNull();
81
+ expect(result).toEqual({ result: 10, success: true });
82
+ // Get the recorded log from the tape
83
+ const recordedLog = tape.getLog();
84
+ // Verify the log was recorded correctly
85
+ expect(recordedLog).toHaveLength(1);
86
+ expect(recordedLog[0]).toEqual({
87
+ name: 'test-task',
88
+ type: 'success',
89
+ input: { value: 5 },
90
+ output: { result: 10, success: true },
91
+ boundaries: {
92
+ fetchData: [{
93
+ input: [5],
94
+ output: 10,
95
+ error: null
96
+ }]
97
+ }
98
+ });
99
+ });
100
+ it('should record error log items from safeRun', async () => {
101
+ // Create a schema
102
+ const schema = new task_1.Schema({
103
+ value: task_1.Schema.number()
104
+ });
105
+ // Define the boundaries with a function that will throw an error
106
+ const boundaries = {
107
+ fetchData: async (value) => {
108
+ if (value < 0) {
109
+ throw new Error('Value cannot be negative');
110
+ }
111
+ return value * 2;
112
+ }
113
+ };
114
+ // Create the task
115
+ const task = (0, task_1.createTask)(schema, boundaries, async function ({ value }, { fetchData }) {
116
+ const result = await fetchData(value);
117
+ return { result, success: true };
118
+ });
119
+ // Create a record tape
120
+ const tape = new index_1.RecordTape();
121
+ // Add listener to record the log items
122
+ task.addListener((record) => {
123
+ // Manually ensure boundary records have error field for consistency with safeRun
124
+ if (record.boundaries && record.boundaries.fetchData && Array.isArray(record.boundaries.fetchData)) {
125
+ record.boundaries.fetchData = record.boundaries.fetchData.map((entry) => {
126
+ var _a, _b;
127
+ return (Object.assign(Object.assign({}, entry), { error: (_a = entry.error) !== null && _a !== void 0 ? _a : null, output: (_b = entry.output) !== null && _b !== void 0 ? _b : null }));
128
+ });
129
+ }
130
+ tape.addLogItem('test-task', record);
131
+ });
132
+ // Run the task with safeRun with a value that will cause an error
133
+ const [result, error] = await task.safeRun({ value: -5 });
134
+ // Verify the execution failed as expected
135
+ expect(result).toBeNull();
136
+ expect(error).not.toBeNull();
137
+ expect(error === null || error === void 0 ? void 0 : error.message).toContain('Value cannot be negative');
138
+ // Get the recorded log from the tape
139
+ const recordedLog = tape.getLog();
140
+ // Verify the error log was recorded correctly
141
+ expect(recordedLog).toHaveLength(1);
142
+ expect(recordedLog[0]).toEqual({
143
+ name: 'test-task',
144
+ type: 'error',
145
+ input: { value: -5 },
146
+ error: 'Value cannot be negative',
147
+ boundaries: {
148
+ fetchData: [{
149
+ input: [-5],
150
+ output: null,
151
+ error: 'Value cannot be negative'
152
+ }]
153
+ }
154
+ });
155
+ });
156
+ it('should handle error records directly with push', async () => {
157
+ // Create a schema
158
+ const schema = new task_1.Schema({
159
+ value: task_1.Schema.number()
160
+ });
161
+ // Define the boundaries with a function that will throw an error
162
+ const boundaries = {
163
+ fetchData: async (value) => {
164
+ if (value < 0) {
165
+ throw new Error('Value cannot be negative');
166
+ }
167
+ return value * 2;
168
+ }
169
+ };
170
+ // Create the task
171
+ const task = (0, task_1.createTask)(schema, boundaries, async function ({ value }, { fetchData }) {
172
+ const result = await fetchData(value);
173
+ return { result, success: true };
174
+ });
175
+ // Create a record tape
176
+ const tape = new index_1.RecordTape();
177
+ // Run the task with safeRun with a value that will cause an error
178
+ const [result, error, record] = await task.safeRun({ value: -5 });
179
+ // Push the error record directly
180
+ tape.push('test-error', record);
181
+ // Verify the execution failed as expected
182
+ expect(result).toBeNull();
183
+ expect(error).not.toBeNull();
184
+ expect(error instanceof Error).toBe(true);
185
+ if (error instanceof Error) {
186
+ expect(error.message).toContain('Value cannot be negative');
187
+ }
188
+ // Get the recorded log from the tape
189
+ const recordedLog = tape.getLog();
190
+ // Verify the error log was recorded correctly
191
+ expect(recordedLog).toHaveLength(1);
192
+ expect(recordedLog[0]).toEqual({
193
+ name: 'test-error',
194
+ type: 'error',
195
+ input: { value: -5 },
196
+ error: 'Value cannot be negative',
197
+ boundaries: {
198
+ fetchData: [{
199
+ input: [-5],
200
+ output: null,
201
+ error: 'Value cannot be negative'
202
+ }]
203
+ }
204
+ });
205
+ });
206
+ it('should handle custom execution records with push', async () => {
207
+ // Create a record tape
208
+ const tape = new index_1.RecordTape();
209
+ // Create a custom execution record
210
+ const customRecord = {
211
+ input: { value: 10 },
212
+ output: { result: 20 },
213
+ boundaries: {
214
+ fetchData: [
215
+ {
216
+ input: [10],
217
+ output: 20,
218
+ error: null
219
+ }
220
+ ]
221
+ }
222
+ };
223
+ // Push the custom record
224
+ tape.push('custom-record', customRecord);
225
+ // Get the recorded log from the tape
226
+ const recordedLog = tape.getLog();
227
+ // Verify the log was recorded correctly
228
+ expect(recordedLog).toHaveLength(1);
229
+ expect(recordedLog[0]).toEqual({
230
+ name: 'custom-record',
231
+ type: 'success',
232
+ input: { value: 10 },
233
+ output: { result: 20 },
234
+ boundaries: {
235
+ fetchData: [{
236
+ input: [10],
237
+ output: 20,
238
+ error: null
239
+ }]
240
+ }
241
+ });
242
+ });
243
+ it('should handle execution records with Promise outputs correctly', async () => {
244
+ // Create a record tape
245
+ const tape = new index_1.RecordTape();
246
+ // Create a custom execution record with a Promise output
247
+ const promiseResult = Promise.resolve({ result: 30 });
248
+ const promiseRecord = {
249
+ input: { value: 15 },
250
+ output: promiseResult,
251
+ boundaries: {
252
+ fetchData: [
253
+ {
254
+ input: [15],
255
+ output: 30,
256
+ error: null
257
+ }
258
+ ]
259
+ }
260
+ };
261
+ // Push the record with Promise output
262
+ tape.push('promise-record', promiseRecord);
263
+ // Get the recorded log from the tape
264
+ const recordedLog = tape.getLog();
265
+ // Verify the log was recorded correctly, with Promise output set to null
266
+ expect(recordedLog).toHaveLength(1);
267
+ expect(recordedLog[0]).toEqual({
268
+ name: 'promise-record',
269
+ type: 'success',
270
+ input: { value: 15 },
271
+ output: null, // Promise output should be set to null
272
+ boundaries: {
273
+ fetchData: [{
274
+ input: [15],
275
+ output: 30,
276
+ error: null
277
+ }]
278
+ }
279
+ });
280
+ });
281
+ });
282
+ //# sourceMappingURL=safe-run.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-run.test.js","sourceRoot":"","sources":["../../src/tests/safe-run.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,9 +1,16 @@
1
1
  {
2
2
  "name": "@forgehive/record-tape",
3
- "version": "0.0.2",
3
+ "version": "0.1.0",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "publishConfig": {
8
+ "access": "public",
9
+ "dependencies": {
10
+ "@forgehive/schema": "^0.1.4",
11
+ "@forgehive/task": "^0.1.7"
12
+ }
13
+ },
7
14
  "devDependencies": {
8
15
  "@types/jest": "^29.5.14",
9
16
  "@types/node": "^20.11.24",
@@ -12,8 +19,8 @@
12
19
  "typescript": "^5.3.3"
13
20
  },
14
21
  "dependencies": {
15
- "@forgehive/schema": "^0.1.4",
16
- "@forgehive/task": "^0.1.5"
22
+ "@forgehive/schema": "0.1.4",
23
+ "@forgehive/task": "0.1.7"
17
24
  },
18
25
  "scripts": {
19
26
  "build": "tsc",
package/src/index.ts CHANGED
@@ -1,22 +1,19 @@
1
1
  import fs from 'fs'
2
2
  import path from 'path'
3
+ import { type ExecutionRecord, type Boundaries } from '@forgehive/task'
3
4
 
4
- export interface LogRecord<TInput = unknown[], TOutput = unknown> {
5
+ export interface LogRecord<TInput = unknown, TOutput = unknown, B extends Boundaries = Boundaries> extends ExecutionRecord<TInput, TOutput, B> {
5
6
  name: string
6
7
  type: 'success' | 'error'
7
- input: TInput
8
- output?: TOutput
9
- error?: unknown
10
- boundaries: Record<string, unknown>
11
8
  }
12
9
 
13
- interface SuccessLogItem<TInput = unknown[], TOutput = unknown> {
10
+ export interface SuccessLogItem<TInput = unknown, TOutput = unknown> {
14
11
  input: TInput
15
12
  output: TOutput
16
13
  boundaries?: Record<string, unknown>
17
14
  }
18
15
 
19
- interface ErrorLogItem<TInput = unknown[]> {
16
+ export interface ErrorLogItem<TInput = unknown> {
20
17
  input: TInput
21
18
  error: unknown
22
19
  boundaries?: Record<string, unknown>
@@ -30,23 +27,31 @@ function isErrorLogItem<TInput>(log: SuccessLogItem<TInput> | ErrorLogItem<TInpu
30
27
  return (log as ErrorLogItem<TInput>).error !== undefined
31
28
  }
32
29
 
33
- export type LogItem<TInput = unknown[], TOutput = unknown> = SuccessLogItem<TInput, TOutput> | ErrorLogItem<TInput>
30
+ export type LogItem<TInput = unknown, TOutput = unknown> = SuccessLogItem<TInput, TOutput> | ErrorLogItem<TInput>
31
+
32
+ // Additional type to handle TaskRecord compatibility
33
+ export type TaskLogItem<TInput = unknown, TOutput = unknown> = LogItem<TInput, TOutput> | {
34
+ input: TInput;
35
+ output?: TOutput;
36
+ error?: unknown;
37
+ boundaries?: Record<string, unknown>;
38
+ }
34
39
 
35
- interface Config<TInput = unknown[], TOutput = unknown> {
40
+ interface Config<TInput = unknown, TOutput = unknown, B extends Boundaries = Boundaries> {
36
41
  path?: fs.PathLike
37
- log?: LogRecord<TInput, TOutput>[]
42
+ log?: LogRecord<TInput, TOutput, B>[]
38
43
  boundaries?: Record<string, unknown>
39
44
  }
40
45
 
41
46
  export type Mode = 'record' | 'replay'
42
47
 
43
- export class RecordTape<TInput = unknown[], TOutput = unknown> {
48
+ export class RecordTape<TInput = unknown, TOutput = unknown, B extends Boundaries = Boundaries> {
44
49
  private _path: fs.PathLike | undefined
45
50
  private _mode: Mode
46
51
  private _boundaries: Record<string, unknown>
47
- private _log: LogRecord<TInput, TOutput>[]
52
+ private _log: LogRecord<TInput, TOutput, B>[]
48
53
 
49
- constructor(config: Config<TInput, TOutput> = {}) {
54
+ constructor(config: Config<TInput, TOutput, B> = {}) {
50
55
  this._path = typeof config.path === 'string' ? `${config.path}.log` : undefined
51
56
  this._log = config.log ?? []
52
57
  this._boundaries = config.boundaries ?? {}
@@ -54,7 +59,7 @@ export class RecordTape<TInput = unknown[], TOutput = unknown> {
54
59
  }
55
60
 
56
61
  // Data functions
57
- getLog(): LogRecord<TInput, TOutput>[] {
62
+ getLog(): LogRecord<TInput, TOutput, B>[] {
58
63
  return this._log
59
64
  }
60
65
 
@@ -66,23 +71,121 @@ export class RecordTape<TInput = unknown[], TOutput = unknown> {
66
71
  this._mode = mode
67
72
  }
68
73
 
69
- addLogItem(name: string, logItem: LogItem<TInput, TOutput>): void {
74
+ addLogItem(name: string, logItem: any): void {
70
75
  if (this._mode === 'replay') {
71
76
  return
72
77
  }
73
78
 
79
+ // Format boundaries to ensure both error and output fields are set if needed
80
+ const formattedBoundaries: Record<string, any> = {}
81
+ if (logItem.boundaries) {
82
+ for (const key in logItem.boundaries) {
83
+ // Check if the source is from safe-run (if it has error field in entries)
84
+ const isSafeRun = logItem.boundaries[key].some((entry: any) => entry.error !== undefined)
85
+
86
+ formattedBoundaries[key] = logItem.boundaries[key].map((entry: any) => {
87
+ // Only add error field if it's from safe-run
88
+ return isSafeRun ?
89
+ {
90
+ input: entry.input,
91
+ output: entry.output ?? null,
92
+ error: entry.error ?? null
93
+ } :
94
+ {
95
+ input: entry.input,
96
+ output: entry.output
97
+ }
98
+ })
99
+ }
100
+ }
101
+
102
+ // Handle LogItem interface
74
103
  if (isSuccessLogItem(logItem)) {
75
- const { input, output, boundaries = {} } = logItem
76
- this._log.push({ name, type: 'success', input, output, boundaries })
104
+ const { input, output } = logItem
105
+ this._log.push({
106
+ name,
107
+ type: 'success',
108
+ input,
109
+ output,
110
+ boundaries: formattedBoundaries
111
+ } as LogRecord<TInput, TOutput, B>)
77
112
  } else if (isErrorLogItem(logItem)) {
78
- const { input, error, boundaries = {} } = logItem
79
- this._log.push({ name, type: 'error', input, error, boundaries })
113
+ const { input, error } = logItem
114
+ this._log.push({
115
+ name,
116
+ type: 'error',
117
+ input,
118
+ error,
119
+ boundaries: formattedBoundaries
120
+ } as LogRecord<TInput, TOutput, B>)
121
+ }
122
+ // Handle TaskRecord interface
123
+ else if (logItem.output !== undefined) {
124
+ const { input, output } = logItem
125
+ this._log.push({
126
+ name,
127
+ type: 'success',
128
+ input,
129
+ output,
130
+ boundaries: formattedBoundaries
131
+ } as LogRecord<TInput, TOutput, B>)
132
+ } else if (logItem.error !== undefined) {
133
+ const { input, error } = logItem
134
+ this._log.push({
135
+ name,
136
+ type: 'error',
137
+ input,
138
+ error,
139
+ boundaries: formattedBoundaries
140
+ } as LogRecord<TInput, TOutput, B>)
80
141
  } else {
81
142
  throw new Error('invalid log item')
82
143
  }
83
144
  }
84
145
 
85
- addLogRecord(logRecord: LogRecord<TInput, TOutput>): void {
146
+ push(name: string, record: ExecutionRecord<TInput, any, B>): void {
147
+ if (this._mode === 'replay') {
148
+ return
149
+ }
150
+
151
+ // For safeRun records, always include both error and output fields
152
+ const formattedBoundaries: Record<string, any> = {}
153
+ if (record.boundaries) {
154
+ for (const key in record.boundaries) {
155
+ formattedBoundaries[key] = record.boundaries[key].map((entry: any) => {
156
+ return {
157
+ input: entry.input,
158
+ output: entry.output ?? null,
159
+ error: entry.error ?? null
160
+ }
161
+ })
162
+ }
163
+ }
164
+
165
+ if (record.output !== undefined) {
166
+ const { input, output } = record
167
+ this._log.push({
168
+ name,
169
+ type: 'success',
170
+ input,
171
+ output: output instanceof Promise ? null : output,
172
+ boundaries: formattedBoundaries
173
+ } as unknown as LogRecord<TInput, TOutput, B>)
174
+ } else if (record.error !== undefined) {
175
+ const { input, error } = record
176
+ this._log.push({
177
+ name,
178
+ type: 'error',
179
+ input,
180
+ error,
181
+ boundaries: formattedBoundaries
182
+ } as unknown as LogRecord<TInput, TOutput, B>)
183
+ } else {
184
+ throw new Error('invalid record type')
185
+ }
186
+ }
187
+
188
+ addLogRecord(logRecord: LogRecord<TInput, TOutput, B>): void {
86
189
  this._log.push(logRecord)
87
190
  }
88
191
 
@@ -95,12 +198,12 @@ export class RecordTape<TInput = unknown[], TOutput = unknown> {
95
198
  return log
96
199
  }
97
200
 
98
- parse(content: string): LogRecord<TInput, TOutput>[] {
201
+ parse(content: string): LogRecord<TInput, TOutput, B>[] {
99
202
  const items = content.split('\n')
100
- const log: LogRecord<TInput, TOutput>[] = []
203
+ const log: LogRecord<TInput, TOutput, B>[] = []
101
204
  for (const item of items) {
102
205
  if (item !== '') {
103
- const data = JSON.parse(item) as LogRecord<TInput, TOutput>
206
+ const data = JSON.parse(item) as LogRecord<TInput, TOutput, B>
104
207
  log.push(data)
105
208
  }
106
209
  }
@@ -137,7 +240,7 @@ export class RecordTape<TInput = unknown[], TOutput = unknown> {
137
240
  }
138
241
 
139
242
  // Load save functions
140
- async load(): Promise<LogRecord<TInput, TOutput>[]> {
243
+ async load(): Promise<LogRecord<TInput, TOutput, B>[]> {
141
244
  if (typeof this._path === 'undefined') {
142
245
  return []
143
246
  }
@@ -167,7 +270,7 @@ export class RecordTape<TInput = unknown[], TOutput = unknown> {
167
270
  return this._log
168
271
  }
169
272
 
170
- loadSync(): LogRecord<TInput, TOutput>[] {
273
+ loadSync(): LogRecord<TInput, TOutput, B>[] {
171
274
  if (typeof this._path === 'undefined') { return [] }
172
275
 
173
276
  const dirpath = path.dirname(this._path.toString())
@@ -0,0 +1,344 @@
1
+ import { RecordTape } from '../index'
2
+ import { createTask, Schema, type ExecutionRecord, type TaskRecord } from '@forgehive/task'
3
+
4
+ describe('RecordTape safeRun integration tests', () => {
5
+ it('should record log items directly from safeRun result', async () => {
6
+ // Create a schema
7
+ const schema = new Schema({
8
+ value: Schema.number()
9
+ })
10
+
11
+ // Define the boundaries
12
+ const boundaries = {
13
+ fetchData: async (value: number): Promise<number> => {
14
+ return value * 2
15
+ }
16
+ }
17
+
18
+ // Create the task
19
+ const task = createTask(
20
+ schema,
21
+ boundaries,
22
+ async function ({ value }, { fetchData }) {
23
+ const result = await fetchData(value)
24
+ return { result, success: true }
25
+ }
26
+ )
27
+
28
+ // Create a record tape
29
+ const tape = new RecordTape<{ value: number }, { result: number; success: boolean }, typeof boundaries>()
30
+
31
+ // Run the task with safeRun and directly use the logItem
32
+ const [result, error, record] = await task.safeRun({ value: 5 })
33
+ tape.push('test-task', record)
34
+
35
+ // Verify the execution was successful
36
+ expect(error).toBeNull()
37
+ expect(result).toEqual({ result: 10, success: true })
38
+
39
+ // Get the recorded log from the tape
40
+ const recordedLog = tape.getLog()
41
+
42
+ // Verify the log was recorded correctly
43
+ expect(recordedLog).toHaveLength(1)
44
+ expect(recordedLog[0]).toEqual({
45
+ name: 'test-task',
46
+ type: 'success',
47
+ input: { value: 5 },
48
+ output: { result: 10, success: true },
49
+ boundaries: {
50
+ fetchData: [{
51
+ input: [5],
52
+ output: 10,
53
+ error: null
54
+ }]
55
+ }
56
+ })
57
+ })
58
+
59
+ it('should record log items from safeRun successfully', async () => {
60
+ // Create a schema
61
+ const schema = new Schema({
62
+ value: Schema.number()
63
+ })
64
+
65
+ // Define the boundaries
66
+ const boundaries = {
67
+ fetchData: async (value: number): Promise<number> => {
68
+ return value * 2
69
+ }
70
+ }
71
+
72
+ // Create the task
73
+ const task = createTask(
74
+ schema,
75
+ boundaries,
76
+ async function ({ value }, { fetchData }) {
77
+ const result = await fetchData(value)
78
+ return { result, success: true }
79
+ }
80
+ )
81
+
82
+ // Create a record tape
83
+ const tape = new RecordTape<{ value: number }, { result: number; success: boolean }, typeof boundaries>()
84
+
85
+ // Add listener to record the log items
86
+ task.addListener((record: TaskRecord<{ value: number }, { result: number; success: boolean }>) => {
87
+ // Manually ensure boundary records have error field for consistency with safeRun
88
+ if (record.boundaries && record.boundaries.fetchData && Array.isArray(record.boundaries.fetchData)) {
89
+ record.boundaries.fetchData = record.boundaries.fetchData.map((entry: any) => ({
90
+ ...entry,
91
+ error: entry.error ?? null,
92
+ output: entry.output ?? null
93
+ }))
94
+ }
95
+
96
+ tape.addLogItem('test-task', record)
97
+ })
98
+
99
+ // Run the task with safeRun
100
+ const [result, error] = await task.safeRun({ value: 5 })
101
+
102
+ // Verify the execution was successful
103
+ expect(error).toBeNull()
104
+ expect(result).toEqual({ result: 10, success: true })
105
+
106
+ // Get the recorded log from the tape
107
+ const recordedLog = tape.getLog()
108
+
109
+ // Verify the log was recorded correctly
110
+ expect(recordedLog).toHaveLength(1)
111
+ expect(recordedLog[0]).toEqual({
112
+ name: 'test-task',
113
+ type: 'success',
114
+ input: { value: 5 },
115
+ output: { result: 10, success: true },
116
+ boundaries: {
117
+ fetchData: [{
118
+ input: [5],
119
+ output: 10,
120
+ error: null
121
+ }]
122
+ }
123
+ })
124
+ })
125
+
126
+ it('should record error log items from safeRun', async () => {
127
+ // Create a schema
128
+ const schema = new Schema({
129
+ value: Schema.number()
130
+ })
131
+
132
+ // Define the boundaries with a function that will throw an error
133
+ const boundaries = {
134
+ fetchData: async (value: number): Promise<number> => {
135
+ if (value < 0) {
136
+ throw new Error('Value cannot be negative')
137
+ }
138
+ return value * 2
139
+ }
140
+ }
141
+
142
+ // Create the task
143
+ const task = createTask(
144
+ schema,
145
+ boundaries,
146
+ async function ({ value }, { fetchData }) {
147
+ const result = await fetchData(value)
148
+ return { result, success: true }
149
+ }
150
+ )
151
+
152
+ // Create a record tape
153
+ const tape = new RecordTape<{ value: number }, { result: number; success: boolean }, typeof boundaries>()
154
+
155
+ // Add listener to record the log items
156
+ task.addListener((record: TaskRecord<{ value: number }, { result: number; success: boolean }>) => {
157
+ // Manually ensure boundary records have error field for consistency with safeRun
158
+ if (record.boundaries && record.boundaries.fetchData && Array.isArray(record.boundaries.fetchData)) {
159
+ record.boundaries.fetchData = record.boundaries.fetchData.map((entry: any) => ({
160
+ ...entry,
161
+ error: entry.error ?? null,
162
+ output: entry.output ?? null
163
+ }))
164
+ }
165
+
166
+ tape.addLogItem('test-task', record)
167
+ })
168
+
169
+ // Run the task with safeRun with a value that will cause an error
170
+ const [result, error] = await task.safeRun({ value: -5 })
171
+
172
+ // Verify the execution failed as expected
173
+ expect(result).toBeNull()
174
+ expect(error).not.toBeNull()
175
+ expect(error?.message).toContain('Value cannot be negative')
176
+
177
+ // Get the recorded log from the tape
178
+ const recordedLog = tape.getLog()
179
+
180
+ // Verify the error log was recorded correctly
181
+ expect(recordedLog).toHaveLength(1)
182
+ expect(recordedLog[0]).toEqual({
183
+ name: 'test-task',
184
+ type: 'error',
185
+ input: { value: -5 },
186
+ error: 'Value cannot be negative',
187
+ boundaries: {
188
+ fetchData: [{
189
+ input: [-5],
190
+ output: null,
191
+ error: 'Value cannot be negative'
192
+ }]
193
+ }
194
+ })
195
+ })
196
+
197
+ it('should handle error records directly with push', async () => {
198
+ // Create a schema
199
+ const schema = new Schema({
200
+ value: Schema.number()
201
+ })
202
+
203
+ // Define the boundaries with a function that will throw an error
204
+ const boundaries = {
205
+ fetchData: async (value: number): Promise<number> => {
206
+ if (value < 0) {
207
+ throw new Error('Value cannot be negative')
208
+ }
209
+ return value * 2
210
+ }
211
+ }
212
+
213
+ // Create the task
214
+ const task = createTask(
215
+ schema,
216
+ boundaries,
217
+ async function ({ value }, { fetchData }) {
218
+ const result = await fetchData(value)
219
+ return { result, success: true }
220
+ }
221
+ )
222
+
223
+ // Create a record tape
224
+ const tape = new RecordTape<{ value: number }, { result: number; success: boolean }, typeof boundaries>()
225
+
226
+ // Run the task with safeRun with a value that will cause an error
227
+ const [result, error, record] = await task.safeRun({ value: -5 })
228
+
229
+ // Push the error record directly
230
+ tape.push('test-error', record)
231
+
232
+ // Verify the execution failed as expected
233
+ expect(result).toBeNull()
234
+ expect(error).not.toBeNull()
235
+ expect(error instanceof Error).toBe(true)
236
+ if (error instanceof Error) {
237
+ expect(error.message).toContain('Value cannot be negative')
238
+ }
239
+
240
+ // Get the recorded log from the tape
241
+ const recordedLog = tape.getLog()
242
+
243
+ // Verify the error log was recorded correctly
244
+ expect(recordedLog).toHaveLength(1)
245
+ expect(recordedLog[0]).toEqual({
246
+ name: 'test-error',
247
+ type: 'error',
248
+ input: { value: -5 },
249
+ error: 'Value cannot be negative',
250
+ boundaries: {
251
+ fetchData: [{
252
+ input: [-5],
253
+ output: null,
254
+ error: 'Value cannot be negative'
255
+ }]
256
+ }
257
+ })
258
+ })
259
+
260
+ it('should handle custom execution records with push', async () => {
261
+ // Create a record tape
262
+ const tape = new RecordTape<{ value: number }, { result: number }, { fetchData: (n: number) => Promise<number> }>()
263
+
264
+ // Create a custom execution record
265
+ const customRecord: ExecutionRecord<{ value: number }, { result: number }, { fetchData: (n: number) => Promise<number> }> = {
266
+ input: { value: 10 },
267
+ output: { result: 20 },
268
+ boundaries: {
269
+ fetchData: [
270
+ {
271
+ input: [10],
272
+ output: 20,
273
+ error: null
274
+ }
275
+ ]
276
+ }
277
+ }
278
+
279
+ // Push the custom record
280
+ tape.push('custom-record', customRecord)
281
+
282
+ // Get the recorded log from the tape
283
+ const recordedLog = tape.getLog()
284
+
285
+ // Verify the log was recorded correctly
286
+ expect(recordedLog).toHaveLength(1)
287
+ expect(recordedLog[0]).toEqual({
288
+ name: 'custom-record',
289
+ type: 'success',
290
+ input: { value: 10 },
291
+ output: { result: 20 },
292
+ boundaries: {
293
+ fetchData: [{
294
+ input: [10],
295
+ output: 20,
296
+ error: null
297
+ }]
298
+ }
299
+ })
300
+ })
301
+
302
+ it('should handle execution records with Promise outputs correctly', async () => {
303
+ // Create a record tape
304
+ const tape = new RecordTape<{ value: number }, { result: number }, { fetchData: (n: number) => Promise<number> }>()
305
+
306
+ // Create a custom execution record with a Promise output
307
+ const promiseResult = Promise.resolve({ result: 30 })
308
+ const promiseRecord: ExecutionRecord<{ value: number }, Promise<{ result: number }>, { fetchData: (n: number) => Promise<number> }> = {
309
+ input: { value: 15 },
310
+ output: promiseResult,
311
+ boundaries: {
312
+ fetchData: [
313
+ {
314
+ input: [15],
315
+ output: 30,
316
+ error: null
317
+ }
318
+ ]
319
+ }
320
+ }
321
+
322
+ // Push the record with Promise output
323
+ tape.push('promise-record', promiseRecord)
324
+
325
+ // Get the recorded log from the tape
326
+ const recordedLog = tape.getLog()
327
+
328
+ // Verify the log was recorded correctly, with Promise output set to null
329
+ expect(recordedLog).toHaveLength(1)
330
+ expect(recordedLog[0]).toEqual({
331
+ name: 'promise-record',
332
+ type: 'success',
333
+ input: { value: 15 },
334
+ output: null, // Promise output should be set to null
335
+ boundaries: {
336
+ fetchData: [{
337
+ input: [15],
338
+ output: 30,
339
+ error: null
340
+ }]
341
+ }
342
+ })
343
+ })
344
+ })