@auto-engineer/message-store 1.148.0 → 1.150.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @auto-engineer/message-store@1.148.0 build /home/runner/work/auto-engineer/auto-engineer/packages/message-store
2
+ > @auto-engineer/message-store@1.150.0 build /home/runner/work/auto-engineer/auto-engineer/packages/message-store
3
3
  > tsc && tsx ../../scripts/fix-esm-imports.ts
4
4
 
5
5
  Fixed ESM imports in dist/
@@ -1,5 +1,5 @@
1
1
 
2
- > @auto-engineer/message-store@1.147.0 test /home/runner/work/auto-engineer/auto-engineer/packages/message-store
2
+ > @auto-engineer/message-store@1.149.0 test /home/runner/work/auto-engineer/auto-engineer/packages/message-store
3
3
  > vitest run --reporter=dot
4
4
 
5
5
 
@@ -1,4 +1,4 @@
1
1
 
2
- > @auto-engineer/message-store@1.147.0 type-check /home/runner/work/auto-engineer/auto-engineer/packages/message-store
2
+ > @auto-engineer/message-store@1.149.0 type-check /home/runner/work/auto-engineer/auto-engineer/packages/message-store
3
3
  > tsc --noEmit
4
4
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @auto-engineer/message-store
2
2
 
3
+ ## 1.150.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`a502d47`](https://github.com/BeOnAuto/auto-engineer/commit/a502d472df528a1c5d53905898220c2a3a49d8a5) Thanks [@osamanar](https://github.com/osamanar)! -
8
+
9
+ - [`c96a70e`](https://github.com/BeOnAuto/auto-engineer/commit/c96a70e49f9f64213450d0b9840bc9a8b2b1d77d) Thanks [@osamanar](https://github.com/osamanar)! -
10
+
11
+ - [`4343bca`](https://github.com/BeOnAuto/auto-engineer/commit/4343bcaa2576703ae578fd9b7f5ec5b9776702a9) Thanks [@osamanar](https://github.com/osamanar)! -
12
+
13
+ - [`28ffce9`](https://github.com/BeOnAuto/auto-engineer/commit/28ffce9c8b95f0c3ca61728bd1f667fa9416d461) Thanks [@osamanar](https://github.com/osamanar)! -
14
+
15
+ - [`3fd5dbf`](https://github.com/BeOnAuto/auto-engineer/commit/3fd5dbfbfb4f7a5fe71ae53105b31a1b0f30f911) Thanks [@osamanar](https://github.com/osamanar)! -
16
+
17
+ ### Patch Changes
18
+
19
+ - [`41f3df3`](https://github.com/BeOnAuto/auto-engineer/commit/41f3df3025445ba92208c2b007b8e29a40489309) Thanks [@github-actions[bot]](https://github.com/github-actions%5Bbot%5D)! - - **global**: version packages
20
+ - **global**: major refresh to all the docs
21
+ - Updated dependencies [[`a502d47`](https://github.com/BeOnAuto/auto-engineer/commit/a502d472df528a1c5d53905898220c2a3a49d8a5), [`c96a70e`](https://github.com/BeOnAuto/auto-engineer/commit/c96a70e49f9f64213450d0b9840bc9a8b2b1d77d), [`4343bca`](https://github.com/BeOnAuto/auto-engineer/commit/4343bcaa2576703ae578fd9b7f5ec5b9776702a9), [`28ffce9`](https://github.com/BeOnAuto/auto-engineer/commit/28ffce9c8b95f0c3ca61728bd1f667fa9416d461), [`41f3df3`](https://github.com/BeOnAuto/auto-engineer/commit/41f3df3025445ba92208c2b007b8e29a40489309), [`3fd5dbf`](https://github.com/BeOnAuto/auto-engineer/commit/3fd5dbfbfb4f7a5fe71ae53105b31a1b0f30f911)]:
22
+ - @auto-engineer/message-bus@1.150.0
23
+
24
+ ## 1.149.0
25
+
26
+ ### Minor Changes
27
+
28
+ - [`e1eebbd`](https://github.com/BeOnAuto/auto-engineer/commit/e1eebbdf4f209780e790094d2e6887c4fa809f98) Thanks [@github-actions[bot]](https://github.com/github-actions%5Bbot%5D)! - - **server-generator-apollo-emmett**: add Given state ref hints to state.ts.ejs
29
+ - **server-generator-apollo-emmett**: context-aware nonCommandField instructions
30
+ - **server-generator-apollo-emmett**: add state context instruction
31
+ - **server-generator-apollo-emmett**: extract shared template helpers
32
+ - **server-generator-apollo-emmett**: filter state refs from hasGivenEvents in decide.ts.ejs
33
+
34
+ ### Patch Changes
35
+
36
+ - [`d38c81e`](https://github.com/BeOnAuto/auto-engineer/commit/d38c81e7bb442a39626564cf4f6d8d55b60d0a38) Thanks [@SamHatoum](https://github.com/SamHatoum)! -
37
+
38
+ - Updated dependencies [[`d38c81e`](https://github.com/BeOnAuto/auto-engineer/commit/d38c81e7bb442a39626564cf4f6d8d55b60d0a38), [`e1eebbd`](https://github.com/BeOnAuto/auto-engineer/commit/e1eebbdf4f209780e790094d2e6887c4fa809f98)]:
39
+ - @auto-engineer/message-bus@1.149.0
40
+
3
41
  ## 1.148.0
4
42
 
5
43
  ### Minor Changes
package/README.md CHANGED
@@ -1,16 +1,17 @@
1
- # @auto-engineer/message-store
2
-
3
- Message store for persisting commands and events with stream-based storage and session tracking.
4
-
5
- ---
1
+ # @auto-engineer/message-store — Stream-based persistence for commands and events
6
2
 
7
3
  ## Purpose
8
4
 
9
- Without `@auto-engineer/message-store`, you would have to implement your own stream-based message persistence, handle revision tracking, manage sessions, and implement filtering across message types.
5
+ Without `@auto-engineer/message-store`, you would have to build your own stream-oriented message persistence with revision tracking, session management, filtering, and optimistic concurrency control.
10
6
 
11
- This package provides a persistence layer for CQRS/Event Sourcing architectures. It supports stream-based storage with revision tracking, session management, flexible filtering, optimistic concurrency control, and global position tracking.
7
+ ## Key Concepts
12
8
 
13
- ---
9
+ - **Streams** — Messages are grouped by `streamId`. Each stream tracks its own revision number, incremented on every append.
10
+ - **Global position** — Every message gets a monotonically increasing `position` across all streams, giving a total ordering of all writes.
11
+ - **Sessions** — A session groups related messages together. Creating a session returns a `sessionId` that is stamped onto every message saved while the session is active.
12
+ - **Optimistic concurrency** — Pass an `expectedRevision` when saving. If the stream's current revision does not match, the write is rejected.
13
+ - **Message type inference** — The store infers whether a message is a `command` or `event` from an explicit parameter, the stream name, or the presence of a `requestId` field.
14
+ - **Pluggable backends** — The `IMessageStore` interface allows alternate implementations. The built-in `MemoryMessageStore` stores everything in-process.
14
15
 
15
16
  ## Installation
16
17
 
@@ -25,40 +26,34 @@ import { MemoryMessageStore } from '@auto-engineer/message-store';
25
26
 
26
27
  const store = new MemoryMessageStore();
27
28
 
29
+ // Save a command
28
30
  await store.saveMessage('user-commands', {
29
31
  type: 'CreateUser',
30
32
  data: { name: 'Alice', email: 'alice@example.com' },
31
33
  requestId: 'req-123',
32
34
  });
33
35
 
36
+ // Read it back
34
37
  const messages = await store.getMessages('user-commands');
35
- console.log(messages);
36
- // → [{ streamId: 'user-commands', message: {...}, revision: 0n, position: 1n, ... }]
38
+ // [{ streamId: 'user-commands', message: {...}, revision: 0n, position: 1n, ... }]
37
39
  ```
38
40
 
39
- ---
40
-
41
41
  ## How-to Guides
42
42
 
43
- ### Save Messages to a Stream
43
+ ### Save multiple messages in one call
44
44
 
45
45
  ```typescript
46
- import { MemoryMessageStore } from '@auto-engineer/message-store';
47
-
48
- const store = new MemoryMessageStore();
49
-
50
- await store.saveMessage('orders-123', {
51
- type: 'OrderPlaced',
52
- data: { orderId: 'ord-001', total: 99.99 },
53
- });
46
+ await store.saveMessages('order-events', [
47
+ { type: 'OrderPlaced', data: { orderId: 'ord-1', total: 42 } },
48
+ { type: 'OrderConfirmed', data: { orderId: 'ord-1' } },
49
+ ]);
54
50
  ```
55
51
 
56
- ### Use Sessions
52
+ ### Use sessions to group related activity
57
53
 
58
54
  ```typescript
59
- const store = new MemoryMessageStore();
60
-
61
55
  const sessionId = await store.createSession();
56
+
62
57
  await store.saveMessage('commands', { type: 'StartProcess', data: {} });
63
58
  await store.saveMessage('events', { type: 'ProcessStarted', data: {} });
64
59
 
@@ -66,36 +61,42 @@ const sessionMessages = await store.getSessionMessages(sessionId);
66
61
  await store.endSession(sessionId);
67
62
  ```
68
63
 
69
- ### Filter Messages
64
+ ### Filter messages
70
65
 
71
66
  ```typescript
67
+ // Commands from the last hour with specific names
72
68
  const recentCommands = await store.getAllCommands({
73
- fromTimestamp: new Date(Date.now() - 3600000),
69
+ fromTimestamp: new Date(Date.now() - 3_600_000),
74
70
  messageNames: ['CreateUser', 'UpdateUser'],
75
71
  });
76
72
 
77
- const correlatedMessages = await store.getAllMessages({
73
+ // All messages sharing a correlation ID
74
+ const correlated = await store.getAllMessages({
78
75
  correlationId: 'corr-456',
79
76
  });
77
+
78
+ // Filter on message data fields
79
+ const matched = await store.getAllMessages({
80
+ jsonFilter: { orderId: 'ord-1' },
81
+ });
80
82
  ```
81
83
 
82
- ### Use Optimistic Concurrency
84
+ ### Enforce optimistic concurrency
83
85
 
84
86
  ```typescript
85
- await store.saveMessage('orders-123', command1); // revision becomes 0
87
+ await store.saveMessage('orders-123', command1); // revision becomes 0n
86
88
 
87
89
  try {
90
+ // This expects the stream to be empty (revision -1n), but it is at 0n
88
91
  await store.saveMessage('orders-123', command2, BigInt(-1));
89
92
  } catch (err) {
90
93
  // "Expected revision -1 but stream is at revision 0"
91
94
  }
92
95
  ```
93
96
 
94
- ---
95
-
96
97
  ## API Reference
97
98
 
98
- ### Package Exports
99
+ ### Exports
99
100
 
100
101
  ```typescript
101
102
  import {
@@ -103,80 +104,119 @@ import {
103
104
  type IMessageStore,
104
105
  type ILocalMessageStore,
105
106
  type Message,
107
+ type MessageType,
106
108
  type PositionalMessage,
107
109
  type MessageFilter,
108
110
  type StreamInfo,
109
111
  type SessionInfo,
112
+ type MessageStoreStats,
110
113
  } from '@auto-engineer/message-store';
111
114
  ```
112
115
 
113
- ### IMessageStore Interface
116
+ ### `IMessageStore`
117
+
118
+ | Method | Signature | Description |
119
+ |--------|-----------|-------------|
120
+ | `saveMessage` | `(streamId: string, message: Message, expectedRevision?: bigint, messageType?: MessageType) => Promise<void>` | Save a single message to a stream |
121
+ | `saveMessages` | `(streamId: string, messages: Message[], expectedRevision?: bigint, messageType?: MessageType) => Promise<void>` | Save multiple messages to a stream |
122
+ | `getMessages` | `(streamId: string, fromRevision?: bigint, count?: number) => Promise<PositionalMessage[]>` | Read messages from a stream |
123
+ | `getAllMessages` | `(filter?: MessageFilter, count?: number) => Promise<PositionalMessage[]>` | Read all messages across streams |
124
+ | `getAllCommands` | `(filter?, count?) => Promise<PositionalMessage[]>` | Shorthand for `getAllMessages` with `messageType: 'command'` |
125
+ | `getAllEvents` | `(filter?, count?) => Promise<PositionalMessage[]>` | Shorthand for `getAllMessages` with `messageType: 'event'` |
126
+ | `getStreamInfo` | `(streamId: string) => Promise<StreamInfo \| null>` | Get metadata about a stream |
127
+ | `getStreams` | `() => Promise<string[]>` | List all stream IDs |
128
+ | `getSessions` | `() => Promise<SessionInfo[]>` | List all sessions |
129
+ | `getSessionInfo` | `(sessionId: string) => Promise<SessionInfo \| null>` | Get metadata about a session |
130
+ | `getSessionMessages` | `(sessionId: string, filter?, count?) => Promise<PositionalMessage[]>` | Get messages for a session |
131
+ | `getStats` | `() => Promise<MessageStoreStats>` | Get aggregate statistics |
132
+ | `dispose` | `() => Promise<void>` | Release resources |
133
+
134
+ ### `ILocalMessageStore` (extends `IMessageStore`)
135
+
136
+ | Method | Signature | Description |
137
+ |--------|-----------|-------------|
138
+ | `reset` | `() => Promise<void>` | Clear all stored messages, sessions, and state |
139
+ | `createSession` | `() => Promise<string>` | Start a new session, returns the session ID |
140
+ | `endSession` | `(sessionId: string) => Promise<void>` | Mark a session as ended |
141
+
142
+ ### Types
114
143
 
115
- | Method | Description |
116
- |--------|-------------|
117
- | `saveMessage(streamId, message, expectedRevision?)` | Save a single message |
118
- | `saveMessages(streamId, messages, expectedRevision?)` | Save multiple messages |
119
- | `getMessages(streamId, fromRevision?, count?)` | Get messages from stream |
120
- | `getAllMessages(filter?, count?)` | Get all messages with filtering |
121
- | `getAllCommands(filter?, count?)` | Get all commands |
122
- | `getAllEvents(filter?, count?)` | Get all events |
123
- | `getStreamInfo(streamId)` | Get stream metadata |
124
- | `getStreams()` | Get all stream IDs |
125
- | `getSessions()` | Get all session info |
126
- | `getStats()` | Get storage statistics |
144
+ ```typescript
145
+ type Message = Command | Event; // from @auto-engineer/message-bus
127
146
 
128
- ### PositionalMessage
147
+ type MessageType = 'command' | 'event';
129
148
 
130
- ```typescript
131
149
  interface PositionalMessage {
132
150
  streamId: string;
133
151
  message: Message;
134
- messageType: 'command' | 'event';
135
- revision: bigint;
136
- position: bigint;
152
+ messageType: MessageType;
153
+ revision: bigint; // position within the stream
154
+ position: bigint; // global position across all streams
137
155
  timestamp: Date;
138
156
  sessionId: string;
139
157
  }
140
- ```
141
158
 
142
- ### MessageFilter
143
-
144
- ```typescript
145
159
  interface MessageFilter {
146
- messageType?: 'command' | 'event';
160
+ messageType?: MessageType;
147
161
  messageNames?: string[];
148
162
  streamId?: string;
149
163
  sessionId?: string;
150
164
  correlationId?: string;
165
+ requestId?: string;
151
166
  fromPosition?: bigint;
152
167
  toPosition?: bigint;
153
168
  fromTimestamp?: Date;
154
169
  toTimestamp?: Date;
170
+ jsonFilter?: Record<string, unknown>;
171
+ }
172
+
173
+ interface StreamInfo {
174
+ streamId: string;
175
+ revision: bigint;
176
+ messageCount: number;
177
+ firstPosition: bigint;
178
+ lastPosition: bigint;
179
+ createdAt: Date;
180
+ lastUpdated: Date;
181
+ }
182
+
183
+ interface SessionInfo {
184
+ sessionId: string;
185
+ startedAt: Date;
186
+ messageCount: number;
187
+ commandCount: number;
188
+ eventCount: number;
189
+ lastActivity: Date;
155
190
  }
156
- ```
157
191
 
158
- ---
192
+ interface MessageStoreStats {
193
+ totalMessages: number;
194
+ totalCommands: number;
195
+ totalEvents: number;
196
+ totalStreams: number;
197
+ totalSessions: number;
198
+ memoryUsage?: number;
199
+ oldestMessage?: Date;
200
+ newestMessage?: Date;
201
+ }
202
+ ```
159
203
 
160
204
  ## Architecture
161
205
 
162
206
  ```
163
207
  src/
164
- ├── index.ts
165
- ├── types.ts
166
- └── MemoryMessageStore.ts
208
+ ├── index.ts # Re-exports all public API
209
+ ├── interfaces/
210
+ │ ├── IMessageStore.ts # IMessageStore and ILocalMessageStore interfaces
211
+ │ └── types.ts # Message, PositionalMessage, filter and info types
212
+ └── memory/
213
+ └── MemoryMessageStore.ts # In-memory implementation
167
214
  ```
168
215
 
169
- ### Key Concepts
170
-
171
- - **Stream-based storage**: Messages organized by streamId
172
- - **Global positioning**: Monotonically increasing position across streams
173
- - **Session tracking**: Group related messages together
174
- - **Optimistic concurrency**: expectedRevision parameter
175
-
176
216
  ### Dependencies
177
217
 
178
- | Package | Usage |
179
- |---------|-------|
180
- | `@auto-engineer/message-bus` | Command and Event types |
181
- | `debug` | Debug logging |
182
- | `nanoid` | Session ID generation |
218
+ | Package | Role |
219
+ |---------|------|
220
+ | `@auto-engineer/message-bus` | Provides `Command` and `Event` types that compose `Message` |
221
+ | `debug` | Namespaced debug logging (`auto:message-store:memory`) |
222
+ | `nanoid` | Generates unique session IDs |
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@auto-engineer/message-store",
3
3
  "type": "module",
4
- "version": "1.148.0",
4
+ "version": "1.150.0",
5
5
  "description": "Message store for commands and events with pluggable backends",
6
6
  "main": "./dist/src/index.js",
7
7
  "types": "./dist/src/index.d.ts",
8
8
  "dependencies": {
9
9
  "debug": "^4.3.4",
10
10
  "nanoid": "^5.0.0",
11
- "@auto-engineer/message-bus": "1.148.0"
11
+ "@auto-engineer/message-bus": "1.150.0"
12
12
  },
13
13
  "devDependencies": {
14
14
  "typescript": "^5.3.0"