@kronos-ts/axon-server 0.1.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/dist/axon-server-event-store.d.ts +16 -0
- package/dist/axon-server-event-store.d.ts.map +1 -0
- package/dist/axon-server-event-store.js +282 -0
- package/dist/axon-server-event-store.js.map +1 -0
- package/dist/axon-server-snapshot-store.d.ts +12 -0
- package/dist/axon-server-snapshot-store.d.ts.map +1 -0
- package/dist/axon-server-snapshot-store.js +88 -0
- package/dist/axon-server-snapshot-store.js.map +1 -0
- package/dist/axon-server.d.ts +115 -0
- package/dist/axon-server.d.ts.map +1 -0
- package/dist/axon-server.js +986 -0
- package/dist/axon-server.js.map +1 -0
- package/dist/connection-manager.d.ts +49 -0
- package/dist/connection-manager.d.ts.map +1 -0
- package/dist/connection-manager.js +37 -0
- package/dist/connection-manager.js.map +1 -0
- package/dist/connection.d.ts +129 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +130 -0
- package/dist/connection.js.map +1 -0
- package/dist/errors.d.ts +96 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +189 -0
- package/dist/errors.js.map +1 -0
- package/dist/event-processor-info.d.ts +35 -0
- package/dist/event-processor-info.d.ts.map +1 -0
- package/dist/event-processor-info.js +28 -0
- package/dist/event-processor-info.js.map +1 -0
- package/dist/flow-controlled-sender.d.ts +30 -0
- package/dist/flow-controlled-sender.d.ts.map +1 -0
- package/dist/flow-controlled-sender.js +60 -0
- package/dist/flow-controlled-sender.js.map +1 -0
- package/dist/generated/command.d.ts +158 -0
- package/dist/generated/command.d.ts.map +1 -0
- package/dist/generated/command.js +970 -0
- package/dist/generated/command.js.map +1 -0
- package/dist/generated/common.d.ts +130 -0
- package/dist/generated/common.d.ts.map +1 -0
- package/dist/generated/common.js +908 -0
- package/dist/generated/common.js.map +1 -0
- package/dist/generated/control.d.ts +293 -0
- package/dist/generated/control.d.ts.map +1 -0
- package/dist/generated/control.js +1938 -0
- package/dist/generated/control.js.map +1 -0
- package/dist/generated/dcb.d.ts +650 -0
- package/dist/generated/dcb.d.ts.map +1 -0
- package/dist/generated/dcb.js +2943 -0
- package/dist/generated/dcb.js.map +1 -0
- package/dist/generated/event.d.ts +667 -0
- package/dist/generated/event.d.ts.map +1 -0
- package/dist/generated/event.js +3185 -0
- package/dist/generated/event.js.map +1 -0
- package/dist/generated/google/protobuf/empty.d.ts +30 -0
- package/dist/generated/google/protobuf/empty.d.ts.map +1 -0
- package/dist/generated/google/protobuf/empty.js +46 -0
- package/dist/generated/google/protobuf/empty.js.map +1 -0
- package/dist/generated/query.d.ts +300 -0
- package/dist/generated/query.d.ts.map +1 -0
- package/dist/generated/query.js +2183 -0
- package/dist/generated/query.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/message-size.d.ts +38 -0
- package/dist/message-size.d.ts.map +1 -0
- package/dist/message-size.js +57 -0
- package/dist/message-size.js.map +1 -0
- package/dist/metadata-conversion.d.ts +11 -0
- package/dist/metadata-conversion.d.ts.map +1 -0
- package/dist/metadata-conversion.js +51 -0
- package/dist/metadata-conversion.js.map +1 -0
- package/dist/outbound-stream.d.ts +15 -0
- package/dist/outbound-stream.d.ts.map +1 -0
- package/dist/outbound-stream.js +39 -0
- package/dist/outbound-stream.js.map +1 -0
- package/dist/platform-service.d.ts +119 -0
- package/dist/platform-service.d.ts.map +1 -0
- package/dist/platform-service.js +250 -0
- package/dist/platform-service.js.map +1 -0
- package/dist/shutdown-latch.d.ts +38 -0
- package/dist/shutdown-latch.d.ts.map +1 -0
- package/dist/shutdown-latch.js +51 -0
- package/dist/shutdown-latch.js.map +1 -0
- package/package.json +69 -0
- package/src/axon-server-event-store.ts +358 -0
- package/src/axon-server-snapshot-store.ts +118 -0
- package/src/axon-server.ts +1202 -0
- package/src/connection-manager.ts +88 -0
- package/src/connection.ts +272 -0
- package/src/errors.ts +223 -0
- package/src/event-processor-info.ts +62 -0
- package/src/flow-controlled-sender.ts +91 -0
- package/src/generated/command.ts +1231 -0
- package/src/generated/common.ts +1097 -0
- package/src/generated/control.ts +2419 -0
- package/src/generated/dcb.ts +3826 -0
- package/src/generated/event.ts +4076 -0
- package/src/generated/google/protobuf/empty.ts +84 -0
- package/src/generated/query.ts +2723 -0
- package/src/index.ts +75 -0
- package/src/message-size.ts +75 -0
- package/src/metadata-conversion.ts +46 -0
- package/src/outbound-stream.ts +52 -0
- package/src/platform-service.ts +361 -0
- package/src/shutdown-latch.ts +97 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Serializer } from "@kronos-ts/common";
|
|
2
|
+
import type { EventStore } from "@kronos-ts/eventsourcing";
|
|
3
|
+
import type { AxonServerConnection } from "./connection.js";
|
|
4
|
+
/**
|
|
5
|
+
* Creates an EventStore implementation backed by Axon Server's DCB event store.
|
|
6
|
+
*
|
|
7
|
+
* This bridges the framework's EventStore interface to the gRPC
|
|
8
|
+
* DcbEventStore service, handling conversion between framework types
|
|
9
|
+
* and proto messages.
|
|
10
|
+
*
|
|
11
|
+
* The {@link open} method returns a persistent {@link MessageStream} backed by
|
|
12
|
+
* a single gRPC Stream RPC call that stays open indefinitely, aligned with
|
|
13
|
+
* Java's infinite {@code ResultStream}.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createAxonServerEventStore(connection: AxonServerConnection, serializer: Serializer): EventStore;
|
|
16
|
+
//# sourceMappingURL=axon-server-event-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"axon-server-event-store.d.ts","sourceRoot":"","sources":["../src/axon-server-event-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,mBAAmB,CAAA;AAS1B,OAAO,KAAK,EACV,UAAU,EAMX,MAAM,0BAA0B,CAAA;AAIjC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAkH3D;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,oBAAoB,EAAE,UAAU,EAAE,UAAU,GAAG,UAAU,CA+M/G"}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { qualifiedNameToString, qualifiedNameFromString, } from "@kronos-ts/common";
|
|
2
|
+
import { createMessageStream } from "@kronos-ts/messaging";
|
|
3
|
+
import { globalSequenceToken, FIRST_TOKEN } from "@kronos-ts/messaging";
|
|
4
|
+
import { markerAt, noMarker } from "@kronos-ts/eventsourcing";
|
|
5
|
+
import { Metadata } from "nice-grpc";
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Criteria conversion — framework EventCriteria → proto Criterion[]
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
function tagToProto(tag) {
|
|
10
|
+
const encoder = new TextEncoder();
|
|
11
|
+
return {
|
|
12
|
+
key: encoder.encode(tag.key),
|
|
13
|
+
value: encoder.encode(tag.value),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function tagFromProto(tag) {
|
|
17
|
+
const decoder = new TextDecoder();
|
|
18
|
+
return {
|
|
19
|
+
key: decoder.decode(tag.key),
|
|
20
|
+
value: decoder.decode(tag.value),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function criteriaToCriterions(criteria) {
|
|
24
|
+
switch (criteria.kind) {
|
|
25
|
+
case "tags":
|
|
26
|
+
return [{
|
|
27
|
+
tagsAndNames: {
|
|
28
|
+
name: [],
|
|
29
|
+
tag: criteria.tags.map(tagToProto),
|
|
30
|
+
},
|
|
31
|
+
}];
|
|
32
|
+
case "type-restricted":
|
|
33
|
+
// Inner must be tags or any-tag
|
|
34
|
+
const innerTags = criteria.inner.kind === "tags"
|
|
35
|
+
? criteria.inner.tags.map(tagToProto)
|
|
36
|
+
: [];
|
|
37
|
+
return [{
|
|
38
|
+
tagsAndNames: {
|
|
39
|
+
name: [...criteria.types],
|
|
40
|
+
tag: innerTags,
|
|
41
|
+
},
|
|
42
|
+
}];
|
|
43
|
+
case "either":
|
|
44
|
+
// Flatten all sub-criteria into a list of criterions (OR semantics)
|
|
45
|
+
return criteria.criteria.flatMap(criteriaToCriterions);
|
|
46
|
+
case "any-tag":
|
|
47
|
+
// Match any tagged event — empty criterion
|
|
48
|
+
return [{ tagsAndNames: { name: [], tag: [] } }];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// Event conversion — framework EventMessage ↔ proto Event/TaggedEvent
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
function createEventConverters(serializer) {
|
|
55
|
+
return {
|
|
56
|
+
eventToProto(event) {
|
|
57
|
+
const name = qualifiedNameToString(event.name);
|
|
58
|
+
const serialized = serializer.serialize(event.payload, name, event.version);
|
|
59
|
+
return {
|
|
60
|
+
event: {
|
|
61
|
+
identifier: event.identifier,
|
|
62
|
+
timestamp: BigInt(event.timestamp),
|
|
63
|
+
name,
|
|
64
|
+
version: event.version,
|
|
65
|
+
payload: serialized.data,
|
|
66
|
+
metadata: Object.fromEntries(Object.entries(event.metadata).map(([k, v]) => [k, String(v)])),
|
|
67
|
+
},
|
|
68
|
+
tag: event.tags.map(tagToProto),
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
eventFromProto(protoEvent, tags) {
|
|
72
|
+
const payload = protoEvent.payload.length > 0
|
|
73
|
+
? serializer.deserialize({ data: protoEvent.payload, type: protoEvent.name, revision: protoEvent.version })
|
|
74
|
+
: {};
|
|
75
|
+
const metadata = {};
|
|
76
|
+
for (const [k, v] of Object.entries(protoEvent.metadata)) {
|
|
77
|
+
metadata[k] = v;
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
identifier: protoEvent.identifier,
|
|
81
|
+
name: qualifiedNameFromString(protoEvent.name),
|
|
82
|
+
version: protoEvent.version,
|
|
83
|
+
payload,
|
|
84
|
+
metadata,
|
|
85
|
+
timestamp: Number(protoEvent.timestamp),
|
|
86
|
+
tags: tags.map(tagFromProto),
|
|
87
|
+
};
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// AxonServerDcbEventStore — implements our EventStore interface via gRPC
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
/**
|
|
95
|
+
* Creates an EventStore implementation backed by Axon Server's DCB event store.
|
|
96
|
+
*
|
|
97
|
+
* This bridges the framework's EventStore interface to the gRPC
|
|
98
|
+
* DcbEventStore service, handling conversion between framework types
|
|
99
|
+
* and proto messages.
|
|
100
|
+
*
|
|
101
|
+
* The {@link open} method returns a persistent {@link MessageStream} backed by
|
|
102
|
+
* a single gRPC Stream RPC call that stays open indefinitely, aligned with
|
|
103
|
+
* Java's infinite {@code ResultStream}.
|
|
104
|
+
*/
|
|
105
|
+
export function createAxonServerEventStore(connection, serializer) {
|
|
106
|
+
const { eventToProto, eventFromProto } = createEventConverters(serializer);
|
|
107
|
+
function createAxonMetadata() {
|
|
108
|
+
const axonMetadata = new Metadata();
|
|
109
|
+
axonMetadata.set("AxonIQ-Context", connection.config.context);
|
|
110
|
+
if (connection.config.token) {
|
|
111
|
+
axonMetadata.set("AxonIQ-Access-Token", connection.config.token);
|
|
112
|
+
}
|
|
113
|
+
return axonMetadata;
|
|
114
|
+
}
|
|
115
|
+
// Push-based subscriber registry (EventBus.subscribe contract). Axon Server's
|
|
116
|
+
// own distribution is the server-side Stream RPC (see open()); these in-process
|
|
117
|
+
// subscribers are notified best-effort on every successful local append.
|
|
118
|
+
const subscribers = new Set();
|
|
119
|
+
async function notifySubscribers(events) {
|
|
120
|
+
for (const sub of subscribers) {
|
|
121
|
+
try {
|
|
122
|
+
await sub(events);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
/* ignore subscriber errors */
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
async source(condition) {
|
|
131
|
+
const criterions = criteriaToCriterions(condition.criteria);
|
|
132
|
+
const request = {
|
|
133
|
+
fromSequence: condition.start ?? 0n,
|
|
134
|
+
criterion: criterions,
|
|
135
|
+
};
|
|
136
|
+
const events = [];
|
|
137
|
+
let marker = noMarker();
|
|
138
|
+
const stream = connection.eventStore.source(request, { metadata: createAxonMetadata() });
|
|
139
|
+
for await (const response of stream) {
|
|
140
|
+
if (response.event) {
|
|
141
|
+
const taggedEvent = response.event;
|
|
142
|
+
const protoEvent = taggedEvent.event;
|
|
143
|
+
if (protoEvent) {
|
|
144
|
+
// DCB source/stream responses carry no tags — the server indexes
|
|
145
|
+
// them write-side but does not echo them back (SequencedEvent has
|
|
146
|
+
// only sequence + event). Reconstructed events get empty tags.
|
|
147
|
+
events.push(eventFromProto(protoEvent, []));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (response.consistencyMarker !== undefined) {
|
|
151
|
+
marker = markerAt(response.consistencyMarker);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return { events, marker };
|
|
155
|
+
},
|
|
156
|
+
async appendEvents(newEvents, condition) {
|
|
157
|
+
const taggedEvents = newEvents.map(eventToProto);
|
|
158
|
+
const request = {
|
|
159
|
+
condition: condition ? {
|
|
160
|
+
consistencyMarker: condition.marker.position,
|
|
161
|
+
criterion: criteriaToCriterions(condition.criteria),
|
|
162
|
+
} : undefined,
|
|
163
|
+
event: taggedEvents,
|
|
164
|
+
};
|
|
165
|
+
// Axon Server's Append RPC is atomic — commit happens on the server
|
|
166
|
+
// We send the request eagerly and wrap the response in a transaction
|
|
167
|
+
let responseMarker;
|
|
168
|
+
return {
|
|
169
|
+
async commit() {
|
|
170
|
+
async function* requestStream() {
|
|
171
|
+
yield request;
|
|
172
|
+
}
|
|
173
|
+
const response = await connection.eventStore.append(requestStream(), { metadata: createAxonMetadata() });
|
|
174
|
+
responseMarker = response.consistencyMarker;
|
|
175
|
+
await notifySubscribers(newEvents);
|
|
176
|
+
},
|
|
177
|
+
async afterCommit() {
|
|
178
|
+
return markerAt(responseMarker ?? 0n);
|
|
179
|
+
},
|
|
180
|
+
rollback() {
|
|
181
|
+
// Axon Server: if commit() was never called, nothing was sent
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
},
|
|
185
|
+
async append(newEvents, condition) {
|
|
186
|
+
const tx = await this.appendEvents(newEvents, condition);
|
|
187
|
+
await tx.commit();
|
|
188
|
+
return tx.afterCommit();
|
|
189
|
+
},
|
|
190
|
+
open(condition) {
|
|
191
|
+
const criterions = condition.criteria ? criteriaToCriterions(condition.criteria) : [];
|
|
192
|
+
const request = {
|
|
193
|
+
fromSequence: condition.position,
|
|
194
|
+
criterion: criterions,
|
|
195
|
+
};
|
|
196
|
+
const grpcStream = connection.eventStore.stream(request, { metadata: createAxonMetadata() });
|
|
197
|
+
// Internal buffer for events pulled from the gRPC stream
|
|
198
|
+
const buffer = [];
|
|
199
|
+
let availableCallback = null;
|
|
200
|
+
let completed = false;
|
|
201
|
+
let streamError;
|
|
202
|
+
let reading = false;
|
|
203
|
+
// Background reader: pulls from gRPC stream into buffer
|
|
204
|
+
async function startReading() {
|
|
205
|
+
if (reading)
|
|
206
|
+
return;
|
|
207
|
+
reading = true;
|
|
208
|
+
try {
|
|
209
|
+
for await (const response of grpcStream) {
|
|
210
|
+
if (completed)
|
|
211
|
+
break;
|
|
212
|
+
const taggedEvent = response.event;
|
|
213
|
+
if (taggedEvent?.event) {
|
|
214
|
+
buffer.push({
|
|
215
|
+
sequence: taggedEvent.sequence,
|
|
216
|
+
event: eventFromProto(taggedEvent.event, []),
|
|
217
|
+
});
|
|
218
|
+
availableCallback?.();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Stream ended (shouldn't happen for infinite stream)
|
|
222
|
+
completed = true;
|
|
223
|
+
availableCallback?.();
|
|
224
|
+
}
|
|
225
|
+
catch (err) {
|
|
226
|
+
streamError = err instanceof Error ? err : new Error(String(err));
|
|
227
|
+
completed = true;
|
|
228
|
+
availableCallback?.();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
startReading();
|
|
232
|
+
return createMessageStream({
|
|
233
|
+
next() {
|
|
234
|
+
return buffer.shift();
|
|
235
|
+
},
|
|
236
|
+
peek() {
|
|
237
|
+
return buffer[0];
|
|
238
|
+
},
|
|
239
|
+
hasNextAvailable() {
|
|
240
|
+
return buffer.length > 0;
|
|
241
|
+
},
|
|
242
|
+
isCompleted() {
|
|
243
|
+
return completed && buffer.length === 0;
|
|
244
|
+
},
|
|
245
|
+
error() {
|
|
246
|
+
return streamError;
|
|
247
|
+
},
|
|
248
|
+
setCallback(callback) {
|
|
249
|
+
availableCallback = callback;
|
|
250
|
+
},
|
|
251
|
+
close() {
|
|
252
|
+
completed = true;
|
|
253
|
+
availableCallback = null;
|
|
254
|
+
// gRPC stream will be cancelled when the async iterator is abandoned
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
},
|
|
258
|
+
async getHeadPosition() {
|
|
259
|
+
const response = await connection.eventStore.getHead({}, { metadata: createAxonMetadata() });
|
|
260
|
+
return response.sequence;
|
|
261
|
+
},
|
|
262
|
+
async firstToken() {
|
|
263
|
+
return FIRST_TOKEN;
|
|
264
|
+
},
|
|
265
|
+
async latestToken() {
|
|
266
|
+
const response = await connection.eventStore.getHead({}, { metadata: createAxonMetadata() });
|
|
267
|
+
return globalSequenceToken(response.sequence);
|
|
268
|
+
},
|
|
269
|
+
// EventBus contract — publish = append without condition, then notify
|
|
270
|
+
// in-process subscribers.
|
|
271
|
+
async publish(events) {
|
|
272
|
+
await this.append(events);
|
|
273
|
+
},
|
|
274
|
+
subscribe(handler) {
|
|
275
|
+
subscribers.add(handler);
|
|
276
|
+
return () => {
|
|
277
|
+
subscribers.delete(handler);
|
|
278
|
+
};
|
|
279
|
+
},
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=axon-server-event-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"axon-server-event-store.js","sourceRoot":"","sources":["../src/axon-server-event-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SnapshotStore } from "@kronos-ts/eventsourcing";
|
|
2
|
+
import type { Serializer } from "@kronos-ts/common";
|
|
3
|
+
import type { AxonServerConnection } from "./connection.js";
|
|
4
|
+
/**
|
|
5
|
+
* Creates a SnapshotStore backed by Axon Server's gRPC snapshot service.
|
|
6
|
+
*
|
|
7
|
+
* Uses the `DcbSnapshotStore` gRPC service to store and retrieve
|
|
8
|
+
* state snapshots. Payload serialization uses the configured
|
|
9
|
+
* Serializer (defaults to JSON).
|
|
10
|
+
*/
|
|
11
|
+
export declare function createAxonServerSnapshotStore(connection: AxonServerConnection, serializer: Serializer): SnapshotStore;
|
|
12
|
+
//# sourceMappingURL=axon-server-snapshot-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"axon-server-snapshot-store.d.ts","sourceRoot":"","sources":["../src/axon-server-snapshot-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAY,MAAM,0BAA0B,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAiD3D;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,oBAAoB,EAChC,UAAU,EAAE,UAAU,GACrB,aAAa,CAwDf"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Metadata } from "nice-grpc";
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Conversion — framework Snapshot ↔ proto Snapshot
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
const encoder = new TextEncoder();
|
|
6
|
+
function createSnapshotConverters(serializer) {
|
|
7
|
+
return {
|
|
8
|
+
snapshotToProto(snapshot) {
|
|
9
|
+
const serialized = serializer.serialize(snapshot.payload, "snapshot", "");
|
|
10
|
+
return {
|
|
11
|
+
name: "",
|
|
12
|
+
version: "",
|
|
13
|
+
payload: serialized.data,
|
|
14
|
+
timestamp: BigInt(snapshot.timestamp),
|
|
15
|
+
metadata: snapshot.metadata,
|
|
16
|
+
};
|
|
17
|
+
},
|
|
18
|
+
snapshotFromProto(proto, position) {
|
|
19
|
+
const payload = proto.payload.length > 0
|
|
20
|
+
? serializer.deserialize({ data: proto.payload, type: "snapshot", revision: "" })
|
|
21
|
+
: {};
|
|
22
|
+
return {
|
|
23
|
+
position,
|
|
24
|
+
payload,
|
|
25
|
+
timestamp: Number(proto.timestamp),
|
|
26
|
+
metadata: proto.metadata ?? {},
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function encodeKey(stateName, id) {
|
|
32
|
+
const idStr = typeof id === "object" && id !== null ? JSON.stringify(id) : String(id);
|
|
33
|
+
return encoder.encode(`${stateName}:${idStr}`);
|
|
34
|
+
}
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Axon Server snapshot store
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
/**
|
|
39
|
+
* Creates a SnapshotStore backed by Axon Server's gRPC snapshot service.
|
|
40
|
+
*
|
|
41
|
+
* Uses the `DcbSnapshotStore` gRPC service to store and retrieve
|
|
42
|
+
* state snapshots. Payload serialization uses the configured
|
|
43
|
+
* Serializer (defaults to JSON).
|
|
44
|
+
*/
|
|
45
|
+
export function createAxonServerSnapshotStore(connection, serializer) {
|
|
46
|
+
const { snapshotToProto, snapshotFromProto } = createSnapshotConverters(serializer);
|
|
47
|
+
function createAxonMetadata() {
|
|
48
|
+
const axonMetadata = new Metadata();
|
|
49
|
+
axonMetadata.set("AxonIQ-Context", connection.config.context);
|
|
50
|
+
if (connection.config.token) {
|
|
51
|
+
axonMetadata.set("AxonIQ-Access-Token", connection.config.token);
|
|
52
|
+
}
|
|
53
|
+
return axonMetadata;
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
async store(stateName, id, snapshot) {
|
|
57
|
+
await connection.snapshotStore.add({
|
|
58
|
+
key: encodeKey(stateName, id),
|
|
59
|
+
sequence: snapshot.position,
|
|
60
|
+
prune: true,
|
|
61
|
+
snapshot: snapshotToProto(snapshot),
|
|
62
|
+
}, { metadata: createAxonMetadata() });
|
|
63
|
+
},
|
|
64
|
+
async load(stateName, id) {
|
|
65
|
+
try {
|
|
66
|
+
const response = await connection.snapshotStore.getLast({ key: encodeKey(stateName, id) }, { metadata: createAxonMetadata() });
|
|
67
|
+
if (!response.snapshot) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
return snapshotFromProto(response.snapshot, response.sequence);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
// Axon Server throws when no snapshot exists — treat as "not found"
|
|
74
|
+
if (String(err).includes("No snapshot found")) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
async deleteSnapshots(stateName, id) {
|
|
81
|
+
await connection.snapshotStore.delete({
|
|
82
|
+
key: encodeKey(stateName, id),
|
|
83
|
+
toSequence: BigInt(Number.MAX_SAFE_INTEGER),
|
|
84
|
+
}, { metadata: createAxonMetadata() });
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=axon-server-snapshot-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"axon-server-snapshot-store.js","sourceRoot":"","sources":["../src/axon-server-snapshot-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native Axon Server extension (Phase 9, D-95 / D-101 / D-102).
|
|
3
|
+
*
|
|
4
|
+
* Replaces the legacy enhancer surface (now deleted) with a
|
|
5
|
+
* `(app: App) => void` extension that:
|
|
6
|
+
*
|
|
7
|
+
* - populates four typed slots (eventStore, snapshotStore, commandBus,
|
|
8
|
+
* queryBus) via app.set(...) using the canonical Resolved slot names
|
|
9
|
+
* (in particular `resolved.unitOfWorkFactory`, NOT `unitOfWorkRunner`);
|
|
10
|
+
* - wires connect-stage transport bring-up under the @kronos-ts/common
|
|
11
|
+
* resilience helper (initial-connect + health-check + platform setup +
|
|
12
|
+
* instruction handlers + platform.start);
|
|
13
|
+
* - wires processors-stage subscription-ack wait via withRetry against
|
|
14
|
+
* `platform.subscriptionsAcked()` — REPLACES the 1-second sleep hack
|
|
15
|
+
* that lived at line 264 of the legacy file (D-102 — Axon equivalent);
|
|
16
|
+
* - reverses shutdown deterministically in a single onStop('connect') hook
|
|
17
|
+
* (busLatches → platform.stop → connection.close — D-101.b).
|
|
18
|
+
*
|
|
19
|
+
* Mirrors `kronosdb.ts` (Plan 09-03) STRUCTURALLY — same slot+lifecycle
|
|
20
|
+
* pattern, same resilience helper, same shutdown ordering, same
|
|
21
|
+
* subscription-ack derivation strategy — but preserves Axon-specific
|
|
22
|
+
* protocol invariants byte-for-byte:
|
|
23
|
+
*
|
|
24
|
+
* - CLIENT_SUPPORTS_STREAMING capability advertised on every dispatched
|
|
25
|
+
* query via `defaultQueryInstructions(...)`;
|
|
26
|
+
* - AxonIQ-Context + AxonIQ-Access-Token gRPC metadata headers built by
|
|
27
|
+
* `createAxonMetadata(...)` and attached to every outbound stream/RPC;
|
|
28
|
+
* - permits-AFTER-subscriptions stream ordering preserved on the initial
|
|
29
|
+
* handshake AND on reconnect (legacy semantics in `ensureStreamStarted`
|
|
30
|
+
* issued permits before subscriptions; this implementation matches that
|
|
31
|
+
* exact ordering — see `ensureStreamStarted` / `reestablishStreamBody`).
|
|
32
|
+
*/
|
|
33
|
+
import { type ResilienceConfig } from "@kronos-ts/common";
|
|
34
|
+
import type { App } from "@kronos-ts/app";
|
|
35
|
+
import type { AxonServerConnectionConfig } from "./connection.js";
|
|
36
|
+
import { type PlatformServiceOptions } from "./platform-service.js";
|
|
37
|
+
/**
|
|
38
|
+
* Flow control configuration for a bus channel.
|
|
39
|
+
*/
|
|
40
|
+
export interface FlowControlConfig {
|
|
41
|
+
/** Initial permits granted to Axon Server. Default: 5000 (aligned with Java). */
|
|
42
|
+
permits?: number;
|
|
43
|
+
/** Threshold at which to request more permits. Default: 2500 (aligned with Java). */
|
|
44
|
+
refillThreshold?: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Processing instructions attached to outbound messages.
|
|
48
|
+
* Controls routing, priority, and timeout behavior on Axon Server.
|
|
49
|
+
*/
|
|
50
|
+
export interface ProcessingInstructions {
|
|
51
|
+
/** Routing key for consistent hashing (e.g., aggregate ID). */
|
|
52
|
+
routingKey?: string;
|
|
53
|
+
/** Priority (higher = processed first). Default: 0 */
|
|
54
|
+
priority?: number;
|
|
55
|
+
/** Timeout in ms. Axon Server cancels the command/query if not handled in time. */
|
|
56
|
+
timeoutMs?: number;
|
|
57
|
+
}
|
|
58
|
+
export interface AxonServerExtensionConfig extends AxonServerConnectionConfig {
|
|
59
|
+
/** Flow control for the command bus channel. */
|
|
60
|
+
commandFlowControl?: FlowControlConfig;
|
|
61
|
+
/** Flow control for the query bus channel. */
|
|
62
|
+
queryFlowControl?: FlowControlConfig;
|
|
63
|
+
/** Platform service configuration (heartbeat, etc.). */
|
|
64
|
+
platformService?: PlatformServiceOptions;
|
|
65
|
+
/**
|
|
66
|
+
* When true, queries are first checked against locally registered handlers
|
|
67
|
+
* before being dispatched through Axon Server. Avoids a network round-trip
|
|
68
|
+
* when the handler is co-located.
|
|
69
|
+
*
|
|
70
|
+
* Aligned with Java's `shortcutQueriesToLocalHandlers`.
|
|
71
|
+
* Default: false.
|
|
72
|
+
*/
|
|
73
|
+
shortcutQueriesToLocalHandlers?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Load factor for command handler registration.
|
|
76
|
+
* Signals to Axon Server how much capacity this handler has.
|
|
77
|
+
* Higher value = handler can take more commands.
|
|
78
|
+
*
|
|
79
|
+
* Aligned with Java's `commandLoadFactor`. Default: 100.
|
|
80
|
+
*/
|
|
81
|
+
commandLoadFactor?: number;
|
|
82
|
+
/**
|
|
83
|
+
* Default timeout for command dispatch in ms. Default: 300000 (5 min).
|
|
84
|
+
* Aligned with Java's processing instruction timeout.
|
|
85
|
+
*/
|
|
86
|
+
commandTimeoutMs?: number;
|
|
87
|
+
/**
|
|
88
|
+
* Default timeout for query dispatch in ms. Default: 3600000 (1 hour).
|
|
89
|
+
* Aligned with Java's processing instruction timeout.
|
|
90
|
+
*/
|
|
91
|
+
queryTimeoutMs?: number;
|
|
92
|
+
/** Per-extension resilience config (D-100 / D-101). */
|
|
93
|
+
resilience?: Partial<ResilienceConfig>;
|
|
94
|
+
/**
|
|
95
|
+
* Delay in ms after the platform-stream ack to give Axon Server's
|
|
96
|
+
* routing tables time to register the subscribe frames sent on the
|
|
97
|
+
* command/query streams. The platform stream cannot observe these (they
|
|
98
|
+
* travel on different streams). Default: 1000 — matches the legacy
|
|
99
|
+
* enhancer's wait. Tests against a freshly-booted server can tighten
|
|
100
|
+
* this once subscriptions are observed to land faster.
|
|
101
|
+
*/
|
|
102
|
+
busSubscriptionAckDelayMs?: number;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Native Axon Server extension factory. Returns an Extension closure shaped
|
|
106
|
+
* as `(app: App) => void` per D-95.
|
|
107
|
+
*
|
|
108
|
+
* ```ts
|
|
109
|
+
* await kronos()
|
|
110
|
+
* .use(axonServer({ componentName: "university-service" }))
|
|
111
|
+
* .start()
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export declare function axonServer(serverConfig: AxonServerExtensionConfig): (app: App) => void;
|
|
115
|
+
//# sourceMappingURL=axon-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"axon-server.d.ts","sourceRoot":"","sources":["../src/axon-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAOL,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AAazC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAA;AAQjE,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,uBAAuB,CAAA;AAM9B;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,qFAAqF;IACrF,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA0DD,MAAM,WAAW,yBAA0B,SAAQ,0BAA0B;IAC3E,gDAAgD;IAChD,kBAAkB,CAAC,EAAE,iBAAiB,CAAA;IACtC,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,iBAAiB,CAAA;IACpC,wDAAwD;IACxD,eAAe,CAAC,EAAE,sBAAsB,CAAA;IACxC;;;;;;;OAOG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAA;IACxC;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,uDAAuD;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACtC;;;;;;;OAOG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAA;CACnC;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,YAAY,EAAE,yBAAyB,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAuTtF"}
|