@auto-engineer/message-store 1.147.0 → 1.149.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.147.0 build /home/runner/work/auto-engineer/auto-engineer/packages/message-store
2
+ > @auto-engineer/message-store@1.149.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,13 +1,13 @@
1
1
 
2
- > @auto-engineer/message-store@1.146.0 test /home/runner/work/auto-engineer/auto-engineer/packages/message-store
2
+ > @auto-engineer/message-store@1.148.0 test /home/runner/work/auto-engineer/auto-engineer/packages/message-store
3
3
  > vitest run --reporter=dot
4
4
 
5
5
 
6
6
   RUN  v3.2.4 /home/runner/work/auto-engineer/auto-engineer/packages/message-store
7
7
 
8
8
 
9
- include: **/*.specs.{js,ts,tsx}
10
9
  No test files found, exiting with code 0
10
+ include: **/*.specs.{js,ts,tsx}
11
11
 
12
12
  exclude: **/.tmp/**, **/node_modules/**, **/dist/**, **/examples/**, **/create-auto-app/templates/**, **/*-starter/**, **/vite.config.ts
13
13
 
@@ -1,4 +1,4 @@
1
1
 
2
- > @auto-engineer/message-store@1.146.0 type-check /home/runner/work/auto-engineer/auto-engineer/packages/message-store
2
+ > @auto-engineer/message-store@1.148.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,56 @@
1
1
  # @auto-engineer/message-store
2
2
 
3
+ ## 1.149.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`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
8
+ - **server-generator-apollo-emmett**: context-aware nonCommandField instructions
9
+ - **server-generator-apollo-emmett**: add state context instruction
10
+ - **server-generator-apollo-emmett**: extract shared template helpers
11
+ - **server-generator-apollo-emmett**: filter state refs from hasGivenEvents in decide.ts.ejs
12
+
13
+ ### Patch Changes
14
+
15
+ - [`d38c81e`](https://github.com/BeOnAuto/auto-engineer/commit/d38c81e7bb442a39626564cf4f6d8d55b60d0a38) Thanks [@SamHatoum](https://github.com/SamHatoum)! -
16
+
17
+ - Updated dependencies [[`d38c81e`](https://github.com/BeOnAuto/auto-engineer/commit/d38c81e7bb442a39626564cf4f6d8d55b60d0a38), [`e1eebbd`](https://github.com/BeOnAuto/auto-engineer/commit/e1eebbdf4f209780e790094d2e6887c4fa809f98)]:
18
+ - @auto-engineer/message-bus@1.149.0
19
+
20
+ ## 1.148.0
21
+
22
+ ### Minor Changes
23
+
24
+ - [`d5ba3a0`](https://github.com/BeOnAuto/auto-engineer/commit/d5ba3a0e3fb0f6a9ad7a3a8b1815590ea77a5b42) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - Added state context instruction to generated decide handlers, preventing unnecessary narrowing when Given steps contain only state references
25
+
26
+ - [`e0cdc4e`](https://github.com/BeOnAuto/auto-engineer/commit/e0cdc4e3363ad84d4bc49996a600ac75c97ccc38) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - Added context-aware classification of non-command fields in generated decide.ts scaffolds, distinguishing between date-derived, state-derived, and not-yet-tested fields
27
+
28
+ - [`9195db7`](https://github.com/BeOnAuto/auto-engineer/commit/9195db78cb707d658866cee99a1c73d34fb4efde) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - Extracted shared template helpers into a dedicated module for cleaner code generation
29
+
30
+ - [`abb6540`](https://github.com/BeOnAuto/auto-engineer/commit/abb6540db7196ed7935c8a8610695828f9035fc3) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - Added status variant hints from Given state references to the state template, helping implementers create matching discriminated union variants
31
+
32
+ - [`9195db7`](https://github.com/BeOnAuto/auto-engineer/commit/9195db78cb707d658866cee99a1c73d34fb4efde) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - Extracted shared template helper functions into a dedicated module for better code reuse across generators
33
+ - Simplified template specs by removing inline duplicate definitions in favor of the shared helpers
34
+
35
+ ### Patch Changes
36
+
37
+ - [`88fb1da`](https://github.com/BeOnAuto/auto-engineer/commit/88fb1da2b222de04dd4959d87657395ee960a6ce) Thanks [@github-actions[bot]](https://github.com/github-actions%5Bbot%5D)! - - **server-generator-apollo-emmett**: skip empty file plans in scaffold output
38
+ - **server-generator-apollo-emmett**: filter state refs from given() in decide.specs.ts.ejs
39
+ - **server-generator-apollo-emmett**: move CS Given states from events to states array
40
+ - **global**: version packages
41
+ - **server-generator-apollo-emmett**: mark G1+G2 ketchup plan complete
42
+
43
+ - [`4255f6d`](https://github.com/BeOnAuto/auto-engineer/commit/4255f6db0d128979e573244a615886482ce799b0) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - Updated ketchup plan for state reference fix in decide template generator
44
+ - Marked generator bug fix milestones G1 and G2 as complete
45
+
46
+ - [`62f1ea3`](https://github.com/BeOnAuto/auto-engineer/commit/62f1ea3dd1b4275211574e3df9d9a6571ae9b27a) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - Fixed scaffold generation to correctly distinguish between event and state references in decision handlers
47
+ - Prevented contradictory instructions from appearing in generated code when Given clauses contain only state references
48
+
49
+ - [`ba4f5c9`](https://github.com/BeOnAuto/auto-engineer/commit/ba4f5c9749fb1c15d444e78ca9a2689817f039cb) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - Added implementation plan for decide.ts code generation fixes in the Apollo Emmett server generator
50
+
51
+ - Updated dependencies [[`88fb1da`](https://github.com/BeOnAuto/auto-engineer/commit/88fb1da2b222de04dd4959d87657395ee960a6ce), [`d5ba3a0`](https://github.com/BeOnAuto/auto-engineer/commit/d5ba3a0e3fb0f6a9ad7a3a8b1815590ea77a5b42), [`e0cdc4e`](https://github.com/BeOnAuto/auto-engineer/commit/e0cdc4e3363ad84d4bc49996a600ac75c97ccc38), [`4255f6d`](https://github.com/BeOnAuto/auto-engineer/commit/4255f6db0d128979e573244a615886482ce799b0), [`9195db7`](https://github.com/BeOnAuto/auto-engineer/commit/9195db78cb707d658866cee99a1c73d34fb4efde), [`abb6540`](https://github.com/BeOnAuto/auto-engineer/commit/abb6540db7196ed7935c8a8610695828f9035fc3), [`9195db7`](https://github.com/BeOnAuto/auto-engineer/commit/9195db78cb707d658866cee99a1c73d34fb4efde), [`62f1ea3`](https://github.com/BeOnAuto/auto-engineer/commit/62f1ea3dd1b4275211574e3df9d9a6571ae9b27a), [`ba4f5c9`](https://github.com/BeOnAuto/auto-engineer/commit/ba4f5c9749fb1c15d444e78ca9a2689817f039cb)]:
52
+ - @auto-engineer/message-bus@1.148.0
53
+
3
54
  ## 1.147.0
4
55
 
5
56
  ### 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.147.0",
4
+ "version": "1.149.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.147.0"
11
+ "@auto-engineer/message-bus": "1.149.0"
12
12
  },
13
13
  "devDependencies": {
14
14
  "typescript": "^5.3.0"