@schemeless/event-store-types 2.9.0 → 2.11.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.
@@ -0,0 +1,6 @@
1
+ export declare class ConcurrencyError extends Error {
2
+ readonly streamKey: string;
3
+ readonly expectedSequence: number;
4
+ readonly actualSequence: number;
5
+ constructor(streamKey: string, expectedSequence: number, actualSequence: number);
6
+ }
package/dist/Errors.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConcurrencyError = void 0;
4
+ class ConcurrencyError extends Error {
5
+ constructor(streamKey, expectedSequence, actualSequence) {
6
+ super(`Concurrency conflict on stream "${streamKey}": expected sequence ${expectedSequence}, but found ${actualSequence}`);
7
+ this.streamKey = streamKey;
8
+ this.expectedSequence = expectedSequence;
9
+ this.actualSequence = actualSequence;
10
+ this.name = 'ConcurrencyError';
11
+ }
12
+ }
13
+ exports.ConcurrencyError = ConcurrencyError;
@@ -1,4 +1,19 @@
1
- export interface BaseEventInput<Payload, META = undefined> {
1
+ /**
2
+ * Base metadata for all events.
3
+ * Framework automatically populates schemaVersion.
4
+ * User code can extend this interface for custom metadata.
5
+ */
6
+ export interface EventMeta {
7
+ /** Schema version of the event payload */
8
+ schemaVersion?: number;
9
+ /** Flag indicating this is a compensating event */
10
+ isCompensating?: boolean;
11
+ /** ID of the event being compensated */
12
+ compensatesEventId?: string;
13
+ /** Allow arbitrary extensions */
14
+ [key: string]: any;
15
+ }
16
+ export interface BaseEventInput<Payload, META extends EventMeta = EventMeta> {
2
17
  payload: Payload;
3
18
  meta?: META;
4
19
  identifier?: string;
@@ -11,7 +26,7 @@ export interface BaseEventInput<Payload, META = undefined> {
11
26
  causationId?: string;
12
27
  created?: Date;
13
28
  }
14
- export interface BaseEvent<Payload, META = undefined> extends BaseEventInput<Payload, META> {
29
+ export interface BaseEvent<Payload, META extends EventMeta = EventMeta> extends BaseEventInput<Payload, META> {
15
30
  id?: string;
16
31
  domain: string;
17
32
  type: string;
@@ -21,13 +36,13 @@ export interface BaseEvent<Payload, META = undefined> extends BaseEventInput<Pay
21
36
  causationId?: string;
22
37
  created?: Date;
23
38
  }
24
- export interface CreatedEvent<Payload, META = undefined> extends BaseEvent<Payload, META> {
39
+ export interface CreatedEvent<Payload, META extends EventMeta = EventMeta> extends BaseEvent<Payload, META> {
25
40
  id: string;
26
41
  readonly created: Date;
27
42
  }
28
- export interface StoredEvent<Payload, META = undefined> extends CreatedEvent<Payload, META> {
43
+ export interface StoredEvent<Payload, META extends EventMeta = EventMeta> extends CreatedEvent<Payload, META> {
29
44
  }
30
- export type Event<Payload, META = undefined> = StoredEvent<Payload, META>;
45
+ export type Event<Payload, META extends EventMeta = EventMeta> = StoredEvent<Payload, META>;
31
46
  export interface EventFlow<PartialPayload = any, Payload extends PartialPayload = PartialPayload> {
32
47
  readonly domain: string;
33
48
  readonly type: string;
@@ -38,6 +53,21 @@ export interface EventFlow<PartialPayload = any, Payload extends PartialPayload
38
53
  readonly eventType?: CreatedEvent<Payload>;
39
54
  readonly payloadType?: PartialPayload | Payload;
40
55
  readonly samplePayload?: PartialPayload | Payload;
56
+ /**
57
+ * Current schema version for this event type.
58
+ * Stored in event.meta.schemaVersion when event is created.
59
+ * @default 1
60
+ */
61
+ readonly schemaVersion?: number;
62
+ /**
63
+ * Upgrades event payload from older versions to the current schemaVersion.
64
+ * Called automatically during event processing and replay.
65
+ *
66
+ * @param event - The event with potentially outdated payload
67
+ * @param fromVersion - The version stored in event.meta.schemaVersion (defaults to 1)
68
+ * @returns Updated event with migrated payload, or void to use the original
69
+ */
70
+ readonly upcast?: (event: CreatedEvent<any>, fromVersion: number) => CreatedEvent<Payload> | Promise<CreatedEvent<Payload>> | void;
41
71
  /**
42
72
  * Extract the shard key for event routing.
43
73
  * Events with the same shard key will be processed sequentially in the same partition.
@@ -8,14 +8,28 @@ export interface IEventStoreEntity<PAYLOAD = any, META = any> {
8
8
  identifier?: string;
9
9
  correlationId?: string;
10
10
  causationId?: string;
11
+ sequence?: number;
11
12
  readonly created: Date;
12
13
  }
14
+ export interface StoreEventsOptions {
15
+ /**
16
+ * Expected sequence number for the stream (domain + identifier).
17
+ * If provided, the store will verify the current sequence matches
18
+ * before writing. Throws ConcurrencyError on mismatch.
19
+ */
20
+ expectedSequence?: number;
21
+ }
13
22
  export interface IEventStoreRepo<PAYLOAD = any, META = any> {
14
23
  init: () => Promise<void>;
15
24
  getAllEvents: (pageSize: number, startFromId?: string) => Promise<AsyncIterableIterator<Array<IEventStoreEntity<PAYLOAD, META>>>>;
16
25
  createEventEntity: (event: CreatedEvent<any>) => IEventStoreEntity<PAYLOAD, META>;
17
- storeEvents: (events: CreatedEvent<any>[]) => Promise<void>;
26
+ storeEvents: (events: CreatedEvent<any>[], options?: StoreEventsOptions) => Promise<void>;
18
27
  resetStore: () => Promise<void>;
28
+ /**
29
+ * Get the current sequence number for a stream.
30
+ * Returns 0 if no events exist for this stream.
31
+ */
32
+ getStreamSequence?: (domain: string, identifier: string) => Promise<number>;
19
33
  /**
20
34
  * Retrieves a single event by its ID.
21
35
  * Required for revert operations.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './EventStore.types';
2
2
  export * from './Repo.types';
3
3
  export * from './Revert.types';
4
+ export * from './Errors';
package/dist/index.js CHANGED
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./EventStore.types"), exports);
18
18
  __exportStar(require("./Repo.types"), exports);
19
19
  __exportStar(require("./Revert.types"), exports);
20
+ __exportStar(require("./Errors"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schemeless/event-store-types",
3
- "version": "2.9.0",
3
+ "version": "2.11.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": "94d1a0a24423072f691d5594c9d966ace2952fe8"
37
+ "gitHead": "299af18aa23f86c614fd38174e5c9ff54d1e3d69"
38
38
  }