@rotorsoft/act 1.37.5 → 1.37.7
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/builders/act-builder.d.ts +2 -1
- package/dist/@types/builders/act-builder.d.ts.map +1 -1
- package/dist/@types/builders/merge.d.ts.map +1 -1
- package/dist/@types/builders/slice-builder.d.ts +2 -1
- package/dist/@types/builders/slice-builder.d.ts.map +1 -1
- package/dist/@types/builders/state-builder.d.ts.map +1 -1
- package/dist/@types/internal/autoclose-policy.d.ts +8 -7
- package/dist/@types/internal/autoclose-policy.d.ts.map +1 -1
- package/dist/@types/internal/autoclose-reaction.d.ts.map +1 -1
- package/dist/@types/internal/event-sourcing.d.ts.map +1 -1
- package/dist/@types/types/action.d.ts +7 -3
- package/dist/@types/types/action.d.ts.map +1 -1
- package/dist/index.cjs +38 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +26 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -416,7 +416,9 @@ var make_restart_candidate_pass = (deps, options) => {
|
|
|
416
416
|
stream,
|
|
417
417
|
stream_exact: true,
|
|
418
418
|
names: [SNAP_EVENT],
|
|
419
|
-
with_snaps: true
|
|
419
|
+
with_snaps: true,
|
|
420
|
+
// From the start: on its own, `with_snaps` resumes at the latest.
|
|
421
|
+
after: -1
|
|
420
422
|
}
|
|
421
423
|
);
|
|
422
424
|
findings.push({
|
|
@@ -573,7 +575,7 @@ var make_correlation_gaps_pass = () => {
|
|
|
573
575
|
seen_ids.add(e.id);
|
|
574
576
|
const causation = e.meta?.causation;
|
|
575
577
|
const parent_id = causation?.event?.id;
|
|
576
|
-
if (parent_id !== void 0) {
|
|
578
|
+
if (parent_id !== void 0 && e.name !== TOMBSTONE_EVENT) {
|
|
577
579
|
checks.push({ stream: e.stream, id: e.id, parent_id });
|
|
578
580
|
}
|
|
579
581
|
},
|
|
@@ -1458,7 +1460,7 @@ var CorrelateCycle = class {
|
|
|
1458
1460
|
});
|
|
1459
1461
|
} catch (error) {
|
|
1460
1462
|
log().warn(
|
|
1461
|
-
`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)}`
|
|
1463
|
+
`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.cause ?? error)}`
|
|
1462
1464
|
);
|
|
1463
1465
|
}
|
|
1464
1466
|
}
|
|
@@ -1837,6 +1839,7 @@ async function scan(source, opts = {}, callback) {
|
|
|
1837
1839
|
async function load(me, target, callback, patch_fn = bare_patch) {
|
|
1838
1840
|
const { stream, actor, asOf } = target;
|
|
1839
1841
|
const time_travel = !!asOf && Object.values(asOf).some((v) => v !== void 0);
|
|
1842
|
+
const seeded = time_travel && asOf.limit === void 0 && !asOf.created_after;
|
|
1840
1843
|
const cached = time_travel ? void 0 : await cache().get(stream);
|
|
1841
1844
|
const cache_hit = !!cached;
|
|
1842
1845
|
let state2 = cached?.state ?? (me.init ? me.init() : {});
|
|
@@ -1846,6 +1849,7 @@ async function load(me, target, callback, patch_fn = bare_patch) {
|
|
|
1846
1849
|
let event;
|
|
1847
1850
|
await store().query(
|
|
1848
1851
|
(raw) => {
|
|
1852
|
+
if (seeded && raw.name === SNAP_EVENT && replayed > 0) return;
|
|
1849
1853
|
event = me.view(raw, actor);
|
|
1850
1854
|
if (event.name === SNAP_EVENT) {
|
|
1851
1855
|
state2 = event.data;
|
|
@@ -1878,7 +1882,11 @@ async function load(me, target, callback, patch_fn = bare_patch) {
|
|
|
1878
1882
|
// `with_snaps` on every non-time-travel load: cold, it resumes from the
|
|
1879
1883
|
// latest snapshot; warm, it keeps a snapshot above a stale checkpoint,
|
|
1880
1884
|
// so a windowed close's prune can't fold the tail onto stale state.
|
|
1881
|
-
...cached ? { after: cached.event_id, with_snaps: true } :
|
|
1885
|
+
...cached ? { after: cached.event_id, with_snaps: true } : seeded ? (
|
|
1886
|
+
// From the start, past the resume floor, which could jump over the
|
|
1887
|
+
// time bound. The snapshots are for the seed.
|
|
1888
|
+
{ with_snaps: true, after: -1, ...asOf }
|
|
1889
|
+
) : time_travel ? asOf : { with_snaps: true }
|
|
1882
1890
|
}
|
|
1883
1891
|
);
|
|
1884
1892
|
const head_is_tombstone = event?.name === TOMBSTONE_EVENT;
|
|
@@ -4019,6 +4027,10 @@ function policy_min_after_days(options) {
|
|
|
4019
4027
|
if (parsed.or?.after) windows.push(parsed.or.after.days);
|
|
4020
4028
|
return windows.length ? Math.min(...windows) : void 0;
|
|
4021
4029
|
}
|
|
4030
|
+
function policy_after_windows(options) {
|
|
4031
|
+
const parsed = AutoclosePolicySchema.parse(options);
|
|
4032
|
+
return [parsed.after, parsed.or?.after].flatMap((w) => w ? [w.days] : []);
|
|
4033
|
+
}
|
|
4022
4034
|
function policy_keep_days(options) {
|
|
4023
4035
|
const parsed = AutoclosePolicySchema.parse(options);
|
|
4024
4036
|
return parsed.keep?.days;
|
|
@@ -4090,7 +4102,7 @@ function synthesize_autoclose_reactions(registry, states, read_window) {
|
|
|
4090
4102
|
for (const st of states.values()) {
|
|
4091
4103
|
const predicate = st.autoclose;
|
|
4092
4104
|
if (!predicate) continue;
|
|
4093
|
-
const
|
|
4105
|
+
const after_windows = st.autoclose_after_windows;
|
|
4094
4106
|
const keep_days = st.autoclose_keep_days;
|
|
4095
4107
|
const archiver = st.archive;
|
|
4096
4108
|
const reaction = {
|
|
@@ -4100,10 +4112,13 @@ function synthesize_autoclose_reactions(registry, states, read_window) {
|
|
|
4100
4112
|
// watermark would let autoclose's defer short-circuit the aggregate's
|
|
4101
4113
|
// other reactions (the "a defer affects all reactions on a stream"
|
|
4102
4114
|
// hazard). The close still targets the aggregate (`source`).
|
|
4103
|
-
|
|
4115
|
+
// A stream name with a regex metacharacter would read as a pattern, and a
|
|
4116
|
+
// store may refuse it at subscribe, stopping every reaction. Such a stream
|
|
4117
|
+
// has no autoclose: `app.close` still closes it.
|
|
4118
|
+
resolver: (e) => is_literal_source(e.stream) ? {
|
|
4104
4119
|
target: `${AUTOCLOSE_TARGET_PREFIX}${e.stream}`,
|
|
4105
4120
|
source: e.stream
|
|
4106
|
-
}
|
|
4121
|
+
} : void 0,
|
|
4107
4122
|
// Never block on autoclose: a transient query/store error should retry,
|
|
4108
4123
|
// not quarantine the synthetic stream.
|
|
4109
4124
|
options: { blockOnError: false, maxRetries: DEFAULT_MAX_RETRIES },
|
|
@@ -4140,8 +4155,8 @@ function synthesize_autoclose_reactions(registry, states, read_window) {
|
|
|
4140
4155
|
});
|
|
4141
4156
|
}
|
|
4142
4157
|
const dues = [];
|
|
4143
|
-
|
|
4144
|
-
dues.push(days_after(head.created,
|
|
4158
|
+
for (const days of after_windows)
|
|
4159
|
+
dues.push(days_after(head.created, days));
|
|
4145
4160
|
if (keep_days !== void 0)
|
|
4146
4161
|
dues.push(days_after(entry.tail.created, keep_days));
|
|
4147
4162
|
const future = dues.map((d) => d.getTime()).filter((t) => t > Date.now());
|
|
@@ -4231,6 +4246,7 @@ function autoclose_of(existing, state2) {
|
|
|
4231
4246
|
return {
|
|
4232
4247
|
autoclose: owner.autoclose,
|
|
4233
4248
|
autoclose_after_days: owner.autoclose_after_days,
|
|
4249
|
+
autoclose_after_windows: owner.autoclose_after_windows,
|
|
4234
4250
|
autoclose_keep_days: owner.autoclose_keep_days
|
|
4235
4251
|
};
|
|
4236
4252
|
}
|
|
@@ -5085,6 +5101,7 @@ function action_builder(state2) {
|
|
|
5085
5101
|
policy
|
|
5086
5102
|
);
|
|
5087
5103
|
internal.autoclose_after_days = policy_min_after_days(policy);
|
|
5104
|
+
internal.autoclose_after_windows = policy_after_windows(policy);
|
|
5088
5105
|
internal.autoclose_keep_days = policy_keep_days(policy);
|
|
5089
5106
|
return builder;
|
|
5090
5107
|
},
|