@rotorsoft/act 1.17.0 → 1.18.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.d.ts.map +1 -1
- package/dist/@types/builders/act-builder.d.ts +3 -6
- package/dist/@types/builders/act-builder.d.ts.map +1 -1
- package/dist/@types/builders/slice-builder.d.ts +16 -8
- package/dist/@types/builders/slice-builder.d.ts.map +1 -1
- package/dist/@types/index.d.ts +1 -0
- package/dist/@types/index.d.ts.map +1 -1
- package/dist/@types/internal/builder-utils.d.ts +65 -0
- package/dist/@types/internal/builder-utils.d.ts.map +1 -0
- package/dist/@types/internal/defer-config.d.ts +64 -0
- package/dist/@types/internal/defer-config.d.ts.map +1 -0
- package/dist/@types/internal/defer-signal.d.ts +19 -11
- package/dist/@types/internal/defer-signal.d.ts.map +1 -1
- package/dist/@types/internal/index.d.ts +3 -2
- package/dist/@types/internal/index.d.ts.map +1 -1
- package/dist/@types/internal/reactions.d.ts.map +1 -1
- package/dist/@types/types/action.d.ts +27 -0
- package/dist/@types/types/action.d.ts.map +1 -1
- package/dist/index.cjs +267 -234
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +266 -234
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -670,13 +670,258 @@ function classify_registry(registry, states) {
|
|
|
670
670
|
};
|
|
671
671
|
}
|
|
672
672
|
|
|
673
|
-
// src/internal/
|
|
673
|
+
// src/internal/defer-config.ts
|
|
674
674
|
import { z as z3 } from "zod";
|
|
675
|
+
|
|
676
|
+
// src/internal/defer-signal.ts
|
|
677
|
+
var DeferSignal = class extends Error {
|
|
678
|
+
/**
|
|
679
|
+
* The unresolved schedule. The dispatcher turns this into an absolute
|
|
680
|
+
* due-time by resolving it against the triggering event.
|
|
681
|
+
*/
|
|
682
|
+
when;
|
|
683
|
+
constructor(when) {
|
|
684
|
+
super("reaction deferred");
|
|
685
|
+
this.name = "DeferSignal";
|
|
686
|
+
this.when = when;
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
// src/internal/defer-config.ts
|
|
691
|
+
var DeferDurationSchema = z3.object({
|
|
692
|
+
days: z3.number().positive().optional(),
|
|
693
|
+
hours: z3.number().positive().optional(),
|
|
694
|
+
minutes: z3.number().positive().optional()
|
|
695
|
+
}).strict().refine((d) => d.days != null || d.hours != null || d.minutes != null, {
|
|
696
|
+
message: "defer: a duration needs at least one of days, hours, or minutes"
|
|
697
|
+
});
|
|
698
|
+
var DeferWhenSchema = z3.object({
|
|
699
|
+
after: DeferDurationSchema.optional(),
|
|
700
|
+
at: z3.date().optional()
|
|
701
|
+
}).strict().refine((w) => w.after === void 0 !== (w.at === void 0), {
|
|
702
|
+
message: "defer: specify exactly one of `after` or `at`"
|
|
703
|
+
});
|
|
704
|
+
function duration_ms(d) {
|
|
705
|
+
return (d.days ?? 0) * 864e5 + (d.hours ?? 0) * 36e5 + (d.minutes ?? 0) * 6e4;
|
|
706
|
+
}
|
|
707
|
+
function resolve_defer_at(when, event) {
|
|
708
|
+
const parsed = DeferWhenSchema.parse(when);
|
|
709
|
+
if (parsed.after) return event.created.getTime() + duration_ms(parsed.after);
|
|
710
|
+
return parsed.at.getTime();
|
|
711
|
+
}
|
|
712
|
+
function assert_defer_when(when) {
|
|
713
|
+
DeferWhenSchema.parse(when);
|
|
714
|
+
}
|
|
715
|
+
function make_deferred(handler, schedule) {
|
|
716
|
+
const call = handler;
|
|
717
|
+
const deferred = async (event, stream, app) => {
|
|
718
|
+
const when = typeof schedule === "function" ? schedule(event) : schedule;
|
|
719
|
+
if (Date.now() < resolve_defer_at(when, event)) throw new DeferSignal(when);
|
|
720
|
+
return call(event, stream, app);
|
|
721
|
+
};
|
|
722
|
+
Object.defineProperty(deferred, "name", { value: handler.name });
|
|
723
|
+
return deferred;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// src/internal/merge.ts
|
|
727
|
+
import { ZodObject } from "zod";
|
|
728
|
+
function base_type_name(zodType) {
|
|
729
|
+
let t = zodType;
|
|
730
|
+
while (typeof t.unwrap === "function") {
|
|
731
|
+
t = t.unwrap();
|
|
732
|
+
}
|
|
733
|
+
return t.constructor.name;
|
|
734
|
+
}
|
|
735
|
+
function merge_schemas(existing, incoming, state_name) {
|
|
736
|
+
if (existing instanceof ZodObject && incoming instanceof ZodObject) {
|
|
737
|
+
const existing_shape = existing.shape;
|
|
738
|
+
const incoming_shape = incoming.shape;
|
|
739
|
+
for (const key of Object.keys(incoming_shape)) {
|
|
740
|
+
if (key in existing_shape) {
|
|
741
|
+
const existing_base = base_type_name(existing_shape[key]);
|
|
742
|
+
const incoming_base = base_type_name(incoming_shape[key]);
|
|
743
|
+
if (existing_base !== incoming_base) {
|
|
744
|
+
throw new Error(
|
|
745
|
+
`Schema conflict in "${state_name}": key "${key}" has type "${existing_base}" but incoming partial declares "${incoming_base}"`
|
|
746
|
+
);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
return existing.extend(incoming_shape);
|
|
751
|
+
}
|
|
752
|
+
return existing;
|
|
753
|
+
}
|
|
754
|
+
function merge_inits(existing, incoming) {
|
|
755
|
+
return () => ({ ...existing(), ...incoming() });
|
|
756
|
+
}
|
|
757
|
+
function register_state(state2, states, actions, events) {
|
|
758
|
+
const existing = states.get(state2.name);
|
|
759
|
+
if (existing) {
|
|
760
|
+
merge_into_existing(state2, existing, states, actions, events);
|
|
761
|
+
} else {
|
|
762
|
+
register_new_state(state2, states, actions, events);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
function register_new_state(state2, states, actions, events) {
|
|
766
|
+
states.set(state2.name, state2);
|
|
767
|
+
for (const name of Object.keys(state2.actions)) {
|
|
768
|
+
if (actions[name]) throw new Error(`Duplicate action "${name}"`);
|
|
769
|
+
actions[name] = state2;
|
|
770
|
+
}
|
|
771
|
+
for (const name of Object.keys(state2.events)) {
|
|
772
|
+
if (events[name]) throw new Error(`Duplicate event "${name}"`);
|
|
773
|
+
events[name] = { schema: state2.events[name], reactions: /* @__PURE__ */ new Map() };
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
function merge_into_existing(state2, existing, states, actions, events) {
|
|
777
|
+
for (const name of Object.keys(state2.actions)) {
|
|
778
|
+
if (existing.actions[name] === state2.actions[name]) continue;
|
|
779
|
+
if (actions[name]) throw new Error(`Duplicate action "${name}"`);
|
|
780
|
+
}
|
|
781
|
+
for (const name of Object.keys(state2.events)) {
|
|
782
|
+
if (existing.events[name] === state2.events[name]) continue;
|
|
783
|
+
if (existing.events[name]) {
|
|
784
|
+
throw new Error(
|
|
785
|
+
`Event "${name}" in state "${state2.name}" is declared with different Zod schemas across slices. Cross-slice event schemas must reference the same instance \u2014 extract a shared schema (e.g. \`export const ${name} = z.object({ ... })\` in a shared module) and import it in every slice that declares it.`
|
|
786
|
+
);
|
|
787
|
+
}
|
|
788
|
+
if (events[name]) throw new Error(`Duplicate event "${name}"`);
|
|
789
|
+
}
|
|
790
|
+
const merged_patch = merge_patches(existing.patch, state2.patch, state2.name);
|
|
791
|
+
const merged = {
|
|
792
|
+
...existing,
|
|
793
|
+
state: merge_schemas(existing.state, state2.state, state2.name),
|
|
794
|
+
init: merge_inits(existing.init, state2.init),
|
|
795
|
+
events: { ...existing.events, ...state2.events },
|
|
796
|
+
actions: { ...existing.actions, ...state2.actions },
|
|
797
|
+
patch: merged_patch,
|
|
798
|
+
on: { ...existing.on, ...state2.on },
|
|
799
|
+
given: { ...existing.given, ...state2.given },
|
|
800
|
+
snap: state2.snap && existing.snap && state2.snap !== existing.snap ? (() => {
|
|
801
|
+
throw new Error(
|
|
802
|
+
`Duplicate snap strategy for state "${state2.name}"`
|
|
803
|
+
);
|
|
804
|
+
})() : state2.snap || existing.snap
|
|
805
|
+
};
|
|
806
|
+
states.set(state2.name, merged);
|
|
807
|
+
for (const name of Object.keys(merged.actions)) {
|
|
808
|
+
actions[name] = merged;
|
|
809
|
+
}
|
|
810
|
+
for (const name of Object.keys(state2.events)) {
|
|
811
|
+
if (events[name]) continue;
|
|
812
|
+
events[name] = { schema: state2.events[name], reactions: /* @__PURE__ */ new Map() };
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
function merge_patches(existing, incoming, state_name) {
|
|
816
|
+
const merged = { ...existing };
|
|
817
|
+
for (const name of Object.keys(incoming)) {
|
|
818
|
+
const existing_p = existing[name];
|
|
819
|
+
const incoming_p = incoming[name];
|
|
820
|
+
if (!existing_p) {
|
|
821
|
+
merged[name] = incoming_p;
|
|
822
|
+
continue;
|
|
823
|
+
}
|
|
824
|
+
const existing_is_default = existing_p._passthrough;
|
|
825
|
+
const incoming_is_default = incoming_p._passthrough;
|
|
826
|
+
if (!existing_is_default && !incoming_is_default && existing_p !== incoming_p) {
|
|
827
|
+
throw new Error(
|
|
828
|
+
`Duplicate custom patch for event "${name}" in state "${state_name}"`
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
if (existing_is_default && !incoming_is_default) {
|
|
832
|
+
merged[name] = incoming_p;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
return merged;
|
|
836
|
+
}
|
|
837
|
+
function merge_event_register(target, source) {
|
|
838
|
+
for (const [event_name, source_reg] of Object.entries(source)) {
|
|
839
|
+
const target_reg = target[event_name];
|
|
840
|
+
if (!target_reg) continue;
|
|
841
|
+
for (const [name, reaction] of source_reg.reactions) {
|
|
842
|
+
const existing = target_reg.reactions.get(name);
|
|
843
|
+
if (existing !== void 0 && existing !== reaction)
|
|
844
|
+
throw new Error(
|
|
845
|
+
`Duplicate reaction "${name}" for event "${event_name}". Reaction handlers are keyed by function name; rename one of them.`
|
|
846
|
+
);
|
|
847
|
+
target_reg.reactions.set(name, reaction);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
function merge_projection(proj, events) {
|
|
852
|
+
for (const event_name of Object.keys(proj.events)) {
|
|
853
|
+
const proj_register = proj.events[event_name];
|
|
854
|
+
const existing = events[event_name];
|
|
855
|
+
if (!existing) {
|
|
856
|
+
events[event_name] = {
|
|
857
|
+
schema: proj_register.schema,
|
|
858
|
+
reactions: new Map(proj_register.reactions)
|
|
859
|
+
};
|
|
860
|
+
} else {
|
|
861
|
+
for (const [name, reaction] of proj_register.reactions) {
|
|
862
|
+
let key = name;
|
|
863
|
+
while (existing.reactions.has(key)) key = `${key}_p`;
|
|
864
|
+
existing.reactions.set(key, reaction);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
var _this_ = ({ stream }) => ({
|
|
870
|
+
source: stream,
|
|
871
|
+
target: stream
|
|
872
|
+
});
|
|
873
|
+
|
|
874
|
+
// src/internal/builder-utils.ts
|
|
875
|
+
function register_lane(config2, lanes) {
|
|
876
|
+
if (config2.name === DEFAULT_LANE)
|
|
877
|
+
throw new Error(`Lane "${DEFAULT_LANE}" is reserved`);
|
|
878
|
+
if (lanes.some((l) => l.name === config2.name))
|
|
879
|
+
throw new Error(`Lane "${config2.name}" was already declared`);
|
|
880
|
+
lanes.push(config2);
|
|
881
|
+
}
|
|
882
|
+
function reaction_on(event, events, builder) {
|
|
883
|
+
const register = (handler, options, schedule) => {
|
|
884
|
+
if (!handler.name)
|
|
885
|
+
throw new Error(
|
|
886
|
+
`Reaction handler for "${String(event)}" must be a named function`
|
|
887
|
+
);
|
|
888
|
+
if (events[event].reactions.has(handler.name))
|
|
889
|
+
throw new Error(
|
|
890
|
+
`Duplicate reaction "${handler.name}" for event "${String(event)}". Reaction handlers are keyed by function name; rename one of them.`
|
|
891
|
+
);
|
|
892
|
+
if (schedule && typeof schedule !== "function") assert_defer_when(schedule);
|
|
893
|
+
const reaction = {
|
|
894
|
+
handler: schedule ? make_deferred(handler, schedule) : handler,
|
|
895
|
+
resolver: _this_,
|
|
896
|
+
options: {
|
|
897
|
+
blockOnError: options?.blockOnError ?? true,
|
|
898
|
+
maxRetries: options?.maxRetries ?? 3,
|
|
899
|
+
backoff: options?.backoff
|
|
900
|
+
}
|
|
901
|
+
};
|
|
902
|
+
events[event].reactions.set(handler.name, reaction);
|
|
903
|
+
return Object.assign(builder, {
|
|
904
|
+
to(resolver) {
|
|
905
|
+
reaction.resolver = typeof resolver === "string" ? { target: resolver } : resolver;
|
|
906
|
+
return builder;
|
|
907
|
+
}
|
|
908
|
+
});
|
|
909
|
+
};
|
|
910
|
+
return {
|
|
911
|
+
do: (handler, options) => register(handler, options),
|
|
912
|
+
defer: (schedule) => ({
|
|
913
|
+
do: (handler, options) => register(handler, options, schedule)
|
|
914
|
+
})
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// src/internal/circuit-breaker.ts
|
|
919
|
+
import { z as z4 } from "zod";
|
|
675
920
|
var DEFAULT_CIRCUIT_FAILURE_THRESHOLD = 5;
|
|
676
921
|
var DEFAULT_CIRCUIT_COOLDOWN_MS = 3e4;
|
|
677
|
-
var CircuitBreakerOptionsSchema =
|
|
678
|
-
failureThreshold:
|
|
679
|
-
cooldownMs:
|
|
922
|
+
var CircuitBreakerOptionsSchema = z4.object({
|
|
923
|
+
failureThreshold: z4.number().int().min(1).default(DEFAULT_CIRCUIT_FAILURE_THRESHOLD),
|
|
924
|
+
cooldownMs: z4.number().int().min(100).max(36e5).default(DEFAULT_CIRCUIT_COOLDOWN_MS)
|
|
680
925
|
});
|
|
681
926
|
var resolveCircuitBreakerConfig = (options) => CircuitBreakerOptionsSchema.parse(options ?? {});
|
|
682
927
|
var CircuitBreaker = class {
|
|
@@ -1106,17 +1351,6 @@ function close_correlation(correlator, actor) {
|
|
|
1106
1351
|
});
|
|
1107
1352
|
}
|
|
1108
1353
|
|
|
1109
|
-
// src/internal/defer-signal.ts
|
|
1110
|
-
var DeferSignal = class extends Error {
|
|
1111
|
-
/** Wall-clock time (ms since epoch) to re-visit the stream. */
|
|
1112
|
-
defer_at;
|
|
1113
|
-
constructor(defer_at) {
|
|
1114
|
-
super("reaction deferred");
|
|
1115
|
-
this.name = "DeferSignal";
|
|
1116
|
-
this.defer_at = defer_at;
|
|
1117
|
-
}
|
|
1118
|
-
};
|
|
1119
|
-
|
|
1120
1354
|
// src/internal/drain-cycle.ts
|
|
1121
1355
|
import { randomUUID } from "crypto";
|
|
1122
1356
|
|
|
@@ -1963,154 +2197,6 @@ var DrainController = class {
|
|
|
1963
2197
|
}
|
|
1964
2198
|
};
|
|
1965
2199
|
|
|
1966
|
-
// src/internal/merge.ts
|
|
1967
|
-
import { ZodObject } from "zod";
|
|
1968
|
-
function base_type_name(zodType) {
|
|
1969
|
-
let t = zodType;
|
|
1970
|
-
while (typeof t.unwrap === "function") {
|
|
1971
|
-
t = t.unwrap();
|
|
1972
|
-
}
|
|
1973
|
-
return t.constructor.name;
|
|
1974
|
-
}
|
|
1975
|
-
function merge_schemas(existing, incoming, state_name) {
|
|
1976
|
-
if (existing instanceof ZodObject && incoming instanceof ZodObject) {
|
|
1977
|
-
const existing_shape = existing.shape;
|
|
1978
|
-
const incoming_shape = incoming.shape;
|
|
1979
|
-
for (const key of Object.keys(incoming_shape)) {
|
|
1980
|
-
if (key in existing_shape) {
|
|
1981
|
-
const existing_base = base_type_name(existing_shape[key]);
|
|
1982
|
-
const incoming_base = base_type_name(incoming_shape[key]);
|
|
1983
|
-
if (existing_base !== incoming_base) {
|
|
1984
|
-
throw new Error(
|
|
1985
|
-
`Schema conflict in "${state_name}": key "${key}" has type "${existing_base}" but incoming partial declares "${incoming_base}"`
|
|
1986
|
-
);
|
|
1987
|
-
}
|
|
1988
|
-
}
|
|
1989
|
-
}
|
|
1990
|
-
return existing.extend(incoming_shape);
|
|
1991
|
-
}
|
|
1992
|
-
return existing;
|
|
1993
|
-
}
|
|
1994
|
-
function merge_inits(existing, incoming) {
|
|
1995
|
-
return () => ({ ...existing(), ...incoming() });
|
|
1996
|
-
}
|
|
1997
|
-
function register_state(state2, states, actions, events) {
|
|
1998
|
-
const existing = states.get(state2.name);
|
|
1999
|
-
if (existing) {
|
|
2000
|
-
merge_into_existing(state2, existing, states, actions, events);
|
|
2001
|
-
} else {
|
|
2002
|
-
register_new_state(state2, states, actions, events);
|
|
2003
|
-
}
|
|
2004
|
-
}
|
|
2005
|
-
function register_new_state(state2, states, actions, events) {
|
|
2006
|
-
states.set(state2.name, state2);
|
|
2007
|
-
for (const name of Object.keys(state2.actions)) {
|
|
2008
|
-
if (actions[name]) throw new Error(`Duplicate action "${name}"`);
|
|
2009
|
-
actions[name] = state2;
|
|
2010
|
-
}
|
|
2011
|
-
for (const name of Object.keys(state2.events)) {
|
|
2012
|
-
if (events[name]) throw new Error(`Duplicate event "${name}"`);
|
|
2013
|
-
events[name] = { schema: state2.events[name], reactions: /* @__PURE__ */ new Map() };
|
|
2014
|
-
}
|
|
2015
|
-
}
|
|
2016
|
-
function merge_into_existing(state2, existing, states, actions, events) {
|
|
2017
|
-
for (const name of Object.keys(state2.actions)) {
|
|
2018
|
-
if (existing.actions[name] === state2.actions[name]) continue;
|
|
2019
|
-
if (actions[name]) throw new Error(`Duplicate action "${name}"`);
|
|
2020
|
-
}
|
|
2021
|
-
for (const name of Object.keys(state2.events)) {
|
|
2022
|
-
if (existing.events[name] === state2.events[name]) continue;
|
|
2023
|
-
if (existing.events[name]) {
|
|
2024
|
-
throw new Error(
|
|
2025
|
-
`Event "${name}" in state "${state2.name}" is declared with different Zod schemas across slices. Cross-slice event schemas must reference the same instance \u2014 extract a shared schema (e.g. \`export const ${name} = z.object({ ... })\` in a shared module) and import it in every slice that declares it.`
|
|
2026
|
-
);
|
|
2027
|
-
}
|
|
2028
|
-
if (events[name]) throw new Error(`Duplicate event "${name}"`);
|
|
2029
|
-
}
|
|
2030
|
-
const merged_patch = merge_patches(existing.patch, state2.patch, state2.name);
|
|
2031
|
-
const merged = {
|
|
2032
|
-
...existing,
|
|
2033
|
-
state: merge_schemas(existing.state, state2.state, state2.name),
|
|
2034
|
-
init: merge_inits(existing.init, state2.init),
|
|
2035
|
-
events: { ...existing.events, ...state2.events },
|
|
2036
|
-
actions: { ...existing.actions, ...state2.actions },
|
|
2037
|
-
patch: merged_patch,
|
|
2038
|
-
on: { ...existing.on, ...state2.on },
|
|
2039
|
-
given: { ...existing.given, ...state2.given },
|
|
2040
|
-
snap: state2.snap && existing.snap && state2.snap !== existing.snap ? (() => {
|
|
2041
|
-
throw new Error(
|
|
2042
|
-
`Duplicate snap strategy for state "${state2.name}"`
|
|
2043
|
-
);
|
|
2044
|
-
})() : state2.snap || existing.snap
|
|
2045
|
-
};
|
|
2046
|
-
states.set(state2.name, merged);
|
|
2047
|
-
for (const name of Object.keys(merged.actions)) {
|
|
2048
|
-
actions[name] = merged;
|
|
2049
|
-
}
|
|
2050
|
-
for (const name of Object.keys(state2.events)) {
|
|
2051
|
-
if (events[name]) continue;
|
|
2052
|
-
events[name] = { schema: state2.events[name], reactions: /* @__PURE__ */ new Map() };
|
|
2053
|
-
}
|
|
2054
|
-
}
|
|
2055
|
-
function merge_patches(existing, incoming, state_name) {
|
|
2056
|
-
const merged = { ...existing };
|
|
2057
|
-
for (const name of Object.keys(incoming)) {
|
|
2058
|
-
const existing_p = existing[name];
|
|
2059
|
-
const incoming_p = incoming[name];
|
|
2060
|
-
if (!existing_p) {
|
|
2061
|
-
merged[name] = incoming_p;
|
|
2062
|
-
continue;
|
|
2063
|
-
}
|
|
2064
|
-
const existing_is_default = existing_p._passthrough;
|
|
2065
|
-
const incoming_is_default = incoming_p._passthrough;
|
|
2066
|
-
if (!existing_is_default && !incoming_is_default && existing_p !== incoming_p) {
|
|
2067
|
-
throw new Error(
|
|
2068
|
-
`Duplicate custom patch for event "${name}" in state "${state_name}"`
|
|
2069
|
-
);
|
|
2070
|
-
}
|
|
2071
|
-
if (existing_is_default && !incoming_is_default) {
|
|
2072
|
-
merged[name] = incoming_p;
|
|
2073
|
-
}
|
|
2074
|
-
}
|
|
2075
|
-
return merged;
|
|
2076
|
-
}
|
|
2077
|
-
function merge_event_register(target, source) {
|
|
2078
|
-
for (const [event_name, source_reg] of Object.entries(source)) {
|
|
2079
|
-
const target_reg = target[event_name];
|
|
2080
|
-
if (!target_reg) continue;
|
|
2081
|
-
for (const [name, reaction] of source_reg.reactions) {
|
|
2082
|
-
const existing = target_reg.reactions.get(name);
|
|
2083
|
-
if (existing !== void 0 && existing !== reaction)
|
|
2084
|
-
throw new Error(
|
|
2085
|
-
`Duplicate reaction "${name}" for event "${event_name}". Reaction handlers are keyed by function name; rename one of them.`
|
|
2086
|
-
);
|
|
2087
|
-
target_reg.reactions.set(name, reaction);
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
|
-
}
|
|
2091
|
-
function merge_projection(proj, events) {
|
|
2092
|
-
for (const event_name of Object.keys(proj.events)) {
|
|
2093
|
-
const proj_register = proj.events[event_name];
|
|
2094
|
-
const existing = events[event_name];
|
|
2095
|
-
if (!existing) {
|
|
2096
|
-
events[event_name] = {
|
|
2097
|
-
schema: proj_register.schema,
|
|
2098
|
-
reactions: new Map(proj_register.reactions)
|
|
2099
|
-
};
|
|
2100
|
-
} else {
|
|
2101
|
-
for (const [name, reaction] of proj_register.reactions) {
|
|
2102
|
-
let key = name;
|
|
2103
|
-
while (existing.reactions.has(key)) key = `${key}_p`;
|
|
2104
|
-
existing.reactions.set(key, reaction);
|
|
2105
|
-
}
|
|
2106
|
-
}
|
|
2107
|
-
}
|
|
2108
|
-
}
|
|
2109
|
-
var _this_ = ({ stream }) => ({
|
|
2110
|
-
source: stream,
|
|
2111
|
-
target: stream
|
|
2112
|
-
});
|
|
2113
|
-
|
|
2114
2200
|
// src/internal/reactions.ts
|
|
2115
2201
|
function finalize(lease, handled, at, error, options, logger, failed_at) {
|
|
2116
2202
|
if (!error) return { lease, handled, acked_at: at };
|
|
@@ -2167,7 +2253,12 @@ function build_handle(deps) {
|
|
|
2167
2253
|
handled++;
|
|
2168
2254
|
} catch (error) {
|
|
2169
2255
|
if (error instanceof DeferSignal)
|
|
2170
|
-
return {
|
|
2256
|
+
return {
|
|
2257
|
+
lease,
|
|
2258
|
+
handled,
|
|
2259
|
+
acked_at: at,
|
|
2260
|
+
defer: resolve_defer_at(error.when, event)
|
|
2261
|
+
};
|
|
2171
2262
|
if (error instanceof CloseSignal)
|
|
2172
2263
|
return {
|
|
2173
2264
|
lease,
|
|
@@ -2487,9 +2578,9 @@ var Act = class {
|
|
|
2487
2578
|
const aggregate = event.stream;
|
|
2488
2579
|
const config2 = this._autoclose_config;
|
|
2489
2580
|
if (!in_autoclose_window(config2.autocloseWindow, /* @__PURE__ */ new Date()))
|
|
2490
|
-
throw new DeferSignal(
|
|
2491
|
-
Date.now() + config2.autocloseCycleMinutes * 6e4
|
|
2492
|
-
);
|
|
2581
|
+
throw new DeferSignal({
|
|
2582
|
+
at: new Date(Date.now() + config2.autocloseCycleMinutes * 6e4)
|
|
2583
|
+
});
|
|
2493
2584
|
const stats = await store().query_stats([aggregate], {
|
|
2494
2585
|
count: true,
|
|
2495
2586
|
exclude: [TOMBSTONE_EVENT]
|
|
@@ -2507,7 +2598,9 @@ var Act = class {
|
|
|
2507
2598
|
at: head.id
|
|
2508
2599
|
});
|
|
2509
2600
|
if (after_ms !== void 0)
|
|
2510
|
-
throw new DeferSignal(
|
|
2601
|
+
throw new DeferSignal({
|
|
2602
|
+
at: new Date(head.created.getTime() + after_ms)
|
|
2603
|
+
});
|
|
2511
2604
|
}
|
|
2512
2605
|
};
|
|
2513
2606
|
const key = `__autoclose_${st.name}`;
|
|
@@ -3608,41 +3701,10 @@ function act() {
|
|
|
3608
3701
|
},
|
|
3609
3702
|
withActor: () => builder,
|
|
3610
3703
|
withLane: (config2) => {
|
|
3611
|
-
|
|
3612
|
-
throw new Error(`Lane "${DEFAULT_LANE}" is reserved`);
|
|
3613
|
-
if (lanes.some((l) => l.name === config2.name))
|
|
3614
|
-
throw new Error(`Lane "${config2.name}" was already declared`);
|
|
3615
|
-
lanes.push(config2);
|
|
3704
|
+
register_lane(config2, lanes);
|
|
3616
3705
|
return builder;
|
|
3617
3706
|
},
|
|
3618
|
-
on: (event) => (
|
|
3619
|
-
do: (handler, options) => {
|
|
3620
|
-
const reaction = {
|
|
3621
|
-
handler,
|
|
3622
|
-
resolver: _this_,
|
|
3623
|
-
options: {
|
|
3624
|
-
blockOnError: options?.blockOnError ?? true,
|
|
3625
|
-
maxRetries: options?.maxRetries ?? 3,
|
|
3626
|
-
backoff: options?.backoff
|
|
3627
|
-
}
|
|
3628
|
-
};
|
|
3629
|
-
if (!handler.name)
|
|
3630
|
-
throw new Error(
|
|
3631
|
-
`Reaction handler for "${String(event)}" must be a named function`
|
|
3632
|
-
);
|
|
3633
|
-
if (registry.events[event].reactions.has(handler.name))
|
|
3634
|
-
throw new Error(
|
|
3635
|
-
`Duplicate reaction "${handler.name}" for event "${String(event)}". Reaction handlers are keyed by function name; rename one of them.`
|
|
3636
|
-
);
|
|
3637
|
-
registry.events[event].reactions.set(handler.name, reaction);
|
|
3638
|
-
return Object.assign(builder, {
|
|
3639
|
-
to(resolver) {
|
|
3640
|
-
reaction.resolver = typeof resolver === "string" ? { target: resolver } : resolver;
|
|
3641
|
-
return builder;
|
|
3642
|
-
}
|
|
3643
|
-
});
|
|
3644
|
-
}
|
|
3645
|
-
}),
|
|
3707
|
+
on: (event) => reaction_on(event, registry.events, builder),
|
|
3646
3708
|
build: (options) => {
|
|
3647
3709
|
if (!_built) {
|
|
3648
3710
|
for (const proj of pending_projections) {
|
|
@@ -3807,41 +3869,10 @@ function slice() {
|
|
|
3807
3869
|
return builder;
|
|
3808
3870
|
},
|
|
3809
3871
|
withLane: (config2) => {
|
|
3810
|
-
|
|
3811
|
-
throw new Error(`Lane "${DEFAULT_LANE}" is reserved`);
|
|
3812
|
-
if (lanes.some((l) => l.name === config2.name))
|
|
3813
|
-
throw new Error(`Lane "${config2.name}" was already declared`);
|
|
3814
|
-
lanes.push(config2);
|
|
3872
|
+
register_lane(config2, lanes);
|
|
3815
3873
|
return builder;
|
|
3816
3874
|
},
|
|
3817
|
-
on: (event) => (
|
|
3818
|
-
do: (handler, options) => {
|
|
3819
|
-
const reaction = {
|
|
3820
|
-
handler,
|
|
3821
|
-
resolver: _this_,
|
|
3822
|
-
options: {
|
|
3823
|
-
blockOnError: options?.blockOnError ?? true,
|
|
3824
|
-
maxRetries: options?.maxRetries ?? 3,
|
|
3825
|
-
backoff: options?.backoff
|
|
3826
|
-
}
|
|
3827
|
-
};
|
|
3828
|
-
if (!handler.name)
|
|
3829
|
-
throw new Error(
|
|
3830
|
-
`Reaction handler for "${String(event)}" must be a named function`
|
|
3831
|
-
);
|
|
3832
|
-
if (events[event].reactions.has(handler.name))
|
|
3833
|
-
throw new Error(
|
|
3834
|
-
`Duplicate reaction "${handler.name}" for event "${String(event)}". Reaction handlers are keyed by function name; rename one of them.`
|
|
3835
|
-
);
|
|
3836
|
-
events[event].reactions.set(handler.name, reaction);
|
|
3837
|
-
return Object.assign(builder, {
|
|
3838
|
-
to(resolver) {
|
|
3839
|
-
reaction.resolver = typeof resolver === "string" ? { target: resolver } : resolver;
|
|
3840
|
-
return builder;
|
|
3841
|
-
}
|
|
3842
|
-
});
|
|
3843
|
-
}
|
|
3844
|
-
}),
|
|
3875
|
+
on: (event) => reaction_on(event, events, builder),
|
|
3845
3876
|
build: () => ({
|
|
3846
3877
|
_tag: "Slice",
|
|
3847
3878
|
states,
|
|
@@ -4151,6 +4182,7 @@ export {
|
|
|
4151
4182
|
DEFAULT_LANE,
|
|
4152
4183
|
DEFAULT_MAX_SUBSCRIBED_STREAMS,
|
|
4153
4184
|
DEFAULT_SETTLE_DEBOUNCE_MS,
|
|
4185
|
+
DeferSignal,
|
|
4154
4186
|
Environments,
|
|
4155
4187
|
Errors,
|
|
4156
4188
|
EventMetaSchema,
|