@dudousxd/nestjs-durable-store-mikro-orm 0.8.0 → 0.9.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/LICENSE +21 -0
- package/dist/index.cjs +785 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +132 -0
- package/dist/index.d.ts +132 -4
- package/dist/index.js +750 -17
- package/dist/index.js.map +1 -1
- package/package.json +25 -6
- package/dist/entities.d.ts +0 -48
- package/dist/entities.d.ts.map +0 -1
- package/dist/entities.js +0 -229
- package/dist/entities.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/mikro-orm-state-store.d.ts +0 -37
- package/dist/mikro-orm-state-store.d.ts.map +0 -1
- package/dist/mikro-orm-state-store.js +0 -231
- package/dist/mikro-orm-state-store.js.map +0 -1
- package/dist/schema.d.ts +0 -14
- package/dist/schema.d.ts.map +0 -1
- package/dist/schema.js +0 -18
- package/dist/schema.js.map +0 -1
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,785 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/index.ts
|
|
22
|
+
var index_exports = {};
|
|
23
|
+
__export(index_exports, {
|
|
24
|
+
BufferedSignalEntity: () => BufferedSignalEntity,
|
|
25
|
+
ENTITIES: () => ENTITIES,
|
|
26
|
+
MikroOrmStateStore: () => MikroOrmStateStore,
|
|
27
|
+
RunAttributeEntity: () => RunAttributeEntity,
|
|
28
|
+
SignalWaiterEntity: () => SignalWaiterEntity,
|
|
29
|
+
StepCheckpointEntity: () => StepCheckpointEntity,
|
|
30
|
+
WorkflowRunEntity: () => WorkflowRunEntity,
|
|
31
|
+
ensureMikroOrmDurableSchema: () => ensureMikroOrmDurableSchema
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(index_exports);
|
|
34
|
+
|
|
35
|
+
// src/entities.ts
|
|
36
|
+
var import_core = require("@mikro-orm/core");
|
|
37
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
38
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
39
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
40
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
41
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
42
|
+
}
|
|
43
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
44
|
+
function _ts_metadata(k, v) {
|
|
45
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
46
|
+
}
|
|
47
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
48
|
+
var WorkflowRunEntity = class {
|
|
49
|
+
static {
|
|
50
|
+
__name(this, "WorkflowRunEntity");
|
|
51
|
+
}
|
|
52
|
+
id;
|
|
53
|
+
workflow;
|
|
54
|
+
workflowVersion;
|
|
55
|
+
status;
|
|
56
|
+
input;
|
|
57
|
+
output;
|
|
58
|
+
error;
|
|
59
|
+
wakeAt;
|
|
60
|
+
lockedBy;
|
|
61
|
+
lockedUntil;
|
|
62
|
+
recoveryAttempts;
|
|
63
|
+
tags;
|
|
64
|
+
searchAttributes;
|
|
65
|
+
createdAt;
|
|
66
|
+
updatedAt;
|
|
67
|
+
};
|
|
68
|
+
_ts_decorate([
|
|
69
|
+
(0, import_core.PrimaryKey)(),
|
|
70
|
+
_ts_metadata("design:type", String)
|
|
71
|
+
], WorkflowRunEntity.prototype, "id", void 0);
|
|
72
|
+
_ts_decorate([
|
|
73
|
+
(0, import_core.Property)(),
|
|
74
|
+
_ts_metadata("design:type", String)
|
|
75
|
+
], WorkflowRunEntity.prototype, "workflow", void 0);
|
|
76
|
+
_ts_decorate([
|
|
77
|
+
(0, import_core.Property)(),
|
|
78
|
+
_ts_metadata("design:type", String)
|
|
79
|
+
], WorkflowRunEntity.prototype, "workflowVersion", void 0);
|
|
80
|
+
_ts_decorate([
|
|
81
|
+
(0, import_core.Property)(),
|
|
82
|
+
_ts_metadata("design:type", typeof RunStatus === "undefined" ? Object : RunStatus)
|
|
83
|
+
], WorkflowRunEntity.prototype, "status", void 0);
|
|
84
|
+
_ts_decorate([
|
|
85
|
+
(0, import_core.Property)({
|
|
86
|
+
type: "json",
|
|
87
|
+
nullable: true
|
|
88
|
+
}),
|
|
89
|
+
_ts_metadata("design:type", Object)
|
|
90
|
+
], WorkflowRunEntity.prototype, "input", void 0);
|
|
91
|
+
_ts_decorate([
|
|
92
|
+
(0, import_core.Property)({
|
|
93
|
+
type: "json",
|
|
94
|
+
nullable: true
|
|
95
|
+
}),
|
|
96
|
+
_ts_metadata("design:type", Object)
|
|
97
|
+
], WorkflowRunEntity.prototype, "output", void 0);
|
|
98
|
+
_ts_decorate([
|
|
99
|
+
(0, import_core.Property)({
|
|
100
|
+
type: "json",
|
|
101
|
+
nullable: true
|
|
102
|
+
}),
|
|
103
|
+
_ts_metadata("design:type", Object)
|
|
104
|
+
], WorkflowRunEntity.prototype, "error", void 0);
|
|
105
|
+
_ts_decorate([
|
|
106
|
+
(0, import_core.Property)({
|
|
107
|
+
nullable: true
|
|
108
|
+
}),
|
|
109
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
110
|
+
], WorkflowRunEntity.prototype, "wakeAt", void 0);
|
|
111
|
+
_ts_decorate([
|
|
112
|
+
(0, import_core.Property)({
|
|
113
|
+
nullable: true
|
|
114
|
+
}),
|
|
115
|
+
_ts_metadata("design:type", String)
|
|
116
|
+
], WorkflowRunEntity.prototype, "lockedBy", void 0);
|
|
117
|
+
_ts_decorate([
|
|
118
|
+
(0, import_core.Property)({
|
|
119
|
+
nullable: true
|
|
120
|
+
}),
|
|
121
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
122
|
+
], WorkflowRunEntity.prototype, "lockedUntil", void 0);
|
|
123
|
+
_ts_decorate([
|
|
124
|
+
(0, import_core.Property)({
|
|
125
|
+
type: "integer",
|
|
126
|
+
nullable: true
|
|
127
|
+
}),
|
|
128
|
+
_ts_metadata("design:type", Number)
|
|
129
|
+
], WorkflowRunEntity.prototype, "recoveryAttempts", void 0);
|
|
130
|
+
_ts_decorate([
|
|
131
|
+
(0, import_core.Property)({
|
|
132
|
+
type: "json",
|
|
133
|
+
nullable: true
|
|
134
|
+
}),
|
|
135
|
+
_ts_metadata("design:type", Object)
|
|
136
|
+
], WorkflowRunEntity.prototype, "tags", void 0);
|
|
137
|
+
_ts_decorate([
|
|
138
|
+
(0, import_core.Property)({
|
|
139
|
+
type: "json",
|
|
140
|
+
nullable: true
|
|
141
|
+
}),
|
|
142
|
+
_ts_metadata("design:type", Object)
|
|
143
|
+
], WorkflowRunEntity.prototype, "searchAttributes", void 0);
|
|
144
|
+
_ts_decorate([
|
|
145
|
+
(0, import_core.Property)(),
|
|
146
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
147
|
+
], WorkflowRunEntity.prototype, "createdAt", void 0);
|
|
148
|
+
_ts_decorate([
|
|
149
|
+
(0, import_core.Property)(),
|
|
150
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
151
|
+
], WorkflowRunEntity.prototype, "updatedAt", void 0);
|
|
152
|
+
WorkflowRunEntity = _ts_decorate([
|
|
153
|
+
(0, import_core.Entity)({
|
|
154
|
+
tableName: "durable_workflow_runs"
|
|
155
|
+
})
|
|
156
|
+
], WorkflowRunEntity);
|
|
157
|
+
var StepCheckpointEntity = class {
|
|
158
|
+
static {
|
|
159
|
+
__name(this, "StepCheckpointEntity");
|
|
160
|
+
}
|
|
161
|
+
runId;
|
|
162
|
+
seq;
|
|
163
|
+
name;
|
|
164
|
+
kind;
|
|
165
|
+
stepId;
|
|
166
|
+
status;
|
|
167
|
+
input;
|
|
168
|
+
output;
|
|
169
|
+
error;
|
|
170
|
+
events;
|
|
171
|
+
attempts;
|
|
172
|
+
workerGroup;
|
|
173
|
+
wakeAt;
|
|
174
|
+
enqueuedAt;
|
|
175
|
+
startedAt;
|
|
176
|
+
finishedAt;
|
|
177
|
+
};
|
|
178
|
+
_ts_decorate([
|
|
179
|
+
(0, import_core.PrimaryKey)(),
|
|
180
|
+
_ts_metadata("design:type", String)
|
|
181
|
+
], StepCheckpointEntity.prototype, "runId", void 0);
|
|
182
|
+
_ts_decorate([
|
|
183
|
+
(0, import_core.PrimaryKey)(),
|
|
184
|
+
_ts_metadata("design:type", Number)
|
|
185
|
+
], StepCheckpointEntity.prototype, "seq", void 0);
|
|
186
|
+
_ts_decorate([
|
|
187
|
+
(0, import_core.Property)(),
|
|
188
|
+
_ts_metadata("design:type", String)
|
|
189
|
+
], StepCheckpointEntity.prototype, "name", void 0);
|
|
190
|
+
_ts_decorate([
|
|
191
|
+
(0, import_core.Property)(),
|
|
192
|
+
_ts_metadata("design:type", typeof StepKind === "undefined" ? Object : StepKind)
|
|
193
|
+
], StepCheckpointEntity.prototype, "kind", void 0);
|
|
194
|
+
_ts_decorate([
|
|
195
|
+
(0, import_core.Property)(),
|
|
196
|
+
_ts_metadata("design:type", String)
|
|
197
|
+
], StepCheckpointEntity.prototype, "stepId", void 0);
|
|
198
|
+
_ts_decorate([
|
|
199
|
+
(0, import_core.Property)(),
|
|
200
|
+
_ts_metadata("design:type", String)
|
|
201
|
+
], StepCheckpointEntity.prototype, "status", void 0);
|
|
202
|
+
_ts_decorate([
|
|
203
|
+
(0, import_core.Property)({
|
|
204
|
+
type: "json",
|
|
205
|
+
nullable: true
|
|
206
|
+
}),
|
|
207
|
+
_ts_metadata("design:type", Object)
|
|
208
|
+
], StepCheckpointEntity.prototype, "input", void 0);
|
|
209
|
+
_ts_decorate([
|
|
210
|
+
(0, import_core.Property)({
|
|
211
|
+
type: "json",
|
|
212
|
+
nullable: true
|
|
213
|
+
}),
|
|
214
|
+
_ts_metadata("design:type", Object)
|
|
215
|
+
], StepCheckpointEntity.prototype, "output", void 0);
|
|
216
|
+
_ts_decorate([
|
|
217
|
+
(0, import_core.Property)({
|
|
218
|
+
type: "json",
|
|
219
|
+
nullable: true
|
|
220
|
+
}),
|
|
221
|
+
_ts_metadata("design:type", Object)
|
|
222
|
+
], StepCheckpointEntity.prototype, "error", void 0);
|
|
223
|
+
_ts_decorate([
|
|
224
|
+
(0, import_core.Property)({
|
|
225
|
+
type: "json",
|
|
226
|
+
nullable: true
|
|
227
|
+
}),
|
|
228
|
+
_ts_metadata("design:type", Object)
|
|
229
|
+
], StepCheckpointEntity.prototype, "events", void 0);
|
|
230
|
+
_ts_decorate([
|
|
231
|
+
(0, import_core.Property)(),
|
|
232
|
+
_ts_metadata("design:type", Number)
|
|
233
|
+
], StepCheckpointEntity.prototype, "attempts", void 0);
|
|
234
|
+
_ts_decorate([
|
|
235
|
+
(0, import_core.Property)({
|
|
236
|
+
nullable: true
|
|
237
|
+
}),
|
|
238
|
+
_ts_metadata("design:type", String)
|
|
239
|
+
], StepCheckpointEntity.prototype, "workerGroup", void 0);
|
|
240
|
+
_ts_decorate([
|
|
241
|
+
(0, import_core.Property)({
|
|
242
|
+
nullable: true
|
|
243
|
+
}),
|
|
244
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
245
|
+
], StepCheckpointEntity.prototype, "wakeAt", void 0);
|
|
246
|
+
_ts_decorate([
|
|
247
|
+
(0, import_core.Property)({
|
|
248
|
+
nullable: true
|
|
249
|
+
}),
|
|
250
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
251
|
+
], StepCheckpointEntity.prototype, "enqueuedAt", void 0);
|
|
252
|
+
_ts_decorate([
|
|
253
|
+
(0, import_core.Property)(),
|
|
254
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
255
|
+
], StepCheckpointEntity.prototype, "startedAt", void 0);
|
|
256
|
+
_ts_decorate([
|
|
257
|
+
(0, import_core.Property)(),
|
|
258
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
259
|
+
], StepCheckpointEntity.prototype, "finishedAt", void 0);
|
|
260
|
+
StepCheckpointEntity = _ts_decorate([
|
|
261
|
+
(0, import_core.Entity)({
|
|
262
|
+
tableName: "durable_step_checkpoints"
|
|
263
|
+
})
|
|
264
|
+
], StepCheckpointEntity);
|
|
265
|
+
var RunAttributeEntity = class {
|
|
266
|
+
static {
|
|
267
|
+
__name(this, "RunAttributeEntity");
|
|
268
|
+
}
|
|
269
|
+
runId;
|
|
270
|
+
key;
|
|
271
|
+
strValue;
|
|
272
|
+
// `float`/`double` is portable across SQLite/MySQL/Postgres for numeric range scans.
|
|
273
|
+
numValue;
|
|
274
|
+
};
|
|
275
|
+
_ts_decorate([
|
|
276
|
+
(0, import_core.PrimaryKey)(),
|
|
277
|
+
_ts_metadata("design:type", String)
|
|
278
|
+
], RunAttributeEntity.prototype, "runId", void 0);
|
|
279
|
+
_ts_decorate([
|
|
280
|
+
(0, import_core.PrimaryKey)(),
|
|
281
|
+
_ts_metadata("design:type", String)
|
|
282
|
+
], RunAttributeEntity.prototype, "key", void 0);
|
|
283
|
+
_ts_decorate([
|
|
284
|
+
(0, import_core.Property)({
|
|
285
|
+
type: "string",
|
|
286
|
+
nullable: true
|
|
287
|
+
}),
|
|
288
|
+
_ts_metadata("design:type", Object)
|
|
289
|
+
], RunAttributeEntity.prototype, "strValue", void 0);
|
|
290
|
+
_ts_decorate([
|
|
291
|
+
(0, import_core.Property)({
|
|
292
|
+
type: "float",
|
|
293
|
+
nullable: true
|
|
294
|
+
}),
|
|
295
|
+
_ts_metadata("design:type", Object)
|
|
296
|
+
], RunAttributeEntity.prototype, "numValue", void 0);
|
|
297
|
+
RunAttributeEntity = _ts_decorate([
|
|
298
|
+
(0, import_core.Entity)({
|
|
299
|
+
tableName: "durable_run_attributes"
|
|
300
|
+
})
|
|
301
|
+
], RunAttributeEntity);
|
|
302
|
+
var SignalWaiterEntity = class {
|
|
303
|
+
static {
|
|
304
|
+
__name(this, "SignalWaiterEntity");
|
|
305
|
+
}
|
|
306
|
+
token;
|
|
307
|
+
runId;
|
|
308
|
+
seq;
|
|
309
|
+
};
|
|
310
|
+
_ts_decorate([
|
|
311
|
+
(0, import_core.PrimaryKey)(),
|
|
312
|
+
_ts_metadata("design:type", String)
|
|
313
|
+
], SignalWaiterEntity.prototype, "token", void 0);
|
|
314
|
+
_ts_decorate([
|
|
315
|
+
(0, import_core.Property)(),
|
|
316
|
+
_ts_metadata("design:type", String)
|
|
317
|
+
], SignalWaiterEntity.prototype, "runId", void 0);
|
|
318
|
+
_ts_decorate([
|
|
319
|
+
(0, import_core.Property)(),
|
|
320
|
+
_ts_metadata("design:type", Number)
|
|
321
|
+
], SignalWaiterEntity.prototype, "seq", void 0);
|
|
322
|
+
SignalWaiterEntity = _ts_decorate([
|
|
323
|
+
(0, import_core.Entity)({
|
|
324
|
+
tableName: "durable_signal_waiters"
|
|
325
|
+
})
|
|
326
|
+
], SignalWaiterEntity);
|
|
327
|
+
var BufferedSignalEntity = class {
|
|
328
|
+
static {
|
|
329
|
+
__name(this, "BufferedSignalEntity");
|
|
330
|
+
}
|
|
331
|
+
id;
|
|
332
|
+
token;
|
|
333
|
+
payload;
|
|
334
|
+
};
|
|
335
|
+
_ts_decorate([
|
|
336
|
+
(0, import_core.PrimaryKey)({
|
|
337
|
+
autoincrement: true
|
|
338
|
+
}),
|
|
339
|
+
_ts_metadata("design:type", Number)
|
|
340
|
+
], BufferedSignalEntity.prototype, "id", void 0);
|
|
341
|
+
_ts_decorate([
|
|
342
|
+
(0, import_core.Property)({
|
|
343
|
+
index: true
|
|
344
|
+
}),
|
|
345
|
+
_ts_metadata("design:type", String)
|
|
346
|
+
], BufferedSignalEntity.prototype, "token", void 0);
|
|
347
|
+
_ts_decorate([
|
|
348
|
+
(0, import_core.Property)({
|
|
349
|
+
type: "json",
|
|
350
|
+
nullable: true
|
|
351
|
+
}),
|
|
352
|
+
_ts_metadata("design:type", Object)
|
|
353
|
+
], BufferedSignalEntity.prototype, "payload", void 0);
|
|
354
|
+
BufferedSignalEntity = _ts_decorate([
|
|
355
|
+
(0, import_core.Entity)({
|
|
356
|
+
tableName: "durable_buffered_signals"
|
|
357
|
+
})
|
|
358
|
+
], BufferedSignalEntity);
|
|
359
|
+
var ENTITIES = [
|
|
360
|
+
WorkflowRunEntity,
|
|
361
|
+
StepCheckpointEntity,
|
|
362
|
+
RunAttributeEntity,
|
|
363
|
+
SignalWaiterEntity,
|
|
364
|
+
BufferedSignalEntity
|
|
365
|
+
];
|
|
366
|
+
|
|
367
|
+
// src/mikro-orm-state-store.ts
|
|
368
|
+
var import_nestjs_durable_core = require("@dudousxd/nestjs-durable-core");
|
|
369
|
+
|
|
370
|
+
// src/schema.ts
|
|
371
|
+
async function ensureMikroOrmDurableSchema(orm) {
|
|
372
|
+
await orm.schema.updateSchema({
|
|
373
|
+
safe: true
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
__name(ensureMikroOrmDurableSchema, "ensureMikroOrmDurableSchema");
|
|
377
|
+
|
|
378
|
+
// src/mikro-orm-state-store.ts
|
|
379
|
+
var MikroOrmStateStore = class {
|
|
380
|
+
static {
|
|
381
|
+
__name(this, "MikroOrmStateStore");
|
|
382
|
+
}
|
|
383
|
+
orm;
|
|
384
|
+
constructor(orm) {
|
|
385
|
+
this.orm = orm;
|
|
386
|
+
}
|
|
387
|
+
async ensureSchema() {
|
|
388
|
+
await ensureMikroOrmDurableSchema(this.orm);
|
|
389
|
+
}
|
|
390
|
+
async createRun(run) {
|
|
391
|
+
const em = this.orm.em.fork();
|
|
392
|
+
em.create(WorkflowRunEntity, toRunEntity(run));
|
|
393
|
+
await em.flush();
|
|
394
|
+
await this.reindexAttributes(run.id, run.searchAttributes);
|
|
395
|
+
}
|
|
396
|
+
async updateRun(runId, patch) {
|
|
397
|
+
const em = this.orm.em.fork();
|
|
398
|
+
const entity = await em.findOneOrFail(WorkflowRunEntity, {
|
|
399
|
+
id: runId
|
|
400
|
+
});
|
|
401
|
+
Object.assign(entity, toRunEntity({
|
|
402
|
+
...fromRunEntity(entity),
|
|
403
|
+
...patch
|
|
404
|
+
}));
|
|
405
|
+
await em.flush();
|
|
406
|
+
if ("searchAttributes" in patch) await this.reindexAttributes(runId, patch.searchAttributes);
|
|
407
|
+
}
|
|
408
|
+
/** Rewrite a run's normalized attribute rows: delete the old set, insert the current one. Mirrors
|
|
409
|
+
* the in-memory store's reindex so the side-table always reflects the run's live searchAttributes. */
|
|
410
|
+
async reindexAttributes(runId, attributes, forked) {
|
|
411
|
+
const em = forked ?? this.orm.em.fork();
|
|
412
|
+
await em.nativeDelete(RunAttributeEntity, {
|
|
413
|
+
runId
|
|
414
|
+
});
|
|
415
|
+
const rows = (0, import_nestjs_durable_core.normalizeAttributeRows)(runId, attributes);
|
|
416
|
+
if (rows.length) await em.insertMany(RunAttributeEntity, rows);
|
|
417
|
+
}
|
|
418
|
+
async getRun(runId) {
|
|
419
|
+
const em = this.orm.em.fork();
|
|
420
|
+
const entity = await em.findOne(WorkflowRunEntity, {
|
|
421
|
+
id: runId
|
|
422
|
+
});
|
|
423
|
+
return entity ? fromRunEntity(entity) : null;
|
|
424
|
+
}
|
|
425
|
+
async getCheckpoint(runId, seq) {
|
|
426
|
+
const em = this.orm.em.fork();
|
|
427
|
+
const entity = await em.findOne(StepCheckpointEntity, {
|
|
428
|
+
runId,
|
|
429
|
+
seq
|
|
430
|
+
});
|
|
431
|
+
return entity ? fromCheckpointEntity(entity) : null;
|
|
432
|
+
}
|
|
433
|
+
async saveCheckpoint(checkpoint) {
|
|
434
|
+
const em = this.orm.em.fork();
|
|
435
|
+
await em.upsert(StepCheckpointEntity, toCheckpointEntity(checkpoint));
|
|
436
|
+
await em.flush();
|
|
437
|
+
}
|
|
438
|
+
async transaction(work) {
|
|
439
|
+
return this.orm.em.fork().transactional(async (em) => work({
|
|
440
|
+
raw: em,
|
|
441
|
+
saveCheckpoint: /* @__PURE__ */ __name(async (cp) => {
|
|
442
|
+
await em.upsert(StepCheckpointEntity, toCheckpointEntity(cp));
|
|
443
|
+
}, "saveCheckpoint")
|
|
444
|
+
}));
|
|
445
|
+
}
|
|
446
|
+
async listIncompleteRuns() {
|
|
447
|
+
const em = this.orm.em.fork();
|
|
448
|
+
const rows = await em.find(WorkflowRunEntity, {
|
|
449
|
+
status: "running"
|
|
450
|
+
});
|
|
451
|
+
return rows.map(fromRunEntity);
|
|
452
|
+
}
|
|
453
|
+
async listPendingRuns(limit) {
|
|
454
|
+
const em = this.orm.em.fork();
|
|
455
|
+
const rows = await em.find(WorkflowRunEntity, {
|
|
456
|
+
status: "pending"
|
|
457
|
+
}, {
|
|
458
|
+
orderBy: {
|
|
459
|
+
createdAt: "asc"
|
|
460
|
+
},
|
|
461
|
+
limit
|
|
462
|
+
});
|
|
463
|
+
return rows.map(fromRunEntity);
|
|
464
|
+
}
|
|
465
|
+
async listDueTimers(nowMs) {
|
|
466
|
+
const em = this.orm.em.fork();
|
|
467
|
+
const rows = await em.find(WorkflowRunEntity, {
|
|
468
|
+
status: "suspended",
|
|
469
|
+
wakeAt: {
|
|
470
|
+
$ne: null,
|
|
471
|
+
$lte: new Date(nowMs)
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
return rows.map(fromRunEntity);
|
|
475
|
+
}
|
|
476
|
+
async tryLockRun(runId, owner, leaseUntilMs, nowMs) {
|
|
477
|
+
const em = this.orm.em.fork();
|
|
478
|
+
const affected = await em.nativeUpdate(WorkflowRunEntity, {
|
|
479
|
+
id: runId,
|
|
480
|
+
$or: [
|
|
481
|
+
{
|
|
482
|
+
lockedUntil: null
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
lockedUntil: {
|
|
486
|
+
$lte: new Date(nowMs)
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
]
|
|
490
|
+
}, {
|
|
491
|
+
lockedBy: owner,
|
|
492
|
+
lockedUntil: new Date(leaseUntilMs)
|
|
493
|
+
});
|
|
494
|
+
return affected === 1;
|
|
495
|
+
}
|
|
496
|
+
async releaseRunLock(runId) {
|
|
497
|
+
const em = this.orm.em.fork();
|
|
498
|
+
await em.nativeUpdate(WorkflowRunEntity, {
|
|
499
|
+
id: runId
|
|
500
|
+
}, {
|
|
501
|
+
lockedBy: null,
|
|
502
|
+
lockedUntil: null
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
async renewRunLock(runId, owner, leaseUntilMs) {
|
|
506
|
+
const em = this.orm.em.fork();
|
|
507
|
+
const affected = await em.nativeUpdate(WorkflowRunEntity, {
|
|
508
|
+
id: runId,
|
|
509
|
+
lockedBy: owner
|
|
510
|
+
}, {
|
|
511
|
+
lockedUntil: new Date(leaseUntilMs)
|
|
512
|
+
});
|
|
513
|
+
return affected === 1;
|
|
514
|
+
}
|
|
515
|
+
async listRuns(query) {
|
|
516
|
+
const em = this.orm.em.fork();
|
|
517
|
+
const where = {};
|
|
518
|
+
if (query.workflow) where.workflow = query.workflow;
|
|
519
|
+
if (query.status && query.statuses) {
|
|
520
|
+
where.$and = [
|
|
521
|
+
{
|
|
522
|
+
status: query.status
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
status: {
|
|
526
|
+
$in: query.statuses
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
];
|
|
530
|
+
} else if (query.status) {
|
|
531
|
+
where.status = query.status;
|
|
532
|
+
} else if (query.statuses) {
|
|
533
|
+
where.status = {
|
|
534
|
+
$in: query.statuses
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
const orderBy = {
|
|
538
|
+
createdAt: "desc"
|
|
539
|
+
};
|
|
540
|
+
if (query.tag || query.attributes?.length) {
|
|
541
|
+
const quote = this.idQuote(em);
|
|
542
|
+
const cols = this.attributeColumns(em);
|
|
543
|
+
const qb = em.createQueryBuilder(WorkflowRunEntity, "r").where(where).orderBy(orderBy);
|
|
544
|
+
if (query.tag) {
|
|
545
|
+
const tagsCol = this.tagsColumn(em);
|
|
546
|
+
const pattern = `%"${query.tag.replace(/'/g, "''")}"%`;
|
|
547
|
+
const colExpr = this.jsonAsText(em, `${quote("r")}.${quote(tagsCol)}`);
|
|
548
|
+
qb.andWhere(`${colExpr} LIKE '${pattern}'`);
|
|
549
|
+
}
|
|
550
|
+
for (const f of query.attributes ?? []) {
|
|
551
|
+
qb.andWhere(this.attributeExistsSql(f, quote, "r", cols));
|
|
552
|
+
}
|
|
553
|
+
if (query.limit != null) qb.limit(query.limit);
|
|
554
|
+
if (query.offset != null) qb.offset(query.offset);
|
|
555
|
+
const rows2 = await qb.getResultList();
|
|
556
|
+
return rows2.map(fromRunEntity);
|
|
557
|
+
}
|
|
558
|
+
const rows = await em.find(WorkflowRunEntity, where, {
|
|
559
|
+
...query.limit != null ? {
|
|
560
|
+
limit: query.limit
|
|
561
|
+
} : {},
|
|
562
|
+
...query.offset != null ? {
|
|
563
|
+
offset: query.offset
|
|
564
|
+
} : {},
|
|
565
|
+
orderBy
|
|
566
|
+
});
|
|
567
|
+
return rows.map(fromRunEntity);
|
|
568
|
+
}
|
|
569
|
+
/** One attribute predicate as a raw EXISTS subquery on the side-table, correlated to the outer run
|
|
570
|
+
* alias. `<>` (ne) also excludes runs where the attribute is absent (missing-key-never-matches):
|
|
571
|
+
* EXISTS already requires a present row, so EXISTS(... <> ...) is exactly ne-with-present. Numeric
|
|
572
|
+
* operands compare the num column, everything else the str column. Identifiers are quoted per
|
|
573
|
+
* driver and operands are inlined as literals (string operands are escaped by doubling quotes). */
|
|
574
|
+
attributeExistsSql(f, quote, alias, cols) {
|
|
575
|
+
const col = (0, import_nestjs_durable_core.attributeColumnFor)(f) === "numValue" ? cols.numValue : cols.strValue;
|
|
576
|
+
const cmp = (0, import_nestjs_durable_core.sqlComparator)(f.op);
|
|
577
|
+
const operand = (0, import_nestjs_durable_core.attributeOperand)(f);
|
|
578
|
+
const literal = typeof operand === "number" ? String(operand) : `'${String(operand).replace(/'/g, "''")}'`;
|
|
579
|
+
const a = quote(cols.table);
|
|
580
|
+
const sub = quote("a");
|
|
581
|
+
const outerId = `${quote(alias)}.${quote(cols.runPk)}`;
|
|
582
|
+
return `EXISTS (SELECT 1 FROM ${a} ${sub} WHERE ${sub}.${quote(cols.runId)} = ${outerId} AND ${sub}.${quote(cols.key)} = '${f.key.replace(/'/g, "''")}' AND ${sub}.${quote(col)} ${cmp} ${literal})`;
|
|
583
|
+
}
|
|
584
|
+
/** Resolve the side-table's actual column names from MikroORM metadata, so the raw EXISTS matches
|
|
585
|
+
* the active naming strategy (underscore vs camelCase) rather than guessing. The run PK column is
|
|
586
|
+
* reused for BOTH the outer correlation and the side-table FK (they share the same fieldName). */
|
|
587
|
+
attributeColumns(em) {
|
|
588
|
+
const meta = em.getMetadata().get(RunAttributeEntity.name);
|
|
589
|
+
const field = /* @__PURE__ */ __name((prop) => meta.properties[prop]?.fieldNames?.[0] ?? prop, "field");
|
|
590
|
+
const runMeta = em.getMetadata().get(WorkflowRunEntity.name);
|
|
591
|
+
const runPk = runMeta.properties.id?.fieldNames?.[0] ?? "id";
|
|
592
|
+
return {
|
|
593
|
+
table: meta.tableName,
|
|
594
|
+
runId: field("runId"),
|
|
595
|
+
runPk,
|
|
596
|
+
key: field("key"),
|
|
597
|
+
strValue: field("strValue"),
|
|
598
|
+
numValue: field("numValue")
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
/** Resolve the `tags` column name from metadata (per the active naming strategy), for the raw LIKE. */
|
|
602
|
+
tagsColumn(em) {
|
|
603
|
+
const runMeta = em.getMetadata().get(WorkflowRunEntity.name);
|
|
604
|
+
return runMeta.properties.tags?.fieldNames?.[0] ?? "tags";
|
|
605
|
+
}
|
|
606
|
+
/** Wrap a JSON column reference so it can be `LIKE`d as text. Postgres `jsonb`/`json` rejects `LIKE`
|
|
607
|
+
* directly (`operator does not exist: jsonb ~~ unknown`) — cast to `text`; MySQL JSON needs an
|
|
608
|
+
* explicit `CHAR` cast; SQLite stores JSON as text already, so no cast. */
|
|
609
|
+
jsonAsText(em, colRef) {
|
|
610
|
+
const platform = String(em.getPlatform().constructor.name).toLowerCase();
|
|
611
|
+
if (platform.includes("postgre")) return `${colRef}::text`;
|
|
612
|
+
if (platform.includes("mysql") || platform.includes("mariadb")) return `CAST(${colRef} AS CHAR)`;
|
|
613
|
+
return colRef;
|
|
614
|
+
}
|
|
615
|
+
/** Quote an identifier per the active SQL driver (MySQL/MariaDB backtick, others double-quote). */
|
|
616
|
+
idQuote(em) {
|
|
617
|
+
const platform = String(em.getPlatform().constructor.name).toLowerCase();
|
|
618
|
+
const isMysql = platform.includes("mysql") || platform.includes("mariadb");
|
|
619
|
+
const ch = isMysql ? "`" : '"';
|
|
620
|
+
return (id) => `${ch}${id}${ch}`;
|
|
621
|
+
}
|
|
622
|
+
async listCheckpoints(runId) {
|
|
623
|
+
const em = this.orm.em.fork();
|
|
624
|
+
const rows = await em.find(StepCheckpointEntity, {
|
|
625
|
+
runId
|
|
626
|
+
}, {
|
|
627
|
+
orderBy: {
|
|
628
|
+
seq: "asc"
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
return rows.map(fromCheckpointEntity);
|
|
632
|
+
}
|
|
633
|
+
async putSignalWaiter(waiter) {
|
|
634
|
+
const em = this.orm.em.fork();
|
|
635
|
+
await em.upsert(SignalWaiterEntity, {
|
|
636
|
+
...waiter
|
|
637
|
+
});
|
|
638
|
+
await em.flush();
|
|
639
|
+
}
|
|
640
|
+
async takeSignalWaiter(token) {
|
|
641
|
+
const em = this.orm.em.fork();
|
|
642
|
+
const entity = await em.findOne(SignalWaiterEntity, {
|
|
643
|
+
token
|
|
644
|
+
});
|
|
645
|
+
if (!entity) return null;
|
|
646
|
+
const waiter = {
|
|
647
|
+
token: entity.token,
|
|
648
|
+
runId: entity.runId,
|
|
649
|
+
seq: entity.seq
|
|
650
|
+
};
|
|
651
|
+
await em.removeAndFlush(entity);
|
|
652
|
+
return waiter;
|
|
653
|
+
}
|
|
654
|
+
async listSignalWaiters(prefix) {
|
|
655
|
+
const em = this.orm.em.fork();
|
|
656
|
+
const rows = await em.find(SignalWaiterEntity, {
|
|
657
|
+
token: {
|
|
658
|
+
$like: `${prefix}%`
|
|
659
|
+
}
|
|
660
|
+
});
|
|
661
|
+
return rows.map((e) => ({
|
|
662
|
+
token: e.token,
|
|
663
|
+
runId: e.runId,
|
|
664
|
+
seq: e.seq
|
|
665
|
+
}));
|
|
666
|
+
}
|
|
667
|
+
async bufferSignal(token, payload) {
|
|
668
|
+
const em = this.orm.em.fork();
|
|
669
|
+
const e = new BufferedSignalEntity();
|
|
670
|
+
e.token = token;
|
|
671
|
+
e.payload = payload ?? null;
|
|
672
|
+
em.persist(e);
|
|
673
|
+
await em.flush();
|
|
674
|
+
}
|
|
675
|
+
async takeBufferedSignal(token) {
|
|
676
|
+
const em = this.orm.em.fork();
|
|
677
|
+
const entity = await em.findOne(BufferedSignalEntity, {
|
|
678
|
+
token
|
|
679
|
+
}, {
|
|
680
|
+
orderBy: {
|
|
681
|
+
id: "asc"
|
|
682
|
+
}
|
|
683
|
+
});
|
|
684
|
+
if (!entity) return null;
|
|
685
|
+
const payload = entity.payload ?? void 0;
|
|
686
|
+
await em.removeAndFlush(entity);
|
|
687
|
+
return {
|
|
688
|
+
payload
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
function toRunEntity(run) {
|
|
693
|
+
const e = new WorkflowRunEntity();
|
|
694
|
+
e.id = run.id;
|
|
695
|
+
e.workflow = run.workflow;
|
|
696
|
+
e.workflowVersion = run.workflowVersion;
|
|
697
|
+
e.status = run.status;
|
|
698
|
+
e.input = run.input ?? null;
|
|
699
|
+
e.output = run.output ?? null;
|
|
700
|
+
e.error = run.error ?? null;
|
|
701
|
+
if (run.wakeAt != null) e.wakeAt = new Date(run.wakeAt);
|
|
702
|
+
if (run.lockedBy !== void 0) e.lockedBy = run.lockedBy;
|
|
703
|
+
if (run.lockedUntil != null) e.lockedUntil = new Date(run.lockedUntil);
|
|
704
|
+
if (run.recoveryAttempts !== void 0) e.recoveryAttempts = run.recoveryAttempts;
|
|
705
|
+
e.tags = run.tags ?? null;
|
|
706
|
+
e.searchAttributes = run.searchAttributes ?? null;
|
|
707
|
+
e.createdAt = run.createdAt;
|
|
708
|
+
e.updatedAt = run.updatedAt;
|
|
709
|
+
return e;
|
|
710
|
+
}
|
|
711
|
+
__name(toRunEntity, "toRunEntity");
|
|
712
|
+
function fromRunEntity(e) {
|
|
713
|
+
return {
|
|
714
|
+
id: e.id,
|
|
715
|
+
workflow: e.workflow,
|
|
716
|
+
workflowVersion: e.workflowVersion,
|
|
717
|
+
status: e.status,
|
|
718
|
+
input: e.input ?? void 0,
|
|
719
|
+
output: e.output ?? void 0,
|
|
720
|
+
error: e.error ?? void 0,
|
|
721
|
+
wakeAt: e.wakeAt?.getTime(),
|
|
722
|
+
lockedBy: e.lockedBy ?? void 0,
|
|
723
|
+
lockedUntil: e.lockedUntil?.getTime(),
|
|
724
|
+
recoveryAttempts: e.recoveryAttempts ?? void 0,
|
|
725
|
+
tags: e.tags ?? void 0,
|
|
726
|
+
searchAttributes: e.searchAttributes ?? void 0,
|
|
727
|
+
createdAt: e.createdAt,
|
|
728
|
+
updatedAt: e.updatedAt
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
__name(fromRunEntity, "fromRunEntity");
|
|
732
|
+
function toCheckpointEntity(cp) {
|
|
733
|
+
const e = new StepCheckpointEntity();
|
|
734
|
+
e.runId = cp.runId;
|
|
735
|
+
e.seq = cp.seq;
|
|
736
|
+
e.name = cp.name;
|
|
737
|
+
e.kind = cp.kind;
|
|
738
|
+
e.stepId = cp.stepId;
|
|
739
|
+
e.status = cp.status;
|
|
740
|
+
e.input = cp.input ?? null;
|
|
741
|
+
e.output = cp.output ?? null;
|
|
742
|
+
e.error = cp.error ?? null;
|
|
743
|
+
e.events = cp.events ?? null;
|
|
744
|
+
e.attempts = cp.attempts;
|
|
745
|
+
if (cp.workerGroup !== void 0) e.workerGroup = cp.workerGroup;
|
|
746
|
+
if (cp.wakeAt != null) e.wakeAt = new Date(cp.wakeAt);
|
|
747
|
+
e.enqueuedAt = cp.enqueuedAt;
|
|
748
|
+
e.startedAt = cp.startedAt;
|
|
749
|
+
e.finishedAt = cp.finishedAt;
|
|
750
|
+
return e;
|
|
751
|
+
}
|
|
752
|
+
__name(toCheckpointEntity, "toCheckpointEntity");
|
|
753
|
+
function fromCheckpointEntity(e) {
|
|
754
|
+
return {
|
|
755
|
+
runId: e.runId,
|
|
756
|
+
seq: e.seq,
|
|
757
|
+
name: e.name,
|
|
758
|
+
kind: e.kind,
|
|
759
|
+
stepId: e.stepId,
|
|
760
|
+
status: e.status,
|
|
761
|
+
input: e.input ?? void 0,
|
|
762
|
+
output: e.output ?? void 0,
|
|
763
|
+
error: e.error ?? void 0,
|
|
764
|
+
events: e.events ?? void 0,
|
|
765
|
+
attempts: e.attempts,
|
|
766
|
+
workerGroup: e.workerGroup ?? void 0,
|
|
767
|
+
wakeAt: e.wakeAt?.getTime(),
|
|
768
|
+
enqueuedAt: e.enqueuedAt ?? e.startedAt,
|
|
769
|
+
startedAt: e.startedAt,
|
|
770
|
+
finishedAt: e.finishedAt
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
__name(fromCheckpointEntity, "fromCheckpointEntity");
|
|
774
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
775
|
+
0 && (module.exports = {
|
|
776
|
+
BufferedSignalEntity,
|
|
777
|
+
ENTITIES,
|
|
778
|
+
MikroOrmStateStore,
|
|
779
|
+
RunAttributeEntity,
|
|
780
|
+
SignalWaiterEntity,
|
|
781
|
+
StepCheckpointEntity,
|
|
782
|
+
WorkflowRunEntity,
|
|
783
|
+
ensureMikroOrmDurableSchema
|
|
784
|
+
});
|
|
785
|
+
//# sourceMappingURL=index.cjs.map
|