@arki/event-sourcing 0.1.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 (130) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +124 -0
  3. package/dist/builders/command-handler.d.ts +48 -0
  4. package/dist/builders/command-handler.d.ts.map +1 -0
  5. package/dist/builders/command-handler.js +40 -0
  6. package/dist/builders/command-handler.js.map +1 -0
  7. package/dist/builders/command.d.ts +39 -0
  8. package/dist/builders/command.d.ts.map +1 -0
  9. package/dist/builders/command.js +44 -0
  10. package/dist/builders/command.js.map +1 -0
  11. package/dist/builders/decider.d.ts +188 -0
  12. package/dist/builders/decider.d.ts.map +1 -0
  13. package/dist/builders/decider.js +252 -0
  14. package/dist/builders/decider.js.map +1 -0
  15. package/dist/builders/event.d.ts +39 -0
  16. package/dist/builders/event.d.ts.map +1 -0
  17. package/dist/builders/event.js +42 -0
  18. package/dist/builders/event.js.map +1 -0
  19. package/dist/builders/index.d.ts +40 -0
  20. package/dist/builders/index.d.ts.map +1 -0
  21. package/dist/builders/index.js +40 -0
  22. package/dist/builders/index.js.map +1 -0
  23. package/dist/builders/process-manager.d.ts +94 -0
  24. package/dist/builders/process-manager.d.ts.map +1 -0
  25. package/dist/builders/process-manager.js +131 -0
  26. package/dist/builders/process-manager.js.map +1 -0
  27. package/dist/builders/projection.d.ts +92 -0
  28. package/dist/builders/projection.d.ts.map +1 -0
  29. package/dist/builders/projection.js +129 -0
  30. package/dist/builders/projection.js.map +1 -0
  31. package/dist/builders/stateful-process-manager.d.ts +181 -0
  32. package/dist/builders/stateful-process-manager.d.ts.map +1 -0
  33. package/dist/builders/stateful-process-manager.js +280 -0
  34. package/dist/builders/stateful-process-manager.js.map +1 -0
  35. package/dist/bus.d.ts +3 -0
  36. package/dist/bus.d.ts.map +1 -0
  37. package/dist/bus.js +2 -0
  38. package/dist/bus.js.map +1 -0
  39. package/dist/command-flow.d.ts +87 -0
  40. package/dist/command-flow.d.ts.map +1 -0
  41. package/dist/command-flow.js +233 -0
  42. package/dist/command-flow.js.map +1 -0
  43. package/dist/command.d.ts +38 -0
  44. package/dist/command.d.ts.map +1 -0
  45. package/dist/command.js +2 -0
  46. package/dist/command.js.map +1 -0
  47. package/dist/debug.d.ts +31 -0
  48. package/dist/debug.d.ts.map +1 -0
  49. package/dist/debug.js +31 -0
  50. package/dist/debug.js.map +1 -0
  51. package/dist/decide.d.ts +11 -0
  52. package/dist/decide.d.ts.map +1 -0
  53. package/dist/decide.js +2 -0
  54. package/dist/decide.js.map +1 -0
  55. package/dist/dot.d.ts +90 -0
  56. package/dist/dot.d.ts.map +1 -0
  57. package/dist/dot.js +91 -0
  58. package/dist/dot.js.map +1 -0
  59. package/dist/error.d.ts +2 -0
  60. package/dist/error.d.ts.map +1 -0
  61. package/dist/error.js +2 -0
  62. package/dist/error.js.map +1 -0
  63. package/dist/event-sourcing-features.d.ts +81 -0
  64. package/dist/event-sourcing-features.d.ts.map +1 -0
  65. package/dist/event-sourcing-features.js +139 -0
  66. package/dist/event-sourcing-features.js.map +1 -0
  67. package/dist/event.d.ts +25 -0
  68. package/dist/event.d.ts.map +1 -0
  69. package/dist/event.js +2 -0
  70. package/dist/event.js.map +1 -0
  71. package/dist/index.d.ts +7 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +6 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/package.json +5 -0
  76. package/dist/process-manager.d.ts +113 -0
  77. package/dist/process-manager.d.ts.map +1 -0
  78. package/dist/process-manager.js +155 -0
  79. package/dist/process-manager.js.map +1 -0
  80. package/dist/simple-process-manager.d.ts +37 -0
  81. package/dist/simple-process-manager.d.ts.map +1 -0
  82. package/dist/simple-process-manager.js +55 -0
  83. package/dist/simple-process-manager.js.map +1 -0
  84. package/dist/src/builders/command-handler.d.ts +48 -0
  85. package/dist/src/builders/command-handler.d.ts.map +1 -0
  86. package/dist/src/builders/command.d.ts +39 -0
  87. package/dist/src/builders/command.d.ts.map +1 -0
  88. package/dist/src/builders/decider.d.ts +188 -0
  89. package/dist/src/builders/decider.d.ts.map +1 -0
  90. package/dist/src/builders/event.d.ts +39 -0
  91. package/dist/src/builders/event.d.ts.map +1 -0
  92. package/dist/src/builders/index.d.ts +40 -0
  93. package/dist/src/builders/index.d.ts.map +1 -0
  94. package/dist/src/builders/process-manager.d.ts +94 -0
  95. package/dist/src/builders/process-manager.d.ts.map +1 -0
  96. package/dist/src/builders/projection.d.ts +92 -0
  97. package/dist/src/builders/projection.d.ts.map +1 -0
  98. package/dist/src/builders/stateful-process-manager.d.ts +181 -0
  99. package/dist/src/builders/stateful-process-manager.d.ts.map +1 -0
  100. package/dist/src/bus.d.ts +3 -0
  101. package/dist/src/bus.d.ts.map +1 -0
  102. package/dist/src/command-flow.d.ts +87 -0
  103. package/dist/src/command-flow.d.ts.map +1 -0
  104. package/dist/src/command.d.ts +16 -0
  105. package/dist/src/command.d.ts.map +1 -0
  106. package/dist/src/debug.d.ts +31 -0
  107. package/dist/src/debug.d.ts.map +1 -0
  108. package/dist/src/decide.d.ts +11 -0
  109. package/dist/src/decide.d.ts.map +1 -0
  110. package/dist/src/error.d.ts +2 -0
  111. package/dist/src/error.d.ts.map +1 -0
  112. package/dist/src/event.d.ts +25 -0
  113. package/dist/src/event.d.ts.map +1 -0
  114. package/dist/src/index.d.ts +5 -0
  115. package/dist/src/index.d.ts.map +1 -0
  116. package/dist/src/process-manager.d.ts +113 -0
  117. package/dist/src/process-manager.d.ts.map +1 -0
  118. package/dist/src/store.d.ts +44 -0
  119. package/dist/src/store.d.ts.map +1 -0
  120. package/dist/src/types.d.ts +10 -0
  121. package/dist/src/types.d.ts.map +1 -0
  122. package/dist/store.d.ts +44 -0
  123. package/dist/store.d.ts.map +1 -0
  124. package/dist/store.js +94 -0
  125. package/dist/store.js.map +1 -0
  126. package/dist/types.d.ts +10 -0
  127. package/dist/types.d.ts.map +1 -0
  128. package/dist/types.js +2 -0
  129. package/dist/types.js.map +1 -0
  130. package/package.json +100 -0
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export * from './command.js';
2
+ export * from './decide.js';
3
+ export * from './event.js';
4
+ export { createSimpleProcessManager } from './simple-process-manager.js';
5
+ export { EVENT_STORE_URL_VARIANTS, eventSourcingFeatures, } from './event-sourcing-features.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EACL,wBAAwB,EACxB,qBAAqB,GAEtB,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "dist",
3
+ "version": "0.0.0",
4
+ "private": true
5
+ }
@@ -0,0 +1,113 @@
1
+ import type { AnyEvent, DefaultRecord, Event, EventTypeOf, GlobalPositionTypeOfRecordedMessageMetadata, MessageBus, MessageProcessorStartFrom, ReadEventMetadataWithGlobalPosition } from '@event-driven-io/emmett';
2
+ /**
3
+ * Process Manager (Saga) handler context
4
+ * This context is passed to the process manager handler function
5
+ */
6
+ export type ProcessManagerContext = DefaultRecord & {
7
+ /** Message bus for sending commands in response to events */
8
+ messageBus: MessageBus;
9
+ };
10
+ /**
11
+ * Process Manager handler function
12
+ */
13
+ export type ProcessManagerHandler<EventType extends Event = AnyEvent, Context extends ProcessManagerContext = ProcessManagerContext> = (events: EventType[], context: Context) => Promise<void>;
14
+ /**
15
+ * Process Manager configuration options
16
+ */
17
+ export type ProcessManagerOptions<EventType extends Event = AnyEvent, Context extends ProcessManagerContext = ProcessManagerContext, CheckpointType = GlobalPositionTypeOfRecordedMessageMetadata<ReadEventMetadataWithGlobalPosition>> = {
18
+ /** Unique identifier for the process manager */
19
+ name: string;
20
+ /** Event types the process manager will handle */
21
+ eventTypes: EventTypeOf<EventType>[];
22
+ /** Handler function that processes events */
23
+ handler: ProcessManagerHandler<EventType, Context>;
24
+ /**
25
+ * Optional hooks for process manager lifecycle
26
+ */
27
+ hooks?: {
28
+ /** Called when the process manager starts */
29
+ onStart?: (context: Context) => Promise<void>;
30
+ /** Called when the process manager closes */
31
+ onClose?: () => Promise<void>;
32
+ };
33
+ /**
34
+ * Optional configuration for resuming from specific checkpoint
35
+ * Useful for long-running process managers
36
+ */
37
+ startFrom?: MessageProcessorStartFrom<CheckpointType>;
38
+ };
39
+ /**
40
+ * Creates a process manager (saga) that subscribes to events and orchestrates responses
41
+ * This is built on top of Emmett's reactor functionality
42
+ */
43
+ export declare function createProcessManager<EventType extends Event = AnyEvent, Context extends ProcessManagerContext = ProcessManagerContext, CheckpointType = GlobalPositionTypeOfRecordedMessageMetadata<ReadEventMetadataWithGlobalPosition>>(options: ProcessManagerOptions<EventType, Context, CheckpointType>): import("@event-driven-io/emmett").MessageProcessor<EventType, ReadEventMetadataWithGlobalPosition, Context, CheckpointType>;
44
+ /**
45
+ * State that can be maintained by a stateful process manager
46
+ */
47
+ export type ProcessManagerState = DefaultRecord;
48
+ /**
49
+ * Handler function for a stateful process manager
50
+ */
51
+ export type StatefulProcessManagerHandler<EventType extends Event = AnyEvent, StateType extends ProcessManagerState = ProcessManagerState, Context extends ProcessManagerContext = ProcessManagerContext> = (events: EventType[], state: StateType, context: Context) => Promise<StateType>;
52
+ /**
53
+ * Options for creating a stateful process manager
54
+ */
55
+ export type StatefulProcessManagerOptions<EventType extends Event = AnyEvent, StateType extends ProcessManagerState = ProcessManagerState, Context extends ProcessManagerContext = ProcessManagerContext, CheckpointType = GlobalPositionTypeOfRecordedMessageMetadata<ReadEventMetadataWithGlobalPosition>> = Omit<ProcessManagerOptions<EventType, Context, CheckpointType>, 'handler'> & {
56
+ /** Initial state for the process manager */
57
+ initialState: StateType;
58
+ /** Handler function that processes events and updates state */
59
+ handler: StatefulProcessManagerHandler<EventType, StateType, Context>;
60
+ /**
61
+ * Store function that persists process manager state
62
+ * Called after each successful event processing
63
+ */
64
+ storeState?: (state: StateType, processorId: string) => Promise<void>;
65
+ /**
66
+ * Load function that retrieves process manager state
67
+ * Called during initialization
68
+ */
69
+ loadState?: (processorId: string) => Promise<StateType | null>;
70
+ };
71
+ /**
72
+ * Creates a stateful process manager that maintains its own state
73
+ * This is useful for tracking saga state across event processing
74
+ */
75
+ export declare function createStatefulProcessManager<EventType extends Event = AnyEvent, StateType extends ProcessManagerState = ProcessManagerState, Context extends ProcessManagerContext = ProcessManagerContext, CheckpointType = GlobalPositionTypeOfRecordedMessageMetadata<ReadEventMetadataWithGlobalPosition>>(options: StatefulProcessManagerOptions<EventType, StateType, Context, CheckpointType>): import("@event-driven-io/emmett").MessageProcessor<EventType, ReadEventMetadataWithGlobalPosition, Context, CheckpointType>;
76
+ /**
77
+ * Function to generate a unique idempotency key for an event
78
+ * Used to ensure that a process manager only processes an event once
79
+ *
80
+ * @param event The event to generate an idempotency key for
81
+ * @param processManagerId Optional identifier for the process manager
82
+ * @returns A string that can be used as an idempotency key
83
+ */
84
+ export declare function generateIdempotencyKey(event: Event<any, any, ReadEventMetadataWithGlobalPosition>, processManagerId?: string): string;
85
+ /**
86
+ * Interface for a function to check if an event has already been processed
87
+ */
88
+ export type IdempotencyCheck = (key: string) => Promise<boolean>;
89
+ /**
90
+ * Interface for a function to mark an event as processed
91
+ */
92
+ export type MarkProcessed = (key: string) => Promise<void>;
93
+ /**
94
+ * Options for idempotent event processing
95
+ */
96
+ export type IdempotentProcessingOptions = {
97
+ /** Function to check if an event has already been processed */
98
+ checkProcessed: IdempotencyCheck;
99
+ /** Function to mark an event as processed */
100
+ markProcessed: MarkProcessed;
101
+ /** Optional process manager ID to include in the idempotency key */
102
+ processManagerId?: string;
103
+ };
104
+ /**
105
+ * Higher-order function that wraps a process manager handler to provide idempotent processing
106
+ * This ensures that each event is only processed once, even if it's received multiple times
107
+ *
108
+ * @param handler The original process manager handler
109
+ * @param options Options for idempotent processing
110
+ * @returns A wrapped handler that implements idempotent processing
111
+ */
112
+ export declare function withIdempotentProcessing<EventType extends Event<any, any, ReadEventMetadataWithGlobalPosition> = Event<any, any, ReadEventMetadataWithGlobalPosition>, Context extends ProcessManagerContext = ProcessManagerContext>(handler: ProcessManagerHandler<EventType, Context>, options: IdempotentProcessingOptions): ProcessManagerHandler<EventType, Context>;
113
+ //# sourceMappingURL=process-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-manager.d.ts","sourceRoot":"","sources":["../src/process-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,155 @@
1
+ import { reactor } from '@event-driven-io/emmett';
2
+ import { debugProcess } from './debug.js';
3
+ /**
4
+ * Creates a process manager (saga) that subscribes to events and orchestrates responses
5
+ * This is built on top of Emmett's reactor functionality
6
+ */
7
+ export function createProcessManager(options) {
8
+ const { name, eventTypes, handler, hooks, startFrom } = options;
9
+ debugProcess('[%s] Creating process manager for event types: %o', name, eventTypes);
10
+ return reactor({
11
+ processorId: name,
12
+ canHandle: eventTypes,
13
+ startFrom,
14
+ // Process events in batch mode
15
+ eachBatch: async (events, context) => {
16
+ debugProcess('[%s] Processing batch of %d events', name, events.length);
17
+ await handler(events, context);
18
+ debugProcess('[%s] Batch processed successfully', name);
19
+ },
20
+ // Pass through lifecycle hooks
21
+ hooks: {
22
+ onStart: async (context) => {
23
+ debugProcess('[%s] Process manager starting', name);
24
+ if (hooks?.onStart) {
25
+ await hooks.onStart(context);
26
+ }
27
+ debugProcess('[%s] Process manager started', name);
28
+ },
29
+ onClose: async () => {
30
+ debugProcess('[%s] Process manager closing', name);
31
+ if (hooks?.onClose) {
32
+ await hooks.onClose();
33
+ }
34
+ debugProcess('[%s] Process manager closed', name);
35
+ },
36
+ },
37
+ });
38
+ }
39
+ /**
40
+ * Creates a stateful process manager that maintains its own state
41
+ * This is useful for tracking saga state across event processing
42
+ */
43
+ export function createStatefulProcessManager(options) {
44
+ const { name, eventTypes, initialState, handler, hooks, startFrom, storeState, loadState } = options;
45
+ debugProcess('[%s] Creating stateful process manager for event types: %o', name, eventTypes);
46
+ // Initialize state (will be updated during processing)
47
+ let state = initialState;
48
+ return reactor({
49
+ processorId: name,
50
+ canHandle: eventTypes,
51
+ startFrom,
52
+ hooks: {
53
+ // Load state during startup
54
+ onStart: async (context) => {
55
+ debugProcess('[%s] Stateful process manager starting', name);
56
+ if (loadState) {
57
+ debugProcess('[%s] Loading state from storage', name);
58
+ const loadedState = await loadState(name);
59
+ if (loadedState) {
60
+ state = loadedState;
61
+ debugProcess('[%s] State loaded successfully', name);
62
+ }
63
+ else {
64
+ debugProcess('[%s] No stored state found, using initial state', name);
65
+ }
66
+ }
67
+ // Call user-provided onStart hook if specified
68
+ if (hooks?.onStart) {
69
+ await hooks.onStart(context);
70
+ }
71
+ debugProcess('[%s] Stateful process manager started', name);
72
+ },
73
+ // Call user-provided onClose hook if specified
74
+ onClose: async () => {
75
+ debugProcess('[%s] Stateful process manager closing', name);
76
+ if (hooks?.onClose) {
77
+ await hooks.onClose();
78
+ }
79
+ debugProcess('[%s] Stateful process manager closed', name);
80
+ },
81
+ },
82
+ // Process events and update state
83
+ eachBatch: async (events, context) => {
84
+ debugProcess('[%s] Processing batch of %d events (stateful)', name, events.length);
85
+ // Update state based on events
86
+ state = await handler(events, state, context);
87
+ debugProcess('[%s] State updated after processing events', name);
88
+ // Persist updated state if storage function provided
89
+ if (storeState) {
90
+ debugProcess('[%s] Storing updated state', name);
91
+ await storeState(state, name);
92
+ debugProcess('[%s] State stored successfully', name);
93
+ }
94
+ },
95
+ });
96
+ }
97
+ /**
98
+ * Function to generate a unique idempotency key for an event
99
+ * Used to ensure that a process manager only processes an event once
100
+ *
101
+ * @param event The event to generate an idempotency key for
102
+ * @param processManagerId Optional identifier for the process manager
103
+ * @returns A string that can be used as an idempotency key
104
+ */
105
+ export function generateIdempotencyKey(event, processManagerId) {
106
+ // Get the event metadata
107
+ const metadata = event.metadata;
108
+ // Create an idempotency key using stream name, position, and optionally process manager ID
109
+ const baseKey = `${metadata.streamName}:${metadata.streamPosition}:${event.type}`;
110
+ // Add process manager ID if provided
111
+ return processManagerId ? `${processManagerId}:${baseKey}` : baseKey;
112
+ }
113
+ /**
114
+ * Higher-order function that wraps a process manager handler to provide idempotent processing
115
+ * This ensures that each event is only processed once, even if it's received multiple times
116
+ *
117
+ * @param handler The original process manager handler
118
+ * @param options Options for idempotent processing
119
+ * @returns A wrapped handler that implements idempotent processing
120
+ */
121
+ export function withIdempotentProcessing(handler, options) {
122
+ const { checkProcessed, markProcessed, processManagerId } = options;
123
+ debugProcess('[%s] Wrapping handler with idempotent processing', processManagerId ?? 'unknown');
124
+ return async (events, context) => {
125
+ debugProcess('[%s] Checking idempotency for %d events', processManagerId ?? 'unknown', events.length);
126
+ // Filter out events that have already been processed
127
+ const unprocessedEvents = [];
128
+ const processedKeys = [];
129
+ // Check each event
130
+ for (const event of events) {
131
+ const idempotencyKey = generateIdempotencyKey(event, processManagerId);
132
+ const alreadyProcessed = await checkProcessed(idempotencyKey);
133
+ if (alreadyProcessed) {
134
+ debugProcess('[%s] Event already processed, skipping: %s', processManagerId ?? 'unknown', idempotencyKey);
135
+ }
136
+ else {
137
+ unprocessedEvents.push(event);
138
+ processedKeys.push(idempotencyKey);
139
+ }
140
+ }
141
+ // If no events need processing, return early
142
+ if (unprocessedEvents.length === 0) {
143
+ debugProcess('[%s] All events already processed, skipping batch', processManagerId ?? 'unknown');
144
+ return;
145
+ }
146
+ debugProcess('[%s] Processing %d unprocessed events', processManagerId ?? 'unknown', unprocessedEvents.length);
147
+ // Process the unprocessed events
148
+ await handler(unprocessedEvents, context);
149
+ // Mark all events as processed
150
+ debugProcess('[%s] Marking %d events as processed', processManagerId ?? 'unknown', processedKeys.length);
151
+ await Promise.all(processedKeys.map(key => markProcessed(key)));
152
+ debugProcess('[%s] Idempotent processing completed', processManagerId ?? 'unknown');
153
+ };
154
+ }
155
+ //# sourceMappingURL=process-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-manager.js","sourceRoot":"","sources":["../src/process-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { Event } from '@event-driven-io/emmett';
2
+ /**
3
+ * Creates a simple process manager that reacts to events one at a time,
4
+ * with a pre-bound context closed over at construction time.
5
+ *
6
+ * This is a thin wrapper around Emmett's `reactor` that exposes a positional
7
+ * API with per-message processing semantics. It is intended for the most
8
+ * common process manager use case where:
9
+ *
10
+ * - The context (repositories, KV, message bus, etc.) is fixed at construction time.
11
+ * - The handler operates on one event at a time rather than a batch.
12
+ * - Errors propagate to the consumer so the underlying subscription can
13
+ * apply retry/back-off policies.
14
+ *
15
+ * For richer use cases (per-batch processing, lifecycle hooks, stateful
16
+ * sagas, idempotency) prefer {@link createProcessManager} or
17
+ * {@link createStatefulProcessManager} from this package.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * const trackingNotifications = createSimpleProcessManager(
22
+ * { repo, kv },
23
+ * 'tracking-notifications',
24
+ * ['MovieWatchLogged', 'TvShowRated'],
25
+ * async (event, context) => {
26
+ * // ... handle one event using context
27
+ * },
28
+ * );
29
+ * ```
30
+ *
31
+ * @param context Fixed context closed over by the process manager handler.
32
+ * @param name Unique identifier for the process manager (used as processor id).
33
+ * @param eventTypes Event types this process manager reacts to.
34
+ * @param handlerFn Async function invoked once per matching event.
35
+ */
36
+ export declare function createSimpleProcessManager<TEvent extends Event, TContext extends object>(context: TContext, name: string, eventTypes: TEvent['type'][], handlerFn: (event: TEvent, context: TContext) => Promise<void>): import("@event-driven-io/emmett").MessageProcessor<TEvent, import("@event-driven-io/emmett").AnyRecordedMessageMetadata, import("@event-driven-io/emmett").DefaultRecord, any>;
37
+ //# sourceMappingURL=simple-process-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-process-manager.d.ts","sourceRoot":"","sources":["../src/simple-process-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAKrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,SAAS,KAAK,EAAE,QAAQ,SAAS,MAAM,EACtF,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAC5B,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,kLA0B/D"}
@@ -0,0 +1,55 @@
1
+ import { reactor } from '@event-driven-io/emmett';
2
+ import { debugProcess } from './debug.js';
3
+ /**
4
+ * Creates a simple process manager that reacts to events one at a time,
5
+ * with a pre-bound context closed over at construction time.
6
+ *
7
+ * This is a thin wrapper around Emmett's `reactor` that exposes a positional
8
+ * API with per-message processing semantics. It is intended for the most
9
+ * common process manager use case where:
10
+ *
11
+ * - The context (repositories, KV, message bus, etc.) is fixed at construction time.
12
+ * - The handler operates on one event at a time rather than a batch.
13
+ * - Errors propagate to the consumer so the underlying subscription can
14
+ * apply retry/back-off policies.
15
+ *
16
+ * For richer use cases (per-batch processing, lifecycle hooks, stateful
17
+ * sagas, idempotency) prefer {@link createProcessManager} or
18
+ * {@link createStatefulProcessManager} from this package.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const trackingNotifications = createSimpleProcessManager(
23
+ * { repo, kv },
24
+ * 'tracking-notifications',
25
+ * ['MovieWatchLogged', 'TvShowRated'],
26
+ * async (event, context) => {
27
+ * // ... handle one event using context
28
+ * },
29
+ * );
30
+ * ```
31
+ *
32
+ * @param context Fixed context closed over by the process manager handler.
33
+ * @param name Unique identifier for the process manager (used as processor id).
34
+ * @param eventTypes Event types this process manager reacts to.
35
+ * @param handlerFn Async function invoked once per matching event.
36
+ */
37
+ export function createSimpleProcessManager(context, name, eventTypes, handlerFn) {
38
+ debugProcess('[createSimpleProcessManager] Creating process manager: %s for event types: %s', name, eventTypes.join(', '));
39
+ return reactor({
40
+ canHandle: [...eventTypes],
41
+ eachMessage: async (message) => {
42
+ debugProcess('[createSimpleProcessManager:%s] Processing event: %s', name, message.type);
43
+ try {
44
+ await handlerFn(message, context);
45
+ debugProcess('[createSimpleProcessManager:%s] Successfully processed event: %s', name, message.type);
46
+ }
47
+ catch (error) {
48
+ debugProcess('[createSimpleProcessManager:%s] Error processing event %s: %s', name, message.type, error instanceof Error ? error.message : String(error));
49
+ throw error;
50
+ }
51
+ },
52
+ processorId: `process-manager-${name}`,
53
+ });
54
+ }
55
+ //# sourceMappingURL=simple-process-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-process-manager.js","sourceRoot":"","sources":["../src/simple-process-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAAiB,EACjB,IAAY,EACZ,UAA4B,EAC5B,SAA8D;IAE9D,YAAY,CACV,+EAA+E,EAC/E,IAAI,EACJ,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CACtB,CAAC;IACF,OAAO,OAAO,CAAS;QACrB,SAAS,EAAE,CAAC,GAAG,UAAU,CAAC;QAC1B,WAAW,EAAE,KAAK,EAAC,OAAO,EAAC,EAAE;YAC3B,YAAY,CAAC,sDAAsD,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;YACzF,IAAI,CAAC;gBACH,MAAM,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAClC,YAAY,CAAC,kEAAkE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;YACvG,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,YAAY,CACV,+DAA+D,EAC/D,IAAI,EACJ,OAAO,CAAC,IAAI,EACZ,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;gBACF,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QACD,WAAW,EAAE,mBAAmB,IAAI,EAAE;KACvC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,48 @@
1
+ import type { CommandHandlerResult, Event, EventStore, HandleOptions } from '@event-driven-io/emmett';
2
+ type DeciderConfig<State, CommandType, StreamEvent> = {
3
+ initialState: () => State;
4
+ evolve: (state: State, event: StreamEvent) => State;
5
+ decide: (command: CommandType, state: State) => StreamEvent | StreamEvent[];
6
+ };
7
+ /**
8
+ * Store-connected command handler function type.
9
+ *
10
+ * Given an event store, stream id, and one or more commands, it loads the
11
+ * current aggregate state from the stream, applies the decider's `decide`
12
+ * function, and appends the resulting events.
13
+ */
14
+ export type CommandHandler<State, CommandType, StreamEvent extends Event> = <Store extends EventStore>(eventStore: Store, id: string, commands: CommandType | CommandType[], handleOptions?: HandleOptions<Store>) => Promise<CommandHandlerResult<State, StreamEvent, Store>>;
15
+ /**
16
+ * Creates a store-connected command handler from a decider configuration.
17
+ *
18
+ * This is the recommended way to create command handlers. It wraps Emmett's
19
+ * `DeciderCommandHandler` while lifting the `CommandType extends Command`
20
+ * constraint that prevents commands with custom metadata from type-checking.
21
+ *
22
+ * Emmett's `Command` type uses a conditional type for metadata:
23
+ * - When metadata is `undefined`, the `metadata` property is optional.
24
+ * - When metadata is defined, it becomes required.
25
+ *
26
+ * TypeScript cannot prove that a concrete command (with custom metadata)
27
+ * satisfies `extends Command` across these conditional branches. This wrapper
28
+ * bridges that gap with a single, localised type assertion — keeping all
29
+ * call sites fully type-safe.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const handler = defineCommandHandler({
34
+ * initialState,
35
+ * evolve,
36
+ * decide,
37
+ * });
38
+ *
39
+ * export const bookCommandHandlers = BookCommands.map(commandType => ({
40
+ * commandType,
41
+ * handler,
42
+ * getStreamName,
43
+ * }));
44
+ * ```
45
+ */
46
+ export declare function defineCommandHandler<State, CommandType, StreamEvent extends Event>(config: DeciderConfig<State, CommandType, StreamEvent>): CommandHandler<State, CommandType, StreamEvent>;
47
+ export {};
48
+ //# sourceMappingURL=command-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-handler.d.ts","sourceRoot":"","sources":["../../../src/builders/command-handler.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAU,oBAAoB,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,EAAC,MAAM,yBAAyB,CAAC;AAI7G,KAAK,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,IAAI;IACpD,YAAY,EAAE,MAAM,KAAK,CAAC;IAC1B,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,KAAK,KAAK,CAAC;IACpD,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,KAAK,WAAW,GAAG,WAAW,EAAE,CAAC;CAC7E,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,SAAS,KAAK,IAAI,CAAC,KAAK,SAAS,UAAU,EACnG,UAAU,EAAE,KAAK,EACjB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,WAAW,GAAG,WAAW,EAAE,EACrC,aAAa,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,KACjC,OAAO,CAAC,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,SAAS,KAAK,EAChF,MAAM,EAAE,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,CAAC,GACrD,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,CAAC,CAWjD"}
@@ -0,0 +1,39 @@
1
+ import type { z } from '@arki/contracts';
2
+ import type { Command, DefaultCommandMetadata } from '../command';
3
+ import type { DefaultRecord } from '../types';
4
+ /**
5
+ * Configuration for defining a domain command factory.
6
+ */
7
+ export type CommandConfig<TType extends string, TInput extends DefaultRecord, TMetadata extends DefaultCommandMetadata | undefined = undefined> = {
8
+ /** The command type string (e.g., 'CreateUser') */
9
+ type: TType;
10
+ /** Zod schema for validating command input */
11
+ inputSchema: z.ZodType<TInput>;
12
+ /** Optional Zod schema for validating command metadata */
13
+ metadataSchema?: z.ZodType<TMetadata>;
14
+ };
15
+ /**
16
+ * Creates a strongly-typed command factory function.
17
+ *
18
+ * This factory validates input and metadata using Zod schemas before
19
+ * creating commands that can be dispatched through a command flow or aggregate.
20
+ *
21
+ * @param config - Configuration object containing type, input schema, and optional metadata schema
22
+ * @returns A factory function that validates and creates commands
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * const createUserCommand = defineCommand({
27
+ * type: 'CreateUser',
28
+ * inputSchema: z.object({ name: z.string(), email: z.email() }),
29
+ * metadataSchema: z.object({ now: z.date(), issuedBy: z.string().uuid() }),
30
+ * });
31
+ *
32
+ * const command = createUserCommand(
33
+ * { name: 'Ada', email: 'ada@example.org' },
34
+ * { now: new Date(), issuedBy: 'usr_123' },
35
+ * );
36
+ * ```
37
+ */
38
+ export declare function defineCommand<TType extends string, TInput extends DefaultRecord, TMetadata extends DefaultCommandMetadata | undefined = undefined>(config: CommandConfig<TType, TInput, TMetadata>): (input: TInput, metadata?: TMetadata) => Command<TType, TInput, TMetadata>;
39
+ //# sourceMappingURL=command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/builders/command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAC;AAEzC,OAAO,KAAK,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,aAAa,CACvB,KAAK,SAAS,MAAM,EACpB,MAAM,SAAS,aAAa,EAC5B,SAAS,SAAS,sBAAsB,GAAG,SAAS,GAAG,SAAS,IAC9D;IACF,mDAAmD;IACnD,IAAI,EAAE,KAAK,CAAC;IACZ,8CAA8C;IAC9C,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,0DAA0D;IAC1D,cAAc,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;CACvC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,aAAa,CAC3B,KAAK,SAAS,MAAM,EACpB,MAAM,SAAS,aAAa,EAC5B,SAAS,SAAS,sBAAsB,GAAG,SAAS,GAAG,SAAS,EAEhE,MAAM,EAAE,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,GAC9C,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS,KAAK,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAqB5E"}