@dudousxd/nestjs-durable-store-mikro-orm 0.19.0 → 0.21.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 CHANGED
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  // src/index.ts
22
22
  var index_exports = {};
23
23
  __export(index_exports, {
24
+ BufferedEventEntity: () => BufferedEventEntity,
24
25
  BufferedSignalEntity: () => BufferedSignalEntity,
25
26
  ENTITIES: () => ENTITIES,
26
27
  MikroOrmStateStore: () => MikroOrmStateStore,
@@ -66,6 +67,7 @@ var WorkflowRunEntity = class {
66
67
  searchAttributes;
67
68
  priority;
68
69
  namespace;
70
+ origin;
69
71
  createdAt;
70
72
  updatedAt;
71
73
  };
@@ -117,6 +119,15 @@ var BufferedSignalEntity = class {
117
119
  token;
118
120
  payload;
119
121
  };
122
+ var BufferedEventEntity = class {
123
+ static {
124
+ __name(this, "BufferedEventEntity");
125
+ }
126
+ id;
127
+ name;
128
+ payload;
129
+ publishedAt;
130
+ };
120
131
  function namespaceFilterCond(args) {
121
132
  if (args?.namespace === void 0) return {};
122
133
  return {
@@ -254,6 +265,31 @@ function durableEntities(options = {}) {
254
265
  default: "default",
255
266
  fieldName: col("namespace")
256
267
  },
268
+ // Which library/module registered the workflow this run belongs to (e.g.
269
+ // `@dudousxd/nestjs-catalog-pipeline`), derived at registration time — never caller input.
270
+ //
271
+ // NULLABLE WITH NO DEFAULT, deliberately unlike `namespace` above. `namespace` can honestly
272
+ // default a pre-existing row to `'default'` (that IS the namespace an unscoped engine ran it
273
+ // in); an origin cannot be reconstructed after the fact, so a row written before this column
274
+ // existed must read back as `undefined` = "unknown". Stamping it `'app'`/`'unknown'` would be
275
+ // indistinguishable from a real registration in the dashboard's facet — a wrong origin is worse
276
+ // than an absent one. Two MikroORM specifics reinforce it: a `default` here would NOT be
277
+ // back-filled onto existing rows anyway (the DDL default only applies to new inserts, and a
278
+ // TypeScript field initialiser never runs for rows the ORM did not create), so a default would
279
+ // buy nothing but a lie for future rows.
280
+ //
281
+ // No index, unlike `namespace`. That one is on the HOT path — every poll tick filters
282
+ // `listPendingRuns`/`listDueTimers`/`listIncompleteRuns` by it, hence
283
+ // `durable_workflow_runs_namespace_status_idx`. Nothing filters by `origin` except the
284
+ // dashboard's `listRuns`, where it is ANDed with the `status`/`workflow` predicates that
285
+ // `durable_workflow_runs_status_wake_at_idx` / `..._workflow_status_idx` already bound. If a
286
+ // deployment ever makes origin-filtered listings hot, add the composite index in your own
287
+ // migration rather than here.
288
+ origin: {
289
+ type: "string",
290
+ nullable: true,
291
+ fieldName: col("origin")
292
+ },
257
293
  createdAt: {
258
294
  type: "Date",
259
295
  fieldName: col("createdAt")
@@ -446,12 +482,50 @@ function durableEntities(options = {}) {
446
482
  }
447
483
  }
448
484
  });
485
+ const bufferedEvents = new import_core.EntitySchema({
486
+ class: BufferedEventEntity,
487
+ tableName: "durable_buffered_events",
488
+ // `(name, publishedAt)` serves both `listBufferedEvents`'s name-scoped scan and its oldest-first
489
+ // ordering in one index.
490
+ indexes: [
491
+ {
492
+ name: "durable_buffered_events_name_published_at_idx",
493
+ properties: [
494
+ "name",
495
+ "publishedAt"
496
+ ]
497
+ }
498
+ ],
499
+ properties: {
500
+ // Caller-minted uuid (engine.publishEvent), not autoincrement — removeBufferedEvent targets it
501
+ // directly and needs to be handed the SAME id it was buffered with.
502
+ id: {
503
+ type: "string",
504
+ primary: true,
505
+ fieldName: col("id")
506
+ },
507
+ name: {
508
+ type: "string",
509
+ fieldName: col("name")
510
+ },
511
+ payload: {
512
+ type: "json",
513
+ nullable: true,
514
+ fieldName: col("payload")
515
+ },
516
+ publishedAt: {
517
+ type: "Date",
518
+ fieldName: col("publishedAt")
519
+ }
520
+ }
521
+ });
449
522
  return [
450
523
  workflowRuns,
451
524
  stepCheckpoints,
452
525
  runAttributes,
453
526
  signalWaiters,
454
- bufferedSignals
527
+ bufferedSignals,
528
+ bufferedEvents
455
529
  ];
456
530
  }
457
531
  __name(durableEntities, "durableEntities");
@@ -467,7 +541,8 @@ var DURABLE_TABLE_NAMES = /* @__PURE__ */ new Set([
467
541
  "durable_step_checkpoints",
468
542
  "durable_run_attributes",
469
543
  "durable_signal_waiters",
470
- "durable_buffered_signals"
544
+ "durable_buffered_signals",
545
+ "durable_buffered_events"
471
546
  ]);
472
547
  function durableManagedTables() {
473
548
  return [
@@ -940,6 +1015,7 @@ var MikroOrmStateStore = class _MikroOrmStateStore {
940
1015
  const where = {};
941
1016
  if (query.workflow) where.workflow = query.workflow;
942
1017
  if (query.namespace !== void 0) where.namespace = query.namespace;
1018
+ if (query.origin !== void 0) where.origin = query.origin;
943
1019
  if (query.status && query.statuses) {
944
1020
  where.$and = [
945
1021
  {
@@ -1155,6 +1231,39 @@ var MikroOrmStateStore = class _MikroOrmStateStore {
1155
1231
  payload
1156
1232
  };
1157
1233
  }
1234
+ async bufferEvent(input) {
1235
+ const em = this.fork();
1236
+ const e = new BufferedEventEntity();
1237
+ e.id = input.id;
1238
+ e.name = input.name;
1239
+ e.payload = input.payload ?? null;
1240
+ e.publishedAt = new Date(input.publishedAt);
1241
+ em.persist(e);
1242
+ await em.flush();
1243
+ }
1244
+ async listBufferedEvents(name, limit) {
1245
+ const em = this.fork();
1246
+ const rows = await em.find(BufferedEventEntity, {
1247
+ name
1248
+ }, {
1249
+ orderBy: {
1250
+ publishedAt: "asc"
1251
+ },
1252
+ limit
1253
+ });
1254
+ return rows.map((e) => ({
1255
+ id: e.id,
1256
+ payload: e.payload ?? void 0,
1257
+ publishedAt: e.publishedAt.getTime()
1258
+ }));
1259
+ }
1260
+ async removeBufferedEvent(id) {
1261
+ const em = this.fork();
1262
+ const affected = await em.nativeDelete(BufferedEventEntity, {
1263
+ id
1264
+ });
1265
+ return affected > 0;
1266
+ }
1158
1267
  };
1159
1268
  function toRunEntity(run) {
1160
1269
  const e = new WorkflowRunEntity();
@@ -1174,6 +1283,7 @@ function toRunEntity(run) {
1174
1283
  e.searchAttributes = run.searchAttributes ?? null;
1175
1284
  e.priority = run.priority ?? null;
1176
1285
  e.namespace = run.namespace ?? "default";
1286
+ e.origin = run.origin ?? null;
1177
1287
  e.createdAt = run.createdAt;
1178
1288
  e.updatedAt = run.updatedAt;
1179
1289
  return e;
@@ -1197,6 +1307,8 @@ function fromRunEntity(e) {
1197
1307
  searchAttributes: e.searchAttributes ?? void 0,
1198
1308
  priority: e.priority ?? void 0,
1199
1309
  namespace: e.namespace,
1310
+ // NULL (a row written before the column existed) surfaces as `undefined` = unknown origin.
1311
+ origin: e.origin ?? void 0,
1200
1312
  createdAt: e.createdAt,
1201
1313
  updatedAt: e.updatedAt
1202
1314
  };
@@ -1248,6 +1360,7 @@ function fromCheckpointEntity(e) {
1248
1360
  __name(fromCheckpointEntity, "fromCheckpointEntity");
1249
1361
  // Annotate the CommonJS export names for ESM import in node:
1250
1362
  0 && (module.exports = {
1363
+ BufferedEventEntity,
1251
1364
  BufferedSignalEntity,
1252
1365
  ENTITIES,
1253
1366
  MikroOrmStateStore,