@kronos-ts/axon-server 0.3.1 → 0.4.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 +9 -5
- package/dist/axon-server-event-store.d.ts.map +1 -1
- package/dist/axon-server-event-store.js +38 -30
- package/dist/axon-server-event-store.js.map +1 -1
- package/dist/axon-server-snapshot-store.d.ts +8 -8
- package/dist/axon-server-snapshot-store.d.ts.map +1 -1
- package/dist/axon-server-snapshot-store.js +8 -14
- package/dist/axon-server-snapshot-store.js.map +1 -1
- package/dist/axon-server.d.ts +97 -186
- package/dist/axon-server.d.ts.map +1 -1
- package/dist/axon-server.js +217 -318
- package/dist/axon-server.js.map +1 -1
- package/dist/connection.d.ts +128 -0
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +134 -10
- package/dist/connection.js.map +1 -1
- package/dist/context-view.d.ts +30 -0
- package/dist/context-view.d.ts.map +1 -0
- package/dist/context-view.js +19 -0
- package/dist/context-view.js.map +1 -0
- package/dist/control-plane.d.ts +14 -13
- package/dist/control-plane.d.ts.map +1 -1
- package/dist/control-plane.js +8 -6
- package/dist/control-plane.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/flow-controlled-sender.js.map +1 -1
- package/dist/generated/command.d.ts.map +1 -1
- package/dist/generated/command.js.map +1 -1
- package/dist/generated/common.js.map +1 -1
- package/dist/generated/control.d.ts.map +1 -1
- package/dist/generated/control.js.map +1 -1
- package/dist/generated/dcb.d.ts.map +1 -1
- package/dist/generated/dcb.js.map +1 -1
- package/dist/generated/event.d.ts.map +1 -1
- package/dist/generated/event.js.map +1 -1
- package/dist/generated/google/protobuf/empty.js.map +1 -1
- package/dist/generated/query.d.ts.map +1 -1
- package/dist/generated/query.js.map +1 -1
- package/dist/index.d.ts +4 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -5
- package/dist/index.js.map +1 -1
- package/dist/message-size.d.ts.map +1 -1
- package/dist/metadata-conversion.d.ts +1 -1
- package/dist/metadata-conversion.d.ts.map +1 -1
- package/dist/shutdown-latch.d.ts.map +1 -1
- package/dist/shutdown-latch.js.map +1 -1
- package/package.json +4 -8
- package/src/axon-server-event-store.ts +51 -43
- package/src/axon-server-snapshot-store.ts +17 -25
- package/src/axon-server.ts +358 -512
- package/src/connection.ts +270 -18
- package/src/context-view.ts +46 -0
- package/src/control-plane.ts +17 -17
- package/src/index.ts +12 -18
- package/src/metadata-conversion.ts +1 -1
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
qualifiedNameFromString,
|
|
4
4
|
type Tag,
|
|
5
5
|
type Serializer,
|
|
6
|
-
} from "@kronos-ts/
|
|
6
|
+
} from "@kronos-ts/core"
|
|
7
7
|
import type {
|
|
8
8
|
EventCriteria,
|
|
9
9
|
EventMessage,
|
|
10
10
|
MessageStream,
|
|
11
11
|
SequencedEvent,
|
|
12
12
|
StreamingCondition,
|
|
13
|
-
} from "@kronos-ts/
|
|
14
|
-
import { messageStream } from "@kronos-ts/
|
|
13
|
+
} from "@kronos-ts/core"
|
|
14
|
+
import { messageStream, compileQuery } from "@kronos-ts/core"
|
|
15
15
|
import type {
|
|
16
16
|
EventStore,
|
|
17
17
|
SourcingResult,
|
|
@@ -19,11 +19,12 @@ import type {
|
|
|
19
19
|
AppendCondition,
|
|
20
20
|
ConsistencyMarker,
|
|
21
21
|
AppendTransaction,
|
|
22
|
-
} from "@kronos-ts/
|
|
23
|
-
import type { TrackingToken } from "@kronos-ts/
|
|
24
|
-
import { globalSequenceToken, FIRST_TOKEN } from "@kronos-ts/
|
|
25
|
-
import { markerAt, noMarker } from "@kronos-ts/
|
|
26
|
-
import type {
|
|
22
|
+
} from "@kronos-ts/core"
|
|
23
|
+
import type { TrackingToken } from "@kronos-ts/core"
|
|
24
|
+
import { globalSequenceToken, FIRST_TOKEN } from "@kronos-ts/core"
|
|
25
|
+
import { markerAt, noMarker } from "@kronos-ts/core"
|
|
26
|
+
import type { AxonServerStoreSource } from "./connection.js"
|
|
27
|
+
import { contextView } from "./context-view.js"
|
|
27
28
|
import type {
|
|
28
29
|
Criterion,
|
|
29
30
|
TagsAndNamesCriterion,
|
|
@@ -32,7 +33,6 @@ import type {
|
|
|
32
33
|
Event as ProtoEvent,
|
|
33
34
|
SourceEventsResponse,
|
|
34
35
|
} from "./generated/dcb.js"
|
|
35
|
-
import { Metadata } from "nice-grpc"
|
|
36
36
|
|
|
37
37
|
// ---------------------------------------------------------------------------
|
|
38
38
|
// Criteria conversion — framework EventCriteria → proto Criterion[]
|
|
@@ -57,24 +57,26 @@ function tagFromProto(tag: ProtoTag): Tag {
|
|
|
57
57
|
function criteriaToCriterions(criteria: EventCriteria): Criterion[] {
|
|
58
58
|
switch (criteria.kind) {
|
|
59
59
|
case "tags":
|
|
60
|
-
return [
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
return [
|
|
61
|
+
{
|
|
62
|
+
tagsAndNames: {
|
|
63
|
+
name: [],
|
|
64
|
+
tag: criteria.tags.map(tagToProto),
|
|
65
|
+
},
|
|
64
66
|
},
|
|
65
|
-
|
|
67
|
+
]
|
|
66
68
|
|
|
67
69
|
case "type-restricted":
|
|
68
70
|
// Inner must be tags or any-tag
|
|
69
|
-
const innerTags = criteria.inner.kind === "tags"
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
const innerTags = criteria.inner.kind === "tags" ? criteria.inner.tags.map(tagToProto) : []
|
|
72
|
+
return [
|
|
73
|
+
{
|
|
74
|
+
tagsAndNames: {
|
|
75
|
+
name: [...criteria.types],
|
|
76
|
+
tag: innerTags,
|
|
77
|
+
},
|
|
76
78
|
},
|
|
77
|
-
|
|
79
|
+
]
|
|
78
80
|
|
|
79
81
|
case "either":
|
|
80
82
|
// Flatten all sub-criteria into a list of criterions (OR semantics)
|
|
@@ -111,9 +113,14 @@ function createEventConverters(serializer: Serializer) {
|
|
|
111
113
|
},
|
|
112
114
|
|
|
113
115
|
eventFromProto(protoEvent: ProtoEvent, tags: ProtoTag[]): EventMessage {
|
|
114
|
-
const payload =
|
|
115
|
-
|
|
116
|
-
|
|
116
|
+
const payload =
|
|
117
|
+
protoEvent.payload.length > 0
|
|
118
|
+
? serializer.deserialize({
|
|
119
|
+
data: protoEvent.payload,
|
|
120
|
+
type: protoEvent.name,
|
|
121
|
+
revision: protoEvent.version,
|
|
122
|
+
})
|
|
123
|
+
: {}
|
|
117
124
|
|
|
118
125
|
const metadata: Record<string, unknown> = {}
|
|
119
126
|
for (const [k, v] of Object.entries(protoEvent.metadata)) {
|
|
@@ -139,28 +146,25 @@ function createEventConverters(serializer: Serializer) {
|
|
|
139
146
|
// ---------------------------------------------------------------------------
|
|
140
147
|
|
|
141
148
|
/**
|
|
142
|
-
*
|
|
149
|
+
* An EventStore over Axon Server's DCB event store, in one context.
|
|
143
150
|
*
|
|
144
151
|
* This bridges the framework's EventStore interface to the gRPC
|
|
145
152
|
* DcbEventStore service, handling conversion between framework types
|
|
146
153
|
* and proto messages.
|
|
147
154
|
*
|
|
155
|
+
* `context` is Axon Server's tenancy boundary and is a per-call header, so
|
|
156
|
+
* several contexts share the one channel `conn` holds — see `contextView`. The
|
|
157
|
+
* serializer is the connection's: one codec for everything this client puts on
|
|
158
|
+
* the wire.
|
|
159
|
+
*
|
|
148
160
|
* The {@link open} method returns a persistent {@link MessageStream} backed by
|
|
149
161
|
* a single gRPC Stream RPC call that stays open indefinitely, aligned with
|
|
150
162
|
* Java's infinite {@code ResultStream}.
|
|
151
163
|
*/
|
|
152
|
-
export function axonServerEventStore(
|
|
164
|
+
export function axonServerEventStore(conn: AxonServerStoreSource, context: string): EventStore {
|
|
165
|
+
const { connection, serializer, metadata: createAxonMetadata } = contextView(conn, context)
|
|
153
166
|
const { eventToProto, eventFromProto } = createEventConverters(serializer)
|
|
154
167
|
|
|
155
|
-
function createAxonMetadata(): Metadata {
|
|
156
|
-
const axonMetadata = new Metadata()
|
|
157
|
-
axonMetadata.set("AxonIQ-Context", connection.config.context)
|
|
158
|
-
if (connection.config.token) {
|
|
159
|
-
axonMetadata.set("AxonIQ-Access-Token", connection.config.token)
|
|
160
|
-
}
|
|
161
|
-
return axonMetadata
|
|
162
|
-
}
|
|
163
|
-
|
|
164
168
|
// Push-based subscriber registry (EventBus.subscribe contract). Axon Server's
|
|
165
169
|
// own distribution is the server-side Stream RPC (see open()); these in-process
|
|
166
170
|
// subscribers are notified best-effort on every successful local append.
|
|
@@ -177,7 +181,7 @@ export function axonServerEventStore(connection: AxonServerConnection, serialize
|
|
|
177
181
|
|
|
178
182
|
return {
|
|
179
183
|
async source(condition: SourcingCondition): Promise<SourcingResult> {
|
|
180
|
-
const criterions = criteriaToCriterions(condition.
|
|
184
|
+
const criterions = criteriaToCriterions(compileQuery(condition.query))
|
|
181
185
|
|
|
182
186
|
const request = {
|
|
183
187
|
fromSequence: condition.start ?? 0n,
|
|
@@ -213,10 +217,12 @@ export function axonServerEventStore(connection: AxonServerConnection, serialize
|
|
|
213
217
|
): Promise<AppendTransaction> {
|
|
214
218
|
const taggedEvents = newEvents.map(eventToProto)
|
|
215
219
|
const request = {
|
|
216
|
-
condition: condition
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
+
condition: condition
|
|
221
|
+
? {
|
|
222
|
+
consistencyMarker: condition.marker.position,
|
|
223
|
+
criterion: criteriaToCriterions(compileQuery(condition.query)),
|
|
224
|
+
}
|
|
225
|
+
: undefined,
|
|
220
226
|
event: taggedEvents,
|
|
221
227
|
}
|
|
222
228
|
|
|
@@ -229,7 +235,9 @@ export function axonServerEventStore(connection: AxonServerConnection, serialize
|
|
|
229
235
|
async function* requestStream() {
|
|
230
236
|
yield request
|
|
231
237
|
}
|
|
232
|
-
const response = await connection.eventStore.append(requestStream(), {
|
|
238
|
+
const response = await connection.eventStore.append(requestStream(), {
|
|
239
|
+
metadata: createAxonMetadata(),
|
|
240
|
+
})
|
|
233
241
|
responseMarker = response.consistencyMarker
|
|
234
242
|
await notifySubscribers(newEvents)
|
|
235
243
|
},
|
|
@@ -252,7 +260,7 @@ export function axonServerEventStore(connection: AxonServerConnection, serialize
|
|
|
252
260
|
},
|
|
253
261
|
|
|
254
262
|
open(condition: StreamingCondition): MessageStream<SequencedEvent> {
|
|
255
|
-
const criterions = condition.
|
|
263
|
+
const criterions = condition.query ? criteriaToCriterions(compileQuery(condition.query)) : []
|
|
256
264
|
|
|
257
265
|
const request = {
|
|
258
266
|
fromSequence: condition.position,
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import type { SnapshotStore, Snapshot } from "@kronos-ts/
|
|
2
|
-
import type { Serializer } from "@kronos-ts/
|
|
3
|
-
import type {
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
} from "./generated/dcb.js"
|
|
7
|
-
import { Metadata } from "nice-grpc"
|
|
1
|
+
import type { SnapshotStore, Snapshot } from "@kronos-ts/core"
|
|
2
|
+
import type { Serializer } from "@kronos-ts/core"
|
|
3
|
+
import type { AxonServerStoreSource } from "./connection.js"
|
|
4
|
+
import { contextView } from "./context-view.js"
|
|
5
|
+
import type { Snapshot as ProtoSnapshot } from "./generated/dcb.js"
|
|
8
6
|
|
|
9
7
|
// ---------------------------------------------------------------------------
|
|
10
8
|
// Conversion — framework Snapshot ↔ proto Snapshot
|
|
@@ -26,9 +24,10 @@ function createSnapshotConverters(serializer: Serializer) {
|
|
|
26
24
|
},
|
|
27
25
|
|
|
28
26
|
snapshotFromProto(proto: ProtoSnapshot, position: bigint): Snapshot {
|
|
29
|
-
const payload =
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
const payload =
|
|
28
|
+
proto.payload.length > 0
|
|
29
|
+
? serializer.deserialize({ data: proto.payload, type: "snapshot", revision: "" })
|
|
30
|
+
: {}
|
|
32
31
|
|
|
33
32
|
return {
|
|
34
33
|
position,
|
|
@@ -50,27 +49,20 @@ function encodeKey(stateName: string, id: unknown): Uint8Array {
|
|
|
50
49
|
// ---------------------------------------------------------------------------
|
|
51
50
|
|
|
52
51
|
/**
|
|
53
|
-
*
|
|
52
|
+
* A SnapshotStore over Axon Server's gRPC snapshot service, in one context.
|
|
54
53
|
*
|
|
55
|
-
* Uses the `DcbSnapshotStore` gRPC service to store and retrieve
|
|
56
|
-
*
|
|
57
|
-
*
|
|
54
|
+
* Uses the `DcbSnapshotStore` gRPC service to store and retrieve state
|
|
55
|
+
* snapshots. `context` is a per-call header, so this shares the one channel
|
|
56
|
+
* `conn` holds with every other context — see `contextView`. Payloads go
|
|
57
|
+
* through the connection's serializer.
|
|
58
58
|
*/
|
|
59
59
|
export function axonServerSnapshotStore(
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
conn: AxonServerStoreSource,
|
|
61
|
+
context: string,
|
|
62
62
|
): SnapshotStore {
|
|
63
|
+
const { connection, serializer, metadata: createAxonMetadata } = contextView(conn, context)
|
|
63
64
|
const { snapshotToProto, snapshotFromProto } = createSnapshotConverters(serializer)
|
|
64
65
|
|
|
65
|
-
function createAxonMetadata(): Metadata {
|
|
66
|
-
const axonMetadata = new Metadata()
|
|
67
|
-
axonMetadata.set("AxonIQ-Context", connection.config.context)
|
|
68
|
-
if (connection.config.token) {
|
|
69
|
-
axonMetadata.set("AxonIQ-Access-Token", connection.config.token)
|
|
70
|
-
}
|
|
71
|
-
return axonMetadata
|
|
72
|
-
}
|
|
73
|
-
|
|
74
66
|
return {
|
|
75
67
|
async store(stateName: string, id: unknown, snapshot: Snapshot): Promise<void> {
|
|
76
68
|
await connection.snapshotStore.add(
|