@entity-access/entity-access 1.0.136 → 1.0.138
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/eternity/EternityContext.d.ts +6 -0
- package/dist/eternity/EternityContext.d.ts.map +1 -1
- package/dist/eternity/EternityContext.js +84 -33
- package/dist/eternity/EternityContext.js.map +1 -1
- package/dist/eternity/EternityStorage.d.ts +2 -0
- package/dist/eternity/EternityStorage.d.ts.map +1 -1
- package/dist/eternity/EternityStorage.js +5 -3
- package/dist/eternity/EternityStorage.js.map +1 -1
- package/dist/eternity/Workflow.d.ts +4 -1
- package/dist/eternity/Workflow.d.ts.map +1 -1
- package/dist/eternity/Workflow.js +1 -1
- package/dist/eternity/Workflow.js.map +1 -1
- package/dist/tests/eternity/external-event-tests.d.ts +3 -0
- package/dist/tests/eternity/external-event-tests.d.ts.map +1 -0
- package/dist/tests/eternity/external-event-tests.js +116 -0
- package/dist/tests/eternity/external-event-tests.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/eternity/EternityContext.ts +97 -38
- package/src/eternity/EternityStorage.ts +5 -3
- package/src/eternity/Workflow.ts +5 -2
- package/src/tests/eternity/external-event-tests.ts +132 -0
|
@@ -114,7 +114,8 @@ export default class EternityStorage {
|
|
|
114
114
|
queued: r.queued,
|
|
115
115
|
state: r.state,
|
|
116
116
|
output: r.output,
|
|
117
|
-
error: r.error
|
|
117
|
+
error: r.error,
|
|
118
|
+
lastID: r.lastID
|
|
118
119
|
};
|
|
119
120
|
}
|
|
120
121
|
return null;
|
|
@@ -135,7 +136,8 @@ export default class EternityStorage {
|
|
|
135
136
|
queued: r.queued,
|
|
136
137
|
state: r.state,
|
|
137
138
|
output: r.output,
|
|
138
|
-
error: r.error
|
|
139
|
+
error: r.error,
|
|
140
|
+
lastID: r.lastID
|
|
139
141
|
};
|
|
140
142
|
}
|
|
141
143
|
return null;
|
|
@@ -187,7 +189,7 @@ export default class EternityStorage {
|
|
|
187
189
|
}
|
|
188
190
|
|
|
189
191
|
w.state ||= "queued";
|
|
190
|
-
w.updated
|
|
192
|
+
w.updated ??= DateTime.utcNow;
|
|
191
193
|
await db.saveChanges();
|
|
192
194
|
});
|
|
193
195
|
}
|
package/src/eternity/Workflow.ts
CHANGED
|
@@ -65,9 +65,12 @@ export default abstract class Workflow<TIn = any, TOut = any> {
|
|
|
65
65
|
return Promise.resolve("");
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
protected waitForExternalEvent(ts: TimeSpan, ... names:
|
|
68
|
+
protected waitForExternalEvent<T = any, TA extends string[] = string[]>(ts: TimeSpan, ... names: TA) {
|
|
69
69
|
// do nothing...
|
|
70
|
-
return Promise.resolve
|
|
70
|
+
return Promise.resolve<{
|
|
71
|
+
name: TA[number] | null | undefined,
|
|
72
|
+
result: T
|
|
73
|
+
}>({} as any);
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
protected async runChild<TChildIn, TChildOut>(type: IClassOf<Workflow<TChildIn, TChildOut>>, input: TChildIn): Promise<TChildOut> {
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import assert from "assert";
|
|
2
|
+
import Inject, { Register, RegisterScoped, RegisterSingleton, ServiceProvider } from "../../di/di.js";
|
|
3
|
+
import EternityContext from "../../eternity/EternityContext.js";
|
|
4
|
+
import Workflow, { Activity } from "../../eternity/Workflow.js";
|
|
5
|
+
import WorkflowClock from "../../eternity/WorkflowClock.js";
|
|
6
|
+
import DateTime from "../../types/DateTime.js";
|
|
7
|
+
import { TestConfig } from "../TestConfig.js";
|
|
8
|
+
import { BaseDriver } from "../../drivers/base/BaseDriver.js";
|
|
9
|
+
import EternityStorage from "../../eternity/EternityStorage.js";
|
|
10
|
+
import TimeSpan from "../../types/TimeSpan.js";
|
|
11
|
+
import sleep from "../../common/sleep.js";
|
|
12
|
+
|
|
13
|
+
class MockClock extends WorkflowClock {
|
|
14
|
+
|
|
15
|
+
public get utcNow(): DateTime {
|
|
16
|
+
return this.time;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public set utcNow(v: DateTime) {
|
|
20
|
+
this.time = v;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private time: DateTime = DateTime.utcNow;
|
|
24
|
+
|
|
25
|
+
public add(ts: TimeSpan) {
|
|
26
|
+
this.time = this.time.add(ts);
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@RegisterSingleton
|
|
32
|
+
class StateLogger {
|
|
33
|
+
state: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
class VerifyWorkflow extends Workflow<string, string> {
|
|
37
|
+
|
|
38
|
+
public async run() {
|
|
39
|
+
|
|
40
|
+
const ts = TimeSpan.fromSeconds(15);
|
|
41
|
+
|
|
42
|
+
for (let index = 0; index < 5; index++) {
|
|
43
|
+
const { name, result } = await this.waitForExternalEvent(ts, "verify", "resend");
|
|
44
|
+
switch(name) {
|
|
45
|
+
case "verify":
|
|
46
|
+
await this.log("verify");
|
|
47
|
+
if (result === this.input) {
|
|
48
|
+
return "ok";
|
|
49
|
+
}
|
|
50
|
+
break;
|
|
51
|
+
case "resend":
|
|
52
|
+
// do something...
|
|
53
|
+
await this.delay(TimeSpan.fromSeconds(1));
|
|
54
|
+
await this.log("resend");
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return "failed";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@Activity
|
|
63
|
+
async log(
|
|
64
|
+
state: string,
|
|
65
|
+
@Inject stateLogger?: StateLogger
|
|
66
|
+
) {
|
|
67
|
+
console.log(`${state} logged`);
|
|
68
|
+
stateLogger.state = state;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export default async function (this: TestConfig) {
|
|
74
|
+
|
|
75
|
+
const mockClock = new MockClock();
|
|
76
|
+
const stateLogger = new StateLogger();
|
|
77
|
+
const scope = new ServiceProvider();
|
|
78
|
+
scope.add(WorkflowClock, mockClock);
|
|
79
|
+
scope.add(BaseDriver, this.driver);
|
|
80
|
+
scope.add(StateLogger, stateLogger);
|
|
81
|
+
const storage = new EternityStorage(this.driver, mockClock);
|
|
82
|
+
scope.add(EternityStorage, storage);
|
|
83
|
+
|
|
84
|
+
const c = new EternityContext(storage);
|
|
85
|
+
scope.add(EternityContext, c);
|
|
86
|
+
|
|
87
|
+
// this is an important step
|
|
88
|
+
c.register(VerifyWorkflow);
|
|
89
|
+
|
|
90
|
+
await storage.seed();
|
|
91
|
+
|
|
92
|
+
const id = await c.queue(VerifyWorkflow, "a");
|
|
93
|
+
|
|
94
|
+
mockClock.add(TimeSpan.fromSeconds(5));
|
|
95
|
+
|
|
96
|
+
await c.processQueueOnce();
|
|
97
|
+
|
|
98
|
+
let w = await c.get(VerifyWorkflow, id);
|
|
99
|
+
assert.equal("queued", w.state);
|
|
100
|
+
|
|
101
|
+
mockClock.add(TimeSpan.fromSeconds(5));
|
|
102
|
+
await c.processQueueOnce();
|
|
103
|
+
|
|
104
|
+
w = await c.get(VerifyWorkflow, id);
|
|
105
|
+
assert.equal("queued", w.state);
|
|
106
|
+
|
|
107
|
+
await c.raiseEvent(id, { name: "resend"});
|
|
108
|
+
mockClock.add(TimeSpan.fromSeconds(5));
|
|
109
|
+
await c.processQueueOnce();
|
|
110
|
+
|
|
111
|
+
assert.equal("resend", stateLogger.state);
|
|
112
|
+
|
|
113
|
+
w = await c.get(VerifyWorkflow, id);
|
|
114
|
+
assert.equal("queued", w.state);
|
|
115
|
+
|
|
116
|
+
mockClock.add(TimeSpan.fromSeconds(5));
|
|
117
|
+
await c.raiseEvent(id, { name: "verify", result: "a"});
|
|
118
|
+
mockClock.add(TimeSpan.fromSeconds(5));
|
|
119
|
+
await c.processQueueOnce();
|
|
120
|
+
assert.equal("verify", stateLogger.state);
|
|
121
|
+
|
|
122
|
+
w = await c.get(VerifyWorkflow, id);
|
|
123
|
+
assert.equal("done", w.state);
|
|
124
|
+
|
|
125
|
+
mockClock.add(TimeSpan.fromDays(1));
|
|
126
|
+
await c.processQueueOnce();
|
|
127
|
+
|
|
128
|
+
// make sure workflow is deleted...
|
|
129
|
+
|
|
130
|
+
w = await c.get(VerifyWorkflow, id);
|
|
131
|
+
assert.equal(null, w);
|
|
132
|
+
}
|