@rotorsoft/act 1.32.30 → 1.33.1
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/README.md +0 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/@types/act.d.ts +96 -385
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/adapters/in-memory-store.d.ts.map +1 -1
- package/dist/@types/builders/act-builder.d.ts +2 -115
- package/dist/@types/builders/act-builder.d.ts.map +1 -1
- package/dist/@types/builders/builder-utils.d.ts +1 -1
- package/dist/@types/builders/builder-utils.d.ts.map +1 -1
- package/dist/@types/builders/event-builder.d.ts +5 -5
- package/dist/@types/builders/event-builder.d.ts.map +1 -1
- package/dist/@types/builders/merge.d.ts +1 -1
- package/dist/@types/builders/merge.d.ts.map +1 -1
- package/dist/@types/builders/projection-builder.d.ts +2 -144
- package/dist/@types/builders/projection-builder.d.ts.map +1 -1
- package/dist/@types/builders/slice-builder.d.ts +2 -71
- package/dist/@types/builders/slice-builder.d.ts.map +1 -1
- package/dist/@types/builders/state-builder.d.ts +2 -376
- package/dist/@types/builders/state-builder.d.ts.map +1 -1
- package/dist/@types/config.d.ts +6 -43
- package/dist/@types/config.d.ts.map +1 -1
- package/dist/@types/csv.d.ts +1 -15
- package/dist/@types/csv.d.ts.map +1 -1
- package/dist/@types/index.d.ts +0 -1
- package/dist/@types/index.d.ts.map +1 -1
- package/dist/@types/internal/autoclose-policy.d.ts +1 -59
- package/dist/@types/internal/autoclose-policy.d.ts.map +1 -1
- package/dist/@types/internal/autoclose-reaction.d.ts +1 -2
- package/dist/@types/internal/autoclose-reaction.d.ts.map +1 -1
- package/dist/@types/internal/autoclose-window.d.ts +1 -1
- package/dist/@types/internal/autoclose-window.d.ts.map +1 -1
- package/dist/@types/internal/circuit-breaker.d.ts +1 -2
- package/dist/@types/internal/circuit-breaker.d.ts.map +1 -1
- package/dist/@types/{builders/build-classify.d.ts → internal/classify.d.ts} +2 -15
- package/dist/@types/internal/classify.d.ts.map +1 -0
- package/dist/@types/internal/close-cycle.d.ts.map +1 -1
- package/dist/@types/internal/config.d.ts +2 -42
- package/dist/@types/internal/config.d.ts.map +1 -1
- package/dist/@types/internal/correlate-cycle.d.ts +1 -1
- package/dist/@types/internal/correlate-cycle.d.ts.map +1 -1
- package/dist/@types/internal/{correlator.d.ts → correlation-id.d.ts} +1 -1
- package/dist/@types/internal/correlation-id.d.ts.map +1 -0
- package/dist/@types/internal/defer-config.d.ts.map +1 -1
- package/dist/@types/internal/drain-cycle.d.ts +1 -1
- package/dist/@types/internal/drain-cycle.d.ts.map +1 -1
- package/dist/@types/internal/{drain.d.ts → drain-ops.d.ts} +1 -1
- package/dist/@types/internal/drain-ops.d.ts.map +1 -0
- package/dist/@types/internal/event-sourcing.d.ts +1 -8
- package/dist/@types/internal/event-sourcing.d.ts.map +1 -1
- package/dist/@types/internal/{sensitive.d.ts → pii.d.ts} +4 -71
- package/dist/@types/internal/pii.d.ts.map +1 -0
- package/dist/@types/internal/projection-fold.d.ts +1 -2
- package/dist/@types/internal/projection-fold.d.ts.map +1 -1
- package/dist/@types/internal/{close-signal.d.ts → reaction-dispatch.d.ts} +47 -2
- package/dist/@types/internal/reaction-dispatch.d.ts.map +1 -0
- package/dist/@types/internal/report-once.d.ts +1 -1
- package/dist/@types/internal/settle.d.ts +21 -12
- package/dist/@types/internal/settle.d.ts.map +1 -1
- package/dist/@types/internal/tracing.d.ts +3 -3
- package/dist/@types/internal/tracing.d.ts.map +1 -1
- package/dist/@types/ports.d.ts +3 -43
- package/dist/@types/ports.d.ts.map +1 -1
- package/dist/@types/scoped.d.ts +1 -6
- package/dist/@types/scoped.d.ts.map +1 -1
- package/dist/@types/sensitive.d.ts +56 -0
- package/dist/@types/sensitive.d.ts.map +1 -0
- package/dist/@types/test/index.d.ts +1 -0
- package/dist/@types/test/index.d.ts.map +1 -1
- package/dist/@types/test/sandbox.d.ts +2 -26
- package/dist/@types/test/sandbox.d.ts.map +1 -1
- package/dist/@types/types/act.d.ts +214 -0
- package/dist/@types/types/act.d.ts.map +1 -0
- package/dist/@types/types/action.d.ts +69 -2
- package/dist/@types/types/action.d.ts.map +1 -1
- package/dist/@types/types/builders.d.ts +721 -0
- package/dist/@types/types/builders.d.ts.map +1 -0
- package/dist/@types/types/errors.d.ts +31 -1
- package/dist/@types/types/errors.d.ts.map +1 -1
- package/dist/@types/types/index.d.ts +38 -0
- package/dist/@types/types/index.d.ts.map +1 -1
- package/dist/@types/types/ports.d.ts +20 -18
- package/dist/@types/types/ports.d.ts.map +1 -1
- package/dist/@types/types/reaction.d.ts +11 -1
- package/dist/@types/types/reaction.d.ts.map +1 -1
- package/dist/@types/types/sandbox.d.ts +31 -0
- package/dist/@types/types/sandbox.d.ts.map +1 -0
- package/dist/@types/types/schemas.d.ts +12 -17
- package/dist/@types/types/schemas.d.ts.map +1 -1
- package/dist/chunk-NNWP65YM.cjs +264 -0
- package/dist/chunk-NNWP65YM.cjs.map +1 -0
- package/dist/{chunk-X3MMQIIP.js → chunk-NYH6FNTM.js} +174 -22
- package/dist/chunk-NYH6FNTM.js.map +1 -0
- package/dist/{chunk-HHKLVRR4.js → chunk-TJ4JRRUR.js} +38 -57
- package/dist/chunk-TJ4JRRUR.js.map +1 -0
- package/dist/chunk-YKL44PYX.cjs +1233 -0
- package/dist/chunk-YKL44PYX.cjs.map +1 -0
- package/dist/index.cjs +1954 -3440
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +911 -1063
- package/dist/index.js.map +1 -1
- package/dist/test/index.cjs +16 -1113
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.js +2 -2
- package/dist/test/index.js.map +1 -1
- package/dist/types/index.cjs +58 -276
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.js +15 -1
- package/package.json +2 -2
- package/dist/@types/builders/build-classify.d.ts.map +0 -1
- package/dist/@types/builders/builder-base.d.ts +0 -70
- package/dist/@types/builders/builder-base.d.ts.map +0 -1
- package/dist/@types/builders/reaction-builder.d.ts +0 -55
- package/dist/@types/builders/reaction-builder.d.ts.map +0 -1
- package/dist/@types/internal/close-signal.d.ts.map +0 -1
- package/dist/@types/internal/correlator.d.ts.map +0 -1
- package/dist/@types/internal/defer-signal.d.ts +0 -32
- package/dist/@types/internal/defer-signal.d.ts.map +0 -1
- package/dist/@types/internal/drain.d.ts.map +0 -1
- package/dist/@types/internal/index.d.ts +0 -38
- package/dist/@types/internal/index.d.ts.map +0 -1
- package/dist/@types/internal/sensitive.d.ts.map +0 -1
- package/dist/chunk-HHKLVRR4.js.map +0 -1
- package/dist/chunk-X3MMQIIP.js.map +0 -1
package/dist/@types/act.d.ts
CHANGED
|
@@ -1,225 +1,18 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
|
|
3
|
-
import { type Scoped } from "./ports.js";
|
|
4
|
-
import type { Actor, AsOf, AuditCategory, AuditFinding, AuditOptions, BatchHandler, BlockedLease, CloseResult, CloseTarget, Committed, Correlator, DoOptions, Drain, DrainOptions, EventSink, EventSource, IAct, LaneConfig, Lease, LoadTarget, Query, Registry, ScanOptions, ScanResult, Schema, SchemaRegister, Schemas, SettleOptions, ShutdownOptions, Snapshot, State, StoreNotification, StreamFilter, StreamPosition, Target } from "./types/index.js";
|
|
5
|
-
export { type AutocloseConfig, type AutoclosePolicy, DEFAULT_AUTOCLOSE_CYCLE_MINUTES, DEFAULT_CLOSE_BATCH_SIZE, DEFAULT_CLOSE_YIELD_MS, DEFAULT_MAX_SUBSCRIBED_STREAMS, DEFAULT_SETTLE_DEBOUNCE_MS, resolveAutocloseConfig, } from "./internal/index.js";
|
|
6
|
-
/**
|
|
7
|
-
* Lifecycle events emitted by {@link Act}, mapped to their payload type.
|
|
8
|
-
* Drives the typing of `emit` / `on` / `off` — the event-name argument
|
|
9
|
-
* narrows its payload at the call site.
|
|
10
|
-
*
|
|
11
|
-
* The first parameter is kept (unused) for arity compatibility: `committed`
|
|
12
|
-
* carries snapshots of whichever state each action targeted, so its honest
|
|
13
|
-
* element type is `Snapshot<Schema, TEvents>` — the register map itself was
|
|
14
|
-
* never the shape of any snapshot's state.
|
|
15
|
-
*/
|
|
16
|
-
export type ActLifecycleEvents<_TSchemaReg extends SchemaRegister<TActions>, TEvents extends Schemas, TActions extends Schemas> = {
|
|
17
|
-
committed: Snapshot<Schema, TEvents>[];
|
|
18
|
-
acked: Lease[];
|
|
19
|
-
blocked: BlockedLease[];
|
|
20
|
-
settled: Drain<TEvents>;
|
|
21
|
-
closed: CloseResult;
|
|
22
|
-
/**
|
|
23
|
-
* A **different process** committed an event to the same backing store.
|
|
24
|
-
*
|
|
25
|
-
* Fires only when the configured store implements
|
|
26
|
-
* {@link Store.notify} and there is at least one registered reaction.
|
|
27
|
-
* The orchestrator uses the same signal internally to wake `settle()`
|
|
28
|
-
* — listeners get the raw payload for SSE fan-out, dashboards, and
|
|
29
|
-
* audit logs.
|
|
30
|
-
*
|
|
31
|
-
* Local commits do *not* fire `notified` (use `committed` for those):
|
|
32
|
-
* stores self-filter their own writes so this channel has a clean
|
|
33
|
-
* cross-process semantic.
|
|
34
|
-
*/
|
|
35
|
-
notified: StoreNotification;
|
|
36
|
-
/**
|
|
37
|
-
* A stream's sensitive-data payload was wiped via {@link Act.forget}.
|
|
38
|
-
* Fires exactly once per successful `forget(stream)` call — idempotent
|
|
39
|
-
* second calls (no PII left on the stream) return `eventCount: 0` and
|
|
40
|
-
* do NOT re-emit. Apps that never call `forget()` never see this event.
|
|
41
|
-
*
|
|
42
|
-
* Listeners use it for the compliance side of GDPR / CCPA: audit log,
|
|
43
|
-
* downstream cache busts, projection-side wipes that the framework
|
|
44
|
-
* doesn't reach (e.g., search indexes, ETL caches). The framework's own
|
|
45
|
-
* cache is invalidated by `forget()` itself before the event fires.
|
|
46
|
-
*/
|
|
47
|
-
forgotten: {
|
|
48
|
-
stream: string;
|
|
49
|
-
at: Date;
|
|
50
|
-
eventCount: number;
|
|
51
|
-
};
|
|
52
|
-
/**
|
|
53
|
-
* A store operation failed during the drain loop. Fires on
|
|
54
|
-
* every failed drain cycle — typically a {@link StoreError} from a
|
|
55
|
-
* degraded backend — carrying the orchestrator circuit breaker's state
|
|
56
|
-
* after the failure (`open` means the drain loop has backed off and will
|
|
57
|
-
* retry after the cooldown). Listen to alert on a degraded store; the
|
|
58
|
-
* framework logs the same error regardless. Emitted only when a listener
|
|
59
|
-
* is registered (Node's `EventEmitter` throws on an unhandled `"error"`).
|
|
60
|
-
*/
|
|
61
|
-
error: {
|
|
62
|
-
error: unknown;
|
|
63
|
-
circuit: CircuitState;
|
|
64
|
-
};
|
|
65
|
-
};
|
|
66
|
-
/**
|
|
67
|
-
* Options for {@link Act} construction (passed via {@link ActBuilder.build}).
|
|
68
|
-
*
|
|
69
|
-
* @property maxSubscribedStreams - Cap for the LRU tracking what each
|
|
70
|
-
* dynamically resolved reaction target was last subscribed at. Statically
|
|
71
|
-
* declared targets are held outside it and never evicted, so their lane
|
|
72
|
-
* and priority stay owned by the build-time subscribe.
|
|
73
|
-
* Default: {@link DEFAULT_MAX_SUBSCRIBED_STREAMS}.
|
|
74
|
-
* @property settleDebounceMs - Debounce window (ms) used by `settle()` when
|
|
75
|
-
* the caller doesn't pass `SettleOptions.debounceMs`. Tune this once per
|
|
76
|
-
* Act instance instead of threading the value through every call site.
|
|
77
|
-
* Default: {@link DEFAULT_SETTLE_DEBOUNCE_MS}.
|
|
78
|
-
*/
|
|
79
|
-
export type ActOptions<TLanes extends string = string> = {
|
|
80
|
-
readonly maxSubscribedStreams?: number;
|
|
81
|
-
readonly settleDebounceMs?: number;
|
|
82
|
-
/**
|
|
83
|
-
* Per-Act ports. When set, this Act runs against the
|
|
84
|
-
* provided store + cache instead of the singletons — threaded via
|
|
85
|
-
* AsyncLocalStorage so internals are unchanged. Both are required
|
|
86
|
-
* together (a shared cache across distinct stores would collide on
|
|
87
|
-
* stream keys). Omit for the singleton path.
|
|
88
|
-
*/
|
|
89
|
-
readonly scoped?: Scoped;
|
|
90
|
-
/**
|
|
91
|
-
* Correlation-id generator for originating actions. When
|
|
92
|
-
* omitted, Act uses {@link default_correlator}, which produces a
|
|
93
|
-
* readable, time-monotonic-within-window, lowercase id of the form
|
|
94
|
-
* `{state[:4]}-{action[:4]}-{ts}{rnd}` (18 chars).
|
|
95
|
-
*
|
|
96
|
-
* Reactions inherit `reactingTo.meta.correlation` so the chain stays
|
|
97
|
-
* intact — the delegate is only consulted on originating commits and
|
|
98
|
-
* for the close-the-books transaction.
|
|
99
|
-
*/
|
|
100
|
-
readonly correlator?: Correlator;
|
|
101
|
-
/** Restrict this process to a subset of declared lanes. */
|
|
102
|
-
readonly onlyLanes?: ReadonlyArray<TLanes>;
|
|
103
|
-
/**
|
|
104
|
-
* Subscribe to {@link Store.notify} on this instance. Defaults
|
|
105
|
-
* to `true`. Set `false` on instances that only commit and never
|
|
106
|
-
* react — the subscriber-connection budget is the practical scaling
|
|
107
|
-
* ceiling for the notify/listen pattern, and writer-only fleets
|
|
108
|
-
* spend it for nothing when they subscribe to a channel they never
|
|
109
|
-
* read. Commits still emit notifications (that's part of the
|
|
110
|
-
* store's commit protocol); only the subscriber side is gated.
|
|
111
|
-
*/
|
|
112
|
-
readonly listen?: boolean;
|
|
113
|
-
/**
|
|
114
|
-
* Run the local reaction pipeline on this instance. Defaults
|
|
115
|
-
* to `true`. Set `false` on writer-only or sidecar instances: drain
|
|
116
|
-
* controllers' auto-cycle workers don't start, `correlate()` /
|
|
117
|
-
* `drain()` / `settle()` become no-ops, and the notify handler
|
|
118
|
-
* skips its drain-wakeup arm (but still emits the `notified`
|
|
119
|
-
* lifecycle event so observability sidecars work).
|
|
120
|
-
*/
|
|
121
|
-
readonly drain?: boolean;
|
|
122
|
-
/**
|
|
123
|
-
* Orchestrator circuit breaker for the drain loop. After
|
|
124
|
-
* `failureThreshold` consecutive store failures the breaker opens and
|
|
125
|
-
* the drain loop skips `claim()` for `cooldownMs` instead of hammering a
|
|
126
|
-
* down backend, then allows a half-open trial. Out-of-range values throw
|
|
127
|
-
* a `ZodError` at `act().build()`. Defaults: threshold 5, cooldown 30s.
|
|
128
|
-
*/
|
|
129
|
-
readonly circuitBreaker?: CircuitBreakerOptions;
|
|
130
|
-
/**
|
|
131
|
-
* @deprecated Accepted, validated, and ignored. It paced the off-hours
|
|
132
|
-
* re-check of the old autoclose sweep; the synthesized autoclose reaction now derives its re-check
|
|
133
|
-
* directly from `autocloseWindow` — a tick landing outside the window
|
|
134
|
-
* parks until the exact instant the window opens, so there is no
|
|
135
|
-
* polling cadence to configure (and nothing minute-denominated on the
|
|
136
|
-
* close surface). Still validated as an integer `[1, 1440]` so typos
|
|
137
|
-
* keep failing loudly at `act().build()`. Will be removed in the next
|
|
138
|
-
* major.
|
|
139
|
-
*/
|
|
140
|
-
readonly autocloseCycleMinutes?: number;
|
|
141
|
-
/**
|
|
142
|
-
* @deprecated Unused since the autoclose sweep was replaced by a
|
|
143
|
-
* synthesized per-aggregate reaction — nothing pages the store in
|
|
144
|
-
* batches anymore, so nothing reads this. Accepted and validated
|
|
145
|
-
* (`[1, 1024]`) for compatibility; will be removed in the next major.
|
|
146
|
-
*/
|
|
147
|
-
readonly closeBatchSize?: number;
|
|
148
|
-
/**
|
|
149
|
-
* @deprecated Unused: the sweep that yielded between
|
|
150
|
-
* successive `Store.truncate` calls no longer exists; closes are
|
|
151
|
-
* staged per stream by the autoclose reaction. Accepted and validated
|
|
152
|
-
* (`[0, 1000]`) for compatibility; will be removed in the next major.
|
|
153
|
-
*/
|
|
154
|
-
readonly closeYieldMs?: number;
|
|
155
|
-
/**
|
|
156
|
-
* @deprecated Unused: the sweep-side predicate try/catch
|
|
157
|
-
* this flag steered no longer exists; a throwing policy predicate now
|
|
158
|
-
* follows the reaction retry path (`blockOnError: false`, three
|
|
159
|
-
* retries). Accepted for compatibility; will be removed in the next
|
|
160
|
-
* major.
|
|
161
|
-
*/
|
|
162
|
-
readonly closeOnError?: boolean;
|
|
163
|
-
/**
|
|
164
|
-
* Optional off-hours window restricting when autoclose evaluates. A
|
|
165
|
-
* synthesized autoclose reaction that triggers outside the window
|
|
166
|
-
* defers to the next instant the window opens — derived from the
|
|
167
|
-
* window itself, no polling cadence. Hours are `[0, 23]` integers in
|
|
168
|
-
* `timeZone` (IANA, default `"UTC"`, DST-correct); `start > end` is
|
|
169
|
-
* an overnight window (e.g. `{ start: 22, end: 6 }`). Omit to
|
|
170
|
-
* evaluate regardless of clock time.
|
|
171
|
-
*/
|
|
172
|
-
readonly autocloseWindow?: {
|
|
173
|
-
readonly start: number;
|
|
174
|
-
readonly end: number;
|
|
175
|
-
readonly timeZone?: string;
|
|
176
|
-
};
|
|
177
|
-
/**
|
|
178
|
-
* Validate folded state against its declared Zod schema after every
|
|
179
|
-
* reduction. Off by default.
|
|
180
|
-
*
|
|
181
|
-
* When `true`, each time an event is folded into state — on the
|
|
182
|
-
* command path (`do`), on `load`/replay, and inside projection-fold
|
|
183
|
-
* projections — the merged full state is parsed against the owning
|
|
184
|
-
* state's `state({ Name: schema })` schema. A reducer that produces
|
|
185
|
-
* schema-violating state (the calculator divide-by-zero NaN
|
|
186
|
-
* class) throws a {@link ValidationError} at the triggering event,
|
|
187
|
-
* whose `target` names the state and the event (`<state>.<event>#<id>`)
|
|
188
|
-
* — instead of the bad value propagating and surfacing hops later as a
|
|
189
|
-
* confusing downstream error.
|
|
190
|
-
*
|
|
191
|
-
* This is a **debugging / CI aid, not a production guard**. Turn it on
|
|
192
|
-
* in development and CI to catch total-reducer bugs at the source; the
|
|
193
|
-
* framework already validates action inputs and emitted events, so the
|
|
194
|
-
* reduced state is the one shape it otherwise trusts. The per-event
|
|
195
|
-
* patch step is selected **once at `build()`** (the same way the
|
|
196
|
-
* orchestrator picks bare vs trace-decorated store ops from the log
|
|
197
|
-
* level): when `false` (the default) the fold loop is byte-identical to
|
|
198
|
-
* a bare reduction — the validating patch step is never selected, so
|
|
199
|
-
* there is no per-event cost, not even a branch.
|
|
200
|
-
*/
|
|
201
|
-
readonly validateFoldedState?: boolean;
|
|
202
|
-
};
|
|
1
|
+
import { type ActLifecycleEvents, type ActOptions } from "./types/act.js";
|
|
2
|
+
import type { Actor, AsOf, AuditCategory, AuditFinding, AuditOptions, BatchHandler, CloseResult, CloseTarget, Committed, DoOptions, Drain, DrainOptions, EventSink, EventSource, IAct, LaneConfig, LoadTarget, PatchFn, Query, Registry, ScanOptions, ScanResult, Schema, SchemaRegister, Schemas, SettleOptions, ShutdownOptions, Snapshot, State, StreamFilter, StreamPosition, Target } from "./types/index.js";
|
|
203
3
|
/**
|
|
204
4
|
* @category Orchestrator
|
|
205
5
|
* @see Store
|
|
206
6
|
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
* It manages the lifecycle of actions, reactions, and event streams, providing APIs for loading state, executing actions, querying events, and draining reactions.
|
|
210
|
-
*
|
|
211
|
-
* ## Usage
|
|
7
|
+
* The orchestrator: executes actions, loads state, queries events, and runs
|
|
8
|
+
* the reactions each commit frees (on its own, unless `autoSettle: false`).
|
|
212
9
|
*
|
|
213
10
|
* ```typescript
|
|
214
11
|
* const app = act().withState(Counter).build();
|
|
215
12
|
* await app.do("increment", { stream: "counter1", actor }, { by: 1 });
|
|
216
13
|
* const snapshot = await app.load(Counter, "counter1");
|
|
217
|
-
* await app.drain();
|
|
218
14
|
* ```
|
|
219
15
|
*
|
|
220
|
-
* - Register event listeners with `.on("committed", ...)` and `.on("acked", ...)` to react to lifecycle events.
|
|
221
|
-
* - Use `.query()` to analyze event streams for analytics or debugging.
|
|
222
|
-
*
|
|
223
16
|
* @template TSchemaReg SchemaRegister for state
|
|
224
17
|
* @template TEvents Schemas for events
|
|
225
18
|
* @template TActions Schemas for actions
|
|
@@ -231,14 +24,15 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
231
24
|
private readonly _breaker;
|
|
232
25
|
private readonly _listen;
|
|
233
26
|
private readonly _drain;
|
|
27
|
+
private readonly _auto_settle;
|
|
234
28
|
/** Whether any event has a reaction; nothing arms without one. */
|
|
235
29
|
private readonly _reactive;
|
|
236
30
|
private readonly _drain_controllers;
|
|
237
31
|
private readonly _correlate;
|
|
238
32
|
private readonly _settle;
|
|
239
33
|
private _poll;
|
|
240
|
-
/** The
|
|
241
|
-
private
|
|
34
|
+
/** The poll's correlate `limit`, used by every settle pass while it runs. */
|
|
35
|
+
private _poll_limit;
|
|
242
36
|
/**
|
|
243
37
|
* Wired at construction against the store current then, so a store
|
|
244
38
|
* injected after `build()` is never notified.
|
|
@@ -318,21 +112,14 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
318
112
|
private _build_settle;
|
|
319
113
|
private _shutdown_promise;
|
|
320
114
|
/**
|
|
321
|
-
* Per-instance teardown:
|
|
322
|
-
*
|
|
323
|
-
* listeners and
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
* out, teardown proceeds anyway.
|
|
330
|
-
*
|
|
331
|
-
* Idempotent — repeated calls return the same promise, and the first
|
|
332
|
-
* call's `graceMs` is the one that applies. Registered automatically with
|
|
333
|
-
* the global `dispose()` registry at construction, so process-wide
|
|
334
|
-
* `dispose()()` covers it; test helpers (or operators that mint
|
|
335
|
-
* short-lived Acts) call it explicitly for prompt cleanup.
|
|
115
|
+
* Per-instance teardown: stops scheduling, gives the cycles in flight up
|
|
116
|
+
* to `graceMs` to reach their `ack` (an abandoned handler holds its lease
|
|
117
|
+
* until it expires), then removes listeners and the notify subscription.
|
|
118
|
+
* The budget is a ceiling, not a delay.
|
|
119
|
+
*
|
|
120
|
+
* Idempotent: repeated calls return the same promise, with the first
|
|
121
|
+
* call's `graceMs`. Registered with the global `dispose()` registry, so
|
|
122
|
+
* `dispose()()` covers it; call it directly for prompt cleanup.
|
|
336
123
|
*
|
|
337
124
|
* @param options - See {@link ShutdownOptions}. Defaults the grace budget
|
|
338
125
|
* to the largest lane `leaseMillis` (capped at 30s).
|
|
@@ -347,15 +134,10 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
347
134
|
/** Failures are logged, never thrown: `notify` is a hint. */
|
|
348
135
|
private _wire_notify;
|
|
349
136
|
/**
|
|
350
|
-
* Executes an action
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
* 2. Loads the current state snapshot
|
|
355
|
-
* 3. Checks invariants (business rules)
|
|
356
|
-
* 4. Executes the action handler to generate events
|
|
357
|
-
* 5. Applies events to create new state
|
|
358
|
-
* 6. Commits events to the store with optimistic concurrency control
|
|
137
|
+
* Executes an action: validates the payload, loads the state, checks its
|
|
138
|
+
* invariants, and commits the events its handler emits, with optimistic
|
|
139
|
+
* concurrency on the stream. The reactions to those events settle on
|
|
140
|
+
* their own (unless `autoSettle: false`).
|
|
359
141
|
*
|
|
360
142
|
* @template TKey - Action name from registered actions
|
|
361
143
|
* @param action - The name of the action to execute
|
|
@@ -429,9 +211,7 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
429
211
|
*
|
|
430
212
|
* For small result sets, consider using {@link query_array} instead.
|
|
431
213
|
*
|
|
432
|
-
* @param query - Filter criteria
|
|
433
|
-
* (`stream`, `name`, `after`, `before`, `created_after`, `created_before`,
|
|
434
|
-
* `limit`, `with_snaps`, `stream_exact`)
|
|
214
|
+
* @param query - Filter criteria; see {@link Query} for the fields
|
|
435
215
|
* @param callback - Optional callback invoked for each matching event
|
|
436
216
|
* @returns Object with first event, last event, and total count
|
|
437
217
|
*
|
|
@@ -486,31 +266,23 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
486
266
|
eventCount: number;
|
|
487
267
|
}>;
|
|
488
268
|
/**
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
*
|
|
492
|
-
* 1. Polls the store for streams with uncommitted events
|
|
493
|
-
* 2. Leases streams to prevent concurrent processing
|
|
494
|
-
* 3. Fetches events for each leased stream
|
|
495
|
-
* 4. Executes matching reaction handlers
|
|
496
|
-
* 5. Acknowledges successful reactions or blocks failing ones
|
|
269
|
+
* Runs one drain cycle: claims streams with marked work (leasing them),
|
|
270
|
+
* fetches their events, runs the matching reactions, and acks or blocks
|
|
271
|
+
* each stream.
|
|
497
272
|
*
|
|
498
|
-
*
|
|
499
|
-
*
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
* `correlate` is the only component that raises that mark, so a
|
|
504
|
-
* commit no correlate has seen is not drainable, static targets included. For a
|
|
505
|
-
* higher-level API that handles debouncing, correlation, and signaling
|
|
506
|
-
* automatically, use {@link settle}.
|
|
273
|
+
* A stream is claimable only once `correlate()` has marked it, static
|
|
274
|
+
* targets included, so a commit no correlate has seen is not drainable.
|
|
275
|
+
* Apps rarely call this: each commit settles its reactions on its own.
|
|
276
|
+
* With `autoSettle: false`, tests walk the pipeline with `correlate()`
|
|
277
|
+
* then `drain()` (see the testing guide).
|
|
507
278
|
*
|
|
508
279
|
* @param options - Drain configuration — see {@link DrainOptions} for fields
|
|
509
280
|
* (`streamLimit`, `eventLimit`, `leaseMillis`).
|
|
510
281
|
* @returns Drain statistics with fetched, leased, acked, and blocked counts
|
|
511
282
|
*
|
|
512
|
-
* @example
|
|
283
|
+
* @example Walking the pipeline in a test
|
|
513
284
|
* ```typescript
|
|
285
|
+
* const app = act().withState(User).withProjection(Users).build({ autoSettle: false });
|
|
514
286
|
* await app.do("createUser", target, payload);
|
|
515
287
|
* await app.correlate();
|
|
516
288
|
* await app.drain();
|
|
@@ -518,41 +290,36 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
518
290
|
*
|
|
519
291
|
* @see {@link settle} for debounced correlate→drain with lifecycle events
|
|
520
292
|
* @see {@link correlate} for dynamic stream discovery
|
|
521
|
-
* @see {@link start_correlations} for automatic correlation
|
|
522
293
|
*/
|
|
523
294
|
drain(options?: DrainOptions): Promise<Drain<TEvents>>;
|
|
524
295
|
private _arm_all;
|
|
296
|
+
/**
|
|
297
|
+
* Settles what a change armed (a commit, a reset, an unblock, a restore,
|
|
298
|
+
* a notification from another process), unless the app walks the
|
|
299
|
+
* pipeline itself (`autoSettle: false`).
|
|
300
|
+
*/
|
|
301
|
+
private _settle_armed;
|
|
302
|
+
/** Schedules a settle pass; writer-only instances (`drain: false`) skip it. */
|
|
303
|
+
private _schedule;
|
|
525
304
|
/** Arms only the lanes these events react on; true when any was armed. */
|
|
526
305
|
private _arm_for_event_names;
|
|
527
306
|
/** In parallel, so a slow lane never holds up a fast one. */
|
|
528
307
|
private _drain_all;
|
|
529
308
|
/**
|
|
530
|
-
*
|
|
531
|
-
*
|
|
532
|
-
*
|
|
533
|
-
* based on event content. For example, you might create a stats stream for each user
|
|
534
|
-
* when they perform certain actions.
|
|
535
|
-
*
|
|
536
|
-
* This method scans events matching the query and identifies new target streams based
|
|
537
|
-
* on reaction resolvers. It then registers these streams so they'll be picked up by
|
|
538
|
-
* the next drain cycle.
|
|
309
|
+
* Scans committed events from the correlation checkpoint, subscribes the
|
|
310
|
+
* target streams their reactions resolve to (static or computed from
|
|
311
|
+
* the event), and marks their work so the next drain can claim it.
|
|
539
312
|
*
|
|
540
313
|
* @param query - Scan filter — see {@link Query} for fields (typically
|
|
541
|
-
* `{
|
|
314
|
+
* `{ limit: <count> }`; the scan starts at the checkpoint)
|
|
542
315
|
* @returns The number of newly subscribed streams and the last scanned event id
|
|
543
316
|
*
|
|
544
317
|
* @example Manual correlation
|
|
545
318
|
* ```typescript
|
|
546
|
-
*
|
|
547
|
-
* const { subscribed, last_id } = await app.correlate({ after: 0, limit: 100 });
|
|
548
|
-
* console.log(`Subscribed ${subscribed} new streams`);
|
|
549
|
-
*
|
|
550
|
-
* // Save last_id for next scan
|
|
551
|
-
* await saveCheckpoint(last_id);
|
|
319
|
+
* const { subscribed } = await app.correlate({ limit: 100 });
|
|
552
320
|
* ```
|
|
553
321
|
*
|
|
554
322
|
* @see {@link start_correlations} for automatic periodic correlation
|
|
555
|
-
* @see {@link stop_correlations} to stop automatic correlation
|
|
556
323
|
*/
|
|
557
324
|
correlate(query?: Query): Promise<{
|
|
558
325
|
subscribed: number;
|
|
@@ -576,9 +343,6 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
576
343
|
* reads (default 100). The scan always starts at the correlation
|
|
577
344
|
* checkpoint, so `after` is ignored.
|
|
578
345
|
* @param frequency - Milliseconds between ticks (default: 10000)
|
|
579
|
-
* @param callback - Called with the number of newly subscribed streams
|
|
580
|
-
* after each correlate pass that found some.
|
|
581
|
-
* @deprecated Listen to the `"settled"` lifecycle event instead.
|
|
582
346
|
* @returns `true` if the poll started, `false` if one is already running
|
|
583
347
|
*
|
|
584
348
|
* @example
|
|
@@ -591,7 +355,7 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
591
355
|
* @see {@link settle} for what each tick runs
|
|
592
356
|
* @see {@link stop_correlations} to stop the poll
|
|
593
357
|
*/
|
|
594
|
-
start_correlations(query?: Query, frequency?: number
|
|
358
|
+
start_correlations(query?: Query, frequency?: number): boolean;
|
|
595
359
|
/**
|
|
596
360
|
* Stops the poll started by {@link start_correlations}. Idempotent, and
|
|
597
361
|
* called by `shutdown()`.
|
|
@@ -600,25 +364,24 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
600
364
|
*/
|
|
601
365
|
stop_correlations(): void;
|
|
602
366
|
/**
|
|
603
|
-
*
|
|
367
|
+
* Drops the settle pass scheduled but not yet started. A cycle already
|
|
368
|
+
* running finishes; later changes schedule new passes.
|
|
604
369
|
*
|
|
605
370
|
* @see {@link settle}
|
|
606
371
|
*/
|
|
607
372
|
stop_settling(): void;
|
|
608
373
|
/**
|
|
609
|
-
* Reset reaction stream watermarks and
|
|
610
|
-
*
|
|
374
|
+
* Reset reaction stream watermarks and settle them, replaying their
|
|
375
|
+
* events through their reactions.
|
|
611
376
|
*
|
|
612
377
|
* Use this to replay events through projections (or other reaction targets)
|
|
613
|
-
* after changing handler logic.
|
|
614
|
-
*
|
|
615
|
-
*
|
|
616
|
-
*
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
*
|
|
620
|
-
* fully catches up paginated streams without forcing callers to roll
|
|
621
|
-
* their own loop.
|
|
378
|
+
* after changing handler logic. It rewinds the same watermarks as
|
|
379
|
+
* `store().reset(streams)`, and also wakes the drain and schedules a
|
|
380
|
+
* settle, which loops correlate→drain until the replay catches up;
|
|
381
|
+
* `store().reset(...)` alone leaves a settled app idle. Call
|
|
382
|
+
* `app.settle(options)` right after to give that pass batch options, or,
|
|
383
|
+
* with `autoSettle: false`, `correlate()` / `drain()` to drive the replay
|
|
384
|
+
* by hand.
|
|
622
385
|
*
|
|
623
386
|
* @param input - Reaction target streams (e.g., projection names) to reset, or a {@link StreamFilter} for bulk operations
|
|
624
387
|
* @returns Count of streams that were actually reset
|
|
@@ -626,7 +389,7 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
626
389
|
* @example Rebuild a projection (production)
|
|
627
390
|
* ```typescript
|
|
628
391
|
* await app.reset(["my-projection"]);
|
|
629
|
-
* app.settle({ eventLimit: 1000 });
|
|
392
|
+
* app.settle({ eventLimit: 1000 }); // optional: bigger batches; emits "settled"
|
|
630
393
|
* ```
|
|
631
394
|
*
|
|
632
395
|
* @see {@link Store.reset} for the underlying store primitive
|
|
@@ -642,11 +405,9 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
642
405
|
* {@link reset}, which rebuilds from event 0 (suitable for projection
|
|
643
406
|
* rebuilds, wrong for "I fixed the bug, please retry").
|
|
644
407
|
*
|
|
645
|
-
* Wraps `store().unblock(streams)` and
|
|
646
|
-
*
|
|
647
|
-
*
|
|
648
|
-
* directly, but `store().unblock(...)` alone leaves the flag
|
|
649
|
-
* untouched.
|
|
408
|
+
* Wraps `store().unblock(streams)` and settles the now-free streams on
|
|
409
|
+
* its own. `store().unblock(...)` alone leaves them waiting for the next
|
|
410
|
+
* commit.
|
|
650
411
|
*
|
|
651
412
|
* @param input - Stream names to unblock, or a {@link StreamFilter} for bulk recovery
|
|
652
413
|
* @returns Count of streams that were actually flipped (were blocked)
|
|
@@ -723,64 +484,30 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
723
484
|
limit?: number;
|
|
724
485
|
}): Promise<StreamPosition[]>;
|
|
725
486
|
/**
|
|
726
|
-
* Operator-driven store audit
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
*
|
|
730
|
-
* driven category as `app.close()` / `app.reset()` /
|
|
731
|
-
* `app.unblock()` / `app.blocked_streams()`: never auto-invoked by
|
|
732
|
-
* the framework; the operator decides when to run it (CI gate,
|
|
733
|
-
* scheduled job, ad-hoc forensics) and what to do with the
|
|
734
|
-
* findings.
|
|
487
|
+
* Operator-driven store audit: walks the store and yields findings per
|
|
488
|
+
* category, each with the remediation it suggests. Never run by the
|
|
489
|
+
* framework. Pass a subset of categories to scope the work; the iterable
|
|
490
|
+
* can be broken early, and findings stream without buffering the report.
|
|
735
491
|
*
|
|
736
|
-
*
|
|
737
|
-
*
|
|
492
|
+
* @param categories - Subset of categories to run (default: all).
|
|
493
|
+
* @param options - Query window + per-category thresholds.
|
|
494
|
+
* @returns Async iterable of {@link AuditFinding}.
|
|
738
495
|
*
|
|
496
|
+
* @example Schema drift since the last scan
|
|
739
497
|
* ```typescript
|
|
740
|
-
*
|
|
741
|
-
* for await (const f of app.audit(["schema", "deprecated-load"], {
|
|
742
|
-
* query: { created_after: lastScan },
|
|
743
|
-
* thresholds: { deprecatedLoadShareMin: 0.10 },
|
|
744
|
-
* })) {
|
|
498
|
+
* for await (const f of app.audit(["schema"], { query: { created_after: lastScan } }))
|
|
745
499
|
* await escalate(f);
|
|
746
|
-
* }
|
|
747
|
-
*
|
|
748
|
-
* // Full audit, default thresholds
|
|
749
|
-
* for await (const f of app.audit()) console.log(f);
|
|
750
500
|
* ```
|
|
751
|
-
*
|
|
752
|
-
* Returns an `AsyncIterable` so callers can `break` early — the
|
|
753
|
-
* underlying store paginations respect the iterator protocol and
|
|
754
|
-
* stop cleanly. Each finding is emitted independently, so
|
|
755
|
-
* pipelining into Slack / persistence / further analysis works
|
|
756
|
-
* without buffering the full report in memory.
|
|
757
|
-
*
|
|
758
|
-
* Findings shape — see {@link AuditFinding}. The discriminated
|
|
759
|
-
* union carries enough context for the operator to act on each
|
|
760
|
-
* finding directly: stream id, event id, recommendation hints.
|
|
761
|
-
*
|
|
762
|
-
* @param categories - Subset of categories to run (default: all).
|
|
763
|
-
* @param options - Query window + per-category thresholds.
|
|
764
|
-
* @returns Async iterable of {@link AuditFinding}.
|
|
765
501
|
*/
|
|
766
502
|
audit(categories?: AuditCategory[], options?: AuditOptions): AsyncIterable<AuditFinding>;
|
|
767
503
|
/**
|
|
768
|
-
*
|
|
769
|
-
*
|
|
770
|
-
*
|
|
771
|
-
*
|
|
772
|
-
*
|
|
773
|
-
*
|
|
774
|
-
*
|
|
775
|
-
* `max()` invariant across reactions; this API ignores that and
|
|
776
|
-
* sets the priority outright on every matching row.
|
|
777
|
-
*
|
|
778
|
-
* Filter shape mirrors {@link query} / {@link Store.query_streams}:
|
|
779
|
-
* `stream` / `source` are regex by default, exact with the
|
|
780
|
-
* `*_exact` flags; `blocked` restricts to blocked or unblocked
|
|
781
|
-
* rows. **An empty filter (`{}`) updates every registered stream.**
|
|
782
|
-
*
|
|
783
|
-
* @param filter - Selection criteria (regex by default).
|
|
504
|
+
* Sets the scheduling priority of every stream matching `filter`, as-is:
|
|
505
|
+
* unlike build-time priorities (the highest across reactions wins), this
|
|
506
|
+
* overrides them. Useful to let a long replay jump ahead of other lagging
|
|
507
|
+
* streams, or to yield slots back. **An empty filter (`{}`) updates every
|
|
508
|
+
* registered stream.**
|
|
509
|
+
*
|
|
510
|
+
* @param filter - Selection criteria (regex by default, like {@link query}).
|
|
784
511
|
* @param priority - New priority value. Set as-is — no clamp.
|
|
785
512
|
* @returns Count of streams whose priority changed.
|
|
786
513
|
*
|
|
@@ -790,36 +517,17 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
790
517
|
* ```
|
|
791
518
|
*
|
|
792
519
|
* @see {@link Store.prioritize} for the underlying primitive
|
|
793
|
-
* @see {@link claim} for how priority biases scheduling
|
|
794
520
|
*/
|
|
795
521
|
prioritize(filter: StreamFilter, priority: number): Promise<number>;
|
|
796
522
|
/** Shared by `close()` and reaction-requested closes. */
|
|
797
523
|
private _run_close;
|
|
798
524
|
/**
|
|
799
|
-
* Close the books
|
|
800
|
-
*
|
|
801
|
-
*
|
|
802
|
-
*
|
|
803
|
-
*
|
|
804
|
-
*
|
|
805
|
-
* 3. **Guard** — commit `__tombstone__` with `expectedVersion` to block concurrent writes
|
|
806
|
-
* 4. **Load state** — for streams in `snapshots`, load final state while guarded (no races)
|
|
807
|
-
* 5. **Archive** — user callback per stream (abort-all on failure, streams are guarded)
|
|
808
|
-
* 6. **Truncate + seed** — atomic: delete all events, insert `__snapshot__` or `__tombstone__`
|
|
809
|
-
* 7. **Cache** — invalidate (tombstoned) or warm (restarted)
|
|
810
|
-
* 8. **Emit "closed"** — lifecycle event with results
|
|
811
|
-
*
|
|
812
|
-
* Targets carrying `before` take the **windowed** branch instead —
|
|
813
|
-
* close the books on a rolling window: probe the min consumer
|
|
814
|
-
* watermark (so the boundary never rises past a lagging reaction),
|
|
815
|
-
* run the archive callback against the cutoff, then prune the prefix
|
|
816
|
-
* below the closest safe `__snapshot__`. No tombstone guard (the
|
|
817
|
-
* pre-cutoff prefix is immutable), no seed, cache untouched — the
|
|
818
|
-
* stream stays live and keeps accepting actions. Requires the state
|
|
819
|
-
* to snapshot via `.snap(...)`; no qualifying snapshot ⇒ the stream
|
|
820
|
-
* lands in `skipped` (retry after the next snapshot). Windowed
|
|
821
|
-
* entries in the result echo `before` and carry the surviving
|
|
822
|
-
* boundary snapshot as `committed`.
|
|
525
|
+
* Close the books: guard, archive, truncate, and optionally restart
|
|
526
|
+
* streams. A stream with pending reactions is skipped; an archive
|
|
527
|
+
* failure aborts the whole close while the streams are still guarded.
|
|
528
|
+
* Targets carrying `before` prune a rolling window instead and leave the
|
|
529
|
+
* stream live (needs `.snap(...)`). The phases and their failure
|
|
530
|
+
* semantics are in the close-cycle architecture page.
|
|
823
531
|
*
|
|
824
532
|
* @param targets - Per-stream close options (stream, restart?, archive?, before?)
|
|
825
533
|
* @returns `{ truncated: TruncateResult, skipped: string[] }`
|
|
@@ -836,25 +544,28 @@ export declare class Act<TSchemaReg extends SchemaRegister<TActions>, TEvents ex
|
|
|
836
544
|
/**
|
|
837
545
|
* Debounced, non-blocking correlate→drain cycle.
|
|
838
546
|
*
|
|
839
|
-
*
|
|
840
|
-
*
|
|
841
|
-
*
|
|
842
|
-
*
|
|
843
|
-
*
|
|
844
|
-
*
|
|
845
|
-
*
|
|
846
|
-
*
|
|
547
|
+
* A local change that frees reaction work (a commit, `reset()`,
|
|
548
|
+
* `unblock()`, `restore()`) schedules this on its own unless the app
|
|
549
|
+
* sets `autoSettle: false`. Call it at startup, to run what was pending
|
|
550
|
+
* before a restart, or with options for the next pass. A pass already
|
|
551
|
+
* scheduled is never put off: calls before it runs join it (a shorter
|
|
552
|
+
* `debounceMs` brings it forward), and a call during a running cycle
|
|
553
|
+
* queues one more pass after it. Runs correlate→drain in a loop until a pass makes no
|
|
554
|
+
* progress — no new subscriptions, no events read, no streams leased —
|
|
555
|
+
* then emits the `"settled"` lifecycle event, so one call fully catches
|
|
556
|
+
* up paginated streams without forcing callers to loop.
|
|
847
557
|
*
|
|
848
558
|
* @param options - Settle configuration — see {@link SettleOptions} for fields:
|
|
849
|
-
* `debounceMs` (default 10), `correlate` (default
|
|
559
|
+
* `debounceMs` (default 10), `correlate.limit` (default 100, or the
|
|
560
|
+
* poll's limit while `start_correlations` runs; `after` is always the
|
|
561
|
+
* checkpoint),
|
|
850
562
|
* `maxPasses` (default `Infinity` — kill-switch for runaway loops),
|
|
851
563
|
* `streamLimit` (default 10), `eventLimit` (default 10),
|
|
852
564
|
* `leaseMillis` (default 10000).
|
|
853
565
|
*
|
|
854
|
-
* @example
|
|
566
|
+
* @example Startup
|
|
855
567
|
* ```typescript
|
|
856
|
-
*
|
|
857
|
-
* app.settle(); // non-blocking, returns immediately
|
|
568
|
+
* app.settle(); // run what was pending before the restart
|
|
858
569
|
*
|
|
859
570
|
* app.on("settled", (drain) => {
|
|
860
571
|
* // notify SSE clients, invalidate caches, etc.
|