@t4h.framework/core 0.9.1 → 0.11.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 +6 -4
- package/.ai/skills/framework-workflow-creation/SKILL.md +32 -7
- package/.ai/skills/framework-workflow-testing/SKILL.md +9 -1
- package/CHANGELOG.md +48 -0
- package/README.md +8 -0
- package/dist/core.d.ts +2 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +2 -0
- package/dist/core.js.map +1 -1
- package/dist/exceptions/TimerNotAllowedException.d.ts +5 -0
- package/dist/exceptions/TimerNotAllowedException.d.ts.map +1 -0
- package/dist/exceptions/TimerNotAllowedException.js +9 -0
- package/dist/exceptions/TimerNotAllowedException.js.map +1 -0
- package/dist/models/AsyncActivity.d.ts +5 -1
- package/dist/models/AsyncActivity.d.ts.map +1 -1
- package/dist/models/AsyncActivity.js.map +1 -1
- package/dist/models/AsyncActivityAdvanceResult.d.ts +4 -1
- package/dist/models/AsyncActivityAdvanceResult.d.ts.map +1 -1
- package/dist/models/AsyncActivityAdvanceResult.js +3 -1
- package/dist/models/AsyncActivityAdvanceResult.js.map +1 -1
- package/dist/models/AsyncActivityAwaitable.d.ts +1 -1
- package/dist/models/AsyncActivityAwaitable.d.ts.map +1 -1
- package/dist/models/AsyncActivityAwaitable.js +2 -0
- package/dist/models/AsyncActivityAwaitable.js.map +1 -1
- package/dist/models/AsyncActivityCallbackAuth.d.ts +36 -0
- package/dist/models/AsyncActivityCallbackAuth.d.ts.map +1 -0
- package/dist/models/AsyncActivityCallbackAuth.js +2 -0
- package/dist/models/AsyncActivityCallbackAuth.js.map +1 -0
- package/dist/models/Claim.d.ts +3 -0
- package/dist/models/Claim.d.ts.map +1 -1
- package/dist/models/Claim.js +2 -0
- package/dist/models/Claim.js.map +1 -1
- package/dist/models/History.d.ts +17 -2
- package/dist/models/History.d.ts.map +1 -1
- package/dist/models/History.js +26 -8
- package/dist/models/History.js.map +1 -1
- package/dist/models/Logger.d.ts.map +1 -1
- package/dist/models/Logger.js +2 -1
- package/dist/models/Logger.js.map +1 -1
- package/dist/testing/TestClock.d.ts.map +1 -1
- package/dist/testing/TestClock.js +6 -35
- package/dist/testing/TestClock.js.map +1 -1
- package/dist/testing/TestWorkflowEnvironment.d.ts.map +1 -1
- package/dist/testing/TestWorkflowEnvironment.js +6 -4
- package/dist/testing/TestWorkflowEnvironment.js.map +1 -1
- package/dist/testing/tools/resolve-activity.d.ts.map +1 -1
- package/dist/testing/tools/resolve-activity.js +4 -1
- package/dist/testing/tools/resolve-activity.js.map +1 -1
- package/dist/testing/tools/resolve-async-activity.d.ts +3 -2
- package/dist/testing/tools/resolve-async-activity.d.ts.map +1 -1
- package/dist/testing/tools/resolve-async-activity.js +17 -36
- package/dist/testing/tools/resolve-async-activity.js.map +1 -1
- package/dist/testing/tools/run-workflow-ticks.d.ts.map +1 -1
- package/dist/testing/tools/run-workflow-ticks.js +6 -0
- package/dist/testing/tools/run-workflow-ticks.js.map +1 -1
- package/dist/testing/tools/run-workflow.d.ts +4 -0
- package/dist/testing/tools/run-workflow.d.ts.map +1 -1
- package/dist/testing/tools/run-workflow.js +17 -7
- package/dist/testing/tools/run-workflow.js.map +1 -1
- package/dist/tools/Deterministic.d.ts +7 -0
- package/dist/tools/Deterministic.d.ts.map +1 -0
- package/dist/tools/Deterministic.js +107 -0
- package/dist/tools/Deterministic.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 +5 -1
- package/dist/tools/Internals.js.map +1 -1
- package/dist/tools/clock.d.ts +3 -0
- package/dist/tools/clock.d.ts.map +1 -0
- package/dist/tools/clock.js +11 -0
- package/dist/tools/clock.js.map +1 -0
- package/dist/tools/random.d.ts +3 -0
- package/dist/tools/random.d.ts.map +1 -0
- package/dist/tools/random.js +29 -0
- package/dist/tools/random.js.map +1 -0
- package/package.json +1 -1
package/dist/models/History.js
CHANGED
|
@@ -2,8 +2,8 @@ import { AsyncLocalStorage } from 'node:async_hooks';
|
|
|
2
2
|
import { uuidv7 } from 'uuidv7';
|
|
3
3
|
import {} from './Activity.js';
|
|
4
4
|
import { AsyncActivity } from './AsyncActivity.js';
|
|
5
|
-
import { AsyncActivityAwaitable } from './AsyncActivityAwaitable.js';
|
|
6
5
|
import { PushActivity } from './PushActivity.js';
|
|
6
|
+
import { Deterministic } from '../tools/Deterministic.js';
|
|
7
7
|
export var History;
|
|
8
8
|
(function (History) {
|
|
9
9
|
const storage = new AsyncLocalStorage();
|
|
@@ -12,17 +12,18 @@ export var History;
|
|
|
12
12
|
}
|
|
13
13
|
History.bind = bind;
|
|
14
14
|
async function reconciler(Activity, ...args) {
|
|
15
|
-
const
|
|
16
|
-
if (!
|
|
15
|
+
const store = storage.getStore();
|
|
16
|
+
if (!store)
|
|
17
17
|
throw new Error('No activities in storage');
|
|
18
|
-
const value =
|
|
18
|
+
const value = store.items.shift();
|
|
19
19
|
const activity = new Activity();
|
|
20
20
|
if (!value) {
|
|
21
21
|
activity.id = uuidv7();
|
|
22
|
-
const input = await activity.toInput(...args);
|
|
22
|
+
const input = await storage.exit(() => activity.toInput(...args));
|
|
23
23
|
throw new PushActivity(activity, input);
|
|
24
24
|
}
|
|
25
25
|
activity.id = value.id;
|
|
26
|
+
advanceClock(value.createdAt);
|
|
26
27
|
if (activity instanceof AsyncActivity) {
|
|
27
28
|
if (value.type !== 'async')
|
|
28
29
|
throw new Error('Invalid history item type');
|
|
@@ -36,11 +37,28 @@ export var History;
|
|
|
36
37
|
const store = storage.getStore();
|
|
37
38
|
if (!store)
|
|
38
39
|
return false;
|
|
39
|
-
return store.length > 0;
|
|
40
|
+
return store.items.length > 0;
|
|
40
41
|
}
|
|
41
42
|
History.isReplaying = isReplaying;
|
|
42
|
-
function
|
|
43
|
-
return storage.
|
|
43
|
+
function peek() {
|
|
44
|
+
return storage.getStore();
|
|
45
|
+
}
|
|
46
|
+
History.peek = peek;
|
|
47
|
+
function advanceClock(at) {
|
|
48
|
+
const store = storage.getStore();
|
|
49
|
+
if (!store || at === undefined)
|
|
50
|
+
return;
|
|
51
|
+
store.clock = Math.max(store.clock, at);
|
|
52
|
+
}
|
|
53
|
+
History.advanceClock = advanceClock;
|
|
54
|
+
function run(options, fn) {
|
|
55
|
+
Deterministic.install();
|
|
56
|
+
return storage.run({
|
|
57
|
+
items: options.history.slice(),
|
|
58
|
+
seed: options.seed,
|
|
59
|
+
clock: options.createdAt,
|
|
60
|
+
randomCalls: 0,
|
|
61
|
+
}, fn);
|
|
44
62
|
}
|
|
45
63
|
History.run = run;
|
|
46
64
|
})(History || (History = {}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"History.js","sourceRoot":"","sources":["../../src/models/History.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEpD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAiB,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAyB,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"History.js","sourceRoot":"","sources":["../../src/models/History.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Logger.d.ts","sourceRoot":"","sources":["../../src/models/Logger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Logger.d.ts","sourceRoot":"","sources":["../../src/models/Logger.ts"],"names":[],"mappings":"AAKA,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;AAMD,yBAAiB,MAAM,CAAC;IAetB,SAAgB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,KAI9C;CAuBF"}
|
package/dist/models/Logger.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
2
|
import { History } from './History.js';
|
|
3
|
+
import { Deterministic } from '../tools/Deterministic.js';
|
|
3
4
|
export var Logger;
|
|
4
5
|
(function (Logger) {
|
|
5
6
|
const storage = new AsyncLocalStorage();
|
|
@@ -31,7 +32,7 @@ export var Logger;
|
|
|
31
32
|
return original[level](...args);
|
|
32
33
|
if (History.isReplaying())
|
|
33
34
|
return;
|
|
34
|
-
context.logs.push({ level, args, at:
|
|
35
|
+
context.logs.push({ level, args, at: Deterministic.hostNow() });
|
|
35
36
|
original[level](...args);
|
|
36
37
|
}
|
|
37
38
|
})(Logger || (Logger = {}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Logger.js","sourceRoot":"","sources":["../../src/models/Logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEpD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"Logger.js","sourceRoot":"","sources":["../../src/models/Logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEpD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAczD,MAAM,KAAW,MAAM,CA0CtB;AA1CD,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;IAEzB,SAAgB,GAAG,CAAI,IAAW,EAAE,EAAW;QAC7C,gBAAgB,EAAE,CAAA;QAElB,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;IAClC,CAAC;IAJe,UAAG,MAIlB,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,IAAI,OAAO,CAAC,WAAW,EAAE;YAAE,OAAM;QAEjC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;QAE/D,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAC1B,CAAC;AACH,CAAC,EA1CgB,MAAM,KAAN,MAAM,QA0CtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestClock.d.ts","sourceRoot":"","sources":["../../src/testing/TestClock.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TestClock.d.ts","sourceRoot":"","sources":["../../src/testing/TestClock.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;CACpB;AAID,qBAAa,SAAS;WACN,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;WAYpD,QAAQ,IAAI,OAAO;WAInB,GAAG,IAAI,MAAM;WAIb,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;WAWzB,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI;WAW7B,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;CAGtC"}
|
|
@@ -1,49 +1,20 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { Deterministic } from '../tools/Deterministic.js';
|
|
2
3
|
const storage = new AsyncLocalStorage();
|
|
3
|
-
const OriginalDate = globalThis.Date;
|
|
4
|
-
function createPatchedDateConstructor() {
|
|
5
|
-
return class extends OriginalDate {
|
|
6
|
-
constructor(...args) {
|
|
7
|
-
if (args.length === 0) {
|
|
8
|
-
super(TestClock.now());
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
super(...args);
|
|
12
|
-
}
|
|
13
|
-
static now() {
|
|
14
|
-
return TestClock.now();
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
4
|
export class TestClock {
|
|
19
5
|
static run(options, fn) {
|
|
6
|
+
Deterministic.install();
|
|
7
|
+
Deterministic.useHostClock(() => storage.getStore()?.now);
|
|
20
8
|
const now = options.now instanceof Date
|
|
21
9
|
? options.now.getTime()
|
|
22
|
-
: (options.now ??
|
|
23
|
-
return storage.run({ now },
|
|
24
|
-
const PatchedDate = createPatchedDateConstructor();
|
|
25
|
-
globalThis.Date = PatchedDate;
|
|
26
|
-
const finish = () => {
|
|
27
|
-
globalThis.Date = OriginalDate;
|
|
28
|
-
};
|
|
29
|
-
try {
|
|
30
|
-
const result = fn();
|
|
31
|
-
if (result instanceof Promise)
|
|
32
|
-
return result.finally(finish);
|
|
33
|
-
finish();
|
|
34
|
-
return result;
|
|
35
|
-
}
|
|
36
|
-
catch (error) {
|
|
37
|
-
finish();
|
|
38
|
-
throw error;
|
|
39
|
-
}
|
|
40
|
-
});
|
|
10
|
+
: (options.now ?? Deterministic.realNow());
|
|
11
|
+
return storage.run({ now }, fn);
|
|
41
12
|
}
|
|
42
13
|
static isActive() {
|
|
43
14
|
return storage.getStore() !== undefined;
|
|
44
15
|
}
|
|
45
16
|
static now() {
|
|
46
|
-
return storage.getStore()?.now ??
|
|
17
|
+
return storage.getStore()?.now ?? Deterministic.realNow();
|
|
47
18
|
}
|
|
48
19
|
static advance(ms) {
|
|
49
20
|
const state = storage.getStore();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestClock.js","sourceRoot":"","sources":["../../src/testing/TestClock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"TestClock.js","sourceRoot":"","sources":["../../src/testing/TestClock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAUzD,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAkB,CAAA;AAEvD,MAAM,OAAO,SAAS;IACb,MAAM,CAAC,GAAG,CAAI,OAA4B,EAAE,EAAW;QAC5D,aAAa,CAAC,OAAO,EAAE,CAAA;QACvB,aAAa,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAA;QAEzD,MAAM,GAAG,GACP,OAAO,CAAC,GAAG,YAAY,IAAI;YACzB,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE;YACvB,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC,CAAA;QAE9C,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAA;IACjC,CAAC;IAEM,MAAM,CAAC,QAAQ;QACpB,OAAO,OAAO,CAAC,QAAQ,EAAE,KAAK,SAAS,CAAA;IACzC,CAAC;IAEM,MAAM,CAAC,GAAG;QACf,OAAO,OAAO,CAAC,QAAQ,EAAE,EAAE,GAAG,IAAI,aAAa,CAAC,OAAO,EAAE,CAAA;IAC3D,CAAC;IAEM,MAAM,CAAC,OAAO,CAAC,EAAU;QAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAA;QAEhC,IAAI,CAAC,KAAK;YACR,MAAM,IAAI,KAAK,CACb,kGAAkG,CACnG,CAAA;QAEH,KAAK,CAAC,GAAG,IAAI,EAAE,CAAA;IACjB,CAAC;IAEM,MAAM,CAAC,GAAG,CAAC,GAAkB;QAClC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAA;QAEhC,IAAI,CAAC,KAAK;YACR,MAAM,IAAI,KAAK,CACb,8FAA8F,CAC/F,CAAA;QAEH,KAAK,CAAC,GAAG,GAAG,GAAG,YAAY,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAA;IACvD,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,EAAU;QAC5B,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IACvB,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestWorkflowEnvironment.d.ts","sourceRoot":"","sources":["../../src/testing/TestWorkflowEnvironment.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TestWorkflowEnvironment.d.ts","sourceRoot":"","sources":["../../src/testing/TestWorkflowEnvironment.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAEpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAEvE,MAAM,WAAW,8BAA8B;IAC7C,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;IACnB,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAClC;AAED,MAAM,WAAW,qCAAqC;IACpD,MAAM,CAAC,EAAE,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,CAAA;IACtC,GAAG,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACjB,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;CACtC;AAED,qBAAa,uBAAuB;IAClC,OAAO,CAAC,uBAAuB,CAAgB;IAE/C,OAAO,CAAC,GAAG,CAAY;IAEvB,OAAO;WASO,MAAM,CAClB,OAAO,GAAE,8BAAmC,GAC3C,uBAAuB;IAI1B,SAAgB,KAAK;;sBAGL,MAAM;mBAMT,IAAI,GAAG,MAAM;MAKzB;IAEY,OAAO,CAAC,CAAC,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EAC/C,QAAQ,EAAE,CAAC,EACX,KAAK,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,EACxB,OAAO,GAAE,qCAA0C;YAgCvC,qBAAqB;CA0BpC"}
|
|
@@ -2,7 +2,7 @@ import { isDeepStrictEqual } from 'node:util';
|
|
|
2
2
|
import { NonDeterministicWorkflowError } from './exceptions/NonDeterministicWorkflowError.js';
|
|
3
3
|
import { TestClock } from './TestClock.js';
|
|
4
4
|
import { clone } from './tools/clone.js';
|
|
5
|
-
import { runWorkflow } from './tools/run-workflow.js';
|
|
5
|
+
import { runWorkflow, } from './tools/run-workflow.js';
|
|
6
6
|
import { Internals } from '../tools/Internals.js';
|
|
7
7
|
export class TestWorkflowEnvironment {
|
|
8
8
|
resolveActivityTimeouts = true;
|
|
@@ -44,19 +44,21 @@ export class TestWorkflowEnvironment {
|
|
|
44
44
|
const result = await runWorkflow(workflow, input, runWorkflowOptions);
|
|
45
45
|
if (result.clockNow !== undefined)
|
|
46
46
|
this.now = result.clockNow;
|
|
47
|
-
await this.assertWorkflowReplays(workflow, input, result
|
|
47
|
+
await this.assertWorkflowReplays(workflow, input, result, runWorkflowOptions);
|
|
48
48
|
return result.output;
|
|
49
49
|
}
|
|
50
|
-
async assertWorkflowReplays(workflow, input,
|
|
50
|
+
async assertWorkflowReplays(workflow, input, result, context) {
|
|
51
51
|
const history = await clone(context.history);
|
|
52
52
|
const replay = await TestClock.run({ now: this.now }, () => Internals.runWorkflow(workflow, {
|
|
53
|
+
id: result.seed,
|
|
54
|
+
createdAt: result.createdAt,
|
|
53
55
|
input,
|
|
54
56
|
claims: context.claims,
|
|
55
57
|
env: context.env,
|
|
56
58
|
history,
|
|
57
59
|
logs: [],
|
|
58
60
|
}));
|
|
59
|
-
if (isDeepStrictEqual(output, replay))
|
|
61
|
+
if (isDeepStrictEqual(result.output, replay))
|
|
60
62
|
return;
|
|
61
63
|
throw new NonDeterministicWorkflowError('Replay from recorded history produced a different workflow output.');
|
|
62
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestWorkflowEnvironment.js","sourceRoot":"","sources":["../../src/testing/TestWorkflowEnvironment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAE7C,OAAO,EAAE,6BAA6B,EAAE,MAAM,+CAA+C,CAAA;AAC7F,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACxC,OAAO,
|
|
1
|
+
{"version":3,"file":"TestWorkflowEnvironment.js","sourceRoot":"","sources":["../../src/testing/TestWorkflowEnvironment.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-activity.d.ts","sourceRoot":"","sources":["../../../src/testing/tools/resolve-activity.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,SAAS,EACT,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,YAAY,EAElB,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"resolve-activity.d.ts","sourceRoot":"","sources":["../../../src/testing/tools/resolve-activity.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,SAAS,EACT,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,YAAY,EAElB,MAAM,eAAe,CAAA;AAEtB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AAExE,UAAU,sBAAsB;IAC9B,IAAI,CAAC,EAAE,iBAAiB,CAAA;IACxB,KAAK,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;CAC9B;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC,EAC5B,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,IAAI,CAAC,EACjD,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,WAAW,CAAC,CAwCtB"}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { resolveAsyncActivity } from './resolve-async-activity.js';
|
|
2
2
|
import { SyncActivity, Internals, AsyncActivity, } from '../../core.js';
|
|
3
|
+
import { TestClock } from '../TestClock.js';
|
|
3
4
|
export async function resolveActivity(push, context, options) {
|
|
4
5
|
const activity = push.activity;
|
|
6
|
+
const createdAt = TestClock.now();
|
|
5
7
|
const activityContext = {
|
|
6
8
|
...context,
|
|
7
9
|
id: activity.id,
|
|
8
10
|
};
|
|
9
11
|
if (activity instanceof SyncActivity) {
|
|
10
12
|
const output = await Internals.runActivity(activity, activityContext, instance => instance.run(push.input));
|
|
11
|
-
return { id: activity.id, type: 'sync', output };
|
|
13
|
+
return { id: activity.id, type: 'sync', output, createdAt };
|
|
12
14
|
}
|
|
13
15
|
if (activity instanceof AsyncActivity) {
|
|
14
16
|
const bootstrap = await Internals.runActivity(activity, activityContext, instance => instance.bootstrap(push.input));
|
|
@@ -16,6 +18,7 @@ export async function resolveActivity(push, context, options) {
|
|
|
16
18
|
...activityContext,
|
|
17
19
|
activity,
|
|
18
20
|
bootstrap,
|
|
21
|
+
createdAt,
|
|
19
22
|
}, push.input, options);
|
|
20
23
|
}
|
|
21
24
|
throw new Error('Unknown activity type');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-activity.js","sourceRoot":"","sources":["../../../src/testing/tools/resolve-activity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EACL,YAAY,EACZ,SAAS,EAIT,aAAa,GACd,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"resolve-activity.js","sourceRoot":"","sources":["../../../src/testing/tools/resolve-activity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EACL,YAAY,EACZ,SAAS,EAIT,aAAa,GACd,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAQ3C,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAA4B,EAC5B,OAAiD,EACjD,OAAgC;IAEhC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IAE9B,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,EAAE,CAAA;IAEjC,MAAM,eAAe,GAAiC;QACpD,GAAG,OAAO;QACV,EAAE,EAAE,QAAQ,CAAC,EAAE;KAChB,CAAA;IAED,IAAI,QAAQ,YAAY,YAAY,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,CACxC,QAAQ,EACR,eAAe,EACf,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CACrC,CAAA;QAED,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;IAC7D,CAAC;IAED,IAAI,QAAQ,YAAY,aAAa,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,WAAW,CAC3C,QAAQ,EACR,eAAe,EACf,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAC3C,CAAA;QAED,OAAO,oBAAoB,CACzB;YACE,GAAG,eAAe;YAClB,QAAQ;YACR,SAAS;YACT,SAAS;SACV,EACD,IAAI,CAAC,KAAK,EACV,OAAO,CACR,CAAA;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;AAC1C,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Internals, type AnyAsyncActivity, type
|
|
1
|
+
import { Internals, type AnyAsyncActivity, type IHistoryItemAsync } from '../../core.js';
|
|
2
2
|
import type { MockAsyncActivity } from '../typings/MockAsyncActivity.js';
|
|
3
3
|
interface ResolveAsyncActivityOptions {
|
|
4
4
|
mock?: MockAsyncActivity;
|
|
@@ -9,7 +9,8 @@ interface ResolveAsyncActivityOptions {
|
|
|
9
9
|
interface ResolveAsyncActivityContext extends Internals.ActivityRunContext {
|
|
10
10
|
activity: AnyAsyncActivity;
|
|
11
11
|
bootstrap: unknown;
|
|
12
|
+
createdAt: number;
|
|
12
13
|
}
|
|
13
|
-
export declare function resolveAsyncActivity(context: ResolveAsyncActivityContext, input: unknown, options?: ResolveAsyncActivityOptions): Promise<
|
|
14
|
+
export declare function resolveAsyncActivity(context: ResolveAsyncActivityContext, input: unknown, options?: ResolveAsyncActivityOptions): Promise<IHistoryItemAsync>;
|
|
14
15
|
export {};
|
|
15
16
|
//# sourceMappingURL=resolve-async-activity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-async-activity.d.ts","sourceRoot":"","sources":["../../../src/testing/tools/resolve-async-activity.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,SAAS,EACT,KAAK,gBAAgB,EACrB,KAAK,
|
|
1
|
+
{"version":3,"file":"resolve-async-activity.d.ts","sourceRoot":"","sources":["../../../src/testing/tools/resolve-async-activity.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,SAAS,EACT,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACvB,MAAM,eAAe,CAAA;AAGtB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AAExE,UAAU,2BAA2B;IACnC,IAAI,CAAC,EAAE,iBAAiB,CAAA;IACxB,KAAK,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;CAC9B;AAED,UAAU,2BAA4B,SAAQ,SAAS,CAAC,kBAAkB;IACxE,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;CAClB;AAwDD,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,2BAA2B,EACpC,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,2BAA2B,GACpC,OAAO,CAAC,iBAAiB,CAAC,CA0B5B"}
|
|
@@ -1,57 +1,38 @@
|
|
|
1
1
|
import { AsyncActivityResultFulfilled, AsyncActivityResultPending, AsyncActivityResultRejected, Internals, } from '../../core.js';
|
|
2
|
+
import { TestClock } from '../TestClock.js';
|
|
3
|
+
function settled(context, status, output) {
|
|
4
|
+
return {
|
|
5
|
+
id: context.activity.id,
|
|
6
|
+
type: 'async',
|
|
7
|
+
status,
|
|
8
|
+
output,
|
|
9
|
+
createdAt: context.createdAt,
|
|
10
|
+
settledAt: TestClock.now(),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
2
13
|
async function toHistoryItem(context, outcome, pending) {
|
|
3
14
|
if (outcome.status === 'fulfilled')
|
|
4
|
-
return
|
|
5
|
-
id: context.activity.id,
|
|
6
|
-
type: 'async',
|
|
7
|
-
status: 'fulfilled',
|
|
8
|
-
output: outcome.output,
|
|
9
|
-
};
|
|
15
|
+
return settled(context, 'fulfilled', outcome.output);
|
|
10
16
|
if (outcome.status === 'rejected')
|
|
11
|
-
return
|
|
12
|
-
id: context.activity.id,
|
|
13
|
-
type: 'async',
|
|
14
|
-
status: 'rejected',
|
|
15
|
-
output: outcome.reason,
|
|
16
|
-
};
|
|
17
|
+
return settled(context, 'rejected', outcome.reason);
|
|
17
18
|
if (outcome.status === 'timeout') {
|
|
18
19
|
const onTimeout = context.activity.onTimeout?.bind(context.activity);
|
|
19
20
|
if (!onTimeout)
|
|
20
21
|
throw new Error(`Async activity "${context.activity.constructor.name}" timed out but defines no onTimeout handler`);
|
|
21
22
|
const result = await Internals.runActivity(context.activity, context, () => onTimeout(pending));
|
|
22
23
|
if (result instanceof AsyncActivityResultFulfilled)
|
|
23
|
-
return
|
|
24
|
-
id: context.activity.id,
|
|
25
|
-
type: 'async',
|
|
26
|
-
status: 'fulfilled',
|
|
27
|
-
output: result.payload,
|
|
28
|
-
};
|
|
24
|
+
return settled(context, 'fulfilled', result.payload);
|
|
29
25
|
if (result instanceof AsyncActivityResultRejected)
|
|
30
|
-
return
|
|
31
|
-
id: context.activity.id,
|
|
32
|
-
type: 'async',
|
|
33
|
-
status: 'rejected',
|
|
34
|
-
output: result.payload,
|
|
35
|
-
};
|
|
26
|
+
return settled(context, 'rejected', result.payload);
|
|
36
27
|
throw new Error(`Async activity "${context.activity.constructor.name}" stayed pending after onTimeout`);
|
|
37
28
|
}
|
|
38
29
|
throw new Error(`Unknown async activity outcome for "${context.activity.constructor.name}"`);
|
|
39
30
|
}
|
|
40
31
|
export async function resolveAsyncActivity(context, input, options) {
|
|
41
32
|
if (context.bootstrap instanceof AsyncActivityResultFulfilled)
|
|
42
|
-
return
|
|
43
|
-
id: context.activity.id,
|
|
44
|
-
type: 'async',
|
|
45
|
-
status: 'fulfilled',
|
|
46
|
-
output: context.bootstrap.payload,
|
|
47
|
-
};
|
|
33
|
+
return settled(context, 'fulfilled', context.bootstrap.payload);
|
|
48
34
|
if (context.bootstrap instanceof AsyncActivityResultRejected)
|
|
49
|
-
return
|
|
50
|
-
id: context.activity.id,
|
|
51
|
-
type: 'async',
|
|
52
|
-
status: 'rejected',
|
|
53
|
-
output: context.bootstrap.payload,
|
|
54
|
-
};
|
|
35
|
+
return settled(context, 'rejected', context.bootstrap.payload);
|
|
55
36
|
if (!(context.bootstrap instanceof AsyncActivityResultPending))
|
|
56
37
|
throw new Error('Unknown async activity result');
|
|
57
38
|
const name = context.activity.constructor.name;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-async-activity.js","sourceRoot":"","sources":["../../../src/testing/tools/resolve-async-activity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,2BAA2B,EAC3B,SAAS,GAGV,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"resolve-async-activity.js","sourceRoot":"","sources":["../../../src/testing/tools/resolve-async-activity.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-workflow-ticks.d.ts","sourceRoot":"","sources":["../../../src/testing/tools/run-workflow-ticks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-workflow-ticks.d.ts","sourceRoot":"","sources":["../../../src/testing/tools/run-workflow-ticks.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAGL,QAAQ,EACR,KAAK,WAAW,EAChB,KAAK,GAAG,EACR,KAAK,aAAa,EACnB,MAAM,eAAe,CAAA;AAGtB,MAAM,WAAW,uBAAwB,SAAQ,kBAAkB;IACjE,OAAO,EAAE,WAAW,EAAE,CAAA;IACtB,IAAI,EAAE,GAAG,EAAE,CAAA;CACZ;AAED,wBAAsB,gBAAgB,CAAC,CAAC,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EACjE,QAAQ,EAAE,CAAC,EACX,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EACvB,OAAO,EAAE,uBAAuB,gBAmCjC"}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { resolveActivity } from './resolve-activity.js';
|
|
2
3
|
import { Internals, PushActivity, Workflow, } from '../../core.js';
|
|
4
|
+
import { TestClock } from '../TestClock.js';
|
|
3
5
|
export async function runWorkflowTicks(workflow, input, options) {
|
|
4
6
|
const maxTicks = options.maxTicks ?? 10_000;
|
|
5
7
|
const state = { callCount: 0 };
|
|
6
8
|
const { history, logs, claims = [], env = {} } = options;
|
|
9
|
+
const seed = options.seed ?? randomUUID();
|
|
10
|
+
const createdAt = options.createdAt ?? TestClock.now();
|
|
7
11
|
for (let tick = 0; tick < maxTicks; tick++) {
|
|
8
12
|
try {
|
|
9
13
|
return await Internals.runWorkflow(workflow, {
|
|
14
|
+
id: seed,
|
|
15
|
+
createdAt,
|
|
10
16
|
input,
|
|
11
17
|
claims,
|
|
12
18
|
env,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-workflow-ticks.js","sourceRoot":"","sources":["../../../src/testing/tools/run-workflow-ticks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EACL,SAAS,EACT,YAAY,EACZ,QAAQ,GAIT,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"run-workflow-ticks.js","sourceRoot":"","sources":["../../../src/testing/tools/run-workflow-ticks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EACL,SAAS,EACT,YAAY,EACZ,QAAQ,GAIT,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAO3C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAW,EACX,KAAuB,EACvB,OAAgC;IAEhC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAA;IAC3C,MAAM,KAAK,GAAG,EAAE,SAAS,EAAE,CAAC,EAAE,CAAA;IAE9B,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,OAAO,CAAA;IAExD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,UAAU,EAAE,CAAA;IACzC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,SAAS,CAAC,GAAG,EAAE,CAAA;IAEtD,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC;QAC3C,IAAI,CAAC;YACH,OAAO,MAAM,SAAS,CAAC,WAAW,CAAC,QAAQ,EAAE;gBAC3C,EAAE,EAAE,IAAI;gBACR,SAAS;gBACT,KAAK;gBACL,MAAM;gBACN,GAAG;gBACH,OAAO;gBACP,IAAI;aACL,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,CAAC,WAAW,YAAY,YAAY,CAAC;gBAAE,MAAM,WAAW,CAAA;YAE7D,MAAM,IAAI,GAAG,MAAM,eAAe,CAChC,WAAW,EACX,EAAE,MAAM,EAAE,GAAG,EAAE,EACf,EAAE,IAAI,EAAE,OAAO,CAAC,iBAAiB,EAAE,KAAK,EAAE,CAC3C,CAAA;YAED,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACpB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,kCAAkC,QAAQ,QAAQ,CAAC,CAAA;AACrE,CAAC"}
|
|
@@ -14,12 +14,16 @@ export interface RunWorkflowOptions {
|
|
|
14
14
|
maxTicks?: number;
|
|
15
15
|
clock?: TestClockRunOptions | false;
|
|
16
16
|
resolveActivityTimeouts?: boolean;
|
|
17
|
+
seed?: string;
|
|
18
|
+
createdAt?: number;
|
|
17
19
|
}
|
|
18
20
|
export interface RunWorkflowResult<TOutput = unknown> {
|
|
19
21
|
output: TOutput;
|
|
20
22
|
history: readonly HistoryItem[];
|
|
21
23
|
logs: readonly Log[];
|
|
22
24
|
clockNow?: number;
|
|
25
|
+
seed: string;
|
|
26
|
+
createdAt: number;
|
|
23
27
|
}
|
|
24
28
|
export declare function runWorkflow<T extends Workflow<any, any>>(workflow: T, input: WorkflowInput<T>, options: RunWorkflowOptions): Promise<RunWorkflowResult>;
|
|
25
29
|
//# sourceMappingURL=run-workflow.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-workflow.d.ts","sourceRoot":"","sources":["../../../src/testing/tools/run-workflow.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-workflow.d.ts","sourceRoot":"","sources":["../../../src/testing/tools/run-workflow.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAC1D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACvE,OAAO,EAAa,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAErE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AAExE,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,CAAA;IACrC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAA;IAChB,IAAI,EAAE,GAAG,EAAE,CAAA;IACX,OAAO,EAAE,WAAW,EAAE,CAAA;IACtB,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,mBAAmB,GAAG,KAAK,CAAA;IACnC,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB,CAAC,OAAO,GAAG,OAAO;IAClD,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,SAAS,WAAW,EAAE,CAAA;IAC/B,IAAI,EAAE,SAAS,GAAG,EAAE,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;CAClB;AAYD,wBAAsB,WAAW,CAAC,CAAC,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EAC5D,QAAQ,EAAE,CAAC,EACX,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EACvB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CA6B5B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { mockAsync } from './mock-async.js';
|
|
2
3
|
import { runWithClock } from './run-with-clock.js';
|
|
3
4
|
import { TestClock } from '../TestClock.js';
|
|
@@ -10,16 +11,25 @@ function resolveMockAsyncActivity(options) {
|
|
|
10
11
|
return undefined;
|
|
11
12
|
}
|
|
12
13
|
export async function runWorkflow(workflow, input, options) {
|
|
13
|
-
|
|
14
|
-
const output = await runWithClock(options.clock, async () => {
|
|
15
|
-
const
|
|
14
|
+
const seed = options.seed ?? randomUUID();
|
|
15
|
+
const { output, createdAt, clockNow } = await runWithClock(options.clock, async () => {
|
|
16
|
+
const createdAt = options.createdAt ?? TestClock.now();
|
|
17
|
+
const output = await runWorkflowTicks(workflow, input, {
|
|
16
18
|
...options,
|
|
19
|
+
seed,
|
|
20
|
+
createdAt,
|
|
17
21
|
mockAsyncActivity: resolveMockAsyncActivity(options),
|
|
18
22
|
});
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return result;
|
|
23
|
+
const clockNow = TestClock.isActive() ? TestClock.now() : undefined;
|
|
24
|
+
return { output, createdAt, clockNow };
|
|
22
25
|
});
|
|
23
|
-
return {
|
|
26
|
+
return {
|
|
27
|
+
output,
|
|
28
|
+
history: options.history,
|
|
29
|
+
logs: options.logs,
|
|
30
|
+
clockNow,
|
|
31
|
+
seed,
|
|
32
|
+
createdAt,
|
|
33
|
+
};
|
|
24
34
|
}
|
|
25
35
|
//# sourceMappingURL=run-workflow.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-workflow.js","sourceRoot":"","sources":["../../../src/testing/tools/run-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAMlD,OAAO,EAAE,SAAS,EAA4B,MAAM,iBAAiB,CAAA;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"run-workflow.js","sourceRoot":"","sources":["../../../src/testing/tools/run-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAMlD,OAAO,EAAE,SAAS,EAA4B,MAAM,iBAAiB,CAAA;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAyB1D,SAAS,wBAAwB,CAC/B,OAA2B;IAE3B,IAAI,OAAO,CAAC,iBAAiB,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,iBAAiB,CAAA;IAE7E,IAAI,OAAO,CAAC,uBAAuB;QAAE,OAAO,SAAS,EAAE,CAAC,OAAO,EAAE,CAAA;IAEjE,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,QAAW,EACX,KAAuB,EACvB,OAA2B;IAE3B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,UAAU,EAAE,CAAA;IAEzC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,YAAY,CACxD,OAAO,CAAC,KAAK,EACb,KAAK,IAAI,EAAE;QACT,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,SAAS,CAAC,GAAG,EAAE,CAAA;QAEtD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE;YACrD,GAAG,OAAO;YACV,IAAI;YACJ,SAAS;YACT,iBAAiB,EAAE,wBAAwB,CAAC,OAAO,CAAC;SACrD,CAAC,CAAA;QAEF,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;QAEnE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAA;IACxC,CAAC,CACF,CAAA;IAED,OAAO;QACL,MAAM;QACN,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,QAAQ;QACR,IAAI;QACJ,SAAS;KACV,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Deterministic.d.ts","sourceRoot":"","sources":["../../src/tools/Deterministic.ts"],"names":[],"mappings":"AAOA,yBAAiB,aAAa,CAAC;IAU7B,SAAgB,OAAO,IAAI,MAAM,CAEhC;IAED,SAAgB,OAAO,IAAI,MAAM,CAEhC;IAED,SAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,MAAM,GAAG,SAAS,QAE1D;IAUD,SAAgB,OAAO,SAUtB;CAgGF"}
|