@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.
- package/LICENSE +21 -0
- package/README.md +124 -0
- package/dist/builders/command-handler.d.ts +48 -0
- package/dist/builders/command-handler.d.ts.map +1 -0
- package/dist/builders/command-handler.js +40 -0
- package/dist/builders/command-handler.js.map +1 -0
- package/dist/builders/command.d.ts +39 -0
- package/dist/builders/command.d.ts.map +1 -0
- package/dist/builders/command.js +44 -0
- package/dist/builders/command.js.map +1 -0
- package/dist/builders/decider.d.ts +188 -0
- package/dist/builders/decider.d.ts.map +1 -0
- package/dist/builders/decider.js +252 -0
- package/dist/builders/decider.js.map +1 -0
- package/dist/builders/event.d.ts +39 -0
- package/dist/builders/event.d.ts.map +1 -0
- package/dist/builders/event.js +42 -0
- package/dist/builders/event.js.map +1 -0
- package/dist/builders/index.d.ts +40 -0
- package/dist/builders/index.d.ts.map +1 -0
- package/dist/builders/index.js +40 -0
- package/dist/builders/index.js.map +1 -0
- package/dist/builders/process-manager.d.ts +94 -0
- package/dist/builders/process-manager.d.ts.map +1 -0
- package/dist/builders/process-manager.js +131 -0
- package/dist/builders/process-manager.js.map +1 -0
- package/dist/builders/projection.d.ts +92 -0
- package/dist/builders/projection.d.ts.map +1 -0
- package/dist/builders/projection.js +129 -0
- package/dist/builders/projection.js.map +1 -0
- package/dist/builders/stateful-process-manager.d.ts +181 -0
- package/dist/builders/stateful-process-manager.d.ts.map +1 -0
- package/dist/builders/stateful-process-manager.js +280 -0
- package/dist/builders/stateful-process-manager.js.map +1 -0
- package/dist/bus.d.ts +3 -0
- package/dist/bus.d.ts.map +1 -0
- package/dist/bus.js +2 -0
- package/dist/bus.js.map +1 -0
- package/dist/command-flow.d.ts +87 -0
- package/dist/command-flow.d.ts.map +1 -0
- package/dist/command-flow.js +233 -0
- package/dist/command-flow.js.map +1 -0
- package/dist/command.d.ts +38 -0
- package/dist/command.d.ts.map +1 -0
- package/dist/command.js +2 -0
- package/dist/command.js.map +1 -0
- package/dist/debug.d.ts +31 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +31 -0
- package/dist/debug.js.map +1 -0
- package/dist/decide.d.ts +11 -0
- package/dist/decide.d.ts.map +1 -0
- package/dist/decide.js +2 -0
- package/dist/decide.js.map +1 -0
- package/dist/dot.d.ts +90 -0
- package/dist/dot.d.ts.map +1 -0
- package/dist/dot.js +91 -0
- package/dist/dot.js.map +1 -0
- package/dist/error.d.ts +2 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +2 -0
- package/dist/error.js.map +1 -0
- package/dist/event-sourcing-features.d.ts +81 -0
- package/dist/event-sourcing-features.d.ts.map +1 -0
- package/dist/event-sourcing-features.js +139 -0
- package/dist/event-sourcing-features.js.map +1 -0
- package/dist/event.d.ts +25 -0
- package/dist/event.d.ts.map +1 -0
- package/dist/event.js +2 -0
- package/dist/event.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/package.json +5 -0
- package/dist/process-manager.d.ts +113 -0
- package/dist/process-manager.d.ts.map +1 -0
- package/dist/process-manager.js +155 -0
- package/dist/process-manager.js.map +1 -0
- package/dist/simple-process-manager.d.ts +37 -0
- package/dist/simple-process-manager.d.ts.map +1 -0
- package/dist/simple-process-manager.js +55 -0
- package/dist/simple-process-manager.js.map +1 -0
- package/dist/src/builders/command-handler.d.ts +48 -0
- package/dist/src/builders/command-handler.d.ts.map +1 -0
- package/dist/src/builders/command.d.ts +39 -0
- package/dist/src/builders/command.d.ts.map +1 -0
- package/dist/src/builders/decider.d.ts +188 -0
- package/dist/src/builders/decider.d.ts.map +1 -0
- package/dist/src/builders/event.d.ts +39 -0
- package/dist/src/builders/event.d.ts.map +1 -0
- package/dist/src/builders/index.d.ts +40 -0
- package/dist/src/builders/index.d.ts.map +1 -0
- package/dist/src/builders/process-manager.d.ts +94 -0
- package/dist/src/builders/process-manager.d.ts.map +1 -0
- package/dist/src/builders/projection.d.ts +92 -0
- package/dist/src/builders/projection.d.ts.map +1 -0
- package/dist/src/builders/stateful-process-manager.d.ts +181 -0
- package/dist/src/builders/stateful-process-manager.d.ts.map +1 -0
- package/dist/src/bus.d.ts +3 -0
- package/dist/src/bus.d.ts.map +1 -0
- package/dist/src/command-flow.d.ts +87 -0
- package/dist/src/command-flow.d.ts.map +1 -0
- package/dist/src/command.d.ts +16 -0
- package/dist/src/command.d.ts.map +1 -0
- package/dist/src/debug.d.ts +31 -0
- package/dist/src/debug.d.ts.map +1 -0
- package/dist/src/decide.d.ts +11 -0
- package/dist/src/decide.d.ts.map +1 -0
- package/dist/src/error.d.ts +2 -0
- package/dist/src/error.d.ts.map +1 -0
- package/dist/src/event.d.ts +25 -0
- package/dist/src/event.d.ts.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/process-manager.d.ts +113 -0
- package/dist/src/process-manager.d.ts.map +1 -0
- package/dist/src/store.d.ts +44 -0
- package/dist/src/store.d.ts.map +1 -0
- package/dist/src/types.d.ts +10 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/store.d.ts +44 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +94 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +100 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Command, DeciderCommandHandler, Event } from '@event-driven-io/emmett';
|
|
2
|
+
import type { CommandHandler } from './builders/command-handler.js';
|
|
3
|
+
export { DeciderCommandHandler } from '@event-driven-io/emmett';
|
|
4
|
+
export type { Command, CommandBus, CommandHandlerOptions, CommandHandlerResult, CommandHandlerRetryOptions, CommandTypeOf, DefaultCommandMetadata, } from '@event-driven-io/emmett';
|
|
5
|
+
/**
|
|
6
|
+
* Generic type for a command handler function
|
|
7
|
+
*/
|
|
8
|
+
export type CommandHandlerType<C extends Command, State, StreamEvent extends Event> = ReturnType<typeof DeciderCommandHandler<State, C, StreamEvent>>;
|
|
9
|
+
/**
|
|
10
|
+
* Command handler configuration
|
|
11
|
+
*/
|
|
12
|
+
export type CommandHandlerConfig<C extends Command = Command, State = unknown, StreamEvent extends Event = Event> = {
|
|
13
|
+
commandType: string;
|
|
14
|
+
handler: CommandHandlerType<C, State, StreamEvent>;
|
|
15
|
+
getStreamName: (command: C) => string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Variance-friendly registration record describing a single command handler.
|
|
19
|
+
*
|
|
20
|
+
* Default type parameters are chosen so that `CommandHandlerRegistration[]`
|
|
21
|
+
* can hold handlers of many concrete command types:
|
|
22
|
+
*
|
|
23
|
+
* - `C = never` — contravariant (parameter position): `never` extends every
|
|
24
|
+
* specific command type, so any handler function is assignable.
|
|
25
|
+
* - `State = unknown` — covariant (return position): all aggregate states
|
|
26
|
+
* extend `unknown`.
|
|
27
|
+
* - `StreamEvent = Event` — covariant: all events extend the base `Event`.
|
|
28
|
+
*
|
|
29
|
+
* @template C The specific command type this handler processes.
|
|
30
|
+
* @template State The aggregate state type.
|
|
31
|
+
* @template StreamEvent The stream event type.
|
|
32
|
+
*/
|
|
33
|
+
export type CommandHandlerRegistration<C = never, State = unknown, StreamEvent extends Event = Event> = {
|
|
34
|
+
commandType: string;
|
|
35
|
+
handler: CommandHandler<State, C, StreamEvent>;
|
|
36
|
+
getStreamName: (command: C) => string;
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAErF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EACV,OAAO,EACP,UAAU,EACV,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC1B,aAAa,EACb,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC;;GAEG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,OAAO,EAAE,KAAK,EAAE,WAAW,SAAS,KAAK,IAAI,UAAU,CAC9F,OAAO,qBAAqB,CAAC,KAAK,EAAE,CAAC,EAAE,WAAW,CAAC,CACpD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO,EAAE,WAAW,SAAS,KAAK,GAAG,KAAK,IAAI;IAClH,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,kBAAkB,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IACnD,aAAa,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,MAAM,CAAC;CACvC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,0BAA0B,CAAC,CAAC,GAAG,KAAK,EAAE,KAAK,GAAG,OAAO,EAAE,WAAW,SAAS,KAAK,GAAG,KAAK,IAAI;IACtG,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC,KAAK,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;IAC/C,aAAa,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,MAAM,CAAC;CACvC,CAAC"}
|
package/dist/command.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/debug.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { debug } from '@arki/log/debug';
|
|
2
|
+
/**
|
|
3
|
+
* Debug logger for event store operations
|
|
4
|
+
* Enable with: DEBUG=es:store
|
|
5
|
+
*/
|
|
6
|
+
export declare const debugStore: debug.Debugger;
|
|
7
|
+
/**
|
|
8
|
+
* Debug logger for command flow operations
|
|
9
|
+
* Enable with: DEBUG=es:command
|
|
10
|
+
*/
|
|
11
|
+
export declare const debugCommand: debug.Debugger;
|
|
12
|
+
/**
|
|
13
|
+
* Debug logger for projection operations
|
|
14
|
+
* Enable with: DEBUG=es:projection
|
|
15
|
+
*/
|
|
16
|
+
export declare const debugProjection: debug.Debugger;
|
|
17
|
+
/**
|
|
18
|
+
* Debug logger for process manager/saga operations
|
|
19
|
+
* Enable with: DEBUG=es:process
|
|
20
|
+
*/
|
|
21
|
+
export declare const debugProcess: debug.Debugger;
|
|
22
|
+
/**
|
|
23
|
+
* Debug logger for builder operations
|
|
24
|
+
* Enable with: DEBUG=es:builder
|
|
25
|
+
*/
|
|
26
|
+
export declare const debugBuilder: debug.Debugger;
|
|
27
|
+
/**
|
|
28
|
+
* Enable all event sourcing debug logs
|
|
29
|
+
* Enable with: DEBUG=es:*
|
|
30
|
+
*/
|
|
31
|
+
//# sourceMappingURL=debug.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,UAAU,gBAAoB,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,YAAY,gBAAsB,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,eAAe,gBAAyB,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,YAAY,gBAAsB,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,YAAY,gBAAsB,CAAC;AAEhD;;;GAGG"}
|
package/dist/debug.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { debug } from '@arki/log/debug';
|
|
2
|
+
/**
|
|
3
|
+
* Debug logger for event store operations
|
|
4
|
+
* Enable with: DEBUG=es:store
|
|
5
|
+
*/
|
|
6
|
+
export const debugStore = debug('es:store');
|
|
7
|
+
/**
|
|
8
|
+
* Debug logger for command flow operations
|
|
9
|
+
* Enable with: DEBUG=es:command
|
|
10
|
+
*/
|
|
11
|
+
export const debugCommand = debug('es:command');
|
|
12
|
+
/**
|
|
13
|
+
* Debug logger for projection operations
|
|
14
|
+
* Enable with: DEBUG=es:projection
|
|
15
|
+
*/
|
|
16
|
+
export const debugProjection = debug('es:projection');
|
|
17
|
+
/**
|
|
18
|
+
* Debug logger for process manager/saga operations
|
|
19
|
+
* Enable with: DEBUG=es:process
|
|
20
|
+
*/
|
|
21
|
+
export const debugProcess = debug('es:process');
|
|
22
|
+
/**
|
|
23
|
+
* Debug logger for builder operations
|
|
24
|
+
* Enable with: DEBUG=es:builder
|
|
25
|
+
*/
|
|
26
|
+
export const debugBuilder = debug('es:builder');
|
|
27
|
+
/**
|
|
28
|
+
* Enable all event sourcing debug logs
|
|
29
|
+
* Enable with: DEBUG=es:*
|
|
30
|
+
*/
|
|
31
|
+
//# sourceMappingURL=debug.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAExC;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;AAE5C;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;AAEhD;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC;AAEtD;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;AAEhD;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;AAEhD;;;GAGG"}
|
package/dist/decide.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-export of Emmett's `Decider` type, which represents the behaviour contract
|
|
3
|
+
* of an event-sourced aggregate: `initialState`, `evolve`, and `decide`.
|
|
4
|
+
*
|
|
5
|
+
* Within this package we often refer to the same concept as an **aggregate**
|
|
6
|
+
* to emphasise that it owns state and command handling. Stick to `Decider` when
|
|
7
|
+
* interacting with upstream Emmett utilities, but feel free to adopt the
|
|
8
|
+
* aggregate terminology in your own domain code for clarity.
|
|
9
|
+
*/
|
|
10
|
+
export { type Decider } from '@event-driven-io/emmett';
|
|
11
|
+
//# sourceMappingURL=decide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decide.d.ts","sourceRoot":"","sources":["../src/decide.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/decide.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decide.js","sourceRoot":"","sources":["../src/decide.ts"],"names":[],"mappings":""}
|
package/dist/dot.d.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOT adapter for `@arki/event-sourcing`.
|
|
3
|
+
*
|
|
4
|
+
* Wraps `eventSourcingFeatures.initEventSourcing` + `initMessageBus` as a
|
|
5
|
+
* single `DotPip`. The pip opens the PostgreSQL event store in
|
|
6
|
+
* `boot`, attaches command handlers to an in-memory message bus, publishes
|
|
7
|
+
* both as `services.eventStore` and `services.messageBus`, and closes the
|
|
8
|
+
* event store pool in `dispose` (reverse-topological order).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { defineApp } from '@arki/dot';
|
|
13
|
+
* import { eventSourcing } from '@arki/event-sourcing/dot';
|
|
14
|
+
*
|
|
15
|
+
* const app = await defineApp('my-app')
|
|
16
|
+
* .use(eventSourcing({
|
|
17
|
+
* projections: [orderProjection, invoiceProjection],
|
|
18
|
+
* commandHandlers: [placeOrderHandler, cancelOrderHandler],
|
|
19
|
+
* }))
|
|
20
|
+
* .boot();
|
|
21
|
+
*
|
|
22
|
+
* await app.services.messageBus.send({ type: 'PlaceOrder', payload: { ... } });
|
|
23
|
+
* await app.dispose();
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* The connection URL is resolved in this order:
|
|
27
|
+
* 1. `options.dbUrl` if provided
|
|
28
|
+
* 2. `process.env.EVENT_STORE_URL`
|
|
29
|
+
* 3. `process.env.EVENTSTORE_URL`
|
|
30
|
+
* 4. `process.env.EVENT_DB_URL`
|
|
31
|
+
*
|
|
32
|
+
* If none are set, `boot` throws with a message naming every accepted env
|
|
33
|
+
* var — same contract as `eventSourcingFeatures.initEventSourcing`.
|
|
34
|
+
*
|
|
35
|
+
* The `@arki/dot` package is an OPTIONAL peer of `@arki/event-sourcing`.
|
|
36
|
+
* Importing this adapter without `@arki/dot` installed will fail at module
|
|
37
|
+
* load — that is intentional: the adapter only makes sense in a DOT app.
|
|
38
|
+
*/
|
|
39
|
+
import type { EventStore, MessageBus } from '@event-driven-io/emmett';
|
|
40
|
+
import type { DotPip } from '@arki/dot/pip';
|
|
41
|
+
import type { CommandHandlerRegistration } from './command.js';
|
|
42
|
+
import type { PostgreSQLProjectionInput } from './event-sourcing-features.js';
|
|
43
|
+
/**
|
|
44
|
+
* Options for the event-sourcing DOT adapter.
|
|
45
|
+
*/
|
|
46
|
+
export type EventSourcingDotOptions = {
|
|
47
|
+
/**
|
|
48
|
+
* PostgreSQL projection definitions registered inline on the event store.
|
|
49
|
+
* Accepts the three projection builder patterns documented on
|
|
50
|
+
* {@link PostgreSQLProjectionInput}.
|
|
51
|
+
*/
|
|
52
|
+
readonly projections: readonly PostgreSQLProjectionInput[];
|
|
53
|
+
/**
|
|
54
|
+
* Command handlers wired into the in-memory message bus. Each handler's
|
|
55
|
+
* `getStreamName` callback maps an incoming command to its target stream.
|
|
56
|
+
*
|
|
57
|
+
* Defaults to `[]` — useful when an app only does projections / event
|
|
58
|
+
* appends without command-side dispatch.
|
|
59
|
+
*/
|
|
60
|
+
readonly commandHandlers?: readonly CommandHandlerRegistration[];
|
|
61
|
+
/**
|
|
62
|
+
* Connection URL for the event store. When omitted, the pip reads
|
|
63
|
+
* `EVENT_STORE_URL`, `EVENTSTORE_URL`, or `EVENT_DB_URL` from
|
|
64
|
+
* `process.env`. If none are set, `boot` throws.
|
|
65
|
+
*/
|
|
66
|
+
readonly dbUrl?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Pip name override. Defaults to `'event-sourcing'`. Use this only
|
|
69
|
+
* when composing multiple event-sourcing scopes inside the same app.
|
|
70
|
+
*/
|
|
71
|
+
readonly name?: string;
|
|
72
|
+
};
|
|
73
|
+
/** Services published by the event-sourcing adapter. */
|
|
74
|
+
export type EventSourcingServices = {
|
|
75
|
+
/** The Emmett event store handle, ready to load/append streams. */
|
|
76
|
+
readonly eventStore: EventStore;
|
|
77
|
+
/**
|
|
78
|
+
* The in-memory message bus. Already has the configured command handlers
|
|
79
|
+
* attached — call `messageBus.send(command)` to dispatch.
|
|
80
|
+
*/
|
|
81
|
+
readonly messageBus: MessageBus;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Build a DOT pip that opens the event store, wires command handlers
|
|
85
|
+
* into an in-memory message bus, and publishes both as services. The
|
|
86
|
+
* kernel calls `dispose` in reverse-topological order to release the
|
|
87
|
+
* underlying PG pool.
|
|
88
|
+
*/
|
|
89
|
+
export declare function eventSourcing(options: EventSourcingDotOptions): DotPip<EventSourcingServices>;
|
|
90
|
+
//# sourceMappingURL=dot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dot.d.ts","sourceRoot":"","sources":["../src/dot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAEtE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAG9E;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC3D;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACjE;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,wDAAwD;AACxD,MAAM,MAAM,qBAAqB,GAAG;IAClC,mEAAmE;IACnE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;CACjC,CAAC;AAgBF;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CA8B7F"}
|
package/dist/dot.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOT adapter for `@arki/event-sourcing`.
|
|
3
|
+
*
|
|
4
|
+
* Wraps `eventSourcingFeatures.initEventSourcing` + `initMessageBus` as a
|
|
5
|
+
* single `DotPip`. The pip opens the PostgreSQL event store in
|
|
6
|
+
* `boot`, attaches command handlers to an in-memory message bus, publishes
|
|
7
|
+
* both as `services.eventStore` and `services.messageBus`, and closes the
|
|
8
|
+
* event store pool in `dispose` (reverse-topological order).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { defineApp } from '@arki/dot';
|
|
13
|
+
* import { eventSourcing } from '@arki/event-sourcing/dot';
|
|
14
|
+
*
|
|
15
|
+
* const app = await defineApp('my-app')
|
|
16
|
+
* .use(eventSourcing({
|
|
17
|
+
* projections: [orderProjection, invoiceProjection],
|
|
18
|
+
* commandHandlers: [placeOrderHandler, cancelOrderHandler],
|
|
19
|
+
* }))
|
|
20
|
+
* .boot();
|
|
21
|
+
*
|
|
22
|
+
* await app.services.messageBus.send({ type: 'PlaceOrder', payload: { ... } });
|
|
23
|
+
* await app.dispose();
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* The connection URL is resolved in this order:
|
|
27
|
+
* 1. `options.dbUrl` if provided
|
|
28
|
+
* 2. `process.env.EVENT_STORE_URL`
|
|
29
|
+
* 3. `process.env.EVENTSTORE_URL`
|
|
30
|
+
* 4. `process.env.EVENT_DB_URL`
|
|
31
|
+
*
|
|
32
|
+
* If none are set, `boot` throws with a message naming every accepted env
|
|
33
|
+
* var — same contract as `eventSourcingFeatures.initEventSourcing`.
|
|
34
|
+
*
|
|
35
|
+
* The `@arki/dot` package is an OPTIONAL peer of `@arki/event-sourcing`.
|
|
36
|
+
* Importing this adapter without `@arki/dot` installed will fail at module
|
|
37
|
+
* load — that is intentional: the adapter only makes sense in a DOT app.
|
|
38
|
+
*/
|
|
39
|
+
import { defineDotPip } from '@arki/dot/pip';
|
|
40
|
+
import { EVENT_STORE_URL_VARIANTS, eventSourcingFeatures } from './event-sourcing-features.js';
|
|
41
|
+
/**
|
|
42
|
+
* Resolve the event-store connection URL from explicit options first, then
|
|
43
|
+
* from the recognised env vars in priority order. Returns `undefined` when
|
|
44
|
+
* none are set so the underlying factory can throw the canonical error.
|
|
45
|
+
*/
|
|
46
|
+
function resolveDbUrl(explicit) {
|
|
47
|
+
if (explicit !== undefined && explicit !== '')
|
|
48
|
+
return explicit;
|
|
49
|
+
for (const name of EVENT_STORE_URL_VARIANTS) {
|
|
50
|
+
const value = process.env[name];
|
|
51
|
+
if (value !== undefined && value !== '')
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Build a DOT pip that opens the event store, wires command handlers
|
|
58
|
+
* into an in-memory message bus, and publishes both as services. The
|
|
59
|
+
* kernel calls `dispose` in reverse-topological order to release the
|
|
60
|
+
* underlying PG pool.
|
|
61
|
+
*/
|
|
62
|
+
export function eventSourcing(options) {
|
|
63
|
+
const name = options.name ?? 'event-sourcing';
|
|
64
|
+
const commandHandlers = options.commandHandlers ?? [];
|
|
65
|
+
// Captured at boot so dispose can call it without re-reading services
|
|
66
|
+
// (dispose is allowed to run even when services failed to publish).
|
|
67
|
+
let closeStore;
|
|
68
|
+
return defineDotPip({
|
|
69
|
+
name,
|
|
70
|
+
version: '0.1.0',
|
|
71
|
+
provides: ['event-store', 'message-bus'],
|
|
72
|
+
configure(ctx) {
|
|
73
|
+
ctx.registerService('eventStore', 'event-store');
|
|
74
|
+
ctx.registerService('messageBus', 'message-bus');
|
|
75
|
+
},
|
|
76
|
+
boot() {
|
|
77
|
+
const dbUrl = resolveDbUrl(options.dbUrl);
|
|
78
|
+
const { eventStore, close } = eventSourcingFeatures.initEventSourcing(options.projections, dbUrl);
|
|
79
|
+
closeStore = close;
|
|
80
|
+
const messageBus = eventSourcingFeatures.initMessageBus(eventStore, [...commandHandlers]);
|
|
81
|
+
return { services: { eventStore, messageBus } };
|
|
82
|
+
},
|
|
83
|
+
async dispose() {
|
|
84
|
+
if (closeStore !== undefined) {
|
|
85
|
+
await closeStore();
|
|
86
|
+
closeStore = undefined;
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=dot.js.map
|
package/dist/dot.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dot.js","sourceRoot":"","sources":["../src/dot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAI7C,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AA4C/F;;;;GAIG;AACH,SAAS,YAAY,CAAC,QAA4B;IAChD,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAC;IAC/D,KAAK,MAAM,IAAI,IAAI,wBAAwB,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC;IACxD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,OAAgC;IAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,gBAAgB,CAAC;IAC9C,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC;IAEtD,sEAAsE;IACtE,oEAAoE;IACpE,IAAI,UAA6C,CAAC;IAElD,OAAO,YAAY,CAAwB;QACzC,IAAI;QACJ,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC;QACxC,SAAS,CAAC,GAAG;YACX,GAAG,CAAC,eAAe,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;YACjD,GAAG,CAAC,eAAe,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QACnD,CAAC;QACD,IAAI;YACF,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,qBAAqB,CAAC,iBAAiB,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YAClG,UAAU,GAAG,KAAK,CAAC;YACnB,MAAM,UAAU,GAAG,qBAAqB,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;YAC1F,OAAO,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,CAAC;QAClD,CAAC;QACD,KAAK,CAAC,OAAO;YACX,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,MAAM,UAAU,EAAE,CAAC;gBACnB,UAAU,GAAG,SAAS,CAAC;YACzB,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
package/dist/error.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/error.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { Event, EventStore, MessageBus, MessageProcessor } from '@event-driven-io/emmett';
|
|
2
|
+
import type { CommandHandlerRegistration } from './command.js';
|
|
3
|
+
import type { PostgresEventStore } from './store.js';
|
|
4
|
+
/**
|
|
5
|
+
* Structural interface for projection definitions accepted by
|
|
6
|
+
* {@link initEventSourcing}.
|
|
7
|
+
*
|
|
8
|
+
* Uses method syntax for `handle` to enable TypeScript's bivariant parameter
|
|
9
|
+
* checking, which allows heterogeneous projection arrays where each projection
|
|
10
|
+
* is parametrised on a different event type.
|
|
11
|
+
*
|
|
12
|
+
* Accepts projections produced by three different builder patterns:
|
|
13
|
+
* 1. Emmett's `postgreSQLProjection` / `PostgreSQLProjectionDefinition<E>`.
|
|
14
|
+
* 2. The `defineProjection` builder from this package.
|
|
15
|
+
* 3. The `@arki/db` builder `projection.named().on().handle()`.
|
|
16
|
+
*/
|
|
17
|
+
export type PostgreSQLProjectionInput = {
|
|
18
|
+
name?: string;
|
|
19
|
+
canHandle: string[];
|
|
20
|
+
handle(events: Event[], context: object): void;
|
|
21
|
+
};
|
|
22
|
+
/** Alternative names for the Event Store connection URL environment variable. */
|
|
23
|
+
export declare const EVENT_STORE_URL_VARIANTS: string[];
|
|
24
|
+
/**
|
|
25
|
+
* Event sourcing wiring helpers.
|
|
26
|
+
*
|
|
27
|
+
* Bundles the three most common bootstrap operations into a single namespace:
|
|
28
|
+
*
|
|
29
|
+
* - {@link eventSourcingFeatures.initEventSourcing} — open the PostgreSQL
|
|
30
|
+
* event store with a set of inline projections, returning a `close()`
|
|
31
|
+
* function for graceful shutdown.
|
|
32
|
+
* - {@link eventSourcingFeatures.initMessageBus} — create an in-memory
|
|
33
|
+
* message bus and register a list of command handler descriptors against it.
|
|
34
|
+
* - {@link eventSourcingFeatures.setupProcessManagers} — attach process
|
|
35
|
+
* manager consumers to the event store, start them, and wire SIGTERM-driven
|
|
36
|
+
* graceful shutdown.
|
|
37
|
+
*
|
|
38
|
+
* The helpers are intentionally framework-agnostic: any composition root
|
|
39
|
+
* (DI container, plugin, plain `bus.ts` factory function) can call them.
|
|
40
|
+
*/
|
|
41
|
+
export declare const eventSourcingFeatures: {
|
|
42
|
+
/**
|
|
43
|
+
* Initialises the PostgreSQL event store with the given inline projections.
|
|
44
|
+
*
|
|
45
|
+
* @param p Projections to register inline on the event store.
|
|
46
|
+
* @param dbUrl Connection string for the event store. When omitted, an
|
|
47
|
+
* error is thrown that names the recognised environment variables.
|
|
48
|
+
* @returns The event store handle plus a `close()` function that releases
|
|
49
|
+
* the underlying connection pool.
|
|
50
|
+
*/
|
|
51
|
+
initEventSourcing(p: readonly PostgreSQLProjectionInput[], dbUrl?: string): {
|
|
52
|
+
eventStore: PostgresEventStore;
|
|
53
|
+
close: () => Promise<void>;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Creates an in-memory message bus and registers a list of command handlers.
|
|
57
|
+
*
|
|
58
|
+
* Each registration is bound to the event store so command handlers can
|
|
59
|
+
* load and append to streams. If the event store is missing, a warning is
|
|
60
|
+
* logged and an empty bus is returned.
|
|
61
|
+
*
|
|
62
|
+
* @param eventStore Event store used to load and append streams.
|
|
63
|
+
* @param commandHandlers Command handler descriptors to register.
|
|
64
|
+
* @returns A message bus with handlers attached.
|
|
65
|
+
*/
|
|
66
|
+
initMessageBus(eventStore: EventStore | undefined, commandHandlers: CommandHandlerRegistration[]): MessageBus;
|
|
67
|
+
/**
|
|
68
|
+
* Attaches process managers as event store consumers, starts them, and
|
|
69
|
+
* wires SIGTERM-driven shutdown of the resulting consumers.
|
|
70
|
+
*
|
|
71
|
+
* @param eventStore Event store the process managers consume from.
|
|
72
|
+
* @param processManagers Process manager `MessageProcessor` instances to
|
|
73
|
+
* register, typically produced by {@link createProcessManager},
|
|
74
|
+
* {@link createStatefulProcessManager}, or
|
|
75
|
+
* `createSimpleProcessManager`.
|
|
76
|
+
* @returns The started consumer handles. Useful for tests that need to
|
|
77
|
+
* stop them explicitly.
|
|
78
|
+
*/
|
|
79
|
+
setupProcessManagers(eventStore: PostgresEventStore, processManagers: MessageProcessor[]): Promise<import("@event-driven-io/emmett-postgresql").PostgreSQLEventStoreConsumer<Event>[]>;
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=event-sourcing-features.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-sourcing-features.d.ts","sourceRoot":"","sources":["../src/event-sourcing-features.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAEjB,MAAM,yBAAyB,CAAC;AAIjC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAE/D,OAAO,KAAK,EACV,kBAAkB,EAGnB,MAAM,YAAY,CAAC;AAGpB;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAChD,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,wBAAwB,UAAwD,CAAC;AAE9F;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,qBAAqB;IAChC;;;;;;;;OAQG;yBACkB,SAAS,yBAAyB,EAAE,UAAU,MAAM;;;;IAsBzE;;;;;;;;;;OAUG;+BACwB,UAAU,GAAG,SAAS,mBAAmB,0BAA0B,EAAE,GAAG,UAAU;IAyE7G;;;;;;;;;;;OAWG;qCACoC,kBAAkB,mBAAmB,gBAAgB,EAAE;CA4B/F,CAAC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { getInMemoryMessageBus } from '@event-driven-io/emmett';
|
|
2
|
+
import { debugCommand, debugStore } from './debug.js';
|
|
3
|
+
import { getEventStore, projections } from './store.js';
|
|
4
|
+
/** Alternative names for the Event Store connection URL environment variable. */
|
|
5
|
+
export const EVENT_STORE_URL_VARIANTS = ['EVENT_STORE_URL', 'EVENTSTORE_URL', 'EVENT_DB_URL'];
|
|
6
|
+
/**
|
|
7
|
+
* Event sourcing wiring helpers.
|
|
8
|
+
*
|
|
9
|
+
* Bundles the three most common bootstrap operations into a single namespace:
|
|
10
|
+
*
|
|
11
|
+
* - {@link eventSourcingFeatures.initEventSourcing} — open the PostgreSQL
|
|
12
|
+
* event store with a set of inline projections, returning a `close()`
|
|
13
|
+
* function for graceful shutdown.
|
|
14
|
+
* - {@link eventSourcingFeatures.initMessageBus} — create an in-memory
|
|
15
|
+
* message bus and register a list of command handler descriptors against it.
|
|
16
|
+
* - {@link eventSourcingFeatures.setupProcessManagers} — attach process
|
|
17
|
+
* manager consumers to the event store, start them, and wire SIGTERM-driven
|
|
18
|
+
* graceful shutdown.
|
|
19
|
+
*
|
|
20
|
+
* The helpers are intentionally framework-agnostic: any composition root
|
|
21
|
+
* (DI container, plugin, plain `bus.ts` factory function) can call them.
|
|
22
|
+
*/
|
|
23
|
+
export const eventSourcingFeatures = {
|
|
24
|
+
/**
|
|
25
|
+
* Initialises the PostgreSQL event store with the given inline projections.
|
|
26
|
+
*
|
|
27
|
+
* @param p Projections to register inline on the event store.
|
|
28
|
+
* @param dbUrl Connection string for the event store. When omitted, an
|
|
29
|
+
* error is thrown that names the recognised environment variables.
|
|
30
|
+
* @returns The event store handle plus a `close()` function that releases
|
|
31
|
+
* the underlying connection pool.
|
|
32
|
+
*/
|
|
33
|
+
initEventSourcing(p, dbUrl) {
|
|
34
|
+
if (!dbUrl) {
|
|
35
|
+
debugStore('[eventSourcingFeatures] Event Store URL not found. Required environment variables: %s', EVENT_STORE_URL_VARIANTS.join(', '));
|
|
36
|
+
throw new Error(`Event Store database URL is not defined. Please set one of the following environment variables: ${EVENT_STORE_URL_VARIANTS.join(', ')}`);
|
|
37
|
+
}
|
|
38
|
+
debugStore('[eventSourcingFeatures] Initializing Event Store with %d projection(s)', p.length);
|
|
39
|
+
const { eventStore, close } = getEventStore(dbUrl, {
|
|
40
|
+
projections: projections.inline(p),
|
|
41
|
+
});
|
|
42
|
+
debugStore('[eventSourcingFeatures] Event Store initialized successfully');
|
|
43
|
+
return { eventStore, close };
|
|
44
|
+
},
|
|
45
|
+
/**
|
|
46
|
+
* Creates an in-memory message bus and registers a list of command handlers.
|
|
47
|
+
*
|
|
48
|
+
* Each registration is bound to the event store so command handlers can
|
|
49
|
+
* load and append to streams. If the event store is missing, a warning is
|
|
50
|
+
* logged and an empty bus is returned.
|
|
51
|
+
*
|
|
52
|
+
* @param eventStore Event store used to load and append streams.
|
|
53
|
+
* @param commandHandlers Command handler descriptors to register.
|
|
54
|
+
* @returns A message bus with handlers attached.
|
|
55
|
+
*/
|
|
56
|
+
initMessageBus(eventStore, commandHandlers) {
|
|
57
|
+
debugCommand('[eventSourcingFeatures] Initializing Message Bus with %d command handler(s)', commandHandlers.length);
|
|
58
|
+
const messageBus = getInMemoryMessageBus();
|
|
59
|
+
if (!eventStore) {
|
|
60
|
+
if (commandHandlers.length > 0) {
|
|
61
|
+
debugCommand('[eventSourcingFeatures] Warning: %d command handler(s) configured but Event Store not initialized', commandHandlers.length);
|
|
62
|
+
console.warn('Command handlers were configured, but the Event Store is not initialized. Commands may fail.');
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
debugCommand('[eventSourcingFeatures] No Event Store and no command handlers - returning empty Message Bus');
|
|
66
|
+
}
|
|
67
|
+
return messageBus;
|
|
68
|
+
}
|
|
69
|
+
if (commandHandlers.length > 0) {
|
|
70
|
+
const createCommandHandlerWrapper = (handler, getStreamNameFn) => {
|
|
71
|
+
return async (command) => {
|
|
72
|
+
const streamName = getStreamNameFn(command);
|
|
73
|
+
debugCommand('[MessageBus] Executing command handler for %s on stream: %s', command.type, streamName);
|
|
74
|
+
try {
|
|
75
|
+
if (typeof handler === 'function') {
|
|
76
|
+
await handler(eventStore, streamName, command);
|
|
77
|
+
debugCommand('[MessageBus] Command handler for %s completed successfully', command.type);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
debugCommand('[MessageBus] Invalid handler type for command: %s', command.type);
|
|
81
|
+
console.error(`Invalid handler type encountered for command: ${command.type}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
debugCommand('[MessageBus] Error executing command handler for %s on stream %s: %s', command.type, streamName, error instanceof Error ? error.message : String(error));
|
|
86
|
+
console.error(`Error executing command handler for ${command.type} on stream ${streamName}:`, error);
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
for (const config of commandHandlers) {
|
|
92
|
+
debugCommand('[eventSourcingFeatures] Registering command handler for type: %s', config.commandType);
|
|
93
|
+
const handler = config.handler;
|
|
94
|
+
const getStreamName = config.getStreamName;
|
|
95
|
+
messageBus.handle(createCommandHandlerWrapper(handler, getStreamName), config.commandType);
|
|
96
|
+
}
|
|
97
|
+
debugCommand('[eventSourcingFeatures] Message Bus initialized with %d command handler(s)', commandHandlers.length);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
debugCommand('[eventSourcingFeatures] No command handlers to register');
|
|
101
|
+
}
|
|
102
|
+
return messageBus;
|
|
103
|
+
},
|
|
104
|
+
/**
|
|
105
|
+
* Attaches process managers as event store consumers, starts them, and
|
|
106
|
+
* wires SIGTERM-driven shutdown of the resulting consumers.
|
|
107
|
+
*
|
|
108
|
+
* @param eventStore Event store the process managers consume from.
|
|
109
|
+
* @param processManagers Process manager `MessageProcessor` instances to
|
|
110
|
+
* register, typically produced by {@link createProcessManager},
|
|
111
|
+
* {@link createStatefulProcessManager}, or
|
|
112
|
+
* `createSimpleProcessManager`.
|
|
113
|
+
* @returns The started consumer handles. Useful for tests that need to
|
|
114
|
+
* stop them explicitly.
|
|
115
|
+
*/
|
|
116
|
+
async setupProcessManagers(eventStore, processManagers) {
|
|
117
|
+
debugStore('[eventSourcingFeatures] Setting up %d process manager(s)', processManagers.length);
|
|
118
|
+
const processManagerConsumers = processManagers.map(pm => {
|
|
119
|
+
debugStore('[eventSourcingFeatures] Creating consumer for process manager: %s', pm.id);
|
|
120
|
+
return eventStore.consumer({
|
|
121
|
+
consumerId: pm.id,
|
|
122
|
+
processors: [pm],
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
debugStore('[eventSourcingFeatures] Starting %d process manager consumer(s)', processManagerConsumers.length);
|
|
126
|
+
await Promise.all(processManagerConsumers.map(consumer => consumer.start()));
|
|
127
|
+
debugStore('[eventSourcingFeatures] All process manager consumers started successfully');
|
|
128
|
+
process.on('SIGTERM', async () => {
|
|
129
|
+
debugStore('[eventSourcingFeatures] SIGTERM received, stopping process managers');
|
|
130
|
+
await Promise.all(processManagerConsumers.map(consumer => consumer.stop()));
|
|
131
|
+
debugStore('[eventSourcingFeatures] All process managers stopped, closing consumers');
|
|
132
|
+
await Promise.all(processManagerConsumers.map(consumer => consumer.close()));
|
|
133
|
+
debugStore('[eventSourcingFeatures] All consumers closed, exiting');
|
|
134
|
+
process.exit(0);
|
|
135
|
+
});
|
|
136
|
+
return processManagerConsumers;
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
//# sourceMappingURL=event-sourcing-features.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-sourcing-features.js","sourceRoot":"","sources":["../src/event-sourcing-features.ts"],"names":[],"mappings":"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"}
|
package/dist/event.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DefaultRecord } from './types.js';
|
|
2
|
+
export type { EventsPublisher, EventStore, ReadEvent, ReadEventMetadataWithGlobalPosition, } from '@event-driven-io/emmett';
|
|
3
|
+
export type Event<EventType extends string = string, EventData extends DefaultRecord = DefaultRecord, EventMetaData extends DefaultRecord | undefined = undefined> = Readonly<{
|
|
4
|
+
type: EventType;
|
|
5
|
+
data: EventData;
|
|
6
|
+
metadata?: EventMetaData;
|
|
7
|
+
kind?: 'Event';
|
|
8
|
+
}>;
|
|
9
|
+
export type AnyEvent = Event<any, any, any>;
|
|
10
|
+
export type EventTypeOf<T extends Event> = T['type'];
|
|
11
|
+
export type EventDataOf<T extends Event> = T['data'];
|
|
12
|
+
export type EventMetaDataOf<T extends Event> = T extends {
|
|
13
|
+
metadata: infer M;
|
|
14
|
+
} ? M : undefined;
|
|
15
|
+
export type CreateEventType<EventType extends string, EventData extends DefaultRecord, EventMetaData extends DefaultRecord | undefined = undefined> = Readonly<EventMetaData extends undefined ? {
|
|
16
|
+
type: EventType;
|
|
17
|
+
data: EventData;
|
|
18
|
+
} : {
|
|
19
|
+
type: EventType;
|
|
20
|
+
data: EventData;
|
|
21
|
+
metadata: EventMetaData;
|
|
22
|
+
}> & {
|
|
23
|
+
readonly kind?: 'Event';
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=event.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../src/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,YAAY,EACV,eAAe,EACf,UAAU,EACV,SAAS,EACT,mCAAmC,GACpC,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,KAAK,CACf,SAAS,SAAS,MAAM,GAAG,MAAM,EACjC,SAAS,SAAS,aAAa,GAAG,aAAa,EAC/C,aAAa,SAAS,aAAa,GAAG,SAAS,GAAG,SAAS,IACzD,QAAQ,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAC5C,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;AACrD,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;AACrD,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS;IACvD,QAAQ,EAAE,MAAM,CAAC,CAAC;CACnB,GACG,CAAC,GACD,SAAS,CAAC;AACd,MAAM,MAAM,eAAe,CACzB,SAAS,SAAS,MAAM,EACxB,SAAS,SAAS,aAAa,EAC/B,aAAa,SAAS,aAAa,GAAG,SAAS,GAAG,SAAS,IACzD,QAAQ,CACV,aAAa,SAAS,SAAS,GAC3B;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;CACjB,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;CACzB,CACN,GAAG;IACF,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC"}
|
package/dist/event.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.js","sourceRoot":"","sources":["../src/event.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
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, type PostgreSQLProjectionInput, } from './event-sourcing-features.js';
|
|
6
|
+
export type { DefaultRecord } from './types.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","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,EACrB,KAAK,yBAAyB,GAC/B,MAAM,8BAA8B,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|