@l-etabli/events 0.5.0 → 0.6.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 (58) hide show
  1. package/README.md +146 -155
  2. package/dist/adapters/in-memory/InMemoryEventBus.cjs +8 -3
  3. package/dist/adapters/in-memory/InMemoryEventBus.cjs.map +1 -1
  4. package/dist/adapters/in-memory/InMemoryEventBus.d.cts +10 -2
  5. package/dist/adapters/in-memory/InMemoryEventBus.d.ts +10 -2
  6. package/dist/adapters/in-memory/InMemoryEventBus.mjs +11 -4
  7. package/dist/adapters/in-memory/InMemoryEventBus.mjs.map +1 -1
  8. package/dist/adapters/in-memory/index.d.cts +1 -0
  9. package/dist/adapters/in-memory/index.d.ts +1 -0
  10. package/dist/adapters/kysely/KyselyEventQueries.cjs +2 -0
  11. package/dist/adapters/kysely/KyselyEventQueries.cjs.map +1 -1
  12. package/dist/adapters/kysely/KyselyEventQueries.mjs +2 -0
  13. package/dist/adapters/kysely/KyselyEventQueries.mjs.map +1 -1
  14. package/dist/adapters/kysely/KyselyEventRepository.cjs +5 -1
  15. package/dist/adapters/kysely/KyselyEventRepository.cjs.map +1 -1
  16. package/dist/adapters/kysely/KyselyEventRepository.mjs +5 -1
  17. package/dist/adapters/kysely/KyselyEventRepository.mjs.map +1 -1
  18. package/dist/adapters/kysely/migration.cjs +1 -1
  19. package/dist/adapters/kysely/migration.cjs.map +1 -1
  20. package/dist/adapters/kysely/migration.mjs +1 -1
  21. package/dist/adapters/kysely/migration.mjs.map +1 -1
  22. package/dist/adapters/kysely/types.cjs.map +1 -1
  23. package/dist/adapters/kysely/types.d.cts +7 -3
  24. package/dist/adapters/kysely/types.d.ts +7 -3
  25. package/dist/createNewEvent.cjs +19 -12
  26. package/dist/createNewEvent.cjs.map +1 -1
  27. package/dist/createNewEvent.d.cts +43 -39
  28. package/dist/createNewEvent.d.ts +43 -39
  29. package/dist/createNewEvent.mjs +19 -12
  30. package/dist/createNewEvent.mjs.map +1 -1
  31. package/dist/eventDefinitions.cjs +32 -0
  32. package/dist/eventDefinitions.cjs.map +1 -0
  33. package/dist/eventDefinitions.d.cts +20 -0
  34. package/dist/eventDefinitions.d.ts +20 -0
  35. package/dist/eventDefinitions.mjs +7 -0
  36. package/dist/eventDefinitions.mjs.map +1 -0
  37. package/dist/index.cjs +5 -1
  38. package/dist/index.cjs.map +1 -1
  39. package/dist/index.d.cts +3 -2
  40. package/dist/index.d.ts +3 -2
  41. package/dist/index.mjs +2 -0
  42. package/dist/index.mjs.map +1 -1
  43. package/dist/types.cjs +37 -0
  44. package/dist/types.cjs.map +1 -1
  45. package/dist/types.d.cts +42 -3
  46. package/dist/types.d.ts +42 -3
  47. package/dist/types.mjs +25 -0
  48. package/dist/types.mjs.map +1 -1
  49. package/package.json +1 -1
  50. package/src/adapters/in-memory/InMemoryEventBus.ts +63 -9
  51. package/src/adapters/kysely/KyselyEventQueries.ts +2 -0
  52. package/src/adapters/kysely/KyselyEventRepository.ts +5 -1
  53. package/src/adapters/kysely/migration.ts +3 -1
  54. package/src/adapters/kysely/types.ts +7 -2
  55. package/src/createNewEvent.ts +116 -48
  56. package/src/eventDefinitions.ts +53 -0
  57. package/src/index.ts +2 -1
  58. package/src/types.ts +74 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/createNewEvent.ts"],"sourcesContent":["import type { DefaultContext, EventId, GenericEvent, UserId } from './types.mjs';\n\ntype MakeCreateNewEventOptions = {\n getNow?: () => Date;\n generateId?: () => EventId;\n};\n\ntype ContextParam<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n Topic extends Event[\"topic\"],\n> = Extract<Event, { topic: Topic }>[\"context\"] extends undefined\n ? { context?: undefined }\n : { context: Extract<Event, { topic: Topic }>[\"context\"] };\n\ntype CreateNewEventParams<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n Topic extends Event[\"topic\"],\n> = {\n topic: Topic;\n payload: Extract<Event, { topic: Topic }>[\"payload\"];\n triggeredByUserId: UserId;\n id?: EventId;\n occurredAt?: Date;\n priority?: number;\n} & ContextParam<Event, Topic>;\n\n/**\n * Creates a typed event creator factory for your event union.\n * Provides type-safe event creation where topic constrains payload type.\n *\n * @param options.getNow - Function to get current time (default: `() => new Date()`)\n * @param options.generateId - Function to generate event IDs (default: `() => crypto.randomUUID()`)\n *\n * @example\n * ```typescript\n * type MyEvents =\n * | GenericEvent<\"UserCreated\", { email: string }>\n * | GenericEvent<\"OrderPlaced\", { orderId: string }>;\n *\n * // Standalone usage:\n * const createEvent = makeCreateNewEvent<MyEvents>();\n *\n * // Or get it from createInMemoryEventBus (recommended):\n * const { eventBus, createEvent } = createInMemoryEventBus<MyEvents>(withUow);\n *\n * // Type-safe: payload must match topic\n * createEvent({ topic: \"UserCreated\", payload: { email: \"a@b.com\" }, triggeredByUserId: \"u1\" }); // OK\n * createEvent({ topic: \"UserCreated\", payload: { orderId: \"123\" }, triggeredByUserId: \"u1\" }); // Error!\n *\n * // For testing, inject deterministic functions:\n * const createEvent = makeCreateNewEvent<MyEvents>({\n * getNow: () => new Date(\"2024-01-01\"),\n * generateId: () => \"test-id\",\n * });\n * ```\n */\n\nexport type CreateNewEvent<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n> = <Topic extends Event[\"topic\"]>(\n params: CreateNewEventParams<Event, Topic>,\n) => Extract<Event, { topic: Topic }>;\n\nexport const makeCreateNewEvent = <\n Event extends GenericEvent<string, unknown, DefaultContext>,\n>(\n options: MakeCreateNewEventOptions = {},\n): CreateNewEvent<Event> => {\n const getNow = options.getNow ?? (() => new Date());\n const generateId =\n options.generateId ?? (() => crypto.randomUUID() as EventId);\n\n return <Topic extends Event[\"topic\"]>(\n params: CreateNewEventParams<Event, Topic>,\n ): Extract<Event, { topic: Topic }> =>\n ({\n id: params.id ?? generateId(),\n topic: params.topic,\n payload: params.payload,\n triggeredByUserId: params.triggeredByUserId,\n occurredAt: params.occurredAt ?? getNow(),\n status: \"never-published\",\n publications: [],\n priority: params.priority,\n context: params.context,\n }) as unknown as Extract<Event, { topic: Topic }>;\n};\n"],"mappings":"AA+DO,MAAM,qBAAqB,CAGhC,UAAqC,CAAC,MACZ;AAC1B,QAAM,SAAS,QAAQ,WAAW,MAAM,oBAAI,KAAK;AACjD,QAAM,aACJ,QAAQ,eAAe,MAAM,OAAO,WAAW;AAEjD,SAAO,CACL,YAEC;AAAA,IACC,IAAI,OAAO,MAAM,WAAW;AAAA,IAC5B,OAAO,OAAO;AAAA,IACd,SAAS,OAAO;AAAA,IAChB,mBAAmB,OAAO;AAAA,IAC1B,YAAY,OAAO,cAAc,OAAO;AAAA,IACxC,QAAQ;AAAA,IACR,cAAc,CAAC;AAAA,IACf,UAAU,OAAO;AAAA,IACjB,SAAS,OAAO;AAAA,EAClB;AACJ;","names":[]}
1
+ {"version":3,"sources":["../src/createNewEvent.ts"],"sourcesContent":["import type {\n EventDefinitions,\n InferEventsFromDefinitions,\n} from './eventDefinitions.mjs';\nimport type { Actor, DefaultContext, EventId, GenericEvent } from './types.mjs';\n\ntype MakeCreateNewEventOptions = {\n getNow?: () => Date;\n generateId?: () => EventId;\n};\n\ntype MakeCreateNewEventFromDefinitionsOptions<\n Definitions extends EventDefinitions,\n> = MakeCreateNewEventOptions & {\n eventDefinitions: Definitions;\n};\n\ntype DeclaredContextForEvent<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n Topic extends Event[\"topic\"],\n> = Exclude<Extract<Event, { topic: Topic }>[\"context\"], undefined>;\n\ntype ContextParamForEvent<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n Topic extends Event[\"topic\"],\n> = [DeclaredContextForEvent<Event, Topic>] extends [never]\n ? { context?: undefined }\n : { context: DeclaredContextForEvent<Event, Topic> };\n\ntype BaseCreateNewEventParams = {\n triggeredByActor: Actor;\n id?: EventId;\n occurredAt?: Date;\n flowId?: string;\n causedByEventId?: EventId;\n};\n\ntype CreateNewEventParams<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n Topic extends Event[\"topic\"],\n> = BaseCreateNewEventParams & {\n topic: Topic;\n payload: Extract<Event, { topic: Topic }>[\"payload\"];\n priority?: number;\n} & ContextParamForEvent<Event, Topic>;\n\ntype PayloadFromDefinitions<\n Definitions extends EventDefinitions,\n Topic extends keyof Definitions & string,\n> = Definitions[Topic] extends {\n _payload?: infer Payload;\n}\n ? Payload\n : never;\n\ntype DeclaredContextFromDefinitions<\n Definitions extends EventDefinitions,\n Topic extends keyof Definitions & string,\n> = Exclude<\n Definitions[Topic] extends { _context?: infer Context } ? Context : never,\n undefined\n>;\n\ntype ContextParamFromDefinitions<\n Definitions extends EventDefinitions,\n Topic extends keyof Definitions & string,\n> = [DeclaredContextFromDefinitions<Definitions, Topic>] extends [never]\n ? { context?: undefined }\n : { context: DeclaredContextFromDefinitions<Definitions, Topic> };\n\ntype CreateNewEventParamsFromDefinitions<\n Definitions extends EventDefinitions,\n Topic extends keyof Definitions & string,\n> = BaseCreateNewEventParams & {\n topic: Topic;\n payload: PayloadFromDefinitions<Definitions, Topic>;\n} & ContextParamFromDefinitions<Definitions, Topic>;\n\n/**\n * Creates a typed event creator factory for your event union.\n * Provides type-safe event creation where topic constrains payload type.\n */\nexport type CreateNewEvent<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n> = <Topic extends Event[\"topic\"]>(\n params: CreateNewEventParams<Event, Topic>,\n) => Extract<Event, { topic: Topic }>;\n\n/**\n * Creates a typed event creator factory directly from event definitions.\n * Priority is injected from the canonical topic definition.\n */\nexport type CreateNewEventFromDefinitions<\n Definitions extends EventDefinitions,\n> = <Topic extends keyof Definitions & string>(\n params: CreateNewEventParamsFromDefinitions<Definitions, Topic>,\n) => Extract<InferEventsFromDefinitions<Definitions>, { topic: Topic }>;\n\nexport function makeCreateNewEvent<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n>(options?: MakeCreateNewEventOptions): CreateNewEvent<Event>;\nexport function makeCreateNewEvent<Definitions extends EventDefinitions>(\n options: MakeCreateNewEventFromDefinitionsOptions<Definitions>,\n): CreateNewEventFromDefinitions<Definitions>;\nexport function makeCreateNewEvent<\n Event extends GenericEvent<string, unknown, DefaultContext>,\n Definitions extends EventDefinitions,\n>(\n options:\n | MakeCreateNewEventOptions\n | MakeCreateNewEventFromDefinitionsOptions<Definitions> = {},\n): CreateNewEvent<Event> | CreateNewEventFromDefinitions<Definitions> {\n const getNow = options.getNow ?? (() => new Date());\n const generateId =\n options.generateId ?? (() => crypto.randomUUID() as EventId);\n const eventDefinitions =\n \"eventDefinitions\" in options ? options.eventDefinitions : undefined;\n\n return ((params: {\n topic: string;\n payload: unknown;\n triggeredByActor: Actor;\n id?: EventId;\n occurredAt?: Date;\n flowId?: string;\n causedByEventId?: EventId;\n context?: DefaultContext;\n priority?: number;\n }) => {\n const definitionPriority = eventDefinitions?.[params.topic]?.priority;\n const priority =\n definitionPriority ??\n (\"priority\" in params\n ? (params.priority as number | undefined)\n : undefined);\n\n return {\n id: params.id ?? generateId(),\n topic: params.topic,\n payload: params.payload,\n triggeredByActor: params.triggeredByActor,\n occurredAt: params.occurredAt ?? getNow(),\n status: \"never-published\",\n publications: [],\n ...(priority !== undefined ? { priority } : {}),\n ...(params.context !== undefined ? { context: params.context } : {}),\n ...(params.flowId !== undefined ? { flowId: params.flowId } : {}),\n ...(params.causedByEventId !== undefined\n ? { causedByEventId: params.causedByEventId }\n : {}),\n };\n }) as unknown as\n | CreateNewEvent<Event>\n | CreateNewEventFromDefinitions<Definitions>;\n}\n"],"mappings":"AAwGO,SAAS,mBAId,UAE4D,CAAC,GACO;AACpE,QAAM,SAAS,QAAQ,WAAW,MAAM,oBAAI,KAAK;AACjD,QAAM,aACJ,QAAQ,eAAe,MAAM,OAAO,WAAW;AACjD,QAAM,mBACJ,sBAAsB,UAAU,QAAQ,mBAAmB;AAE7D,UAAQ,CAAC,WAUH;AACJ,UAAM,qBAAqB,mBAAmB,OAAO,KAAK,GAAG;AAC7D,UAAM,WACJ,uBACC,cAAc,SACV,OAAO,WACR;AAEN,WAAO;AAAA,MACL,IAAI,OAAO,MAAM,WAAW;AAAA,MAC5B,OAAO,OAAO;AAAA,MACd,SAAS,OAAO;AAAA,MAChB,kBAAkB,OAAO;AAAA,MACzB,YAAY,OAAO,cAAc,OAAO;AAAA,MACxC,QAAQ;AAAA,MACR,cAAc,CAAC;AAAA,MACf,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,MAC7C,GAAI,OAAO,YAAY,SAAY,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,MAClE,GAAI,OAAO,WAAW,SAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;AAAA,MAC/D,GAAI,OAAO,oBAAoB,SAC3B,EAAE,iBAAiB,OAAO,gBAAgB,IAC1C,CAAC;AAAA,IACP;AAAA,EACF;AAGF;","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 eventDefinitions_exports = {};
20
+ __export(eventDefinitions_exports, {
21
+ defineEvent: () => defineEvent,
22
+ defineEvents: () => defineEvents
23
+ });
24
+ module.exports = __toCommonJS(eventDefinitions_exports);
25
+ const defineEvent = (options = {}) => options;
26
+ const defineEvents = (definitions) => definitions;
27
+ // Annotate the CommonJS export names for ESM import in node:
28
+ 0 && (module.exports = {
29
+ defineEvent,
30
+ defineEvents
31
+ });
32
+ //# sourceMappingURL=eventDefinitions.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/eventDefinitions.ts"],"sourcesContent":["import type { DefaultContext, GenericEvent } from \"./types.ts\";\n\nexport type EventDefinition<\n Payload,\n Context extends DefaultContext = undefined,\n> = {\n priority?: number;\n _payload?: Payload;\n _context?: Context;\n};\n\nexport type EventDefinitions = Record<\n string,\n EventDefinition<unknown, DefaultContext>\n>;\n\ntype PayloadFromDefinition<Definition> = Definition extends EventDefinition<\n infer Payload,\n DefaultContext\n>\n ? Payload\n : never;\n\ntype ContextFromDefinition<Definition> = Definition extends EventDefinition<\n unknown,\n infer Context\n>\n ? Context\n : never;\n\nexport type InferEventsFromDefinitions<Definitions extends EventDefinitions> = {\n [Topic in keyof Definitions & string]: GenericEvent<\n Topic,\n PayloadFromDefinition<Definitions[Topic]>,\n ContextFromDefinition<Definitions[Topic]>\n >;\n}[keyof Definitions & string];\n\ntype DefineEventOptions = {\n priority?: number;\n};\n\nexport const defineEvent = <\n Payload,\n Context extends DefaultContext = undefined,\n>(\n options: DefineEventOptions = {},\n): EventDefinition<Payload, Context> =>\n options as EventDefinition<Payload, Context>;\n\nexport const defineEvents = <Definitions extends EventDefinitions>(\n definitions: Definitions,\n): Definitions => definitions;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0CO,MAAM,cAAc,CAIzB,UAA8B,CAAC,MAE/B;AAEK,MAAM,eAAe,CAC1B,gBACgB;","names":[]}
@@ -0,0 +1,20 @@
1
+ import { DefaultContext, GenericEvent } from './types.cjs';
2
+
3
+ type EventDefinition<Payload, Context extends DefaultContext = undefined> = {
4
+ priority?: number;
5
+ _payload?: Payload;
6
+ _context?: Context;
7
+ };
8
+ type EventDefinitions = Record<string, EventDefinition<unknown, DefaultContext>>;
9
+ type PayloadFromDefinition<Definition> = Definition extends EventDefinition<infer Payload, DefaultContext> ? Payload : never;
10
+ type ContextFromDefinition<Definition> = Definition extends EventDefinition<unknown, infer Context> ? Context : never;
11
+ type InferEventsFromDefinitions<Definitions extends EventDefinitions> = {
12
+ [Topic in keyof Definitions & string]: GenericEvent<Topic, PayloadFromDefinition<Definitions[Topic]>, ContextFromDefinition<Definitions[Topic]>>;
13
+ }[keyof Definitions & string];
14
+ type DefineEventOptions = {
15
+ priority?: number;
16
+ };
17
+ declare const defineEvent: <Payload, Context extends DefaultContext = undefined>(options?: DefineEventOptions) => EventDefinition<Payload, Context>;
18
+ declare const defineEvents: <Definitions extends EventDefinitions>(definitions: Definitions) => Definitions;
19
+
20
+ export { type EventDefinition, type EventDefinitions, type InferEventsFromDefinitions, defineEvent, defineEvents };
@@ -0,0 +1,20 @@
1
+ import { DefaultContext, GenericEvent } from './types.js';
2
+
3
+ type EventDefinition<Payload, Context extends DefaultContext = undefined> = {
4
+ priority?: number;
5
+ _payload?: Payload;
6
+ _context?: Context;
7
+ };
8
+ type EventDefinitions = Record<string, EventDefinition<unknown, DefaultContext>>;
9
+ type PayloadFromDefinition<Definition> = Definition extends EventDefinition<infer Payload, DefaultContext> ? Payload : never;
10
+ type ContextFromDefinition<Definition> = Definition extends EventDefinition<unknown, infer Context> ? Context : never;
11
+ type InferEventsFromDefinitions<Definitions extends EventDefinitions> = {
12
+ [Topic in keyof Definitions & string]: GenericEvent<Topic, PayloadFromDefinition<Definitions[Topic]>, ContextFromDefinition<Definitions[Topic]>>;
13
+ }[keyof Definitions & string];
14
+ type DefineEventOptions = {
15
+ priority?: number;
16
+ };
17
+ declare const defineEvent: <Payload, Context extends DefaultContext = undefined>(options?: DefineEventOptions) => EventDefinition<Payload, Context>;
18
+ declare const defineEvents: <Definitions extends EventDefinitions>(definitions: Definitions) => Definitions;
19
+
20
+ export { type EventDefinition, type EventDefinitions, type InferEventsFromDefinitions, defineEvent, defineEvents };
@@ -0,0 +1,7 @@
1
+ const defineEvent = (options = {}) => options;
2
+ const defineEvents = (definitions) => definitions;
3
+ export {
4
+ defineEvent,
5
+ defineEvents
6
+ };
7
+ //# sourceMappingURL=eventDefinitions.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/eventDefinitions.ts"],"sourcesContent":["import type { DefaultContext, GenericEvent } from './types.mjs';\n\nexport type EventDefinition<\n Payload,\n Context extends DefaultContext = undefined,\n> = {\n priority?: number;\n _payload?: Payload;\n _context?: Context;\n};\n\nexport type EventDefinitions = Record<\n string,\n EventDefinition<unknown, DefaultContext>\n>;\n\ntype PayloadFromDefinition<Definition> = Definition extends EventDefinition<\n infer Payload,\n DefaultContext\n>\n ? Payload\n : never;\n\ntype ContextFromDefinition<Definition> = Definition extends EventDefinition<\n unknown,\n infer Context\n>\n ? Context\n : never;\n\nexport type InferEventsFromDefinitions<Definitions extends EventDefinitions> = {\n [Topic in keyof Definitions & string]: GenericEvent<\n Topic,\n PayloadFromDefinition<Definitions[Topic]>,\n ContextFromDefinition<Definitions[Topic]>\n >;\n}[keyof Definitions & string];\n\ntype DefineEventOptions = {\n priority?: number;\n};\n\nexport const defineEvent = <\n Payload,\n Context extends DefaultContext = undefined,\n>(\n options: DefineEventOptions = {},\n): EventDefinition<Payload, Context> =>\n options as EventDefinition<Payload, Context>;\n\nexport const defineEvents = <Definitions extends EventDefinitions>(\n definitions: Definitions,\n): Definitions => definitions;\n"],"mappings":"AA0CO,MAAM,cAAc,CAIzB,UAA8B,CAAC,MAE/B;AAEK,MAAM,eAAe,CAC1B,gBACgB;","names":[]}
package/dist/index.cjs CHANGED
@@ -18,12 +18,16 @@ module.exports = __toCommonJS(index_exports);
18
18
  __reExport(index_exports, require("./adapters/in-memory/index.ts"), module.exports);
19
19
  __reExport(index_exports, require("./createEventCrawler.ts"), module.exports);
20
20
  __reExport(index_exports, require("./createNewEvent.ts"), module.exports);
21
+ __reExport(index_exports, require("./eventDefinitions.ts"), module.exports);
21
22
  __reExport(index_exports, require("./subscriptions.ts"), module.exports);
23
+ __reExport(index_exports, require("./types.ts"), module.exports);
22
24
  // Annotate the CommonJS export names for ESM import in node:
23
25
  0 && (module.exports = {
24
26
  ...require("./adapters/in-memory/index.ts"),
25
27
  ...require("./createEventCrawler.ts"),
26
28
  ...require("./createNewEvent.ts"),
27
- ...require("./subscriptions.ts")
29
+ ...require("./eventDefinitions.ts"),
30
+ ...require("./subscriptions.ts"),
31
+ ...require("./types.ts")
28
32
  });
29
33
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./adapters/in-memory/index.ts\";\nexport * from \"./createEventCrawler.ts\";\nexport * from \"./createNewEvent.ts\";\nexport type * from \"./ports/EventBus.ts\";\nexport type * from \"./ports/EventQueries.ts\";\nexport type * from \"./ports/EventRepository.ts\";\nexport * from \"./subscriptions.ts\";\nexport type * from \"./types.ts\";\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,0BAAc,0CAAd;AACA,0BAAc,oCADd;AAEA,0BAAc,gCAFd;AAMA,0BAAc,+BANd;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./adapters/in-memory/index.ts\";\nexport * from \"./createEventCrawler.ts\";\nexport * from \"./createNewEvent.ts\";\nexport * from \"./eventDefinitions.ts\";\nexport type * from \"./ports/EventBus.ts\";\nexport type * from \"./ports/EventQueries.ts\";\nexport type * from \"./ports/EventRepository.ts\";\nexport * from \"./subscriptions.ts\";\nexport * from \"./types.ts\";\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,0BAAc,0CAAd;AACA,0BAAc,oCADd;AAEA,0BAAc,gCAFd;AAGA,0BAAc,kCAHd;AAOA,0BAAc,+BAPd;AAQA,0BAAc,uBARd;","names":[]}
package/dist/index.d.cts CHANGED
@@ -1,11 +1,12 @@
1
1
  export { createInMemoryEventRepositoryAndQueries } from './adapters/in-memory/index.cjs';
2
2
  export { createEventCrawler } from './createEventCrawler.cjs';
3
- export { CreateNewEvent, makeCreateNewEvent } from './createNewEvent.cjs';
3
+ export { CreateNewEvent, CreateNewEventFromDefinitions, makeCreateNewEvent } from './createNewEvent.cjs';
4
+ export { EventDefinition, EventDefinitions, InferEventsFromDefinitions, defineEvent, defineEvents } from './eventDefinitions.cjs';
4
5
  export { EventBus } from './ports/EventBus.cjs';
5
6
  export { EventQueries } from './ports/EventQueries.cjs';
6
7
  export { EventRepository, EventsUnitOfWork, WithEventsUow, WithEventsUowOptions } from './ports/EventRepository.cjs';
7
8
  export { GlobalSubscriberConfig, NarrowEvent, TopicFilter, TopicSubscriber, TopicSubscriptions, subscribeByTopic, subscribeGlobalToTopics } from './subscriptions.cjs';
8
- export { DefaultContext, EventFailure, EventId, EventPublication, EventStatus, Flavor, GenericEvent, SubscriptionId, UserId } from './types.cjs';
9
+ export { Actor, AnonymousActor, ApiKeyActor, DefaultContext, EventFailure, EventId, EventPublication, EventStatus, Flavor, GenericEvent, SubscriptionId, SystemActor, UserActor, UserId, WorkerActor, createAnonymousActor, createApiKeyActor, createSystemActor, createUserActor, createWorkerActor } from './types.cjs';
9
10
  export { createInMemoryEventBus } from './adapters/in-memory/InMemoryEventBus.cjs';
10
11
  export { createInMemoryEventQueries } from './adapters/in-memory/InMemoryEventQueries.cjs';
11
12
  export { InMemoryEventRepositoryHelpers, createInMemoryEventRepository, createInMemoryWithUow } from './adapters/in-memory/InMemoryEventRepository.cjs';
package/dist/index.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  export { createInMemoryEventRepositoryAndQueries } from './adapters/in-memory/index.js';
2
2
  export { createEventCrawler } from './createEventCrawler.js';
3
- export { CreateNewEvent, makeCreateNewEvent } from './createNewEvent.js';
3
+ export { CreateNewEvent, CreateNewEventFromDefinitions, makeCreateNewEvent } from './createNewEvent.js';
4
+ export { EventDefinition, EventDefinitions, InferEventsFromDefinitions, defineEvent, defineEvents } from './eventDefinitions.js';
4
5
  export { EventBus } from './ports/EventBus.js';
5
6
  export { EventQueries } from './ports/EventQueries.js';
6
7
  export { EventRepository, EventsUnitOfWork, WithEventsUow, WithEventsUowOptions } from './ports/EventRepository.js';
7
8
  export { GlobalSubscriberConfig, NarrowEvent, TopicFilter, TopicSubscriber, TopicSubscriptions, subscribeByTopic, subscribeGlobalToTopics } from './subscriptions.js';
8
- export { DefaultContext, EventFailure, EventId, EventPublication, EventStatus, Flavor, GenericEvent, SubscriptionId, UserId } from './types.js';
9
+ export { Actor, AnonymousActor, ApiKeyActor, DefaultContext, EventFailure, EventId, EventPublication, EventStatus, Flavor, GenericEvent, SubscriptionId, SystemActor, UserActor, UserId, WorkerActor, createAnonymousActor, createApiKeyActor, createSystemActor, createUserActor, createWorkerActor } from './types.js';
9
10
  export { createInMemoryEventBus } from './adapters/in-memory/InMemoryEventBus.js';
10
11
  export { createInMemoryEventQueries } from './adapters/in-memory/InMemoryEventQueries.js';
11
12
  export { InMemoryEventRepositoryHelpers, createInMemoryEventRepository, createInMemoryWithUow } from './adapters/in-memory/InMemoryEventRepository.js';
package/dist/index.mjs CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from "./adapters/in-memory/index.mjs";
2
2
  export * from "./createEventCrawler.mjs";
3
3
  export * from "./createNewEvent.mjs";
4
+ export * from "./eventDefinitions.mjs";
4
5
  export * from "./subscriptions.mjs";
6
+ export * from "./types.mjs";
5
7
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './adapters/in-memory/index.mjs';\nexport * from './createEventCrawler.mjs';\nexport * from './createNewEvent.mjs';\nexport type * from './ports/EventBus.mjs';\nexport type * from './ports/EventQueries.mjs';\nexport type * from './ports/EventRepository.mjs';\nexport * from './subscriptions.mjs';\nexport type * from './types.mjs';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AAId,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './adapters/in-memory/index.mjs';\nexport * from './createEventCrawler.mjs';\nexport * from './createNewEvent.mjs';\nexport * from './eventDefinitions.mjs';\nexport type * from './ports/EventBus.mjs';\nexport type * from './ports/EventQueries.mjs';\nexport type * from './ports/EventRepository.mjs';\nexport * from './subscriptions.mjs';\nexport * from './types.mjs';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAId,cAAc;AACd,cAAc;","names":[]}
package/dist/types.cjs CHANGED
@@ -3,6 +3,10 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
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
+ };
6
10
  var __copyProps = (to, from, except, desc) => {
7
11
  if (from && typeof from === "object" || typeof from === "function") {
8
12
  for (let key of __getOwnPropNames(from))
@@ -13,5 +17,38 @@ var __copyProps = (to, from, except, desc) => {
13
17
  };
14
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
19
  var types_exports = {};
20
+ __export(types_exports, {
21
+ createAnonymousActor: () => createAnonymousActor,
22
+ createApiKeyActor: () => createApiKeyActor,
23
+ createSystemActor: () => createSystemActor,
24
+ createUserActor: () => createUserActor,
25
+ createWorkerActor: () => createWorkerActor
26
+ });
16
27
  module.exports = __toCommonJS(types_exports);
28
+ const createUserActor = (id) => ({
29
+ kind: "user",
30
+ id
31
+ });
32
+ const createSystemActor = () => ({
33
+ kind: "system"
34
+ });
35
+ const createWorkerActor = (id) => ({
36
+ kind: "worker",
37
+ ...id !== void 0 ? { id } : {}
38
+ });
39
+ const createApiKeyActor = (id) => ({
40
+ kind: "api-key",
41
+ id
42
+ });
43
+ const createAnonymousActor = () => ({
44
+ kind: "anonymous"
45
+ });
46
+ // Annotate the CommonJS export names for ESM import in node:
47
+ 0 && (module.exports = {
48
+ createAnonymousActor,
49
+ createApiKeyActor,
50
+ createSystemActor,
51
+ createUserActor,
52
+ createWorkerActor
53
+ });
17
54
  //# sourceMappingURL=types.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * Branded type helper for nominal typing.\n * Adds a phantom type property to distinguish between structurally identical types.\n */\nexport type Flavor<T, FlavorT> = T & {\n _type?: FlavorT;\n};\n\n/** Unique identifier for an event subscription. */\nexport type SubscriptionId = Flavor<string, \"SubscriptionId\">;\n\n/** Unique identifier for a user who triggered an event. */\nexport type UserId = Flavor<string, \"UserId\">;\n\n/** Unique identifier for an event. */\nexport type EventId = Flavor<string, \"EventId\">;\n\n/**\n * Records a subscription failure during event publication.\n * Contains the subscription that failed and error details for debugging.\n */\nexport type EventFailure = {\n subscriptionId: SubscriptionId;\n errorMessage: string;\n /** Stack trace captured when the subscription callback threw. */\n stack?: string;\n};\n\n/**\n * Records a single publication attempt for an event.\n * Tracks which subscribers were notified and any failures that occurred.\n */\nexport type EventPublication = {\n publishedAt: Date;\n /** All subscription IDs that were attempted in this publication. */\n publishedSubscribers: SubscriptionId[];\n /** Subscriptions that failed during this publication attempt. */\n failures?: EventFailure[];\n};\n\n/**\n * Event lifecycle status.\n * - `never-published`: New event, not yet processed by crawler\n * - `in-process`: Currently being published by crawler\n * - `published`: Successfully delivered to all subscribers\n * - `failed-but-will-retry`: Some subscribers failed, will retry\n * - `quarantined`: Exceeded max retries, requires manual intervention\n * - `to-republish`: Force republish to all subscribers (manual trigger)\n */\nexport type EventStatus =\n | \"never-published\"\n | \"to-republish\"\n | \"in-process\"\n | \"published\"\n | \"failed-but-will-retry\"\n | \"quarantined\";\n\n/** Context type constraint - must be a string record or undefined. */\nexport type DefaultContext = Record<string, string> | undefined;\n\n/**\n * Generic event type for the outbox pattern.\n * Events are persisted in the same transaction as domain changes,\n * then asynchronously published to subscribers.\n *\n * @typeParam T - Event topic/type string literal\n * @typeParam P - Event payload type\n * @typeParam C - Optional context for filtering (e.g., tenant ID)\n *\n * @example\n * ```typescript\n * type MyEvents =\n * | GenericEvent<\"UserCreated\", { userId: string; email: string }>\n * | GenericEvent<\"OrderPlaced\", { orderId: string }, { tenantId: string }>;\n * ```\n */\nexport type GenericEvent<\n T extends string,\n P,\n C extends DefaultContext = undefined,\n> = {\n /** Unique event identifier. */\n id: EventId;\n /** When the event occurred in the domain. */\n occurredAt: Date;\n /** Event type/topic for routing to subscribers. */\n topic: T;\n /** Event-specific data. */\n payload: P;\n /** Current lifecycle status. */\n status: EventStatus;\n /** History of publication attempts. */\n publications: EventPublication[];\n /** User who triggered the action that created this event. */\n triggeredByUserId: UserId;\n /** Optional priority for processing order (not yet implemented in crawler). */\n priority?: number;\n /** Optional context for filtering events (e.g., by tenant). */\n context?: C;\n};\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * Branded type helper for nominal typing.\n * Adds a phantom type property to distinguish between structurally identical types.\n */\nexport type Flavor<T, FlavorT> = T & {\n _type?: FlavorT;\n};\n\n/** Unique identifier for an event subscription. */\nexport type SubscriptionId = Flavor<string, \"SubscriptionId\">;\n\n/** Unique identifier for a user who triggered an event. */\nexport type UserId = Flavor<string, \"UserId\">;\n\n/** Actor representing a user action. */\nexport type UserActor<Id extends string = string> = {\n kind: \"user\";\n id: Id;\n};\n\n/** Actor representing platform or infrastructure initiated work. */\nexport type SystemActor = {\n kind: \"system\";\n};\n\n/** Actor representing a background worker or job. */\nexport type WorkerActor<Id extends string = string> = {\n kind: \"worker\";\n id?: Id;\n};\n\n/** Actor representing an API key. */\nexport type ApiKeyActor<Id extends string = string> = {\n kind: \"api-key\";\n id: Id;\n};\n\n/** Actor representing an anonymous caller. */\nexport type AnonymousActor = {\n kind: \"anonymous\";\n};\n\n/** JSON-serializable actor metadata persisted alongside the event. */\nexport type Actor =\n | UserActor\n | SystemActor\n | WorkerActor\n | ApiKeyActor\n | AnonymousActor;\n\n/** Creates a typed user actor. */\nexport const createUserActor = <Id extends string>(id: Id): UserActor<Id> => ({\n kind: \"user\",\n id,\n});\n\n/** Creates a typed system actor. */\nexport const createSystemActor = (): SystemActor => ({\n kind: \"system\",\n});\n\n/** Creates a typed worker actor. */\nexport const createWorkerActor = <Id extends string>(\n id?: Id,\n): WorkerActor<Id> => ({\n kind: \"worker\",\n ...(id !== undefined ? { id } : {}),\n});\n\n/** Creates a typed API key actor. */\nexport const createApiKeyActor = <Id extends string>(\n id: Id,\n): ApiKeyActor<Id> => ({\n kind: \"api-key\",\n id,\n});\n\n/** Creates a typed anonymous actor. */\nexport const createAnonymousActor = (): AnonymousActor => ({\n kind: \"anonymous\",\n});\n\n/** Unique identifier for an event. */\nexport type EventId = Flavor<string, \"EventId\">;\n\n/**\n * Records a subscription failure during event publication.\n * Contains the subscription that failed and error details for debugging.\n */\nexport type EventFailure = {\n subscriptionId: SubscriptionId;\n errorMessage: string;\n /** Stack trace captured when the subscription callback threw. */\n stack?: string;\n};\n\n/**\n * Records a single publication attempt for an event.\n * Tracks which subscribers were notified and any failures that occurred.\n */\nexport type EventPublication = {\n publishedAt: Date;\n /** All subscription IDs that were attempted in this publication. */\n publishedSubscribers: SubscriptionId[];\n /** Subscriptions that failed during this publication attempt. */\n failures?: EventFailure[];\n};\n\n/**\n * Event lifecycle status.\n * - `never-published`: New event, not yet processed by crawler\n * - `in-process`: Currently being published by crawler\n * - `published`: Successfully delivered to all subscribers\n * - `failed-but-will-retry`: Some subscribers failed, will retry\n * - `quarantined`: Exceeded max retries, requires manual intervention\n * - `to-republish`: Force republish to all subscribers (manual trigger)\n */\nexport type EventStatus =\n | \"never-published\"\n | \"to-republish\"\n | \"in-process\"\n | \"published\"\n | \"failed-but-will-retry\"\n | \"quarantined\";\n\n/** Context type constraint - must be a string record or undefined. */\nexport type DefaultContext = Record<string, string> | undefined;\n\n/**\n * Generic event type for the outbox pattern.\n * Events are persisted in the same transaction as domain changes,\n * then asynchronously published to subscribers.\n *\n * @typeParam T - Event topic/type string literal\n * @typeParam P - Event payload type\n * @typeParam C - Optional context for filtering (e.g., tenant ID)\n *\n * @example\n * ```typescript\n * type MyEvents =\n * | GenericEvent<\"UserCreated\", { userId: string; email: string }>\n * | GenericEvent<\"OrderPlaced\", { orderId: string }, { tenantId: string }>;\n * ```\n */\nexport type GenericEvent<\n T extends string,\n P,\n C extends DefaultContext = undefined,\n> = {\n /** Unique event identifier. */\n id: EventId;\n /** When the event occurred in the domain. */\n occurredAt: Date;\n /** Event type/topic for routing to subscribers. */\n topic: T;\n /** Event-specific data. */\n payload: P;\n /** Current lifecycle status. */\n status: EventStatus;\n /** History of publication attempts. */\n publications: EventPublication[];\n /** Actor identifier that triggered the action that created this event. */\n triggeredByActor: Actor;\n /** Optional correlation identifier for a request or cross-event flow. */\n flowId?: string;\n /** Optional parent event identifier for cascading events. */\n causedByEventId?: EventId;\n /** Optional priority for processing order (not yet implemented in crawler). */\n priority?: number;\n /** Optional context for filtering events (e.g., by tenant). */\n context?: C;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmDO,MAAM,kBAAkB,CAAoB,QAA2B;AAAA,EAC5E,MAAM;AAAA,EACN;AACF;AAGO,MAAM,oBAAoB,OAAoB;AAAA,EACnD,MAAM;AACR;AAGO,MAAM,oBAAoB,CAC/B,QACqB;AAAA,EACrB,MAAM;AAAA,EACN,GAAI,OAAO,SAAY,EAAE,GAAG,IAAI,CAAC;AACnC;AAGO,MAAM,oBAAoB,CAC/B,QACqB;AAAA,EACrB,MAAM;AAAA,EACN;AACF;AAGO,MAAM,uBAAuB,OAAuB;AAAA,EACzD,MAAM;AACR;","names":[]}
package/dist/types.d.cts CHANGED
@@ -9,6 +9,41 @@ type Flavor<T, FlavorT> = T & {
9
9
  type SubscriptionId = Flavor<string, "SubscriptionId">;
10
10
  /** Unique identifier for a user who triggered an event. */
11
11
  type UserId = Flavor<string, "UserId">;
12
+ /** Actor representing a user action. */
13
+ type UserActor<Id extends string = string> = {
14
+ kind: "user";
15
+ id: Id;
16
+ };
17
+ /** Actor representing platform or infrastructure initiated work. */
18
+ type SystemActor = {
19
+ kind: "system";
20
+ };
21
+ /** Actor representing a background worker or job. */
22
+ type WorkerActor<Id extends string = string> = {
23
+ kind: "worker";
24
+ id?: Id;
25
+ };
26
+ /** Actor representing an API key. */
27
+ type ApiKeyActor<Id extends string = string> = {
28
+ kind: "api-key";
29
+ id: Id;
30
+ };
31
+ /** Actor representing an anonymous caller. */
32
+ type AnonymousActor = {
33
+ kind: "anonymous";
34
+ };
35
+ /** JSON-serializable actor metadata persisted alongside the event. */
36
+ type Actor = UserActor | SystemActor | WorkerActor | ApiKeyActor | AnonymousActor;
37
+ /** Creates a typed user actor. */
38
+ declare const createUserActor: <Id extends string>(id: Id) => UserActor<Id>;
39
+ /** Creates a typed system actor. */
40
+ declare const createSystemActor: () => SystemActor;
41
+ /** Creates a typed worker actor. */
42
+ declare const createWorkerActor: <Id extends string>(id?: Id) => WorkerActor<Id>;
43
+ /** Creates a typed API key actor. */
44
+ declare const createApiKeyActor: <Id extends string>(id: Id) => ApiKeyActor<Id>;
45
+ /** Creates a typed anonymous actor. */
46
+ declare const createAnonymousActor: () => AnonymousActor;
12
47
  /** Unique identifier for an event. */
13
48
  type EventId = Flavor<string, "EventId">;
14
49
  /**
@@ -73,12 +108,16 @@ type GenericEvent<T extends string, P, C extends DefaultContext = undefined> = {
73
108
  status: EventStatus;
74
109
  /** History of publication attempts. */
75
110
  publications: EventPublication[];
76
- /** User who triggered the action that created this event. */
77
- triggeredByUserId: UserId;
111
+ /** Actor identifier that triggered the action that created this event. */
112
+ triggeredByActor: Actor;
113
+ /** Optional correlation identifier for a request or cross-event flow. */
114
+ flowId?: string;
115
+ /** Optional parent event identifier for cascading events. */
116
+ causedByEventId?: EventId;
78
117
  /** Optional priority for processing order (not yet implemented in crawler). */
79
118
  priority?: number;
80
119
  /** Optional context for filtering events (e.g., by tenant). */
81
120
  context?: C;
82
121
  };
83
122
 
84
- export type { DefaultContext, EventFailure, EventId, EventPublication, EventStatus, Flavor, GenericEvent, SubscriptionId, UserId };
123
+ export { type Actor, type AnonymousActor, type ApiKeyActor, type DefaultContext, type EventFailure, type EventId, type EventPublication, type EventStatus, type Flavor, type GenericEvent, type SubscriptionId, type SystemActor, type UserActor, type UserId, type WorkerActor, createAnonymousActor, createApiKeyActor, createSystemActor, createUserActor, createWorkerActor };
package/dist/types.d.ts CHANGED
@@ -9,6 +9,41 @@ type Flavor<T, FlavorT> = T & {
9
9
  type SubscriptionId = Flavor<string, "SubscriptionId">;
10
10
  /** Unique identifier for a user who triggered an event. */
11
11
  type UserId = Flavor<string, "UserId">;
12
+ /** Actor representing a user action. */
13
+ type UserActor<Id extends string = string> = {
14
+ kind: "user";
15
+ id: Id;
16
+ };
17
+ /** Actor representing platform or infrastructure initiated work. */
18
+ type SystemActor = {
19
+ kind: "system";
20
+ };
21
+ /** Actor representing a background worker or job. */
22
+ type WorkerActor<Id extends string = string> = {
23
+ kind: "worker";
24
+ id?: Id;
25
+ };
26
+ /** Actor representing an API key. */
27
+ type ApiKeyActor<Id extends string = string> = {
28
+ kind: "api-key";
29
+ id: Id;
30
+ };
31
+ /** Actor representing an anonymous caller. */
32
+ type AnonymousActor = {
33
+ kind: "anonymous";
34
+ };
35
+ /** JSON-serializable actor metadata persisted alongside the event. */
36
+ type Actor = UserActor | SystemActor | WorkerActor | ApiKeyActor | AnonymousActor;
37
+ /** Creates a typed user actor. */
38
+ declare const createUserActor: <Id extends string>(id: Id) => UserActor<Id>;
39
+ /** Creates a typed system actor. */
40
+ declare const createSystemActor: () => SystemActor;
41
+ /** Creates a typed worker actor. */
42
+ declare const createWorkerActor: <Id extends string>(id?: Id) => WorkerActor<Id>;
43
+ /** Creates a typed API key actor. */
44
+ declare const createApiKeyActor: <Id extends string>(id: Id) => ApiKeyActor<Id>;
45
+ /** Creates a typed anonymous actor. */
46
+ declare const createAnonymousActor: () => AnonymousActor;
12
47
  /** Unique identifier for an event. */
13
48
  type EventId = Flavor<string, "EventId">;
14
49
  /**
@@ -73,12 +108,16 @@ type GenericEvent<T extends string, P, C extends DefaultContext = undefined> = {
73
108
  status: EventStatus;
74
109
  /** History of publication attempts. */
75
110
  publications: EventPublication[];
76
- /** User who triggered the action that created this event. */
77
- triggeredByUserId: UserId;
111
+ /** Actor identifier that triggered the action that created this event. */
112
+ triggeredByActor: Actor;
113
+ /** Optional correlation identifier for a request or cross-event flow. */
114
+ flowId?: string;
115
+ /** Optional parent event identifier for cascading events. */
116
+ causedByEventId?: EventId;
78
117
  /** Optional priority for processing order (not yet implemented in crawler). */
79
118
  priority?: number;
80
119
  /** Optional context for filtering events (e.g., by tenant). */
81
120
  context?: C;
82
121
  };
83
122
 
84
- export type { DefaultContext, EventFailure, EventId, EventPublication, EventStatus, Flavor, GenericEvent, SubscriptionId, UserId };
123
+ export { type Actor, type AnonymousActor, type ApiKeyActor, type DefaultContext, type EventFailure, type EventId, type EventPublication, type EventStatus, type Flavor, type GenericEvent, type SubscriptionId, type SystemActor, type UserActor, type UserId, type WorkerActor, createAnonymousActor, createApiKeyActor, createSystemActor, createUserActor, createWorkerActor };
package/dist/types.mjs CHANGED
@@ -1 +1,26 @@
1
+ const createUserActor = (id) => ({
2
+ kind: "user",
3
+ id
4
+ });
5
+ const createSystemActor = () => ({
6
+ kind: "system"
7
+ });
8
+ const createWorkerActor = (id) => ({
9
+ kind: "worker",
10
+ ...id !== void 0 ? { id } : {}
11
+ });
12
+ const createApiKeyActor = (id) => ({
13
+ kind: "api-key",
14
+ id
15
+ });
16
+ const createAnonymousActor = () => ({
17
+ kind: "anonymous"
18
+ });
19
+ export {
20
+ createAnonymousActor,
21
+ createApiKeyActor,
22
+ createSystemActor,
23
+ createUserActor,
24
+ createWorkerActor
25
+ };
1
26
  //# sourceMappingURL=types.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * Branded type helper for nominal typing.\n * Adds a phantom type property to distinguish between structurally identical types.\n */\nexport type Flavor<T, FlavorT> = T & {\n _type?: FlavorT;\n};\n\n/** Unique identifier for an event subscription. */\nexport type SubscriptionId = Flavor<string, \"SubscriptionId\">;\n\n/** Unique identifier for a user who triggered an event. */\nexport type UserId = Flavor<string, \"UserId\">;\n\n/** Actor representing a user action. */\nexport type UserActor<Id extends string = string> = {\n kind: \"user\";\n id: Id;\n};\n\n/** Actor representing platform or infrastructure initiated work. */\nexport type SystemActor = {\n kind: \"system\";\n};\n\n/** Actor representing a background worker or job. */\nexport type WorkerActor<Id extends string = string> = {\n kind: \"worker\";\n id?: Id;\n};\n\n/** Actor representing an API key. */\nexport type ApiKeyActor<Id extends string = string> = {\n kind: \"api-key\";\n id: Id;\n};\n\n/** Actor representing an anonymous caller. */\nexport type AnonymousActor = {\n kind: \"anonymous\";\n};\n\n/** JSON-serializable actor metadata persisted alongside the event. */\nexport type Actor =\n | UserActor\n | SystemActor\n | WorkerActor\n | ApiKeyActor\n | AnonymousActor;\n\n/** Creates a typed user actor. */\nexport const createUserActor = <Id extends string>(id: Id): UserActor<Id> => ({\n kind: \"user\",\n id,\n});\n\n/** Creates a typed system actor. */\nexport const createSystemActor = (): SystemActor => ({\n kind: \"system\",\n});\n\n/** Creates a typed worker actor. */\nexport const createWorkerActor = <Id extends string>(\n id?: Id,\n): WorkerActor<Id> => ({\n kind: \"worker\",\n ...(id !== undefined ? { id } : {}),\n});\n\n/** Creates a typed API key actor. */\nexport const createApiKeyActor = <Id extends string>(\n id: Id,\n): ApiKeyActor<Id> => ({\n kind: \"api-key\",\n id,\n});\n\n/** Creates a typed anonymous actor. */\nexport const createAnonymousActor = (): AnonymousActor => ({\n kind: \"anonymous\",\n});\n\n/** Unique identifier for an event. */\nexport type EventId = Flavor<string, \"EventId\">;\n\n/**\n * Records a subscription failure during event publication.\n * Contains the subscription that failed and error details for debugging.\n */\nexport type EventFailure = {\n subscriptionId: SubscriptionId;\n errorMessage: string;\n /** Stack trace captured when the subscription callback threw. */\n stack?: string;\n};\n\n/**\n * Records a single publication attempt for an event.\n * Tracks which subscribers were notified and any failures that occurred.\n */\nexport type EventPublication = {\n publishedAt: Date;\n /** All subscription IDs that were attempted in this publication. */\n publishedSubscribers: SubscriptionId[];\n /** Subscriptions that failed during this publication attempt. */\n failures?: EventFailure[];\n};\n\n/**\n * Event lifecycle status.\n * - `never-published`: New event, not yet processed by crawler\n * - `in-process`: Currently being published by crawler\n * - `published`: Successfully delivered to all subscribers\n * - `failed-but-will-retry`: Some subscribers failed, will retry\n * - `quarantined`: Exceeded max retries, requires manual intervention\n * - `to-republish`: Force republish to all subscribers (manual trigger)\n */\nexport type EventStatus =\n | \"never-published\"\n | \"to-republish\"\n | \"in-process\"\n | \"published\"\n | \"failed-but-will-retry\"\n | \"quarantined\";\n\n/** Context type constraint - must be a string record or undefined. */\nexport type DefaultContext = Record<string, string> | undefined;\n\n/**\n * Generic event type for the outbox pattern.\n * Events are persisted in the same transaction as domain changes,\n * then asynchronously published to subscribers.\n *\n * @typeParam T - Event topic/type string literal\n * @typeParam P - Event payload type\n * @typeParam C - Optional context for filtering (e.g., tenant ID)\n *\n * @example\n * ```typescript\n * type MyEvents =\n * | GenericEvent<\"UserCreated\", { userId: string; email: string }>\n * | GenericEvent<\"OrderPlaced\", { orderId: string }, { tenantId: string }>;\n * ```\n */\nexport type GenericEvent<\n T extends string,\n P,\n C extends DefaultContext = undefined,\n> = {\n /** Unique event identifier. */\n id: EventId;\n /** When the event occurred in the domain. */\n occurredAt: Date;\n /** Event type/topic for routing to subscribers. */\n topic: T;\n /** Event-specific data. */\n payload: P;\n /** Current lifecycle status. */\n status: EventStatus;\n /** History of publication attempts. */\n publications: EventPublication[];\n /** Actor identifier that triggered the action that created this event. */\n triggeredByActor: Actor;\n /** Optional correlation identifier for a request or cross-event flow. */\n flowId?: string;\n /** Optional parent event identifier for cascading events. */\n causedByEventId?: EventId;\n /** Optional priority for processing order (not yet implemented in crawler). */\n priority?: number;\n /** Optional context for filtering events (e.g., by tenant). */\n context?: C;\n};\n"],"mappings":"AAmDO,MAAM,kBAAkB,CAAoB,QAA2B;AAAA,EAC5E,MAAM;AAAA,EACN;AACF;AAGO,MAAM,oBAAoB,OAAoB;AAAA,EACnD,MAAM;AACR;AAGO,MAAM,oBAAoB,CAC/B,QACqB;AAAA,EACrB,MAAM;AAAA,EACN,GAAI,OAAO,SAAY,EAAE,GAAG,IAAI,CAAC;AACnC;AAGO,MAAM,oBAAoB,CAC/B,QACqB;AAAA,EACrB,MAAM;AAAA,EACN;AACF;AAGO,MAAM,uBAAuB,OAAuB;AAAA,EACzD,MAAM;AACR;","names":[]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "The purpose of this repository is to make it easy to setup event driven architecture using outbox pattern",
4
4
  "module": "src/index.ts",
5
5
  "type": "module",
6
- "version": "0.5.0",
6
+ "version": "0.6.0",
7
7
  "main": "./dist/index.mjs",
8
8
  "types": "./dist/index.d.ts",
9
9
  "files": [
@@ -1,4 +1,12 @@
1
- import { makeCreateNewEvent } from "../../createNewEvent.ts";
1
+ import {
2
+ type CreateNewEvent,
3
+ type CreateNewEventFromDefinitions,
4
+ makeCreateNewEvent,
5
+ } from "../../createNewEvent.ts";
6
+ import type {
7
+ EventDefinitions,
8
+ InferEventsFromDefinitions,
9
+ } from "../../eventDefinitions.ts";
2
10
  import type { EventBus } from "../../ports/EventBus.ts";
3
11
  import type { WithEventsUow } from "../../ports/EventRepository.ts";
4
12
  import {
@@ -26,17 +34,63 @@ type CreateInMemoryEventBusOptions = {
26
34
  generateId?: () => EventId;
27
35
  };
28
36
 
29
- export const createInMemoryEventBus = <
37
+ type CreateInMemoryEventBusFromDefinitionsOptions<
38
+ Definitions extends EventDefinitions,
39
+ > = CreateInMemoryEventBusOptions & {
40
+ eventDefinitions: Definitions;
41
+ };
42
+
43
+ type CreateInMemoryEventBusResult<
44
+ Event extends GenericEvent<string, unknown, DefaultContext>,
45
+ > = {
46
+ eventBus: EventBus<Event>;
47
+ createNewEvent: CreateNewEvent<Event>;
48
+ defineSubscriptions: (
49
+ subscriptions: TopicSubscriptions<Event>,
50
+ ) => TopicSubscriptions<Event>;
51
+ subscribeAll: (subscriptions: TopicSubscriptions<Event>) => void;
52
+ subscribeGlobal: (
53
+ subscriptions: TopicSubscriptions<Event>,
54
+ config: GlobalSubscriberConfig<Event>,
55
+ ) => void;
56
+ };
57
+
58
+ export function createInMemoryEventBus<
59
+ Event extends GenericEvent<string, unknown, DefaultContext>,
60
+ >(
61
+ withUow: WithEventsUow<Event>,
62
+ options?: CreateInMemoryEventBusOptions,
63
+ ): CreateInMemoryEventBusResult<Event>;
64
+ export function createInMemoryEventBus<Definitions extends EventDefinitions>(
65
+ withUow: WithEventsUow<InferEventsFromDefinitions<Definitions>>,
66
+ options: CreateInMemoryEventBusFromDefinitionsOptions<Definitions>,
67
+ ): Omit<
68
+ CreateInMemoryEventBusResult<InferEventsFromDefinitions<Definitions>>,
69
+ "createNewEvent"
70
+ > & {
71
+ createNewEvent: CreateNewEventFromDefinitions<Definitions>;
72
+ };
73
+ export function createInMemoryEventBus<
30
74
  Event extends GenericEvent<string, unknown, DefaultContext>,
31
75
  >(
32
76
  withUow: WithEventsUow<Event>,
33
- options: CreateInMemoryEventBusOptions = {},
34
- ) => {
77
+ options:
78
+ | CreateInMemoryEventBusOptions
79
+ | CreateInMemoryEventBusFromDefinitionsOptions<EventDefinitions> = {},
80
+ ) {
35
81
  const maxRetries = options.maxRetries ?? 3;
36
- const createNewEvent = makeCreateNewEvent<Event>({
37
- getNow: options.getNow,
38
- generateId: options.generateId,
39
- });
82
+ const eventDefinitions =
83
+ "eventDefinitions" in options ? options.eventDefinitions : undefined;
84
+ const createNewEvent = eventDefinitions
85
+ ? makeCreateNewEvent({
86
+ getNow: options.getNow,
87
+ generateId: options.generateId,
88
+ eventDefinitions,
89
+ })
90
+ : makeCreateNewEvent<Event>({
91
+ getNow: options.getNow,
92
+ generateId: options.generateId,
93
+ });
40
94
  const subscriptions: Partial<Record<string, SubscriptionsForTopic>> = {};
41
95
 
42
96
  const executeCallback = async (
@@ -221,4 +275,4 @@ export const createInMemoryEventBus = <
221
275
  subscribeAll,
222
276
  subscribeGlobal,
223
277
  };
224
- };
278
+ }
@@ -36,6 +36,8 @@ export const createKyselyEventQueries = <
36
36
  ({
37
37
  ...row,
38
38
  context: row.context ?? undefined,
39
+ flowId: row.flowId ?? undefined,
40
+ causedByEventId: row.causedByEventId ?? undefined,
39
41
  priority: row.priority ?? undefined,
40
42
  }) as Event,
41
43
  );
@@ -17,6 +17,7 @@ export const createKyselyEventRepository = <
17
17
  .values({
18
18
  ...event,
19
19
  payload: jsonb(event.payload),
20
+ triggeredByActor: jsonb(event.triggeredByActor),
20
21
  context: jsonb(event.context),
21
22
  publications: jsonb(event.publications),
22
23
  })
@@ -24,9 +25,11 @@ export const createKyselyEventRepository = <
24
25
  oc.column("id").doUpdateSet({
25
26
  topic: event.topic,
26
27
  payload: jsonb(event.payload),
28
+ triggeredByActor: jsonb(event.triggeredByActor),
27
29
  context: jsonb(event.context),
28
30
  status: event.status,
29
- triggeredByUserId: event.triggeredByUserId,
31
+ flowId: event.flowId,
32
+ causedByEventId: event.causedByEventId,
30
33
  occurredAt: event.occurredAt,
31
34
  publications: jsonb(event.publications),
32
35
  priority: event.priority,
@@ -43,6 +46,7 @@ export const createKyselyEventRepository = <
43
46
  events.map((event) => ({
44
47
  ...event,
45
48
  payload: jsonb(event.payload),
49
+ triggeredByActor: jsonb(event.triggeredByActor),
46
50
  context: jsonb(event.context),
47
51
  publications: jsonb(event.publications),
48
52
  })),
@@ -8,7 +8,9 @@ export async function up(db: Kysely<unknown>): Promise<void> {
8
8
  .addColumn("payload", "jsonb", (col) => col.notNull())
9
9
  .addColumn("context", "jsonb")
10
10
  .addColumn("status", "text", (col) => col.notNull())
11
- .addColumn("triggeredByUserId", "text", (col) => col.notNull())
11
+ .addColumn("triggeredByActor", "jsonb", (col) => col.notNull())
12
+ .addColumn("flowId", "text")
13
+ .addColumn("causedByEventId", "text")
12
14
  .addColumn("occurredAt", "timestamptz", (col) => col.notNull())
13
15
  .addColumn("publications", "jsonb", (col) => col.notNull().defaultTo("[]"))
14
16
  .addColumn("priority", "integer")