@dudousxd/nestjs-durable-store-typeorm 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/dist/index.cjs +354 -296
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -7
- package/dist/index.d.ts +48 -7
- package/dist/index.js +352 -297
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,9 @@ __export(index_exports, {
|
|
|
30
30
|
TypeOrmStateStore: () => TypeOrmStateStore,
|
|
31
31
|
WorkflowRunEntity: () => WorkflowRunEntity,
|
|
32
32
|
buildWidenStatements: () => buildWidenStatements,
|
|
33
|
+
columnNamer: () => columnNamer,
|
|
34
|
+
durableColumnResolver: () => durableColumnResolver,
|
|
35
|
+
durableEntities: () => durableEntities,
|
|
33
36
|
ensureTypeOrmDurableSchema: () => ensureTypeOrmDurableSchema,
|
|
34
37
|
jsonBlobColumnType: () => jsonBlobColumnType,
|
|
35
38
|
parseJsonColumn: () => parseJsonColumn
|
|
@@ -38,17 +41,6 @@ module.exports = __toCommonJS(index_exports);
|
|
|
38
41
|
|
|
39
42
|
// src/entities.ts
|
|
40
43
|
var import_typeorm = require("typeorm");
|
|
41
|
-
function _ts_decorate(decorators, target, key, desc) {
|
|
42
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
43
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
44
|
-
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;
|
|
45
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
46
|
-
}
|
|
47
|
-
__name(_ts_decorate, "_ts_decorate");
|
|
48
|
-
function _ts_metadata(k, v) {
|
|
49
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
50
|
-
}
|
|
51
|
-
__name(_ts_metadata, "_ts_metadata");
|
|
52
44
|
function parseJsonColumn(raw, field) {
|
|
53
45
|
if (raw == null) return void 0;
|
|
54
46
|
if (typeof raw !== "string") return raw;
|
|
@@ -67,6 +59,16 @@ function jsonColumnTransformer(field) {
|
|
|
67
59
|
};
|
|
68
60
|
}
|
|
69
61
|
__name(jsonColumnTransformer, "jsonColumnTransformer");
|
|
62
|
+
function snakeCase(property) {
|
|
63
|
+
return property.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
|
|
64
|
+
}
|
|
65
|
+
__name(snakeCase, "snakeCase");
|
|
66
|
+
function columnNamer(naming) {
|
|
67
|
+
if (naming === "snake_case") return snakeCase;
|
|
68
|
+
if (naming === "preserve") return (property) => property;
|
|
69
|
+
return naming;
|
|
70
|
+
}
|
|
71
|
+
__name(columnNamer, "columnNamer");
|
|
70
72
|
var WorkflowRunEntity = class {
|
|
71
73
|
static {
|
|
72
74
|
__name(this, "WorkflowRunEntity");
|
|
@@ -87,94 +89,6 @@ var WorkflowRunEntity = class {
|
|
|
87
89
|
createdAt;
|
|
88
90
|
updatedAt;
|
|
89
91
|
};
|
|
90
|
-
_ts_decorate([
|
|
91
|
-
(0, import_typeorm.PrimaryColumn)("text"),
|
|
92
|
-
_ts_metadata("design:type", String)
|
|
93
|
-
], WorkflowRunEntity.prototype, "id", void 0);
|
|
94
|
-
_ts_decorate([
|
|
95
|
-
(0, import_typeorm.Column)("text"),
|
|
96
|
-
_ts_metadata("design:type", String)
|
|
97
|
-
], WorkflowRunEntity.prototype, "workflow", void 0);
|
|
98
|
-
_ts_decorate([
|
|
99
|
-
(0, import_typeorm.Column)("text"),
|
|
100
|
-
_ts_metadata("design:type", String)
|
|
101
|
-
], WorkflowRunEntity.prototype, "workflowVersion", void 0);
|
|
102
|
-
_ts_decorate([
|
|
103
|
-
(0, import_typeorm.Column)("text"),
|
|
104
|
-
_ts_metadata("design:type", typeof RunStatus === "undefined" ? Object : RunStatus)
|
|
105
|
-
], WorkflowRunEntity.prototype, "status", void 0);
|
|
106
|
-
_ts_decorate([
|
|
107
|
-
(0, import_typeorm.Column)("text", {
|
|
108
|
-
nullable: true,
|
|
109
|
-
transformer: jsonColumnTransformer("runs.input")
|
|
110
|
-
}),
|
|
111
|
-
_ts_metadata("design:type", Object)
|
|
112
|
-
], WorkflowRunEntity.prototype, "input", void 0);
|
|
113
|
-
_ts_decorate([
|
|
114
|
-
(0, import_typeorm.Column)("text", {
|
|
115
|
-
nullable: true,
|
|
116
|
-
transformer: jsonColumnTransformer("runs.output")
|
|
117
|
-
}),
|
|
118
|
-
_ts_metadata("design:type", Object)
|
|
119
|
-
], WorkflowRunEntity.prototype, "output", void 0);
|
|
120
|
-
_ts_decorate([
|
|
121
|
-
(0, import_typeorm.Column)("text", {
|
|
122
|
-
nullable: true,
|
|
123
|
-
transformer: jsonColumnTransformer("runs.error")
|
|
124
|
-
}),
|
|
125
|
-
_ts_metadata("design:type", Object)
|
|
126
|
-
], WorkflowRunEntity.prototype, "error", void 0);
|
|
127
|
-
_ts_decorate([
|
|
128
|
-
(0, import_typeorm.Column)({
|
|
129
|
-
nullable: true
|
|
130
|
-
}),
|
|
131
|
-
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
132
|
-
], WorkflowRunEntity.prototype, "wakeAt", void 0);
|
|
133
|
-
_ts_decorate([
|
|
134
|
-
(0, import_typeorm.Column)("text", {
|
|
135
|
-
nullable: true
|
|
136
|
-
}),
|
|
137
|
-
_ts_metadata("design:type", Object)
|
|
138
|
-
], WorkflowRunEntity.prototype, "lockedBy", void 0);
|
|
139
|
-
_ts_decorate([
|
|
140
|
-
(0, import_typeorm.Column)({
|
|
141
|
-
nullable: true
|
|
142
|
-
}),
|
|
143
|
-
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
144
|
-
], WorkflowRunEntity.prototype, "lockedUntil", void 0);
|
|
145
|
-
_ts_decorate([
|
|
146
|
-
(0, import_typeorm.Column)("integer", {
|
|
147
|
-
nullable: true
|
|
148
|
-
}),
|
|
149
|
-
_ts_metadata("design:type", Number)
|
|
150
|
-
], WorkflowRunEntity.prototype, "recoveryAttempts", void 0);
|
|
151
|
-
_ts_decorate([
|
|
152
|
-
(0, import_typeorm.Column)("text", {
|
|
153
|
-
nullable: true,
|
|
154
|
-
transformer: jsonColumnTransformer("runs.tags")
|
|
155
|
-
}),
|
|
156
|
-
_ts_metadata("design:type", Object)
|
|
157
|
-
], WorkflowRunEntity.prototype, "tags", void 0);
|
|
158
|
-
_ts_decorate([
|
|
159
|
-
(0, import_typeorm.Column)("text", {
|
|
160
|
-
nullable: true,
|
|
161
|
-
transformer: jsonColumnTransformer("runs.searchAttributes")
|
|
162
|
-
}),
|
|
163
|
-
_ts_metadata("design:type", Object)
|
|
164
|
-
], WorkflowRunEntity.prototype, "searchAttributes", void 0);
|
|
165
|
-
_ts_decorate([
|
|
166
|
-
(0, import_typeorm.Column)(),
|
|
167
|
-
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
168
|
-
], WorkflowRunEntity.prototype, "createdAt", void 0);
|
|
169
|
-
_ts_decorate([
|
|
170
|
-
(0, import_typeorm.Column)(),
|
|
171
|
-
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
172
|
-
], WorkflowRunEntity.prototype, "updatedAt", void 0);
|
|
173
|
-
WorkflowRunEntity = _ts_decorate([
|
|
174
|
-
(0, import_typeorm.Entity)({
|
|
175
|
-
name: "durable_workflow_runs"
|
|
176
|
-
})
|
|
177
|
-
], WorkflowRunEntity);
|
|
178
92
|
var StepCheckpointEntity = class {
|
|
179
93
|
static {
|
|
180
94
|
__name(this, "StepCheckpointEntity");
|
|
@@ -196,93 +110,6 @@ var StepCheckpointEntity = class {
|
|
|
196
110
|
startedAt;
|
|
197
111
|
finishedAt;
|
|
198
112
|
};
|
|
199
|
-
_ts_decorate([
|
|
200
|
-
(0, import_typeorm.PrimaryColumn)("text"),
|
|
201
|
-
_ts_metadata("design:type", String)
|
|
202
|
-
], StepCheckpointEntity.prototype, "runId", void 0);
|
|
203
|
-
_ts_decorate([
|
|
204
|
-
(0, import_typeorm.PrimaryColumn)("integer"),
|
|
205
|
-
_ts_metadata("design:type", Number)
|
|
206
|
-
], StepCheckpointEntity.prototype, "seq", void 0);
|
|
207
|
-
_ts_decorate([
|
|
208
|
-
(0, import_typeorm.Column)("text"),
|
|
209
|
-
_ts_metadata("design:type", String)
|
|
210
|
-
], StepCheckpointEntity.prototype, "name", void 0);
|
|
211
|
-
_ts_decorate([
|
|
212
|
-
(0, import_typeorm.Column)("text"),
|
|
213
|
-
_ts_metadata("design:type", typeof StepKind === "undefined" ? Object : StepKind)
|
|
214
|
-
], StepCheckpointEntity.prototype, "kind", void 0);
|
|
215
|
-
_ts_decorate([
|
|
216
|
-
(0, import_typeorm.Column)("text"),
|
|
217
|
-
_ts_metadata("design:type", String)
|
|
218
|
-
], StepCheckpointEntity.prototype, "stepId", void 0);
|
|
219
|
-
_ts_decorate([
|
|
220
|
-
(0, import_typeorm.Column)("text"),
|
|
221
|
-
_ts_metadata("design:type", String)
|
|
222
|
-
], StepCheckpointEntity.prototype, "status", void 0);
|
|
223
|
-
_ts_decorate([
|
|
224
|
-
(0, import_typeorm.Column)("text", {
|
|
225
|
-
nullable: true,
|
|
226
|
-
transformer: jsonColumnTransformer("checkpoints.input")
|
|
227
|
-
}),
|
|
228
|
-
_ts_metadata("design:type", Object)
|
|
229
|
-
], StepCheckpointEntity.prototype, "input", void 0);
|
|
230
|
-
_ts_decorate([
|
|
231
|
-
(0, import_typeorm.Column)("text", {
|
|
232
|
-
nullable: true,
|
|
233
|
-
transformer: jsonColumnTransformer("checkpoints.output")
|
|
234
|
-
}),
|
|
235
|
-
_ts_metadata("design:type", Object)
|
|
236
|
-
], StepCheckpointEntity.prototype, "output", void 0);
|
|
237
|
-
_ts_decorate([
|
|
238
|
-
(0, import_typeorm.Column)("text", {
|
|
239
|
-
nullable: true,
|
|
240
|
-
transformer: jsonColumnTransformer("checkpoints.error")
|
|
241
|
-
}),
|
|
242
|
-
_ts_metadata("design:type", Object)
|
|
243
|
-
], StepCheckpointEntity.prototype, "error", void 0);
|
|
244
|
-
_ts_decorate([
|
|
245
|
-
(0, import_typeorm.Column)("text", {
|
|
246
|
-
nullable: true,
|
|
247
|
-
transformer: jsonColumnTransformer("checkpoints.events")
|
|
248
|
-
}),
|
|
249
|
-
_ts_metadata("design:type", Object)
|
|
250
|
-
], StepCheckpointEntity.prototype, "events", void 0);
|
|
251
|
-
_ts_decorate([
|
|
252
|
-
(0, import_typeorm.Column)("integer"),
|
|
253
|
-
_ts_metadata("design:type", Number)
|
|
254
|
-
], StepCheckpointEntity.prototype, "attempts", void 0);
|
|
255
|
-
_ts_decorate([
|
|
256
|
-
(0, import_typeorm.Column)("text", {
|
|
257
|
-
nullable: true
|
|
258
|
-
}),
|
|
259
|
-
_ts_metadata("design:type", Object)
|
|
260
|
-
], StepCheckpointEntity.prototype, "workerGroup", void 0);
|
|
261
|
-
_ts_decorate([
|
|
262
|
-
(0, import_typeorm.Column)({
|
|
263
|
-
nullable: true
|
|
264
|
-
}),
|
|
265
|
-
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
266
|
-
], StepCheckpointEntity.prototype, "wakeAt", void 0);
|
|
267
|
-
_ts_decorate([
|
|
268
|
-
(0, import_typeorm.Column)({
|
|
269
|
-
nullable: true
|
|
270
|
-
}),
|
|
271
|
-
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
272
|
-
], StepCheckpointEntity.prototype, "enqueuedAt", void 0);
|
|
273
|
-
_ts_decorate([
|
|
274
|
-
(0, import_typeorm.Column)(),
|
|
275
|
-
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
276
|
-
], StepCheckpointEntity.prototype, "startedAt", void 0);
|
|
277
|
-
_ts_decorate([
|
|
278
|
-
(0, import_typeorm.Column)(),
|
|
279
|
-
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
280
|
-
], StepCheckpointEntity.prototype, "finishedAt", void 0);
|
|
281
|
-
StepCheckpointEntity = _ts_decorate([
|
|
282
|
-
(0, import_typeorm.Entity)({
|
|
283
|
-
name: "durable_step_checkpoints"
|
|
284
|
-
})
|
|
285
|
-
], StepCheckpointEntity);
|
|
286
113
|
var RunAttributeEntity = class {
|
|
287
114
|
static {
|
|
288
115
|
__name(this, "RunAttributeEntity");
|
|
@@ -290,34 +117,8 @@ var RunAttributeEntity = class {
|
|
|
290
117
|
runId;
|
|
291
118
|
key;
|
|
292
119
|
strValue;
|
|
293
|
-
// `float`/`double` portable across SQLite/MySQL/Postgres for numeric range scans.
|
|
294
120
|
numValue;
|
|
295
121
|
};
|
|
296
|
-
_ts_decorate([
|
|
297
|
-
(0, import_typeorm.PrimaryColumn)("text"),
|
|
298
|
-
_ts_metadata("design:type", String)
|
|
299
|
-
], RunAttributeEntity.prototype, "runId", void 0);
|
|
300
|
-
_ts_decorate([
|
|
301
|
-
(0, import_typeorm.PrimaryColumn)("text"),
|
|
302
|
-
_ts_metadata("design:type", String)
|
|
303
|
-
], RunAttributeEntity.prototype, "key", void 0);
|
|
304
|
-
_ts_decorate([
|
|
305
|
-
(0, import_typeorm.Column)("text", {
|
|
306
|
-
nullable: true
|
|
307
|
-
}),
|
|
308
|
-
_ts_metadata("design:type", Object)
|
|
309
|
-
], RunAttributeEntity.prototype, "strValue", void 0);
|
|
310
|
-
_ts_decorate([
|
|
311
|
-
(0, import_typeorm.Column)("float", {
|
|
312
|
-
nullable: true
|
|
313
|
-
}),
|
|
314
|
-
_ts_metadata("design:type", Object)
|
|
315
|
-
], RunAttributeEntity.prototype, "numValue", void 0);
|
|
316
|
-
RunAttributeEntity = _ts_decorate([
|
|
317
|
-
(0, import_typeorm.Entity)({
|
|
318
|
-
name: "durable_run_attributes"
|
|
319
|
-
})
|
|
320
|
-
], RunAttributeEntity);
|
|
321
122
|
var SignalWaiterEntity = class {
|
|
322
123
|
static {
|
|
323
124
|
__name(this, "SignalWaiterEntity");
|
|
@@ -326,60 +127,265 @@ var SignalWaiterEntity = class {
|
|
|
326
127
|
runId;
|
|
327
128
|
seq;
|
|
328
129
|
};
|
|
329
|
-
_ts_decorate([
|
|
330
|
-
(0, import_typeorm.PrimaryColumn)("text"),
|
|
331
|
-
_ts_metadata("design:type", String)
|
|
332
|
-
], SignalWaiterEntity.prototype, "token", void 0);
|
|
333
|
-
_ts_decorate([
|
|
334
|
-
(0, import_typeorm.Column)("text"),
|
|
335
|
-
_ts_metadata("design:type", String)
|
|
336
|
-
], SignalWaiterEntity.prototype, "runId", void 0);
|
|
337
|
-
_ts_decorate([
|
|
338
|
-
(0, import_typeorm.Column)("integer"),
|
|
339
|
-
_ts_metadata("design:type", Number)
|
|
340
|
-
], SignalWaiterEntity.prototype, "seq", void 0);
|
|
341
|
-
SignalWaiterEntity = _ts_decorate([
|
|
342
|
-
(0, import_typeorm.Entity)({
|
|
343
|
-
name: "durable_signal_waiters"
|
|
344
|
-
})
|
|
345
|
-
], SignalWaiterEntity);
|
|
346
130
|
var BufferedSignalEntity = class {
|
|
347
131
|
static {
|
|
348
132
|
__name(this, "BufferedSignalEntity");
|
|
349
133
|
}
|
|
350
|
-
// Auto-increment PK for FIFO ordering. Left as TypeORM's default increment type so it maps to the
|
|
351
|
-
// driver-native auto-increment column (INTEGER on SQLite, BIGINT/SERIAL on MySQL/Postgres).
|
|
352
134
|
id;
|
|
353
135
|
token;
|
|
354
136
|
payload;
|
|
355
137
|
};
|
|
356
|
-
|
|
357
|
-
(
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
138
|
+
function durableEntities(options = {}) {
|
|
139
|
+
const col = columnNamer(options.naming ?? "snake_case");
|
|
140
|
+
const workflowRuns = new import_typeorm.EntitySchema({
|
|
141
|
+
name: "WorkflowRunEntity",
|
|
142
|
+
target: WorkflowRunEntity,
|
|
143
|
+
tableName: "durable_workflow_runs",
|
|
144
|
+
columns: {
|
|
145
|
+
id: {
|
|
146
|
+
type: "text",
|
|
147
|
+
primary: true,
|
|
148
|
+
name: col("id")
|
|
149
|
+
},
|
|
150
|
+
workflow: {
|
|
151
|
+
type: "text",
|
|
152
|
+
name: col("workflow")
|
|
153
|
+
},
|
|
154
|
+
workflowVersion: {
|
|
155
|
+
type: "text",
|
|
156
|
+
name: col("workflowVersion")
|
|
157
|
+
},
|
|
158
|
+
status: {
|
|
159
|
+
type: "text",
|
|
160
|
+
name: col("status")
|
|
161
|
+
},
|
|
162
|
+
input: {
|
|
163
|
+
type: "text",
|
|
164
|
+
nullable: true,
|
|
165
|
+
name: col("input"),
|
|
166
|
+
transformer: jsonColumnTransformer("runs.input")
|
|
167
|
+
},
|
|
168
|
+
output: {
|
|
169
|
+
type: "text",
|
|
170
|
+
nullable: true,
|
|
171
|
+
name: col("output"),
|
|
172
|
+
transformer: jsonColumnTransformer("runs.output")
|
|
173
|
+
},
|
|
174
|
+
error: {
|
|
175
|
+
type: "text",
|
|
176
|
+
nullable: true,
|
|
177
|
+
name: col("error"),
|
|
178
|
+
transformer: jsonColumnTransformer("runs.error")
|
|
179
|
+
},
|
|
180
|
+
wakeAt: {
|
|
181
|
+
type: Date,
|
|
182
|
+
nullable: true,
|
|
183
|
+
name: col("wakeAt")
|
|
184
|
+
},
|
|
185
|
+
lockedBy: {
|
|
186
|
+
type: "text",
|
|
187
|
+
nullable: true,
|
|
188
|
+
name: col("lockedBy")
|
|
189
|
+
},
|
|
190
|
+
lockedUntil: {
|
|
191
|
+
type: Date,
|
|
192
|
+
nullable: true,
|
|
193
|
+
name: col("lockedUntil")
|
|
194
|
+
},
|
|
195
|
+
recoveryAttempts: {
|
|
196
|
+
type: "integer",
|
|
197
|
+
nullable: true,
|
|
198
|
+
name: col("recoveryAttempts")
|
|
199
|
+
},
|
|
200
|
+
tags: {
|
|
201
|
+
type: "text",
|
|
202
|
+
nullable: true,
|
|
203
|
+
name: col("tags"),
|
|
204
|
+
transformer: jsonColumnTransformer("runs.tags")
|
|
205
|
+
},
|
|
206
|
+
searchAttributes: {
|
|
207
|
+
type: "text",
|
|
208
|
+
nullable: true,
|
|
209
|
+
name: col("searchAttributes"),
|
|
210
|
+
transformer: jsonColumnTransformer("runs.searchAttributes")
|
|
211
|
+
},
|
|
212
|
+
createdAt: {
|
|
213
|
+
type: Date,
|
|
214
|
+
name: col("createdAt")
|
|
215
|
+
},
|
|
216
|
+
updatedAt: {
|
|
217
|
+
type: Date,
|
|
218
|
+
name: col("updatedAt")
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
const stepCheckpoints = new import_typeorm.EntitySchema({
|
|
223
|
+
name: "StepCheckpointEntity",
|
|
224
|
+
target: StepCheckpointEntity,
|
|
225
|
+
tableName: "durable_step_checkpoints",
|
|
226
|
+
columns: {
|
|
227
|
+
runId: {
|
|
228
|
+
type: "text",
|
|
229
|
+
primary: true,
|
|
230
|
+
name: col("runId")
|
|
231
|
+
},
|
|
232
|
+
seq: {
|
|
233
|
+
type: "integer",
|
|
234
|
+
primary: true,
|
|
235
|
+
name: col("seq")
|
|
236
|
+
},
|
|
237
|
+
name: {
|
|
238
|
+
type: "text",
|
|
239
|
+
name: col("name")
|
|
240
|
+
},
|
|
241
|
+
kind: {
|
|
242
|
+
type: "text",
|
|
243
|
+
name: col("kind")
|
|
244
|
+
},
|
|
245
|
+
stepId: {
|
|
246
|
+
type: "text",
|
|
247
|
+
name: col("stepId")
|
|
248
|
+
},
|
|
249
|
+
status: {
|
|
250
|
+
type: "text",
|
|
251
|
+
name: col("status")
|
|
252
|
+
},
|
|
253
|
+
input: {
|
|
254
|
+
type: "text",
|
|
255
|
+
nullable: true,
|
|
256
|
+
name: col("input"),
|
|
257
|
+
transformer: jsonColumnTransformer("checkpoints.input")
|
|
258
|
+
},
|
|
259
|
+
output: {
|
|
260
|
+
type: "text",
|
|
261
|
+
nullable: true,
|
|
262
|
+
name: col("output"),
|
|
263
|
+
transformer: jsonColumnTransformer("checkpoints.output")
|
|
264
|
+
},
|
|
265
|
+
error: {
|
|
266
|
+
type: "text",
|
|
267
|
+
nullable: true,
|
|
268
|
+
name: col("error"),
|
|
269
|
+
transformer: jsonColumnTransformer("checkpoints.error")
|
|
270
|
+
},
|
|
271
|
+
events: {
|
|
272
|
+
type: "text",
|
|
273
|
+
nullable: true,
|
|
274
|
+
name: col("events"),
|
|
275
|
+
transformer: jsonColumnTransformer("checkpoints.events")
|
|
276
|
+
},
|
|
277
|
+
attempts: {
|
|
278
|
+
type: "integer",
|
|
279
|
+
name: col("attempts")
|
|
280
|
+
},
|
|
281
|
+
workerGroup: {
|
|
282
|
+
type: "text",
|
|
283
|
+
nullable: true,
|
|
284
|
+
name: col("workerGroup")
|
|
285
|
+
},
|
|
286
|
+
wakeAt: {
|
|
287
|
+
type: Date,
|
|
288
|
+
nullable: true,
|
|
289
|
+
name: col("wakeAt")
|
|
290
|
+
},
|
|
291
|
+
enqueuedAt: {
|
|
292
|
+
type: Date,
|
|
293
|
+
nullable: true,
|
|
294
|
+
name: col("enqueuedAt")
|
|
295
|
+
},
|
|
296
|
+
startedAt: {
|
|
297
|
+
type: Date,
|
|
298
|
+
name: col("startedAt")
|
|
299
|
+
},
|
|
300
|
+
finishedAt: {
|
|
301
|
+
type: Date,
|
|
302
|
+
name: col("finishedAt")
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
const runAttributes = new import_typeorm.EntitySchema({
|
|
307
|
+
name: "RunAttributeEntity",
|
|
308
|
+
target: RunAttributeEntity,
|
|
309
|
+
tableName: "durable_run_attributes",
|
|
310
|
+
columns: {
|
|
311
|
+
runId: {
|
|
312
|
+
type: "text",
|
|
313
|
+
primary: true,
|
|
314
|
+
name: col("runId")
|
|
315
|
+
},
|
|
316
|
+
key: {
|
|
317
|
+
type: "text",
|
|
318
|
+
primary: true,
|
|
319
|
+
name: col("key")
|
|
320
|
+
},
|
|
321
|
+
strValue: {
|
|
322
|
+
type: "text",
|
|
323
|
+
nullable: true,
|
|
324
|
+
name: col("strValue")
|
|
325
|
+
},
|
|
326
|
+
// `float`/`double` portable across SQLite/MySQL/Postgres for numeric range scans.
|
|
327
|
+
numValue: {
|
|
328
|
+
type: "float",
|
|
329
|
+
nullable: true,
|
|
330
|
+
name: col("numValue")
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
const signalWaiters = new import_typeorm.EntitySchema({
|
|
335
|
+
name: "SignalWaiterEntity",
|
|
336
|
+
target: SignalWaiterEntity,
|
|
337
|
+
tableName: "durable_signal_waiters",
|
|
338
|
+
columns: {
|
|
339
|
+
token: {
|
|
340
|
+
type: "text",
|
|
341
|
+
primary: true,
|
|
342
|
+
name: col("token")
|
|
343
|
+
},
|
|
344
|
+
runId: {
|
|
345
|
+
type: "text",
|
|
346
|
+
name: col("runId")
|
|
347
|
+
},
|
|
348
|
+
seq: {
|
|
349
|
+
type: "integer",
|
|
350
|
+
name: col("seq")
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
const bufferedSignals = new import_typeorm.EntitySchema({
|
|
355
|
+
name: "BufferedSignalEntity",
|
|
356
|
+
target: BufferedSignalEntity,
|
|
357
|
+
tableName: "durable_buffered_signals",
|
|
358
|
+
columns: {
|
|
359
|
+
// Auto-increment PK for FIFO ordering. Left as TypeORM's default increment generation so it
|
|
360
|
+
// maps to the driver-native auto-increment column (INTEGER on SQLite, BIGINT/SERIAL elsewhere).
|
|
361
|
+
id: {
|
|
362
|
+
type: Number,
|
|
363
|
+
primary: true,
|
|
364
|
+
generated: "increment",
|
|
365
|
+
name: col("id")
|
|
366
|
+
},
|
|
367
|
+
token: {
|
|
368
|
+
type: "text",
|
|
369
|
+
name: col("token")
|
|
370
|
+
},
|
|
371
|
+
payload: {
|
|
372
|
+
type: "text",
|
|
373
|
+
nullable: true,
|
|
374
|
+
name: col("payload"),
|
|
375
|
+
transformer: jsonColumnTransformer("buffered.payload")
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
return [
|
|
380
|
+
workflowRuns,
|
|
381
|
+
stepCheckpoints,
|
|
382
|
+
runAttributes,
|
|
383
|
+
signalWaiters,
|
|
384
|
+
bufferedSignals
|
|
385
|
+
];
|
|
386
|
+
}
|
|
387
|
+
__name(durableEntities, "durableEntities");
|
|
388
|
+
var ENTITIES = durableEntities();
|
|
383
389
|
|
|
384
390
|
// src/schema.ts
|
|
385
391
|
var JSON_BLOB_COLUMNS = {
|
|
@@ -397,16 +403,36 @@ var JSON_BLOB_COLUMNS = {
|
|
|
397
403
|
"events"
|
|
398
404
|
]
|
|
399
405
|
};
|
|
406
|
+
var TABLE_TO_ENTITY = {
|
|
407
|
+
durable_workflow_runs: WorkflowRunEntity,
|
|
408
|
+
durable_step_checkpoints: StepCheckpointEntity,
|
|
409
|
+
durable_run_attributes: RunAttributeEntity,
|
|
410
|
+
durable_signal_waiters: SignalWaiterEntity,
|
|
411
|
+
durable_buffered_signals: BufferedSignalEntity
|
|
412
|
+
};
|
|
413
|
+
function durableColumnResolver(dataSource) {
|
|
414
|
+
return (table, property) => {
|
|
415
|
+
const entity = TABLE_TO_ENTITY[table];
|
|
416
|
+
if (!entity) throw new Error(`durable store: unknown table "${table}"`);
|
|
417
|
+
const meta = dataSource.getMetadata(entity);
|
|
418
|
+
const column = meta.findColumnWithPropertyName(property);
|
|
419
|
+
if (!column) {
|
|
420
|
+
throw new Error(`durable store: no column for ${table}.${property} in entity metadata`);
|
|
421
|
+
}
|
|
422
|
+
return column.databaseName;
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
__name(durableColumnResolver, "durableColumnResolver");
|
|
400
426
|
function jsonBlobColumnType(isMysql) {
|
|
401
427
|
return isMysql ? "longtext" : "text";
|
|
402
428
|
}
|
|
403
429
|
__name(jsonBlobColumnType, "jsonBlobColumnType");
|
|
404
|
-
function buildWidenStatements(isMysql, quote) {
|
|
430
|
+
function buildWidenStatements(isMysql, quote, col) {
|
|
405
431
|
if (!isMysql) return [];
|
|
406
432
|
const out = [];
|
|
407
|
-
for (const [table,
|
|
408
|
-
for (const
|
|
409
|
-
out.push(`ALTER TABLE ${quote(table)} MODIFY COLUMN ${quote(col)} longtext`);
|
|
433
|
+
for (const [table, props] of Object.entries(JSON_BLOB_COLUMNS)) {
|
|
434
|
+
for (const prop of props) {
|
|
435
|
+
out.push(`ALTER TABLE ${quote(table)} MODIFY COLUMN ${quote(col(table, prop))} longtext`);
|
|
410
436
|
}
|
|
411
437
|
}
|
|
412
438
|
return out;
|
|
@@ -414,6 +440,7 @@ function buildWidenStatements(isMysql, quote) {
|
|
|
414
440
|
__name(buildWidenStatements, "buildWidenStatements");
|
|
415
441
|
async function ensureTypeOrmDurableSchema(dataSource) {
|
|
416
442
|
const q = /* @__PURE__ */ __name((id) => dataSource.driver.escape(id), "q");
|
|
443
|
+
const resolve = durableColumnResolver(dataSource);
|
|
417
444
|
const type = String(dataSource.options.type);
|
|
418
445
|
const isPg = type === "postgres" || type === "aurora-postgres";
|
|
419
446
|
const isMysql = type === "mysql" || type === "mariadb" || type === "aurora-mysql";
|
|
@@ -427,40 +454,45 @@ async function ensureTypeOrmDurableSchema(dataSource) {
|
|
|
427
454
|
const runAttributes = q("durable_run_attributes");
|
|
428
455
|
const waiters = q("durable_signal_waiters");
|
|
429
456
|
const buffered = q("durable_buffered_signals");
|
|
457
|
+
const runsCol = /* @__PURE__ */ __name((property) => q(resolve("durable_workflow_runs", property)), "runsCol");
|
|
458
|
+
const cpCol = /* @__PURE__ */ __name((property) => q(resolve("durable_step_checkpoints", property)), "cpCol");
|
|
459
|
+
const attrCol = /* @__PURE__ */ __name((property) => q(resolve("durable_run_attributes", property)), "attrCol");
|
|
460
|
+
const waiterCol = /* @__PURE__ */ __name((property) => q(resolve("durable_signal_waiters", property)), "waiterCol");
|
|
461
|
+
const bufCol = /* @__PURE__ */ __name((property) => q(resolve("durable_buffered_signals", property)), "bufCol");
|
|
430
462
|
const num = isPg ? "double precision" : isMysql ? "double" : "real";
|
|
431
|
-
const bufferedId = isSqlite ? `${
|
|
463
|
+
const bufferedId = isSqlite ? `${bufCol("id")} integer PRIMARY KEY AUTOINCREMENT` : isMysql ? `${bufCol("id")} bigint NOT NULL AUTO_INCREMENT PRIMARY KEY` : isPg ? `${bufCol("id")} bigserial PRIMARY KEY` : `${bufCol("id")} bigint NOT NULL AUTO_INCREMENT PRIMARY KEY`;
|
|
432
464
|
const tables = [
|
|
433
465
|
`CREATE TABLE IF NOT EXISTS ${runs} (
|
|
434
|
-
${
|
|
435
|
-
${
|
|
436
|
-
${
|
|
437
|
-
${
|
|
438
|
-
${
|
|
439
|
-
${
|
|
440
|
-
${
|
|
441
|
-
${
|
|
466
|
+
${runsCol("id")} ${str} PRIMARY KEY,
|
|
467
|
+
${runsCol("workflow")} ${str} NOT NULL,
|
|
468
|
+
${runsCol("workflowVersion")} ${str} NOT NULL,
|
|
469
|
+
${runsCol("status")} ${str} NOT NULL,
|
|
470
|
+
${runsCol("input")} ${txt}, ${runsCol("output")} ${txt}, ${runsCol("error")} ${txt},
|
|
471
|
+
${runsCol("wakeAt")} ${ts}, ${runsCol("lockedBy")} ${str}, ${runsCol("lockedUntil")} ${ts},
|
|
472
|
+
${runsCol("recoveryAttempts")} ${int}, ${runsCol("tags")} ${txt}, ${runsCol("searchAttributes")} ${txt},
|
|
473
|
+
${runsCol("createdAt")} ${ts} NOT NULL, ${runsCol("updatedAt")} ${ts} NOT NULL
|
|
442
474
|
)`,
|
|
443
475
|
`CREATE TABLE IF NOT EXISTS ${checkpoints} (
|
|
444
|
-
${
|
|
445
|
-
${
|
|
446
|
-
${
|
|
447
|
-
${
|
|
448
|
-
${
|
|
449
|
-
${
|
|
450
|
-
PRIMARY KEY (${
|
|
476
|
+
${cpCol("runId")} ${str} NOT NULL, ${cpCol("seq")} ${int} NOT NULL,
|
|
477
|
+
${cpCol("name")} ${str} NOT NULL, ${cpCol("kind")} ${str} NOT NULL, ${cpCol("stepId")} ${str} NOT NULL,
|
|
478
|
+
${cpCol("status")} ${str} NOT NULL, ${cpCol("input")} ${txt}, ${cpCol("output")} ${txt}, ${cpCol("error")} ${txt}, ${cpCol("events")} ${txt},
|
|
479
|
+
${cpCol("attempts")} ${int} NOT NULL, ${cpCol("workerGroup")} ${str},
|
|
480
|
+
${cpCol("wakeAt")} ${ts}, ${cpCol("enqueuedAt")} ${ts},
|
|
481
|
+
${cpCol("startedAt")} ${ts} NOT NULL, ${cpCol("finishedAt")} ${ts} NOT NULL,
|
|
482
|
+
PRIMARY KEY (${cpCol("runId")}, ${cpCol("seq")})
|
|
451
483
|
)`,
|
|
452
484
|
// Normalized search-attribute side-table: one row per (run, key) so attribute predicates push
|
|
453
485
|
// DOWN into SQL via an EXISTS join (indexed below). `key` is keyed → must be varchar on MySQL.
|
|
454
486
|
`CREATE TABLE IF NOT EXISTS ${runAttributes} (
|
|
455
|
-
${
|
|
456
|
-
${
|
|
457
|
-
PRIMARY KEY (${
|
|
487
|
+
${attrCol("runId")} ${str} NOT NULL, ${attrCol("key")} ${str} NOT NULL,
|
|
488
|
+
${attrCol("strValue")} ${str}, ${attrCol("numValue")} ${num},
|
|
489
|
+
PRIMARY KEY (${attrCol("runId")}, ${attrCol("key")})
|
|
458
490
|
)`,
|
|
459
491
|
`CREATE TABLE IF NOT EXISTS ${waiters} (
|
|
460
|
-
${
|
|
492
|
+
${waiterCol("token")} ${str} PRIMARY KEY, ${waiterCol("runId")} ${str} NOT NULL, ${waiterCol("seq")} ${int} NOT NULL
|
|
461
493
|
)`,
|
|
462
494
|
`CREATE TABLE IF NOT EXISTS ${buffered} (
|
|
463
|
-
${bufferedId}, ${
|
|
495
|
+
${bufferedId}, ${bufCol("token")} ${str} NOT NULL, ${bufCol("payload")} ${txt}
|
|
464
496
|
)`
|
|
465
497
|
];
|
|
466
498
|
const additive = {
|
|
@@ -520,18 +552,19 @@ async function ensureTypeOrmDurableSchema(dataSource) {
|
|
|
520
552
|
const runner = dataSource.createQueryRunner();
|
|
521
553
|
try {
|
|
522
554
|
for (const sql of tables) await runner.query(sql);
|
|
523
|
-
for (const [table,
|
|
555
|
+
for (const [table, props] of Object.entries(additive)) {
|
|
524
556
|
const have = await existingColumns(runner, table, {
|
|
525
557
|
isSqlite,
|
|
526
558
|
isMysql
|
|
527
559
|
});
|
|
528
|
-
for (const [
|
|
529
|
-
|
|
530
|
-
|
|
560
|
+
for (const [property, colType] of props) {
|
|
561
|
+
const column = resolve(table, property);
|
|
562
|
+
if (!have.has(column)) {
|
|
563
|
+
await runner.query(`ALTER TABLE ${q(table)} ADD COLUMN ${q(column)} ${colType}`);
|
|
531
564
|
}
|
|
532
565
|
}
|
|
533
566
|
}
|
|
534
|
-
for (const sql of buildWidenStatements(isMysql, q)) {
|
|
567
|
+
for (const sql of buildWidenStatements(isMysql, q, resolve)) {
|
|
535
568
|
try {
|
|
536
569
|
await runner.query(sql);
|
|
537
570
|
} catch {
|
|
@@ -540,26 +573,26 @@ async function ensureTypeOrmDurableSchema(dataSource) {
|
|
|
540
573
|
const indexes = [
|
|
541
574
|
[
|
|
542
575
|
"durable_runs_status_idx",
|
|
543
|
-
`${runs} (${
|
|
576
|
+
`${runs} (${runsCol("status")}, ${runsCol("wakeAt")})`
|
|
544
577
|
],
|
|
545
578
|
[
|
|
546
579
|
"durable_runs_workflow_status_idx",
|
|
547
|
-
`${runs} (${
|
|
580
|
+
`${runs} (${runsCol("workflow")}, ${runsCol("status")})`
|
|
548
581
|
],
|
|
549
582
|
// buffered signals are taken FIFO per token (smallest id) — index the token for the scan.
|
|
550
583
|
[
|
|
551
584
|
"durable_buffered_signals_token_idx",
|
|
552
|
-
`${buffered} (${
|
|
585
|
+
`${buffered} (${bufCol("token")})`
|
|
553
586
|
],
|
|
554
587
|
// Search-attribute pushdown: equality + range predicates probe by (key, value). Two composite
|
|
555
588
|
// indexes — one per typed column — so a numeric range or a string equality is an index scan.
|
|
556
589
|
[
|
|
557
590
|
"durable_run_attributes_num_idx",
|
|
558
|
-
`${runAttributes} (${
|
|
591
|
+
`${runAttributes} (${attrCol("key")}, ${attrCol("numValue")})`
|
|
559
592
|
],
|
|
560
593
|
[
|
|
561
594
|
"durable_run_attributes_str_idx",
|
|
562
|
-
`${runAttributes} (${
|
|
595
|
+
`${runAttributes} (${attrCol("key")}, ${attrCol("strValue")})`
|
|
563
596
|
]
|
|
564
597
|
];
|
|
565
598
|
for (const [name, target] of indexes) {
|
|
@@ -658,6 +691,20 @@ var TypeOrmStateStore = class {
|
|
|
658
691
|
});
|
|
659
692
|
return e ? fromRunEntity(e) : null;
|
|
660
693
|
}
|
|
694
|
+
async deleteRun(runId) {
|
|
695
|
+
await this.checkpoints().delete({
|
|
696
|
+
runId
|
|
697
|
+
});
|
|
698
|
+
await this.waiters().delete({
|
|
699
|
+
runId
|
|
700
|
+
});
|
|
701
|
+
await this.attributes().delete({
|
|
702
|
+
runId
|
|
703
|
+
});
|
|
704
|
+
await this.runs().delete({
|
|
705
|
+
id: runId
|
|
706
|
+
});
|
|
707
|
+
}
|
|
661
708
|
async getCheckpoint(runId, seq) {
|
|
662
709
|
const e = await this.checkpoints().findOneBy({
|
|
663
710
|
runId,
|
|
@@ -761,13 +808,21 @@ var TypeOrmStateStore = class {
|
|
|
761
808
|
/** Add one attribute predicate to `qb` as an EXISTS subquery on the side-table. `i` namespaces the
|
|
762
809
|
* bind params so multiple ANDed filters don't collide. */
|
|
763
810
|
applyAttributeExists(qb, f, i) {
|
|
764
|
-
const
|
|
811
|
+
const valueProperty = (0, import_nestjs_durable_core.attributeColumnFor)(f);
|
|
765
812
|
const cmp = (0, import_nestjs_durable_core.sqlComparator)(f.op);
|
|
766
813
|
const keyParam = `attrKey${i}`;
|
|
767
814
|
const valParam = `attrVal${i}`;
|
|
815
|
+
const resolve = durableColumnResolver(this.dataSource);
|
|
816
|
+
const q = this.idQuote();
|
|
817
|
+
const wrap = /* @__PURE__ */ __name((name) => `${q}${name}${q}`, "wrap");
|
|
818
|
+
const runIdCol = wrap(resolve("durable_run_attributes", "runId"));
|
|
819
|
+
const keyCol = wrap(resolve("durable_run_attributes", "key"));
|
|
820
|
+
const valueCol = wrap(resolve("durable_run_attributes", valueProperty));
|
|
821
|
+
const runPkCol = wrap(resolve("durable_workflow_runs", "id"));
|
|
822
|
+
const table = wrap("durable_run_attributes");
|
|
768
823
|
const a = `a${i}`;
|
|
769
|
-
const sql = `EXISTS (SELECT 1 FROM
|
|
770
|
-
qb.andWhere(sql
|
|
824
|
+
const sql = `EXISTS (SELECT 1 FROM ${table} ${a} WHERE ${a}.${runIdCol} = r.${runPkCol} AND ${a}.${keyCol} = :${keyParam} AND ${a}.${valueCol} ${cmp} :${valParam})`;
|
|
825
|
+
qb.andWhere(sql, {
|
|
771
826
|
[keyParam]: f.key,
|
|
772
827
|
[valParam]: (0, import_nestjs_durable_core.attributeOperand)(f)
|
|
773
828
|
});
|
|
@@ -971,6 +1026,9 @@ __name(fromCheckpointEntity, "fromCheckpointEntity");
|
|
|
971
1026
|
TypeOrmStateStore,
|
|
972
1027
|
WorkflowRunEntity,
|
|
973
1028
|
buildWidenStatements,
|
|
1029
|
+
columnNamer,
|
|
1030
|
+
durableColumnResolver,
|
|
1031
|
+
durableEntities,
|
|
974
1032
|
ensureTypeOrmDurableSchema,
|
|
975
1033
|
jsonBlobColumnType,
|
|
976
1034
|
parseJsonColumn
|