@forgehive/task 0.1.13 → 0.2.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.
@@ -17,14 +17,15 @@ describe('Listener with boundaries tests', () => {
17
17
  }
18
18
 
19
19
  // Create the task using createTask
20
- const task = createTask(
20
+ const task = createTask({
21
+ name: 'task',
21
22
  schema,
22
23
  boundaries,
23
- async (argv, boundaries) => {
24
+ fn: async (argv, boundaries) => {
24
25
  const externalData = await boundaries.fetchExternalData()
25
26
  return { ...externalData, ...argv }
26
27
  }
27
- )
28
+ })
28
29
 
29
30
  task.addListener<{ value: number }, { value: number, foo: boolean }>((record) => {
30
31
  tape.push(record)
@@ -58,14 +59,15 @@ describe('Listener with boundaries tests', () => {
58
59
  }
59
60
 
60
61
  // Create the task using createTask
61
- const task = createTask(
62
+ const task = createTask({
63
+ name: 'task',
62
64
  schema,
63
65
  boundaries,
64
- async (argv, boundaries) => {
66
+ fn: async (argv, boundaries) => {
65
67
  const externalData = await boundaries.fetchExternalData()
66
68
  return { ...externalData, ...argv }
67
69
  }
68
- )
70
+ })
69
71
 
70
72
  task.addListener<{ value: number }, { value: number, foo: boolean }>((record) => {
71
73
  tape.push(record)
@@ -109,10 +111,11 @@ describe('Listener with boundaries tests', () => {
109
111
  }
110
112
 
111
113
  // Create the task using createTask
112
- const task = createTask(
114
+ const task = createTask({
115
+ name: 'task',
113
116
  schema,
114
117
  boundaries,
115
- async (argv, boundaries) => {
118
+ fn: async (argv, boundaries) => {
116
119
  const externalData = await boundaries.fetchExternalData()
117
120
  if (typeof argv.value === 'undefined') {
118
121
  throw new Error('Value is required')
@@ -120,7 +123,7 @@ describe('Listener with boundaries tests', () => {
120
123
 
121
124
  return { ...externalData, ...argv as { value: number } }
122
125
  }
123
- )
126
+ })
124
127
 
125
128
  task.addListener<Record<string, unknown>, { value: number, foo: boolean }>((record) => {
126
129
  tape.push(record)
@@ -158,10 +161,11 @@ describe('Listener with boundaries tests', () => {
158
161
  }
159
162
 
160
163
  // Create the task using createTask
161
- const task = createTask(
164
+ const task = createTask({
165
+ name: 'task',
162
166
  schema,
163
167
  boundaries,
164
- async (argv, boundaries) => {
168
+ fn: async (argv, boundaries) => {
165
169
  const externalData = await boundaries.fetchExternalData()
166
170
  if (typeof argv.value === 'undefined') {
167
171
  throw new Error('Value is required')
@@ -169,7 +173,7 @@ describe('Listener with boundaries tests', () => {
169
173
 
170
174
  return { ...externalData, ...argv as { value: number } }
171
175
  }
172
- )
176
+ })
173
177
 
174
178
  task.addListener<{ value?: number }, { value: number, foo: boolean }>((record) => {
175
179
  tape.push(record)
@@ -216,16 +220,17 @@ describe('Listener with boundaries tests', () => {
216
220
  }
217
221
 
218
222
  // Create the task using createTask
219
- const task = createTask(
223
+ const task = createTask({
224
+ name: 'task',
220
225
  schema,
221
226
  boundaries,
222
- async (argv, boundaries) => {
227
+ fn: async (argv, boundaries) => {
223
228
  await boundaries.fetchExternalData()
224
229
  await boundaries.fetchExternalData()
225
230
 
226
231
  return { foo: true }
227
232
  }
228
- )
233
+ })
229
234
 
230
235
  task.addListener<{ value: number }, { foo: boolean }>((record) => {
231
236
  tape.push(record)
@@ -263,10 +268,11 @@ describe('Listener with boundaries tests', () => {
263
268
  }
264
269
 
265
270
  // Create the task using createTask
266
- const task = createTask(
271
+ const task = createTask({
272
+ name: 'task',
267
273
  schema,
268
274
  boundaries,
269
- async (argv, boundaries) => {
275
+ fn: async (argv, boundaries) => {
270
276
  let counter = argv.value
271
277
 
272
278
  counter = await boundaries.add(counter)
@@ -275,7 +281,7 @@ describe('Listener with boundaries tests', () => {
275
281
 
276
282
  return counter
277
283
  }
278
- )
284
+ })
279
285
 
280
286
  task.addListener<{ value: number }, number>((record) => {
281
287
  tape.push(record)
@@ -1,7 +1,14 @@
1
1
  import { Schema } from '@forgehive/schema'
2
- import { createTask, ExecutionRecord } from '../index'
2
+ import { createTask, ExecutionRecord, getExecutionRecordType } from '../index'
3
3
 
4
4
  describe('Complex boundary replay tests', () => {
5
+ // Helper function to create ExecutionRecord with computed type
6
+ function createExecutionRecord<T, U>(partial: Omit<ExecutionRecord<T, U>, 'type'>): ExecutionRecord<T, U> {
7
+ return {
8
+ ...partial,
9
+ type: getExecutionRecordType(partial)
10
+ }
11
+ }
5
12
  // Define types for our portfolio data
6
13
  type Stock = {
7
14
  ticker: string;
@@ -81,10 +88,11 @@ describe('Complex boundary replay tests', () => {
81
88
  })
82
89
 
83
90
  // Create the portfolio value calculation task
84
- calculatePortfolioValue = createTask(
91
+ calculatePortfolioValue = createTask({
92
+ name: 'calculatePortfolioValue',
85
93
  schema,
86
94
  boundaries,
87
- async ({ userId }, { fetchPortfolio, fetchPrice }) => {
95
+ fn: async ({ userId }, { fetchPortfolio, fetchPrice }) => {
88
96
  // First fetch the portfolio for the user
89
97
  const portfolio = await fetchPortfolio(userId)
90
98
 
@@ -114,7 +122,7 @@ describe('Complex boundary replay tests', () => {
114
122
  stocks: stocksWithValue
115
123
  }
116
124
  }
117
- )
125
+ })
118
126
  })
119
127
 
120
128
  it('Should calculate portfolio value using multiple boundaries', async () => {
@@ -158,7 +166,7 @@ describe('Complex boundary replay tests', () => {
158
166
 
159
167
  it('Should replay portfolio calculation from an execution log', async () => {
160
168
  // First create a portfolio value calculation execution log
161
- const executionLog: ExecutionRecord = {
169
+ const executionLog: ExecutionRecord = createExecutionRecord({
162
170
  input: { userId: 'user1' },
163
171
  output: {
164
172
  id: 'portfolio1',
@@ -200,7 +208,7 @@ describe('Complex boundary replay tests', () => {
200
208
  }
201
209
  ]
202
210
  }
203
- }
211
+ })
204
212
 
205
213
  // Use replay mode for all boundaries
206
214
  const [replayResult, replayError, replayLog] = await calculatePortfolioValue.safeReplay(
@@ -235,7 +243,7 @@ describe('Complex boundary replay tests', () => {
235
243
 
236
244
  it('Should handle errors during replay', async () => {
237
245
  // Create an execution log with an error in one of the price fetches
238
- const executionLog: ExecutionRecord = {
246
+ const executionLog: ExecutionRecord = createExecutionRecord({
239
247
  input: { userId: 'user1' },
240
248
  error: 'Price data not available for ticker: GOOGL',
241
249
  boundaries: {
@@ -268,7 +276,7 @@ describe('Complex boundary replay tests', () => {
268
276
  }
269
277
  ]
270
278
  }
271
- }
279
+ })
272
280
 
273
281
  // Use replay mode for all boundaries
274
282
  const [replayResult, replayError, replayLog] = await calculatePortfolioValue.safeReplay(
@@ -303,7 +311,7 @@ describe('Complex boundary replay tests', () => {
303
311
  priceData['AAPL'] = 195.00 // Different from replay data
304
312
 
305
313
  // Create an execution log with historical data
306
- const executionLog: ExecutionRecord = {
314
+ const executionLog: ExecutionRecord = createExecutionRecord({
307
315
  input: { userId: 'user1' },
308
316
  output: {
309
317
  id: 'portfolio1',
@@ -345,7 +353,7 @@ describe('Complex boundary replay tests', () => {
345
353
  }
346
354
  ]
347
355
  }
348
- }
356
+ })
349
357
 
350
358
  // Use replay mode for portfolio but proxy mode for prices
351
359
  const [replayResult, replayError, replayLog] = await calculatePortfolioValue.safeReplay(
@@ -1,7 +1,15 @@
1
1
  import { Schema } from '@forgehive/schema'
2
- import { createTask, ExecutionRecord } from '../index'
2
+ import { createTask, ExecutionRecord, getExecutionRecordType } from '../index'
3
3
 
4
4
  describe('safeReplay functionality tests', () => {
5
+ // Helper function to create ExecutionRecord with computed type
6
+ function createExecutionRecord<T, U>(partial: Omit<ExecutionRecord<T, U>, 'type'>): ExecutionRecord<T, U> {
7
+ return {
8
+ ...partial,
9
+ type: getExecutionRecordType(partial)
10
+ }
11
+ }
12
+
5
13
  // Common variables
6
14
  let prices: Record<string, number>
7
15
  let boundaries: {
@@ -38,22 +46,23 @@ describe('safeReplay functionality tests', () => {
38
46
  }
39
47
 
40
48
  // Create the task using createTask
41
- getTickerPrice = createTask(
49
+ getTickerPrice = createTask({
50
+ name: 'getTickerPrice',
42
51
  schema,
43
52
  boundaries,
44
- async ({ ticker }, { fetchData }) => {
53
+ fn: async ({ ticker }, { fetchData }) => {
45
54
  const price = await fetchData(ticker)
46
55
  return {
47
56
  ticker,
48
57
  price
49
58
  }
50
59
  }
51
- )
60
+ })
52
61
  })
53
62
 
54
63
  it('Should replay a previous execution using the execution log and replay the fetchData boundary', async () => {
55
64
  // Create a manual execution log
56
- const executionLog: ExecutionRecord = {
65
+ const executionLog: ExecutionRecord = createExecutionRecord({
57
66
  input: { ticker: 'AAPL' },
58
67
  output: {
59
68
  ticker: 'AAPL',
@@ -67,7 +76,7 @@ describe('safeReplay functionality tests', () => {
67
76
  }
68
77
  ]
69
78
  }
70
- }
79
+ })
71
80
 
72
81
  // No safeReplay method yet, this will be implemented later
73
82
  // This will be our test for that functionality
@@ -101,7 +110,7 @@ describe('safeReplay functionality tests', () => {
101
110
 
102
111
  it('Should execute with mixed boundaries modes', async () => {
103
112
  // Create a manual execution log for testing
104
- const executionLog: ExecutionRecord = {
113
+ const executionLog: ExecutionRecord = createExecutionRecord({
105
114
  input: { ticker: 'AAPL' },
106
115
  output: {
107
116
  ticker: 'AAPL',
@@ -115,7 +124,7 @@ describe('safeReplay functionality tests', () => {
115
124
  }
116
125
  ]
117
126
  }
118
- }
127
+ })
119
128
 
120
129
  // Use mixed mode - replay for fetchData but execute logAccess
121
130
  const [replayResult, replayError, replayLog] = await getTickerPrice.safeReplay(
@@ -153,7 +162,7 @@ describe('safeReplay functionality tests', () => {
153
162
 
154
163
  it('Should properly handle errors in boundary replay mode', async () => {
155
164
  // Create a manual execution log with an error in the boundary
156
- const executionLog: ExecutionRecord = {
165
+ const executionLog: ExecutionRecord = createExecutionRecord({
157
166
  input: { ticker: 'AAPL' },
158
167
  output: null,
159
168
  error: 'API error: Rate limit exceeded',
@@ -165,7 +174,7 @@ describe('safeReplay functionality tests', () => {
165
174
  }
166
175
  ]
167
176
  }
168
- }
177
+ })
169
178
 
170
179
  // Use replay mode for fetchData
171
180
  const [replayResult, replayError, replayLog] = await getTickerPrice.safeReplay(
@@ -189,7 +198,7 @@ describe('safeReplay functionality tests', () => {
189
198
 
190
199
  it('Should handle boundaries with both output and error as null', async () => {
191
200
  // Create a manual execution log with null output and error in the boundary
192
- const executionLog: ExecutionRecord = {
201
+ const executionLog: ExecutionRecord = createExecutionRecord({
193
202
  input: { ticker: 'AAPL' },
194
203
  output: { ticker: 'AAPL', price: 160.23 },
195
204
  boundaries: {
@@ -201,7 +210,7 @@ describe('safeReplay functionality tests', () => {
201
210
  }
202
211
  ]
203
212
  }
204
- }
213
+ })
205
214
 
206
215
  // Use replay mode for fetchData
207
216
  const [replayResult, replayError, replayLog] = await getTickerPrice.safeReplay(
@@ -15,14 +15,15 @@ describe('Task safeRun tests', () => {
15
15
  }
16
16
 
17
17
  // Create the task
18
- const successTask = createTask(
18
+ const successTask = createTask({
19
+ name: 'successTask',
19
20
  schema,
20
21
  boundaries,
21
- async function ({ value }, { fetchData }) {
22
+ fn: async function ({ value }, { fetchData }) {
22
23
  const result = await fetchData(value)
23
24
  return { result, success: true }
24
25
  }
25
- )
26
+ })
26
27
 
27
28
  // Call safeRun with valid input
28
29
  const [result, error, record] = await successTask.safeRun({ value: 5 })
@@ -58,14 +59,15 @@ describe('Task safeRun tests', () => {
58
59
  }
59
60
 
60
61
  // Create the task
61
- const errorTask = createTask(
62
+ const errorTask = createTask({
63
+ name: 'errorTask',
62
64
  schema,
63
65
  boundaries,
64
- async function ({ value }, { fetchData }) {
66
+ fn: async function ({ value }, { fetchData }) {
65
67
  const result = await fetchData(value)
66
68
  return { result, success: true }
67
69
  }
68
- )
70
+ })
69
71
 
70
72
  // Call safeRun with problematic input that will cause an error
71
73
  const [result, error, record] = await errorTask.safeRun({ value: -5 })
@@ -101,14 +103,15 @@ describe('Task safeRun tests', () => {
101
103
  }
102
104
 
103
105
  // Create the task
104
- const validationTask = createTask(
106
+ const validationTask = createTask({
107
+ name: 'validationTask',
105
108
  schema,
106
109
  boundaries,
107
- async function ({ value }, { fetchData }) {
110
+ fn: async function ({ value }, { fetchData }) {
108
111
  const result = await fetchData(value)
109
112
  return { result, success: true }
110
113
  }
111
- )
114
+ })
112
115
 
113
116
  // Call safeRun with invalid input that will fail schema validation
114
117
  const [result, error, record] = await validationTask.safeRun({ value: 0 })
@@ -142,14 +145,15 @@ describe('Task safeRun tests', () => {
142
145
  }
143
146
 
144
147
  // Create the task
145
- const listenerTask = createTask(
148
+ const listenerTask = createTask({
149
+ name: 'listenerTask',
146
150
  schema,
147
151
  boundaries,
148
- async function ({ value }, { fetchData }) {
152
+ fn: async function ({ value }, { fetchData }) {
149
153
  const result = await fetchData(value)
150
154
  return result
151
155
  }
152
- )
156
+ })
153
157
 
154
158
  // Create a mock listener
155
159
  const originalListener = jest.fn()
@@ -206,15 +210,16 @@ describe('Task safeRun tests', () => {
206
210
  }
207
211
 
208
212
  // Create a task that uses multiple boundaries
209
- const multiBoundaryTask = createTask(
213
+ const multiBoundaryTask = createTask({
214
+ name: 'multiBoundaryTask',
210
215
  schema,
211
216
  boundaries,
212
- async function ({ values }, { doubleValue, sumValues }) {
217
+ fn: async function ({ values }, { doubleValue, sumValues }) {
213
218
  const doubled = await Promise.all(values.map(value => doubleValue(value)))
214
219
  const total = await sumValues(doubled)
215
220
  return { doubled, total }
216
221
  }
217
- )
222
+ })
218
223
 
219
224
  // Call safeRun
220
225
  const [result, error, record] = await multiBoundaryTask.safeRun({ values: [1, 2, 3] })
@@ -17,14 +17,15 @@ describe('Task boundary mocking', () => {
17
17
  }
18
18
 
19
19
  // Create the task using createTask
20
- const multiplyTask = createTask(
20
+ const multiplyTask = createTask({
21
+ name: 'multiplyTask',
21
22
  schema,
22
23
  boundaries,
23
- async function ({ value }, { fetchExternalData }) {
24
+ fn: async function ({ value }, { fetchExternalData }) {
24
25
  const result = value * await fetchExternalData(value)
25
26
  return result
26
27
  }
27
- )
28
+ })
28
29
 
29
30
  // Create mock for fetchExternalData boundary that returns a specific value
30
31
  const mockFetchData = jest.fn().mockResolvedValue(5)
@@ -71,15 +72,16 @@ describe('Task boundary mocking', () => {
71
72
  }
72
73
 
73
74
  // Create the task
74
- const calculateTask = createTask(
75
+ const calculateTask = createTask({
76
+ name: 'calculateTask',
75
77
  schema,
76
78
  boundaries,
77
- async function ({ value }, { doubleValue, tripleValue }) {
79
+ fn: async function ({ value }, { doubleValue, tripleValue }) {
78
80
  const doubled = await doubleValue(value)
79
81
  const tripled = await tripleValue(value)
80
82
  return doubled + tripled
81
83
  }
82
- )
84
+ })
83
85
 
84
86
  // Create wrapped mock functions
85
87
  const mockDoubleValue = jest.fn().mockResolvedValue(10)