@dudousxd/nestjs-durable-store-mikro-orm 0.21.0 → 0.23.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 +117 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +49 -3
- package/dist/index.d.ts +49 -3
- package/dist/index.js +107 -17
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -22,13 +22,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
22
22
|
var index_exports = {};
|
|
23
23
|
__export(index_exports, {
|
|
24
24
|
BufferedEventEntity: () => BufferedEventEntity,
|
|
25
|
+
BufferedEventRepository: () => BufferedEventRepository,
|
|
25
26
|
BufferedSignalEntity: () => BufferedSignalEntity,
|
|
27
|
+
BufferedSignalRepository: () => BufferedSignalRepository,
|
|
26
28
|
ENTITIES: () => ENTITIES,
|
|
27
29
|
MikroOrmStateStore: () => MikroOrmStateStore,
|
|
28
30
|
RunAttributeEntity: () => RunAttributeEntity,
|
|
31
|
+
RunAttributeRepository: () => RunAttributeRepository,
|
|
29
32
|
SignalWaiterEntity: () => SignalWaiterEntity,
|
|
33
|
+
SignalWaiterRepository: () => SignalWaiterRepository,
|
|
30
34
|
StepCheckpointEntity: () => StepCheckpointEntity,
|
|
35
|
+
StepCheckpointRepository: () => StepCheckpointRepository,
|
|
31
36
|
WorkflowRunEntity: () => WorkflowRunEntity,
|
|
37
|
+
WorkflowRunRepository: () => WorkflowRunRepository,
|
|
32
38
|
durableEntities: () => durableEntities,
|
|
33
39
|
durableManagedTables: () => durableManagedTables,
|
|
34
40
|
ensureMikroOrmDurableSchema: () => ensureMikroOrmDurableSchema
|
|
@@ -36,7 +42,42 @@ __export(index_exports, {
|
|
|
36
42
|
module.exports = __toCommonJS(index_exports);
|
|
37
43
|
|
|
38
44
|
// src/entities.ts
|
|
45
|
+
var import_core2 = require("@mikro-orm/core");
|
|
46
|
+
|
|
47
|
+
// src/repositories.ts
|
|
39
48
|
var import_core = require("@mikro-orm/core");
|
|
49
|
+
var WorkflowRunRepository = class extends import_core.EntityRepository {
|
|
50
|
+
static {
|
|
51
|
+
__name(this, "WorkflowRunRepository");
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
var StepCheckpointRepository = class extends import_core.EntityRepository {
|
|
55
|
+
static {
|
|
56
|
+
__name(this, "StepCheckpointRepository");
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
var RunAttributeRepository = class extends import_core.EntityRepository {
|
|
60
|
+
static {
|
|
61
|
+
__name(this, "RunAttributeRepository");
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var SignalWaiterRepository = class extends import_core.EntityRepository {
|
|
65
|
+
static {
|
|
66
|
+
__name(this, "SignalWaiterRepository");
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
var BufferedSignalRepository = class extends import_core.EntityRepository {
|
|
70
|
+
static {
|
|
71
|
+
__name(this, "BufferedSignalRepository");
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
var BufferedEventRepository = class extends import_core.EntityRepository {
|
|
75
|
+
static {
|
|
76
|
+
__name(this, "BufferedEventRepository");
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// src/entities.ts
|
|
40
81
|
function snakeCase(property) {
|
|
41
82
|
return property.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
|
|
42
83
|
}
|
|
@@ -51,6 +92,7 @@ var WorkflowRunEntity = class {
|
|
|
51
92
|
static {
|
|
52
93
|
__name(this, "WorkflowRunEntity");
|
|
53
94
|
}
|
|
95
|
+
[import_core2.EntityRepositoryType];
|
|
54
96
|
id;
|
|
55
97
|
workflow;
|
|
56
98
|
workflowVersion;
|
|
@@ -75,6 +117,7 @@ var StepCheckpointEntity = class {
|
|
|
75
117
|
static {
|
|
76
118
|
__name(this, "StepCheckpointEntity");
|
|
77
119
|
}
|
|
120
|
+
[import_core2.EntityRepositoryType];
|
|
78
121
|
runId;
|
|
79
122
|
seq;
|
|
80
123
|
name;
|
|
@@ -97,6 +140,7 @@ var RunAttributeEntity = class {
|
|
|
97
140
|
static {
|
|
98
141
|
__name(this, "RunAttributeEntity");
|
|
99
142
|
}
|
|
143
|
+
[import_core2.EntityRepositoryType];
|
|
100
144
|
runId;
|
|
101
145
|
key;
|
|
102
146
|
strValue;
|
|
@@ -106,6 +150,7 @@ var SignalWaiterEntity = class {
|
|
|
106
150
|
static {
|
|
107
151
|
__name(this, "SignalWaiterEntity");
|
|
108
152
|
}
|
|
153
|
+
[import_core2.EntityRepositoryType];
|
|
109
154
|
token;
|
|
110
155
|
runId;
|
|
111
156
|
seq;
|
|
@@ -115,6 +160,7 @@ var BufferedSignalEntity = class {
|
|
|
115
160
|
static {
|
|
116
161
|
__name(this, "BufferedSignalEntity");
|
|
117
162
|
}
|
|
163
|
+
[import_core2.EntityRepositoryType];
|
|
118
164
|
id;
|
|
119
165
|
token;
|
|
120
166
|
payload;
|
|
@@ -123,6 +169,7 @@ var BufferedEventEntity = class {
|
|
|
123
169
|
static {
|
|
124
170
|
__name(this, "BufferedEventEntity");
|
|
125
171
|
}
|
|
172
|
+
[import_core2.EntityRepositoryType];
|
|
126
173
|
id;
|
|
127
174
|
name;
|
|
128
175
|
payload;
|
|
@@ -137,9 +184,12 @@ function namespaceFilterCond(args) {
|
|
|
137
184
|
__name(namespaceFilterCond, "namespaceFilterCond");
|
|
138
185
|
function durableEntities(options = {}) {
|
|
139
186
|
const col = columnNamer(options.naming ?? "snake_case");
|
|
140
|
-
const workflowRuns = new
|
|
187
|
+
const workflowRuns = new import_core2.EntitySchema({
|
|
141
188
|
class: WorkflowRunEntity,
|
|
142
189
|
tableName: "durable_workflow_runs",
|
|
190
|
+
// Wired per schema rather than once on the class: `durableEntities` can be called again with a
|
|
191
|
+
// different `naming`, and each call builds a distinct EntitySchema over the same class.
|
|
192
|
+
repository: /* @__PURE__ */ __name(() => WorkflowRunRepository, "repository"),
|
|
143
193
|
// Global filter: confines every read to the tenant's namespace when the store is scoped.
|
|
144
194
|
// The `cond` returns `{}` (no-op) when the `namespace` arg is `undefined`, so an unscoped
|
|
145
195
|
// (operator / control-plane) store sees all rows unchanged — existing behaviour is preserved.
|
|
@@ -300,9 +350,10 @@ function durableEntities(options = {}) {
|
|
|
300
350
|
}
|
|
301
351
|
}
|
|
302
352
|
});
|
|
303
|
-
const stepCheckpoints = new
|
|
353
|
+
const stepCheckpoints = new import_core2.EntitySchema({
|
|
304
354
|
class: StepCheckpointEntity,
|
|
305
355
|
tableName: "durable_step_checkpoints",
|
|
356
|
+
repository: /* @__PURE__ */ __name(() => StepCheckpointRepository, "repository"),
|
|
306
357
|
properties: {
|
|
307
358
|
runId: {
|
|
308
359
|
type: "string",
|
|
@@ -388,9 +439,10 @@ function durableEntities(options = {}) {
|
|
|
388
439
|
}
|
|
389
440
|
}
|
|
390
441
|
});
|
|
391
|
-
const runAttributes = new
|
|
442
|
+
const runAttributes = new import_core2.EntitySchema({
|
|
392
443
|
class: RunAttributeEntity,
|
|
393
444
|
tableName: "durable_run_attributes",
|
|
445
|
+
repository: /* @__PURE__ */ __name(() => RunAttributeRepository, "repository"),
|
|
394
446
|
// The search-attribute EXISTS join (see the class docstring) pushes equality/range predicates down
|
|
395
447
|
// onto `(key, numValue)` / `(key, strValue)`; mirror the Prisma adapter so those scans stay indexed.
|
|
396
448
|
indexes: [
|
|
@@ -433,9 +485,10 @@ function durableEntities(options = {}) {
|
|
|
433
485
|
}
|
|
434
486
|
}
|
|
435
487
|
});
|
|
436
|
-
const signalWaiters = new
|
|
488
|
+
const signalWaiters = new import_core2.EntitySchema({
|
|
437
489
|
class: SignalWaiterEntity,
|
|
438
490
|
tableName: "durable_signal_waiters",
|
|
491
|
+
repository: /* @__PURE__ */ __name(() => SignalWaiterRepository, "repository"),
|
|
439
492
|
properties: {
|
|
440
493
|
token: {
|
|
441
494
|
type: "string",
|
|
@@ -460,9 +513,10 @@ function durableEntities(options = {}) {
|
|
|
460
513
|
}
|
|
461
514
|
}
|
|
462
515
|
});
|
|
463
|
-
const bufferedSignals = new
|
|
516
|
+
const bufferedSignals = new import_core2.EntitySchema({
|
|
464
517
|
class: BufferedSignalEntity,
|
|
465
518
|
tableName: "durable_buffered_signals",
|
|
519
|
+
repository: /* @__PURE__ */ __name(() => BufferedSignalRepository, "repository"),
|
|
466
520
|
properties: {
|
|
467
521
|
id: {
|
|
468
522
|
type: "integer",
|
|
@@ -482,9 +536,10 @@ function durableEntities(options = {}) {
|
|
|
482
536
|
}
|
|
483
537
|
}
|
|
484
538
|
});
|
|
485
|
-
const bufferedEvents = new
|
|
539
|
+
const bufferedEvents = new import_core2.EntitySchema({
|
|
486
540
|
class: BufferedEventEntity,
|
|
487
541
|
tableName: "durable_buffered_events",
|
|
542
|
+
repository: /* @__PURE__ */ __name(() => BufferedEventRepository, "repository"),
|
|
488
543
|
// `(name, publishedAt)` serves both `listBufferedEvents`'s name-scoped scan and its oldest-first
|
|
489
544
|
// ordering in one index.
|
|
490
545
|
indexes: [
|
|
@@ -533,6 +588,7 @@ var ENTITIES = durableEntities();
|
|
|
533
588
|
|
|
534
589
|
// src/mikro-orm-state-store.ts
|
|
535
590
|
var import_nestjs_durable_core = require("@dudousxd/nestjs-durable-core");
|
|
591
|
+
var import_core3 = require("@mikro-orm/core");
|
|
536
592
|
|
|
537
593
|
// src/schema.ts
|
|
538
594
|
var import_node_crypto = require("crypto");
|
|
@@ -1010,8 +1066,10 @@ var MikroOrmStateStore = class _MikroOrmStateStore {
|
|
|
1010
1066
|
});
|
|
1011
1067
|
return affected === 1;
|
|
1012
1068
|
}
|
|
1013
|
-
|
|
1014
|
-
|
|
1069
|
+
/** The `where` every run query shares — {@link listRuns} pages it, {@link runFacets} groups it.
|
|
1070
|
+
* Only the predicates MikroORM can express declaratively; `tag`/`attributes` need raw SQL and are
|
|
1071
|
+
* applied by the QueryBuilder path in both callers. */
|
|
1072
|
+
runWhere(query) {
|
|
1015
1073
|
const where = {};
|
|
1016
1074
|
if (query.workflow) where.workflow = query.workflow;
|
|
1017
1075
|
if (query.namespace !== void 0) where.namespace = query.namespace;
|
|
@@ -1034,23 +1092,16 @@ var MikroOrmStateStore = class _MikroOrmStateStore {
|
|
|
1034
1092
|
$in: query.statuses
|
|
1035
1093
|
};
|
|
1036
1094
|
}
|
|
1095
|
+
return where;
|
|
1096
|
+
}
|
|
1097
|
+
async listRuns(query) {
|
|
1098
|
+
const em = this.fork();
|
|
1099
|
+
const where = this.runWhere(query);
|
|
1037
1100
|
const orderBy = {
|
|
1038
1101
|
createdAt: "desc"
|
|
1039
1102
|
};
|
|
1040
1103
|
if (query.tag || query.attributes?.length) {
|
|
1041
|
-
|
|
1042
|
-
const quote = this.idQuote(em);
|
|
1043
|
-
const cols = this.attributeColumns(em);
|
|
1044
|
-
const qb = em.createQueryBuilder(WorkflowRunEntity, "r").where(where).orderBy(orderBy);
|
|
1045
|
-
if (query.tag) {
|
|
1046
|
-
const tagsCol = this.tagsColumn(em);
|
|
1047
|
-
const pattern = `%"${query.tag.replace(/'/g, "''")}"%`;
|
|
1048
|
-
const colExpr = this.jsonAsText(em, `${quote("r")}.${quote(tagsCol)}`);
|
|
1049
|
-
qb.andWhere(`${colExpr} LIKE '${pattern}'`);
|
|
1050
|
-
}
|
|
1051
|
-
for (const f of query.attributes ?? []) {
|
|
1052
|
-
qb.andWhere(this.attributeExistsSql(f, quote, "r", cols));
|
|
1053
|
-
}
|
|
1104
|
+
const qb = this.runQueryBuilder(em, query, where).orderBy(orderBy);
|
|
1054
1105
|
if (query.limit != null) qb.limit(query.limit);
|
|
1055
1106
|
if (query.offset != null) qb.offset(query.offset);
|
|
1056
1107
|
const rows2 = await qb.getResultList();
|
|
@@ -1067,6 +1118,45 @@ var MikroOrmStateStore = class _MikroOrmStateStore {
|
|
|
1067
1118
|
});
|
|
1068
1119
|
return rows.map(fromRunEntity);
|
|
1069
1120
|
}
|
|
1121
|
+
/** A QueryBuilder over `durable_workflow_runs` (root alias `r`) carrying `where` plus the two
|
|
1122
|
+
* predicates only raw SQL can express — the `tag` JSON LIKE and one EXISTS per attribute filter.
|
|
1123
|
+
* Shared so a facet count and the page it labels are taken over the SAME set. */
|
|
1124
|
+
runQueryBuilder(em, query, where) {
|
|
1125
|
+
if (this.scopeNamespace !== void 0) where.namespace = this.scopeNamespace;
|
|
1126
|
+
const quote = this.idQuote(em);
|
|
1127
|
+
const cols = this.attributeColumns(em);
|
|
1128
|
+
const qb = em.createQueryBuilder(WorkflowRunEntity, "r").where(where);
|
|
1129
|
+
if (query.tag) {
|
|
1130
|
+
const tagsCol = this.tagsColumn(em);
|
|
1131
|
+
const pattern = `%"${query.tag.replace(/'/g, "''")}"%`;
|
|
1132
|
+
const colExpr = this.jsonAsText(em, `${quote("r")}.${quote(tagsCol)}`);
|
|
1133
|
+
qb.andWhere(`${colExpr} LIKE '${pattern}'`);
|
|
1134
|
+
}
|
|
1135
|
+
for (const f of query.attributes ?? []) {
|
|
1136
|
+
qb.andWhere(this.attributeExistsSql(f, quote, "r", cols));
|
|
1137
|
+
}
|
|
1138
|
+
return qb;
|
|
1139
|
+
}
|
|
1140
|
+
/** `GROUP BY status, origin` over the same predicates {@link listRuns} pages — one aggregate, so a
|
|
1141
|
+
* console can show whole-set counts next to a bounded page instead of downloading every run to
|
|
1142
|
+
* count them in the browser. */
|
|
1143
|
+
async runFacets(query) {
|
|
1144
|
+
const em = this.fork();
|
|
1145
|
+
const meta = em.getMetadata().get(WorkflowRunEntity);
|
|
1146
|
+
const statusCol = meta.properties.status?.fieldNames?.[0] ?? "status";
|
|
1147
|
+
const originCol = meta.properties.origin?.fieldNames?.[0] ?? "origin";
|
|
1148
|
+
const rows = await this.runQueryBuilder(em, query, this.runWhere(query)).select([
|
|
1149
|
+
`r.${statusCol}`,
|
|
1150
|
+
`r.${originCol}`
|
|
1151
|
+
]).addSelect((0, import_core3.raw)("count(*) as count")).groupBy([
|
|
1152
|
+
`r.${statusCol}`,
|
|
1153
|
+
`r.${originCol}`
|
|
1154
|
+
]).execute();
|
|
1155
|
+
return (0, import_nestjs_durable_core.mergeRunFacetRows)(rows.map((r) => ({
|
|
1156
|
+
...r,
|
|
1157
|
+
count: Number(r.count)
|
|
1158
|
+
})));
|
|
1159
|
+
}
|
|
1070
1160
|
/** One attribute predicate as a raw EXISTS subquery on the side-table, correlated to the outer run
|
|
1071
1161
|
* alias. `<>` (ne) also excludes runs where the attribute is absent (missing-key-never-matches):
|
|
1072
1162
|
* EXISTS already requires a present row, so EXISTS(... <> ...) is exactly ne-with-present. Numeric
|
|
@@ -1361,13 +1451,19 @@ __name(fromCheckpointEntity, "fromCheckpointEntity");
|
|
|
1361
1451
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1362
1452
|
0 && (module.exports = {
|
|
1363
1453
|
BufferedEventEntity,
|
|
1454
|
+
BufferedEventRepository,
|
|
1364
1455
|
BufferedSignalEntity,
|
|
1456
|
+
BufferedSignalRepository,
|
|
1365
1457
|
ENTITIES,
|
|
1366
1458
|
MikroOrmStateStore,
|
|
1367
1459
|
RunAttributeEntity,
|
|
1460
|
+
RunAttributeRepository,
|
|
1368
1461
|
SignalWaiterEntity,
|
|
1462
|
+
SignalWaiterRepository,
|
|
1369
1463
|
StepCheckpointEntity,
|
|
1464
|
+
StepCheckpointRepository,
|
|
1370
1465
|
WorkflowRunEntity,
|
|
1466
|
+
WorkflowRunRepository,
|
|
1371
1467
|
durableEntities,
|
|
1372
1468
|
durableManagedTables,
|
|
1373
1469
|
ensureMikroOrmDurableSchema
|