@rotorsoft/act 1.23.18 → 1.23.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/internal/correlate-cycle.d.ts +7 -0
- package/dist/@types/internal/correlate-cycle.d.ts.map +1 -1
- package/dist/@types/internal/event-sourcing.d.ts.map +1 -1
- package/dist/@types/internal/settle.d.ts +10 -0
- package/dist/@types/internal/settle.d.ts.map +1 -1
- package/dist/index.cjs +38 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +38 -11
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1566,6 +1566,15 @@ var CorrelateCycle = class {
|
|
|
1566
1566
|
get checkpoint() {
|
|
1567
1567
|
return this._checkpoint;
|
|
1568
1568
|
}
|
|
1569
|
+
/**
|
|
1570
|
+
* Whether any reaction uses a dynamic resolver — i.e. whether `correlate`
|
|
1571
|
+
* performs a store scan rather than the static no-op early-return. The
|
|
1572
|
+
* settle loop reads this to avoid recording a fictitious circuit-breaker
|
|
1573
|
+
* success on a static app whose correlate never touches the store (#1329).
|
|
1574
|
+
*/
|
|
1575
|
+
get has_dynamic_resolvers() {
|
|
1576
|
+
return this._has_dynamic_resolvers;
|
|
1577
|
+
}
|
|
1569
1578
|
/**
|
|
1570
1579
|
* Initialize correlation state on first call.
|
|
1571
1580
|
* - Reads max(at) from store, then floors the cold-start checkpoint at
|
|
@@ -2067,8 +2076,21 @@ async function load(me, target, callback, patch_fn = bare_patch) {
|
|
|
2067
2076
|
// a non-time-travel cold load — a bounded load full-scans real events
|
|
2068
2077
|
// under its `asOf` filter. This is the single floor-eligibility decision
|
|
2069
2078
|
// for the whole system; the stores apply the floor whenever asked and
|
|
2070
|
-
// never re-derive it (RFC 1274).
|
|
2071
|
-
|
|
2079
|
+
// never re-derive it (RFC 1274).
|
|
2080
|
+
//
|
|
2081
|
+
// The warm path resumes from `after`, and MUST also carry `with_snaps`
|
|
2082
|
+
// (#1345): `after` and `with_snaps` are independent store conditions —
|
|
2083
|
+
// `after` bounds the scan (id > cached.event_id), `with_snaps` keeps
|
|
2084
|
+
// `__snapshot__` rows in the result. A stale (lagging/cross-process)
|
|
2085
|
+
// cache checkpoint can sit below a newer `__snapshot__` boundary, and a
|
|
2086
|
+
// windowed close (`app.close`/`.autocloses({keep})`) may have pruned the
|
|
2087
|
+
// domain events between the checkpoint and that snapshot. Without
|
|
2088
|
+
// `with_snaps` the rebaselining snapshot is filtered out and the fold
|
|
2089
|
+
// silently applies the surviving tail on top of stale state (wrong
|
|
2090
|
+
// count, yet `version` still reports the true head — the concurrency
|
|
2091
|
+
// guard passes). With it, the snapshot in the after-window rebaselines
|
|
2092
|
+
// the fold; when no snapshot falls in the window it is a no-op.
|
|
2093
|
+
...cached ? { after: cached.event_id, with_snaps: true } : { ...time_travel ? {} : { with_snaps: true }, ...asOf }
|
|
2072
2094
|
}
|
|
2073
2095
|
);
|
|
2074
2096
|
const head_is_tombstone = event?.name === TOMBSTONE_EVENT;
|
|
@@ -2860,7 +2882,7 @@ var SettleLoop = class {
|
|
|
2860
2882
|
...correlate_query,
|
|
2861
2883
|
after: after_before
|
|
2862
2884
|
});
|
|
2863
|
-
this._deps.breaker.passed();
|
|
2885
|
+
if (this._deps.correlate_probes_store) this._deps.breaker.passed();
|
|
2864
2886
|
last_drain = await this._deps.drain(drain_options);
|
|
2865
2887
|
const made_progress = subscribed > 0 || last_drain.acked.length > 0 || last_drain.blocked.length > 0 || last_id > after_before;
|
|
2866
2888
|
if (!made_progress) break;
|
|
@@ -3125,13 +3147,14 @@ var Act = class {
|
|
|
3125
3147
|
on_error: (error, circuit) => this._emit_error(error, circuit),
|
|
3126
3148
|
// Re-probe the store when the cooldown elapses, so recovery is
|
|
3127
3149
|
// automatic even on the default lane (which has no periodic poller).
|
|
3128
|
-
//
|
|
3129
|
-
//
|
|
3130
|
-
//
|
|
3131
|
-
//
|
|
3132
|
-
//
|
|
3133
|
-
//
|
|
3134
|
-
// the breaker
|
|
3150
|
+
// The wake fires `settle()`, which (in half-open) runs a real store
|
|
3151
|
+
// probe: for a dynamic-resolver app the probe is settle's correlate
|
|
3152
|
+
// (a store scan); for a static-reaction app correlate is a no-op that
|
|
3153
|
+
// records no health, so the probe is settle's DRAIN claim — either
|
|
3154
|
+
// way one success closes the breaker and every loop resumes, a
|
|
3155
|
+
// failure re-opens it and reschedules the wake. Settle does NOT close
|
|
3156
|
+
// the breaker off a no-op correlate (#1329) — only a real store op
|
|
3157
|
+
// (correlate scan or drain claim) records `passed()`.
|
|
3135
3158
|
on_retry: () => {
|
|
3136
3159
|
this.settle({ debounceMs: 0 });
|
|
3137
3160
|
}
|
|
@@ -3308,7 +3331,11 @@ var Act = class {
|
|
|
3308
3331
|
correlate: (q) => this.correlate(q),
|
|
3309
3332
|
drain: (o) => this.drain(o),
|
|
3310
3333
|
on_settled: (drain) => this.emit("settled", drain),
|
|
3311
|
-
breaker: this._breaker
|
|
3334
|
+
breaker: this._breaker,
|
|
3335
|
+
// Static-reaction apps' correlate is a no-op (no store call), so a
|
|
3336
|
+
// settle pass carries no store-health signal — don't let it record a
|
|
3337
|
+
// breaker success (#1329).
|
|
3338
|
+
correlate_probes_store: this._correlate.has_dynamic_resolvers
|
|
3312
3339
|
},
|
|
3313
3340
|
options.settleDebounceMs ?? DEFAULT_SETTLE_DEBOUNCE_MS
|
|
3314
3341
|
);
|