@pattern-stack/codegen 0.19.0 → 0.20.1

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.
Files changed (125) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/consumer-skills/events/authoring-events.md +31 -0
  3. package/dist/{chunk-Z7PQCAVK.js → chunk-4OC5MSHO.js} +50 -4
  4. package/dist/chunk-4OC5MSHO.js.map +1 -0
  5. package/dist/{chunk-7OVCARTQ.js → chunk-5RT7JGKT.js} +4 -4
  6. package/dist/{chunk-AZLUWG5S.js → chunk-AJILKWGO.js} +9 -9
  7. package/dist/{chunk-SNH35CNA.js → chunk-AODME4YK.js} +10 -10
  8. package/dist/{chunk-PKDS6QIJ.js → chunk-ATVGYF3D.js} +7 -7
  9. package/dist/{chunk-4MVGAMUA.js → chunk-BK5ICA2F.js} +4 -4
  10. package/dist/{chunk-2TVVBC53.js → chunk-BORNCTH3.js} +2 -2
  11. package/dist/{chunk-J7JMVS2B.js → chunk-CZQUOIDY.js} +4 -4
  12. package/dist/{chunk-V4AF6DI4.js → chunk-DUBZOXJC.js} +9 -2
  13. package/dist/{chunk-V4AF6DI4.js.map → chunk-DUBZOXJC.js.map} +1 -1
  14. package/dist/{chunk-VQOAATIG.js → chunk-DUMI2J5M.js} +4 -4
  15. package/dist/chunk-DUUCU77W.js +211 -0
  16. package/dist/chunk-DUUCU77W.js.map +1 -0
  17. package/dist/{chunk-OFRRBC7M.js → chunk-E2BRT5IB.js} +15 -1
  18. package/dist/chunk-E2BRT5IB.js.map +1 -0
  19. package/dist/{chunk-XKWOJZZ4.js → chunk-E45CSC33.js} +2 -2
  20. package/dist/{chunk-B34G6PHD.js → chunk-HCAKMT64.js} +77 -10
  21. package/dist/chunk-HCAKMT64.js.map +1 -0
  22. package/dist/{chunk-43SBT72G.js → chunk-I6UXRJ3Q.js} +4 -4
  23. package/dist/{chunk-GM3RMJIJ.js → chunk-INO47JXD.js} +3 -3
  24. package/dist/{chunk-BGULBWKJ.js → chunk-JOBQ6RUU.js} +1 -1
  25. package/dist/chunk-JOBQ6RUU.js.map +1 -0
  26. package/dist/{chunk-F7KN3U6U.js → chunk-KK5A7B2T.js} +27 -1
  27. package/dist/chunk-KK5A7B2T.js.map +1 -0
  28. package/dist/{chunk-65MO75WM.js → chunk-M3TIZGIB.js} +9 -9
  29. package/dist/{chunk-E6PLM6QG.js → chunk-MB5VVG4Z.js} +8 -8
  30. package/dist/{chunk-K2I6XIK5.js → chunk-MVKW2BCR.js} +2 -2
  31. package/dist/{chunk-VDL5CJ5C.js → chunk-P7EZCTIN.js} +8 -8
  32. package/dist/{chunk-R6F6KFIL.js → chunk-SGSWVNNB.js} +7 -7
  33. package/dist/chunk-SYVZ4MD2.js +1 -0
  34. package/dist/{chunk-235ZMMJR.js → chunk-SZYZ4SHF.js} +6 -6
  35. package/dist/{chunk-7LKAMLV4.js → chunk-T6SCOJF4.js} +4 -4
  36. package/dist/{chunk-OZEPJGMA.js → chunk-VOYFPR3S.js} +54 -6
  37. package/dist/chunk-VOYFPR3S.js.map +1 -0
  38. package/dist/{chunk-CLWBNXKF.js → chunk-W2UIDI3R.js} +4 -4
  39. package/dist/runtime/subsystems/analytics/analytics.module.js +2 -2
  40. package/dist/runtime/subsystems/analytics/index.js +4 -4
  41. package/dist/runtime/subsystems/auth/auth.module.js +2 -2
  42. package/dist/runtime/subsystems/auth/index.js +7 -7
  43. package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js +3 -3
  44. package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.js +4 -4
  45. package/dist/runtime/subsystems/bridge/bridge-delivery.schema.js +2 -2
  46. package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js +8 -8
  47. package/dist/runtime/subsystems/bridge/bridge.module.js +19 -19
  48. package/dist/runtime/subsystems/bridge/event-flow.service.js +2 -2
  49. package/dist/runtime/subsystems/bridge/index.js +27 -27
  50. package/dist/runtime/subsystems/events/domain-events.schema.js +1 -1
  51. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.d.ts +19 -32
  52. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +4 -4
  53. package/dist/runtime/subsystems/events/event-bus.memory-backend.d.ts +18 -1
  54. package/dist/runtime/subsystems/events/event-bus.memory-backend.js +2 -2
  55. package/dist/runtime/subsystems/events/event-bus.protocol.d.ts +45 -1
  56. package/dist/runtime/subsystems/events/event-scheduler.d.ts +96 -0
  57. package/dist/runtime/subsystems/events/event-scheduler.js +25 -0
  58. package/dist/runtime/subsystems/events/event-scheduler.js.map +1 -0
  59. package/dist/runtime/subsystems/events/events-errors.d.ts +12 -1
  60. package/dist/runtime/subsystems/events/events-errors.js +5 -3
  61. package/dist/runtime/subsystems/events/events.module.d.ts +41 -2
  62. package/dist/runtime/subsystems/events/events.module.js +12 -9
  63. package/dist/runtime/subsystems/events/generated/bus.js +3 -3
  64. package/dist/runtime/subsystems/events/generated/index.js +3 -3
  65. package/dist/runtime/subsystems/events/generated/registry.d.ts +6 -0
  66. package/dist/runtime/subsystems/events/generated/registry.js +1 -1
  67. package/dist/runtime/subsystems/events/index.d.ts +4 -3
  68. package/dist/runtime/subsystems/events/index.js +39 -15
  69. package/dist/runtime/subsystems/index.d.ts +1 -0
  70. package/dist/runtime/subsystems/index.js +99 -98
  71. package/dist/runtime/subsystems/integration/build-change-source.js +2 -2
  72. package/dist/runtime/subsystems/integration/index.js +36 -36
  73. package/dist/runtime/subsystems/integration/integration.module.js +4 -4
  74. package/dist/runtime/subsystems/jobs/index.js +23 -23
  75. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js +3 -3
  76. package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js +3 -3
  77. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js +2 -2
  78. package/dist/runtime/subsystems/jobs/job-worker.js +3 -3
  79. package/dist/runtime/subsystems/jobs/job-worker.module.js +9 -9
  80. package/dist/runtime/subsystems/jobs/jobs-domain.module.js +7 -7
  81. package/dist/runtime/subsystems/observability/index.js +3 -3
  82. package/dist/runtime/subsystems/observability/observability.module.js +3 -3
  83. package/dist/runtime/subsystems/observability/observability.service.js +2 -2
  84. package/dist/runtime/subsystems/storage/index.js +4 -4
  85. package/dist/runtime/subsystems/storage/storage.module.js +2 -2
  86. package/dist/src/cli/index.js +38 -15
  87. package/dist/src/cli/index.js.map +1 -1
  88. package/dist/src/index.js +12 -12
  89. package/package.json +1 -1
  90. package/runtime/subsystems/events/domain-events.schema.ts +16 -0
  91. package/runtime/subsystems/events/event-bus.drizzle-backend.ts +103 -1
  92. package/runtime/subsystems/events/event-bus.memory-backend.ts +57 -1
  93. package/runtime/subsystems/events/event-bus.protocol.ts +47 -0
  94. package/runtime/subsystems/events/event-scheduler.ts +351 -0
  95. package/runtime/subsystems/events/events-errors.ts +14 -0
  96. package/runtime/subsystems/events/events.module.ts +78 -1
  97. package/runtime/subsystems/events/generated/registry.ts +1 -0
  98. package/runtime/subsystems/events/index.ts +25 -3
  99. package/dist/chunk-B34G6PHD.js.map +0 -1
  100. package/dist/chunk-BGULBWKJ.js.map +0 -1
  101. package/dist/chunk-F7KN3U6U.js.map +0 -1
  102. package/dist/chunk-FN2PYDPP.js +0 -1
  103. package/dist/chunk-OFRRBC7M.js.map +0 -1
  104. package/dist/chunk-OZEPJGMA.js.map +0 -1
  105. package/dist/chunk-Z7PQCAVK.js.map +0 -1
  106. /package/dist/{chunk-7OVCARTQ.js.map → chunk-5RT7JGKT.js.map} +0 -0
  107. /package/dist/{chunk-AZLUWG5S.js.map → chunk-AJILKWGO.js.map} +0 -0
  108. /package/dist/{chunk-SNH35CNA.js.map → chunk-AODME4YK.js.map} +0 -0
  109. /package/dist/{chunk-PKDS6QIJ.js.map → chunk-ATVGYF3D.js.map} +0 -0
  110. /package/dist/{chunk-4MVGAMUA.js.map → chunk-BK5ICA2F.js.map} +0 -0
  111. /package/dist/{chunk-2TVVBC53.js.map → chunk-BORNCTH3.js.map} +0 -0
  112. /package/dist/{chunk-J7JMVS2B.js.map → chunk-CZQUOIDY.js.map} +0 -0
  113. /package/dist/{chunk-VQOAATIG.js.map → chunk-DUMI2J5M.js.map} +0 -0
  114. /package/dist/{chunk-XKWOJZZ4.js.map → chunk-E45CSC33.js.map} +0 -0
  115. /package/dist/{chunk-43SBT72G.js.map → chunk-I6UXRJ3Q.js.map} +0 -0
  116. /package/dist/{chunk-GM3RMJIJ.js.map → chunk-INO47JXD.js.map} +0 -0
  117. /package/dist/{chunk-65MO75WM.js.map → chunk-M3TIZGIB.js.map} +0 -0
  118. /package/dist/{chunk-E6PLM6QG.js.map → chunk-MB5VVG4Z.js.map} +0 -0
  119. /package/dist/{chunk-K2I6XIK5.js.map → chunk-MVKW2BCR.js.map} +0 -0
  120. /package/dist/{chunk-VDL5CJ5C.js.map → chunk-P7EZCTIN.js.map} +0 -0
  121. /package/dist/{chunk-R6F6KFIL.js.map → chunk-SGSWVNNB.js.map} +0 -0
  122. /package/dist/{chunk-FN2PYDPP.js.map → chunk-SYVZ4MD2.js.map} +0 -0
  123. /package/dist/{chunk-235ZMMJR.js.map → chunk-SZYZ4SHF.js.map} +0 -0
  124. /package/dist/{chunk-7LKAMLV4.js.map → chunk-T6SCOJF4.js.map} +0 -0
  125. /package/dist/{chunk-CLWBNXKF.js.map → chunk-W2UIDI3R.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,97 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.20.1] — 2026-06-06
8
+
9
+ **Fix: the subsystems barrel never threaded `eventRegistry` into
10
+ `EventsModule.forRoot`** — so `EventSchedulerLifecycle` never spawned and
11
+ ADR-039 scheduled events silently didn't tick (dogfood gap found consuming
12
+ 0.20.0 in swe-brain, package mode). The 0.20.0 runtime expected the barrel to
13
+ pass the consumer's generated `eventRegistry`, but the emitter (`subsystem-
14
+ barrel-generator`) was never updated to do so.
15
+
16
+ ### Fixed
17
+
18
+ - **`subsystem-barrel-generator` now threads `eventRegistry`** into
19
+ `EventsModule.forRoot` on every events branch (package + vendored, plain +
20
+ `listenNotify`). The registry is imported from `./events/registry`
21
+ (package mode) or `<subsystemsRoot>/events/generated/registry` (vendored) —
22
+ the same conditioning/relative-import mechanism the `TypedEventBus` import
23
+ already uses. `EventSchedulerLifecycle` reads `eventRegistry` (and only it —
24
+ no bundled fallback), so this is what makes the scheduler spawn.
25
+ - **Stub guard extended to vendored mode.** A bare `subsystem install events`
26
+ regenerates the barrel before `entity new --all` has emitted the generated
27
+ events set; the writer drops the empty 5-file set (incl. `registry.ts`) into
28
+ the vendored `<subsystemsRoot>/events/generated/` if absent, so the barrel's
29
+ new `eventRegistry` import never dangles (package mode already had this guard
30
+ for `./events/bus`; the same path emits `registry.ts`).
31
+
32
+ ### Tests
33
+
34
+ - `subsystem-barrel-generator` tests updated for the new `forRoot` shape +
35
+ a both-modes regression guard asserting `eventRegistry` is imported AND
36
+ threaded.
37
+ - **Subsystems smoke now asserts the threading end-to-end** — the gap survived
38
+ because nothing checked that a consumer's barrel actually wires the scheduler.
39
+ `run-smoke-subsystems` now fails if the real generated barrel doesn't import
40
+ `eventRegistry` and pass it to `EventsModule.forRoot`.
41
+
42
+ ## [0.20.0] — 2026-06-06
43
+
44
+ **Declarative time-based scheduling: time as an event source** (ADR-039;
45
+ swe-brain consumer-test finding — an hourly reconcile poll had to be hand-rolled
46
+ as a self-perpetuating job chain because there was no time-based trigger, and
47
+ its flat dedupe key collapsed the chain into the running parent).
48
+
49
+ ### Added
50
+
51
+ - **`schedule:` on event YAML** (`definitions/events/<domain>/*.yaml`) —
52
+ `{ every, align?, catchUp?, maxCatchUpSlots? }`. Declares that the platform
53
+ emits this event on a cadence. `every` is a duration string (`'1h'`/`'30m'`/
54
+ `'15s'`/`'500ms'`/`'1d'`) or raw ms. Domain-tier only (audit rejected). Time
55
+ is a third event **source** (peer to use-case publishes + webhook receivers),
56
+ not a fourth activation tier — consumers react through ADR-023's existing
57
+ tiers (`subscribe` or `@JobHandler({ triggers })`); no new activation
58
+ mechanism. Carried into the generated `eventRegistry` + `EventMetadata`.
59
+ - **`EventScheduler`** (`runtime/subsystems/events/event-scheduler.ts`) — a
60
+ strict producer that materialises **exactly one `domain_events` row per
61
+ (type, slot)** on a cadence; the existing outbox drain + bridge activate them.
62
+ Reconcile-on-boot (materialise the current slot, or bounded `catchUp`
63
+ backfill) + a tick pass for the next slot. Wired by `EventsModule.forRoot`
64
+ for the drizzle + memory backends (the Redis bus retains no outbox history, so
65
+ slot idempotency can't be enforced there). Pure helpers exported:
66
+ `parseEvery`, `slotStartFor`, `nextSlotStart`, `slotKeyFor`,
67
+ `scheduledEventsFromRegistry`.
68
+ - **Partial UNIQUE expression index** `idx_domain_events_schedule_slot` on
69
+ `(type, metadata->>'scheduleSlot')` — the DB-level exactly-once-per-slot
70
+ invariant (no advisory lock, no leader election; multi-instance + boot/tick
71
+ races collapse on it). Partial on the slot key so ordinary events are
72
+ untouched. Additive Atlas migration.
73
+ - **`ScheduleConfigError`** + `IEventBus.materializeScheduledEvent` /
74
+ `lastScheduledSlotMs` (both backends).
75
+
76
+ ### Misfire policy
77
+
78
+ - Down across N slots → on recovery, materialise **one** tick for the current
79
+ slot (don't replay the misses). `catchUp: true` opts into bounded backfill.
80
+
81
+ ### Provenance
82
+
83
+ - A scheduled tick carries `metadata.triggerSource = 'schedule'` +
84
+ `metadata.scheduleSlot`. A bridge run from it reads `job_run.trigger_source =
85
+ 'event'`; the clock origin is joinable via `trigger_ref → domain_events.id`.
86
+ The dormant ADR-022 `triggerSource: 'schedule'` enum is the correct stamp for
87
+ the **direct-start** path (a Tier-1 subscriber calling `orchestrator.start(…,
88
+ { triggerSource: 'schedule' })`).
89
+
90
+ ### Retires
91
+
92
+ - The self-perpetuating job-chain pattern (a handler enqueuing its own
93
+ successor) and its slot-keyed-dedupe workaround — replaced by a `schedule:`
94
+ YAML + a `triggers:` entry. Supersedes the dangling "ADR-025 scheduling
95
+ territory" pointer in `docs/specs/BULLMQ-1.md` (the future BullMQ backend maps
96
+ `schedule:` onto `upsertJobScheduler`; the YAML contract is identical).
97
+
7
98
  ## [0.19.0] — 2026-06-05
8
99
 
9
100
  **Providers catalog emission + planned providers** (ADR-038 follow-on;
@@ -65,6 +65,7 @@ After editing any `events/*.yaml`, re-run codegen (e.g. `codegen entity new --al
65
65
  | `payload` | yes | Map of snake_case keys → field specs. Keys become camelCase TS props. |
66
66
  | `pool` | no | Override the direction's default pool. Only valid within the same category (a `change` event can't opt into `events_inbound`). User pools are never valid. Rarely needed — if you reach for it, revisit the direction. **Must be omitted for `tier: audit`.** |
67
67
  | `retry` | no | `{ attempts, backoff }`; hints surfaced to the bus. |
68
+ | `schedule` | no | `{ every, align?, catchUp?, maxCatchUpSlots? }` — the platform emits this event on a cadence (ADR-039). `every` is a duration (`'1h'`/`'30m'`/`'15s'`/`'500ms'`/`'1d'`) or raw ms. **Domain-tier only.** See §Scheduled events. |
68
69
  | `version` | no | Integer, defaults to 1. Stamped on every publish; multi-version coexistence is not exercised yet. |
69
70
 
70
71
  ### Payload field types
@@ -117,6 +118,36 @@ Codegen hard-errors on misuse:
117
118
  - `tier: audit` with a `direction` → error naming the event.
118
119
  - A job whose `@JobHandler.triggers` points at an audit event → `AuditEventTriggerError`. Use a domain event or remove the trigger.
119
120
 
121
+ ## Scheduled events (time as an event source)
122
+
123
+ Add a `schedule:` block and the platform emits this event on a cadence — you react with the **same** tiers you use for any event (a `subscribe(...)` or a `@JobHandler({ triggers })`). There is no separate "cron handler" or schedule decorator; time is just a third way an event gets produced.
124
+
125
+ ```yaml
126
+ # definitions/events/messaging/reconcile_due.yaml
127
+ type: reconcile_due
128
+ direction: inbound # scheduled events are domain-tier; route by direction
129
+ schedule:
130
+ every: 1h # '1h' | '30m' | '15s' | '500ms' | '1d' | raw ms
131
+ align: true # epoch-anchored boundaries (fires at :00) — default
132
+ # catchUp: false # down across N slots → run ONCE on recovery (default)
133
+ # maxCatchUpSlots: 1000 # bound when catchUp: true
134
+ payload: {} # scheduled events are payload-free facts
135
+ ```
136
+
137
+ ```ts
138
+ // React via Tier 3 (bridge) — the cadence is on the event, the reaction on the job.
139
+ @JobHandler<ReconcileInput>('reconcile-poll', {
140
+ pool: 'batch',
141
+ concurrency: { key: 'reconcile:{{provider}}', collisionMode: 'queue' }, // serialises overruns
142
+ triggers: [{ event: 'reconcile_due', map: () => ({ provider: 'slack', windowHours: 24 }) }],
143
+ })
144
+ export class ReconcilePollHandler extends JobHandlerBase<ReconcileInput, ReconcileOutput> { /* … */ }
145
+ ```
146
+
147
+ Behavior: the framework emits **exactly one** `domain_events` row per slot (idempotent across instances + restarts), runs **reconcile-on-boot** (one tick on startup — healing any downtime gap), and by default does **not** replay missed slots. **This replaces the old "self-perpetuating job chain"** (a handler enqueuing its own successor with a slot-keyed dedupe) — delete that pattern; declare `schedule:` instead.
148
+
149
+ Rules: domain-tier only; a malformed `every` fails `gen-validate`; available on the drizzle/memory backends. See ADR-039.
150
+
120
151
  ## Entity `events:` block is sugar for change events
121
152
 
122
153
  An entity's YAML may keep an `events:` block. At parse time each entry desugars into an equivalent `events/<name>.yaml` with `direction: change` and `aggregate: <entity>`. Both paths produce the same registry entry — inline blocks are convenience, not a second source of truth.
@@ -1,17 +1,18 @@
1
+ import {
2
+ EVENTS_MODULE_OPTIONS
3
+ } from "./chunk-H5NH7KPE.js";
1
4
  import {
2
5
  clampEventLimit,
3
6
  decodeEventCursor,
4
7
  encodeEventCursor
5
8
  } from "./chunk-UQ5EHOH2.js";
6
- import {
7
- EVENTS_MODULE_OPTIONS
8
- } from "./chunk-H5NH7KPE.js";
9
9
  import {
10
10
  __decorateClass,
11
11
  __decorateParam
12
12
  } from "./chunk-2E224ZSN.js";
13
13
 
14
14
  // runtime/subsystems/events/event-bus.memory-backend.ts
15
+ import { randomUUID } from "crypto";
15
16
  import { Inject, Injectable, Logger, Optional } from "@nestjs/common";
16
17
  function toEventSummary(event) {
17
18
  const metadata = event.metadata;
@@ -58,6 +59,51 @@ var MemoryEventBus = class {
58
59
  async findById(eventId) {
59
60
  return this.publishedEvents.find((e) => e.id === eventId) ?? null;
60
61
  }
62
+ // ============================================================================
63
+ // ADR-039 — scheduled-event materialisation (memory parity)
64
+ // ============================================================================
65
+ /** Slot keys already materialised — the in-memory mirror of the partial
66
+ * UNIQUE expression index `idx_domain_events_schedule_slot`. */
67
+ materialisedSlots = /* @__PURE__ */ new Set();
68
+ /**
69
+ * Mirror of the Drizzle `ON CONFLICT DO NOTHING` insert: emit one payload-free
70
+ * tick event per slot key, no-op if the slot was already materialised. The
71
+ * "constraint" is the `materialisedSlots` set. The tick is published through
72
+ * the normal `publish` path so subscribers fire synchronously (the memory bus
73
+ * has no future-slot/poll concept — a materialised slot dispatches now, which
74
+ * is the behaviour the unit suite pins).
75
+ */
76
+ async materializeScheduledEvent(spec) {
77
+ if (this.materialisedSlots.has(spec.slotKey)) return { created: false };
78
+ this.materialisedSlots.add(spec.slotKey);
79
+ const event = {
80
+ id: randomUUID(),
81
+ type: spec.type,
82
+ aggregateId: spec.type,
83
+ aggregateType: spec.type,
84
+ payload: {},
85
+ occurredAt: spec.slotStart,
86
+ metadata: {
87
+ pool: spec.pool,
88
+ direction: spec.direction,
89
+ scheduleSlot: spec.slotKey,
90
+ triggerSource: "schedule"
91
+ }
92
+ };
93
+ await this.publish(event);
94
+ return { created: true };
95
+ }
96
+ /** Most recent scheduled tick's `occurred_at` (epoch ms) for `type`, or null. */
97
+ async lastScheduledSlotMs(type) {
98
+ let best = null;
99
+ for (const e of this.publishedEvents) {
100
+ if (e.type !== type) continue;
101
+ if (e.metadata?.["triggerSource"] !== "schedule") continue;
102
+ const ms = e.occurredAt.getTime();
103
+ if (best === null || ms > best) best = ms;
104
+ }
105
+ return best;
106
+ }
61
107
  subscribe(eventType, handler) {
62
108
  if (!this.handlers.has(eventType)) {
63
109
  this.handlers.set(eventType, /* @__PURE__ */ new Set());
@@ -197,4 +243,4 @@ MemoryEventBus = __decorateClass([
197
243
  export {
198
244
  MemoryEventBus
199
245
  };
200
- //# sourceMappingURL=chunk-Z7PQCAVK.js.map
246
+ //# sourceMappingURL=chunk-4OC5MSHO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../runtime/subsystems/events/event-bus.memory-backend.ts"],"sourcesContent":["/**\n * MemoryEventBus — in-memory backend for the event bus.\n *\n * Dispatches events synchronously to registered subscribers. The `tx`\n * parameter is ignored — all events are dispatched immediately.\n *\n * Use this backend in tests to assert event publication without a database.\n * Swap via EventsModule.forRoot({ backend: 'memory' }).\n *\n * Pool awareness (EVT-5):\n * - Mirrors the `DrizzleEventBus` per-process restriction (EVT-4). When\n * `opts.pools` is set, `publish`/`publishMany` still push the event into\n * `publishedEvents` (so test code can assert the full set of emitted\n * events regardless of pool filter), but handlers are NOT invoked for\n * events whose `metadata.pool` is outside the configured pools.\n * - `publishedEventsForPool(pool)` and `publishedEventsForDirection(dir)`\n * helpers are provided for targeted assertions.\n * - Shares the `EventsModuleOptions` shape (same token as Drizzle) rather\n * than introducing a memory-only options type — the surface is the same\n * and keeping them unified avoids drift between backends.\n */\nimport { randomUUID } from 'node:crypto';\nimport { Inject, Injectable, Logger, Optional } from '@nestjs/common';\nimport type {\n DomainEvent,\n IEventBus,\n ScheduledEventSpec,\n} from './event-bus.protocol';\nimport type {\n EventPage,\n EventSummary,\n IEventReadPort,\n ListEventsQuery,\n} from './event-read.protocol';\nimport {\n clampEventLimit,\n decodeEventCursor,\n encodeEventCursor,\n} from './event-keyset-cursor';\nimport { EVENTS_MODULE_OPTIONS } from './events.tokens';\nimport type { EventsModuleOptions } from './events.module';\n\n/**\n * Project an in-memory `DomainEvent` into the narrow `EventSummary` shape.\n * The memory backend has no first-class columns, so `pool` / `direction` /\n * `tier` / `tenantId` / `rootRunId` are read from `metadata` (mirroring how\n * the Drizzle backend stamps them onto columns at publish time). `status`\n * is reported as `'processed'` — the memory bus dispatches synchronously,\n * so once an event is in `publishedEvents` it has been handled.\n */\nfunction toEventSummary(event: DomainEvent): EventSummary {\n const metadata = event.metadata;\n const str = (key: string): string | null => {\n const v = metadata?.[key];\n return typeof v === 'string' ? v : null;\n };\n return {\n id: event.id,\n type: event.type,\n aggregateId: event.aggregateId,\n aggregateType: event.aggregateType,\n status: 'processed',\n pool: str('pool'),\n direction: str('direction'),\n tier: str('tier') ?? 'domain',\n rootRunId: str('rootRunId'),\n tenantId: str('tenantId'),\n occurredAt: event.occurredAt,\n processedAt: event.occurredAt,\n };\n}\n\n@Injectable()\nexport class MemoryEventBus implements IEventBus, IEventReadPort {\n private readonly logger = new Logger(MemoryEventBus.name);\n\n /** All events published since construction (or last clear). */\n readonly publishedEvents: DomainEvent[] = [];\n\n private readonly handlers = new Map<string, Set<(event: DomainEvent) => Promise<void>>>();\n private readonly opts: EventsModuleOptions;\n\n constructor(\n @Optional() @Inject(EVENTS_MODULE_OPTIONS) opts?: EventsModuleOptions,\n ) {\n // Default so direct construction (e.g. `new MemoryEventBus()` from a\n // unit test outside NestJS DI) keeps working without an explicit\n // options object.\n this.opts = opts ?? { backend: 'memory' };\n }\n\n async publish(event: DomainEvent): Promise<void> {\n // Mirror the `domain_events_tier_routing_check` DB constraint at the\n // memory backend boundary so misuse fails the same way regardless of\n // backend (AUDIT-1).\n this.assertTierRouting(event);\n\n // Always record the event — even if this process is configured with a\n // pool filter that excludes it. Test code relies on `publishedEvents`\n // being a complete log of what was published, not a filtered view.\n this.publishedEvents.push(event);\n\n if (this.shouldDispatch(event)) {\n await this.dispatch(event);\n }\n }\n\n async publishMany(events: DomainEvent[]): Promise<void> {\n for (const event of events) {\n await this.publish(event);\n }\n }\n\n async findById(eventId: string): Promise<DomainEvent | null> {\n return this.publishedEvents.find((e) => e.id === eventId) ?? null;\n }\n\n // ============================================================================\n // ADR-039 — scheduled-event materialisation (memory parity)\n // ============================================================================\n\n /** Slot keys already materialised — the in-memory mirror of the partial\n * UNIQUE expression index `idx_domain_events_schedule_slot`. */\n private readonly materialisedSlots = new Set<string>();\n\n /**\n * Mirror of the Drizzle `ON CONFLICT DO NOTHING` insert: emit one payload-free\n * tick event per slot key, no-op if the slot was already materialised. The\n * \"constraint\" is the `materialisedSlots` set. The tick is published through\n * the normal `publish` path so subscribers fire synchronously (the memory bus\n * has no future-slot/poll concept — a materialised slot dispatches now, which\n * is the behaviour the unit suite pins).\n */\n async materializeScheduledEvent(\n spec: ScheduledEventSpec,\n ): Promise<{ created: boolean }> {\n if (this.materialisedSlots.has(spec.slotKey)) return { created: false };\n this.materialisedSlots.add(spec.slotKey);\n const event: DomainEvent = {\n id: randomUUID(),\n type: spec.type,\n aggregateId: spec.type,\n aggregateType: spec.type,\n payload: {},\n occurredAt: spec.slotStart,\n metadata: {\n pool: spec.pool,\n direction: spec.direction,\n scheduleSlot: spec.slotKey,\n triggerSource: 'schedule',\n },\n };\n await this.publish(event);\n return { created: true };\n }\n\n /** Most recent scheduled tick's `occurred_at` (epoch ms) for `type`, or null. */\n async lastScheduledSlotMs(type: string): Promise<number | null> {\n let best: number | null = null;\n for (const e of this.publishedEvents) {\n if (e.type !== type) continue;\n if (e.metadata?.['triggerSource'] !== 'schedule') continue;\n const ms = e.occurredAt.getTime();\n if (best === null || ms > best) best = ms;\n }\n return best;\n }\n\n subscribe<T extends DomainEvent = DomainEvent>(\n eventType: string,\n handler: (event: T) => Promise<void>,\n ): () => void {\n if (!this.handlers.has(eventType)) {\n this.handlers.set(eventType, new Set());\n }\n // Cast is safe — callers pass a typed handler; we store as the base type\n const set = this.handlers.get(eventType)!;\n const h = handler as (event: DomainEvent) => Promise<void>;\n set.add(h);\n\n return () => {\n set.delete(h);\n };\n }\n\n // ============================================================================\n // IEventReadPort (OBS-LIST-1)\n // ============================================================================\n\n async listEvents(query: ListEventsQuery = {}): Promise<EventPage> {\n const limit = clampEventLimit(query.limit);\n const keyset = query.cursor ? decodeEventCursor(query.cursor) : null;\n\n const str = (e: DomainEvent, key: string): string | null => {\n const v = e.metadata?.[key];\n return typeof v === 'string' ? v : null;\n };\n\n const matched = this.publishedEvents.filter((e) => {\n if (query.poolId && str(e, 'pool') !== query.poolId) return false;\n if (query.direction && str(e, 'direction') !== query.direction)\n return false;\n if (query.rootRunId && str(e, 'rootRunId') !== query.rootRunId)\n return false;\n if (query.since && e.occurredAt.getTime() < query.since.getTime())\n return false;\n if (query.tenantId !== undefined) {\n const t = str(e, 'tenantId');\n if (query.tenantId === null) {\n if (t !== null) return false;\n } else if (t !== query.tenantId) {\n return false;\n }\n }\n return true;\n });\n\n // Order occurred_at DESC, id DESC to match the Drizzle backend keyset.\n matched.sort((a, b) => {\n const dt = b.occurredAt.getTime() - a.occurredAt.getTime();\n if (dt !== 0) return dt;\n return a.id < b.id ? 1 : a.id > b.id ? -1 : 0;\n });\n\n const seeked = keyset\n ? matched.filter((e) => {\n const ct = e.occurredAt.getTime();\n const kt = keyset.occurredAt.getTime();\n if (ct < kt) return true;\n if (ct > kt) return false;\n return e.id < keyset.id;\n })\n : matched;\n\n const hasMore = seeked.length > limit;\n const page = hasMore ? seeked.slice(0, limit) : seeked;\n const items = page.map(toEventSummary);\n const last = page[page.length - 1];\n const nextCursor =\n hasMore && last\n ? encodeEventCursor({ occurredAt: last.occurredAt, id: last.id })\n : null;\n\n return { items, nextCursor };\n }\n\n /** Remove all published events and subscriptions. Useful in beforeEach. */\n clear(): void {\n this.publishedEvents.length = 0;\n this.handlers.clear();\n }\n\n /** Filter published events by `metadata.pool`. */\n publishedEventsForPool(pool: string): DomainEvent[] {\n return this.publishedEvents.filter((e) => e.metadata?.['pool'] === pool);\n }\n\n /** Filter published events by `metadata.direction`. */\n publishedEventsForDirection(direction: string): DomainEvent[] {\n return this.publishedEvents.filter((e) => e.metadata?.['direction'] === direction);\n }\n\n /**\n * Decide whether `event` should be dispatched to handlers given the\n * current pool filter.\n *\n * Semantics (mirroring `DrizzleEventBus.processBatch`):\n * - `opts.pools` undefined → dispatch everything (no filter).\n * - `opts.pools` empty array → treated as \"no filter\" to match the\n * Drizzle backend, where `pools && pools.length > 0` is the gate on\n * the `inArray` WHERE clause. Empty arrays dispatch everything.\n * - `opts.pools` non-empty → dispatch only when `event.metadata.pool`\n * is in the list. Events without `metadata.pool` do NOT match — they\n * are out of all configured pools by definition.\n */\n private shouldDispatch(event: DomainEvent): boolean {\n const pools = this.opts.pools;\n if (!pools || pools.length === 0) return true;\n const eventPool = event.metadata?.['pool'];\n return typeof eventPool === 'string' && pools.includes(eventPool);\n }\n\n /**\n * Mirror the `domain_events_tier_routing_check` DB CHECK at the memory\n * backend (AUDIT-1). Audit-tier events MUST have null/undefined\n * `pool` and `direction` in metadata; the bridge dispatcher relies on\n * this invariant.\n */\n private assertTierRouting(event: DomainEvent): void {\n const tier = event.metadata?.['tier'];\n if (tier !== 'audit') return;\n const pool = event.metadata?.['pool'];\n const direction = event.metadata?.['direction'];\n const poolIsNull = pool === null || pool === undefined;\n const directionIsNull = direction === null || direction === undefined;\n if (!poolIsNull || !directionIsNull) {\n throw new Error(\n `MemoryEventBus: tier='audit' events must have null pool and direction ` +\n `(got pool=${String(pool)}, direction=${String(direction)}). ` +\n `This mirrors the domain_events CHECK constraint.`,\n );\n }\n }\n\n private async dispatch(event: DomainEvent): Promise<void> {\n const set = this.handlers.get(event.type);\n if (!set) return;\n\n let firstError: unknown;\n for (const handler of set) {\n try {\n await handler(event);\n } catch (err) {\n this.logger.error(\n `Handler error for event type \"${event.type}\" (id: ${event.id}): ${err}`,\n );\n if (firstError === undefined) {\n firstError = err;\n }\n }\n }\n\n if (firstError !== undefined) {\n throw firstError;\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -4,14 +4,14 @@ import {
4
4
  import {
5
5
  JOB_ORCHESTRATOR
6
6
  } from "./chunk-ZPL74UQN.js";
7
- import {
8
- EVENT_BUS
9
- } from "./chunk-H5NH7KPE.js";
10
7
  import {
11
8
  BRIDGE_DELIVERY_REPO,
12
9
  BRIDGE_MULTI_TENANT,
13
10
  BRIDGE_REGISTRY
14
11
  } from "./chunk-4LH67P4U.js";
12
+ import {
13
+ EVENT_BUS
14
+ } from "./chunk-H5NH7KPE.js";
15
15
  import {
16
16
  DRIZZLE
17
17
  } from "./chunk-U64T4YZE.js";
@@ -106,4 +106,4 @@ EventFlowService = __decorateClass([
106
106
  export {
107
107
  EventFlowService
108
108
  };
109
- //# sourceMappingURL=chunk-7OVCARTQ.js.map
109
+ //# sourceMappingURL=chunk-5RT7JGKT.js.map
@@ -1,21 +1,21 @@
1
- import {
2
- DrizzleJobRunService
3
- } from "./chunk-VNBC3VXM.js";
4
- import {
5
- MemoryJobRunService
6
- } from "./chunk-BHZP6LOV.js";
7
1
  import {
8
2
  DrizzleJobStepService
9
3
  } from "./chunk-DV4RV2DC.js";
10
4
  import {
11
5
  DrizzleJobOrchestrator
12
- } from "./chunk-E6PLM6QG.js";
6
+ } from "./chunk-MB5VVG4Z.js";
13
7
  import {
14
8
  MemoryJobOrchestrator
15
- } from "./chunk-VQOAATIG.js";
9
+ } from "./chunk-DUMI2J5M.js";
16
10
  import {
17
11
  MemoryJobStepService
18
12
  } from "./chunk-PNZSGAB2.js";
13
+ import {
14
+ DrizzleJobRunService
15
+ } from "./chunk-VNBC3VXM.js";
16
+ import {
17
+ MemoryJobRunService
18
+ } from "./chunk-BHZP6LOV.js";
19
19
  import {
20
20
  MemoryJobStore
21
21
  } from "./chunk-SNQ3TOWP.js";
@@ -114,4 +114,4 @@ JobsDomainModule = __decorateClass([
114
114
  export {
115
115
  JobsDomainModule
116
116
  };
117
- //# sourceMappingURL=chunk-AZLUWG5S.js.map
117
+ //# sourceMappingURL=chunk-AJILKWGO.js.map
@@ -1,30 +1,30 @@
1
1
  import {
2
2
  bridgeRegistry
3
3
  } from "./chunk-5A432NZJ.js";
4
- import {
5
- BridgeOutboxDrainHook
6
- } from "./chunk-65MO75WM.js";
7
4
  import {
8
5
  EventFlowService
9
- } from "./chunk-7OVCARTQ.js";
6
+ } from "./chunk-5RT7JGKT.js";
10
7
  import {
11
8
  BRIDGE_RESERVED_POOLS
12
9
  } from "./chunk-EDKJU5BO.js";
13
- import {
14
- BridgeDeliveryHandler
15
- } from "./chunk-R6F6KFIL.js";
16
10
  import {
17
11
  DrizzleBridgeDeliveryRepo
18
- } from "./chunk-K2I6XIK5.js";
12
+ } from "./chunk-MVKW2BCR.js";
19
13
  import {
20
14
  MemoryBridgeDeliveryRepo
21
15
  } from "./chunk-4DOJBQTP.js";
16
+ import {
17
+ BridgeOutboxDrainHook
18
+ } from "./chunk-M3TIZGIB.js";
19
+ import {
20
+ BridgeDeliveryHandler
21
+ } from "./chunk-SGSWVNNB.js";
22
22
  import {
23
23
  BridgeReservedPoolsNotPolledError
24
24
  } from "./chunk-NXXDZ6ZF.js";
25
25
  import {
26
26
  JOB_WORKER_MODULE_OPTIONS
27
- } from "./chunk-235ZMMJR.js";
27
+ } from "./chunk-SZYZ4SHF.js";
28
28
  import {
29
29
  BRIDGE_DELIVERY_REPO,
30
30
  BRIDGE_MODULE_OPTIONS,
@@ -119,4 +119,4 @@ BridgeModule = __decorateClass([
119
119
  export {
120
120
  BridgeModule
121
121
  };
122
- //# sourceMappingURL=chunk-SNH35CNA.js.map
122
+ //# sourceMappingURL=chunk-AODME4YK.js.map
@@ -7,6 +7,12 @@ import {
7
7
  import {
8
8
  PostgresCursorStore
9
9
  } from "./chunk-XWBK3XJK.js";
10
+ import {
11
+ MemoryCursorStore
12
+ } from "./chunk-AHV4GDYM.js";
13
+ import {
14
+ DeepEqualDiffer
15
+ } from "./chunk-JEINYUJH.js";
10
16
  import {
11
17
  INTEGRATION_CURSOR_STORE,
12
18
  INTEGRATION_FIELD_DIFFER,
@@ -14,12 +20,6 @@ import {
14
20
  INTEGRATION_MULTI_TENANT,
15
21
  INTEGRATION_RUN_RECORDER
16
22
  } from "./chunk-S7C6TIIF.js";
17
- import {
18
- MemoryCursorStore
19
- } from "./chunk-AHV4GDYM.js";
20
- import {
21
- DeepEqualDiffer
22
- } from "./chunk-JEINYUJH.js";
23
23
  import {
24
24
  __decorateClass
25
25
  } from "./chunk-2E224ZSN.js";
@@ -84,4 +84,4 @@ IntegrationModule = __decorateClass([
84
84
  export {
85
85
  IntegrationModule
86
86
  };
87
- //# sourceMappingURL=chunk-PKDS6QIJ.js.map
87
+ //# sourceMappingURL=chunk-ATVGYF3D.js.map
@@ -1,12 +1,12 @@
1
+ import {
2
+ STORAGE
3
+ } from "./chunk-NYBCQZC7.js";
1
4
  import {
2
5
  LocalStorageBackend
3
6
  } from "./chunk-JWNHNUYL.js";
4
7
  import {
5
8
  MemoryStorageBackend
6
9
  } from "./chunk-3SZFUTXE.js";
7
- import {
8
- STORAGE
9
- } from "./chunk-NYBCQZC7.js";
10
10
  import {
11
11
  __decorateClass
12
12
  } from "./chunk-2E224ZSN.js";
@@ -37,4 +37,4 @@ StorageModule = __decorateClass([
37
37
  export {
38
38
  StorageModule
39
39
  };
40
- //# sourceMappingURL=chunk-4MVGAMUA.js.map
40
+ //# sourceMappingURL=chunk-BK5ICA2F.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-OKXZ63IA.js";
4
4
  import {
5
5
  domainEvents
6
- } from "./chunk-OFRRBC7M.js";
6
+ } from "./chunk-E2BRT5IB.js";
7
7
 
8
8
  // runtime/subsystems/bridge/bridge-delivery.schema.ts
9
9
  import {
@@ -89,4 +89,4 @@ export {
89
89
  bridgeDeliveryStatusEnum,
90
90
  bridgeDelivery
91
91
  };
92
- //# sourceMappingURL=chunk-2TVVBC53.js.map
92
+ //# sourceMappingURL=chunk-BORNCTH3.js.map
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  CubeAnalyticsBackend
3
3
  } from "./chunk-7B3RYX45.js";
4
- import {
5
- NoopAnalyticsBackend
6
- } from "./chunk-J37YWU7Y.js";
7
4
  import {
8
5
  ANALYTICS_QUERY,
9
6
  CUBE_API_SECRET,
10
7
  CUBE_API_URL
11
8
  } from "./chunk-6I7ULIN6.js";
9
+ import {
10
+ NoopAnalyticsBackend
11
+ } from "./chunk-J37YWU7Y.js";
12
12
  import {
13
13
  __decorateClass
14
14
  } from "./chunk-2E224ZSN.js";
@@ -50,4 +50,4 @@ AnalyticsModule = __decorateClass([
50
50
  export {
51
51
  AnalyticsModule
52
52
  };
53
- //# sourceMappingURL=chunk-J7JMVS2B.js.map
53
+ //# sourceMappingURL=chunk-CZQUOIDY.js.map
@@ -9,8 +9,15 @@ var MissingTenantIdError = class extends Error {
9
9
  eventType;
10
10
  name = "MissingTenantIdError";
11
11
  };
12
+ var ScheduleConfigError = class extends Error {
13
+ name = "ScheduleConfigError";
14
+ constructor(message) {
15
+ super(`ScheduleConfigError: ${message}`);
16
+ }
17
+ };
12
18
 
13
19
  export {
14
- MissingTenantIdError
20
+ MissingTenantIdError,
21
+ ScheduleConfigError
15
22
  };
16
- //# sourceMappingURL=chunk-V4AF6DI4.js.map
23
+ //# sourceMappingURL=chunk-DUBZOXJC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../runtime/subsystems/events/events-errors.ts"],"sourcesContent":["/**\n * Typed errors for the events subsystem (ADR-024, EVT-6).\n *\n * All thrown from the publish path of `TypedEventBus`. They exist as\n * classes so consumers can `instanceof` them in catch blocks and\n * exception filters can map them to HTTP codes.\n */\n\n/**\n * Thrown by `TypedEventBus.publish()` when the EventsModule is configured\n * with `multiTenant: true` and the caller did not supply\n * `opts.metadata.tenantId`. Multi-tenant mode requires every outbox row to\n * be attributable to a tenant — the `domain_events.tenant_id` column is\n * populated from this value and the drain loop uses it for future\n * tenant-scoped filtering (deferred — see ADR-024 §Multi-tenancy).\n *\n * Disable multi-tenancy at the module level (`multiTenant: false`, the\n * default) to opt out of the requirement entirely.\n */\nexport class MissingTenantIdError extends Error {\n override readonly name = 'MissingTenantIdError';\n constructor(public readonly eventType: string) {\n super(\n `Missing tenantId for event '${eventType}'. EventsModule is configured ` +\n `with multiTenant: true — every publish must include ` +\n `opts.metadata.tenantId. Either pass the tenantId or disable ` +\n `multi-tenancy on the module.`,\n );\n }\n}\n"],"mappings":";AAmBO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAE9C,YAA4B,WAAmB;AAC7C;AAAA,MACE,+BAA+B,SAAS;AAAA,IAI1C;AAN0B;AAAA,EAO5B;AAAA,EAP4B;AAAA,EADV,OAAO;AAS3B;","names":[]}
1
+ {"version":3,"sources":["../runtime/subsystems/events/events-errors.ts"],"sourcesContent":["/**\n * Typed errors for the events subsystem (ADR-024, EVT-6).\n *\n * All thrown from the publish path of `TypedEventBus`. They exist as\n * classes so consumers can `instanceof` them in catch blocks and\n * exception filters can map them to HTTP codes.\n */\n\n/**\n * Thrown by `TypedEventBus.publish()` when the EventsModule is configured\n * with `multiTenant: true` and the caller did not supply\n * `opts.metadata.tenantId`. Multi-tenant mode requires every outbox row to\n * be attributable to a tenant — the `domain_events.tenant_id` column is\n * populated from this value and the drain loop uses it for future\n * tenant-scoped filtering (deferred — see ADR-024 §Multi-tenancy).\n *\n * Disable multi-tenancy at the module level (`multiTenant: false`, the\n * default) to opt out of the requirement entirely.\n */\nexport class MissingTenantIdError extends Error {\n override readonly name = 'MissingTenantIdError';\n constructor(public readonly eventType: string) {\n super(\n `Missing tenantId for event '${eventType}'. EventsModule is configured ` +\n `with multiTenant: true — every publish must include ` +\n `opts.metadata.tenantId. Either pass the tenantId or disable ` +\n `multi-tenancy on the module.`,\n );\n }\n}\n\n/**\n * Thrown (ADR-039) when a scheduled event's `schedule` config is invalid at\n * runtime — a malformed `schedule.every` duration, or a scheduled event with no\n * direction/pool to route by. Codegen validates `schedule` at `gen-all` time;\n * this is the boot backstop for a hand-edited registry or version skew. Raised\n * by `EventScheduler` construction / `parseEvery`.\n */\nexport class ScheduleConfigError extends Error {\n override readonly name = 'ScheduleConfigError';\n constructor(message: string) {\n super(`ScheduleConfigError: ${message}`);\n }\n}\n"],"mappings":";AAmBO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAE9C,YAA4B,WAAmB;AAC7C;AAAA,MACE,+BAA+B,SAAS;AAAA,IAI1C;AAN0B;AAAA,EAO5B;AAAA,EAP4B;AAAA,EADV,OAAO;AAS3B;AASO,IAAM,sBAAN,cAAkC,MAAM;AAAA,EAC3B,OAAO;AAAA,EACzB,YAAY,SAAiB;AAC3B,UAAM,wBAAwB,OAAO,EAAE;AAAA,EACzC;AACF;","names":[]}
@@ -11,14 +11,14 @@ import {
11
11
  JobTypeNotFoundError,
12
12
  MissingTenantIdError
13
13
  } from "./chunk-T4BIIU5E.js";
14
+ import {
15
+ JOBS_MULTI_TENANT
16
+ } from "./chunk-ZPL74UQN.js";
14
17
  import {
15
18
  FN_KEY_SENTINEL,
16
19
  JobKeyFunctionUnavailableError,
17
20
  keySelectorToTemplate
18
21
  } from "./chunk-7P5ODGLA.js";
19
- import {
20
- JOBS_MULTI_TENANT
21
- } from "./chunk-ZPL74UQN.js";
22
22
  import {
23
23
  __decorateClass,
24
24
  __decorateParam
@@ -663,4 +663,4 @@ function serialiseError(err, attempt, retryable) {
663
663
  export {
664
664
  MemoryJobOrchestrator
665
665
  };
666
- //# sourceMappingURL=chunk-VQOAATIG.js.map
666
+ //# sourceMappingURL=chunk-DUMI2J5M.js.map