@rotorsoft/act 0.8.0 → 0.10.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/.tsbuildinfo +1 -1
- package/dist/@types/act-builder.d.ts +37 -220
- package/dist/@types/act-builder.d.ts.map +1 -1
- package/dist/@types/act.d.ts +2 -2
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/index.d.ts +2 -0
- package/dist/@types/index.d.ts.map +1 -1
- package/dist/@types/merge.d.ts +38 -0
- package/dist/@types/merge.d.ts.map +1 -0
- package/dist/@types/projection-builder.d.ts +123 -0
- package/dist/@types/projection-builder.d.ts.map +1 -0
- package/dist/@types/slice-builder.d.ts +107 -0
- package/dist/@types/slice-builder.d.ts.map +1 -0
- package/dist/@types/state-builder.d.ts +26 -21
- package/dist/@types/state-builder.d.ts.map +1 -1
- package/dist/@types/types/action.d.ts +46 -1
- package/dist/@types/types/action.d.ts.map +1 -1
- package/dist/@types/types/reaction.d.ts +1 -1
- package/dist/@types/types/reaction.d.ts.map +1 -1
- package/dist/@types/utils.d.ts +1 -1
- package/dist/index.cjs +216 -71
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +212 -71
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module act-builder
|
|
3
|
+
* @category Builders
|
|
4
|
+
*
|
|
5
|
+
* Fluent builder for composing event-sourced applications.
|
|
6
|
+
*/
|
|
1
7
|
import { Act } from "./act.js";
|
|
2
|
-
import
|
|
8
|
+
import { type Projection } from "./projection-builder.js";
|
|
9
|
+
import { type Slice } from "./slice-builder.js";
|
|
10
|
+
import type { Committed, Dispatcher, EventRegister, ReactionOptions, ReactionResolver, Registry, Schema, SchemaRegister, Schemas, Snapshot, State } from "./types/index.js";
|
|
3
11
|
/**
|
|
4
12
|
* Fluent builder interface for composing event-sourced applications.
|
|
5
13
|
*
|
|
6
14
|
* Provides a chainable API for:
|
|
7
|
-
* - Registering states via `.with()`
|
|
15
|
+
* - Registering states or slices via `.with()`
|
|
8
16
|
* - Defining event reactions via `.on()` → `.do()` → `.to()` or `.void()`
|
|
9
17
|
* - Building the orchestrator via `.build()`
|
|
10
18
|
*
|
|
@@ -15,43 +23,33 @@ import type { EventRegister, ReactionHandler, ReactionOptions, ReactionResolver,
|
|
|
15
23
|
* @see {@link act} for usage examples
|
|
16
24
|
* @see {@link Act} for the built orchestrator API
|
|
17
25
|
*/
|
|
18
|
-
export type ActBuilder<S extends SchemaRegister<A>, E extends Schemas, A extends Schemas, M extends Record<string, Schema> =
|
|
26
|
+
export type ActBuilder<S extends SchemaRegister<A>, E extends Schemas, A extends Schemas, M extends Record<string, Schema> = {}> = {
|
|
19
27
|
/**
|
|
20
|
-
* Registers a state definition with the builder.
|
|
21
|
-
*
|
|
22
|
-
* States define aggregates that process actions and emit events. Each state
|
|
23
|
-
* registration adds its actions and events to the orchestrator's registry.
|
|
24
|
-
* State names, action names, and event names must be unique across the application.
|
|
28
|
+
* Registers a state definition or a slice with the builder.
|
|
25
29
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* @returns The builder with updated type information for chaining
|
|
30
|
+
* When receiving a State, it registers the state's actions and events.
|
|
31
|
+
* When receiving a Slice, it merges all the slice's states and reactions.
|
|
32
|
+
* State names, action names, and event names must be unique across the application
|
|
33
|
+
* (partial states with the same name are merged automatically).
|
|
31
34
|
*
|
|
32
|
-
* @throws {Error} If
|
|
35
|
+
* @throws {Error} If duplicate action or event names are detected
|
|
33
36
|
*
|
|
34
|
-
* @example Register
|
|
37
|
+
* @example Register a state
|
|
35
38
|
* ```typescript
|
|
36
|
-
* const app = act()
|
|
37
|
-
* .with(Counter)
|
|
38
|
-
* .build();
|
|
39
|
+
* const app = act().with(Counter).build();
|
|
39
40
|
* ```
|
|
40
41
|
*
|
|
41
|
-
* @example Register
|
|
42
|
+
* @example Register a slice
|
|
42
43
|
* ```typescript
|
|
43
|
-
* const
|
|
44
|
-
*
|
|
45
|
-
* .with(Order)
|
|
46
|
-
* .with(Inventory)
|
|
47
|
-
* .build();
|
|
44
|
+
* const CounterSlice = slice().with(Counter).on("Incremented").do(log).void().build();
|
|
45
|
+
* const app = act().with(CounterSlice).build();
|
|
48
46
|
* ```
|
|
49
47
|
*/
|
|
50
|
-
with: <SX extends Schema, EX extends Schemas, AX extends Schemas, NX extends string = string>(state: State<SX, EX, AX, NX>) => ActBuilder<S & {
|
|
48
|
+
with: (<SX extends Schema, EX extends Schemas, AX extends Schemas, NX extends string = string>(state: State<SX, EX, AX, NX>) => ActBuilder<S & {
|
|
51
49
|
[K in keyof AX]: SX;
|
|
52
50
|
}, E & EX, A & AX, M & {
|
|
53
51
|
[K in NX]: SX;
|
|
54
|
-
}
|
|
52
|
+
}>) & (<SX extends SchemaRegister<AX>, EX extends Schemas, AX extends Schemas, MX extends Record<string, Schema>>(slice: Slice<SX, EX, AX, MX>) => ActBuilder<S & SX, E & EX, A & AX, M & MX>) & (<EX extends Schemas>(projection: Projection<EX>) => ActBuilder<S, E & EX, A, M>);
|
|
55
53
|
/**
|
|
56
54
|
* Begins defining a reaction to a specific event.
|
|
57
55
|
*
|
|
@@ -89,92 +87,19 @@ export type ActBuilder<S extends SchemaRegister<A>, E extends Schemas, A extends
|
|
|
89
87
|
* @param options.blockOnError - Block this stream if handler fails (default: true)
|
|
90
88
|
* @param options.maxRetries - Maximum retry attempts on failure (default: 3)
|
|
91
89
|
* @returns The builder with `.to()` and `.void()` methods for routing configuration
|
|
92
|
-
*
|
|
93
|
-
* @example Side effect only (void)
|
|
94
|
-
* ```typescript
|
|
95
|
-
* .on("UserCreated")
|
|
96
|
-
* .do(async (event) => {
|
|
97
|
-
* await analytics.track("user_created", event.data);
|
|
98
|
-
* })
|
|
99
|
-
* .void()
|
|
100
|
-
* ```
|
|
101
|
-
*
|
|
102
|
-
* @example Trigger another action
|
|
103
|
-
* ```typescript
|
|
104
|
-
* .on("OrderPlaced")
|
|
105
|
-
* .do(async (event) => {
|
|
106
|
-
* return ["reduceStock", { amount: event.data.items.length }];
|
|
107
|
-
* })
|
|
108
|
-
* .to("inventory-1")
|
|
109
|
-
* ```
|
|
110
|
-
*
|
|
111
|
-
* @example With retry configuration
|
|
112
|
-
* ```typescript
|
|
113
|
-
* .on("PaymentProcessed")
|
|
114
|
-
* .do(async (event) => {
|
|
115
|
-
* await externalAPI.notify(event.data);
|
|
116
|
-
* }, {
|
|
117
|
-
* blockOnError: false, // Don't block on failure
|
|
118
|
-
* maxRetries: 5 // Retry up to 5 times
|
|
119
|
-
* })
|
|
120
|
-
* .void()
|
|
121
|
-
* ```
|
|
122
90
|
*/
|
|
123
|
-
do: (handler:
|
|
91
|
+
do: (handler: (event: Committed<E, K>, stream: string, app: Dispatcher<A>) => Promise<Snapshot<E, Schema> | void>, options?: Partial<ReactionOptions>) => ActBuilder<S, E, A, M> & {
|
|
124
92
|
/**
|
|
125
93
|
* Routes the reaction to a specific target stream.
|
|
126
94
|
*
|
|
127
|
-
* Use this when the reaction triggers an action on a specific state instance.
|
|
128
|
-
* You can provide either a static stream name (string) or a resolver function
|
|
129
|
-
* that dynamically determines the target based on the event.
|
|
130
|
-
*
|
|
131
95
|
* @param resolver - Target stream name (string) or resolver function
|
|
132
96
|
* @returns The builder for chaining
|
|
133
|
-
*
|
|
134
|
-
* @example Static target stream
|
|
135
|
-
* ```typescript
|
|
136
|
-
* .on("OrderPlaced")
|
|
137
|
-
* .do(async (event) => ["reduceStock", { amount: 10 }])
|
|
138
|
-
* .to("inventory-main")
|
|
139
|
-
* ```
|
|
140
|
-
*
|
|
141
|
-
* @example Dynamic target based on event data
|
|
142
|
-
* ```typescript
|
|
143
|
-
* .on("OrderPlaced")
|
|
144
|
-
* .do(async (event) => ["reduceStock", { amount: 10 }])
|
|
145
|
-
* .to((event) => ({
|
|
146
|
-
* target: `inventory-${event.data.warehouseId}`
|
|
147
|
-
* }))
|
|
148
|
-
* ```
|
|
149
|
-
*
|
|
150
|
-
* @example Source and target routing
|
|
151
|
-
* ```typescript
|
|
152
|
-
* .on("UserLoggedIn")
|
|
153
|
-
* .do(async (event) => ["incrementCount", {}])
|
|
154
|
-
* .to(({ stream }) => ({
|
|
155
|
-
* source: stream, // React to events from this user stream
|
|
156
|
-
* target: `stats-${stream}` // Update corresponding stats stream
|
|
157
|
-
* }))
|
|
158
|
-
* ```
|
|
159
97
|
*/
|
|
160
98
|
to: (resolver: ReactionResolver<E, K> | string) => ActBuilder<S, E, A, M>;
|
|
161
99
|
/**
|
|
162
100
|
* Marks the reaction as void (side-effect only, no target stream).
|
|
163
101
|
*
|
|
164
|
-
* Use this when the reaction doesn't trigger any actions - it only performs
|
|
165
|
-
* side effects like logging, sending notifications, or updating external systems.
|
|
166
|
-
*
|
|
167
102
|
* @returns The builder for chaining
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```typescript
|
|
171
|
-
* .on("UserCreated")
|
|
172
|
-
* .do(async (event) => {
|
|
173
|
-
* await sendEmail(event.data.email, "Welcome!");
|
|
174
|
-
* await logger.info("User created", event.data);
|
|
175
|
-
* })
|
|
176
|
-
* .void() // No target stream
|
|
177
|
-
* ```
|
|
178
103
|
*/
|
|
179
104
|
void: () => ActBuilder<S, E, A, M>;
|
|
180
105
|
};
|
|
@@ -182,35 +107,14 @@ export type ActBuilder<S extends SchemaRegister<A>, E extends Schemas, A extends
|
|
|
182
107
|
/**
|
|
183
108
|
* Builds and returns the Act orchestrator instance.
|
|
184
109
|
*
|
|
185
|
-
* This finalizes the builder configuration and creates the orchestrator that
|
|
186
|
-
* can execute actions, load state, and process reactions.
|
|
187
|
-
*
|
|
188
110
|
* @param drainLimit - Deprecated parameter, no longer used
|
|
189
111
|
* @returns The Act orchestrator instance
|
|
190
112
|
*
|
|
191
|
-
* @example
|
|
192
|
-
* ```typescript
|
|
193
|
-
* const app = act()
|
|
194
|
-
* .with(Counter)
|
|
195
|
-
* .with(User)
|
|
196
|
-
* .on("UserCreated")
|
|
197
|
-
* .do(sendWelcomeEmail)
|
|
198
|
-
* .void()
|
|
199
|
-
* .build();
|
|
200
|
-
*
|
|
201
|
-
* // Now use the app
|
|
202
|
-
* await app.do("createUser", target, payload);
|
|
203
|
-
* await app.drain();
|
|
204
|
-
* ```
|
|
205
|
-
*
|
|
206
113
|
* @see {@link Act} for available orchestrator methods
|
|
207
114
|
*/
|
|
208
115
|
build: (drainLimit?: number) => Act<S, E, A, M>;
|
|
209
116
|
/**
|
|
210
117
|
* The registered event schemas and their reaction maps.
|
|
211
|
-
*
|
|
212
|
-
* This is an internal registry maintained by the builder. Generally, you don't
|
|
213
|
-
* need to access this directly.
|
|
214
118
|
*/
|
|
215
119
|
readonly events: EventRegister<E>;
|
|
216
120
|
};
|
|
@@ -223,8 +127,8 @@ export type ActBuilder<S extends SchemaRegister<A>, E extends Schemas, A extends
|
|
|
223
127
|
* - Processing reactions (event handlers)
|
|
224
128
|
* - Coordinating event-driven workflows
|
|
225
129
|
*
|
|
226
|
-
* Use the fluent API to register states with `.with()`, define event
|
|
227
|
-
* and build the orchestrator with `.build()`.
|
|
130
|
+
* Use the fluent API to register states or slices with `.with()`, define event
|
|
131
|
+
* reactions with `.on()`, and build the orchestrator with `.build()`.
|
|
228
132
|
*
|
|
229
133
|
* @template S - State schema register type
|
|
230
134
|
* @template E - Event schemas type
|
|
@@ -240,122 +144,35 @@ export type ActBuilder<S extends SchemaRegister<A>, E extends Schemas, A extends
|
|
|
240
144
|
* .init(() => ({ count: 0 }))
|
|
241
145
|
* .emits({ Incremented: z.object({ amount: z.number() }) })
|
|
242
146
|
* .patch({ Incremented: (event, state) => ({ count: state.count + event.data.amount }) })
|
|
243
|
-
* .on(
|
|
147
|
+
* .on({ increment: z.object({ by: z.number() }) })
|
|
244
148
|
* .emit((action) => ["Incremented", { amount: action.by }])
|
|
245
149
|
* .build();
|
|
246
150
|
*
|
|
247
151
|
* const app = act()
|
|
248
152
|
* .with(Counter)
|
|
249
153
|
* .build();
|
|
250
|
-
*
|
|
251
|
-
* // Execute action
|
|
252
|
-
* await app.do("increment",
|
|
253
|
-
* { stream: "counter1", actor: { id: "user1", name: "Alice" } },
|
|
254
|
-
* { by: 5 }
|
|
255
|
-
* );
|
|
256
|
-
*
|
|
257
|
-
* // Load current state
|
|
258
|
-
* const snapshot = await app.load(Counter, "counter1");
|
|
259
|
-
* console.log(snapshot.state.count); // 5
|
|
260
|
-
* ```
|
|
261
|
-
*
|
|
262
|
-
* @example Application with reactions
|
|
263
|
-
* ```typescript
|
|
264
|
-
* const User = state("User", z.object({ name: z.string(), email: z.string() }))
|
|
265
|
-
* .init((data) => data)
|
|
266
|
-
* .emits({ UserCreated: z.object({ name: z.string(), email: z.string() }) })
|
|
267
|
-
* .patch({ UserCreated: (event) => event.data })
|
|
268
|
-
* .on("createUser", z.object({ name: z.string(), email: z.string() }))
|
|
269
|
-
* .emit((action) => ["UserCreated", action])
|
|
270
|
-
* .build();
|
|
271
|
-
*
|
|
272
|
-
* const app = act()
|
|
273
|
-
* .with(User)
|
|
274
|
-
* .on("UserCreated")
|
|
275
|
-
* .do(async (event) => {
|
|
276
|
-
* // Send welcome email
|
|
277
|
-
* await sendEmail(event.data.email, "Welcome!");
|
|
278
|
-
* logger.info(`Sent welcome email to ${event.data.email}`);
|
|
279
|
-
* })
|
|
280
|
-
* .void() // No target stream, just side effects
|
|
281
|
-
* .build();
|
|
282
|
-
*
|
|
283
|
-
* // Create user (triggers email sending via reaction)
|
|
284
|
-
* await app.do("createUser",
|
|
285
|
-
* { stream: "user-123", actor: { id: "admin", name: "Admin" } },
|
|
286
|
-
* { name: "Alice", email: "alice@example.com" }
|
|
287
|
-
* );
|
|
288
|
-
*
|
|
289
|
-
* // Process reactions
|
|
290
|
-
* await app.drain();
|
|
291
|
-
* ```
|
|
292
|
-
*
|
|
293
|
-
* @example Multi-state application with event correlation
|
|
294
|
-
* ```typescript
|
|
295
|
-
* const Order = state("Order", z.object({ items: z.array(z.string()), total: z.number() }))
|
|
296
|
-
* .init((data) => data)
|
|
297
|
-
* .emits({ OrderPlaced: z.object({ items: z.array(z.string()), total: z.number() }) })
|
|
298
|
-
* .patch({ OrderPlaced: (event) => event.data })
|
|
299
|
-
* .on("placeOrder", z.object({ items: z.array(z.string()), total: z.number() }))
|
|
300
|
-
* .emit((action) => ["OrderPlaced", action])
|
|
301
|
-
* .build();
|
|
302
|
-
*
|
|
303
|
-
* const Inventory = state("Inventory", z.object({ stock: z.number() }))
|
|
304
|
-
* .init(() => ({ stock: 100 }))
|
|
305
|
-
* .emits({ StockReduced: z.object({ amount: z.number() }) })
|
|
306
|
-
* .patch({ StockReduced: (event, state) => ({ stock: state.stock - event.data.amount }) })
|
|
307
|
-
* .on("reduceStock", z.object({ amount: z.number() }))
|
|
308
|
-
* .emit((action) => ["StockReduced", { amount: action.amount }])
|
|
309
|
-
* .build();
|
|
310
|
-
*
|
|
311
|
-
* const app = act()
|
|
312
|
-
* .with(Order)
|
|
313
|
-
* .with(Inventory)
|
|
314
|
-
* .on("OrderPlaced")
|
|
315
|
-
* .do(async (event) => {
|
|
316
|
-
* // Reduce inventory for each item
|
|
317
|
-
* return ["reduceStock", { amount: event.data.items.length }];
|
|
318
|
-
* })
|
|
319
|
-
* .to("inventory-1") // Target specific inventory stream
|
|
320
|
-
* .build();
|
|
321
|
-
*
|
|
322
|
-
* await app.do("placeOrder",
|
|
323
|
-
* { stream: "order-1", actor: { id: "user1", name: "Alice" } },
|
|
324
|
-
* { items: ["item1", "item2"], total: 100 }
|
|
325
|
-
* );
|
|
326
|
-
*
|
|
327
|
-
* // Process reaction (reduces inventory)
|
|
328
|
-
* await app.drain();
|
|
329
154
|
* ```
|
|
330
155
|
*
|
|
331
|
-
* @example
|
|
156
|
+
* @example Application with slices (vertical slice architecture)
|
|
332
157
|
* ```typescript
|
|
333
|
-
*
|
|
334
|
-
* .init(() => initialTicket)
|
|
335
|
-
* .emits({ TicketOpened: ..., TicketClosed: ... })
|
|
336
|
-
* .patch({ TicketOpened: ..., TicketClosed: ... })
|
|
337
|
-
* .on("OpenTicket", ...).emit(...)
|
|
338
|
-
* .on("CloseTicket", ...).emit(...)
|
|
339
|
-
* .build();
|
|
158
|
+
* import { act, slice, state } from "@rotorsoft/act";
|
|
340
159
|
*
|
|
341
|
-
* const
|
|
342
|
-
* .
|
|
343
|
-
* .
|
|
344
|
-
*
|
|
345
|
-
*
|
|
160
|
+
* const CounterSlice = slice()
|
|
161
|
+
* .with(Counter)
|
|
162
|
+
* .on("Incremented")
|
|
163
|
+
* .do(async (event) => { console.log("incremented!"); })
|
|
164
|
+
* .void()
|
|
346
165
|
* .build();
|
|
347
166
|
*
|
|
348
|
-
* // Partials with same name are merged automatically
|
|
349
167
|
* const app = act()
|
|
350
|
-
* .with(
|
|
351
|
-
* .with(TicketMessaging)
|
|
168
|
+
* .with(CounterSlice)
|
|
352
169
|
* .build();
|
|
353
170
|
* ```
|
|
354
171
|
*
|
|
355
172
|
* @see {@link ActBuilder} for available builder methods
|
|
356
173
|
* @see {@link Act} for orchestrator API methods
|
|
357
174
|
* @see {@link state} for defining states
|
|
358
|
-
* @see {@link
|
|
175
|
+
* @see {@link slice} for defining slices
|
|
359
176
|
*/
|
|
360
177
|
export declare function act<S extends SchemaRegister<A> = {}, E extends Schemas = {}, A extends Schemas = {}, M extends Record<string, Schema> = {}>(states?: Map<string, State<any, any, any>>, registry?: Registry<S, E, A>): ActBuilder<S, E, A, M>;
|
|
361
178
|
//# sourceMappingURL=act-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"act-builder.d.ts","sourceRoot":"","sources":["../../src/act-builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"act-builder.d.ts","sourceRoot":"","sources":["../../src/act-builder.ts"],"names":[],"mappings":"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"}
|
package/dist/@types/act.d.ts
CHANGED
|
@@ -156,7 +156,7 @@ export declare class Act<S extends SchemaRegister<A>, E extends Schemas, A exten
|
|
|
156
156
|
* @see {@link Snapshot} for return value structure
|
|
157
157
|
* @see {@link ValidationError}, {@link InvariantError}, {@link ConcurrencyError}
|
|
158
158
|
*/
|
|
159
|
-
do<K extends keyof A>(action: K, target: Target, payload: Readonly<A[K]>, reactingTo?: Committed<E, keyof E>, skipValidation?: boolean): Promise<Snapshot<S[K], E>[]>;
|
|
159
|
+
do<K extends keyof A>(action: K, target: Target, payload: Readonly<A[K]>, reactingTo?: Committed<E, string & keyof E>, skipValidation?: boolean): Promise<Snapshot<S[K], E>[]>;
|
|
160
160
|
/**
|
|
161
161
|
* Loads the current state snapshot for a specific stream.
|
|
162
162
|
*
|
|
@@ -359,7 +359,7 @@ export declare class Act<S extends SchemaRegister<A>, E extends Schemas, A exten
|
|
|
359
359
|
* @see {@link correlate} for dynamic stream discovery
|
|
360
360
|
* @see {@link start_correlations} for automatic correlation
|
|
361
361
|
*/
|
|
362
|
-
drain
|
|
362
|
+
drain({ streamLimit, eventLimit, leaseMillis, }?: DrainOptions): Promise<Drain<E>>;
|
|
363
363
|
/**
|
|
364
364
|
* Discovers and registers new streams dynamically based on reaction resolvers.
|
|
365
365
|
*
|
package/dist/@types/act.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"act.d.ts","sourceRoot":"","sources":["../../src/act.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,SAAS,EACT,KAAK,EACL,YAAY,EACZ,KAAK,EACL,KAAK,EAEL,QAAQ,EACR,MAAM,EACN,cAAc,EACd,OAAO,EACP,QAAQ,EACR,KAAK,EACL,MAAM,EACP,MAAM,kBAAkB,CAAC;AAI1B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,GAAG,CACd,CAAC,SAAS,cAAc,CAAC,CAAC,CAAC,EAC3B,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;aAgEtC,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO;IA/D1B,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,qBAAqB,CAAO;IACpC,OAAO,CAAC,qBAAqB,CAAyC;IAEtE;;;;;;OAMG;IACH,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO;IACzD,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,OAAO;IAC5C,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,OAAO;IAKvE;;;;;;OAMG;IACH,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,IAAI,GAAG,IAAI;IACxE,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,GAAG,IAAI;IAC3D,EAAE,CACA,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,KAAK,IAAI,GACzD,IAAI;IAMP;;;;;;OAMG;IACH,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,IAAI,GAAG,IAAI;IACzE,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,GAAG,IAAI;IAC5D,GAAG,CACD,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,KAAK,IAAI,GACzD,IAAI;IAMP;;;;;OAKG;gBAEe,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC1B,OAAO,GAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAa;IASzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkFG;IACG,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,EACxB,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACvB,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"act.d.ts","sourceRoot":"","sources":["../../src/act.ts"],"names":[],"mappings":"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"}
|
package/dist/@types/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export * from "./act-builder.js";
|
|
|
8
8
|
export * from "./act.js";
|
|
9
9
|
export * from "./config.js";
|
|
10
10
|
export * from "./ports.js";
|
|
11
|
+
export * from "./projection-builder.js";
|
|
12
|
+
export * from "./slice-builder.js";
|
|
11
13
|
export * from "./state-builder.js";
|
|
12
14
|
export * from "./types/index.js";
|
|
13
15
|
export * from "./utils.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAEtB;;;;GAIG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAEtB;;;;GAIG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module merge
|
|
3
|
+
* @category Builders
|
|
4
|
+
*
|
|
5
|
+
* Shared utilities for merging partial states across builders.
|
|
6
|
+
*/
|
|
7
|
+
import { type ZodType } from "zod";
|
|
8
|
+
import type { Schema, State } from "./types/index.js";
|
|
9
|
+
/**
|
|
10
|
+
* Unwraps wrapper types (ZodOptional, ZodNullable, ZodDefault, ZodReadonly)
|
|
11
|
+
* to find the base type name, e.g. `z.string().optional()` -> `"ZodString"`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function baseTypeName(zodType: ZodType): string;
|
|
14
|
+
/**
|
|
15
|
+
* Merges two Zod schemas. If both are ZodObject instances, checks for
|
|
16
|
+
* overlapping shape keys with incompatible base types (throws descriptive
|
|
17
|
+
* error), then merges via `.extend()`. Falls back to keeping existing
|
|
18
|
+
* schema if either is not a ZodObject.
|
|
19
|
+
*/
|
|
20
|
+
export declare function mergeSchemas(existing: ZodType, incoming: ZodType, stateName: string): ZodType;
|
|
21
|
+
/**
|
|
22
|
+
* Merges two init functions by spreading both results together.
|
|
23
|
+
* Each partial only provides its own defaults.
|
|
24
|
+
*/
|
|
25
|
+
export declare function mergeInits<S extends Schema>(existing: () => Readonly<S>, incoming: () => Readonly<S>): () => Readonly<S>;
|
|
26
|
+
/**
|
|
27
|
+
* Registers a state into a states map and action/event registries,
|
|
28
|
+
* merging with existing same-name states (partial state support).
|
|
29
|
+
*/
|
|
30
|
+
export declare function registerState(state: State<any, any, any>, states: Map<string, State<any, any, any>>, actions: Record<string, any>, events: Record<string, any>): void;
|
|
31
|
+
export declare const _this_: ({ stream }: {
|
|
32
|
+
stream: string;
|
|
33
|
+
}) => {
|
|
34
|
+
source: string;
|
|
35
|
+
target: string;
|
|
36
|
+
};
|
|
37
|
+
export declare const _void_: () => undefined;
|
|
38
|
+
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/merge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,KAAK,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEtD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAMrD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,OAAO,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAkBT;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EACzC,QAAQ,EAAE,MAAM,QAAQ,CAAC,CAAC,CAAC,EAC3B,QAAQ,EAAE,MAAM,QAAQ,CAAC,CAAC,CAAC,GAC1B,MAAM,QAAQ,CAAC,CAAC,CAAC,CAEnB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC3B,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,EACzC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC1B,IAAI,CAoDN;AAGD,eAAO,MAAM,MAAM,GAAI,YAAY;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE;;;CAGnD,CAAC;AAGH,eAAO,MAAM,MAAM,iBAAkB,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module projection-builder
|
|
3
|
+
* @category Builders
|
|
4
|
+
*
|
|
5
|
+
* Fluent builder for composing projection handlers — read-model updaters
|
|
6
|
+
* that react to events and update external state (databases, caches, etc.).
|
|
7
|
+
*
|
|
8
|
+
* Projections differ from slices: they don't contain states, don't dispatch
|
|
9
|
+
* actions, and are pure side-effect handlers routed to a named stream.
|
|
10
|
+
*/
|
|
11
|
+
import type { ZodType } from "zod";
|
|
12
|
+
import type { Committed, EventRegister, ReactionResolver, Schema, Schemas } from "./types/index.js";
|
|
13
|
+
/**
|
|
14
|
+
* A self-contained projection grouping read-model update handlers.
|
|
15
|
+
* Projections are composed into an Act orchestrator via `act().with(projection)`.
|
|
16
|
+
*
|
|
17
|
+
* @template E - Event schemas handled by this projection
|
|
18
|
+
*/
|
|
19
|
+
export type Projection<E extends Schemas> = {
|
|
20
|
+
readonly _tag: "Projection";
|
|
21
|
+
readonly events: EventRegister<E>;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Type guard for distinguishing Projection from State and Slice objects.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isProjection(x: any): x is Projection<any>;
|
|
27
|
+
/** Helper: a single-key record mapping an event name to its Zod schema. */
|
|
28
|
+
type EventEntry<K extends string = string, D extends Schema = Schema> = {
|
|
29
|
+
[P in K]: ZodType<D>;
|
|
30
|
+
};
|
|
31
|
+
/** Infer the handler-result type after registering one event. */
|
|
32
|
+
type DoResult<E extends Schemas, K extends string, D extends Schema> = ProjectionBuilder<E & {
|
|
33
|
+
[P in K]: D;
|
|
34
|
+
}> & {
|
|
35
|
+
to: (resolver: ReactionResolver<E & {
|
|
36
|
+
[P in K]: D;
|
|
37
|
+
}, K> | string) => ProjectionBuilder<E & {
|
|
38
|
+
[P in K]: D;
|
|
39
|
+
}>;
|
|
40
|
+
void: () => ProjectionBuilder<E & {
|
|
41
|
+
[P in K]: D;
|
|
42
|
+
}>;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Fluent builder interface for composing projections.
|
|
46
|
+
*
|
|
47
|
+
* Provides a chainable API for registering event handlers that update
|
|
48
|
+
* read models. Unlike slices, projections have no `.with()` for states
|
|
49
|
+
* and handlers do not receive a `Dispatcher`.
|
|
50
|
+
*
|
|
51
|
+
* When a default target is provided via `projection("target")`, all
|
|
52
|
+
* handlers inherit that resolver. Per-handler `.to()` or `.void()` can
|
|
53
|
+
* still override it.
|
|
54
|
+
*
|
|
55
|
+
* @template E - Event schemas
|
|
56
|
+
*/
|
|
57
|
+
export type ProjectionBuilder<E extends Schemas> = {
|
|
58
|
+
/**
|
|
59
|
+
* Begins defining a projection handler for a specific event.
|
|
60
|
+
*
|
|
61
|
+
* Pass a `{ EventName: schema }` record — use shorthand `{ EventName }`
|
|
62
|
+
* when the variable name matches the event name. The key becomes the
|
|
63
|
+
* event name, the value the Zod schema.
|
|
64
|
+
*/
|
|
65
|
+
on: <K extends string, D extends Schema>(entry: EventEntry<K, D>) => {
|
|
66
|
+
do: (handler: (event: Committed<E & {
|
|
67
|
+
[P in K]: D;
|
|
68
|
+
}, K>, stream: string) => Promise<void>) => DoResult<E, K, D>;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Builds and returns the Projection data structure.
|
|
72
|
+
*/
|
|
73
|
+
build: () => Projection<E>;
|
|
74
|
+
/**
|
|
75
|
+
* The registered event schemas and their reaction maps.
|
|
76
|
+
*/
|
|
77
|
+
readonly events: EventRegister<E>;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Creates a new projection builder for composing read-model update handlers.
|
|
81
|
+
*
|
|
82
|
+
* Projections enable separation of read-model concerns from command handling.
|
|
83
|
+
* Each `.on({ Event }).do(handler)` call registers a handler that updates
|
|
84
|
+
* a projection (database table, cache, etc.) in response to events.
|
|
85
|
+
*
|
|
86
|
+
* Pass a target stream name to `projection("target")` so every handler
|
|
87
|
+
* inherits that resolver automatically. Omit it and use per-handler
|
|
88
|
+
* `.to()` / `.void()` when handlers route to different streams.
|
|
89
|
+
*
|
|
90
|
+
* @param target - Optional default target stream for all handlers
|
|
91
|
+
*
|
|
92
|
+
* @example Default target (all handlers routed to "tickets")
|
|
93
|
+
* ```typescript
|
|
94
|
+
* const TicketProjection = projection("tickets")
|
|
95
|
+
* .on({ TicketOpened })
|
|
96
|
+
* .do(async ({ stream, data }) => {
|
|
97
|
+
* await db.insert(tickets).values({ id: stream, ...data });
|
|
98
|
+
* })
|
|
99
|
+
* .on({ TicketClosed })
|
|
100
|
+
* .do(async ({ stream, data }) => {
|
|
101
|
+
* await db.update(tickets).set(data).where(eq(tickets.id, stream));
|
|
102
|
+
* })
|
|
103
|
+
* .build();
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @example Per-handler routing
|
|
107
|
+
* ```typescript
|
|
108
|
+
* const MultiProjection = projection()
|
|
109
|
+
* .on({ OrderPlaced })
|
|
110
|
+
* .do(async (event) => { ... })
|
|
111
|
+
* .to("orders")
|
|
112
|
+
* .on({ PaymentReceived })
|
|
113
|
+
* .do(async (event) => { ... })
|
|
114
|
+
* .to("payments")
|
|
115
|
+
* .build();
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
* @see {@link ProjectionBuilder} for builder methods
|
|
119
|
+
* @see {@link Projection} for the output type
|
|
120
|
+
*/
|
|
121
|
+
export declare function projection<E extends Schemas = {}>(target?: string, events?: EventRegister<E>): ProjectionBuilder<E>;
|
|
122
|
+
export {};
|
|
123
|
+
//# sourceMappingURL=projection-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projection-builder.d.ts","sourceRoot":"","sources":["../../src/projection-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EAGb,gBAAgB,EAChB,MAAM,EACN,OAAO,EACR,MAAM,kBAAkB,CAAC;AAE1B;;;;;GAKG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,OAAO,IAAI;IAC1C,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;CACnC,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAEzD;AAED,2EAA2E;AAC3E,KAAK,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;KACrE,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CACrB,CAAC;AAEF,iEAAiE;AACjE,KAAK,QAAQ,CACX,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,MAAM,IACd,iBAAiB,CAAC,CAAC,GAAG;KAAG,CAAC,IAAI,CAAC,GAAG,CAAC;CAAE,CAAC,GAAG;IAC3C,EAAE,EAAE,CACF,QAAQ,EAAE,gBAAgB,CAAC,CAAC,GAAG;SAAG,CAAC,IAAI,CAAC,GAAG,CAAC;KAAE,EAAE,CAAC,CAAC,GAAG,MAAM,KACxD,iBAAiB,CAAC,CAAC,GAAG;SAAG,CAAC,IAAI,CAAC,GAAG,CAAC;KAAE,CAAC,CAAC;IAC5C,IAAI,EAAE,MAAM,iBAAiB,CAAC,CAAC,GAAG;SAAG,CAAC,IAAI,CAAC,GAAG,CAAC;KAAE,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,OAAO,IAAI;IACjD;;;;;;OAMG;IACH,EAAE,EAAE,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,EACrC,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,KACpB;QACH,EAAE,EAAE,CACF,OAAO,EAAE,CACP,KAAK,EAAE,SAAS,CAAC,CAAC,GAAG;aAAG,CAAC,IAAI,CAAC,GAAG,CAAC;SAAE,EAAE,CAAC,CAAC,EACxC,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,IAAI,CAAC,KACf,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;KACxB,CAAC;IACF;;OAEG;IACH,KAAK,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;CACnC,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,OAAO,GAAG,EAAE,EAC/C,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,GAAE,aAAa,CAAC,CAAC,CAA0B,GAChD,iBAAiB,CAAC,CAAC,CAAC,CAyEtB"}
|