@rotorsoft/act 0.33.2 → 0.34.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.
Files changed (83) hide show
  1. package/README.md +26 -2
  2. package/package.json +4 -2
  3. package/dist/.tsbuildinfo +0 -1
  4. package/dist/@types/act.d.ts +0 -598
  5. package/dist/@types/act.d.ts.map +0 -1
  6. package/dist/@types/adapters/console-logger.d.ts +0 -41
  7. package/dist/@types/adapters/console-logger.d.ts.map +0 -1
  8. package/dist/@types/adapters/in-memory-cache.d.ts +0 -34
  9. package/dist/@types/adapters/in-memory-cache.d.ts.map +0 -1
  10. package/dist/@types/adapters/in-memory-store.d.ts +0 -181
  11. package/dist/@types/adapters/in-memory-store.d.ts.map +0 -1
  12. package/dist/@types/adapters/index.d.ts +0 -4
  13. package/dist/@types/adapters/index.d.ts.map +0 -1
  14. package/dist/@types/builders/act-builder.d.ts +0 -160
  15. package/dist/@types/builders/act-builder.d.ts.map +0 -1
  16. package/dist/@types/builders/index.d.ts +0 -13
  17. package/dist/@types/builders/index.d.ts.map +0 -1
  18. package/dist/@types/builders/projection-builder.d.ts +0 -101
  19. package/dist/@types/builders/projection-builder.d.ts.map +0 -1
  20. package/dist/@types/builders/slice-builder.d.ts +0 -109
  21. package/dist/@types/builders/slice-builder.d.ts.map +0 -1
  22. package/dist/@types/builders/state-builder.d.ts +0 -408
  23. package/dist/@types/builders/state-builder.d.ts.map +0 -1
  24. package/dist/@types/config.d.ts +0 -119
  25. package/dist/@types/config.d.ts.map +0 -1
  26. package/dist/@types/index.d.ts +0 -14
  27. package/dist/@types/index.d.ts.map +0 -1
  28. package/dist/@types/internal/build-classify.d.ts +0 -44
  29. package/dist/@types/internal/build-classify.d.ts.map +0 -1
  30. package/dist/@types/internal/close-cycle.d.ts +0 -38
  31. package/dist/@types/internal/close-cycle.d.ts.map +0 -1
  32. package/dist/@types/internal/correlate-cycle.d.ts +0 -73
  33. package/dist/@types/internal/correlate-cycle.d.ts.map +0 -1
  34. package/dist/@types/internal/drain-cycle.d.ts +0 -113
  35. package/dist/@types/internal/drain-cycle.d.ts.map +0 -1
  36. package/dist/@types/internal/drain-ratio.d.ts +0 -26
  37. package/dist/@types/internal/drain-ratio.d.ts.map +0 -1
  38. package/dist/@types/internal/drain.d.ts +0 -41
  39. package/dist/@types/internal/drain.d.ts.map +0 -1
  40. package/dist/@types/internal/event-sourcing.d.ts +0 -96
  41. package/dist/@types/internal/event-sourcing.d.ts.map +0 -1
  42. package/dist/@types/internal/index.d.ts +0 -29
  43. package/dist/@types/internal/index.d.ts.map +0 -1
  44. package/dist/@types/internal/merge.d.ts +0 -31
  45. package/dist/@types/internal/merge.d.ts.map +0 -1
  46. package/dist/@types/internal/reactions.d.ts +0 -54
  47. package/dist/@types/internal/reactions.d.ts.map +0 -1
  48. package/dist/@types/internal/settle.d.ts +0 -60
  49. package/dist/@types/internal/settle.d.ts.map +0 -1
  50. package/dist/@types/internal/tracing.d.ts +0 -45
  51. package/dist/@types/internal/tracing.d.ts.map +0 -1
  52. package/dist/@types/lru-map.d.ts +0 -50
  53. package/dist/@types/lru-map.d.ts.map +0 -1
  54. package/dist/@types/ports.d.ts +0 -196
  55. package/dist/@types/ports.d.ts.map +0 -1
  56. package/dist/@types/signals.d.ts +0 -2
  57. package/dist/@types/signals.d.ts.map +0 -1
  58. package/dist/@types/types/action.d.ts +0 -444
  59. package/dist/@types/types/action.d.ts.map +0 -1
  60. package/dist/@types/types/errors.d.ts +0 -284
  61. package/dist/@types/types/errors.d.ts.map +0 -1
  62. package/dist/@types/types/index.d.ts +0 -39
  63. package/dist/@types/types/index.d.ts.map +0 -1
  64. package/dist/@types/types/ports.d.ts +0 -485
  65. package/dist/@types/types/ports.d.ts.map +0 -1
  66. package/dist/@types/types/reaction.d.ts +0 -291
  67. package/dist/@types/types/reaction.d.ts.map +0 -1
  68. package/dist/@types/types/registry.d.ts +0 -74
  69. package/dist/@types/types/registry.d.ts.map +0 -1
  70. package/dist/@types/types/schemas.d.ts +0 -117
  71. package/dist/@types/types/schemas.d.ts.map +0 -1
  72. package/dist/@types/utils.d.ts +0 -54
  73. package/dist/@types/utils.d.ts.map +0 -1
  74. package/dist/chunk-AWT7TU22.js +0 -127
  75. package/dist/chunk-AWT7TU22.js.map +0 -1
  76. package/dist/index.cjs +0 -2985
  77. package/dist/index.cjs.map +0 -1
  78. package/dist/index.js +0 -2816
  79. package/dist/index.js.map +0 -1
  80. package/dist/types/index.cjs +0 -166
  81. package/dist/types/index.cjs.map +0 -1
  82. package/dist/types/index.js +0 -33
  83. package/dist/types/index.js.map +0 -1
@@ -1,598 +0,0 @@
1
- import type { Actor, AsOf, BatchHandler, BlockedLease, CloseResult, CloseTarget, Committed, Drain, DrainOptions, IAct, Lease, Query, Registry, Schema, SchemaRegister, Schemas, SettleOptions, Snapshot, State, Target } from "./types/index.js";
2
- /**
3
- * @category Orchestrator
4
- * @see Store
5
- *
6
- * Main orchestrator for event-sourced state machines and workflows.
7
- *
8
- * It manages the lifecycle of actions, reactions, and event streams, providing APIs for loading state, executing actions, querying events, and draining reactions.
9
- *
10
- * ## Usage
11
- *
12
- * ```typescript
13
- * const app = new Act(registry, 100);
14
- * await app.do("increment", { stream: "counter1", actor }, { by: 1 });
15
- * const snapshot = await app.load(Counter, "counter1");
16
- * await app.drain();
17
- * ```
18
- *
19
- * - Register event listeners with `.on("committed", ...)` and `.on("acked", ...)` to react to lifecycle events.
20
- * - Use `.query()` to analyze event streams for analytics or debugging.
21
- *
22
- * @template TSchemaReg SchemaRegister for state
23
- * @template TEvents Schemas for events
24
- * @template TActions Schemas for actions
25
- * @template TStateMap Map of state names to state schemas
26
- * @template TActor Actor type extending base Actor
27
- */
28
- /**
29
- * Default LRU cap for the subscribed-streams cache. Apps that mint many
30
- * dynamic targets (one per aggregate) should override via
31
- * {@link ActOptions.maxSubscribedStreams} based on expected concurrency.
32
- */
33
- export declare const DEFAULT_MAX_SUBSCRIBED_STREAMS = 1000;
34
- /**
35
- * Default debounce window (ms) for `settle()` when neither the per-call
36
- * `SettleOptions.debounceMs` nor `ActOptions.settleDebounceMs` is set.
37
- * Coalesces commits in the same tick and small bursts; sub-perceptible
38
- * latency on the `"settled"` signal.
39
- */
40
- export declare const DEFAULT_SETTLE_DEBOUNCE_MS = 10;
41
- /**
42
- * Lifecycle events emitted by {@link Act}, mapped to their payload type.
43
- * Drives the typing of `emit` / `on` / `off` — the event-name argument
44
- * narrows its payload at the call site.
45
- */
46
- export type ActLifecycleEvents<TSchemaReg extends SchemaRegister<TActions>, TEvents extends Schemas, TActions extends Schemas> = {
47
- committed: Snapshot<TSchemaReg, TEvents>[];
48
- acked: Lease[];
49
- blocked: BlockedLease[];
50
- settled: Drain<TEvents>;
51
- closed: CloseResult;
52
- };
53
- /**
54
- * Options for {@link Act} construction (passed via {@link ActBuilder.build}).
55
- *
56
- * @property maxSubscribedStreams - Cap for the LRU set tracking already-
57
- * subscribed reaction streams. Default: {@link DEFAULT_MAX_SUBSCRIBED_STREAMS}.
58
- * @property settleDebounceMs - Debounce window (ms) used by `settle()` when
59
- * the caller doesn't pass `SettleOptions.debounceMs`. Tune this once per
60
- * Act instance instead of threading the value through every call site.
61
- * Default: {@link DEFAULT_SETTLE_DEBOUNCE_MS}.
62
- */
63
- export type ActOptions = {
64
- readonly maxSubscribedStreams?: number;
65
- readonly settleDebounceMs?: number;
66
- };
67
- export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents extends Schemas, TActions extends Schemas, TStateMap extends Record<string, Schema> = Record<string, never>, TActor extends Actor = Actor> implements IAct<TEvents, TActions, TActor> {
68
- readonly registry: Registry<TSchemaReg, TEvents, TActions>;
69
- private readonly _states;
70
- private _emitter;
71
- /** Event names with at least one registered reaction (computed at build time) */
72
- private readonly _reactive_events;
73
- /** Drain pipeline driver: armed flag, concurrency lock, adaptive ratio. */
74
- private readonly _drain;
75
- /** Correlation state machine: lazy init, dynamic-resolver scan, periodic worker. */
76
- private readonly _correlate;
77
- /** Debounced correlate→drain catch-up loop. */
78
- private readonly _settle;
79
- /**
80
- * Emit a lifecycle event. The payload type is inferred from the event name
81
- * via {@link ActLifecycleEvents}.
82
- */
83
- emit<E extends keyof ActLifecycleEvents<TSchemaReg, TEvents, TActions>>(event: E, args: ActLifecycleEvents<TSchemaReg, TEvents, TActions>[E]): boolean;
84
- /**
85
- * Register a listener for a lifecycle event. The listener receives the
86
- * event-specific payload.
87
- */
88
- on<E extends keyof ActLifecycleEvents<TSchemaReg, TEvents, TActions>>(event: E, listener: (args: ActLifecycleEvents<TSchemaReg, TEvents, TActions>[E]) => void): this;
89
- /**
90
- * Remove a previously registered lifecycle listener.
91
- */
92
- off<E extends keyof ActLifecycleEvents<TSchemaReg, TEvents, TActions>>(event: E, listener: (args: ActLifecycleEvents<TSchemaReg, TEvents, TActions>[E]) => void): this;
93
- /** Batch handlers for static-target projections (target → handler) */
94
- private readonly _batch_handlers;
95
- /** Event-sourcing handlers, optionally wrapped with trace decorators */
96
- private readonly _es;
97
- /** Correlate/drain pipeline ops, optionally wrapped with trace decorators */
98
- private readonly _cd;
99
- /**
100
- * Event-name → owning state, computed at build time. The duplicate-event
101
- * guard in merge.ts ensures one event name maps to at most one state, so
102
- * this lookup is unambiguous. Used by `close()` to pick the right reducer
103
- * set when seeding a `restart` snapshot in multi-state apps.
104
- */
105
- private readonly _event_to_state;
106
- /** Logger resolved at construction time (after user port configuration) */
107
- private readonly _logger;
108
- /** Pre-bound IAct methods reused across drain cycles. Only `do` varies per
109
- * payload (it captures the triggering event for reactingTo auto-inject). */
110
- private readonly _bound_do;
111
- private readonly _bound_load;
112
- private readonly _bound_query;
113
- private readonly _bound_query_array;
114
- /** Reaction dispatchers built once and handed to runDrainCycle each cycle. */
115
- private readonly _handle;
116
- private readonly _handle_batch;
117
- /**
118
- * Create a new Act orchestrator. Prefer the {@link act} builder over
119
- * direct construction — `act()...build()` wires the registry, merges
120
- * partial states, and collects batch handlers from registered slices
121
- * and projections in one pass.
122
- *
123
- * @param registry Schemas for every event and action across registered states
124
- * @param _states Merged map of state name → state definition
125
- * @param batchHandlers Static-target projection batch handlers (target → handler)
126
- * @param options Tuning knobs — see {@link ActOptions}
127
- */
128
- constructor(registry: Registry<TSchemaReg, TEvents, TActions>, _states?: Map<string, State<any, any, any>>, batchHandlers?: Map<string, BatchHandler<any>>, options?: ActOptions);
129
- /**
130
- * Executes an action on a state instance, committing resulting events.
131
- *
132
- * This is the primary method for modifying state. It:
133
- * 1. Validates the action payload against the schema
134
- * 2. Loads the current state snapshot
135
- * 3. Checks invariants (business rules)
136
- * 4. Executes the action handler to generate events
137
- * 5. Applies events to create new state
138
- * 6. Commits events to the store with optimistic concurrency control
139
- *
140
- * @template TKey - Action name from registered actions
141
- * @param action - The name of the action to execute
142
- * @param target - Target specification with stream ID and actor context
143
- * @param payload - Action payload matching the action's schema
144
- * @param reactingTo - Optional event that triggered this action (for correlation)
145
- * @param skipValidation - Skip schema validation (use carefully, for performance)
146
- * @returns Array of snapshots for all affected states (usually one)
147
- *
148
- * @throws {ValidationError} If payload doesn't match action schema
149
- * @throws {InvariantError} If business rules are violated
150
- * @throws {ConcurrencyError} If another process modified the stream
151
- *
152
- * @example Basic action execution
153
- * ```typescript
154
- * const snapshots = await app.do(
155
- * "increment",
156
- * {
157
- * stream: "counter-1",
158
- * actor: { id: "user1", name: "Alice" }
159
- * },
160
- * { by: 5 }
161
- * );
162
- *
163
- * console.log(snapshots[0].state.count); // Current count after increment
164
- * ```
165
- *
166
- * @example With error handling
167
- * ```typescript
168
- * try {
169
- * await app.do(
170
- * "withdraw",
171
- * { stream: "account-123", actor: { id: "user1", name: "Alice" } },
172
- * { amount: 1000 }
173
- * );
174
- * } catch (error) {
175
- * if (error instanceof InvariantError) {
176
- * console.error("Business rule violated:", error.description);
177
- * } else if (error instanceof ConcurrencyError) {
178
- * console.error("Concurrent modification detected, retry...");
179
- * } else if (error instanceof ValidationError) {
180
- * console.error("Invalid payload:", error.details);
181
- * }
182
- * }
183
- * ```
184
- *
185
- * @example Reaction triggering another action (reactingTo auto-injected)
186
- * ```typescript
187
- * const app = act()
188
- * .withState(Order)
189
- * .withState(Inventory)
190
- * .on("OrderPlaced")
191
- * .do(async function reduceInventory(event, _stream, app) {
192
- * // Inside reaction handlers, reactingTo is auto-injected when omitted.
193
- * // The triggering event is used by default, maintaining the correlation chain.
194
- * await app.do(
195
- * "reduceStock",
196
- * { stream: "inventory-1", actor: { id: "sys", name: "system" } },
197
- * { amount: event.data.items.length }
198
- * );
199
- * // To use a different correlation, pass reactingTo explicitly:
200
- * // await app.do("reduceStock", target, payload, customEvent);
201
- * })
202
- * .to("inventory-1")
203
- * .build();
204
- * ```
205
- *
206
- * @see {@link Target} for target structure
207
- * @see {@link Snapshot} for return value structure
208
- * @see {@link ValidationError}, {@link InvariantError}, {@link ConcurrencyError}
209
- */
210
- do<TKey extends keyof TActions>(action: TKey, target: Target<TActor>, payload: Readonly<TActions[TKey]>, reactingTo?: Committed<TEvents, string & keyof TEvents>, skipValidation?: boolean): Promise<Snapshot<TSchemaReg[TKey], TEvents>[]>;
211
- /**
212
- * Loads the current state snapshot for a specific stream.
213
- *
214
- * Reconstructs the current state by replaying events from the event store.
215
- * Uses snapshots when available to optimize loading performance.
216
- *
217
- * Accepts either a State definition object or a state name string. When
218
- * using a string, the merged state (from partial states registered via
219
- * `.withState()`) is resolved by name.
220
- *
221
- * @template TNewState - State schema type
222
- * @template TNewEvents - Event schemas type
223
- * @template TNewActions - Action schemas type
224
- * @param state - The state definition or state name to load
225
- * @param stream - The stream ID (state instance identifier)
226
- * @param callback - Optional callback invoked with the loaded snapshot
227
- * @returns The current state snapshot for the stream
228
- *
229
- * @example Load by state definition
230
- * ```typescript
231
- * const snapshot = await app.load(Counter, "counter-1");
232
- * console.log(snapshot.state.count); // Current count
233
- * console.log(snapshot.patches); // Events since last snapshot
234
- * ```
235
- *
236
- * @example Load by state name (useful with partial states)
237
- * ```typescript
238
- * const snapshot = await app.load("Ticket", "ticket-123");
239
- * console.log(snapshot.state.title); // Merged state from all partials
240
- * ```
241
- *
242
- * @example Load multiple states
243
- * ```typescript
244
- * const [user, account] = await Promise.all([
245
- * app.load(User, "user-123"),
246
- * app.load(BankAccount, "account-456")
247
- * ]);
248
- * ```
249
- *
250
- * @see {@link Snapshot} for snapshot structure
251
- */
252
- load<TNewState extends Schema, TNewEvents extends Schemas, TNewActions extends Schemas>(state: State<TNewState, TNewEvents, TNewActions>, stream: string, callback?: (snapshot: Snapshot<TNewState, TNewEvents>) => void, asOf?: AsOf): Promise<Snapshot<TNewState, TNewEvents>>;
253
- load<TKey extends keyof TStateMap & string>(name: TKey, stream: string, callback?: (snapshot: Snapshot<TStateMap[TKey], TEvents>) => void, asOf?: AsOf): Promise<Snapshot<TStateMap[TKey], TEvents>>;
254
- /**
255
- * Queries the event store for events matching a filter.
256
- *
257
- * Use this for analyzing event streams, generating reports, or debugging.
258
- * The callback is invoked for each matching event, and the method returns
259
- * summary information (first event, last event, total count).
260
- *
261
- * For small result sets, consider using {@link query_array} instead.
262
- *
263
- * @param query - Filter criteria — see {@link Query} for available fields
264
- * (`stream`, `name`, `after`, `before`, `created_after`, `created_before`,
265
- * `limit`, `with_snaps`, `stream_exact`)
266
- * @param callback - Optional callback invoked for each matching event
267
- * @returns Object with first event, last event, and total count
268
- *
269
- * @example Query all events for a stream
270
- * ```typescript
271
- * const { first, last, count } = await app.query(
272
- * { stream: "counter-1" },
273
- * (event) => console.log(event.name, event.data)
274
- * );
275
- * console.log(`Found ${count} events from ${first?.id} to ${last?.id}`);
276
- * ```
277
- *
278
- * @example Query specific event types
279
- * ```typescript
280
- * const { count } = await app.query(
281
- * { name: "UserCreated", limit: 100 },
282
- * (event) => {
283
- * console.log("User created:", event.data.email);
284
- * }
285
- * );
286
- * ```
287
- *
288
- * @example Query events in time range
289
- * ```typescript
290
- * const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000);
291
- * const { count } = await app.query({
292
- * created_after: yesterday,
293
- * stream: "user-123"
294
- * });
295
- * console.log(`User had ${count} events in last 24 hours`);
296
- * ```
297
- *
298
- * @see {@link query_array} for loading events into memory
299
- */
300
- query(query: Query, callback?: (event: Committed<TEvents, keyof TEvents>) => void): Promise<{
301
- first?: Committed<TEvents, keyof TEvents>;
302
- last?: Committed<TEvents, keyof TEvents>;
303
- count: number;
304
- }>;
305
- /**
306
- * Queries the event store and returns all matching events in memory.
307
- *
308
- * **Use with caution** - this loads all results into memory. For large result sets,
309
- * use {@link query} with a callback instead to process events incrementally.
310
- *
311
- * @param query - The query filter (same as {@link query})
312
- * @returns Array of all matching events
313
- *
314
- * @example Load all events for a stream
315
- * ```typescript
316
- * const events = await app.query_array({ stream: "counter-1" });
317
- * console.log(`Loaded ${events.length} events`);
318
- * events.forEach(event => console.log(event.name, event.data));
319
- * ```
320
- *
321
- * @example Get recent events
322
- * ```typescript
323
- * const recent = await app.query_array({
324
- * stream: "user-123",
325
- * limit: 10
326
- * });
327
- * ```
328
- *
329
- * @see {@link query} for large result sets
330
- */
331
- query_array(query: Query): Promise<Committed<TEvents, keyof TEvents>[]>;
332
- /**
333
- * Processes pending reactions by draining uncommitted events from the event store.
334
- *
335
- * Runs a single drain cycle:
336
- * 1. Polls the store for streams with uncommitted events
337
- * 2. Leases streams to prevent concurrent processing
338
- * 3. Fetches events for each leased stream
339
- * 4. Executes matching reaction handlers
340
- * 5. Acknowledges successful reactions or blocks failing ones
341
- *
342
- * Drain uses a dual-frontier strategy to balance processing of new streams (lagging)
343
- * vs active streams (leading). The ratio adapts based on event pressure.
344
- *
345
- * Call `correlate()` before `drain()` to discover target streams. For a higher-level
346
- * API that handles debouncing, correlation, and signaling automatically, use {@link settle}.
347
- *
348
- * @param options - Drain configuration — see {@link DrainOptions} for fields
349
- * (`streamLimit`, `eventLimit`, `leaseMillis`).
350
- * @returns Drain statistics with fetched, leased, acked, and blocked counts
351
- *
352
- * @example In tests and scripts
353
- * ```typescript
354
- * await app.do("createUser", target, payload);
355
- * await app.correlate();
356
- * await app.drain();
357
- * ```
358
- *
359
- * @example In production, prefer settle()
360
- * ```typescript
361
- * await app.do("CreateItem", target, input);
362
- * app.settle(); // debounced correlate→drain, emits "settled"
363
- * ```
364
- *
365
- * @see {@link settle} for debounced correlate→drain with lifecycle events
366
- * @see {@link correlate} for dynamic stream discovery
367
- * @see {@link start_correlations} for automatic correlation
368
- */
369
- drain(options?: DrainOptions): Promise<Drain<TEvents>>;
370
- /**
371
- * Discovers and registers new streams dynamically based on reaction resolvers.
372
- *
373
- * Correlation enables "dynamic reactions" where target streams are determined at runtime
374
- * based on event content. For example, you might create a stats stream for each user
375
- * when they perform certain actions.
376
- *
377
- * This method scans events matching the query and identifies new target streams based
378
- * on reaction resolvers. It then registers these streams so they'll be picked up by
379
- * the next drain cycle.
380
- *
381
- * @param query - Query filter to scan for new correlations
382
- * @param query - Scan filter — see {@link Query} for fields (typically
383
- * `{ after: <event-id>, limit: <count> }`)
384
- * @returns Object with newly leased streams and last scanned event ID
385
- *
386
- * @example Manual correlation
387
- * ```typescript
388
- * // Scan for new streams
389
- * const { leased, last_id } = await app.correlate({ after: 0, limit: 100 });
390
- * console.log(`Found ${leased.length} new streams`);
391
- *
392
- * // Save last_id for next scan
393
- * await saveCheckpoint(last_id);
394
- * ```
395
- *
396
- * @example Dynamic stream creation
397
- * ```typescript
398
- * const app = act()
399
- * .withState(User)
400
- * .withState(UserStats)
401
- * .on("UserLoggedIn")
402
- * .do(async (event) => ["incrementLoginCount", {}])
403
- * .to((event) => ({
404
- * target: `stats-${event.stream}` // Dynamic target per user
405
- * }))
406
- * .build();
407
- *
408
- * // Discover stats streams as users log in
409
- * await app.correlate();
410
- * ```
411
- *
412
- * @see {@link start_correlations} for automatic periodic correlation
413
- * @see {@link stop_correlations} to stop automatic correlation
414
- */
415
- correlate(query?: Query): Promise<{
416
- subscribed: number;
417
- last_id: number;
418
- }>;
419
- /**
420
- * Starts automatic periodic correlation worker for discovering new streams.
421
- *
422
- * The correlation worker runs in the background, scanning for new events and identifying
423
- * new target streams based on reaction resolvers. It maintains a sliding window that
424
- * advances with each scan, ensuring all events are eventually correlated.
425
- *
426
- * This is useful for dynamic stream creation patterns where you don't know all streams
427
- * upfront - they're discovered as events arrive.
428
- *
429
- * **Note:** Only one correlation worker can run at a time per Act instance.
430
- *
431
- * @param query - Query filter for correlation scans — see {@link Query}
432
- * (typically `{ after: -1, limit: 100 }`)
433
- * @param frequency - Correlation frequency in milliseconds (default: 10000)
434
- * @param callback - Optional callback invoked with newly discovered streams
435
- * @returns `true` if worker started, `false` if already running
436
- *
437
- * @example Start automatic correlation
438
- * ```typescript
439
- * // Start correlation worker scanning every 5 seconds
440
- * app.start_correlations(
441
- * { after: 0, limit: 100 },
442
- * 5000,
443
- * (leased) => {
444
- * console.log(`Discovered ${leased.length} new streams`);
445
- * }
446
- * );
447
- *
448
- * // Later, stop it
449
- * app.stop_correlations();
450
- * ```
451
- *
452
- * @example With checkpoint persistence
453
- * ```typescript
454
- * // Load last checkpoint
455
- * const lastId = await loadCheckpoint();
456
- *
457
- * app.start_correlations(
458
- * { after: lastId, limit: 100 },
459
- * 10000,
460
- * async (leased) => {
461
- * // Save checkpoint for next restart
462
- * if (leased.length) {
463
- * const maxId = Math.max(...leased.map(l => l.at));
464
- * await saveCheckpoint(maxId);
465
- * }
466
- * }
467
- * );
468
- * ```
469
- *
470
- * @see {@link correlate} for manual one-time correlation
471
- * @see {@link stop_correlations} to stop the worker
472
- */
473
- start_correlations(query?: Query, frequency?: number, callback?: (subscribed: number) => void): boolean;
474
- /**
475
- * Stops the automatic correlation worker.
476
- *
477
- * Call this to stop the background correlation worker started by {@link start_correlations}.
478
- * This is automatically called when the Act instance is disposed.
479
- *
480
- * @example
481
- * ```typescript
482
- * // Start correlation
483
- * app.start_correlations();
484
- *
485
- * // Later, stop it
486
- * app.stop_correlations();
487
- * ```
488
- *
489
- * @see {@link start_correlations}
490
- */
491
- stop_correlations(): void;
492
- /**
493
- * Cancels any pending or active settle cycle.
494
- *
495
- * @see {@link settle}
496
- */
497
- stop_settling(): void;
498
- /**
499
- * Reset reaction stream watermarks and request a drain on the next
500
- * `drain()` / `settle()` cycle.
501
- *
502
- * Use this to replay events through projections (or other reaction targets)
503
- * after changing handler logic. Equivalent to calling `store().reset(streams)`
504
- * directly, but also raises the orchestrator's internal "needs drain" flag —
505
- * `store().reset(...)` alone leaves the flag untouched, so a settled app
506
- * would short-circuit and skip the replay.
507
- *
508
- * Pair with `app.settle()` (or a single `app.drain()` for small streams).
509
- * `settle()` loops correlate→drain until no progress is made, so one call
510
- * fully catches up paginated streams without forcing callers to roll
511
- * their own loop.
512
- *
513
- * @param streams - Reaction target streams (e.g., projection names) to reset
514
- * @returns Count of streams that were actually reset
515
- *
516
- * @example Rebuild a projection (production)
517
- * ```typescript
518
- * await app.reset(["my-projection"]);
519
- * app.settle({ eventLimit: 1000 }); // emits "settled" when fully replayed
520
- * ```
521
- *
522
- * @example Rebuild a projection (tests / scripts)
523
- * ```typescript
524
- * await app.reset(["my-projection"]);
525
- * await app.drain({ eventLimit: 1000 }); // small streams: one pass is enough
526
- * ```
527
- *
528
- * @see {@link Store.reset} for the underlying store primitive
529
- * @see {@link settle} for the debounced full-catch-up loop
530
- */
531
- reset(streams: string[]): Promise<number>;
532
- /**
533
- * Close the books — guard, archive, truncate, and optionally restart streams.
534
- *
535
- * Safely removes historical events from the operational store:
536
- *
537
- * 1. **Correlate** — discover pending reaction targets
538
- * 2. **Safety check** — skip streams with pending reactions (skipped when no reactive events)
539
- * 3. **Guard** — commit `__tombstone__` with `expectedVersion` to block concurrent writes
540
- * 4. **Load state** — for streams in `snapshots`, load final state while guarded (no races)
541
- * 5. **Archive** — user callback per stream (abort-all on failure, streams are guarded)
542
- * 6. **Truncate + seed** — atomic: delete all events, insert `__snapshot__` or `__tombstone__`
543
- * 7. **Cache** — invalidate (tombstoned) or warm (restarted)
544
- * 8. **Emit "closed"** — lifecycle event with results
545
- *
546
- * @param targets - Per-stream close options (stream, restart?, archive?)
547
- * @returns `{ truncated: TruncateResult, skipped: string[] }`
548
- *
549
- * @example Archive and close
550
- * ```typescript
551
- * await app.close([
552
- * { stream: "order-123", archive: async () => { await archiveToS3("order-123"); } },
553
- * { stream: "order-456" },
554
- * ]);
555
- * ```
556
- *
557
- * @example Close with restart (state loaded automatically after guard)
558
- * ```typescript
559
- * await app.close([
560
- * { stream: "counter-1", restart: true },
561
- * { stream: "counter-2" }, // tombstoned
562
- * ]);
563
- * ```
564
- */
565
- close(targets: CloseTarget[]): Promise<CloseResult>;
566
- /**
567
- * Debounced, non-blocking correlate→drain cycle.
568
- *
569
- * Call this after `app.do()` (or `app.reset()`) to schedule a background
570
- * drain. Multiple rapid calls within the debounce window are coalesced
571
- * into a single cycle. Runs correlate→drain in a loop until a pass makes
572
- * no progress — no new subscriptions, no acks, no blocks — then emits
573
- * the `"settled"` lifecycle event. This means a single `settle()` call
574
- * fully catches up paginated streams (e.g. after `reset()` on a long
575
- * projection) without forcing callers to loop.
576
- *
577
- * @param options - Settle configuration — see {@link SettleOptions} for fields:
578
- * `debounceMs` (default 10), `correlate` (default `{ after: -1, limit: 100 }`),
579
- * `maxPasses` (default `Infinity` — kill-switch for runaway loops),
580
- * `streamLimit` (default 10), `eventLimit` (default 10),
581
- * `leaseMillis` (default 10000).
582
- *
583
- * @example API mutations
584
- * ```typescript
585
- * await app.do("CreateItem", target, input);
586
- * app.settle(); // non-blocking, returns immediately
587
- *
588
- * app.on("settled", (drain) => {
589
- * // notify SSE clients, invalidate caches, etc.
590
- * });
591
- * ```
592
- *
593
- * @see {@link drain} for single synchronous drain cycles
594
- * @see {@link correlate} for manual correlation
595
- */
596
- settle(options?: SettleOptions): void;
597
- }
598
- //# sourceMappingURL=act.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"act.d.ts","sourceRoot":"","sources":["../../src/act.ts"],"names":[],"mappings":"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"}
@@ -1,41 +0,0 @@
1
- /**
2
- * @module adapters/console-logger
3
- *
4
- * High-performance console logger inspired by pino's design:
5
- * - Numeric level comparison for O(1) gating
6
- * - stdout.write() in production for raw JSON lines (no console overhead)
7
- * - Colorized single-line output in development
8
- * - No-op method replacement when level is above threshold
9
- * - Child logger support with merged bindings
10
- */
11
- import type { Logger } from "../types/index.js";
12
- /**
13
- * Default console logger for the Act framework.
14
- *
15
- * Production mode emits newline-delimited JSON (compatible with GCP, AWS
16
- * CloudWatch, Datadog, and other structured log ingestion systems).
17
- *
18
- * Development mode emits colorized, human-readable output.
19
- */
20
- export declare class ConsoleLogger implements Logger {
21
- level: string;
22
- private readonly _pretty;
23
- readonly fatal: Logger["fatal"];
24
- readonly error: Logger["error"];
25
- readonly warn: Logger["warn"];
26
- readonly info: Logger["info"];
27
- readonly debug: Logger["debug"];
28
- readonly trace: Logger["trace"];
29
- constructor(options?: {
30
- level?: string;
31
- pretty?: boolean;
32
- bindings?: Record<string, unknown>;
33
- });
34
- /** No-op — `console.log` has no resources to release. */
35
- dispose(): Promise<void>;
36
- /** @inheritDoc */
37
- child(bindings: Record<string, unknown>): Logger;
38
- private _jsonWrite;
39
- private _prettyWrite;
40
- }
41
- //# sourceMappingURL=console-logger.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"console-logger.d.ts","sourceRoot":"","sources":["../../../src/adapters/console-logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAwBhD;;;;;;;GAOG;AACH,qBAAa,aAAc,YAAW,MAAM;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAElC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;gBAG9B,OAAO,GAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC/B;IAwBR,yDAAyD;IACnD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAE9B,kBAAkB;IAClB,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM;IAQhD,OAAO,CAAC,UAAU;IAwClB,OAAO,CAAC,YAAY;CAmCrB"}