@auto-engineer/message-store 1.148.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.
- package/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +2 -2
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +17 -0
- package/README.md +112 -72
- package/package.json +2 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @auto-engineer/message-store@1.
|
|
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/
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @auto-engineer/message-store@1.
|
|
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
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
No test files found, exiting with code 0
|
|
10
|
-
|
|
11
10
|
[2minclude: [22m[33m**/*.specs.{js,ts,tsx}[39m
|
|
11
|
+
|
|
12
12
|
[2mexclude: [22m[33m**/.tmp/**[2m, [22m**/node_modules/**[2m, [22m**/dist/**[2m, [22m**/examples/**[2m, [22m**/create-auto-app/templates/**[2m, [22m**/*-starter/**[2m, [22m**/vite.config.ts[39m
|
|
13
13
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
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
|
+
|
|
3
20
|
## 1.148.0
|
|
4
21
|
|
|
5
22
|
### 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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
43
|
+
### Save multiple messages in one call
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
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
|
|
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() -
|
|
69
|
+
fromTimestamp: new Date(Date.now() - 3_600_000),
|
|
74
70
|
messageNames: ['CreateUser', 'UpdateUser'],
|
|
75
71
|
});
|
|
76
72
|
|
|
77
|
-
|
|
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
|
-
###
|
|
84
|
+
### Enforce optimistic concurrency
|
|
83
85
|
|
|
84
86
|
```typescript
|
|
85
|
-
await store.saveMessage('orders-123', command1); // revision becomes
|
|
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
|
-
###
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
147
|
+
type MessageType = 'command' | 'event';
|
|
129
148
|
|
|
130
|
-
```typescript
|
|
131
149
|
interface PositionalMessage {
|
|
132
150
|
streamId: string;
|
|
133
151
|
message: Message;
|
|
134
|
-
messageType:
|
|
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?:
|
|
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
|
-
├──
|
|
166
|
-
|
|
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 |
|
|
179
|
-
|
|
180
|
-
| `@auto-engineer/message-bus` | Command and Event types |
|
|
181
|
-
| `debug` |
|
|
182
|
-
| `nanoid` |
|
|
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.
|
|
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.
|
|
11
|
+
"@auto-engineer/message-bus": "1.149.0"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
14
|
"typescript": "^5.3.0"
|