@l-etabli/events 0.6.0 → 0.7.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.
Files changed (156) hide show
  1. package/README.md +96 -0
  2. package/dist/adapters/effect-kysely/EffectKyselyEventQueries.cjs +54 -0
  3. package/dist/adapters/effect-kysely/EffectKyselyEventQueries.cjs.map +1 -0
  4. package/dist/adapters/effect-kysely/EffectKyselyEventQueries.d.cts +10 -0
  5. package/dist/adapters/effect-kysely/EffectKyselyEventQueries.d.ts +10 -0
  6. package/dist/adapters/effect-kysely/EffectKyselyEventQueries.mjs +30 -0
  7. package/dist/adapters/effect-kysely/EffectKyselyEventQueries.mjs.map +1 -0
  8. package/dist/adapters/effect-kysely/EffectKyselyEventRepository.cjs +85 -0
  9. package/dist/adapters/effect-kysely/EffectKyselyEventRepository.cjs.map +1 -0
  10. package/dist/adapters/effect-kysely/EffectKyselyEventRepository.d.cts +9 -0
  11. package/dist/adapters/effect-kysely/EffectKyselyEventRepository.d.ts +9 -0
  12. package/dist/adapters/effect-kysely/EffectKyselyEventRepository.mjs +61 -0
  13. package/dist/adapters/effect-kysely/EffectKyselyEventRepository.mjs.map +1 -0
  14. package/dist/adapters/effect-kysely/index.cjs +32 -0
  15. package/dist/adapters/effect-kysely/index.cjs.map +1 -0
  16. package/dist/adapters/effect-kysely/index.d.cts +9 -0
  17. package/dist/adapters/effect-kysely/index.d.ts +9 -0
  18. package/dist/adapters/effect-kysely/index.mjs +7 -0
  19. package/dist/adapters/effect-kysely/index.mjs.map +1 -0
  20. package/dist/adapters/in-memory/InMemoryEventBus.cjs +3 -17
  21. package/dist/adapters/in-memory/InMemoryEventBus.cjs.map +1 -1
  22. package/dist/adapters/in-memory/InMemoryEventBus.mjs +2 -16
  23. package/dist/adapters/in-memory/InMemoryEventBus.mjs.map +1 -1
  24. package/dist/adapters/in-memory/InMemoryEventQueries.cjs +2 -20
  25. package/dist/adapters/in-memory/InMemoryEventQueries.cjs.map +1 -1
  26. package/dist/adapters/in-memory/InMemoryEventQueries.mjs +2 -20
  27. package/dist/adapters/in-memory/InMemoryEventQueries.mjs.map +1 -1
  28. package/dist/adapters/kysely/KyselyEventQueries.cjs +20 -24
  29. package/dist/adapters/kysely/KyselyEventQueries.cjs.map +1 -1
  30. package/dist/adapters/kysely/KyselyEventQueries.d.cts +1 -1
  31. package/dist/adapters/kysely/KyselyEventQueries.d.ts +1 -1
  32. package/dist/adapters/kysely/KyselyEventQueries.mjs +20 -24
  33. package/dist/adapters/kysely/KyselyEventQueries.mjs.map +1 -1
  34. package/dist/adapters/kysely/KyselyEventRepository.cjs +47 -45
  35. package/dist/adapters/kysely/KyselyEventRepository.cjs.map +1 -1
  36. package/dist/adapters/kysely/KyselyEventRepository.d.cts +1 -1
  37. package/dist/adapters/kysely/KyselyEventRepository.d.ts +1 -1
  38. package/dist/adapters/kysely/KyselyEventRepository.mjs +43 -41
  39. package/dist/adapters/kysely/KyselyEventRepository.mjs.map +1 -1
  40. package/dist/adapters/kysely/jsonb.cjs +30 -0
  41. package/dist/adapters/kysely/jsonb.cjs.map +1 -0
  42. package/dist/adapters/kysely/jsonb.d.cts +5 -0
  43. package/dist/adapters/kysely/jsonb.d.ts +5 -0
  44. package/dist/adapters/kysely/jsonb.mjs +6 -0
  45. package/dist/adapters/kysely/jsonb.mjs.map +1 -0
  46. package/dist/adapters/kysely/mapEventRow.cjs +35 -0
  47. package/dist/adapters/kysely/mapEventRow.cjs.map +1 -0
  48. package/dist/adapters/kysely/mapEventRow.d.cts +6 -0
  49. package/dist/adapters/kysely/mapEventRow.d.ts +6 -0
  50. package/dist/adapters/kysely/mapEventRow.mjs +11 -0
  51. package/dist/adapters/kysely/mapEventRow.mjs.map +1 -0
  52. package/dist/createEventCrawler.cjs +2 -8
  53. package/dist/createEventCrawler.cjs.map +1 -1
  54. package/dist/createEventCrawler.mjs +1 -7
  55. package/dist/createEventCrawler.mjs.map +1 -1
  56. package/dist/effect/EffectEventCrawler.cjs +111 -0
  57. package/dist/effect/EffectEventCrawler.cjs.map +1 -0
  58. package/dist/effect/EffectEventCrawler.d.cts +26 -0
  59. package/dist/effect/EffectEventCrawler.d.ts +26 -0
  60. package/dist/effect/EffectEventCrawler.mjs +87 -0
  61. package/dist/effect/EffectEventCrawler.mjs.map +1 -0
  62. package/dist/effect/EffectInMemoryEventBus.cjs +131 -0
  63. package/dist/effect/EffectInMemoryEventBus.cjs.map +1 -0
  64. package/dist/effect/EffectInMemoryEventBus.d.cts +31 -0
  65. package/dist/effect/EffectInMemoryEventBus.d.ts +31 -0
  66. package/dist/effect/EffectInMemoryEventBus.mjs +112 -0
  67. package/dist/effect/EffectInMemoryEventBus.mjs.map +1 -0
  68. package/dist/effect/EffectInMemoryEventQueries.cjs +35 -0
  69. package/dist/effect/EffectInMemoryEventQueries.cjs.map +1 -0
  70. package/dist/effect/EffectInMemoryEventQueries.d.cts +12 -0
  71. package/dist/effect/EffectInMemoryEventQueries.d.ts +12 -0
  72. package/dist/effect/EffectInMemoryEventQueries.mjs +11 -0
  73. package/dist/effect/EffectInMemoryEventQueries.mjs.map +1 -0
  74. package/dist/effect/EffectInMemoryEventRepository.cjs +73 -0
  75. package/dist/effect/EffectInMemoryEventRepository.cjs.map +1 -0
  76. package/dist/effect/EffectInMemoryEventRepository.d.cts +15 -0
  77. package/dist/effect/EffectInMemoryEventRepository.d.ts +15 -0
  78. package/dist/effect/EffectInMemoryEventRepository.mjs +48 -0
  79. package/dist/effect/EffectInMemoryEventRepository.mjs.map +1 -0
  80. package/dist/effect/EffectSubscriptions.cjs +61 -0
  81. package/dist/effect/EffectSubscriptions.cjs.map +1 -0
  82. package/dist/effect/EffectSubscriptions.d.cts +22 -0
  83. package/dist/effect/EffectSubscriptions.d.ts +22 -0
  84. package/dist/effect/EffectSubscriptions.mjs +36 -0
  85. package/dist/effect/EffectSubscriptions.mjs.map +1 -0
  86. package/dist/effect/index.cjs +47 -0
  87. package/dist/effect/index.cjs.map +1 -0
  88. package/dist/effect/index.d.cts +27 -0
  89. package/dist/effect/index.d.ts +27 -0
  90. package/dist/effect/index.mjs +20 -0
  91. package/dist/effect/index.mjs.map +1 -0
  92. package/dist/effect/ports/EffectEventBus.cjs +17 -0
  93. package/dist/effect/ports/EffectEventBus.cjs.map +1 -0
  94. package/dist/effect/ports/EffectEventBus.d.cts +13 -0
  95. package/dist/effect/ports/EffectEventBus.d.ts +13 -0
  96. package/dist/effect/ports/EffectEventBus.mjs +1 -0
  97. package/dist/effect/ports/EffectEventBus.mjs.map +1 -0
  98. package/dist/effect/ports/EffectEventQueries.cjs +17 -0
  99. package/dist/effect/ports/EffectEventQueries.cjs.map +1 -0
  100. package/dist/effect/ports/EffectEventQueries.d.cts +9 -0
  101. package/dist/effect/ports/EffectEventQueries.d.ts +9 -0
  102. package/dist/effect/ports/EffectEventQueries.mjs +1 -0
  103. package/dist/effect/ports/EffectEventQueries.mjs.map +1 -0
  104. package/dist/effect/ports/EffectEventRepository.cjs +17 -0
  105. package/dist/effect/ports/EffectEventRepository.cjs.map +1 -0
  106. package/dist/effect/ports/EffectEventRepository.d.cts +17 -0
  107. package/dist/effect/ports/EffectEventRepository.d.ts +17 -0
  108. package/dist/effect/ports/EffectEventRepository.mjs +1 -0
  109. package/dist/effect/ports/EffectEventRepository.mjs.map +1 -0
  110. package/dist/filterEvents.cjs +48 -0
  111. package/dist/filterEvents.cjs.map +1 -0
  112. package/dist/filterEvents.d.cts +6 -0
  113. package/dist/filterEvents.d.ts +6 -0
  114. package/dist/filterEvents.mjs +24 -0
  115. package/dist/filterEvents.mjs.map +1 -0
  116. package/dist/getSubscriptionIdsToPublish.cjs +40 -0
  117. package/dist/getSubscriptionIdsToPublish.cjs.map +1 -0
  118. package/dist/getSubscriptionIdsToPublish.d.cts +5 -0
  119. package/dist/getSubscriptionIdsToPublish.d.ts +5 -0
  120. package/dist/getSubscriptionIdsToPublish.mjs +16 -0
  121. package/dist/getSubscriptionIdsToPublish.mjs.map +1 -0
  122. package/dist/index.d.cts +1 -1
  123. package/dist/index.d.ts +1 -1
  124. package/dist/ports/EventQueries.cjs.map +1 -1
  125. package/dist/ports/EventQueries.d.cts +1 -1
  126. package/dist/ports/EventQueries.d.ts +1 -1
  127. package/dist/splitIntoChunks.cjs +35 -0
  128. package/dist/splitIntoChunks.cjs.map +1 -0
  129. package/dist/splitIntoChunks.d.cts +3 -0
  130. package/dist/splitIntoChunks.d.ts +3 -0
  131. package/dist/splitIntoChunks.mjs +11 -0
  132. package/dist/splitIntoChunks.mjs.map +1 -0
  133. package/package.json +18 -3
  134. package/src/adapters/effect-kysely/EffectKyselyEventQueries.ts +45 -0
  135. package/src/adapters/effect-kysely/EffectKyselyEventRepository.ts +90 -0
  136. package/src/adapters/effect-kysely/index.ts +3 -0
  137. package/src/adapters/in-memory/InMemoryEventBus.ts +2 -23
  138. package/src/adapters/in-memory/InMemoryEventQueries.ts +2 -32
  139. package/src/adapters/kysely/KyselyEventQueries.ts +27 -31
  140. package/src/adapters/kysely/KyselyEventRepository.ts +66 -64
  141. package/src/adapters/kysely/jsonb.ts +4 -0
  142. package/src/adapters/kysely/mapEventRow.ts +15 -0
  143. package/src/createEventCrawler.ts +1 -8
  144. package/src/effect/EffectEventCrawler.ts +124 -0
  145. package/src/effect/EffectInMemoryEventBus.ts +231 -0
  146. package/src/effect/EffectInMemoryEventQueries.ts +16 -0
  147. package/src/effect/EffectInMemoryEventRepository.ts +68 -0
  148. package/src/effect/EffectSubscriptions.ts +74 -0
  149. package/src/effect/index.ts +26 -0
  150. package/src/effect/ports/EffectEventBus.ts +17 -0
  151. package/src/effect/ports/EffectEventQueries.ts +9 -0
  152. package/src/effect/ports/EffectEventRepository.ts +27 -0
  153. package/src/filterEvents.ts +39 -0
  154. package/src/getSubscriptionIdsToPublish.ts +21 -0
  155. package/src/ports/EventQueries.ts +1 -1
  156. package/src/splitIntoChunks.ts +7 -0
package/README.md CHANGED
@@ -253,6 +253,102 @@ export async function up(db: Kysely<unknown>): Promise<void> {
253
253
  }
254
254
  ```
255
255
 
256
+ ## Effect v4 support
257
+
258
+ Effect-native ports and adapters are available via dedicated subpath exports. Non-Effect users are not impacted — `effect` is an optional peer dependency.
259
+
260
+ ```bash
261
+ bun add @l-etabli/events effect
262
+ ```
263
+
264
+ ### Setup
265
+
266
+ ```ts
267
+ import { Effect } from "effect";
268
+ import type { InferEventsFromDefinitions } from "@l-etabli/events";
269
+ import {
270
+ createEffectInMemoryEventBus,
271
+ createEffectInMemoryEventRepositoryAndQueries,
272
+ createEffectEventCrawler,
273
+ } from "@l-etabli/events/effect";
274
+
275
+ const { eventQueries, withUow } =
276
+ createEffectInMemoryEventRepositoryAndQueries<AppEvents>();
277
+
278
+ const { eventBus, createNewEvent } = createEffectInMemoryEventBus(withUow, {
279
+ eventDefinitions,
280
+ });
281
+
282
+ const crawler = createEffectEventCrawler({
283
+ withUow,
284
+ eventQueries,
285
+ eventBus,
286
+ });
287
+ ```
288
+
289
+ ### Subscribe
290
+
291
+ ```ts
292
+ eventBus.subscribe({
293
+ topic: "ProjectCreated",
294
+ subscriptionId: "send-project-created-email",
295
+ callBack: (event) =>
296
+ Effect.promise(() => emailService.send(event.payload.project.id)),
297
+ });
298
+ ```
299
+
300
+ ### Emit
301
+
302
+ ```ts
303
+ await Effect.runPromise(
304
+ withUow((uow) =>
305
+ uow.eventRepository.saveNewEventsBatch([
306
+ createNewEvent({
307
+ topic: "ProjectCreated",
308
+ payload: { project },
309
+ context: { projectId: project.id },
310
+ triggeredByActor: createUserActor(currentUserId),
311
+ }),
312
+ ]),
313
+ ),
314
+ );
315
+ ```
316
+
317
+ ### Process
318
+
319
+ ```ts
320
+ // Traditional server
321
+ crawler.start();
322
+
323
+ // Serverless / on-demand
324
+ await Effect.runPromise(crawler.triggerProcessing());
325
+ ```
326
+
327
+ ### Kysely adapters
328
+
329
+ For PostgreSQL with Effect-native Kysely:
330
+
331
+ ```ts
332
+ import {
333
+ createEffectKyselyEventRepository,
334
+ createEffectKyselyEventQueries,
335
+ } from "@l-etabli/events/effect-kysely";
336
+
337
+ const eventRepository = createEffectKyselyEventRepository<AppEvents, Db>(db);
338
+ const eventQueries = createEffectKyselyEventQueries<AppEvents, Db>(db);
339
+ ```
340
+
341
+ These adapters wrap Kysely queries with `Effect.promise()` — they work with any standard Kysely instance.
342
+
343
+ ### Subpath exports
344
+
345
+ | Import path | What | Requires |
346
+ |---|---|---|
347
+ | `@l-etabli/events` | Promise-based ports, in-memory adapters, crawler | — |
348
+ | `@l-etabli/events/kysely` | Promise-based Kysely adapters | `kysely` |
349
+ | `@l-etabli/events/effect` | Effect-native ports, in-memory adapters, crawler | `effect` |
350
+ | `@l-etabli/events/effect-kysely` | Effect-native Kysely adapters | `effect`, `kysely` |
351
+
256
352
  ## Examples
257
353
 
258
354
  See [`examples/`](./examples/) for Kysely integration, cascading events and serverless usage.
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var EffectKyselyEventQueries_exports = {};
20
+ __export(EffectKyselyEventQueries_exports, {
21
+ createEffectKyselyEventQueries: () => createEffectKyselyEventQueries
22
+ });
23
+ module.exports = __toCommonJS(EffectKyselyEventQueries_exports);
24
+ var import_effect = require("effect");
25
+ var import_kysely = require("kysely");
26
+ var import_mapEventRow = require("../kysely/mapEventRow.ts");
27
+ const createEffectKyselyEventQueries = (db) => {
28
+ const eventsDb = db;
29
+ return {
30
+ getEvents: ({ filters, limit }) => import_effect.Effect.gen(function* () {
31
+ let query = eventsDb.selectFrom("events").selectAll().where("status", "in", filters.statuses).limit(limit);
32
+ if (filters.context) {
33
+ for (const [key, value] of Object.entries(filters.context)) {
34
+ query = query.where(import_kysely.sql`context->>${key} = ${value}`);
35
+ }
36
+ }
37
+ if (filters.occurredAt?.from) {
38
+ query = query.where("occurredAt", ">=", filters.occurredAt.from);
39
+ }
40
+ if (filters.occurredAt?.to) {
41
+ query = query.where("occurredAt", "<=", filters.occurredAt.to);
42
+ }
43
+ const rows = yield* import_effect.Effect.promise(() => query.execute());
44
+ return rows.map(
45
+ (row) => (0, import_mapEventRow.mapEventRow)(row)
46
+ );
47
+ })
48
+ };
49
+ };
50
+ // Annotate the CommonJS export names for ESM import in node:
51
+ 0 && (module.exports = {
52
+ createEffectKyselyEventQueries
53
+ });
54
+ //# sourceMappingURL=EffectKyselyEventQueries.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/effect-kysely/EffectKyselyEventQueries.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport type { Kysely, SqlBool } from \"kysely\";\nimport { sql } from \"kysely\";\nimport type { EventQueries } from \"../../effect/ports/EffectEventQueries.ts\";\nimport type { DefaultContext, GenericEvent } from \"../../types.ts\";\nimport { mapEventRow } from \"../kysely/mapEventRow.ts\";\nimport type { EventsTable } from \"../kysely/types.ts\";\n\nexport const createEffectKyselyEventQueries = <\n Event extends GenericEvent<string, unknown, DefaultContext>,\n DB extends EventsTable = EventsTable,\n>(\n db: Kysely<DB>,\n): EventQueries<Event> => {\n const eventsDb = db as unknown as Kysely<EventsTable>;\n return {\n getEvents: ({ filters, limit }) =>\n Effect.gen(function* () {\n let query = eventsDb\n .selectFrom(\"events\")\n .selectAll()\n .where(\"status\", \"in\", filters.statuses)\n .limit(limit);\n\n if (filters.context) {\n for (const [key, value] of Object.entries(filters.context)) {\n query = query.where(sql<SqlBool>`context->>${key} = ${value}`);\n }\n }\n\n if (filters.occurredAt?.from) {\n query = query.where(\"occurredAt\", \">=\", filters.occurredAt.from);\n }\n\n if (filters.occurredAt?.to) {\n query = query.where(\"occurredAt\", \"<=\", filters.occurredAt.to);\n }\n\n const rows = yield* Effect.promise(() => query.execute());\n return rows.map((row: EventsTable[\"events\"]) =>\n mapEventRow<Event>(row),\n );\n }),\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAuB;AAEvB,oBAAoB;AAGpB,yBAA4B;AAGrB,MAAM,iCAAiC,CAI5C,OACwB;AACxB,QAAM,WAAW;AACjB,SAAO;AAAA,IACL,WAAW,CAAC,EAAE,SAAS,MAAM,MAC3B,qBAAO,IAAI,aAAa;AACtB,UAAI,QAAQ,SACT,WAAW,QAAQ,EACnB,UAAU,EACV,MAAM,UAAU,MAAM,QAAQ,QAAQ,EACtC,MAAM,KAAK;AAEd,UAAI,QAAQ,SAAS;AACnB,mBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,OAAO,GAAG;AAC1D,kBAAQ,MAAM,MAAM,8BAAyB,GAAG,MAAM,KAAK,EAAE;AAAA,QAC/D;AAAA,MACF;AAEA,UAAI,QAAQ,YAAY,MAAM;AAC5B,gBAAQ,MAAM,MAAM,cAAc,MAAM,QAAQ,WAAW,IAAI;AAAA,MACjE;AAEA,UAAI,QAAQ,YAAY,IAAI;AAC1B,gBAAQ,MAAM,MAAM,cAAc,MAAM,QAAQ,WAAW,EAAE;AAAA,MAC/D;AAEA,YAAM,OAAO,OAAO,qBAAO,QAAQ,MAAM,MAAM,QAAQ,CAAC;AACxD,aAAO,KAAK;AAAA,QAAI,CAAC,YACf,gCAAmB,GAAG;AAAA,MACxB;AAAA,IACF,CAAC;AAAA,EACL;AACF;","names":[]}
@@ -0,0 +1,10 @@
1
+ import { Kysely } from 'kysely';
2
+ import { EventQueries } from '../../effect/ports/EffectEventQueries.cjs';
3
+ import { GenericEvent, DefaultContext } from '../../types.cjs';
4
+ import { EventsTable } from '../kysely/types.cjs';
5
+ import 'effect';
6
+ import '../../ports/EventQueries.cjs';
7
+
8
+ declare const createEffectKyselyEventQueries: <Event extends GenericEvent<string, unknown, DefaultContext>, DB extends EventsTable = EventsTable>(db: Kysely<DB>) => EventQueries<Event>;
9
+
10
+ export { createEffectKyselyEventQueries };
@@ -0,0 +1,10 @@
1
+ import { Kysely } from 'kysely';
2
+ import { EventQueries } from '../../effect/ports/EffectEventQueries.js';
3
+ import { GenericEvent, DefaultContext } from '../../types.js';
4
+ import { EventsTable } from '../kysely/types.js';
5
+ import 'effect';
6
+ import '../../ports/EventQueries.js';
7
+
8
+ declare const createEffectKyselyEventQueries: <Event extends GenericEvent<string, unknown, DefaultContext>, DB extends EventsTable = EventsTable>(db: Kysely<DB>) => EventQueries<Event>;
9
+
10
+ export { createEffectKyselyEventQueries };
@@ -0,0 +1,30 @@
1
+ import { Effect } from "effect";
2
+ import { sql } from "kysely";
3
+ import { mapEventRow } from "../kysely/mapEventRow.mjs";
4
+ const createEffectKyselyEventQueries = (db) => {
5
+ const eventsDb = db;
6
+ return {
7
+ getEvents: ({ filters, limit }) => Effect.gen(function* () {
8
+ let query = eventsDb.selectFrom("events").selectAll().where("status", "in", filters.statuses).limit(limit);
9
+ if (filters.context) {
10
+ for (const [key, value] of Object.entries(filters.context)) {
11
+ query = query.where(sql`context->>${key} = ${value}`);
12
+ }
13
+ }
14
+ if (filters.occurredAt?.from) {
15
+ query = query.where("occurredAt", ">=", filters.occurredAt.from);
16
+ }
17
+ if (filters.occurredAt?.to) {
18
+ query = query.where("occurredAt", "<=", filters.occurredAt.to);
19
+ }
20
+ const rows = yield* Effect.promise(() => query.execute());
21
+ return rows.map(
22
+ (row) => mapEventRow(row)
23
+ );
24
+ })
25
+ };
26
+ };
27
+ export {
28
+ createEffectKyselyEventQueries
29
+ };
30
+ //# sourceMappingURL=EffectKyselyEventQueries.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/effect-kysely/EffectKyselyEventQueries.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport type { Kysely, SqlBool } from \"kysely\";\nimport { sql } from \"kysely\";\nimport type { EventQueries } from '../../effect/ports/EffectEventQueries.mjs';\nimport type { DefaultContext, GenericEvent } from '../../types.mjs';\nimport { mapEventRow } from '../kysely/mapEventRow.mjs';\nimport type { EventsTable } from '../kysely/types.mjs';\n\nexport const createEffectKyselyEventQueries = <\n Event extends GenericEvent<string, unknown, DefaultContext>,\n DB extends EventsTable = EventsTable,\n>(\n db: Kysely<DB>,\n): EventQueries<Event> => {\n const eventsDb = db as unknown as Kysely<EventsTable>;\n return {\n getEvents: ({ filters, limit }) =>\n Effect.gen(function* () {\n let query = eventsDb\n .selectFrom(\"events\")\n .selectAll()\n .where(\"status\", \"in\", filters.statuses)\n .limit(limit);\n\n if (filters.context) {\n for (const [key, value] of Object.entries(filters.context)) {\n query = query.where(sql<SqlBool>`context->>${key} = ${value}`);\n }\n }\n\n if (filters.occurredAt?.from) {\n query = query.where(\"occurredAt\", \">=\", filters.occurredAt.from);\n }\n\n if (filters.occurredAt?.to) {\n query = query.where(\"occurredAt\", \"<=\", filters.occurredAt.to);\n }\n\n const rows = yield* Effect.promise(() => query.execute());\n return rows.map((row: EventsTable[\"events\"]) =>\n mapEventRow<Event>(row),\n );\n }),\n };\n};\n"],"mappings":"AAAA,SAAS,cAAc;AAEvB,SAAS,WAAW;AAGpB,SAAS,mBAAmB;AAGrB,MAAM,iCAAiC,CAI5C,OACwB;AACxB,QAAM,WAAW;AACjB,SAAO;AAAA,IACL,WAAW,CAAC,EAAE,SAAS,MAAM,MAC3B,OAAO,IAAI,aAAa;AACtB,UAAI,QAAQ,SACT,WAAW,QAAQ,EACnB,UAAU,EACV,MAAM,UAAU,MAAM,QAAQ,QAAQ,EACtC,MAAM,KAAK;AAEd,UAAI,QAAQ,SAAS;AACnB,mBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,OAAO,GAAG;AAC1D,kBAAQ,MAAM,MAAM,gBAAyB,GAAG,MAAM,KAAK,EAAE;AAAA,QAC/D;AAAA,MACF;AAEA,UAAI,QAAQ,YAAY,MAAM;AAC5B,gBAAQ,MAAM,MAAM,cAAc,MAAM,QAAQ,WAAW,IAAI;AAAA,MACjE;AAEA,UAAI,QAAQ,YAAY,IAAI;AAC1B,gBAAQ,MAAM,MAAM,cAAc,MAAM,QAAQ,WAAW,EAAE;AAAA,MAC/D;AAEA,YAAM,OAAO,OAAO,OAAO,QAAQ,MAAM,MAAM,QAAQ,CAAC;AACxD,aAAO,KAAK;AAAA,QAAI,CAAC,QACf,YAAmB,GAAG;AAAA,MACxB;AAAA,IACF,CAAC;AAAA,EACL;AACF;","names":[]}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var EffectKyselyEventRepository_exports = {};
20
+ __export(EffectKyselyEventRepository_exports, {
21
+ createEffectKyselyEventRepository: () => createEffectKyselyEventRepository
22
+ });
23
+ module.exports = __toCommonJS(EffectKyselyEventRepository_exports);
24
+ var import_effect = require("effect");
25
+ var import_jsonb = require("../kysely/jsonb.ts");
26
+ const createEffectKyselyEventRepository = (db) => {
27
+ const eventsDb = db;
28
+ return {
29
+ save: (event) => import_effect.Effect.promise(
30
+ () => eventsDb.insertInto("events").values({
31
+ ...event,
32
+ payload: (0, import_jsonb.jsonb)(event.payload),
33
+ triggeredByActor: (0, import_jsonb.jsonb)(event.triggeredByActor),
34
+ context: (0, import_jsonb.jsonb)(event.context),
35
+ publications: (0, import_jsonb.jsonb)(event.publications)
36
+ }).onConflict(
37
+ (oc) => oc.column("id").doUpdateSet({
38
+ topic: event.topic,
39
+ payload: (0, import_jsonb.jsonb)(event.payload),
40
+ triggeredByActor: (0, import_jsonb.jsonb)(event.triggeredByActor),
41
+ context: (0, import_jsonb.jsonb)(event.context),
42
+ status: event.status,
43
+ flowId: event.flowId,
44
+ causedByEventId: event.causedByEventId,
45
+ occurredAt: event.occurredAt,
46
+ publications: (0, import_jsonb.jsonb)(event.publications),
47
+ priority: event.priority
48
+ })
49
+ ).execute()
50
+ ).pipe(import_effect.Effect.asVoid),
51
+ saveNewEventsBatch: (events) => {
52
+ if (events.length === 0) return import_effect.Effect.void;
53
+ return import_effect.Effect.promise(
54
+ () => eventsDb.insertInto("events").values(
55
+ events.map((event) => ({
56
+ ...event,
57
+ payload: (0, import_jsonb.jsonb)(event.payload),
58
+ triggeredByActor: (0, import_jsonb.jsonb)(event.triggeredByActor),
59
+ context: (0, import_jsonb.jsonb)(event.context),
60
+ publications: (0, import_jsonb.jsonb)(event.publications)
61
+ }))
62
+ ).execute()
63
+ ).pipe(import_effect.Effect.asVoid);
64
+ },
65
+ markEventsAsInProcess: (events) => {
66
+ if (events.length === 0) return import_effect.Effect.void;
67
+ const ids = events.map((e) => e.id);
68
+ return import_effect.Effect.gen(function* () {
69
+ const lockedRows = yield* import_effect.Effect.promise(
70
+ () => eventsDb.selectFrom("events").select("id").where("id", "in", ids).forUpdate().skipLocked().execute()
71
+ );
72
+ if (lockedRows.length === 0) return;
73
+ const lockedIds = lockedRows.map((r) => r.id);
74
+ yield* import_effect.Effect.promise(
75
+ () => eventsDb.updateTable("events").set({ status: "in-process" }).where("id", "in", lockedIds).execute()
76
+ ).pipe(import_effect.Effect.asVoid);
77
+ });
78
+ }
79
+ };
80
+ };
81
+ // Annotate the CommonJS export names for ESM import in node:
82
+ 0 && (module.exports = {
83
+ createEffectKyselyEventRepository
84
+ });
85
+ //# sourceMappingURL=EffectKyselyEventRepository.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/effect-kysely/EffectKyselyEventRepository.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport type { Kysely } from \"kysely\";\nimport type { EventRepository } from \"../../effect/ports/EffectEventRepository.ts\";\nimport type { DefaultContext, GenericEvent } from \"../../types.ts\";\nimport { jsonb } from \"../kysely/jsonb.ts\";\nimport type { EventsTable } from \"../kysely/types.ts\";\n\nexport const createEffectKyselyEventRepository = <\n Event extends GenericEvent<string, unknown, DefaultContext>,\n DB extends EventsTable = EventsTable,\n>(\n db: Kysely<DB>,\n): EventRepository<Event> => {\n const eventsDb = db as unknown as Kysely<EventsTable>;\n return {\n save: (event) =>\n Effect.promise(() =>\n eventsDb\n .insertInto(\"events\")\n .values({\n ...event,\n payload: jsonb(event.payload),\n triggeredByActor: jsonb(event.triggeredByActor),\n context: jsonb(event.context),\n publications: jsonb(event.publications),\n })\n .onConflict((oc) =>\n oc.column(\"id\").doUpdateSet({\n topic: event.topic,\n payload: jsonb(event.payload),\n triggeredByActor: jsonb(event.triggeredByActor),\n context: jsonb(event.context),\n status: event.status,\n flowId: event.flowId,\n causedByEventId: event.causedByEventId,\n occurredAt: event.occurredAt,\n publications: jsonb(event.publications),\n priority: event.priority,\n }),\n )\n .execute(),\n ).pipe(Effect.asVoid),\n\n saveNewEventsBatch: (events) => {\n if (events.length === 0) return Effect.void;\n return Effect.promise(() =>\n eventsDb\n .insertInto(\"events\")\n .values(\n events.map((event) => ({\n ...event,\n payload: jsonb(event.payload),\n triggeredByActor: jsonb(event.triggeredByActor),\n context: jsonb(event.context),\n publications: jsonb(event.publications),\n })),\n )\n .execute(),\n ).pipe(Effect.asVoid);\n },\n\n markEventsAsInProcess: (events) => {\n if (events.length === 0) return Effect.void;\n const ids = events.map((e) => e.id);\n\n return Effect.gen(function* () {\n const lockedRows = yield* Effect.promise(() =>\n eventsDb\n .selectFrom(\"events\")\n .select(\"id\")\n .where(\"id\", \"in\", ids)\n .forUpdate()\n .skipLocked()\n .execute(),\n );\n\n if (lockedRows.length === 0) return;\n const lockedIds = lockedRows.map((r) => r.id);\n\n yield* Effect.promise(() =>\n eventsDb\n .updateTable(\"events\")\n .set({ status: \"in-process\" })\n .where(\"id\", \"in\", lockedIds)\n .execute(),\n ).pipe(Effect.asVoid);\n });\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAuB;AAIvB,mBAAsB;AAGf,MAAM,oCAAoC,CAI/C,OAC2B;AAC3B,QAAM,WAAW;AACjB,SAAO;AAAA,IACL,MAAM,CAAC,UACL,qBAAO;AAAA,MAAQ,MACb,SACG,WAAW,QAAQ,EACnB,OAAO;AAAA,QACN,GAAG;AAAA,QACH,aAAS,oBAAM,MAAM,OAAO;AAAA,QAC5B,sBAAkB,oBAAM,MAAM,gBAAgB;AAAA,QAC9C,aAAS,oBAAM,MAAM,OAAO;AAAA,QAC5B,kBAAc,oBAAM,MAAM,YAAY;AAAA,MACxC,CAAC,EACA;AAAA,QAAW,CAAC,OACX,GAAG,OAAO,IAAI,EAAE,YAAY;AAAA,UAC1B,OAAO,MAAM;AAAA,UACb,aAAS,oBAAM,MAAM,OAAO;AAAA,UAC5B,sBAAkB,oBAAM,MAAM,gBAAgB;AAAA,UAC9C,aAAS,oBAAM,MAAM,OAAO;AAAA,UAC5B,QAAQ,MAAM;AAAA,UACd,QAAQ,MAAM;AAAA,UACd,iBAAiB,MAAM;AAAA,UACvB,YAAY,MAAM;AAAA,UAClB,kBAAc,oBAAM,MAAM,YAAY;AAAA,UACtC,UAAU,MAAM;AAAA,QAClB,CAAC;AAAA,MACH,EACC,QAAQ;AAAA,IACb,EAAE,KAAK,qBAAO,MAAM;AAAA,IAEtB,oBAAoB,CAAC,WAAW;AAC9B,UAAI,OAAO,WAAW,EAAG,QAAO,qBAAO;AACvC,aAAO,qBAAO;AAAA,QAAQ,MACpB,SACG,WAAW,QAAQ,EACnB;AAAA,UACC,OAAO,IAAI,CAAC,WAAW;AAAA,YACrB,GAAG;AAAA,YACH,aAAS,oBAAM,MAAM,OAAO;AAAA,YAC5B,sBAAkB,oBAAM,MAAM,gBAAgB;AAAA,YAC9C,aAAS,oBAAM,MAAM,OAAO;AAAA,YAC5B,kBAAc,oBAAM,MAAM,YAAY;AAAA,UACxC,EAAE;AAAA,QACJ,EACC,QAAQ;AAAA,MACb,EAAE,KAAK,qBAAO,MAAM;AAAA,IACtB;AAAA,IAEA,uBAAuB,CAAC,WAAW;AACjC,UAAI,OAAO,WAAW,EAAG,QAAO,qBAAO;AACvC,YAAM,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE;AAElC,aAAO,qBAAO,IAAI,aAAa;AAC7B,cAAM,aAAa,OAAO,qBAAO;AAAA,UAAQ,MACvC,SACG,WAAW,QAAQ,EACnB,OAAO,IAAI,EACX,MAAM,MAAM,MAAM,GAAG,EACrB,UAAU,EACV,WAAW,EACX,QAAQ;AAAA,QACb;AAEA,YAAI,WAAW,WAAW,EAAG;AAC7B,cAAM,YAAY,WAAW,IAAI,CAAC,MAAM,EAAE,EAAE;AAE5C,eAAO,qBAAO;AAAA,UAAQ,MACpB,SACG,YAAY,QAAQ,EACpB,IAAI,EAAE,QAAQ,aAAa,CAAC,EAC5B,MAAM,MAAM,MAAM,SAAS,EAC3B,QAAQ;AAAA,QACb,EAAE,KAAK,qBAAO,MAAM;AAAA,MACtB,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,9 @@
1
+ import { Kysely } from 'kysely';
2
+ import { EventRepository } from '../../effect/ports/EffectEventRepository.cjs';
3
+ import { GenericEvent, DefaultContext } from '../../types.cjs';
4
+ import { EventsTable } from '../kysely/types.cjs';
5
+ import 'effect';
6
+
7
+ declare const createEffectKyselyEventRepository: <Event extends GenericEvent<string, unknown, DefaultContext>, DB extends EventsTable = EventsTable>(db: Kysely<DB>) => EventRepository<Event>;
8
+
9
+ export { createEffectKyselyEventRepository };
@@ -0,0 +1,9 @@
1
+ import { Kysely } from 'kysely';
2
+ import { EventRepository } from '../../effect/ports/EffectEventRepository.js';
3
+ import { GenericEvent, DefaultContext } from '../../types.js';
4
+ import { EventsTable } from '../kysely/types.js';
5
+ import 'effect';
6
+
7
+ declare const createEffectKyselyEventRepository: <Event extends GenericEvent<string, unknown, DefaultContext>, DB extends EventsTable = EventsTable>(db: Kysely<DB>) => EventRepository<Event>;
8
+
9
+ export { createEffectKyselyEventRepository };
@@ -0,0 +1,61 @@
1
+ import { Effect } from "effect";
2
+ import { jsonb } from "../kysely/jsonb.mjs";
3
+ const createEffectKyselyEventRepository = (db) => {
4
+ const eventsDb = db;
5
+ return {
6
+ save: (event) => Effect.promise(
7
+ () => eventsDb.insertInto("events").values({
8
+ ...event,
9
+ payload: jsonb(event.payload),
10
+ triggeredByActor: jsonb(event.triggeredByActor),
11
+ context: jsonb(event.context),
12
+ publications: jsonb(event.publications)
13
+ }).onConflict(
14
+ (oc) => oc.column("id").doUpdateSet({
15
+ topic: event.topic,
16
+ payload: jsonb(event.payload),
17
+ triggeredByActor: jsonb(event.triggeredByActor),
18
+ context: jsonb(event.context),
19
+ status: event.status,
20
+ flowId: event.flowId,
21
+ causedByEventId: event.causedByEventId,
22
+ occurredAt: event.occurredAt,
23
+ publications: jsonb(event.publications),
24
+ priority: event.priority
25
+ })
26
+ ).execute()
27
+ ).pipe(Effect.asVoid),
28
+ saveNewEventsBatch: (events) => {
29
+ if (events.length === 0) return Effect.void;
30
+ return Effect.promise(
31
+ () => eventsDb.insertInto("events").values(
32
+ events.map((event) => ({
33
+ ...event,
34
+ payload: jsonb(event.payload),
35
+ triggeredByActor: jsonb(event.triggeredByActor),
36
+ context: jsonb(event.context),
37
+ publications: jsonb(event.publications)
38
+ }))
39
+ ).execute()
40
+ ).pipe(Effect.asVoid);
41
+ },
42
+ markEventsAsInProcess: (events) => {
43
+ if (events.length === 0) return Effect.void;
44
+ const ids = events.map((e) => e.id);
45
+ return Effect.gen(function* () {
46
+ const lockedRows = yield* Effect.promise(
47
+ () => eventsDb.selectFrom("events").select("id").where("id", "in", ids).forUpdate().skipLocked().execute()
48
+ );
49
+ if (lockedRows.length === 0) return;
50
+ const lockedIds = lockedRows.map((r) => r.id);
51
+ yield* Effect.promise(
52
+ () => eventsDb.updateTable("events").set({ status: "in-process" }).where("id", "in", lockedIds).execute()
53
+ ).pipe(Effect.asVoid);
54
+ });
55
+ }
56
+ };
57
+ };
58
+ export {
59
+ createEffectKyselyEventRepository
60
+ };
61
+ //# sourceMappingURL=EffectKyselyEventRepository.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/effect-kysely/EffectKyselyEventRepository.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport type { Kysely } from \"kysely\";\nimport type { EventRepository } from '../../effect/ports/EffectEventRepository.mjs';\nimport type { DefaultContext, GenericEvent } from '../../types.mjs';\nimport { jsonb } from '../kysely/jsonb.mjs';\nimport type { EventsTable } from '../kysely/types.mjs';\n\nexport const createEffectKyselyEventRepository = <\n Event extends GenericEvent<string, unknown, DefaultContext>,\n DB extends EventsTable = EventsTable,\n>(\n db: Kysely<DB>,\n): EventRepository<Event> => {\n const eventsDb = db as unknown as Kysely<EventsTable>;\n return {\n save: (event) =>\n Effect.promise(() =>\n eventsDb\n .insertInto(\"events\")\n .values({\n ...event,\n payload: jsonb(event.payload),\n triggeredByActor: jsonb(event.triggeredByActor),\n context: jsonb(event.context),\n publications: jsonb(event.publications),\n })\n .onConflict((oc) =>\n oc.column(\"id\").doUpdateSet({\n topic: event.topic,\n payload: jsonb(event.payload),\n triggeredByActor: jsonb(event.triggeredByActor),\n context: jsonb(event.context),\n status: event.status,\n flowId: event.flowId,\n causedByEventId: event.causedByEventId,\n occurredAt: event.occurredAt,\n publications: jsonb(event.publications),\n priority: event.priority,\n }),\n )\n .execute(),\n ).pipe(Effect.asVoid),\n\n saveNewEventsBatch: (events) => {\n if (events.length === 0) return Effect.void;\n return Effect.promise(() =>\n eventsDb\n .insertInto(\"events\")\n .values(\n events.map((event) => ({\n ...event,\n payload: jsonb(event.payload),\n triggeredByActor: jsonb(event.triggeredByActor),\n context: jsonb(event.context),\n publications: jsonb(event.publications),\n })),\n )\n .execute(),\n ).pipe(Effect.asVoid);\n },\n\n markEventsAsInProcess: (events) => {\n if (events.length === 0) return Effect.void;\n const ids = events.map((e) => e.id);\n\n return Effect.gen(function* () {\n const lockedRows = yield* Effect.promise(() =>\n eventsDb\n .selectFrom(\"events\")\n .select(\"id\")\n .where(\"id\", \"in\", ids)\n .forUpdate()\n .skipLocked()\n .execute(),\n );\n\n if (lockedRows.length === 0) return;\n const lockedIds = lockedRows.map((r) => r.id);\n\n yield* Effect.promise(() =>\n eventsDb\n .updateTable(\"events\")\n .set({ status: \"in-process\" })\n .where(\"id\", \"in\", lockedIds)\n .execute(),\n ).pipe(Effect.asVoid);\n });\n },\n };\n};\n"],"mappings":"AAAA,SAAS,cAAc;AAIvB,SAAS,aAAa;AAGf,MAAM,oCAAoC,CAI/C,OAC2B;AAC3B,QAAM,WAAW;AACjB,SAAO;AAAA,IACL,MAAM,CAAC,UACL,OAAO;AAAA,MAAQ,MACb,SACG,WAAW,QAAQ,EACnB,OAAO;AAAA,QACN,GAAG;AAAA,QACH,SAAS,MAAM,MAAM,OAAO;AAAA,QAC5B,kBAAkB,MAAM,MAAM,gBAAgB;AAAA,QAC9C,SAAS,MAAM,MAAM,OAAO;AAAA,QAC5B,cAAc,MAAM,MAAM,YAAY;AAAA,MACxC,CAAC,EACA;AAAA,QAAW,CAAC,OACX,GAAG,OAAO,IAAI,EAAE,YAAY;AAAA,UAC1B,OAAO,MAAM;AAAA,UACb,SAAS,MAAM,MAAM,OAAO;AAAA,UAC5B,kBAAkB,MAAM,MAAM,gBAAgB;AAAA,UAC9C,SAAS,MAAM,MAAM,OAAO;AAAA,UAC5B,QAAQ,MAAM;AAAA,UACd,QAAQ,MAAM;AAAA,UACd,iBAAiB,MAAM;AAAA,UACvB,YAAY,MAAM;AAAA,UAClB,cAAc,MAAM,MAAM,YAAY;AAAA,UACtC,UAAU,MAAM;AAAA,QAClB,CAAC;AAAA,MACH,EACC,QAAQ;AAAA,IACb,EAAE,KAAK,OAAO,MAAM;AAAA,IAEtB,oBAAoB,CAAC,WAAW;AAC9B,UAAI,OAAO,WAAW,EAAG,QAAO,OAAO;AACvC,aAAO,OAAO;AAAA,QAAQ,MACpB,SACG,WAAW,QAAQ,EACnB;AAAA,UACC,OAAO,IAAI,CAAC,WAAW;AAAA,YACrB,GAAG;AAAA,YACH,SAAS,MAAM,MAAM,OAAO;AAAA,YAC5B,kBAAkB,MAAM,MAAM,gBAAgB;AAAA,YAC9C,SAAS,MAAM,MAAM,OAAO;AAAA,YAC5B,cAAc,MAAM,MAAM,YAAY;AAAA,UACxC,EAAE;AAAA,QACJ,EACC,QAAQ;AAAA,MACb,EAAE,KAAK,OAAO,MAAM;AAAA,IACtB;AAAA,IAEA,uBAAuB,CAAC,WAAW;AACjC,UAAI,OAAO,WAAW,EAAG,QAAO,OAAO;AACvC,YAAM,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE;AAElC,aAAO,OAAO,IAAI,aAAa;AAC7B,cAAM,aAAa,OAAO,OAAO;AAAA,UAAQ,MACvC,SACG,WAAW,QAAQ,EACnB,OAAO,IAAI,EACX,MAAM,MAAM,MAAM,GAAG,EACrB,UAAU,EACV,WAAW,EACX,QAAQ;AAAA,QACb;AAEA,YAAI,WAAW,WAAW,EAAG;AAC7B,cAAM,YAAY,WAAW,IAAI,CAAC,MAAM,EAAE,EAAE;AAE5C,eAAO,OAAO;AAAA,UAAQ,MACpB,SACG,YAAY,QAAQ,EACpB,IAAI,EAAE,QAAQ,aAAa,CAAC,EAC5B,MAAM,MAAM,MAAM,SAAS,EAC3B,QAAQ;AAAA,QACb,EAAE,KAAK,OAAO,MAAM;AAAA,MACtB,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var effect_kysely_exports = {};
20
+ __export(effect_kysely_exports, {
21
+ createEffectKyselyEventQueries: () => import_EffectKyselyEventQueries.createEffectKyselyEventQueries,
22
+ createEffectKyselyEventRepository: () => import_EffectKyselyEventRepository.createEffectKyselyEventRepository
23
+ });
24
+ module.exports = __toCommonJS(effect_kysely_exports);
25
+ var import_EffectKyselyEventQueries = require("./EffectKyselyEventQueries.ts");
26
+ var import_EffectKyselyEventRepository = require("./EffectKyselyEventRepository.ts");
27
+ // Annotate the CommonJS export names for ESM import in node:
28
+ 0 && (module.exports = {
29
+ createEffectKyselyEventQueries,
30
+ createEffectKyselyEventRepository
31
+ });
32
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/effect-kysely/index.ts"],"sourcesContent":["export type { EventsTable, TypedEventsTable } from \"../kysely/types.ts\";\nexport { createEffectKyselyEventQueries } from \"./EffectKyselyEventQueries.ts\";\nexport { createEffectKyselyEventRepository } from \"./EffectKyselyEventRepository.ts\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,sCAA+C;AAC/C,yCAAkD;","names":[]}
@@ -0,0 +1,9 @@
1
+ export { EventsTable, TypedEventsTable } from '../kysely/types.cjs';
2
+ export { createEffectKyselyEventQueries } from './EffectKyselyEventQueries.cjs';
3
+ export { createEffectKyselyEventRepository } from './EffectKyselyEventRepository.cjs';
4
+ import '../../types.cjs';
5
+ import 'kysely';
6
+ import '../../effect/ports/EffectEventQueries.cjs';
7
+ import 'effect';
8
+ import '../../ports/EventQueries.cjs';
9
+ import '../../effect/ports/EffectEventRepository.cjs';
@@ -0,0 +1,9 @@
1
+ export { EventsTable, TypedEventsTable } from '../kysely/types.js';
2
+ export { createEffectKyselyEventQueries } from './EffectKyselyEventQueries.js';
3
+ export { createEffectKyselyEventRepository } from './EffectKyselyEventRepository.js';
4
+ import '../../types.js';
5
+ import 'kysely';
6
+ import '../../effect/ports/EffectEventQueries.js';
7
+ import 'effect';
8
+ import '../../ports/EventQueries.js';
9
+ import '../../effect/ports/EffectEventRepository.js';
@@ -0,0 +1,7 @@
1
+ import { createEffectKyselyEventQueries } from "./EffectKyselyEventQueries.mjs";
2
+ import { createEffectKyselyEventRepository } from "./EffectKyselyEventRepository.mjs";
3
+ export {
4
+ createEffectKyselyEventQueries,
5
+ createEffectKyselyEventRepository
6
+ };
7
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/effect-kysely/index.ts"],"sourcesContent":["export type { EventsTable, TypedEventsTable } from '../kysely/types.mjs';\nexport { createEffectKyselyEventQueries } from './EffectKyselyEventQueries.mjs';\nexport { createEffectKyselyEventRepository } from './EffectKyselyEventRepository.mjs';\n"],"mappings":"AACA,SAAS,sCAAsC;AAC/C,SAAS,yCAAyC;","names":[]}
@@ -22,6 +22,7 @@ __export(InMemoryEventBus_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(InMemoryEventBus_exports);
24
24
  var import_createNewEvent = require("../../createNewEvent.ts");
25
+ var import_getSubscriptionIdsToPublish = require("../../getSubscriptionIdsToPublish.ts");
25
26
  var import_subscriptions = require("../../subscriptions.ts");
26
27
  function createInMemoryEventBus(withUow, options = {}) {
27
28
  const maxRetries = options.maxRetries ?? 3;
@@ -46,21 +47,6 @@ function createInMemoryEventBus(withUow, options = {}) {
46
47
  };
47
48
  }
48
49
  };
49
- const getSubscriptionIdsToPublish = (event, callbacksBySubscriptionId) => {
50
- const allSubscriptionIds = Object.keys(callbacksBySubscriptionId);
51
- if (event.publications.length === 0 || event.status === "to-republish") {
52
- return allSubscriptionIds;
53
- }
54
- const lastPublication = event.publications.reduce(
55
- (latest, current) => current.publishedAt > latest.publishedAt ? current : latest
56
- );
57
- const failedSubscriptionIds = (lastPublication.failures ?? []).map(
58
- (failure) => failure.subscriptionId
59
- );
60
- return allSubscriptionIds.filter(
61
- (id) => failedSubscriptionIds.includes(id)
62
- );
63
- };
64
50
  const eventBus = {
65
51
  publish: async (event) => {
66
52
  const publishedAt = /* @__PURE__ */ new Date();
@@ -77,9 +63,9 @@ function createInMemoryEventBus(withUow, options = {}) {
77
63
  });
78
64
  return;
79
65
  }
80
- const subscriptionIdsToPublish = getSubscriptionIdsToPublish(
66
+ const subscriptionIdsToPublish = (0, import_getSubscriptionIdsToPublish.getSubscriptionIdsToPublish)(
81
67
  event,
82
- callbacksBySubscriptionSlug
68
+ Object.keys(callbacksBySubscriptionSlug)
83
69
  );
84
70
  const failuresOrUndefined = await Promise.all(
85
71
  subscriptionIdsToPublish.map(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/adapters/in-memory/InMemoryEventBus.ts"],"sourcesContent":["import {\n type CreateNewEvent,\n type CreateNewEventFromDefinitions,\n makeCreateNewEvent,\n} from \"../../createNewEvent.ts\";\nimport type {\n EventDefinitions,\n InferEventsFromDefinitions,\n} from \"../../eventDefinitions.ts\";\nimport type { EventBus } from \"../../ports/EventBus.ts\";\nimport type { WithEventsUow } from \"../../ports/EventRepository.ts\";\nimport {\n type GlobalSubscriberConfig,\n subscribeByTopic,\n subscribeGlobalToTopics,\n type TopicSubscriptions,\n} from \"../../subscriptions.ts\";\nimport type {\n DefaultContext,\n EventId,\n EventPublication,\n GenericEvent,\n SubscriptionId,\n} from \"../../types.ts\";\n\ntype SubscriptionsForTopic = Record<\n string,\n (event: GenericEvent<string, unknown, DefaultContext>) => Promise<void>\n>;\n\ntype CreateInMemoryEventBusOptions = {\n maxRetries?: number;\n getNow?: () => Date;\n generateId?: () => EventId;\n};\n\ntype CreateInMemoryEventBusFromDefinitionsOptions<\n Definitions extends EventDefinitions,\n> = CreateInMemoryEventBusOptions & {\n eventDefinitions: Definitions;\n};\n\ntype CreateInMemoryEventBusResult<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n> = {\n eventBus: EventBus<Event>;\n createNewEvent: CreateNewEvent<Event>;\n defineSubscriptions: (\n subscriptions: TopicSubscriptions<Event>,\n ) => TopicSubscriptions<Event>;\n subscribeAll: (subscriptions: TopicSubscriptions<Event>) => void;\n subscribeGlobal: (\n subscriptions: TopicSubscriptions<Event>,\n config: GlobalSubscriberConfig<Event>,\n ) => void;\n};\n\nexport function createInMemoryEventBus<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n>(\n withUow: WithEventsUow<Event>,\n options?: CreateInMemoryEventBusOptions,\n): CreateInMemoryEventBusResult<Event>;\nexport function createInMemoryEventBus<Definitions extends EventDefinitions>(\n withUow: WithEventsUow<InferEventsFromDefinitions<Definitions>>,\n options: CreateInMemoryEventBusFromDefinitionsOptions<Definitions>,\n): Omit<\n CreateInMemoryEventBusResult<InferEventsFromDefinitions<Definitions>>,\n \"createNewEvent\"\n> & {\n createNewEvent: CreateNewEventFromDefinitions<Definitions>;\n};\nexport function createInMemoryEventBus<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n>(\n withUow: WithEventsUow<Event>,\n options:\n | CreateInMemoryEventBusOptions\n | CreateInMemoryEventBusFromDefinitionsOptions<EventDefinitions> = {},\n) {\n const maxRetries = options.maxRetries ?? 3;\n const eventDefinitions =\n \"eventDefinitions\" in options ? options.eventDefinitions : undefined;\n const createNewEvent = eventDefinitions\n ? makeCreateNewEvent({\n getNow: options.getNow,\n generateId: options.generateId,\n eventDefinitions,\n })\n : makeCreateNewEvent<Event>({\n getNow: options.getNow,\n generateId: options.generateId,\n });\n const subscriptions: Partial<Record<string, SubscriptionsForTopic>> = {};\n\n const executeCallback = async (\n event: Event,\n subscriptionId: string,\n callback: (\n event: GenericEvent<string, unknown, DefaultContext>,\n ) => Promise<void>,\n ): Promise<\n { subscriptionId: string; errorMessage: string; stack?: string } | undefined\n > => {\n try {\n await callback(event);\n } catch (error) {\n return {\n subscriptionId,\n errorMessage: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n };\n }\n };\n\n const getSubscriptionIdsToPublish = (\n event: Event,\n callbacksBySubscriptionId: SubscriptionsForTopic,\n ): string[] => {\n const allSubscriptionIds = Object.keys(callbacksBySubscriptionId);\n\n if (event.publications.length === 0 || event.status === \"to-republish\") {\n return allSubscriptionIds;\n }\n\n const lastPublication = event.publications.reduce((latest, current) =>\n current.publishedAt > latest.publishedAt ? current : latest,\n );\n const failedSubscriptionIds = (lastPublication.failures ?? []).map(\n (failure) => failure.subscriptionId,\n );\n\n return allSubscriptionIds.filter((id) =>\n failedSubscriptionIds.includes(id),\n );\n };\n\n const eventBus: EventBus<Event> = {\n publish: async (event) => {\n const publishedAt = new Date();\n const topic = event.topic;\n\n const callbacksBySubscriptionSlug = subscriptions[topic];\n\n if (!callbacksBySubscriptionSlug) {\n event.publications.push({\n publishedAt,\n publishedSubscribers: [],\n });\n event.status = \"published\";\n await withUow(async (uow) => {\n await uow.eventRepository.save(event);\n });\n return;\n }\n\n const subscriptionIdsToPublish = getSubscriptionIdsToPublish(\n event,\n callbacksBySubscriptionSlug,\n );\n\n const failuresOrUndefined = await Promise.all(\n subscriptionIdsToPublish.map((subscriptionId) =>\n executeCallback(\n event,\n subscriptionId,\n callbacksBySubscriptionSlug[subscriptionId],\n ),\n ),\n );\n\n const failures = failuresOrUndefined.filter(\n (\n f,\n ): f is {\n subscriptionId: string;\n errorMessage: string;\n stack?: string;\n } => f !== undefined,\n );\n\n const publications: EventPublication[] = [\n ...event.publications,\n {\n publishedAt,\n publishedSubscribers: subscriptionIdsToPublish.map(\n (id) => id as SubscriptionId,\n ),\n ...(failures.length > 0 && { failures }),\n },\n ];\n\n if (failures.length === 0) {\n event.status = \"published\";\n } else {\n const wasMaxNumberOfErrorsReached = publications.length >= maxRetries;\n event.status = wasMaxNumberOfErrorsReached\n ? \"quarantined\"\n : \"failed-but-will-retry\";\n }\n\n event.publications = publications;\n\n await withUow(async (uow) => {\n await uow.eventRepository.save(event);\n });\n },\n\n subscribe: ({ topic, subscriptionId, callBack }) => {\n if (!subscriptions[topic]) {\n subscriptions[topic] = {};\n }\n\n const subscriptionsForTopic = subscriptions[topic];\n if (subscriptionsForTopic) {\n subscriptionsForTopic[subscriptionId] = callBack as (\n event: GenericEvent<string, unknown, DefaultContext>,\n ) => Promise<void>;\n }\n },\n };\n\n /**\n * Identity function for type inference when defining subscription maps.\n * Ensures all topics are covered and handlers have correct payload types.\n *\n * @example\n * ```typescript\n * const subscriptions = defineSubscriptions({\n * OrderCreated: [{ subscriptionId: \"notify\", handler: async (e) => {...} }],\n * OrderShipped: [], // Required even if empty\n * });\n * ```\n */\n const defineSubscriptions = (\n subscriptions: TopicSubscriptions<Event>,\n ): TopicSubscriptions<Event> => subscriptions;\n\n /**\n * Subscribe all handlers from a topic subscription map to this event bus.\n *\n * @example\n * ```typescript\n * const subscriptions = defineSubscriptions({...});\n * subscribeAll(subscriptions);\n * ```\n */\n const subscribeAll = (subscriptions: TopicSubscriptions<Event>): void => {\n subscribeByTopic(eventBus, subscriptions);\n };\n\n /**\n * Subscribe a global handler to multiple topics with optional filtering.\n *\n * @example\n * ```typescript\n * subscribeGlobal(subscriptions, {\n * subscriptionId: \"audit-log\",\n * handler: async (event) => auditLog.record(event),\n * filter: { exclude: [\"NotificationAdded\"] },\n * });\n * ```\n */\n const subscribeGlobal = (\n subscriptions: TopicSubscriptions<Event>,\n config: GlobalSubscriberConfig<Event>,\n ): void => {\n subscribeGlobalToTopics(eventBus, subscriptions, config);\n };\n\n return {\n eventBus,\n createNewEvent,\n defineSubscriptions,\n subscribeAll,\n subscribeGlobal,\n };\n}\n"],"mappings":"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","names":["subscriptions"]}
1
+ {"version":3,"sources":["../../../src/adapters/in-memory/InMemoryEventBus.ts"],"sourcesContent":["import {\n type CreateNewEvent,\n type CreateNewEventFromDefinitions,\n makeCreateNewEvent,\n} from \"../../createNewEvent.ts\";\nimport type {\n EventDefinitions,\n InferEventsFromDefinitions,\n} from \"../../eventDefinitions.ts\";\nimport { getSubscriptionIdsToPublish } from \"../../getSubscriptionIdsToPublish.ts\";\nimport type { EventBus } from \"../../ports/EventBus.ts\";\nimport type { WithEventsUow } from \"../../ports/EventRepository.ts\";\nimport {\n type GlobalSubscriberConfig,\n subscribeByTopic,\n subscribeGlobalToTopics,\n type TopicSubscriptions,\n} from \"../../subscriptions.ts\";\nimport type {\n DefaultContext,\n EventId,\n EventPublication,\n GenericEvent,\n SubscriptionId,\n} from \"../../types.ts\";\n\ntype SubscriptionsForTopic = Record<\n string,\n (event: GenericEvent<string, unknown, DefaultContext>) => Promise<void>\n>;\n\ntype CreateInMemoryEventBusOptions = {\n maxRetries?: number;\n getNow?: () => Date;\n generateId?: () => EventId;\n};\n\ntype CreateInMemoryEventBusFromDefinitionsOptions<\n Definitions extends EventDefinitions,\n> = CreateInMemoryEventBusOptions & {\n eventDefinitions: Definitions;\n};\n\ntype CreateInMemoryEventBusResult<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n> = {\n eventBus: EventBus<Event>;\n createNewEvent: CreateNewEvent<Event>;\n defineSubscriptions: (\n subscriptions: TopicSubscriptions<Event>,\n ) => TopicSubscriptions<Event>;\n subscribeAll: (subscriptions: TopicSubscriptions<Event>) => void;\n subscribeGlobal: (\n subscriptions: TopicSubscriptions<Event>,\n config: GlobalSubscriberConfig<Event>,\n ) => void;\n};\n\nexport function createInMemoryEventBus<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n>(\n withUow: WithEventsUow<Event>,\n options?: CreateInMemoryEventBusOptions,\n): CreateInMemoryEventBusResult<Event>;\nexport function createInMemoryEventBus<Definitions extends EventDefinitions>(\n withUow: WithEventsUow<InferEventsFromDefinitions<Definitions>>,\n options: CreateInMemoryEventBusFromDefinitionsOptions<Definitions>,\n): Omit<\n CreateInMemoryEventBusResult<InferEventsFromDefinitions<Definitions>>,\n \"createNewEvent\"\n> & {\n createNewEvent: CreateNewEventFromDefinitions<Definitions>;\n};\nexport function createInMemoryEventBus<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n>(\n withUow: WithEventsUow<Event>,\n options:\n | CreateInMemoryEventBusOptions\n | CreateInMemoryEventBusFromDefinitionsOptions<EventDefinitions> = {},\n) {\n const maxRetries = options.maxRetries ?? 3;\n const eventDefinitions =\n \"eventDefinitions\" in options ? options.eventDefinitions : undefined;\n const createNewEvent = eventDefinitions\n ? makeCreateNewEvent({\n getNow: options.getNow,\n generateId: options.generateId,\n eventDefinitions,\n })\n : makeCreateNewEvent<Event>({\n getNow: options.getNow,\n generateId: options.generateId,\n });\n const subscriptions: Partial<Record<string, SubscriptionsForTopic>> = {};\n\n const executeCallback = async (\n event: Event,\n subscriptionId: string,\n callback: (\n event: GenericEvent<string, unknown, DefaultContext>,\n ) => Promise<void>,\n ): Promise<\n { subscriptionId: string; errorMessage: string; stack?: string } | undefined\n > => {\n try {\n await callback(event);\n } catch (error) {\n return {\n subscriptionId,\n errorMessage: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n };\n }\n };\n\n const eventBus: EventBus<Event> = {\n publish: async (event) => {\n const publishedAt = new Date();\n const topic = event.topic;\n\n const callbacksBySubscriptionSlug = subscriptions[topic];\n\n if (!callbacksBySubscriptionSlug) {\n event.publications.push({\n publishedAt,\n publishedSubscribers: [],\n });\n event.status = \"published\";\n await withUow(async (uow) => {\n await uow.eventRepository.save(event);\n });\n return;\n }\n\n const subscriptionIdsToPublish = getSubscriptionIdsToPublish(\n event,\n Object.keys(callbacksBySubscriptionSlug),\n );\n\n const failuresOrUndefined = await Promise.all(\n subscriptionIdsToPublish.map((subscriptionId) =>\n executeCallback(\n event,\n subscriptionId,\n callbacksBySubscriptionSlug[subscriptionId],\n ),\n ),\n );\n\n const failures = failuresOrUndefined.filter(\n (\n f,\n ): f is {\n subscriptionId: string;\n errorMessage: string;\n stack?: string;\n } => f !== undefined,\n );\n\n const publications: EventPublication[] = [\n ...event.publications,\n {\n publishedAt,\n publishedSubscribers: subscriptionIdsToPublish.map(\n (id) => id as SubscriptionId,\n ),\n ...(failures.length > 0 && { failures }),\n },\n ];\n\n if (failures.length === 0) {\n event.status = \"published\";\n } else {\n const wasMaxNumberOfErrorsReached = publications.length >= maxRetries;\n event.status = wasMaxNumberOfErrorsReached\n ? \"quarantined\"\n : \"failed-but-will-retry\";\n }\n\n event.publications = publications;\n\n await withUow(async (uow) => {\n await uow.eventRepository.save(event);\n });\n },\n\n subscribe: ({ topic, subscriptionId, callBack }) => {\n if (!subscriptions[topic]) {\n subscriptions[topic] = {};\n }\n\n const subscriptionsForTopic = subscriptions[topic];\n if (subscriptionsForTopic) {\n subscriptionsForTopic[subscriptionId] = callBack as (\n event: GenericEvent<string, unknown, DefaultContext>,\n ) => Promise<void>;\n }\n },\n };\n\n /**\n * Identity function for type inference when defining subscription maps.\n * Ensures all topics are covered and handlers have correct payload types.\n *\n * @example\n * ```typescript\n * const subscriptions = defineSubscriptions({\n * OrderCreated: [{ subscriptionId: \"notify\", handler: async (e) => {...} }],\n * OrderShipped: [], // Required even if empty\n * });\n * ```\n */\n const defineSubscriptions = (\n subscriptions: TopicSubscriptions<Event>,\n ): TopicSubscriptions<Event> => subscriptions;\n\n /**\n * Subscribe all handlers from a topic subscription map to this event bus.\n *\n * @example\n * ```typescript\n * const subscriptions = defineSubscriptions({...});\n * subscribeAll(subscriptions);\n * ```\n */\n const subscribeAll = (subscriptions: TopicSubscriptions<Event>): void => {\n subscribeByTopic(eventBus, subscriptions);\n };\n\n /**\n * Subscribe a global handler to multiple topics with optional filtering.\n *\n * @example\n * ```typescript\n * subscribeGlobal(subscriptions, {\n * subscriptionId: \"audit-log\",\n * handler: async (event) => auditLog.record(event),\n * filter: { exclude: [\"NotificationAdded\"] },\n * });\n * ```\n */\n const subscribeGlobal = (\n subscriptions: TopicSubscriptions<Event>,\n config: GlobalSubscriberConfig<Event>,\n ): void => {\n subscribeGlobalToTopics(eventBus, subscriptions, config);\n };\n\n return {\n eventBus,\n createNewEvent,\n defineSubscriptions,\n subscribeAll,\n subscribeGlobal,\n };\n}\n"],"mappings":"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","names":["subscriptions"]}
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  makeCreateNewEvent
3
3
  } from "../../createNewEvent.mjs";
4
+ import { getSubscriptionIdsToPublish } from "../../getSubscriptionIdsToPublish.mjs";
4
5
  import {
5
6
  subscribeByTopic,
6
7
  subscribeGlobalToTopics
@@ -28,21 +29,6 @@ function createInMemoryEventBus(withUow, options = {}) {
28
29
  };
29
30
  }
30
31
  };
31
- const getSubscriptionIdsToPublish = (event, callbacksBySubscriptionId) => {
32
- const allSubscriptionIds = Object.keys(callbacksBySubscriptionId);
33
- if (event.publications.length === 0 || event.status === "to-republish") {
34
- return allSubscriptionIds;
35
- }
36
- const lastPublication = event.publications.reduce(
37
- (latest, current) => current.publishedAt > latest.publishedAt ? current : latest
38
- );
39
- const failedSubscriptionIds = (lastPublication.failures ?? []).map(
40
- (failure) => failure.subscriptionId
41
- );
42
- return allSubscriptionIds.filter(
43
- (id) => failedSubscriptionIds.includes(id)
44
- );
45
- };
46
32
  const eventBus = {
47
33
  publish: async (event) => {
48
34
  const publishedAt = /* @__PURE__ */ new Date();
@@ -61,7 +47,7 @@ function createInMemoryEventBus(withUow, options = {}) {
61
47
  }
62
48
  const subscriptionIdsToPublish = getSubscriptionIdsToPublish(
63
49
  event,
64
- callbacksBySubscriptionSlug
50
+ Object.keys(callbacksBySubscriptionSlug)
65
51
  );
66
52
  const failuresOrUndefined = await Promise.all(
67
53
  subscriptionIdsToPublish.map(