@t4h.framework/core 0.3.0 → 0.5.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/.ai/skills/framework-core/SKILL.md +403 -0
- package/.ai/skills/framework-workflow-creation/SKILL.md +170 -0
- package/.ai/skills/framework-workflow-testing/SKILL.md +172 -0
- package/README.md +78 -5
- package/dist/core.d.ts +1 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +1 -0
- package/dist/core.js.map +1 -1
- package/dist/models/Logger.d.ts +13 -0
- package/dist/models/Logger.d.ts.map +1 -0
- package/dist/models/Logger.js +42 -0
- package/dist/models/Logger.js.map +1 -0
- package/dist/testing/WorkflowTesting.d.ts +6 -0
- package/dist/testing/WorkflowTesting.d.ts.map +1 -0
- package/dist/testing/WorkflowTesting.js +7 -0
- package/dist/testing/WorkflowTesting.js.map +1 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +2 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/run-workflow.d.ts +31 -0
- package/dist/testing/run-workflow.d.ts.map +1 -0
- package/dist/testing/run-workflow.js +102 -0
- package/dist/testing/run-workflow.js.map +1 -0
- package/dist/tools/Internals.d.ts +2 -0
- package/dist/tools/Internals.d.ts.map +1 -1
- package/dist/tools/Internals.js +2 -1
- package/dist/tools/Internals.js.map +1 -1
- package/dist/tools/runWorkflowToCompletion.d.ts +15 -0
- package/dist/tools/runWorkflowToCompletion.d.ts.map +1 -0
- package/dist/tools/runWorkflowToCompletion.js +61 -0
- package/dist/tools/runWorkflowToCompletion.js.map +1 -0
- package/package.json +11 -4
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: framework-workflow-testing
|
|
3
|
+
description: >-
|
|
4
|
+
Build and maintain high-quality unit tests for T4H Framework workflows using
|
|
5
|
+
@t4h.framework/core/testing. Use this whenever the user asks to test a
|
|
6
|
+
workflow, add Vitest coverage for History.reconciler flows, mock claims,
|
|
7
|
+
validate logs, or simulate async activity outcomes (fulfilled/rejected/timeout),
|
|
8
|
+
even when they only mention "workflow test", "mock claim", or "run workflow in memory".
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Workflow unit testing with `@t4h.framework/core/testing`
|
|
12
|
+
|
|
13
|
+
Use this skill to create or improve **workflow-focused unit tests** in T4H Framework projects.
|
|
14
|
+
|
|
15
|
+
## What this skill optimizes
|
|
16
|
+
|
|
17
|
+
- Fast in-memory workflow execution with `WorkflowTesting.run`.
|
|
18
|
+
- Reliable claim mocking with real claim instances + `vi.spyOn`.
|
|
19
|
+
- Clear assertions for behavior (calls, payload, order, and logs).
|
|
20
|
+
- Predictable handling of async activities with `mockAsyncActivity`.
|
|
21
|
+
|
|
22
|
+
## When to choose this skill
|
|
23
|
+
|
|
24
|
+
Choose this skill when the user asks to:
|
|
25
|
+
|
|
26
|
+
- test a `Workflow` end-to-end (without infra);
|
|
27
|
+
- mock outbound dependencies used by activities (HTTP, DB, etc.);
|
|
28
|
+
- assert emitted logs for workflow execution paths;
|
|
29
|
+
- simulate async activity outcomes in tests;
|
|
30
|
+
- add or fix `vitest` tests for workflow modules.
|
|
31
|
+
|
|
32
|
+
If the request is specifically about testing `AsyncActivity.advance`, use `Internals.runActivity` directly instead of only `WorkflowTesting.run`.
|
|
33
|
+
|
|
34
|
+
## Public API available
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { WorkflowTesting } from '@t4h.framework/core/testing'
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`WorkflowTesting.run(workflow, input?, options?)`
|
|
41
|
+
|
|
42
|
+
Supported options:
|
|
43
|
+
|
|
44
|
+
- `claims`: claim providers used during execution.
|
|
45
|
+
- `env`: environment entries for `Env.run`.
|
|
46
|
+
- `mockAsyncActivity`: function or queue for pending async activities.
|
|
47
|
+
- `logs`: capture runtime logs.
|
|
48
|
+
- `maxTicks`: protect against infinite replay loops (default `10_000`).
|
|
49
|
+
|
|
50
|
+
## Canonical workflow test pattern
|
|
51
|
+
|
|
52
|
+
Follow this structure by default:
|
|
53
|
+
|
|
54
|
+
1. Arrange claims and spies in helper functions.
|
|
55
|
+
2. Initialize setup in `beforeEach`.
|
|
56
|
+
3. Execute workflow with `WorkflowTesting.run`.
|
|
57
|
+
4. Assert calls, payload structure, ordering, and logs.
|
|
58
|
+
|
|
59
|
+
Base mock style on this pattern:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
function createClaimsWithHttpSpy() {
|
|
63
|
+
const http = findClaimByConstructor(DevHttpClientRequestClaim)
|
|
64
|
+
const mockRequest = vi.spyOn(http, 'request').mockResolvedValue({
|
|
65
|
+
status: 200,
|
|
66
|
+
headers: { 'content-type': 'application/json' },
|
|
67
|
+
body: Readable.from(Buffer.from('{}')),
|
|
68
|
+
})
|
|
69
|
+
return { claims, mockRequest }
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Why this pattern: it keeps tests close to real wiring while still allowing strict call inspection.
|
|
74
|
+
|
|
75
|
+
## Standard recipe for new tests
|
|
76
|
+
|
|
77
|
+
### 1) Create setup helpers
|
|
78
|
+
|
|
79
|
+
- Put claim setup and spies in dedicated functions (`createClaimsWith...`).
|
|
80
|
+
- Return both `claims` and the spy object(s) for assertions.
|
|
81
|
+
- Keep data decoders (e.g. request-body parser) as small utility functions.
|
|
82
|
+
|
|
83
|
+
### 2) Execute workflow under test
|
|
84
|
+
|
|
85
|
+
- Use `await WorkflowTesting.run(workflow, input, { claims, logs, ... })`.
|
|
86
|
+
- Capture logs with `const logs: Log[] = []` when log behavior matters.
|
|
87
|
+
|
|
88
|
+
### 3) Assert behavior and contract
|
|
89
|
+
|
|
90
|
+
Prefer these assertions:
|
|
91
|
+
|
|
92
|
+
- call count (`toHaveBeenCalledTimes`);
|
|
93
|
+
- important call arguments (URL, method, payload);
|
|
94
|
+
- ordering (`mock.calls[0]`, `mock.calls[1]`);
|
|
95
|
+
- final workflow output;
|
|
96
|
+
- log messages and sequence (`logs.map(entry => entry.args[0])`).
|
|
97
|
+
|
|
98
|
+
### 4) Cover async outcomes when applicable
|
|
99
|
+
|
|
100
|
+
If any async activity can return `pending`, provide `mockAsyncActivity`.
|
|
101
|
+
|
|
102
|
+
Function strategy:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
mockAsyncActivity: (activity, { index, pending }) => {
|
|
106
|
+
if (index === 0) return { status: 'fulfilled', output: true }
|
|
107
|
+
return { status: 'rejected', reason: 'denied' }
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Queue strategy:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
mockAsyncActivity: [
|
|
115
|
+
{ status: 'fulfilled', output: true },
|
|
116
|
+
{ status: 'timeout' },
|
|
117
|
+
]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Important behavior:
|
|
121
|
+
|
|
122
|
+
- no resolver + pending async => throws;
|
|
123
|
+
- timeout outcome runs real `onTimeout`;
|
|
124
|
+
- exhausted queue => throws `No more async outcomes`.
|
|
125
|
+
|
|
126
|
+
## Mocking guidelines (do this, avoid that)
|
|
127
|
+
|
|
128
|
+
Do:
|
|
129
|
+
|
|
130
|
+
- mock concrete claim instances used by runtime providers;
|
|
131
|
+
- use `vi.spyOn` on dependency methods (e.g. `request`);
|
|
132
|
+
- return realistic shapes (status/headers/body) for external call mocks;
|
|
133
|
+
- isolate each test with `beforeEach`.
|
|
134
|
+
|
|
135
|
+
Avoid:
|
|
136
|
+
|
|
137
|
+
- over-mocking framework internals;
|
|
138
|
+
- asserting implementation details unrelated to behavior;
|
|
139
|
+
- using `WorkflowTesting.run` to validate real `advance` logic.
|
|
140
|
+
|
|
141
|
+
## Minimal template to generate quickly
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
import { WorkflowTesting } from '@t4h.framework/core/testing'
|
|
145
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
146
|
+
|
|
147
|
+
describe('my workflow', () => {
|
|
148
|
+
let claims: ReturnType<typeof createClaimsWithSpy>['claims']
|
|
149
|
+
let mockCall: ReturnType<typeof vi.spyOn>
|
|
150
|
+
|
|
151
|
+
beforeEach(() => {
|
|
152
|
+
const setup = createClaimsWithSpy()
|
|
153
|
+
claims = setup.claims
|
|
154
|
+
mockCall = setup.mockCall
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
it('runs to completion with expected side effects', async () => {
|
|
158
|
+
const logs = []
|
|
159
|
+
await WorkflowTesting.run(myWorkflow, undefined, { claims, logs })
|
|
160
|
+
expect(mockCall).toHaveBeenCalledTimes(1)
|
|
161
|
+
})
|
|
162
|
+
})
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Completion checklist before finishing
|
|
166
|
+
|
|
167
|
+
- Test imports `WorkflowTesting` from `@t4h.framework/core/testing`.
|
|
168
|
+
- Claim providers are passed via `options.claims`.
|
|
169
|
+
- Pending async paths have `mockAsyncActivity`.
|
|
170
|
+
- Assertions cover side effects and expected ordering.
|
|
171
|
+
- Logs are asserted when they are part of the workflow contract.
|
|
172
|
+
- Test file uses Vitest idioms consistently.
|
package/README.md
CHANGED
|
@@ -190,10 +190,7 @@ For long-running operations that need a bootstrap/advance cycle (e.g. waiting fo
|
|
|
190
190
|
|
|
191
191
|
```typescript
|
|
192
192
|
import Type from 'typebox'
|
|
193
|
-
import {
|
|
194
|
-
AsyncActivity,
|
|
195
|
-
AsyncActivityResultPending,
|
|
196
|
-
} from '@t4h.framework/core'
|
|
193
|
+
import { AsyncActivity, AsyncActivityResultPending } from '@t4h.framework/core'
|
|
197
194
|
|
|
198
195
|
const ApprovalSchema = Type.Object({
|
|
199
196
|
approved: Type.Boolean(),
|
|
@@ -243,7 +240,10 @@ class WaitForApprovalActivity extends AsyncActivity<
|
|
|
243
240
|
}
|
|
244
241
|
|
|
245
242
|
public async onTimeout(
|
|
246
|
-
bootstrap: AsyncActivityResultPending<{
|
|
243
|
+
bootstrap: AsyncActivityResultPending<{
|
|
244
|
+
requestId: string
|
|
245
|
+
orderId: string
|
|
246
|
+
}>,
|
|
247
247
|
) {
|
|
248
248
|
return this.rejected({
|
|
249
249
|
approved: false,
|
|
@@ -346,3 +346,76 @@ Env.run → Claim.run → fn(activity)
|
|
|
346
346
|
```
|
|
347
347
|
|
|
348
348
|
**History** handles reconciliation: when an activity has been executed before, the previous result is returned directly (deterministic replay). When there is no history, the activity runs and the result is stored.
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## Testing
|
|
353
|
+
|
|
354
|
+
For running a workflow fully in-memory (driving its activities to completion in a
|
|
355
|
+
single process), use the dedicated `testing` entrypoint. It is meant for tests and
|
|
356
|
+
local execution only and is not part of the runtime contract.
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
import { WorkflowTesting } from '@t4h.framework/core/testing'
|
|
360
|
+
|
|
361
|
+
const output = await WorkflowTesting.run<MyWorkflow>(myWorkflow, input, {
|
|
362
|
+
env: { API_URL: 'https://api.example.com' },
|
|
363
|
+
claims: [
|
|
364
|
+
{ provide: UserRepositoryClaim, value: new UserRepositoryClaimImpl() },
|
|
365
|
+
],
|
|
366
|
+
mockAsyncActivity: () => ({ status: 'fulfilled', output: true }),
|
|
367
|
+
})
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Driving async activities
|
|
371
|
+
|
|
372
|
+
The harness runs the real `bootstrap`. If it already settles (`done`/`rejected`),
|
|
373
|
+
that result is honored. If it returns `pending`, you **must** provide a
|
|
374
|
+
`mockAsyncActivity` mock that declares the outcome for that activity — otherwise
|
|
375
|
+
the run throws. This forces each test to consciously pick the scenario it covers.
|
|
376
|
+
|
|
377
|
+
The mock returns an outcome (not an `advance` payload):
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
// success
|
|
381
|
+
mockAsyncActivity: () => ({ status: 'fulfilled', output: true })
|
|
382
|
+
|
|
383
|
+
// rejection
|
|
384
|
+
mockAsyncActivity: () => ({ status: 'rejected', reason: 'denied' })
|
|
385
|
+
|
|
386
|
+
// timeout — runs the activity's real onTimeout(pending) policy
|
|
387
|
+
mockAsyncActivity: () => ({ status: 'timeout' })
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
For workflows with several async activities in a fixed order, pass an array of
|
|
391
|
+
outcomes — each pending async consumes the next entry (FIFO):
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
mockAsyncActivity: [
|
|
395
|
+
{ status: 'fulfilled', output: true },
|
|
396
|
+
{ status: 'rejected', reason: 'denied' },
|
|
397
|
+
{ status: 'timeout' },
|
|
398
|
+
]
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
The mock receives the activity instance and `{ input, pending, index }`, so you
|
|
402
|
+
can branch per activity or per resolution order:
|
|
403
|
+
|
|
404
|
+
```typescript
|
|
405
|
+
mockAsyncActivity: (activity, { index }) => {
|
|
406
|
+
if (activity instanceof WaitForApprovalActivity)
|
|
407
|
+
return { status: 'fulfilled', output: true }
|
|
408
|
+
|
|
409
|
+
if (index === 1) return { status: 'timeout' }
|
|
410
|
+
|
|
411
|
+
return { status: 'rejected', reason: 'denied' }
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
You can also build the same FIFO behavior explicitly with
|
|
416
|
+
`resolveAsyncActivitiesInOrder([...])` from `@t4h.framework/core/testing`.
|
|
417
|
+
|
|
418
|
+
> The real `advance` logic is intentionally **not** exercised here — drive it in a
|
|
419
|
+
> dedicated activity-level test via `Internals.runActivity`. The pending/resume
|
|
420
|
+
> boundary (`PushWaitAsyncActivity`) is also not modeled: an async activity is a
|
|
421
|
+
> single decision point per run.
|
package/dist/core.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export * from './models/Claim.js';
|
|
|
12
12
|
export * from './models/Env.js';
|
|
13
13
|
export * from './models/EnvDesign.js';
|
|
14
14
|
export * from './models/History.js';
|
|
15
|
+
export * from './models/Logger.js';
|
|
15
16
|
export * from './models/PushActivity.js';
|
|
16
17
|
export * from './models/PushWaitAsyncActivity.js';
|
|
17
18
|
export * from './models/SerializableHelper.js';
|
package/dist/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAA;AAErD,cAAc,mCAAmC,CAAA;AACjD,cAAc,gCAAgC,CAAA;AAE9C,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,2BAA2B,CAAA;AACzC,cAAc,wCAAwC,CAAA;AACtD,cAAc,oCAAoC,CAAA;AAClD,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,mCAAmC,CAAA;AACjD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,yBAAyB,CAAA;AAEvC,cAAc,sBAAsB,CAAA;AAEpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2BAA2B,CAAA"}
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAA;AAErD,cAAc,mCAAmC,CAAA;AACjD,cAAc,gCAAgC,CAAA;AAE9C,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,2BAA2B,CAAA;AACzC,cAAc,wCAAwC,CAAA;AACtD,cAAc,oCAAoC,CAAA;AAClD,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,oBAAoB,CAAA;AAClC,cAAc,0BAA0B,CAAA;AACxC,cAAc,mCAAmC,CAAA;AACjD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,yBAAyB,CAAA;AAEvC,cAAc,sBAAsB,CAAA;AAEpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2BAA2B,CAAA"}
|
package/dist/core.js
CHANGED
|
@@ -12,6 +12,7 @@ export * from './models/Claim.js';
|
|
|
12
12
|
export * from './models/Env.js';
|
|
13
13
|
export * from './models/EnvDesign.js';
|
|
14
14
|
export * from './models/History.js';
|
|
15
|
+
export * from './models/Logger.js';
|
|
15
16
|
export * from './models/PushActivity.js';
|
|
16
17
|
export * from './models/PushWaitAsyncActivity.js';
|
|
17
18
|
export * from './models/SerializableHelper.js';
|
package/dist/core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAA;AAErD,cAAc,mCAAmC,CAAA;AACjD,cAAc,gCAAgC,CAAA;AAE9C,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,2BAA2B,CAAA;AACzC,cAAc,wCAAwC,CAAA;AACtD,cAAc,oCAAoC,CAAA;AAClD,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,mCAAmC,CAAA;AACjD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,yBAAyB,CAAA;AAEvC,cAAc,sBAAsB,CAAA;AAEpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2BAA2B,CAAA"}
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAA;AAErD,cAAc,mCAAmC,CAAA;AACjD,cAAc,gCAAgC,CAAA;AAE9C,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,2BAA2B,CAAA;AACzC,cAAc,wCAAwC,CAAA;AACtD,cAAc,oCAAoC,CAAA;AAClD,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,oBAAoB,CAAA;AAClC,cAAc,0BAA0B,CAAA;AACxC,cAAc,mCAAmC,CAAA;AACjD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,yBAAyB,CAAA;AAEvC,cAAc,sBAAsB,CAAA;AAEpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2BAA2B,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type LogLevel = 'log' | 'debug' | 'info' | 'warn' | 'error';
|
|
2
|
+
export interface Log {
|
|
3
|
+
level: LogLevel;
|
|
4
|
+
args: unknown[];
|
|
5
|
+
at: number;
|
|
6
|
+
}
|
|
7
|
+
export declare namespace Logger {
|
|
8
|
+
interface RunOptions {
|
|
9
|
+
logs: Log[];
|
|
10
|
+
}
|
|
11
|
+
function run<T>(logs: Log[], fn: () => T): T;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=Logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Logger.d.ts","sourceRoot":"","sources":["../../src/models/Logger.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAElE,MAAM,WAAW,GAAG;IAClB,KAAK,EAAE,QAAQ,CAAA;IACf,IAAI,EAAE,OAAO,EAAE,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;CACX;AAOD,yBAAiB,MAAM,CAAC;IAetB,UAAiB,UAAU;QACzB,IAAI,EAAE,GAAG,EAAE,CAAA;KACZ;IAED,SAAgB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,KAS9C;CAyBF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
export var Logger;
|
|
3
|
+
(function (Logger) {
|
|
4
|
+
const storage = new AsyncLocalStorage();
|
|
5
|
+
const levels = ['log', 'debug', 'info', 'warn', 'error'];
|
|
6
|
+
const original = {
|
|
7
|
+
log: console.log.bind(console),
|
|
8
|
+
debug: console.debug.bind(console),
|
|
9
|
+
info: console.info.bind(console),
|
|
10
|
+
warn: console.warn.bind(console),
|
|
11
|
+
error: console.error.bind(console),
|
|
12
|
+
};
|
|
13
|
+
let isIntercepted = false;
|
|
14
|
+
function run(logs, fn) {
|
|
15
|
+
interceptConsole();
|
|
16
|
+
const context = {
|
|
17
|
+
invocationIndex: 0,
|
|
18
|
+
logs,
|
|
19
|
+
};
|
|
20
|
+
return storage.run(context, fn);
|
|
21
|
+
}
|
|
22
|
+
Logger.run = run;
|
|
23
|
+
function interceptConsole() {
|
|
24
|
+
if (isIntercepted)
|
|
25
|
+
return;
|
|
26
|
+
isIntercepted = true;
|
|
27
|
+
for (const level of levels) {
|
|
28
|
+
console[level] = (...args) => record(level, args);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function record(level, args) {
|
|
32
|
+
const context = storage.getStore();
|
|
33
|
+
if (!context)
|
|
34
|
+
return original[level](...args);
|
|
35
|
+
const index = context.invocationIndex++;
|
|
36
|
+
if (index < context.logs.length)
|
|
37
|
+
return;
|
|
38
|
+
context.logs.push({ level, args, at: Date.now() });
|
|
39
|
+
original[level](...args);
|
|
40
|
+
}
|
|
41
|
+
})(Logger || (Logger = {}));
|
|
42
|
+
//# sourceMappingURL=Logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Logger.js","sourceRoot":"","sources":["../../src/models/Logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAepD,MAAM,KAAW,MAAM,CAqDtB;AArDD,WAAiB,MAAM;IACrB,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAiB,CAAA;IAEtD,MAAM,MAAM,GAAwB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IAE7E,MAAM,QAAQ,GAAmD;QAC/D,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;QAC9B,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;QAClC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;QAChC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;QAChC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;KACnC,CAAA;IAED,IAAI,aAAa,GAAG,KAAK,CAAA;IAMzB,SAAgB,GAAG,CAAI,IAAW,EAAE,EAAW;QAC7C,gBAAgB,EAAE,CAAA;QAElB,MAAM,OAAO,GAAkB;YAC7B,eAAe,EAAE,CAAC;YAClB,IAAI;SACL,CAAA;QAED,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;IACjC,CAAC;IATe,UAAG,MASlB,CAAA;IAED,SAAS,gBAAgB;QACvB,IAAI,aAAa;YAAE,OAAM;QAEzB,aAAa,GAAG,IAAI,CAAA;QAEpB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAC9D,CAAC;IACH,CAAC;IAED,SAAS,MAAM,CAAC,KAAe,EAAE,IAAe;QAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAA;QAElC,IAAI,CAAC,OAAO;YAAE,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;QAE7C,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,EAAE,CAAA;QAEvC,IAAI,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM;YAAE,OAAM;QAEvC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;QAElD,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAC1B,CAAC;AACH,CAAC,EArDgB,MAAM,KAAN,MAAM,QAqDtB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type RunWorkflowOptions } from './run-workflow.js';
|
|
2
|
+
import type { Workflow, WorkflowInput } from '../models/Workflow.js';
|
|
3
|
+
export declare class WorkflowTesting {
|
|
4
|
+
static run<T extends Workflow<any, any>>(workflow: T, input?: WorkflowInput<T>, options?: RunWorkflowOptions): Promise<any>;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=WorkflowTesting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkflowTesting.d.ts","sourceRoot":"","sources":["../../src/testing/WorkflowTesting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAEpE,qBAAa,eAAe;WACN,GAAG,CAAC,CAAC,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EAClD,QAAQ,EAAE,CAAC,EACX,KAAK,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,EACxB,OAAO,CAAC,EAAE,kBAAkB;CAI/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkflowTesting.js","sourceRoot":"","sources":["../../src/testing/WorkflowTesting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAA2B,MAAM,mBAAmB,CAAA;AAGxE,MAAM,OAAO,eAAe;IACnB,MAAM,CAAC,KAAK,CAAC,GAAG,CACrB,QAAW,EACX,KAAwB,EACxB,OAA4B;QAE5B,OAAO,WAAW,CAAC,QAAQ,EAAE,KAAyB,EAAE,OAAO,CAAC,CAAA;IAClE,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type AnyAsyncActivity } from '../models/AsyncActivity.js';
|
|
2
|
+
import { AsyncActivityResultPending } from '../models/AsyncActivityAdvanceResult.js';
|
|
3
|
+
import type { ClaimProvider } from '../models/Claim.js';
|
|
4
|
+
import { Env } from '../models/Env.js';
|
|
5
|
+
import type { Log } from '../models/Logger.js';
|
|
6
|
+
import type { Workflow, WorkflowInput } from '../models/Workflow.js';
|
|
7
|
+
interface MockAsyncActivityContext {
|
|
8
|
+
input: unknown;
|
|
9
|
+
pending: AsyncActivityResultPending;
|
|
10
|
+
index: number;
|
|
11
|
+
}
|
|
12
|
+
export type AsyncActivityOutcome = {
|
|
13
|
+
status: 'fulfilled';
|
|
14
|
+
output?: unknown;
|
|
15
|
+
} | {
|
|
16
|
+
status: 'rejected';
|
|
17
|
+
reason?: unknown;
|
|
18
|
+
} | {
|
|
19
|
+
status: 'timeout';
|
|
20
|
+
};
|
|
21
|
+
type MockAsyncActivity = (activity: AnyAsyncActivity, context: MockAsyncActivityContext) => AsyncActivityOutcome | Promise<AsyncActivityOutcome>;
|
|
22
|
+
export interface RunWorkflowOptions {
|
|
23
|
+
claims?: readonly ClaimProvider<any>[];
|
|
24
|
+
env?: Env.Entries;
|
|
25
|
+
mockAsyncActivity?: MockAsyncActivity | readonly AsyncActivityOutcome[];
|
|
26
|
+
maxTicks?: number;
|
|
27
|
+
logs?: Log[];
|
|
28
|
+
}
|
|
29
|
+
export declare function runWorkflow<T extends Workflow<any, any>>(workflow: T, input: WorkflowInput<T>, options?: RunWorkflowOptions): Promise<any>;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=run-workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-workflow.d.ts","sourceRoot":"","sources":["../../src/testing/run-workflow.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EAEL,0BAA0B,EAE3B,MAAM,yCAAyC,CAAA;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAEtC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AAG9C,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAGpE,UAAU,wBAAwB;IAChC,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,0BAA0B,CAAA;IACnC,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GACzC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,CAAA;AAEzB,KAAK,iBAAiB,GAAG,CACvB,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,wBAAwB,KAC9B,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;AAEzD,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,CAAA;IACtC,GAAG,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACjB,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,SAAS,oBAAoB,EAAE,CAAA;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;CACb;AA6BD,wBAAsB,WAAW,CAAC,CAAC,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EAC5D,QAAQ,EAAE,CAAC,EACX,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EACvB,OAAO,GAAE,kBAAuB,gBAmCjC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { AsyncActivity, } from '../models/AsyncActivity.js';
|
|
2
|
+
import { AsyncActivityResultFulfilled, AsyncActivityResultPending, AsyncActivityResultRejected, } from '../models/AsyncActivityAdvanceResult.js';
|
|
3
|
+
import { Env } from '../models/Env.js';
|
|
4
|
+
import { PushActivity } from '../models/PushActivity.js';
|
|
5
|
+
import { SyncActivity } from '../models/SyncActivity.js';
|
|
6
|
+
import { Internals } from '../tools/Internals.js';
|
|
7
|
+
function mockAsyncActivities(outcomes) {
|
|
8
|
+
const queue = [...outcomes];
|
|
9
|
+
return (activity, context) => {
|
|
10
|
+
const next = queue.shift();
|
|
11
|
+
if (!next)
|
|
12
|
+
throw new Error(`No more async outcomes (activity: "${activity.constructor.name}", index: ${context.index}, input: ${JSON.stringify(context.input)})`);
|
|
13
|
+
return next;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function normalizeMockAsyncActivity(mock) {
|
|
17
|
+
if (!mock)
|
|
18
|
+
return undefined;
|
|
19
|
+
if (Array.isArray(mock))
|
|
20
|
+
return mockAsyncActivities(mock);
|
|
21
|
+
return mock;
|
|
22
|
+
}
|
|
23
|
+
export async function runWorkflow(workflow, input, options = {}) {
|
|
24
|
+
const claims = options.claims ?? [];
|
|
25
|
+
const env = options.env ?? {};
|
|
26
|
+
const maxTicks = options.maxTicks ?? 10_000;
|
|
27
|
+
const history = [];
|
|
28
|
+
const logs = options.logs ?? [];
|
|
29
|
+
const mocks = normalizeMockAsyncActivity(options.mockAsyncActivity);
|
|
30
|
+
const resolutionState = { index: 0 };
|
|
31
|
+
for (let tick = 0; tick < maxTicks; tick++) {
|
|
32
|
+
try {
|
|
33
|
+
return await Internals.runWorkflow(workflow, {
|
|
34
|
+
input,
|
|
35
|
+
claims,
|
|
36
|
+
env,
|
|
37
|
+
history,
|
|
38
|
+
logs,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch (pushOrError) {
|
|
42
|
+
if (!(pushOrError instanceof PushActivity))
|
|
43
|
+
throw pushOrError;
|
|
44
|
+
const item = await resolveActivity(pushOrError, { claims, env }, mocks, resolutionState);
|
|
45
|
+
history.push(item);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
throw new Error(`Workflow did not settle within ${maxTicks} ticks`);
|
|
49
|
+
}
|
|
50
|
+
async function resolveActivity(push, context, mockAsyncActivity, resolutionState) {
|
|
51
|
+
const activity = push.activity;
|
|
52
|
+
if (activity instanceof SyncActivity) {
|
|
53
|
+
const output = await Internals.runActivity(activity, context, instance => instance.run(push.input));
|
|
54
|
+
return { type: 'sync', output };
|
|
55
|
+
}
|
|
56
|
+
if (activity instanceof AsyncActivity) {
|
|
57
|
+
const bootstrap = await Internals.runActivity(activity, context, instance => instance.bootstrap(push.input));
|
|
58
|
+
return resolveAsyncActivity(activity, bootstrap, context, push.input, mockAsyncActivity, resolutionState);
|
|
59
|
+
}
|
|
60
|
+
throw new Error('Unknown activity type');
|
|
61
|
+
}
|
|
62
|
+
async function resolveAsyncActivity(activity, bootstrap, context, input, mockAsyncActivity, resolutionState) {
|
|
63
|
+
if (bootstrap instanceof AsyncActivityResultFulfilled)
|
|
64
|
+
return { type: 'async', status: 'fulfilled', output: bootstrap.payload };
|
|
65
|
+
if (bootstrap instanceof AsyncActivityResultRejected)
|
|
66
|
+
return { type: 'async', status: 'rejected', output: bootstrap.payload };
|
|
67
|
+
if (!(bootstrap instanceof AsyncActivityResultPending))
|
|
68
|
+
throw new Error('Unknown async activity result');
|
|
69
|
+
const name = activity.constructor.name;
|
|
70
|
+
if (!mockAsyncActivity)
|
|
71
|
+
throw new Error(`Async activity "${name}" is pending and no resolveAsyncActivity was provided`);
|
|
72
|
+
const outcome = await mockAsyncActivity(activity, {
|
|
73
|
+
input,
|
|
74
|
+
pending: bootstrap,
|
|
75
|
+
index: resolutionState?.index ?? 0,
|
|
76
|
+
});
|
|
77
|
+
if (resolutionState)
|
|
78
|
+
resolutionState.index++;
|
|
79
|
+
return outcomeToHistoryItem(activity, outcome, bootstrap, context, name);
|
|
80
|
+
}
|
|
81
|
+
async function outcomeToHistoryItem(activity, outcome, pending, context, name) {
|
|
82
|
+
switch (outcome.status) {
|
|
83
|
+
case 'fulfilled':
|
|
84
|
+
return { type: 'async', status: 'fulfilled', output: outcome.output };
|
|
85
|
+
case 'rejected':
|
|
86
|
+
return { type: 'async', status: 'rejected', output: outcome.reason };
|
|
87
|
+
case 'timeout': {
|
|
88
|
+
const onTimeout = activity.onTimeout?.bind(activity);
|
|
89
|
+
if (!onTimeout)
|
|
90
|
+
throw new Error(`Async activity "${name}" timed out but defines no onTimeout handler`);
|
|
91
|
+
const result = await Internals.runActivity(activity, context, () => onTimeout(pending));
|
|
92
|
+
if (result instanceof AsyncActivityResultFulfilled)
|
|
93
|
+
return { type: 'async', status: 'fulfilled', output: result.payload };
|
|
94
|
+
if (result instanceof AsyncActivityResultRejected)
|
|
95
|
+
return { type: 'async', status: 'rejected', output: result.payload };
|
|
96
|
+
throw new Error(`Async activity "${name}" stayed pending after onTimeout`);
|
|
97
|
+
}
|
|
98
|
+
default:
|
|
99
|
+
throw new Error(`Unknown async activity outcome for "${name}"`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=run-workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-workflow.js","sourceRoot":"","sources":["../../src/testing/run-workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import type { Activity, ActivityConstructor } from '../models/Activity.js';
|
|
|
2
2
|
import { type ClaimProvider } from '../models/Claim.js';
|
|
3
3
|
import { Env } from '../models/Env.js';
|
|
4
4
|
import { type HistoryItem } from '../models/History.js';
|
|
5
|
+
import { type Log } from '../models/Logger.js';
|
|
5
6
|
import type { Workflow, WorkflowInput } from '../models/Workflow.js';
|
|
6
7
|
export declare namespace Internals {
|
|
7
8
|
interface WorkflowRunContext<TWorkflow extends Workflow<any, any>> {
|
|
@@ -9,6 +10,7 @@ export declare namespace Internals {
|
|
|
9
10
|
history: readonly HistoryItem[];
|
|
10
11
|
env: Env.Entries;
|
|
11
12
|
input: WorkflowInput<TWorkflow>;
|
|
13
|
+
logs: Log[];
|
|
12
14
|
}
|
|
13
15
|
function runWorkflow<T extends Workflow<any, any>>(workflow: T, context: WorkflowRunContext<T>): any;
|
|
14
16
|
interface ActivityRunContext {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Internals.d.ts","sourceRoot":"","sources":["../../src/tools/Internals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC1E,OAAO,EAAS,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAW,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAEpE,yBAAiB,SAAS,CAAC;IACzB,UAAiB,kBAAkB,CAAC,SAAS,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;QACtE,MAAM,EAAE,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,CAAA;QACrC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAA;QAC/B,GAAG,EAAE,GAAG,CAAC,OAAO,CAAA;QAChB,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"Internals.d.ts","sourceRoot":"","sources":["../../src/tools/Internals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC1E,OAAO,EAAS,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAW,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAU,KAAK,GAAG,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAEpE,yBAAiB,SAAS,CAAC;IACzB,UAAiB,kBAAkB,CAAC,SAAS,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;QACtE,MAAM,EAAE,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,CAAA;QACrC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAA;QAC/B,GAAG,EAAE,GAAG,CAAC,OAAO,CAAA;QAChB,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;QAC/B,IAAI,EAAE,GAAG,EAAE,CAAA;KACZ;IAED,SAAgB,WAAW,CAAC,CAAC,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EACtD,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,OAS/B;IAED,UAAiB,kBAAkB;QACjC,MAAM,EAAE,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,CAAA;QACrC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAA;KACjB;IAED,SAAgB,WAAW,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,EAC/C,6BAA6B,EAAE,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,EACzD,OAAO,EAAE,kBAAkB,EAC3B,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,KAUvB;CACF"}
|
package/dist/tools/Internals.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Claim } from '../models/Claim.js';
|
|
2
2
|
import { Env } from '../models/Env.js';
|
|
3
3
|
import { History } from '../models/History.js';
|
|
4
|
+
import { Logger } from '../models/Logger.js';
|
|
4
5
|
export var Internals;
|
|
5
6
|
(function (Internals) {
|
|
6
7
|
function runWorkflow(workflow, context) {
|
|
7
|
-
return Env.run(context.env, () => Claim.run(context.claims, () => History.run(context.history, () => workflow.fn(context.input))));
|
|
8
|
+
return Env.run(context.env, () => Claim.run(context.claims, () => History.run(context.history, () => Logger.run(context.logs, () => workflow.fn(context.input)))));
|
|
8
9
|
}
|
|
9
10
|
Internals.runWorkflow = runWorkflow;
|
|
10
11
|
function runActivity(activityOrActivityConstructor, context, fn) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Internals.js","sourceRoot":"","sources":["../../src/tools/Internals.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAsB,MAAM,oBAAoB,CAAA;AAC9D,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAE,OAAO,EAAoB,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"Internals.js","sourceRoot":"","sources":["../../src/tools/Internals.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAsB,MAAM,oBAAoB,CAAA;AAC9D,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAE,OAAO,EAAoB,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,MAAM,EAAY,MAAM,qBAAqB,CAAA;AAGtD,MAAM,KAAW,SAAS,CAyCzB;AAzCD,WAAiB,SAAS;IASxB,SAAgB,WAAW,CACzB,QAAW,EACX,OAA8B;QAE9B,OAAO,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,CAC/B,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,CAC7B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,CAChC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAC3D,CACF,CACF,CAAA;IACH,CAAC;IAXe,qBAAW,cAW1B,CAAA;IAOD,SAAgB,WAAW,CACzB,6BAAyD,EACzD,OAA2B,EAC3B,EAAsB;QAEtB,MAAM,QAAQ,GACZ,OAAO,6BAA6B,KAAK,UAAU;YACjD,CAAC,CAAC,IAAI,6BAA6B,EAAE;YACrC,CAAC,CAAC,6BAA6B,CAAA;QAEnC,OAAO,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,CAC/B,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAC9C,CAAA;IACH,CAAC;IAbe,qBAAW,cAa1B,CAAA;AACH,CAAC,EAzCgB,SAAS,KAAT,SAAS,QAyCzB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AsyncActivity } from '../models/AsyncActivity.js';
|
|
2
|
+
import type { ClaimProvider } from '../models/Claim.js';
|
|
3
|
+
import { Env } from '../models/Env.js';
|
|
4
|
+
import type { Log } from '../models/Logger.js';
|
|
5
|
+
import type { Workflow, WorkflowInput } from '../models/Workflow.js';
|
|
6
|
+
export type AsyncActivityResolver = (activity: AsyncActivity<any, any, any, any, any, any>, input: unknown) => unknown | Promise<unknown>;
|
|
7
|
+
export interface RunWorkflowToCompletionOptions {
|
|
8
|
+
claims?: readonly ClaimProvider<any>[];
|
|
9
|
+
env?: Env.Entries;
|
|
10
|
+
resolveAsyncActivity?: AsyncActivityResolver;
|
|
11
|
+
maxTicks?: number;
|
|
12
|
+
logs?: Log[];
|
|
13
|
+
}
|
|
14
|
+
export declare function runWorkflowToCompletion<T extends Workflow<any, any>>(workflow: T, input: WorkflowInput<T>, options?: RunWorkflowToCompletionOptions): Promise<any>;
|
|
15
|
+
//# sourceMappingURL=runWorkflowToCompletion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runWorkflowToCompletion.d.ts","sourceRoot":"","sources":["../../src/tools/runWorkflowToCompletion.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAM1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAEtC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AAG9C,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAGpE,MAAM,MAAM,qBAAqB,GAAG,CAClC,QAAQ,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EACrD,KAAK,EAAE,OAAO,KACX,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;AAE/B,MAAM,WAAW,8BAA8B;IAC7C,MAAM,CAAC,EAAE,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,CAAA;IACtC,GAAG,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACjB,oBAAoB,CAAC,EAAE,qBAAqB,CAAA;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;CACb;AAED,wBAAsB,uBAAuB,CAAC,CAAC,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EACxE,QAAQ,EAAE,CAAC,EACX,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EACvB,OAAO,GAAE,8BAAmC,gBAgC7C"}
|