@rotorsoft/act 1.32.21 → 1.32.23
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 +1 -2
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/adapters/in-memory-store.d.ts +18 -16
- package/dist/@types/adapters/in-memory-store.d.ts.map +1 -1
- package/dist/@types/builders/act-builder.d.ts.map +1 -1
- package/dist/@types/internal/audit.d.ts +1 -4
- package/dist/@types/internal/audit.d.ts.map +1 -1
- package/dist/@types/internal/config.d.ts +3 -9
- package/dist/@types/internal/config.d.ts.map +1 -1
- package/dist/@types/internal/correlate-cycle.d.ts +1 -11
- package/dist/@types/internal/correlate-cycle.d.ts.map +1 -1
- package/dist/@types/internal/defer-timer.d.ts +0 -5
- package/dist/@types/internal/defer-timer.d.ts.map +1 -1
- package/dist/@types/internal/drain-cycle.d.ts +3 -5
- package/dist/@types/internal/drain-cycle.d.ts.map +1 -1
- package/dist/@types/internal/index.d.ts +1 -1
- package/dist/@types/internal/index.d.ts.map +1 -1
- package/dist/@types/types/ports.d.ts +10 -10
- package/dist/@types/types/ports.d.ts.map +1 -1
- package/dist/@types/utils.d.ts +3 -2
- package/dist/@types/utils.d.ts.map +1 -1
- package/dist/{chunk-QOSQI3CA.js → chunk-OG5O36AJ.js} +50 -141
- package/dist/chunk-OG5O36AJ.js.map +1 -0
- package/dist/index.cjs +75 -191
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +27 -52
- package/dist/index.js.map +1 -1
- package/dist/test/index.cjs +49 -140
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-QOSQI3CA.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
sleep,
|
|
27
27
|
store,
|
|
28
28
|
validate
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-OG5O36AJ.js";
|
|
30
30
|
import {
|
|
31
31
|
ActorSchema,
|
|
32
32
|
CausationEventSchema,
|
|
@@ -926,7 +926,6 @@ function resolveSettleConfig(options) {
|
|
|
926
926
|
return options;
|
|
927
927
|
}
|
|
928
928
|
var MAX_SHUTDOWN_GRACE_MS = 3e4;
|
|
929
|
-
var DEFAULT_SHUTDOWN_GRACE_MS = DEFAULT_LEASE_MILLIS;
|
|
930
929
|
var ShutdownOptionsSchema = z2.object({
|
|
931
930
|
// `0` is legal and is exactly today's behavior: stop scheduling and
|
|
932
931
|
// return without waiting.
|
|
@@ -1561,8 +1560,8 @@ function report_once(seen, key, message) {
|
|
|
1561
1560
|
}
|
|
1562
1561
|
|
|
1563
1562
|
// src/internal/correlate-cycle.ts
|
|
1564
|
-
var
|
|
1565
|
-
var
|
|
1563
|
+
var COLD_START_BACK_SCAN = 1e4;
|
|
1564
|
+
var CORRELATION_LEASE_MS = 5e3;
|
|
1566
1565
|
var registry_key = (events) => {
|
|
1567
1566
|
const shape = Object.keys(events).filter((name) => events[name].reactions.size > 0).sort().map((name) => [name, [...events[name].reactions.keys()].sort()]);
|
|
1568
1567
|
return createHash("sha256").update(JSON.stringify(shape)).digest("hex").slice(0, 32);
|
|
@@ -1591,8 +1590,6 @@ var CorrelateCycle = class {
|
|
|
1591
1590
|
* same holder and a restarted process never inherits a stale claim.
|
|
1592
1591
|
*/
|
|
1593
1592
|
_by = randomUUID();
|
|
1594
|
-
/** How long the correlation lease is taken for. */
|
|
1595
|
-
_lease_millis;
|
|
1596
1593
|
/**
|
|
1597
1594
|
* Which correlator this is. Computed once from the registry so identical
|
|
1598
1595
|
* workers share a lease and unrelated applications never do.
|
|
@@ -1645,12 +1642,6 @@ var CorrelateCycle = class {
|
|
|
1645
1642
|
* here, so an idle deferred stream re-arms across a restart.
|
|
1646
1643
|
*/
|
|
1647
1644
|
_on_init_async;
|
|
1648
|
-
/**
|
|
1649
|
-
* Tail re-scan window applied to the cold-start checkpoint.
|
|
1650
|
-
* See {@link DEFAULT_COLD_START_BACK_SCAN}. Constructor arg (not a
|
|
1651
|
-
* public option) so tests can shrink it; defaults otherwise.
|
|
1652
|
-
*/
|
|
1653
|
-
_cold_start_back_scan;
|
|
1654
1645
|
/** Lanes a controller exists for. See {@link CorrelateCycleDeps}. */
|
|
1655
1646
|
_declared_lanes;
|
|
1656
1647
|
/**
|
|
@@ -1667,11 +1658,8 @@ var CorrelateCycle = class {
|
|
|
1667
1658
|
declared_lanes,
|
|
1668
1659
|
shard,
|
|
1669
1660
|
on_init,
|
|
1670
|
-
on_init_async
|
|
1671
|
-
cold_start_back_scan = DEFAULT_COLD_START_BACK_SCAN,
|
|
1672
|
-
lease_millis = DEFAULT_CORRELATION_LEASE_MS
|
|
1661
|
+
on_init_async
|
|
1673
1662
|
}) {
|
|
1674
|
-
this._lease_millis = lease_millis;
|
|
1675
1663
|
this._key = shard ? `${registry_key(registry.events)}:${[...shard].sort().join(",")}` : registry_key(registry.events);
|
|
1676
1664
|
this._dynamic_subscriptions = new LruMap(max_subscribed_streams);
|
|
1677
1665
|
this._registry = registry;
|
|
@@ -1680,7 +1668,6 @@ var CorrelateCycle = class {
|
|
|
1680
1668
|
this._cd = cd;
|
|
1681
1669
|
this._on_init = on_init;
|
|
1682
1670
|
this._on_init_async = on_init_async;
|
|
1683
|
-
this._cold_start_back_scan = cold_start_back_scan;
|
|
1684
1671
|
}
|
|
1685
1672
|
/** Last correlated event id. */
|
|
1686
1673
|
get checkpoint() {
|
|
@@ -1719,7 +1706,7 @@ var CorrelateCycle = class {
|
|
|
1719
1706
|
const { watermark, correlated_at } = await this._cd.subscribe([
|
|
1720
1707
|
...this._static_targets
|
|
1721
1708
|
]);
|
|
1722
|
-
this._checkpoint = correlated_at >= 0 ? correlated_at : Math.max(-1, watermark -
|
|
1709
|
+
this._checkpoint = correlated_at >= 0 ? correlated_at : Math.max(-1, watermark - COLD_START_BACK_SCAN);
|
|
1723
1710
|
this._on_init?.();
|
|
1724
1711
|
for (const { stream, priority = 0, lane } of this._static_targets) {
|
|
1725
1712
|
this._static_subscriptions.set(stream, {
|
|
@@ -1793,13 +1780,13 @@ var CorrelateCycle = class {
|
|
|
1793
1780
|
scanned: false
|
|
1794
1781
|
};
|
|
1795
1782
|
const now = Date.now();
|
|
1796
|
-
if (lease && now >= this._lease_until -
|
|
1783
|
+
if (lease && now >= this._lease_until - CORRELATION_LEASE_MS / 2) {
|
|
1797
1784
|
const { correlating } = await this._cd.subscribe([], void 0, {
|
|
1798
1785
|
key: this._key,
|
|
1799
1786
|
by: this._by,
|
|
1800
|
-
millis:
|
|
1787
|
+
millis: CORRELATION_LEASE_MS
|
|
1801
1788
|
});
|
|
1802
|
-
this._lease_until = correlating ? now +
|
|
1789
|
+
this._lease_until = correlating ? now + CORRELATION_LEASE_MS : 0;
|
|
1803
1790
|
if (correlating === false)
|
|
1804
1791
|
return {
|
|
1805
1792
|
subscribed: 0,
|
|
@@ -1890,10 +1877,10 @@ var CorrelateCycle = class {
|
|
|
1890
1877
|
const { subscribed, correlating } = await this._cd.subscribe(
|
|
1891
1878
|
streams,
|
|
1892
1879
|
last_id,
|
|
1893
|
-
lease ? { key: this._key, by: this._by, millis:
|
|
1880
|
+
lease ? { key: this._key, by: this._by, millis: CORRELATION_LEASE_MS } : void 0
|
|
1894
1881
|
);
|
|
1895
1882
|
if (lease && correlating !== false)
|
|
1896
|
-
this._lease_until = renewed_at +
|
|
1883
|
+
this._lease_until = renewed_at + CORRELATION_LEASE_MS;
|
|
1897
1884
|
const marked = streams.filter(
|
|
1898
1885
|
(entry) => entry.correlated_at !== void 0
|
|
1899
1886
|
).length;
|
|
@@ -1973,7 +1960,7 @@ var CorrelateCycle = class {
|
|
|
1973
1960
|
});
|
|
1974
1961
|
} catch (error) {
|
|
1975
1962
|
log().warn(
|
|
1976
|
-
`Could not hand back the correlation lease during shutdown; it expires on its own within ${
|
|
1963
|
+
`Could not hand back the correlation lease during shutdown; it expires on its own within ${CORRELATION_LEASE_MS}ms and correlation resumes normally after that. On a single-writer store this usually means another connection holds the database. Cause: ${String(error)}`
|
|
1977
1964
|
);
|
|
1978
1965
|
}
|
|
1979
1966
|
}
|
|
@@ -2125,14 +2112,6 @@ var DeferTimer = class {
|
|
|
2125
2112
|
get size() {
|
|
2126
2113
|
return this._due.size;
|
|
2127
2114
|
}
|
|
2128
|
-
/**
|
|
2129
|
-
* True while `stream` is parked with a due-time still in the future.
|
|
2130
|
-
* Consumers skip work for deferred streams until their window elapses.
|
|
2131
|
-
*/
|
|
2132
|
-
is_deferred = (stream) => {
|
|
2133
|
-
const next = this._due.get(stream);
|
|
2134
|
-
return next !== void 0 && next > Date.now();
|
|
2135
|
-
};
|
|
2136
2115
|
/**
|
|
2137
2116
|
* Park `stream` for a re-visit at `at` (ms since epoch). A plain
|
|
2138
2117
|
* overwrite: the caller computes the authoritative next-visit for the
|
|
@@ -2815,7 +2794,7 @@ function trace_cycle(logger, leased, fetched, handled, acked, blocked) {
|
|
|
2815
2794
|
function budget_exhausted(lease, options, store_failing) {
|
|
2816
2795
|
if (store_failing || !options?.blockOnError || lease.retry <= options.maxRetries)
|
|
2817
2796
|
return void 0;
|
|
2818
|
-
const error = `Blocking ${lease.stream} after ${lease.retry} claims with no acknowledged progress \u2014 the retry budget (${options.maxRetries}) was spent without the handler ever reporting an error. That means every attempt lost its lease before it could ack:
|
|
2797
|
+
const error = `Blocking ${lease.stream} after ${lease.retry} claims with no acknowledged progress \u2014 the retry budget (${options.maxRetries}) was spent without the handler ever reporting an error. That means every attempt lost its lease before it could ack: move the reaction to a lane whose leaseMillis covers the handler, then unblock the stream.`;
|
|
2819
2798
|
log().error(error);
|
|
2820
2799
|
return { lease, handled: 0, acked_at: lease.at, error, block: true };
|
|
2821
2800
|
}
|
|
@@ -2895,7 +2874,9 @@ async function run_drain_cycle(deps, cycle) {
|
|
|
2895
2874
|
handled: 0,
|
|
2896
2875
|
acked_at: lease.at,
|
|
2897
2876
|
error,
|
|
2898
|
-
...block2 ? { block: true } : {
|
|
2877
|
+
...block2 ? { block: true } : {
|
|
2878
|
+
next_attempt_at: Date.now() + compute_backoff_delay(lease.retry, DEFAULT_BACKOFF)
|
|
2879
|
+
}
|
|
2899
2880
|
};
|
|
2900
2881
|
return Promise.resolve(failed);
|
|
2901
2882
|
}
|
|
@@ -3044,7 +3025,7 @@ var DrainController = class {
|
|
|
3044
3025
|
if (this._locked) return EMPTY_DRAIN;
|
|
3045
3026
|
const d = this._deps.defaults ?? {};
|
|
3046
3027
|
const streamLimit = d.streamLimit ?? options.streamLimit ?? DEFAULT_STREAM_LIMIT;
|
|
3047
|
-
const eventLimit =
|
|
3028
|
+
const eventLimit = options.eventLimit ?? DEFAULT_EVENT_LIMIT;
|
|
3048
3029
|
const leaseMillis = d.leaseMillis ?? options.leaseMillis ?? DEFAULT_LEASE_MILLIS;
|
|
3049
3030
|
if (this._deps.breaker.state(Date.now()) === "open")
|
|
3050
3031
|
return EMPTY_DRAIN;
|
|
@@ -3708,9 +3689,7 @@ var Act = class {
|
|
|
3708
3689
|
_build_audit_deps() {
|
|
3709
3690
|
return {
|
|
3710
3691
|
store,
|
|
3711
|
-
logger: this._logger,
|
|
3712
3692
|
event_to_state: this._event_to_state,
|
|
3713
|
-
states: this._states,
|
|
3714
3693
|
// Declared lanes, not this process's controllers: a lane another
|
|
3715
3694
|
// worker drains is not `unknown-lane`.
|
|
3716
3695
|
declared_lanes: new Set(this._declared_lanes),
|
|
@@ -3817,9 +3796,9 @@ var Act = class {
|
|
|
3817
3796
|
* fallback, capped at the maximum. Idle lanes don't count.
|
|
3818
3797
|
*/
|
|
3819
3798
|
_derive_grace_ms(running, settling) {
|
|
3820
|
-
let max = settling ?
|
|
3799
|
+
let max = settling ? DEFAULT_LEASE_MILLIS : 0;
|
|
3821
3800
|
for (const c of running)
|
|
3822
|
-
max = Math.max(max, c.lease_millis ||
|
|
3801
|
+
max = Math.max(max, c.lease_millis || DEFAULT_LEASE_MILLIS);
|
|
3823
3802
|
return Math.min(max, MAX_SHUTDOWN_GRACE_MS);
|
|
3824
3803
|
}
|
|
3825
3804
|
async _await_inflight(grace_ms) {
|
|
@@ -4129,8 +4108,7 @@ var Act = class {
|
|
|
4129
4108
|
* Call `correlate()` before `drain()`. It is not only how dynamic targets
|
|
4130
4109
|
* are discovered: a stream is claimable while `at < correlated_at`, and
|
|
4131
4110
|
* `correlate` is the only component that raises that mark, so a
|
|
4132
|
-
* commit no correlate has seen is not drainable
|
|
4133
|
-
* targets, which were served by a probe of the event log before. For a
|
|
4111
|
+
* commit no correlate has seen is not drainable, static targets included. For a
|
|
4134
4112
|
* higher-level API that handles debouncing, correlation, and signaling
|
|
4135
4113
|
* automatically, use {@link settle}.
|
|
4136
4114
|
*
|
|
@@ -5136,6 +5114,12 @@ function act() {
|
|
|
5136
5114
|
};
|
|
5137
5115
|
const fold_projections = [];
|
|
5138
5116
|
const batch_handlers = /* @__PURE__ */ new Map();
|
|
5117
|
+
const add_projection = (proj) => {
|
|
5118
|
+
record_projection_reactions(proj);
|
|
5119
|
+
merge_projection(proj, registry.events);
|
|
5120
|
+
register_batch_handler(proj, batch_handlers);
|
|
5121
|
+
if (proj.fold) fold_projections.push(proj);
|
|
5122
|
+
};
|
|
5139
5123
|
const fold_specs = [];
|
|
5140
5124
|
const lanes = [];
|
|
5141
5125
|
let _built = false;
|
|
@@ -5235,11 +5219,7 @@ function act() {
|
|
|
5235
5219
|
},
|
|
5236
5220
|
withProjection: (proj) => {
|
|
5237
5221
|
if (_built) closed("withProjection");
|
|
5238
|
-
|
|
5239
|
-
merge_projection(proj, registry.events);
|
|
5240
|
-
register_batch_handler(proj, batch_handlers);
|
|
5241
|
-
if (proj.fold)
|
|
5242
|
-
fold_projections.push(proj);
|
|
5222
|
+
add_projection(proj);
|
|
5243
5223
|
return builder;
|
|
5244
5224
|
},
|
|
5245
5225
|
withActor: () => builder,
|
|
@@ -5256,12 +5236,7 @@ function act() {
|
|
|
5256
5236
|
resolveActConfig(options);
|
|
5257
5237
|
const patch_fn = options?.validateFoldedState === true ? validating_patch : bare_patch;
|
|
5258
5238
|
if (!_built) {
|
|
5259
|
-
for (const proj of pending_projections)
|
|
5260
|
-
record_projection_reactions(proj);
|
|
5261
|
-
merge_projection(proj, registry.events);
|
|
5262
|
-
register_batch_handler(proj, batch_handlers);
|
|
5263
|
-
if (proj.fold) fold_projections.push(proj);
|
|
5264
|
-
}
|
|
5239
|
+
for (const proj of pending_projections) add_projection(proj);
|
|
5265
5240
|
for (const proj of fold_projections) {
|
|
5266
5241
|
const fold = proj.fold;
|
|
5267
5242
|
const merged = states.get(fold.name);
|