@schemeless/event-store-types 2.4.3 → 2.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.
@@ -3,6 +3,11 @@ export interface BaseEventInput<Payload, META = undefined> {
3
3
  meta?: META;
4
4
  identifier?: string;
5
5
  correlationId?: string;
6
+ /**
7
+ * @deprecated Will be removed in v3.0.
8
+ * causationId is now managed exclusively by the framework.
9
+ * Do not set this field manually.
10
+ */
6
11
  causationId?: string;
7
12
  created?: Date;
8
13
  }
@@ -42,6 +47,18 @@ export interface EventFlow<PartialPayload = any, Payload extends PartialPayload
42
47
  readonly sideEffect?: (event: CreatedEvent<Payload>) => Promise<void | BaseEvent<any>[]> | void | BaseEvent<any>[];
43
48
  readonly cancelApply?: (event: CreatedEvent<Payload>) => Promise<void> | void;
44
49
  readonly createConsequentEvents?: (causalEvent: CreatedEvent<Payload>) => Promise<BaseEvent<any>[]> | BaseEvent<any>[];
50
+ /**
51
+ * Generates compensating event(s) to reverse this event's effects.
52
+ * Called by the framework during revert operations.
53
+ *
54
+ * If this hook is not defined, the event cannot be reverted.
55
+ * If any event in a causal chain lacks this hook, the entire chain
56
+ * cannot be reverted.
57
+ *
58
+ * @param originalEvent - The event being reverted
59
+ * @returns Compensating event(s) to persist
60
+ */
61
+ readonly compensate?: (originalEvent: CreatedEvent<Payload>) => BaseEvent<any> | BaseEvent<any>[];
45
62
  }
46
63
  export type EventTaskAndError = {
47
64
  task: CreatedEvent<any>;
@@ -68,7 +85,9 @@ export declare enum SideEffectsState {
68
85
  export declare enum EventOutputState {
69
86
  success = "Event:success",
70
87
  invalid = "Event:invalid",
71
- canceled = "Event:canceled"
88
+ canceled = "Event:canceled",
89
+ reverted = "Event:reverted",
90
+ revertFailed = "Event:revertFailed"
72
91
  }
73
92
  export declare enum EventObserverState {
74
93
  success = "Observer:success"
@@ -12,6 +12,8 @@ var EventOutputState;
12
12
  EventOutputState["success"] = "Event:success";
13
13
  EventOutputState["invalid"] = "Event:invalid";
14
14
  EventOutputState["canceled"] = "Event:canceled";
15
+ EventOutputState["reverted"] = "Event:reverted";
16
+ EventOutputState["revertFailed"] = "Event:revertFailed";
15
17
  })(EventOutputState = exports.EventOutputState || (exports.EventOutputState = {}));
16
18
  var EventObserverState;
17
19
  (function (EventObserverState) {
@@ -16,4 +16,18 @@ export interface IEventStoreRepo<PAYLOAD = any, META = any> {
16
16
  createEventEntity: (event: CreatedEvent<any>) => IEventStoreEntity<PAYLOAD, META>;
17
17
  storeEvents: (events: CreatedEvent<any>[]) => Promise<void>;
18
18
  resetStore: () => Promise<void>;
19
+ /**
20
+ * Retrieves a single event by its ID.
21
+ * Required for revert operations.
22
+ */
23
+ getEventById?: (id: string) => Promise<IEventStoreEntity<PAYLOAD, META> | null>;
24
+ /**
25
+ * Finds all events directly caused by the specified event.
26
+ * Returns events where causationId equals the given eventId.
27
+ * Required for revert operations to traverse the event tree.
28
+ *
29
+ * Note for DynamoDB: Consider adding a GSI on causationId for better
30
+ * performance. Without a GSI, this will result in a table scan.
31
+ */
32
+ findByCausationId?: (causationId: string) => Promise<IEventStoreEntity<PAYLOAD, META>[]>;
19
33
  }
@@ -0,0 +1,38 @@
1
+ import type { CreatedEvent } from './EventStore.types';
2
+ /**
3
+ * Result of canRevert() check
4
+ */
5
+ export interface CanRevertResult {
6
+ /** Whether the event can be reverted */
7
+ canRevert: boolean;
8
+ /** Reason why revert is not possible (if canRevert is false) */
9
+ reason?: string;
10
+ /** Events missing the 'compensate' hook */
11
+ missingCompensateEvents?: Array<{
12
+ id: string;
13
+ domain: string;
14
+ type: string;
15
+ }>;
16
+ }
17
+ /**
18
+ * Result of previewRevert() - shows what would be affected
19
+ */
20
+ export interface PreviewRevertResult {
21
+ /** The root event that would be reverted */
22
+ rootEvent: CreatedEvent<any>;
23
+ /** All descendant events that would be reverted */
24
+ descendantEvents: CreatedEvent<any>[];
25
+ /** Total count of events affected */
26
+ totalEventCount: number;
27
+ }
28
+ /**
29
+ * Result of a successful revert() operation
30
+ */
31
+ export interface RevertResult {
32
+ /** ID of the event that was reverted */
33
+ revertedEventId: string;
34
+ /** Compensating events generated for this event */
35
+ compensatingEvents: CreatedEvent<any>[];
36
+ /** Revert results for child events */
37
+ childResults: RevertResult[];
38
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './EventStore.types';
2
2
  export * from './Repo.types';
3
+ export * from './Revert.types';
package/dist/index.js CHANGED
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./EventStore.types"), exports);
18
18
  __exportStar(require("./Repo.types"), exports);
19
+ __exportStar(require("./Revert.types"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schemeless/event-store-types",
3
- "version": "2.4.3",
3
+ "version": "2.6.0",
4
4
  "typescript:main": "src/index.ts",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -34,5 +34,5 @@
34
34
  "publishConfig": {
35
35
  "access": "public"
36
36
  },
37
- "gitHead": "c94ac386be41b1a90c8d9bd4c047fac3c7b5031f"
37
+ "gitHead": "fa654aea833fcac2ee269d23e7f7683bd20bd16f"
38
38
  }
package/readme.md CHANGED
@@ -28,6 +28,17 @@ const eventFlow: EventFlow = {
28
28
 
29
29
  `CreatedEvent` extends the base shape with generated identifiers and timestamps, while `SideEffectsState`, `EventOutputState`, and `EventObserverState` describe the possible outcomes emitted by the runtime.
30
30
 
31
+ ### Traceability IDs
32
+
33
+ The event store uses several ID fields to track causation and correlation across event chains:
34
+
35
+ - **`correlationId`** – Groups all events originating from the same root command. The framework inherits this from parent events or creates it for root events. Developers can optionally pass this from external systems (e.g., HTTP request headers).
36
+ - **`causationId`** – Links each event to its immediate parent. This field is **managed exclusively by the framework** via `createConsequentEvents` or `sideEffect` handlers.
37
+ - **`identifier`** – Developer-provided field to record who or what triggered the event (e.g., user ID, service name).
38
+ - **`trackingId`** – Developer-provided external reference for cross-system tracing.
39
+
40
+ > **Important:** Do not manually set `causationId` in your event inputs. The framework automatically populates this field based on the event creation context to ensure chain integrity.
41
+
31
42
  ## Repository contracts
32
43
 
33
44
  `Repo.types` exposes the `IEventStoreRepo` and `IEventStoreEntity` interfaces. Adapters implement these to integrate with the core runtime.
@@ -49,3 +60,36 @@ class CustomRepo implements IEventStoreRepo {
49
60
  ```
50
61
 
51
62
  The iterator returned by `getAllEvents` yields arrays of `IEventStoreEntity` records. Each record includes identifiers, correlation/causation metadata, and the `created` timestamp so replays can process history in order.
63
+
64
+ ### Revert support
65
+
66
+ To enable revert operations, adapters should also implement two additional optional methods:
67
+
68
+ ```ts
69
+ class CustomRepo implements IEventStoreRepo {
70
+ // ... existing methods ...
71
+
72
+ async getEventById(id: string) {
73
+ // Return a single event by ID, or null if not found
74
+ }
75
+
76
+ async findByCausationId(causationId: string) {
77
+ // Return all events where causationId equals the given value
78
+ // Used to traverse the event tree during reverts
79
+ }
80
+ }
81
+ ```
82
+
83
+ > **Note:** For DynamoDB adapters, consider adding a Global Secondary Index on `causationId` for better performance.
84
+
85
+ ## Revert types
86
+
87
+ The package exports types for the revert API:
88
+
89
+ ```ts
90
+ import { CanRevertResult, PreviewRevertResult, RevertResult } from '@schemeless/event-store-types';
91
+ ```
92
+
93
+ - `CanRevertResult` – Indicates whether an event can be reverted, with reasons if not
94
+ - `PreviewRevertResult` – Shows which events would be affected by a revert
95
+ - `RevertResult` – Contains the outcome of a revert operation, including generated compensating events