@kronos-ts/messaging 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/command-bus.d.ts +30 -0
- package/dist/command-bus.d.ts.map +1 -0
- package/dist/command-bus.js +2 -0
- package/dist/command-bus.js.map +1 -0
- package/dist/command-handler.d.ts +58 -0
- package/dist/command-handler.d.ts.map +1 -0
- package/dist/command-handler.js +12 -0
- package/dist/command-handler.js.map +1 -0
- package/dist/command-handling-module.d.ts +53 -0
- package/dist/command-handling-module.d.ts.map +1 -0
- package/dist/command-handling-module.js +130 -0
- package/dist/command-handling-module.js.map +1 -0
- package/dist/correlation-data.d.ts +79 -0
- package/dist/correlation-data.d.ts.map +1 -0
- package/dist/correlation-data.js +133 -0
- package/dist/correlation-data.js.map +1 -0
- package/dist/dead-letter-queue.d.ts +134 -0
- package/dist/dead-letter-queue.d.ts.map +1 -0
- package/dist/dead-letter-queue.js +176 -0
- package/dist/dead-letter-queue.js.map +1 -0
- package/dist/dead-lettering-handler.d.ts +42 -0
- package/dist/dead-lettering-handler.d.ts.map +1 -0
- package/dist/dead-lettering-handler.js +67 -0
- package/dist/dead-lettering-handler.js.map +1 -0
- package/dist/descriptor.d.ts +135 -0
- package/dist/descriptor.d.ts.map +1 -0
- package/dist/descriptor.js +36 -0
- package/dist/descriptor.js.map +1 -0
- package/dist/emit-update.d.ts +22 -0
- package/dist/emit-update.d.ts.map +1 -0
- package/dist/emit-update.js +23 -0
- package/dist/emit-update.js.map +1 -0
- package/dist/event-bus.d.ts +29 -0
- package/dist/event-bus.d.ts.map +1 -0
- package/dist/event-bus.js +22 -0
- package/dist/event-bus.js.map +1 -0
- package/dist/event-criteria.d.ts +87 -0
- package/dist/event-criteria.d.ts.map +1 -0
- package/dist/event-criteria.js +90 -0
- package/dist/event-criteria.js.map +1 -0
- package/dist/event-gateway.d.ts +19 -0
- package/dist/event-gateway.d.ts.map +1 -0
- package/dist/event-gateway.js +22 -0
- package/dist/event-gateway.js.map +1 -0
- package/dist/event-handler.d.ts +30 -0
- package/dist/event-handler.d.ts.map +1 -0
- package/dist/event-handler.js +18 -0
- package/dist/event-handler.js.map +1 -0
- package/dist/event-processor-builder.d.ts +148 -0
- package/dist/event-processor-builder.d.ts.map +1 -0
- package/dist/event-processor-builder.js +175 -0
- package/dist/event-processor-builder.js.map +1 -0
- package/dist/event-processor.d.ts +10 -0
- package/dist/event-processor.d.ts.map +1 -0
- package/dist/event-processor.js +2 -0
- package/dist/event-processor.js.map +1 -0
- package/dist/event-sink.d.ts +23 -0
- package/dist/event-sink.d.ts.map +1 -0
- package/dist/event-sink.js +2 -0
- package/dist/event-sink.js.map +1 -0
- package/dist/event-source.d.ts +98 -0
- package/dist/event-source.d.ts.map +1 -0
- package/dist/event-source.js +191 -0
- package/dist/event-source.js.map +1 -0
- package/dist/gateway.d.ts +68 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +62 -0
- package/dist/gateway.js.map +1 -0
- package/dist/handler-enhancer.d.ts +53 -0
- package/dist/handler-enhancer.d.ts.map +1 -0
- package/dist/handler-enhancer.js +17 -0
- package/dist/handler-enhancer.js.map +1 -0
- package/dist/handler.d.ts +51 -0
- package/dist/handler.d.ts.map +1 -0
- package/dist/handler.js +26 -0
- package/dist/handler.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +103 -0
- package/dist/index.js.map +1 -0
- package/dist/intercepting-command-bus.d.ts +17 -0
- package/dist/intercepting-command-bus.d.ts.map +1 -0
- package/dist/intercepting-command-bus.js +54 -0
- package/dist/intercepting-command-bus.js.map +1 -0
- package/dist/intercepting-event-bus.d.ts +8 -0
- package/dist/intercepting-event-bus.d.ts.map +1 -0
- package/dist/intercepting-event-bus.js +22 -0
- package/dist/intercepting-event-bus.js.map +1 -0
- package/dist/intercepting-query-bus.d.ts +17 -0
- package/dist/intercepting-query-bus.d.ts.map +1 -0
- package/dist/intercepting-query-bus.js +68 -0
- package/dist/intercepting-query-bus.js.map +1 -0
- package/dist/interceptor.d.ts +46 -0
- package/dist/interceptor.d.ts.map +1 -0
- package/dist/interceptor.js +2 -0
- package/dist/interceptor.js.map +1 -0
- package/dist/message-monitor-registry.d.ts +28 -0
- package/dist/message-monitor-registry.d.ts.map +1 -0
- package/dist/message-monitor-registry.js +37 -0
- package/dist/message-monitor-registry.js.map +1 -0
- package/dist/message-monitor.d.ts +36 -0
- package/dist/message-monitor.d.ts.map +1 -0
- package/dist/message-monitor.js +39 -0
- package/dist/message-monitor.js.map +1 -0
- package/dist/message.d.ts +42 -0
- package/dist/message.d.ts.map +1 -0
- package/dist/message.js +2 -0
- package/dist/message.js.map +1 -0
- package/dist/processing-state.d.ts +115 -0
- package/dist/processing-state.d.ts.map +1 -0
- package/dist/processing-state.js +205 -0
- package/dist/processing-state.js.map +1 -0
- package/dist/processor-configuration.d.ts +51 -0
- package/dist/processor-configuration.d.ts.map +1 -0
- package/dist/processor-configuration.js +2 -0
- package/dist/processor-configuration.js.map +1 -0
- package/dist/query-bus.d.ts +51 -0
- package/dist/query-bus.d.ts.map +1 -0
- package/dist/query-bus.js +2 -0
- package/dist/query-bus.js.map +1 -0
- package/dist/query-handler.d.ts +35 -0
- package/dist/query-handler.d.ts.map +1 -0
- package/dist/query-handler.js +19 -0
- package/dist/query-handler.js.map +1 -0
- package/dist/query-handling-module.d.ts +24 -0
- package/dist/query-handling-module.d.ts.map +1 -0
- package/dist/query-handling-module.js +32 -0
- package/dist/query-handling-module.js.map +1 -0
- package/dist/replay-token.d.ts +31 -0
- package/dist/replay-token.d.ts.map +1 -0
- package/dist/replay-token.js +37 -0
- package/dist/replay-token.js.map +1 -0
- package/dist/retrying-command-bus.d.ts +32 -0
- package/dist/retrying-command-bus.d.ts.map +1 -0
- package/dist/retrying-command-bus.js +58 -0
- package/dist/retrying-command-bus.js.map +1 -0
- package/dist/routing-strategy.d.ts +30 -0
- package/dist/routing-strategy.d.ts.map +1 -0
- package/dist/routing-strategy.js +37 -0
- package/dist/routing-strategy.js.map +1 -0
- package/dist/segment.d.ts +72 -0
- package/dist/segment.d.ts.map +1 -0
- package/dist/segment.js +103 -0
- package/dist/segment.js.map +1 -0
- package/dist/send.d.ts +28 -0
- package/dist/send.d.ts.map +1 -0
- package/dist/send.js +36 -0
- package/dist/send.js.map +1 -0
- package/dist/serializer.d.ts +40 -0
- package/dist/serializer.d.ts.map +1 -0
- package/dist/serializer.js +90 -0
- package/dist/serializer.js.map +1 -0
- package/dist/simple-command-bus.d.ts +23 -0
- package/dist/simple-command-bus.d.ts.map +1 -0
- package/dist/simple-command-bus.js +49 -0
- package/dist/simple-command-bus.js.map +1 -0
- package/dist/simple-query-bus.d.ts +16 -0
- package/dist/simple-query-bus.d.ts.map +1 -0
- package/dist/simple-query-bus.js +122 -0
- package/dist/simple-query-bus.js.map +1 -0
- package/dist/span-factory.d.ts +58 -0
- package/dist/span-factory.d.ts.map +1 -0
- package/dist/span-factory.js +19 -0
- package/dist/span-factory.js.map +1 -0
- package/dist/streaming-event-processor.d.ts +65 -0
- package/dist/streaming-event-processor.d.ts.map +1 -0
- package/dist/streaming-event-processor.js +239 -0
- package/dist/streaming-event-processor.js.map +1 -0
- package/dist/subscribing-event-processor.d.ts +57 -0
- package/dist/subscribing-event-processor.d.ts.map +1 -0
- package/dist/subscribing-event-processor.js +100 -0
- package/dist/subscribing-event-processor.js.map +1 -0
- package/dist/subscription-query.d.ts +63 -0
- package/dist/subscription-query.d.ts.map +1 -0
- package/dist/subscription-query.js +119 -0
- package/dist/subscription-query.js.map +1 -0
- package/dist/token-store.d.ts +83 -0
- package/dist/token-store.d.ts.map +1 -0
- package/dist/token-store.js +112 -0
- package/dist/token-store.js.map +1 -0
- package/dist/tracing-command-bus.d.ts +16 -0
- package/dist/tracing-command-bus.d.ts.map +1 -0
- package/dist/tracing-command-bus.js +44 -0
- package/dist/tracing-command-bus.js.map +1 -0
- package/dist/tracing-handler-enhancer.d.ts +11 -0
- package/dist/tracing-handler-enhancer.d.ts.map +1 -0
- package/dist/tracing-handler-enhancer.js +27 -0
- package/dist/tracing-handler-enhancer.js.map +1 -0
- package/dist/tracking-event-processor.d.ts +72 -0
- package/dist/tracking-event-processor.d.ts.map +1 -0
- package/dist/tracking-event-processor.js +223 -0
- package/dist/tracking-event-processor.js.map +1 -0
- package/dist/tracking-token.d.ts +120 -0
- package/dist/tracking-token.d.ts.map +1 -0
- package/dist/tracking-token.js +132 -0
- package/dist/tracking-token.js.map +1 -0
- package/dist/transaction.d.ts +60 -0
- package/dist/transaction.d.ts.map +1 -0
- package/dist/transaction.js +74 -0
- package/dist/transaction.js.map +1 -0
- package/dist/unit-of-work.d.ts +41 -0
- package/dist/unit-of-work.d.ts.map +1 -0
- package/dist/unit-of-work.js +96 -0
- package/dist/unit-of-work.js.map +1 -0
- package/dist/upcaster.d.ts +91 -0
- package/dist/upcaster.d.ts.map +1 -0
- package/dist/upcaster.js +114 -0
- package/dist/upcaster.js.map +1 -0
- package/dist/with-namespace.d.ts +59 -0
- package/dist/with-namespace.d.ts.map +1 -0
- package/dist/with-namespace.js +42 -0
- package/dist/with-namespace.js.map +1 -0
- package/package.json +65 -0
- package/src/command-bus.ts +34 -0
- package/src/command-handler.ts +116 -0
- package/src/command-handling-module.ts +183 -0
- package/src/correlation-data.ts +169 -0
- package/src/dead-letter-queue.ts +330 -0
- package/src/dead-lettering-handler.ts +109 -0
- package/src/descriptor.ts +176 -0
- package/src/emit-update.ts +35 -0
- package/src/event-bus.ts +45 -0
- package/src/event-criteria.ts +141 -0
- package/src/event-gateway.ts +42 -0
- package/src/event-handler.ts +44 -0
- package/src/event-processor-builder.ts +246 -0
- package/src/event-processor.ts +9 -0
- package/src/event-sink.ts +23 -0
- package/src/event-source.ts +301 -0
- package/src/gateway.ts +144 -0
- package/src/handler-enhancer.ts +70 -0
- package/src/handler.ts +133 -0
- package/src/index.ts +356 -0
- package/src/intercepting-command-bus.ts +73 -0
- package/src/intercepting-event-bus.ts +29 -0
- package/src/intercepting-query-bus.ts +104 -0
- package/src/interceptor.ts +48 -0
- package/src/message-monitor-registry.ts +64 -0
- package/src/message-monitor.ts +68 -0
- package/src/message.ts +41 -0
- package/src/processing-state.ts +258 -0
- package/src/processor-configuration.ts +59 -0
- package/src/query-bus.ts +69 -0
- package/src/query-handler.ts +49 -0
- package/src/query-handling-module.ts +44 -0
- package/src/replay-token.ts +53 -0
- package/src/retrying-command-bus.ts +80 -0
- package/src/routing-strategy.ts +59 -0
- package/src/segment.ts +136 -0
- package/src/send.ts +44 -0
- package/src/serializer.ts +122 -0
- package/src/simple-command-bus.ts +59 -0
- package/src/simple-query-bus.ts +158 -0
- package/src/span-factory.ts +81 -0
- package/src/streaming-event-processor.ts +351 -0
- package/src/subscribing-event-processor.ts +169 -0
- package/src/subscription-query.ts +173 -0
- package/src/token-store.ts +211 -0
- package/src/tracing-command-bus.ts +52 -0
- package/src/tracing-handler-enhancer.ts +34 -0
- package/src/tracking-event-processor.ts +336 -0
- package/src/tracking-token.ts +231 -0
- package/src/transaction.ts +98 -0
- package/src/unit-of-work.ts +138 -0
- package/src/upcaster.ts +174 -0
- package/src/with-namespace.ts +75 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Tracking processor builder
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
/**
|
|
5
|
+
* Builder for a tracking event processor.
|
|
6
|
+
*
|
|
7
|
+
* Tracking processors poll the event store for new events, maintain
|
|
8
|
+
* position via a token store, and support replay/reset.
|
|
9
|
+
*
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const onCreated = eventHandler(CourseCreated, async (e) => { ... })
|
|
12
|
+
* const onCapChanged = eventHandler(CourseCapacityChanged, async (e) => { ... })
|
|
13
|
+
*
|
|
14
|
+
* trackingProcessor("course-projection")
|
|
15
|
+
* .eventHandlers(onCreated, onCapChanged)
|
|
16
|
+
* .onReset(async () => courseViews.clear())
|
|
17
|
+
* .batchSize(50)
|
|
18
|
+
* .build()
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* NOTE: Pooled streaming processor support is deferred to a follow-up
|
|
22
|
+
* research phase exploring how that model should fit Node/Bun runtime
|
|
23
|
+
* semantics, where worker threads are not reservable the same way as JVM
|
|
24
|
+
* threads.
|
|
25
|
+
*/
|
|
26
|
+
export function trackingProcessor(name) {
|
|
27
|
+
return new TrackingProcessorBuilder(name);
|
|
28
|
+
}
|
|
29
|
+
export class TrackingProcessorBuilder {
|
|
30
|
+
_name;
|
|
31
|
+
_eventHandlers = [];
|
|
32
|
+
_onReset;
|
|
33
|
+
_batchSize;
|
|
34
|
+
_pollingIntervalMs;
|
|
35
|
+
_tokenStore;
|
|
36
|
+
_unitOfWorkRunner;
|
|
37
|
+
_errorHandler;
|
|
38
|
+
_deadLetterQueue;
|
|
39
|
+
_initialSegmentCount;
|
|
40
|
+
_claimExtensionThresholdMs;
|
|
41
|
+
_tokenClaimIntervalMs;
|
|
42
|
+
constructor(name) {
|
|
43
|
+
this._name = name;
|
|
44
|
+
}
|
|
45
|
+
/** Register one or more singular event handlers on this processor. */
|
|
46
|
+
eventHandlers(...handlers) {
|
|
47
|
+
this._eventHandlers.push(...handlers);
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
/** Register a callback fired when the processor is reset (clears view state for replay). */
|
|
51
|
+
onReset(fn) {
|
|
52
|
+
this._onReset = fn;
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
/** Events per batch/transaction. Default: 100. */
|
|
56
|
+
batchSize(size) {
|
|
57
|
+
this._batchSize = size;
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
/** Polling interval in ms. Default: 500. */
|
|
61
|
+
pollingIntervalMs(ms) {
|
|
62
|
+
this._pollingIntervalMs = ms;
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
/** Override the token store for this processor. */
|
|
66
|
+
tokenStore(store) {
|
|
67
|
+
this._tokenStore = store;
|
|
68
|
+
return this;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Override the UnitOfWork runner for this processor. Compose with
|
|
72
|
+
* `transactionalUnitOfWorkFactory(runInUoW, txManager)` to attach
|
|
73
|
+
* transactional semantics.
|
|
74
|
+
*/
|
|
75
|
+
unitOfWorkRunner(runner) {
|
|
76
|
+
this._unitOfWorkRunner = runner;
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
/** Override the error handler for this processor. */
|
|
80
|
+
errorHandler(handler) {
|
|
81
|
+
this._errorHandler = handler;
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
/** Set a dead letter queue for this processor. */
|
|
85
|
+
deadLetterQueue(queue) {
|
|
86
|
+
this._deadLetterQueue = queue;
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
/** Number of segments to create on first startup. Default: 16 (Axon Framework parity). */
|
|
90
|
+
initialSegmentCount(count) {
|
|
91
|
+
this._initialSegmentCount = count;
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
/** @internal Build the processor configuration. */
|
|
95
|
+
build() {
|
|
96
|
+
return {
|
|
97
|
+
kind: "tracking",
|
|
98
|
+
name: this._name,
|
|
99
|
+
eventHandlers: this._eventHandlers,
|
|
100
|
+
batchSize: this._batchSize,
|
|
101
|
+
pollingIntervalMs: this._pollingIntervalMs,
|
|
102
|
+
tokenStore: this._tokenStore,
|
|
103
|
+
unitOfWorkRunner: this._unitOfWorkRunner,
|
|
104
|
+
errorHandler: this._errorHandler,
|
|
105
|
+
deadLetterQueue: this._deadLetterQueue,
|
|
106
|
+
initialSegmentCount: this._initialSegmentCount ?? 16,
|
|
107
|
+
claimExtensionThresholdMs: this._claimExtensionThresholdMs,
|
|
108
|
+
tokenClaimIntervalMs: this._tokenClaimIntervalMs,
|
|
109
|
+
onReset: this._onReset,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Subscribing processor builder
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
/**
|
|
117
|
+
* Builder for a subscribing event processor.
|
|
118
|
+
*
|
|
119
|
+
* Subscribing processors receive events pushed from the event source
|
|
120
|
+
* as they are appended. No token store, no position tracking, no replay.
|
|
121
|
+
*
|
|
122
|
+
* ```typescript
|
|
123
|
+
* const onNotification = eventHandler(NotificationRaised, async (e) => { ... })
|
|
124
|
+
*
|
|
125
|
+
* subscribingProcessor("notifications")
|
|
126
|
+
* .eventHandlers(onNotification)
|
|
127
|
+
* .build()
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* Subscribing processors do NOT support reset (`supportsReset() === false`),
|
|
131
|
+
* so there is no `.onReset(fn)` builder method here — that lives on
|
|
132
|
+
* `TrackingProcessorBuilder` only.
|
|
133
|
+
*/
|
|
134
|
+
export function subscribingProcessor(name) {
|
|
135
|
+
return new SubscribingProcessorBuilder(name);
|
|
136
|
+
}
|
|
137
|
+
export class SubscribingProcessorBuilder {
|
|
138
|
+
_name;
|
|
139
|
+
_eventHandlers = [];
|
|
140
|
+
_unitOfWorkRunner;
|
|
141
|
+
_errorHandler;
|
|
142
|
+
constructor(name) {
|
|
143
|
+
this._name = name;
|
|
144
|
+
}
|
|
145
|
+
/** Register one or more singular event handlers on this processor. */
|
|
146
|
+
eventHandlers(...handlers) {
|
|
147
|
+
this._eventHandlers.push(...handlers);
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Override the UnitOfWork runner for this processor. Compose with
|
|
152
|
+
* `transactionalUnitOfWorkFactory(runInUoW, txManager)` to attach
|
|
153
|
+
* transactional semantics.
|
|
154
|
+
*/
|
|
155
|
+
unitOfWorkRunner(runner) {
|
|
156
|
+
this._unitOfWorkRunner = runner;
|
|
157
|
+
return this;
|
|
158
|
+
}
|
|
159
|
+
/** Override the error handler for this processor. */
|
|
160
|
+
errorHandler(handler) {
|
|
161
|
+
this._errorHandler = handler;
|
|
162
|
+
return this;
|
|
163
|
+
}
|
|
164
|
+
/** @internal Build the processor configuration. */
|
|
165
|
+
build() {
|
|
166
|
+
return {
|
|
167
|
+
kind: "subscribing",
|
|
168
|
+
name: this._name,
|
|
169
|
+
eventHandlers: this._eventHandlers,
|
|
170
|
+
unitOfWorkRunner: this._unitOfWorkRunner,
|
|
171
|
+
errorHandler: this._errorHandler,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=event-processor-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-processor-builder.js","sourceRoot":"","sources":["../src/event-processor-builder.ts"],"names":[],"mappings":"AAmDA,8EAA8E;AAC9E,6BAA6B;AAC7B,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI,wBAAwB,CAAC,IAAI,CAAC,CAAA;AAC3C,CAAC;AAED,MAAM,OAAO,wBAAwB;IAClB,KAAK,CAAQ;IACb,cAAc,GAA6B,EAAE,CAAA;IACtD,QAAQ,CAA6B;IACrC,UAAU,CAAS;IACnB,kBAAkB,CAAS;IAC3B,WAAW,CAAa;IACxB,iBAAiB,CAAY;IAC7B,aAAa,CAA8B;IAC3C,gBAAgB,CAA2B;IAC3C,oBAAoB,CAAS;IAC7B,0BAA0B,CAAS;IACnC,qBAAqB,CAAS;IAEtC,YAAY,IAAY;QACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;IACnB,CAAC;IAED,sEAAsE;IACtE,aAAa,CAAC,GAAG,QAAkC;QACjD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAA;QACrC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,4FAA4F;IAC5F,OAAO,CAAC,EAA8B;QACpC,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAA;QAClB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,kDAAkD;IAClD,SAAS,CAAC,IAAY;QACpB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;QACtB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,4CAA4C;IAC5C,iBAAiB,CAAC,EAAU;QAC1B,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAA;QAC5B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,mDAAmD;IACnD,UAAU,CAAC,KAAiB;QAC1B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAA;QACxB,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;OAIG;IACH,gBAAgB,CAAC,MAAiB;QAChC,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAA;QAC/B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,qDAAqD;IACrD,YAAY,CAAC,OAAoC;QAC/C,IAAI,CAAC,aAAa,GAAG,OAAO,CAAA;QAC5B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,kDAAkD;IAClD,eAAe,CAAC,KAA+B;QAC7C,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAA;QAC7B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,0FAA0F;IAC1F,mBAAmB,CAAC,KAAa;QAC/B,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAA;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,mDAAmD;IACnD,KAAK;QACH,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,IAAI,CAAC,KAAK;YAChB,aAAa,EAAE,IAAI,CAAC,cAAc;YAClC,SAAS,EAAE,IAAI,CAAC,UAAU;YAC1B,iBAAiB,EAAE,IAAI,CAAC,kBAAkB;YAC1C,UAAU,EAAE,IAAI,CAAC,WAAW;YAC5B,gBAAgB,EAAE,IAAI,CAAC,iBAAiB;YACxC,YAAY,EAAE,IAAI,CAAC,aAAa;YAChC,eAAe,EAAE,IAAI,CAAC,gBAAgB;YACtC,mBAAmB,EAAE,IAAI,CAAC,oBAAoB,IAAI,EAAE;YACpD,yBAAyB,EAAE,IAAI,CAAC,0BAA0B;YAC1D,oBAAoB,EAAE,IAAI,CAAC,qBAAqB;YAChD,OAAO,EAAE,IAAI,CAAC,QAAQ;SACvB,CAAA;IACH,CAAC;CACF;AAED,8EAA8E;AAC9E,gCAAgC;AAChC,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,IAAI,2BAA2B,CAAC,IAAI,CAAC,CAAA;AAC9C,CAAC;AAED,MAAM,OAAO,2BAA2B;IACrB,KAAK,CAAQ;IACb,cAAc,GAA6B,EAAE,CAAA;IACtD,iBAAiB,CAAY;IAC7B,aAAa,CAA8B;IAEnD,YAAY,IAAY;QACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;IACnB,CAAC;IAED,sEAAsE;IACtE,aAAa,CAAC,GAAG,QAAkC;QACjD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAA;QACrC,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;OAIG;IACH,gBAAgB,CAAC,MAAiB;QAChC,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAA;QAC/B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,qDAAqD;IACrD,YAAY,CAAC,OAAoC;QAC/C,IAAI,CAAC,aAAa,GAAG,OAAO,CAAA;QAC5B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,mDAAmD;IACnD,KAAK;QACH,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,IAAI,CAAC,KAAK;YAChB,aAAa,EAAE,IAAI,CAAC,cAAc;YAClC,gBAAgB,EAAE,IAAI,CAAC,iBAAiB;YACxC,YAAY,EAAE,IAAI,CAAC,aAAa;SACjC,CAAA;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-processor.d.ts","sourceRoot":"","sources":["../src/event-processor.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,IAAI,IAAI,IAAI,CAAA;CACb"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-processor.js","sourceRoot":"","sources":["../src/event-processor.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { EventMessage } from "./message.js";
|
|
2
|
+
/**
|
|
3
|
+
* Publish-only abstraction for event publication.
|
|
4
|
+
*
|
|
5
|
+
* This is the messaging-level contract for publishing events. The EventGateway
|
|
6
|
+
* and command handlers use this to emit events without needing to know about
|
|
7
|
+
* event storage.
|
|
8
|
+
*
|
|
9
|
+
* Implementations include:
|
|
10
|
+
* - The EventStore (which persists AND publishes)
|
|
11
|
+
* - A simple EventBus (which only distributes to subscribers)
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
export interface EventSink {
|
|
15
|
+
/**
|
|
16
|
+
* Publish events. The events are distributed to any subscribed handlers.
|
|
17
|
+
*
|
|
18
|
+
* In an event sourcing context, this also persists the events to the
|
|
19
|
+
* underlying storage engine.
|
|
20
|
+
*/
|
|
21
|
+
publish(events: ReadonlyArray<EventMessage>): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=event-sink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-sink.d.ts","sourceRoot":"","sources":["../src/event-sink.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAEhD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IACH,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-sink.js","sourceRoot":"","sources":["../src/event-sink.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { EventMessage } from "./message.js";
|
|
2
|
+
import type { EventCriteria } from "./event-criteria.js";
|
|
3
|
+
import type { TrackingToken } from "./tracking-token.js";
|
|
4
|
+
/**
|
|
5
|
+
* An event with its global sequence position.
|
|
6
|
+
*/
|
|
7
|
+
export interface SequencedEvent {
|
|
8
|
+
readonly sequence: bigint;
|
|
9
|
+
readonly event: EventMessage;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Condition for opening a streaming event source.
|
|
13
|
+
* Defines the starting position and optional event criteria filter.
|
|
14
|
+
*/
|
|
15
|
+
export interface StreamingCondition {
|
|
16
|
+
/** Position to start streaming from. */
|
|
17
|
+
readonly position: bigint;
|
|
18
|
+
/** Optional criteria to filter events. When omitted, all events are delivered. */
|
|
19
|
+
readonly criteria?: EventCriteria;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A push-based message stream. Events are buffered internally and
|
|
23
|
+
* pulled via {@link next}. The stream notifies when events become
|
|
24
|
+
* available via {@link setCallback}.
|
|
25
|
+
*/
|
|
26
|
+
export interface MessageStream<M> {
|
|
27
|
+
/** Pull the next available item (non-blocking). */
|
|
28
|
+
next(): M | undefined;
|
|
29
|
+
/** Peek at the next item without consuming it. */
|
|
30
|
+
peek(): M | undefined;
|
|
31
|
+
/** Check if there are items ready to be pulled. */
|
|
32
|
+
hasNextAvailable(): boolean;
|
|
33
|
+
/** Whether the stream has been completed. */
|
|
34
|
+
isCompleted(): boolean;
|
|
35
|
+
/** The error that caused the stream to fail, if any. */
|
|
36
|
+
error(): Error | undefined;
|
|
37
|
+
/** Register a callback for when items become available. */
|
|
38
|
+
setCallback(callback: () => void): void;
|
|
39
|
+
/** Close the stream and release resources. */
|
|
40
|
+
close(): void;
|
|
41
|
+
/** Transform each item. */
|
|
42
|
+
map<R>(mapper: (item: M) => R): MessageStream<R>;
|
|
43
|
+
/** Filter items by predicate. */
|
|
44
|
+
filter(predicate: (item: M) => boolean): MessageStream<M>;
|
|
45
|
+
/** Recover from stream errors by providing a continuation stream. */
|
|
46
|
+
onErrorContinue(recovery: (error: Error) => MessageStream<M>): MessageStream<M>;
|
|
47
|
+
/** Reduce all items to a single value. Resolves when the stream completes. */
|
|
48
|
+
reduce<R>(identity: R, accumulator: (acc: R, item: M) => R): Promise<R>;
|
|
49
|
+
/** Concatenate another stream after this one completes. */
|
|
50
|
+
concatWith(other: MessageStream<M>): MessageStream<M>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Creates a MessageStream that wraps a source with transformation support.
|
|
54
|
+
* Used by event store implementations to provide stream instances.
|
|
55
|
+
*/
|
|
56
|
+
export declare function createMessageStream<M>(source: {
|
|
57
|
+
next(): M | undefined;
|
|
58
|
+
peek(): M | undefined;
|
|
59
|
+
hasNextAvailable(): boolean;
|
|
60
|
+
isCompleted(): boolean;
|
|
61
|
+
error(): Error | undefined;
|
|
62
|
+
setCallback(callback: () => void): void;
|
|
63
|
+
close(): void;
|
|
64
|
+
}): MessageStream<M>;
|
|
65
|
+
/**
|
|
66
|
+
* Creates a completed empty MessageStream.
|
|
67
|
+
*/
|
|
68
|
+
export declare function emptyMessageStream<M>(): MessageStream<M>;
|
|
69
|
+
/**
|
|
70
|
+
* Creates a MessageStream that immediately fails with the given error.
|
|
71
|
+
*/
|
|
72
|
+
export declare function failedMessageStream<M>(error: Error): MessageStream<M>;
|
|
73
|
+
/**
|
|
74
|
+
* A source of events that can be opened as an infinite stream.
|
|
75
|
+
*/
|
|
76
|
+
export interface StreamableEventSource {
|
|
77
|
+
/**
|
|
78
|
+
* Open an infinite event stream starting from the given condition.
|
|
79
|
+
*/
|
|
80
|
+
open(condition: StreamingCondition): MessageStream<SequencedEvent>;
|
|
81
|
+
/**
|
|
82
|
+
* Get the token representing the beginning of the event stream.
|
|
83
|
+
* A processor starting from this token will read all events.
|
|
84
|
+
*/
|
|
85
|
+
firstToken(): Promise<TrackingToken>;
|
|
86
|
+
/**
|
|
87
|
+
* Get the token representing the current tail of the event stream.
|
|
88
|
+
* A processor starting from this token will only see new events.
|
|
89
|
+
*/
|
|
90
|
+
latestToken(): Promise<TrackingToken>;
|
|
91
|
+
/**
|
|
92
|
+
* Get the current head position — the sequence of the next event
|
|
93
|
+
* to be appended. Convenience method equivalent to
|
|
94
|
+
* {@code (await latestToken()).position()}.
|
|
95
|
+
*/
|
|
96
|
+
getHeadPosition(): Promise<bigint>;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=event-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-source.d.ts","sourceRoot":"","sources":["../src/event-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a MessageStream that wraps a source with transformation support.
|
|
3
|
+
* Used by event store implementations to provide stream instances.
|
|
4
|
+
*/
|
|
5
|
+
export function createMessageStream(source) {
|
|
6
|
+
const stream = {
|
|
7
|
+
...source,
|
|
8
|
+
map(mapper) {
|
|
9
|
+
return createMappedStream(stream, mapper);
|
|
10
|
+
},
|
|
11
|
+
filter(predicate) {
|
|
12
|
+
return createFilteredStream(stream, predicate);
|
|
13
|
+
},
|
|
14
|
+
onErrorContinue(recovery) {
|
|
15
|
+
return createErrorRecoveryStream(stream, recovery);
|
|
16
|
+
},
|
|
17
|
+
reduce(identity, accumulator) {
|
|
18
|
+
return reduceStream(stream, identity, accumulator);
|
|
19
|
+
},
|
|
20
|
+
concatWith(other) {
|
|
21
|
+
return createConcatStream(stream, other);
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
return stream;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Creates a completed empty MessageStream.
|
|
28
|
+
*/
|
|
29
|
+
export function emptyMessageStream() {
|
|
30
|
+
return createMessageStream({
|
|
31
|
+
next: () => undefined,
|
|
32
|
+
peek: () => undefined,
|
|
33
|
+
hasNextAvailable: () => false,
|
|
34
|
+
isCompleted: () => true,
|
|
35
|
+
error: () => undefined,
|
|
36
|
+
setCallback: () => { },
|
|
37
|
+
close: () => { },
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Creates a MessageStream that immediately fails with the given error.
|
|
42
|
+
*/
|
|
43
|
+
export function failedMessageStream(error) {
|
|
44
|
+
return createMessageStream({
|
|
45
|
+
next: () => undefined,
|
|
46
|
+
peek: () => undefined,
|
|
47
|
+
hasNextAvailable: () => false,
|
|
48
|
+
isCompleted: () => true,
|
|
49
|
+
error: () => error,
|
|
50
|
+
setCallback: () => { },
|
|
51
|
+
close: () => { },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Stream transformations
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
function createMappedStream(source, mapper) {
|
|
58
|
+
return createMessageStream({
|
|
59
|
+
next() {
|
|
60
|
+
const item = source.next();
|
|
61
|
+
return item !== undefined ? mapper(item) : undefined;
|
|
62
|
+
},
|
|
63
|
+
peek() {
|
|
64
|
+
const item = source.peek();
|
|
65
|
+
return item !== undefined ? mapper(item) : undefined;
|
|
66
|
+
},
|
|
67
|
+
hasNextAvailable: () => source.hasNextAvailable(),
|
|
68
|
+
isCompleted: () => source.isCompleted(),
|
|
69
|
+
error: () => source.error(),
|
|
70
|
+
setCallback: (cb) => source.setCallback(cb),
|
|
71
|
+
close: () => source.close(),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function createFilteredStream(source, predicate) {
|
|
75
|
+
let buffered;
|
|
76
|
+
function advance() {
|
|
77
|
+
while (true) {
|
|
78
|
+
const item = source.next();
|
|
79
|
+
if (item === undefined)
|
|
80
|
+
return undefined;
|
|
81
|
+
if (predicate(item))
|
|
82
|
+
return item;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return createMessageStream({
|
|
86
|
+
next() {
|
|
87
|
+
if (buffered !== undefined) {
|
|
88
|
+
const item = buffered;
|
|
89
|
+
buffered = undefined;
|
|
90
|
+
return item;
|
|
91
|
+
}
|
|
92
|
+
return advance();
|
|
93
|
+
},
|
|
94
|
+
peek() {
|
|
95
|
+
if (buffered !== undefined)
|
|
96
|
+
return buffered;
|
|
97
|
+
buffered = advance();
|
|
98
|
+
return buffered;
|
|
99
|
+
},
|
|
100
|
+
hasNextAvailable() {
|
|
101
|
+
if (buffered !== undefined)
|
|
102
|
+
return true;
|
|
103
|
+
buffered = advance();
|
|
104
|
+
return buffered !== undefined;
|
|
105
|
+
},
|
|
106
|
+
isCompleted: () => source.isCompleted() && buffered === undefined,
|
|
107
|
+
error: () => source.error(),
|
|
108
|
+
setCallback: (cb) => source.setCallback(cb),
|
|
109
|
+
close: () => source.close(),
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function createErrorRecoveryStream(source, recovery) {
|
|
113
|
+
let current = source;
|
|
114
|
+
let recovered = false;
|
|
115
|
+
function checkRecovery() {
|
|
116
|
+
if (!recovered && current.error()) {
|
|
117
|
+
current = recovery(current.error());
|
|
118
|
+
recovered = true;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return createMessageStream({
|
|
122
|
+
next() { checkRecovery(); return current.next(); },
|
|
123
|
+
peek() { checkRecovery(); return current.peek(); },
|
|
124
|
+
hasNextAvailable() { checkRecovery(); return current.hasNextAvailable(); },
|
|
125
|
+
isCompleted() { checkRecovery(); return current.isCompleted(); },
|
|
126
|
+
error() { return recovered ? current.error() : undefined; },
|
|
127
|
+
setCallback(cb) { current.setCallback(cb); },
|
|
128
|
+
close() { current.close(); },
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function createConcatStream(first, second) {
|
|
132
|
+
let usingFirst = true;
|
|
133
|
+
function current() {
|
|
134
|
+
if (usingFirst && first.isCompleted() && !first.hasNextAvailable()) {
|
|
135
|
+
usingFirst = false;
|
|
136
|
+
}
|
|
137
|
+
return usingFirst ? first : second;
|
|
138
|
+
}
|
|
139
|
+
return createMessageStream({
|
|
140
|
+
next() { return current().next(); },
|
|
141
|
+
peek() { return current().peek(); },
|
|
142
|
+
hasNextAvailable() { return current().hasNextAvailable(); },
|
|
143
|
+
isCompleted() { return current().isCompleted(); },
|
|
144
|
+
error() { return current().error(); },
|
|
145
|
+
setCallback(cb) {
|
|
146
|
+
if (usingFirst) {
|
|
147
|
+
first.setCallback(() => {
|
|
148
|
+
if (first.isCompleted() && !first.hasNextAvailable()) {
|
|
149
|
+
usingFirst = false;
|
|
150
|
+
second.setCallback(cb);
|
|
151
|
+
cb();
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
cb();
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
second.setCallback(cb);
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
close() { first.close(); second.close(); },
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
async function reduceStream(stream, identity, accumulator) {
|
|
166
|
+
let result = identity;
|
|
167
|
+
return new Promise((resolve, reject) => {
|
|
168
|
+
function drain() {
|
|
169
|
+
while (true) {
|
|
170
|
+
const item = stream.next();
|
|
171
|
+
if (item !== undefined) {
|
|
172
|
+
result = accumulator(result, item);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (stream.error()) {
|
|
176
|
+
reject(stream.error());
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (stream.isCompleted()) {
|
|
180
|
+
resolve(result);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
// Wait for more items
|
|
184
|
+
stream.setCallback(drain);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
drain();
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=event-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-source.js","sourceRoot":"","sources":["../src/event-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type Metadata } from "@kronos-ts/common";
|
|
2
|
+
import type { CommandBus } from "./command-bus.js";
|
|
3
|
+
import type { QueryBus } from "./query-bus.js";
|
|
4
|
+
import type { CommandDescriptor, QueryDescriptor } from "./descriptor.js";
|
|
5
|
+
import type { SubscriptionQueryResult } from "./subscription-query.js";
|
|
6
|
+
import { type UoWRunner } from "./unit-of-work.js";
|
|
7
|
+
import type { z } from "zod";
|
|
8
|
+
/**
|
|
9
|
+
* Infers the result type from a descriptor's `result` schema.
|
|
10
|
+
* If no result schema, returns `unknown`.
|
|
11
|
+
*/
|
|
12
|
+
type InferResult<R extends z.ZodType | undefined> = R extends z.ZodType ? z.infer<R> : unknown;
|
|
13
|
+
/**
|
|
14
|
+
* User-facing command gateway. Wraps payloads into proper command messages
|
|
15
|
+
* and delegates to the command bus.
|
|
16
|
+
*
|
|
17
|
+
* When the command descriptor has a `result` schema, the return type is inferred:
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const CreateCourse = command({
|
|
20
|
+
* name: qn("university", "CreateCourse"),
|
|
21
|
+
* payload: z.object({ courseId: z.string() }),
|
|
22
|
+
* result: z.object({ id: z.string() }),
|
|
23
|
+
* })
|
|
24
|
+
*
|
|
25
|
+
* const result = await gateway.send(CreateCourse, { courseId: "cs-101" })
|
|
26
|
+
* // ^ { id: string } — inferred from descriptor
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export interface CommandGateway {
|
|
30
|
+
send<P extends z.ZodType, R extends z.ZodType | undefined = undefined>(descriptor: CommandDescriptor<P, R>, payload: z.infer<P>, metadata?: Metadata): Promise<InferResult<R>>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* User-facing query gateway. Wraps payloads into proper query messages
|
|
34
|
+
* and delegates to the query bus.
|
|
35
|
+
*
|
|
36
|
+
* When the query descriptor has a `result` schema, the return type is inferred:
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const GetCourse = query({
|
|
39
|
+
* name: qn("university", "GetCourseView"),
|
|
40
|
+
* payload: z.object({ courseId: z.string() }),
|
|
41
|
+
* result: z.object({ courseId: z.string(), name: z.string() }),
|
|
42
|
+
* })
|
|
43
|
+
*
|
|
44
|
+
* const course = await gateway.query(GetCourse, { courseId: "cs-101" })
|
|
45
|
+
* // ^ { courseId: string, name: string } — inferred from descriptor
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export interface QueryGateway {
|
|
49
|
+
query<P extends z.ZodType, R extends z.ZodType | undefined = undefined>(descriptor: QueryDescriptor<P, R>, payload: z.infer<P>, metadata?: Metadata): Promise<InferResult<R>>;
|
|
50
|
+
subscriptionQuery<P extends z.ZodType, R extends z.ZodType | undefined = undefined>(descriptor: QueryDescriptor<P, R>, payload: z.infer<P>, metadata?: Metadata): SubscriptionQueryResult;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Creates a command gateway backed by a command bus.
|
|
54
|
+
*
|
|
55
|
+
* Plan 03-04 (CTX-04 / D-34): the optional `unitOfWorkRunner` lets the
|
|
56
|
+
* configurer inject a transactional wrapper (`transactionalUnitOfWorkFactory`)
|
|
57
|
+
* around the dispatch boundary. Defaults to `runInNewUoW` — preserves the
|
|
58
|
+
* Plan 03-01 contract that every gateway call starts a fresh UoW.
|
|
59
|
+
*/
|
|
60
|
+
export declare function createCommandGateway(bus: CommandBus, unitOfWorkRunner?: UoWRunner): CommandGateway;
|
|
61
|
+
/**
|
|
62
|
+
* Creates a query gateway backed by a query bus.
|
|
63
|
+
*
|
|
64
|
+
* See `createCommandGateway` for the `unitOfWorkRunner` injection contract.
|
|
65
|
+
*/
|
|
66
|
+
export declare function createQueryGateway(bus: QueryBus, unitOfWorkRunner?: UoWRunner): QueryGateway;
|
|
67
|
+
export {};
|
|
68
|
+
//# sourceMappingURL=gateway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,QAAQ,EACd,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACzE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAE5B;;;GAGG;AACH,KAAK,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS,IAC9C,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAA;AAE5C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,SAAS,EACnE,UAAU,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,EACnC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EACnB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;CAC3B;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,SAAS,EACpE,UAAU,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACjC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EACnB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;IAE1B,iBAAiB,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,SAAS,EAChF,UAAU,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACjC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EACnB,QAAQ,CAAC,EAAE,QAAQ,GAClB,uBAAuB,CAAA;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,UAAU,EACf,gBAAgB,GAAE,SAAuB,GACxC,cAAc,CAoBhB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,QAAQ,EACb,gBAAgB,GAAE,SAAuB,GACxC,YAAY,CA6Bd"}
|