@rotorsoft/act 0.26.0 → 0.27.0
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-builder.d.ts.map +1 -1
- package/dist/@types/adapters/InMemoryStore.d.ts +7 -0
- package/dist/@types/adapters/InMemoryStore.d.ts.map +1 -1
- package/dist/@types/merge.d.ts.map +1 -1
- package/dist/@types/projection-builder.d.ts.map +1 -1
- package/dist/@types/slice-builder.d.ts.map +1 -1
- package/dist/@types/types/ports.d.ts +19 -0
- package/dist/@types/types/ports.d.ts.map +1 -1
- package/dist/index.cjs +59 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +59 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -309,7 +309,7 @@ var InMemoryStream = class {
|
|
|
309
309
|
_error = "";
|
|
310
310
|
_leased_by = void 0;
|
|
311
311
|
_leased_until = void 0;
|
|
312
|
-
get
|
|
312
|
+
get is_available() {
|
|
313
313
|
return !this._blocked && (!this._leased_until || this._leased_until <= /* @__PURE__ */ new Date());
|
|
314
314
|
}
|
|
315
315
|
get at() {
|
|
@@ -376,6 +376,17 @@ var InMemoryStream = class {
|
|
|
376
376
|
};
|
|
377
377
|
}
|
|
378
378
|
}
|
|
379
|
+
/**
|
|
380
|
+
* Reset this stream's watermark and state for replay.
|
|
381
|
+
*/
|
|
382
|
+
reset() {
|
|
383
|
+
this._at = -1;
|
|
384
|
+
this._retry = 0;
|
|
385
|
+
this._blocked = false;
|
|
386
|
+
this._error = "";
|
|
387
|
+
this._leased_by = void 0;
|
|
388
|
+
this._leased_until = void 0;
|
|
389
|
+
}
|
|
379
390
|
};
|
|
380
391
|
var InMemoryStore = class {
|
|
381
392
|
// stored events
|
|
@@ -503,7 +514,7 @@ var InMemoryStore = class {
|
|
|
503
514
|
async claim(lagging, leading, by, millis) {
|
|
504
515
|
await sleep();
|
|
505
516
|
const available = [...this._streams.values()].filter(
|
|
506
|
-
(s) => s.
|
|
517
|
+
(s) => s.is_available && (s.at < 0 || this._events.some(
|
|
507
518
|
(e) => e.id > s.at && e.name !== SNAP_EVENT && (!s.source || RegExp(s.source).test(e.stream))
|
|
508
519
|
))
|
|
509
520
|
);
|
|
@@ -566,6 +577,24 @@ var InMemoryStore = class {
|
|
|
566
577
|
await sleep();
|
|
567
578
|
return leases.map((l) => this._streams.get(l.stream)?.block(l, l.error)).filter((l) => !!l);
|
|
568
579
|
}
|
|
580
|
+
/**
|
|
581
|
+
* Reset watermarks for the given streams to -1, clearing retry, blocked,
|
|
582
|
+
* error, and lease state so they can be replayed from the beginning.
|
|
583
|
+
* @param streams - Stream names to reset.
|
|
584
|
+
* @returns Count of streams that were actually reset.
|
|
585
|
+
*/
|
|
586
|
+
async reset(streams) {
|
|
587
|
+
await sleep();
|
|
588
|
+
let count = 0;
|
|
589
|
+
for (const name of streams) {
|
|
590
|
+
const s = this._streams.get(name);
|
|
591
|
+
if (s) {
|
|
592
|
+
s.reset();
|
|
593
|
+
count++;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
return count;
|
|
597
|
+
}
|
|
569
598
|
};
|
|
570
599
|
|
|
571
600
|
// src/ports.ts
|
|
@@ -747,7 +776,7 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
747
776
|
if (!stream) throw new Error("Missing target stream");
|
|
748
777
|
payload = skipValidation ? payload : validate(action2, payload, me.actions[action2]);
|
|
749
778
|
const snapshot = await load(me, stream);
|
|
750
|
-
const expected = expectedVersion
|
|
779
|
+
const expected = expectedVersion ?? snapshot.event?.version;
|
|
751
780
|
logger2.trace(
|
|
752
781
|
payload,
|
|
753
782
|
`\u{1F535} ${stream}.${action2}${typeof expected === "number" ? `.${expected}` : ""}`
|
|
@@ -806,7 +835,7 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
806
835
|
);
|
|
807
836
|
} catch (error) {
|
|
808
837
|
if (error.name === "ERR_CONCURRENCY") {
|
|
809
|
-
|
|
838
|
+
await cache().invalidate(stream);
|
|
810
839
|
}
|
|
811
840
|
throw error;
|
|
812
841
|
}
|
|
@@ -1657,7 +1686,11 @@ function registerState(state2, states, actions, events) {
|
|
|
1657
1686
|
patch: mergedPatch,
|
|
1658
1687
|
on: { ...existing.on, ...state2.on },
|
|
1659
1688
|
given: { ...existing.given, ...state2.given },
|
|
1660
|
-
snap: state2.snap
|
|
1689
|
+
snap: state2.snap && existing.snap && state2.snap !== existing.snap ? (() => {
|
|
1690
|
+
throw new Error(
|
|
1691
|
+
`Duplicate snap strategy for state "${state2.name}"`
|
|
1692
|
+
);
|
|
1693
|
+
})() : state2.snap || existing.snap
|
|
1661
1694
|
};
|
|
1662
1695
|
states.set(state2.name, merged);
|
|
1663
1696
|
for (const name of Object.keys(merged.actions)) {
|
|
@@ -1772,19 +1805,22 @@ function act(states = /* @__PURE__ */ new Map(), registry = {
|
|
|
1772
1805
|
maxRetries: options?.maxRetries ?? 3
|
|
1773
1806
|
}
|
|
1774
1807
|
};
|
|
1775
|
-
|
|
1776
|
-
|
|
1808
|
+
if (!handler.name)
|
|
1809
|
+
throw new Error(
|
|
1810
|
+
`Reaction handler for "${String(event)}" must be a named function`
|
|
1811
|
+
);
|
|
1812
|
+
registry.events[event].reactions.set(handler.name, reaction);
|
|
1777
1813
|
return {
|
|
1778
1814
|
...builder,
|
|
1779
1815
|
to(resolver) {
|
|
1780
|
-
registry.events[event].reactions.set(name, {
|
|
1816
|
+
registry.events[event].reactions.set(handler.name, {
|
|
1781
1817
|
...reaction,
|
|
1782
1818
|
resolver: typeof resolver === "string" ? { target: resolver } : resolver
|
|
1783
1819
|
});
|
|
1784
1820
|
return builder;
|
|
1785
1821
|
},
|
|
1786
1822
|
void() {
|
|
1787
|
-
registry.events[event].reactions.set(name, {
|
|
1823
|
+
registry.events[event].reactions.set(handler.name, {
|
|
1788
1824
|
...reaction,
|
|
1789
1825
|
resolver: _void_
|
|
1790
1826
|
});
|
|
@@ -1837,20 +1873,23 @@ function _projection(target, events) {
|
|
|
1837
1873
|
}
|
|
1838
1874
|
};
|
|
1839
1875
|
const register = events[event];
|
|
1840
|
-
|
|
1841
|
-
|
|
1876
|
+
if (!handler.name)
|
|
1877
|
+
throw new Error(
|
|
1878
|
+
`Projection handler for "${event}" must be a named function`
|
|
1879
|
+
);
|
|
1880
|
+
register.reactions.set(handler.name, reaction);
|
|
1842
1881
|
const nextBuilder = _projection(target, events);
|
|
1843
1882
|
return {
|
|
1844
1883
|
...nextBuilder,
|
|
1845
1884
|
to(resolver) {
|
|
1846
|
-
register.reactions.set(name, {
|
|
1885
|
+
register.reactions.set(handler.name, {
|
|
1847
1886
|
...reaction,
|
|
1848
1887
|
resolver: typeof resolver === "string" ? { target: resolver } : resolver
|
|
1849
1888
|
});
|
|
1850
1889
|
return nextBuilder;
|
|
1851
1890
|
},
|
|
1852
1891
|
void() {
|
|
1853
|
-
register.reactions.set(name, {
|
|
1892
|
+
register.reactions.set(handler.name, {
|
|
1854
1893
|
...reaction,
|
|
1855
1894
|
resolver: _void_
|
|
1856
1895
|
});
|
|
@@ -1917,19 +1956,22 @@ function slice(states = /* @__PURE__ */ new Map(), actions = {}, events = {}, pr
|
|
|
1917
1956
|
maxRetries: options?.maxRetries ?? 3
|
|
1918
1957
|
}
|
|
1919
1958
|
};
|
|
1920
|
-
|
|
1921
|
-
|
|
1959
|
+
if (!handler.name)
|
|
1960
|
+
throw new Error(
|
|
1961
|
+
`Reaction handler for "${String(event)}" must be a named function`
|
|
1962
|
+
);
|
|
1963
|
+
events[event].reactions.set(handler.name, reaction);
|
|
1922
1964
|
return {
|
|
1923
1965
|
...builder,
|
|
1924
1966
|
to(resolver) {
|
|
1925
|
-
events[event].reactions.set(name, {
|
|
1967
|
+
events[event].reactions.set(handler.name, {
|
|
1926
1968
|
...reaction,
|
|
1927
1969
|
resolver: typeof resolver === "string" ? { target: resolver } : resolver
|
|
1928
1970
|
});
|
|
1929
1971
|
return builder;
|
|
1930
1972
|
},
|
|
1931
1973
|
void() {
|
|
1932
|
-
events[event].reactions.set(name, {
|
|
1974
|
+
events[event].reactions.set(handler.name, {
|
|
1933
1975
|
...reaction,
|
|
1934
1976
|
resolver: _void_
|
|
1935
1977
|
});
|