@forgehive/task 0.1.13 → 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.
Files changed (32) hide show
  1. package/dist/index.d.ts +37 -24
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +58 -13
  4. package/dist/index.js.map +1 -1
  5. package/dist/test/add-listener-with-boundaries.test.js +186 -181
  6. package/dist/test/add-listener-with-boundaries.test.js.map +1 -1
  7. package/dist/test/add-listener.test.js +80 -52
  8. package/dist/test/add-listener.test.js.map +1 -1
  9. package/dist/test/safe-replay-complex-boundary.test.js +36 -27
  10. package/dist/test/safe-replay-complex-boundary.test.js.map +1 -1
  11. package/dist/test/safe-replay.test.js +23 -14
  12. package/dist/test/safe-replay.test.js.map +1 -1
  13. package/dist/test/safe-run.test.js +41 -16
  14. package/dist/test/safe-run.test.js.map +1 -1
  15. package/dist/test/task-boundary-mocking.test.js +17 -7
  16. package/dist/test/task-boundary-mocking.test.js.map +1 -1
  17. package/dist/test/task-execution-log.test.d.ts +2 -0
  18. package/dist/test/task-execution-log.test.d.ts.map +1 -0
  19. package/dist/test/task-execution-log.test.js +207 -0
  20. package/dist/test/task-execution-log.test.js.map +1 -0
  21. package/dist/test/task-with-boundaries.test.js +56 -24
  22. package/dist/test/task-with-boundaries.test.js.map +1 -1
  23. package/package.json +1 -1
  24. package/src/index.ts +109 -40
  25. package/src/test/add-listener-with-boundaries.test.ts +202 -252
  26. package/src/test/add-listener.test.ts +90 -64
  27. package/src/test/safe-replay-complex-boundary.test.ts +18 -10
  28. package/src/test/safe-replay.test.ts +21 -12
  29. package/src/test/safe-run.test.ts +20 -15
  30. package/src/test/task-boundary-mocking.test.ts +8 -6
  31. package/src/test/task-execution-log.test.ts +246 -0
  32. package/src/test/task-with-boundaries.test.ts +45 -44
@@ -1,299 +1,249 @@
1
- import { type TaskRecord, createTask, Schema } from '../index'
2
-
3
- describe('Listener with boundaries tests', () => {
4
- it('Should record one item and its boundaries tape', async () => {
5
- const tape: TaskRecord<{ value: number }, { value: number, foo: boolean }>[] = []
6
-
7
- // Create a schema for the task
8
- const schema = new Schema({
9
- value: Schema.number()
10
- })
11
-
12
- // Define the boundaries
13
- const boundaries = {
14
- fetchExternalData: async (): Promise<{ foo: boolean }> => {
15
- return { foo: false }
16
- }
17
- }
18
-
19
- // Create the task using createTask
20
- const task = createTask(
21
- schema,
22
- boundaries,
23
- async (argv, boundaries) => {
24
- const externalData = await boundaries.fetchExternalData()
25
- return { ...externalData, ...argv }
1
+ import { type ExecutionRecord, createTask, Schema } from '../index'
2
+
3
+ describe('Listener with boundaries', () => {
4
+ it('Should add a listener to the task and capture boundaries', async () => {
5
+ const tape: ExecutionRecord[] = []
6
+ const task = createTask({
7
+ name: 'test',
8
+ schema: new Schema({
9
+ value: Schema.number()
10
+ }),
11
+ boundaries: {
12
+ getTen: async () => {
13
+ return 10
14
+ }
15
+ },
16
+ fn: async (argv, boundaries) => {
17
+ const ten = await boundaries.getTen()
18
+ return { value: argv.value, foo: ten > 5 }
26
19
  }
27
- )
28
-
29
- task.addListener<{ value: number }, { value: number, foo: boolean }>((record) => {
30
- tape.push(record)
31
20
  })
32
21
 
33
- await task.run({ value: 5 })
34
-
35
- expect(tape.length).toBe(1)
36
- expect(tape[0].input).toEqual({ value: 5 })
37
- expect(tape[0].output).toEqual({ value: 5, foo: false })
38
- expect(tape[0].boundaries).toEqual({
39
- fetchExternalData: [
40
- { input: [], output: { foo: false } }
41
- ]
42
- })
43
- })
44
-
45
- it('Should record multiple items and their boundaries tape', async () => {
46
- const tape: TaskRecord<{ value: number }, { value: number, foo: boolean }>[] = []
47
-
48
- // Create a schema for the task
49
- const schema = new Schema({
50
- value: Schema.number()
51
- })
52
-
53
- // Define the boundaries
54
- const boundaries = {
55
- fetchExternalData: async (): Promise<{ foo: boolean }> => {
56
- return { foo: false }
57
- }
58
- }
59
-
60
- // Create the task using createTask
61
- const task = createTask(
62
- schema,
63
- boundaries,
64
- async (argv, boundaries) => {
65
- const externalData = await boundaries.fetchExternalData()
66
- return { ...externalData, ...argv }
67
- }
68
- )
69
-
70
- task.addListener<{ value: number }, { value: number, foo: boolean }>((record) => {
22
+ task.addListener((record) => {
71
23
  tape.push(record)
72
24
  })
73
25
 
74
26
  await task.run({ value: 5 })
75
- await task.run({ value: 6 })
76
-
77
- expect(tape.length).toBe(2)
78
-
79
- expect(tape[0].input).toEqual({ value: 5 })
80
- expect(tape[0].output).toEqual({ value: 5, foo: false })
81
- expect(tape[0].boundaries).toEqual({
82
- fetchExternalData: [
83
- { input: [], output: { foo: false } }
84
- ]
85
- })
86
-
87
- expect(tape[1].input).toEqual({ value: 6 })
88
- expect(tape[1].output).toEqual({ value: 6, foo: false })
89
- expect(tape[1].boundaries).toEqual({
90
- fetchExternalData: [
91
- { input: [], output: { foo: false } }
92
- ]
93
- })
27
+ expect(tape).toEqual([{
28
+ input: { value: 5 },
29
+ output: { value: 5, foo: true },
30
+ boundaries: {
31
+ getTen: [{
32
+ input: [],
33
+ output: 10
34
+ }]
35
+ },
36
+ taskName: 'test',
37
+ metadata: {},
38
+ type: 'success'
39
+ }])
94
40
  })
95
41
 
96
- it('Should record error and its boundaries tape', async () => {
97
- const tape: TaskRecord<Record<string, unknown>, { value: number, foo: boolean }>[] = []
98
-
99
- // Create a schema for the task
100
- const schema = new Schema({
101
- value: Schema.number().optional()
102
- })
103
-
104
- // Define the boundaries
105
- const boundaries = {
106
- fetchExternalData: async (): Promise<{ foo: boolean }> => {
107
- return { foo: false }
108
- }
109
- }
110
-
111
- // Create the task using createTask
112
- const task = createTask(
113
- schema,
114
- boundaries,
115
- async (argv, boundaries) => {
116
- const externalData = await boundaries.fetchExternalData()
117
- if (typeof argv.value === 'undefined') {
118
- throw new Error('Value is required')
42
+ it('Should add a listener to the task and capture boundaries with error', async () => {
43
+ const tape: ExecutionRecord[] = []
44
+ const task = createTask({
45
+ name: 'test',
46
+ schema: new Schema({
47
+ value: Schema.number()
48
+ }),
49
+ boundaries: {
50
+ getTen: async () => {
51
+ throw new Error('Network error')
119
52
  }
120
-
121
- return { ...externalData, ...argv as { value: number } }
53
+ },
54
+ fn: async (argv, boundaries) => {
55
+ const ten = await boundaries.getTen()
56
+ return { value: argv.value, foo: ten > 5 }
122
57
  }
123
- )
58
+ })
124
59
 
125
- task.addListener<Record<string, unknown>, { value: number, foo: boolean }>((record) => {
60
+ task.addListener((record) => {
126
61
  tape.push(record)
127
62
  })
128
63
 
129
64
  try {
130
- await task.run({})
131
- } catch (e) {
132
- // Error is expected
65
+ await task.run({ value: 5 })
66
+ } catch (error) {
67
+ // Expected error
133
68
  }
134
69
 
135
- expect(tape.length).toBe(1)
136
- expect(tape[0].input).toEqual({})
137
- expect(tape[0].error).toBe('Value is required')
138
- expect(tape[0].boundaries).toEqual({
139
- fetchExternalData: [
140
- { input: [], output: { foo: false } }
141
- ]
142
- })
70
+ expect(tape).toEqual([{
71
+ input: { value: 5 },
72
+ error: 'Network error',
73
+ boundaries: {
74
+ getTen: [{
75
+ input: [],
76
+ error: 'Network error'
77
+ }]
78
+ },
79
+ taskName: 'test',
80
+ metadata: {},
81
+ type: 'error'
82
+ }])
143
83
  })
144
84
 
145
- it('Should record error + success and their boundaries tape', async () => {
146
- const tape: TaskRecord<{ value?: number }, { value: number, foo: boolean }>[] = []
147
-
148
- // Create a schema for the task
149
- const schema = new Schema({
150
- value: Schema.number().optional()
151
- })
152
-
153
- // Define the boundaries
154
- const boundaries = {
155
- fetchExternalData: async (): Promise<{ foo: boolean }> => {
156
- return { foo: false }
157
- }
158
- }
159
-
160
- // Create the task using createTask
161
- const task = createTask(
162
- schema,
163
- boundaries,
164
- async (argv, boundaries) => {
165
- const externalData = await boundaries.fetchExternalData()
166
- if (typeof argv.value === 'undefined') {
167
- throw new Error('Value is required')
85
+ it('Should add a listener to the task and capture boundaries with dynamic parameters', async () => {
86
+ const tape: ExecutionRecord[] = []
87
+ const task = createTask({
88
+ name: 'test',
89
+ schema: new Schema({}),
90
+ boundaries: {
91
+ addNumbers: async (a: number, b: number) => {
92
+ return a + b
168
93
  }
169
-
170
- return { ...externalData, ...argv as { value: number } }
94
+ },
95
+ fn: async (argv, boundaries) => {
96
+ const sum = await boundaries.addNumbers(3, 7)
97
+ return { value: sum, foo: sum > 5 }
171
98
  }
172
- )
173
-
174
- task.addListener<{ value?: number }, { value: number, foo: boolean }>((record) => {
175
- tape.push(record)
176
99
  })
177
100
 
178
- try {
179
- await task.run({})
180
- } catch (e) {
181
- // Error is expected
182
- }
183
- await task.run({ value: 5 })
184
-
185
- expect(tape.length).toBe(2)
186
- expect(tape[0].input).toEqual({})
187
- expect(tape[0].error).toBe('Value is required')
188
- expect(tape[0].boundaries).toEqual({
189
- fetchExternalData: [
190
- { input: [], output: { foo: false } }
191
- ]
101
+ task.addListener((record) => {
102
+ tape.push(record)
192
103
  })
193
104
 
194
- expect(tape[1].input).toEqual({ value: 5 })
195
- expect(tape[1].output).toEqual({ value: 5, foo: false })
196
- expect(tape[1].boundaries).toEqual({
197
- fetchExternalData: [
198
- { input: [], output: { foo: false } }
199
- ]
200
- })
105
+ await task.run({})
106
+ expect(tape).toEqual([{
107
+ input: {},
108
+ output: { value: 10, foo: true },
109
+ boundaries: {
110
+ addNumbers: [{
111
+ input: [3, 7],
112
+ output: 10
113
+ }]
114
+ },
115
+ taskName: 'test',
116
+ metadata: {},
117
+ type: 'success'
118
+ }])
201
119
  })
202
120
 
203
- it('Should record 2 run logs if boundary called twice', async () => {
204
- const tape: TaskRecord<{ value: number }, { foo: boolean }>[] = []
205
-
206
- // Create a schema for the task
207
- const schema = new Schema({
208
- value: Schema.number()
209
- })
210
-
211
- // Define the boundaries
212
- const boundaries = {
213
- fetchExternalData: async (): Promise<{ foo: boolean }> => {
214
- return { foo: false }
215
- }
216
- }
217
-
218
- // Create the task using createTask
219
- const task = createTask(
220
- schema,
221
- boundaries,
222
- async (argv, boundaries) => {
223
- await boundaries.fetchExternalData()
224
- await boundaries.fetchExternalData()
225
-
226
- return { foo: true }
121
+ it('Should add a listener to the task and capture boundaries with optional parameters', async () => {
122
+ const tape: ExecutionRecord[] = []
123
+ const task = createTask({
124
+ name: 'test',
125
+ schema: new Schema({
126
+ value: Schema.number().optional()
127
+ }),
128
+ boundaries: {
129
+ processValue: async (val?: number) => {
130
+ return val || 0
131
+ }
132
+ },
133
+ fn: async (argv, boundaries) => {
134
+ const processed = await boundaries.processValue(argv.value)
135
+ return { value: processed, foo: processed > 5 }
227
136
  }
228
- )
137
+ })
229
138
 
230
- task.addListener<{ value: number }, { foo: boolean }>((record) => {
139
+ task.addListener((record) => {
231
140
  tape.push(record)
232
141
  })
233
142
 
234
- await task.run({ value: 5 })
235
-
236
- expect(tape.length).toBe(1)
237
- expect(tape[0].input).toEqual({ value: 5 })
238
- expect(tape[0].output).toEqual({ foo: true })
239
- expect(tape[0].boundaries).toEqual({
240
- fetchExternalData: [
241
- { input: [], output: { foo: false } },
242
- { input: [], output: { foo: false } }
243
- ]
244
- })
143
+ await task.run({ value: undefined })
144
+ expect(tape).toEqual([{
145
+ input: { value: undefined },
146
+ output: { value: 0, foo: false },
147
+ boundaries: {
148
+ processValue: [{
149
+ input: [undefined],
150
+ output: 0
151
+ }]
152
+ },
153
+ taskName: 'test',
154
+ metadata: {},
155
+ type: 'success'
156
+ }])
245
157
  })
246
158
 
247
- it('Should record 2 boundary logs', async () => {
248
- const tape: TaskRecord<{ value: number }, number>[] = []
249
-
250
- // Create a schema for the task
251
- const schema = new Schema({
252
- value: Schema.number()
253
- })
254
-
255
- // Define the boundaries
256
- const boundaries = {
257
- add: async (value: number): Promise<number> => {
258
- return value + 1
159
+ it('Should add a listener to the task and capture boundaries with multiple calls', async () => {
160
+ const tape: ExecutionRecord[] = []
161
+ const task = createTask({
162
+ name: 'test',
163
+ schema: new Schema({
164
+ value: Schema.number()
165
+ }),
166
+ boundaries: {
167
+ multiplyByTwo: async (num: number) => {
168
+ return num * 2
169
+ }
259
170
  },
260
- subtract: async (value: number): Promise<number> => {
261
- return value - 1
171
+ fn: async (argv, boundaries) => {
172
+ const doubled = await boundaries.multiplyByTwo(argv.value)
173
+ const quadrupled = await boundaries.multiplyByTwo(doubled)
174
+ return { foo: quadrupled > 10 }
262
175
  }
263
- }
176
+ })
264
177
 
265
- // Create the task using createTask
266
- const task = createTask(
267
- schema,
268
- boundaries,
269
- async (argv, boundaries) => {
270
- let counter = argv.value
178
+ task.addListener((record) => {
179
+ tape.push(record)
180
+ })
271
181
 
272
- counter = await boundaries.add(counter)
273
- counter = await boundaries.subtract(counter)
274
- counter = await boundaries.subtract(counter)
182
+ await task.run({ value: 3 })
183
+ expect(tape).toEqual([{
184
+ input: { value: 3 },
185
+ output: { foo: true },
186
+ boundaries: {
187
+ multiplyByTwo: [
188
+ {
189
+ input: [3],
190
+ output: 6
191
+ },
192
+ {
193
+ input: [6],
194
+ output: 12
195
+ }
196
+ ]
197
+ },
198
+ taskName: 'test',
199
+ metadata: {},
200
+ type: 'success'
201
+ }])
202
+ })
275
203
 
276
- return counter
204
+ it('Should add a listener to the task and capture boundaries with mixed results', async () => {
205
+ const tape: ExecutionRecord[] = []
206
+ const task = createTask({
207
+ name: 'test',
208
+ schema: new Schema({
209
+ value: Schema.number()
210
+ }),
211
+ boundaries: {
212
+ getResult: async (num: number) => {
213
+ if (num > 5) {
214
+ return num * 2
215
+ }
216
+ throw new Error('Number too small')
217
+ }
218
+ },
219
+ fn: async (argv, boundaries) => {
220
+ let result = 0
221
+ try {
222
+ result = await boundaries.getResult(argv.value)
223
+ } catch (error) {
224
+ // Continue with default
225
+ }
226
+ return result
277
227
  }
278
- )
228
+ })
279
229
 
280
- task.addListener<{ value: number }, number>((record) => {
230
+ task.addListener((record) => {
281
231
  tape.push(record)
282
232
  })
283
233
 
284
- await task.run({ value: 5 })
285
-
286
- expect(tape.length).toBe(1)
287
- expect(tape[0].input).toEqual({ value: 5 })
288
- expect(tape[0].output).toBe(4)
289
- expect(tape[0].boundaries).toEqual({
290
- add: [
291
- { input: [5], output: 6 }
292
- ],
293
- subtract: [
294
- { input: [6], output: 5 },
295
- { input: [5], output: 4 }
296
- ]
297
- })
234
+ await task.run({ value: 3 })
235
+ expect(tape).toEqual([{
236
+ input: { value: 3 },
237
+ output: 0,
238
+ boundaries: {
239
+ getResult: [{
240
+ input: [3],
241
+ error: 'Number too small'
242
+ }]
243
+ },
244
+ taskName: 'test',
245
+ metadata: {},
246
+ type: 'success'
247
+ }])
298
248
  })
299
249
  })