@rotorsoft/act 1.32.22 → 1.32.24

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.
@@ -1,190 +1,53 @@
1
1
  /**
2
- * @module event-sourcing
3
- * @category Internal
4
- *
5
- * Pure event-sourcing primitives: `snap` persists state checkpoints, `load`
6
- * reconstructs state by folding events through reducers, and `action`
7
- * validates an action, runs invariants, emits events, and commits them
8
- * atomically. `tombstone` commits the close-the-books guard with optimistic
9
- * concurrency.
10
- *
11
- * These are the bare implementations — observability is layered on top in
12
- * {@link "tracing"} and wired by the orchestrator at construction time.
13
- * No tracing imports here, no module-level mutable state.
14
- *
15
- * @internal
2
+ * Event-sourcing primitives: `snap`, `load`, `action`, `tombstone`, `scan`.
3
+ * Bare implementations; tracing wraps them in `tracing.ts`.
16
4
  */
17
5
  import { type Patch } from "@rotorsoft/act-patch";
18
6
  import type { Committed, DoOptions, EventSource, LoadTarget, ScanOptions, ScanResult, Schema, Schemas, Snapshot, State, Target } from "../types/index.js";
19
7
  /**
20
- * The reduction pipeline names three distinct things, and each word means
21
- * exactly one of them:
22
- *
23
- * - a **reducer** is a state's `.patch()` handler — it takes one event and
24
- * returns a {@link Patch} *partial*;
25
- * - a **patch step** ({@link bare_patch} / {@link validating_patch}) merges
26
- * that partial into the current state, yielding the next full state;
27
- * - the **fold** is the loop that applies the patch step across a stream's
28
- * events (the reader loop in {@link load} / {@link action}, and the
29
- * projection engine in {@link "projection-fold"}).
30
- *
31
- * `PatchFn` is the per-event patch step. The fold loop calls one of two
32
- * implementations, selected **once** at construction (in
33
- * {@link "tracing".build_es}) — never branched per event:
34
- *
35
- * - {@link bare_patch} — the default. Literally `patch(state, partial)`,
36
- * no wrapper. No validation cost on the hot path.
37
- * - {@link validating_patch} — the opt-in `ActOptions.validateFoldedState`
38
- * path. Merges, then parses the merged full state against the state's
39
- * declared Zod schema.
40
- *
41
- * The `me`/`event` arguments are unused by the bare implementation but
42
- * carried on the shared signature so the fold loop is call-shape-identical
43
- * regardless of which patch step was selected — the validating
44
- * implementation needs them to name the failing reduction.
45
- *
46
- * @internal
8
+ * The patch step: merges a reducer's partial into state. Chosen once at
9
+ * construction (`build_es`), never per event. `me`/`event` only serve
10
+ * {@link validating_patch}, to name the failing reduction.
47
11
  */
48
12
  export type PatchFn = <TState extends Schema, TEvents extends Schemas, TActions extends Schemas>(me: State<TState, TEvents, TActions>, state: TState, partial: Readonly<Patch<TState>>, event: Committed<TEvents, keyof TEvents>) => TState;
49
- /**
50
- * The default patch step: a bare `patch()` merge with no wrapper and no
51
- * branch. The off-path is a plain reduction, so an
52
- * app that leaves `validateFoldedState` off pays nothing — not even a
53
- * comparison.
54
- *
55
- * @internal
56
- */
13
+ /** The default patch step: a bare merge, so the hot path pays nothing. */
57
14
  export declare const bare_patch: PatchFn;
58
15
  /**
59
- * The opt-in patch step: merge the partial into state, then
60
- * parse the merged full state against the owning state's declared Zod
61
- * schema. A reducer that produces schema-violating state (the calculator
62
- * divide-by-zero NaN class) fails here, at the triggering event,
63
- * instead of propagating and surfacing hops later as a confusing
64
- * downstream error.
65
- *
66
- * The `target` string names the state and the triggering event
67
- * (`"<state>.<event>#<id>"`) so the resulting {@link ValidationError}
68
- * points straight at the reduction that produced bad state. A debugging /
69
- * CI aid, not a production guard — selected only when the operator opts
70
- * in.
71
- *
72
- * @internal
16
+ * `validateFoldedState`: merge, then parse against the state schema, so a
17
+ * bad reducer fails at its own event. A debugging aid, not a production guard.
73
18
  */
74
19
  export declare const validating_patch: PatchFn;
75
- /**
76
- * Internal action signature seen by the orchestrator — the {@link Correlator}
77
- * is bound at `build_es` time, so callers don't pass it through.
78
- *
79
- * @internal
80
- */
20
+ /** `action` with the correlator and patch step bound by `build_es`. */
81
21
  type BoundAction = <TState extends Schema, TEvents extends Schemas, TActions extends Schemas, TKey extends keyof TActions>(me: State<TState, TEvents, TActions>, action: TKey, target: Target, payload: Readonly<TActions[TKey]>, options?: DoOptions<TEvents>) => Promise<Snapshot<TState, TEvents>[]>;
82
- /** @internal */
83
22
  export interface EsOps {
84
23
  snap: typeof snap;
85
24
  load: typeof load;
86
25
  action: BoundAction;
87
26
  tombstone: typeof tombstone;
88
27
  }
89
- /**
90
- * Event sourcing utilities for snapshotting, loading, and committing actions/events.
91
- * Used internally by Act and state machines.
92
- */
93
- /**
94
- * Saves a snapshot of the state to the store.
95
- *
96
- * Snapshots are used to optimize state reconstruction for aggregates with long event streams.
97
- *
98
- * @template TState The type of state
99
- * @template TEvents The type of events
100
- * @param snapshot The snapshot to save
101
- * @returns Promise that resolves when the snapshot is saved
102
- *
103
- * @example
104
- * await snap(snapshot);
105
- */
28
+ /** Commits a snapshot event. Never throws: a failed snapshot must not fail the action. */
106
29
  export declare function snap<TState extends Schema, TEvents extends Schemas>(snapshot: Snapshot<TState, TEvents>): Promise<Committed<TEvents, keyof TEvents> | undefined>;
107
30
  /**
108
- * Commits a tombstone event with optimistic concurrency, returning the
109
- * committed record on success or `undefined` if the stream moved past
110
- * `expectedVersion` (concurrent write detected). Other store errors
111
- * propagate.
112
- *
113
- * Used by `close()` to guard a stream while archive/truncate runs:
114
- * subsequent `action()` calls see the tombstone at head and reject with
115
- * {@link StreamClosedError} until the close completes.
116
- *
117
- * @internal
31
+ * Commits the close guard at `expectedVersion`; `undefined` when the stream
32
+ * moved. Actions then see the tombstone at head and throw {@link StreamClosedError}.
118
33
  */
119
34
  export declare function tombstone(stream: string, expectedVersion: number, correlation: string): Promise<Committed<Schemas, keyof Schemas> | undefined>;
120
35
  /**
121
- * Scan a restore source event by event. Owns pagination, validation,
122
- * the `drop_snapshots` filter, the `on_progress` callback, and the
123
- * causation remap; adapters supply only the per-event insert
124
- * `callback` via the driver pattern (see {@link Store.restore}).
125
- *
126
- * Pages the source with `limit`/`after`; a source that ignores the
127
- * filter (`CsvFile`) returns everything at once and the loop ends. Throws
128
- * on the first invalid event. Returns the result without `duration_ms`,
129
- * which {@link Act.restore} adds.
130
- *
131
- * @internal
36
+ * Pages a restore source: validation, drop filters, migrations, progress and
37
+ * causation remap. Adapters supply only the per-event insert `callback`
38
+ * (see {@link Store.restore}). A source that ignores `limit` (`CsvFile`)
39
+ * returns everything in one page.
132
40
  */
133
41
  export declare function scan(source: EventSource, opts?: ScanOptions, callback?: (event: Committed<Schemas, keyof Schemas>) => Promise<number>): Promise<Omit<ScanResult, "duration_ms">>;
134
42
  /**
135
- * Loads a snapshot of the state from the store by folding events through the
136
- * state's patch reducers.
137
- *
138
- * First checks the cache for a checkpoint, then queries the store for events
139
- * committed after the cached position. On cache miss, replays from the store
140
- * (using snapshots if available to avoid full replay).
141
- *
142
- * @template TState The type of state
143
- * @template TEvents The type of events
144
- * @template TActions The type of actions
145
- * @param me The state machine definition.
146
- * @param stream The stream (instance) to load
147
- * @param callback (Optional) Callback to receive the loaded snapshot as it is built
148
- * @param asOf (Optional) Time-travel cursor; bypasses the cache.
149
- * @param actor (Optional) Passed through to the state's `view` delegate
150
- * when constructing the snapshot.event — semantics are the state's to
151
- * define (see {@link state}).
152
- * @returns The snapshot of the loaded state
153
- *
154
- * @example
155
- * const snapshot = await load(Counter, "counter1");
43
+ * Folds a stream into state, from the cached checkpoint or the latest
44
+ * snapshot. `asOf` time-travels and bypasses the cache.
156
45
  */
157
46
  export declare function load<TState extends Schema, TEvents extends Schemas, TActions extends Schemas>(me: State<TState, TEvents, TActions>, target: LoadTarget, callback?: (snapshot: Snapshot<TState, TEvents>) => void, patch_fn?: PatchFn): Promise<Snapshot<TState, TEvents>>;
158
47
  /**
159
- * Executes an action and emits an event to be committed by the store.
160
- *
161
- * Validates the action, applies business invariants, emits events, and
162
- * commits them to the event store. When the action's
163
- * {@link ActionOptions} declare a retry budget, the orchestrator owns
164
- * the loop on {@link ConcurrencyError}: cache is invalidated, optional
165
- * `backoff` delay is applied, and the action re-runs from `load`. Any
166
- * other error rethrows immediately and does not consume the budget.
167
- *
168
- * Reactions skip optimistic concurrency (commit below passes
169
- * `undefined` as `expectedVersion` when `reactingTo` is set), so
170
- * `ConcurrencyError` cannot fire on the reaction-driven path — the
171
- * loop is naturally a no-op there.
172
- *
173
- * @template TState The type of state
174
- * @template TEvents The type of events
175
- * @template TActions The type of action_schemas
176
- * @template TKey The type of action to execute
177
- * @param me The state machine definition
178
- * @param action The action to execute
179
- * @param target The target (stream, actor, etc.)
180
- * @param payload The payload of the action
181
- * @param options Per-call dispatch options ({@link DoOptions}) —
182
- * `reactingTo` to thread correlation, `correlator` to override the
183
- * framework or orchestrator-level correlator for this call only.
184
- * @returns The snapshot of the committed event
185
- *
186
- * @example
187
- * const snapshot = await action(Counter, "increment", { stream: "counter1", actor }, { by: 1 });
48
+ * Validates, checks invariants, emits and commits. On {@link ConcurrencyError}
49
+ * it re-runs from `load` within the action's `maxRetries`; any other error
50
+ * rethrows. Reactions commit without the inferred version guard.
188
51
  */
189
52
  export declare function action<TState extends Schema, TEvents extends Schemas, TActions extends Schemas, TKey extends keyof TActions>(me: State<TState, TEvents, TActions>, action: TKey, target: Target, payload: Readonly<TActions[TKey]>, options?: DoOptions<TEvents>, patch_fn?: PatchFn): Promise<Snapshot<TState, TEvents>[]>;
190
53
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"event-sourcing.d.ts","sourceRoot":"","sources":["../../../src/internal/event-sourcing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"event-sourcing.d.ts","sourceRoot":"","sources":["../../../src/internal/event-sourcing.ts"],"names":[],"mappings":"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"}
@@ -749,25 +749,19 @@ var InMemoryStore = class {
749
749
  */
750
750
  async defer(input, deferred_at) {
751
751
  await sleep();
752
- let count = 0;
753
- if (Array.isArray(input)) {
754
- for (const name of new Set(input)) {
755
- const s = this._streams.get(name);
756
- if (s) {
757
- s.defer(deferred_at);
758
- count++;
759
- }
760
- }
761
- } else {
762
- const matches = this._filter_predicate(input);
763
- for (const s of this._streams.values()) {
764
- if (matches(s)) {
765
- s.defer(deferred_at);
766
- count++;
767
- }
768
- }
769
- }
770
- return count;
752
+ const selected = this._select(input);
753
+ for (const s of selected) s.defer(deferred_at);
754
+ return selected.length;
755
+ }
756
+ /**
757
+ * The streams named by `input`: an explicit list (de-duplicated, so a
758
+ * repeated name counts once, matching the SQL adapters' set-based
759
+ * `stream = ANY(...)`; unknown names are skipped) or a {@link StreamFilter}.
760
+ */
761
+ _select(input) {
762
+ if (Array.isArray(input))
763
+ return [...new Set(input)].map((name) => this._streams.get(name)).filter((s) => s !== void 0);
764
+ return [...this._streams.values()].filter(this._filter_predicate(input));
771
765
  }
772
766
  /**
773
767
  * Build a predicate from a {@link StreamFilter}. Compiled regexes are
@@ -803,37 +797,10 @@ var InMemoryStore = class {
803
797
  */
804
798
  async reset(input) {
805
799
  await sleep();
806
- let count = 0;
807
- if (Array.isArray(input)) {
808
- for (const name of new Set(input)) {
809
- const s = this._streams.get(name);
810
- if (s) {
811
- s.reset();
812
- count++;
813
- }
814
- }
815
- } else {
816
- const matches = this._filter_predicate(input);
817
- for (const s of this._streams.values()) {
818
- if (matches(s)) {
819
- s.reset();
820
- count++;
821
- }
822
- }
823
- }
824
- return count;
800
+ const selected = this._select(input);
801
+ for (const s of selected) s.reset();
802
+ return selected.length;
825
803
  }
826
- /**
827
- * Clear the blocked flag (and retry / error / lease) on the matched
828
- * streams without touching the watermark. Streams that aren't blocked
829
- * at call time are silently skipped. Accepts either an explicit list
830
- * of names or a {@link StreamFilter}. The filter form always restricts
831
- * to blocked streams — passing `blocked: false` matches nothing.
832
- * See {@link Store.unblock}.
833
- *
834
- * @param input - Stream names or a filter selecting the streams to unblock.
835
- * @returns Count of streams that were actually flipped (were blocked).
836
- */
837
804
  /**
838
805
  * Wipe the sensitive-data payload for every event on the stream — see
839
806
  * {@link Store.forget_pii}. O(1) drop of the stream's inner Map; the size of
@@ -849,21 +816,23 @@ var InMemoryStore = class {
849
816
  this._pii.delete(stream);
850
817
  return count;
851
818
  }
819
+ /**
820
+ * Clear the blocked flag (and retry / error / lease) on the matched
821
+ * streams without touching the watermark. Streams that aren't blocked
822
+ * at call time are silently skipped. Accepts either an explicit list
823
+ * of names or a {@link StreamFilter}. The filter form always restricts
824
+ * to blocked streams — passing `blocked: false` matches nothing.
825
+ * See {@link Store.unblock}.
826
+ *
827
+ * @param input - Stream names or a filter selecting the streams to unblock.
828
+ * @returns Count of streams that were actually flipped (were blocked).
829
+ */
852
830
  async unblock(input) {
853
831
  await sleep();
854
- let count = 0;
855
- if (Array.isArray(input)) {
856
- for (const name of input) {
857
- const s = this._streams.get(name);
858
- if (s?.unblock()) count++;
859
- }
860
- } else {
861
- const matches = this._filter_predicate({ ...input, blocked: true });
862
- for (const s of this._streams.values()) {
863
- if (matches(s) && s.unblock()) count++;
864
- }
865
- }
866
- return count;
832
+ const selected = this._select(
833
+ Array.isArray(input) ? input : { ...input, blocked: true }
834
+ );
835
+ return selected.filter((s) => s.unblock()).length;
867
836
  }
868
837
  /**
869
838
  * Bulk-update priority of streams matching `filter`. Mirrors
@@ -876,16 +845,9 @@ var InMemoryStore = class {
876
845
  */
877
846
  async prioritize(filter, priority) {
878
847
  await sleep();
879
- const matches = this._filter_predicate(filter);
880
- let count = 0;
881
- for (const s of this._streams.values()) {
882
- if (!matches(s)) continue;
883
- if (s.priority !== priority) {
884
- s.set_priority(priority);
885
- count++;
886
- }
887
- }
888
- return count;
848
+ const changed = this._select(filter).filter((s) => s.priority !== priority);
849
+ for (const s of changed) s.set_priority(priority);
850
+ return changed.length;
889
851
  }
890
852
  /**
891
853
  * Streams registered subscription positions to the callback, ordered by
@@ -896,10 +858,8 @@ var InMemoryStore = class {
896
858
  await sleep();
897
859
  const limit = query?.limit ?? 100;
898
860
  const after = query?.after;
899
- const blocked = query?.blocked;
900
861
  const source_matches = query?.source_matches;
901
- const stream_re = query?.stream !== void 0 && !query.stream_exact ? new RegExp(query.stream) : void 0;
902
- const source_re = query?.source !== void 0 && !query.source_exact ? new RegExp(query.source) : void 0;
862
+ const matches = this._filter_predicate(query ?? {});
903
863
  const reverse_cache = /* @__PURE__ */ new Map();
904
864
  const reverse_match = (source) => {
905
865
  let re = reverse_cache.get(source);
@@ -913,20 +873,10 @@ var InMemoryStore = class {
913
873
  let count = 0;
914
874
  for (const s of sorted) {
915
875
  if (after !== void 0 && s.stream <= after) continue;
916
- if (query?.stream !== void 0) {
917
- if (query.stream_exact ? s.stream !== query.stream : !stream_re.test(s.stream))
918
- continue;
919
- }
920
- if (query?.source !== void 0) {
921
- if (s.source === void 0) continue;
922
- if (query.source_exact ? s.source !== query.source : !source_re.test(s.source))
923
- continue;
924
- }
876
+ if (!matches(s)) continue;
925
877
  if (source_matches !== void 0) {
926
878
  if (s.source && !reverse_match(s.source)) continue;
927
879
  }
928
- if (blocked !== void 0 && s.blocked !== blocked) continue;
929
- if (query?.lane !== void 0 && s.lane !== query.lane) continue;
930
880
  if (count >= limit) break;
931
881
  callback({
932
882
  stream: s.stream,
@@ -1339,4 +1289,4 @@ export {
1339
1289
  TOMBSTONE_EVENT,
1340
1290
  DEFAULT_LANE
1341
1291
  };
1342
- //# sourceMappingURL=chunk-T3CWXVGT.js.map
1292
+ //# sourceMappingURL=chunk-OG5O36AJ.js.map