@rotorsoft/act 1.23.5 → 1.23.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/act.d.ts.map +1 -1
- 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/builders/state-builder.d.ts.map +1 -1
- package/dist/@types/internal/autoclose-reaction.d.ts +1 -1
- package/dist/@types/internal/autoclose-reaction.d.ts.map +1 -1
- package/dist/@types/internal/autoclose-window.d.ts +66 -0
- package/dist/@types/internal/autoclose-window.d.ts.map +1 -0
- package/dist/@types/internal/backoff.d.ts.map +1 -1
- package/dist/@types/internal/builder-utils.d.ts.map +1 -1
- package/dist/@types/internal/circuit-breaker.d.ts +1 -19
- package/dist/@types/internal/circuit-breaker.d.ts.map +1 -1
- package/dist/@types/internal/config.d.ts +139 -0
- package/dist/@types/internal/config.d.ts.map +1 -0
- package/dist/@types/internal/event-sourcing.d.ts.map +1 -1
- package/dist/@types/internal/index.d.ts +4 -3
- package/dist/@types/internal/index.d.ts.map +1 -1
- package/dist/@types/internal/projection-fold.d.ts +2 -11
- package/dist/@types/internal/projection-fold.d.ts.map +1 -1
- package/dist/@types/types/action.d.ts +14 -3
- package/dist/@types/types/action.d.ts.map +1 -1
- package/dist/{chunk-DORIRU2I.js → chunk-C7H3GARW.js} +14 -11
- package/dist/chunk-C7H3GARW.js.map +1 -0
- package/dist/index.cjs +200 -118
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +188 -109
- package/dist/index.js.map +1 -1
- package/dist/test/index.cjs +13 -10
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.js +1 -1
- package/package.json +2 -2
- package/dist/@types/internal/autoclose-config.d.ts +0 -142
- package/dist/@types/internal/autoclose-config.d.ts.map +0 -1
- package/dist/chunk-DORIRU2I.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
sleep,
|
|
21
21
|
store,
|
|
22
22
|
validate
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-C7H3GARW.js";
|
|
24
24
|
import {
|
|
25
25
|
ActorSchema,
|
|
26
26
|
CausationEventSchema,
|
|
@@ -496,84 +496,8 @@ var PASS_FACTORIES = {
|
|
|
496
496
|
"clock-anomalies": make_clock_anomalies_pass
|
|
497
497
|
};
|
|
498
498
|
|
|
499
|
-
// src/internal/autoclose-config.ts
|
|
500
|
-
import { z } from "zod";
|
|
501
|
-
var DEFAULT_AUTOCLOSE_CYCLE_MINUTES = 720;
|
|
502
|
-
var DEFAULT_CLOSE_BATCH_SIZE = 64;
|
|
503
|
-
var DEFAULT_CLOSE_YIELD_MS = 0;
|
|
504
|
-
var DEFAULT_AUTOCLOSE_WINDOW_TZ = "UTC";
|
|
505
|
-
function is_valid_time_zone(tz) {
|
|
506
|
-
try {
|
|
507
|
-
new Intl.DateTimeFormat("en-US", { timeZone: tz });
|
|
508
|
-
return true;
|
|
509
|
-
} catch {
|
|
510
|
-
return false;
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
var AutocloseWindowSchema = z.object({
|
|
514
|
-
start: z.number().int().min(0).max(23, { message: "autocloseWindow.start must be an hour in [0, 23]" }),
|
|
515
|
-
end: z.number().int().min(0).max(23, { message: "autocloseWindow.end must be an hour in [0, 23]" }),
|
|
516
|
-
timeZone: z.string().refine(is_valid_time_zone, {
|
|
517
|
-
message: "autocloseWindow.timeZone must be a valid IANA time zone"
|
|
518
|
-
}).default(DEFAULT_AUTOCLOSE_WINDOW_TZ)
|
|
519
|
-
}).refine((w) => w.start !== w.end, {
|
|
520
|
-
message: "autocloseWindow.start and end must differ \u2014 an empty window disables autoclose"
|
|
521
|
-
});
|
|
522
|
-
var AutocloseOptionsSchema = z.object({
|
|
523
|
-
autocloseCycleMinutes: z.number().int().min(1).max(1440).default(DEFAULT_AUTOCLOSE_CYCLE_MINUTES),
|
|
524
|
-
closeBatchSize: z.number().int().min(1).max(1024).default(DEFAULT_CLOSE_BATCH_SIZE),
|
|
525
|
-
closeYieldMs: z.number().min(0).max(1e3).default(DEFAULT_CLOSE_YIELD_MS),
|
|
526
|
-
closeOnError: z.boolean().default(false),
|
|
527
|
-
autocloseWindow: AutocloseWindowSchema.optional()
|
|
528
|
-
});
|
|
529
|
-
function resolveAutocloseConfig(options) {
|
|
530
|
-
return AutocloseOptionsSchema.parse({
|
|
531
|
-
autocloseCycleMinutes: options?.autocloseCycleMinutes,
|
|
532
|
-
closeBatchSize: options?.closeBatchSize,
|
|
533
|
-
closeYieldMs: options?.closeYieldMs,
|
|
534
|
-
closeOnError: options?.closeOnError,
|
|
535
|
-
autocloseWindow: options?.autocloseWindow
|
|
536
|
-
});
|
|
537
|
-
}
|
|
538
|
-
function hour_in_zone(now, timeZone) {
|
|
539
|
-
const parts = new Intl.DateTimeFormat("en-US", {
|
|
540
|
-
timeZone,
|
|
541
|
-
hour: "2-digit",
|
|
542
|
-
hourCycle: "h23"
|
|
543
|
-
}).formatToParts(now);
|
|
544
|
-
return Number(parts.find((p) => p.type === "hour")?.value);
|
|
545
|
-
}
|
|
546
|
-
function hour_in_range(hour, start, end) {
|
|
547
|
-
return start < end ? hour >= start && hour < end : hour >= start || hour < end;
|
|
548
|
-
}
|
|
549
|
-
function is_dst_gap_open(now, timeZone, start) {
|
|
550
|
-
const hour = hour_in_zone(now, timeZone);
|
|
551
|
-
if (hour <= start) return false;
|
|
552
|
-
const prev = hour_in_zone(new Date(now.getTime() - 36e5), timeZone);
|
|
553
|
-
return prev === start - 1 && hour === start + 1;
|
|
554
|
-
}
|
|
555
|
-
function in_autoclose_window(window, now) {
|
|
556
|
-
if (!window) return true;
|
|
557
|
-
const hour = hour_in_zone(now, window.timeZone);
|
|
558
|
-
return hour_in_range(hour, window.start, window.end) || is_dst_gap_open(now, window.timeZone, window.start);
|
|
559
|
-
}
|
|
560
|
-
function next_window_open(window, now) {
|
|
561
|
-
const start_ms = now.getTime();
|
|
562
|
-
for (let h = 0; h <= 48; h++) {
|
|
563
|
-
const candidate = new Date(start_ms + h * 36e5);
|
|
564
|
-
if (hour_in_zone(candidate, window.timeZone) === window.start)
|
|
565
|
-
return candidate;
|
|
566
|
-
const boundary = new Date(
|
|
567
|
-
candidate.getTime() - candidate.getTime() % 36e5
|
|
568
|
-
);
|
|
569
|
-
if (is_dst_gap_open(boundary, window.timeZone, window.start))
|
|
570
|
-
return boundary;
|
|
571
|
-
}
|
|
572
|
-
return new Date(start_ms + 864e5);
|
|
573
|
-
}
|
|
574
|
-
|
|
575
499
|
// src/internal/autoclose-policy.ts
|
|
576
|
-
import { z
|
|
500
|
+
import { z } from "zod";
|
|
577
501
|
var DAY_MS = 864e5;
|
|
578
502
|
var MIN_AFTER_DAYS = 1 / 1440;
|
|
579
503
|
var MIN_KEEP_DAYS = 1;
|
|
@@ -583,21 +507,21 @@ function days_after(date, days) {
|
|
|
583
507
|
function days_before_now(days) {
|
|
584
508
|
return new Date(Date.now() - days * DAY_MS);
|
|
585
509
|
}
|
|
586
|
-
var window_schema = (field, min_days, floor) =>
|
|
587
|
-
days:
|
|
510
|
+
var window_schema = (field, min_days, floor) => z.object({
|
|
511
|
+
days: z.number({ message: `autocloses: ${field}.days must be a number` }).positive(`autocloses: ${field}.days must be > 0`)
|
|
588
512
|
}).refine((o) => o.days >= min_days, {
|
|
589
513
|
message: `autocloses: ${field} resolves to < ${floor}, which is too short to be a meaningful retention window`
|
|
590
514
|
});
|
|
591
515
|
var AfterSchema = window_schema("after", MIN_AFTER_DAYS, "one minute");
|
|
592
516
|
var KeepSchema = window_schema("keep", MIN_KEEP_DAYS, "one day");
|
|
593
|
-
var IsSchema =
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
517
|
+
var IsSchema = z.union([
|
|
518
|
+
z.string().min(1, "autocloses: is must be a non-empty event name"),
|
|
519
|
+
z.array(
|
|
520
|
+
z.string().min(1, "autocloses: is entries must be non-empty event names")
|
|
597
521
|
).min(1, "autocloses: is must include at least one event name").readonly()
|
|
598
522
|
]);
|
|
599
|
-
var ReachesSchema =
|
|
600
|
-
var OrBlockSchema =
|
|
523
|
+
var ReachesSchema = z.number({ message: "autocloses: reaches must be a number" }).int("autocloses: reaches must be an integer").min(1, "autocloses: reaches must be >= 1");
|
|
524
|
+
var OrBlockSchema = z.object({
|
|
601
525
|
after: AfterSchema.optional(),
|
|
602
526
|
is: IsSchema.optional(),
|
|
603
527
|
reaches: ReachesSchema.optional()
|
|
@@ -607,7 +531,7 @@ var OrBlockSchema = z2.object({
|
|
|
607
531
|
message: "autocloses: `or` block must include at least one of after / is / reaches"
|
|
608
532
|
}
|
|
609
533
|
);
|
|
610
|
-
var AutoclosePolicySchema =
|
|
534
|
+
var AutoclosePolicySchema = z.object({
|
|
611
535
|
after: AfterSchema.optional(),
|
|
612
536
|
is: IsSchema.optional(),
|
|
613
537
|
reaches: ReachesSchema.optional(),
|
|
@@ -663,6 +587,44 @@ function compile_autoclose_policy(options) {
|
|
|
663
587
|
};
|
|
664
588
|
}
|
|
665
589
|
|
|
590
|
+
// src/internal/autoclose-window.ts
|
|
591
|
+
function hour_in_zone(now, timeZone) {
|
|
592
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
593
|
+
timeZone,
|
|
594
|
+
hour: "2-digit",
|
|
595
|
+
hourCycle: "h23"
|
|
596
|
+
}).formatToParts(now);
|
|
597
|
+
return Number(parts.find((p) => p.type === "hour")?.value);
|
|
598
|
+
}
|
|
599
|
+
function hour_in_range(hour, start, end) {
|
|
600
|
+
return start < end ? hour >= start && hour < end : hour >= start || hour < end;
|
|
601
|
+
}
|
|
602
|
+
function is_dst_gap_open(now, timeZone, start) {
|
|
603
|
+
const hour = hour_in_zone(now, timeZone);
|
|
604
|
+
if (hour <= start) return false;
|
|
605
|
+
const prev = hour_in_zone(new Date(now.getTime() - 36e5), timeZone);
|
|
606
|
+
return prev === start - 1 && hour === start + 1;
|
|
607
|
+
}
|
|
608
|
+
function in_autoclose_window(window, now) {
|
|
609
|
+
if (!window) return true;
|
|
610
|
+
const hour = hour_in_zone(now, window.timeZone);
|
|
611
|
+
return hour_in_range(hour, window.start, window.end) || is_dst_gap_open(now, window.timeZone, window.start);
|
|
612
|
+
}
|
|
613
|
+
function next_window_open(window, now) {
|
|
614
|
+
const start_ms = now.getTime();
|
|
615
|
+
for (let h = 0; h <= 48; h++) {
|
|
616
|
+
const candidate = new Date(start_ms + h * 36e5);
|
|
617
|
+
if (hour_in_zone(candidate, window.timeZone) === window.start)
|
|
618
|
+
return candidate;
|
|
619
|
+
const boundary = new Date(
|
|
620
|
+
candidate.getTime() - candidate.getTime() % 36e5
|
|
621
|
+
);
|
|
622
|
+
if (is_dst_gap_open(boundary, window.timeZone, window.start))
|
|
623
|
+
return boundary;
|
|
624
|
+
}
|
|
625
|
+
return new Date(start_ms + 864e5);
|
|
626
|
+
}
|
|
627
|
+
|
|
666
628
|
// src/internal/close-signal.ts
|
|
667
629
|
var CloseSignal = class extends Error {
|
|
668
630
|
/**
|
|
@@ -843,6 +805,123 @@ function classify_registry(registry, states) {
|
|
|
843
805
|
};
|
|
844
806
|
}
|
|
845
807
|
|
|
808
|
+
// src/internal/config.ts
|
|
809
|
+
import { z as z2 } from "zod";
|
|
810
|
+
var BackoffOptionsSchema = z2.object({
|
|
811
|
+
strategy: z2.enum(["fixed", "linear", "exponential"]),
|
|
812
|
+
baseMs: z2.number().min(0),
|
|
813
|
+
maxMs: z2.number().gt(0).optional(),
|
|
814
|
+
jitter: z2.boolean().optional()
|
|
815
|
+
});
|
|
816
|
+
var ReactionOptionsSchema = z2.object({
|
|
817
|
+
blockOnError: z2.boolean(),
|
|
818
|
+
maxRetries: z2.number().int().min(0),
|
|
819
|
+
backoff: BackoffOptionsSchema.optional()
|
|
820
|
+
});
|
|
821
|
+
function resolveReactionConfig(options) {
|
|
822
|
+
return ReactionOptionsSchema.parse(options);
|
|
823
|
+
}
|
|
824
|
+
var ActionOptionsSchema = z2.object({
|
|
825
|
+
maxRetries: z2.number().int().min(0).optional(),
|
|
826
|
+
backoff: BackoffOptionsSchema.optional()
|
|
827
|
+
});
|
|
828
|
+
function resolveActionConfig(options) {
|
|
829
|
+
return ActionOptionsSchema.parse(options);
|
|
830
|
+
}
|
|
831
|
+
var LaneConfigSchema = z2.object({
|
|
832
|
+
name: z2.string().min(1),
|
|
833
|
+
leaseMillis: z2.number().min(0).optional(),
|
|
834
|
+
streamLimit: z2.number().int().min(0).optional(),
|
|
835
|
+
cycleMs: z2.number().min(0).optional()
|
|
836
|
+
});
|
|
837
|
+
function resolveLaneConfig(options) {
|
|
838
|
+
LaneConfigSchema.parse(options);
|
|
839
|
+
return options;
|
|
840
|
+
}
|
|
841
|
+
var DrainOptionsSchema = z2.object({
|
|
842
|
+
streamLimit: z2.number().int().min(0).optional(),
|
|
843
|
+
eventLimit: z2.number().int().min(0).optional(),
|
|
844
|
+
leaseMillis: z2.number().min(0).optional()
|
|
845
|
+
});
|
|
846
|
+
function resolveDrainConfig(options) {
|
|
847
|
+
if (options === void 0) return void 0;
|
|
848
|
+
DrainOptionsSchema.parse(options);
|
|
849
|
+
return options;
|
|
850
|
+
}
|
|
851
|
+
var SettleOptionsSchema = DrainOptionsSchema.extend({
|
|
852
|
+
debounceMs: z2.number().min(0).optional(),
|
|
853
|
+
// `maxPasses` defaults to Infinity (no cap) when omitted; a present value is
|
|
854
|
+
// a non-negative integer — `0` is legal and means "run no passes".
|
|
855
|
+
maxPasses: z2.number().int().min(0).optional()
|
|
856
|
+
}).loose();
|
|
857
|
+
function resolveSettleConfig(options) {
|
|
858
|
+
if (options === void 0) return void 0;
|
|
859
|
+
SettleOptionsSchema.parse(options);
|
|
860
|
+
return options;
|
|
861
|
+
}
|
|
862
|
+
var ActOptionsSchema = z2.object({
|
|
863
|
+
maxSubscribedStreams: z2.number().int().min(1).optional(),
|
|
864
|
+
settleDebounceMs: z2.number().int().min(0).optional()
|
|
865
|
+
}).loose();
|
|
866
|
+
function resolveActConfig(options) {
|
|
867
|
+
if (options === void 0) return void 0;
|
|
868
|
+
ActOptionsSchema.parse(options);
|
|
869
|
+
return options;
|
|
870
|
+
}
|
|
871
|
+
var DEFAULT_AUTOCLOSE_CYCLE_MINUTES = 720;
|
|
872
|
+
var DEFAULT_CLOSE_BATCH_SIZE = 64;
|
|
873
|
+
var DEFAULT_CLOSE_YIELD_MS = 0;
|
|
874
|
+
var DEFAULT_AUTOCLOSE_WINDOW_TZ = "UTC";
|
|
875
|
+
function is_valid_time_zone(tz) {
|
|
876
|
+
try {
|
|
877
|
+
new Intl.DateTimeFormat("en-US", { timeZone: tz });
|
|
878
|
+
return true;
|
|
879
|
+
} catch {
|
|
880
|
+
return false;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
var AutocloseWindowSchema = z2.object({
|
|
884
|
+
start: z2.number().int().min(0).max(23, { message: "autocloseWindow.start must be an hour in [0, 23]" }),
|
|
885
|
+
end: z2.number().int().min(0).max(23, { message: "autocloseWindow.end must be an hour in [0, 23]" }),
|
|
886
|
+
timeZone: z2.string().refine(is_valid_time_zone, {
|
|
887
|
+
message: "autocloseWindow.timeZone must be a valid IANA time zone"
|
|
888
|
+
}).default(DEFAULT_AUTOCLOSE_WINDOW_TZ)
|
|
889
|
+
}).refine((w) => w.start !== w.end, {
|
|
890
|
+
message: "autocloseWindow.start and end must differ \u2014 an empty window disables autoclose"
|
|
891
|
+
});
|
|
892
|
+
var AutocloseOptionsSchema = z2.object({
|
|
893
|
+
autocloseCycleMinutes: z2.number().int().min(1).max(1440).default(DEFAULT_AUTOCLOSE_CYCLE_MINUTES),
|
|
894
|
+
closeBatchSize: z2.number().int().min(1).max(1024).default(DEFAULT_CLOSE_BATCH_SIZE),
|
|
895
|
+
closeYieldMs: z2.number().min(0).max(1e3).default(DEFAULT_CLOSE_YIELD_MS),
|
|
896
|
+
closeOnError: z2.boolean().default(false),
|
|
897
|
+
autocloseWindow: AutocloseWindowSchema.optional()
|
|
898
|
+
});
|
|
899
|
+
function resolveAutocloseConfig(options) {
|
|
900
|
+
return AutocloseOptionsSchema.parse({
|
|
901
|
+
autocloseCycleMinutes: options?.autocloseCycleMinutes,
|
|
902
|
+
closeBatchSize: options?.closeBatchSize,
|
|
903
|
+
closeYieldMs: options?.closeYieldMs,
|
|
904
|
+
closeOnError: options?.closeOnError,
|
|
905
|
+
autocloseWindow: options?.autocloseWindow
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
var DEFAULT_CIRCUIT_FAILURE_THRESHOLD = 5;
|
|
909
|
+
var DEFAULT_CIRCUIT_COOLDOWN_MS = 3e4;
|
|
910
|
+
var CircuitBreakerOptionsSchema = z2.object({
|
|
911
|
+
failureThreshold: z2.number().int().min(1).default(DEFAULT_CIRCUIT_FAILURE_THRESHOLD),
|
|
912
|
+
cooldownMs: z2.number().int().min(100).max(36e5).default(DEFAULT_CIRCUIT_COOLDOWN_MS)
|
|
913
|
+
});
|
|
914
|
+
var resolveCircuitBreakerConfig = (options) => CircuitBreakerOptionsSchema.parse(options ?? {});
|
|
915
|
+
var DEFAULT_FOLD_FLUSH_EVERY = 1e3;
|
|
916
|
+
var DEFAULT_MAX_CACHED_STATES = 1e4;
|
|
917
|
+
var FoldOptionsSchema = z2.object({
|
|
918
|
+
flushEvery: z2.number().int().min(1).default(DEFAULT_FOLD_FLUSH_EVERY),
|
|
919
|
+
maxCachedStates: z2.number().int().min(1).default(DEFAULT_MAX_CACHED_STATES)
|
|
920
|
+
});
|
|
921
|
+
function resolveFoldConfig(options) {
|
|
922
|
+
return FoldOptionsSchema.parse(options);
|
|
923
|
+
}
|
|
924
|
+
|
|
846
925
|
// src/internal/defer-config.ts
|
|
847
926
|
import { z as z3 } from "zod";
|
|
848
927
|
var DeferDurationSchema = z3.object({
|
|
@@ -1050,11 +1129,14 @@ function reaction_on(event, events, builder) {
|
|
|
1050
1129
|
const reaction = {
|
|
1051
1130
|
handler: schedule ? make_deferred(handler, schedule) : handler,
|
|
1052
1131
|
resolver: _this_,
|
|
1053
|
-
|
|
1132
|
+
// #1269: validate the whole bag at the declaration site so a bad
|
|
1133
|
+
// `maxRetries`/`backoff`/`blockOnError` throws ZodError at build,
|
|
1134
|
+
// not a NaN gate on the first retry.
|
|
1135
|
+
options: resolveReactionConfig({
|
|
1054
1136
|
blockOnError: options?.blockOnError ?? true,
|
|
1055
1137
|
maxRetries: options?.maxRetries ?? 3,
|
|
1056
1138
|
backoff: options?.backoff
|
|
1057
|
-
}
|
|
1139
|
+
})
|
|
1058
1140
|
};
|
|
1059
1141
|
events[event].reactions.set(handler.name, reaction);
|
|
1060
1142
|
return Object.assign(builder, {
|
|
@@ -1073,14 +1155,6 @@ function reaction_on(event, events, builder) {
|
|
|
1073
1155
|
}
|
|
1074
1156
|
|
|
1075
1157
|
// src/internal/circuit-breaker.ts
|
|
1076
|
-
import { z as z4 } from "zod";
|
|
1077
|
-
var DEFAULT_CIRCUIT_FAILURE_THRESHOLD = 5;
|
|
1078
|
-
var DEFAULT_CIRCUIT_COOLDOWN_MS = 3e4;
|
|
1079
|
-
var CircuitBreakerOptionsSchema = z4.object({
|
|
1080
|
-
failureThreshold: z4.number().int().min(1).default(DEFAULT_CIRCUIT_FAILURE_THRESHOLD),
|
|
1081
|
-
cooldownMs: z4.number().int().min(100).max(36e5).default(DEFAULT_CIRCUIT_COOLDOWN_MS)
|
|
1082
|
-
});
|
|
1083
|
-
var resolveCircuitBreakerConfig = (options) => CircuitBreakerOptionsSchema.parse(options ?? {});
|
|
1084
1158
|
var CircuitBreaker = class {
|
|
1085
1159
|
_failures = 0;
|
|
1086
1160
|
_opened_at;
|
|
@@ -1748,6 +1822,10 @@ function compute_backoff_delay(retry, opts) {
|
|
|
1748
1822
|
delay = opts.baseMs * 2 ** r;
|
|
1749
1823
|
if (opts.maxMs !== void 0) delay = Math.min(delay, opts.maxMs);
|
|
1750
1824
|
break;
|
|
1825
|
+
default: {
|
|
1826
|
+
const _never = opts.strategy;
|
|
1827
|
+
throw new Error(`unknown backoff strategy: ${String(_never)}`);
|
|
1828
|
+
}
|
|
1751
1829
|
}
|
|
1752
1830
|
if (opts.jitter) delay = delay * (0.5 + Math.random());
|
|
1753
1831
|
return Math.max(0, Math.floor(delay));
|
|
@@ -1958,7 +2036,14 @@ async function load(me, target, callback, patch_fn = bare_patch) {
|
|
|
1958
2036
|
{
|
|
1959
2037
|
stream,
|
|
1960
2038
|
stream_exact: true,
|
|
1961
|
-
|
|
2039
|
+
// The snapshot resume floor is a current-state optimization: it only
|
|
2040
|
+
// holds when the load has no window of its own. `time_travel` already
|
|
2041
|
+
// captures that (any `asOf` bound set), so request `with_snaps` only for
|
|
2042
|
+
// a non-time-travel cold load — a bounded load full-scans real events
|
|
2043
|
+
// under its `asOf` filter. This is the single floor-eligibility decision
|
|
2044
|
+
// for the whole system; the stores apply the floor whenever asked and
|
|
2045
|
+
// never re-derive it (RFC 1274). The warm path resumes from `after`.
|
|
2046
|
+
...cached ? { after: cached.event_id } : { ...time_travel ? {} : { with_snaps: true }, ...asOf }
|
|
1962
2047
|
}
|
|
1963
2048
|
);
|
|
1964
2049
|
const head_is_tombstone = event?.name === TOMBSTONE_EVENT;
|
|
@@ -2497,16 +2582,6 @@ var DrainController = class {
|
|
|
2497
2582
|
};
|
|
2498
2583
|
|
|
2499
2584
|
// src/internal/projection-fold.ts
|
|
2500
|
-
import { z as z5 } from "zod";
|
|
2501
|
-
var DEFAULT_FOLD_FLUSH_EVERY = 1e3;
|
|
2502
|
-
var DEFAULT_MAX_CACHED_STATES = 1e4;
|
|
2503
|
-
var FoldOptionsSchema = z5.object({
|
|
2504
|
-
flushEvery: z5.number().int().min(1).default(DEFAULT_FOLD_FLUSH_EVERY),
|
|
2505
|
-
maxCachedStates: z5.number().int().min(1).default(DEFAULT_MAX_CACHED_STATES)
|
|
2506
|
-
});
|
|
2507
|
-
function resolveFoldConfig(options) {
|
|
2508
|
-
return FoldOptionsSchema.parse(options);
|
|
2509
|
-
}
|
|
2510
2585
|
function make_fold_handler(me, flush, config2, patch_fn = bare_patch) {
|
|
2511
2586
|
const cache2 = /* @__PURE__ */ new Map();
|
|
2512
2587
|
const row = ({ dirty: _, ...row2 }) => row2;
|
|
@@ -3533,6 +3608,7 @@ var Act = class {
|
|
|
3533
3608
|
* @see {@link start_correlations} for automatic correlation
|
|
3534
3609
|
*/
|
|
3535
3610
|
async drain(options = {}) {
|
|
3611
|
+
resolveDrainConfig(options);
|
|
3536
3612
|
if (!this._drain)
|
|
3537
3613
|
return { fetched: [], leased: [], acked: [], blocked: [] };
|
|
3538
3614
|
return this._scoped(() => this._drain_all(options));
|
|
@@ -4095,6 +4171,7 @@ var Act = class {
|
|
|
4095
4171
|
* @see {@link correlate} for manual correlation
|
|
4096
4172
|
*/
|
|
4097
4173
|
settle(options = {}) {
|
|
4174
|
+
resolveSettleConfig(options);
|
|
4098
4175
|
if (!this._drain) return;
|
|
4099
4176
|
this._settle.schedule(options);
|
|
4100
4177
|
}
|
|
@@ -4215,11 +4292,12 @@ function act() {
|
|
|
4215
4292
|
},
|
|
4216
4293
|
withActor: () => builder,
|
|
4217
4294
|
withLane: (config2) => {
|
|
4218
|
-
register_lane(config2, lanes);
|
|
4295
|
+
register_lane(resolveLaneConfig(config2), lanes);
|
|
4219
4296
|
return builder;
|
|
4220
4297
|
},
|
|
4221
4298
|
on: (event) => reaction_on(event, registry.events, builder),
|
|
4222
4299
|
build: (options) => {
|
|
4300
|
+
resolveActConfig(options);
|
|
4223
4301
|
const patch_fn = options?.validateFoldedState === true ? validating_patch : bare_patch;
|
|
4224
4302
|
if (!_built) {
|
|
4225
4303
|
for (const proj of pending_projections) {
|
|
@@ -4536,6 +4614,7 @@ function action_builder(state2) {
|
|
|
4536
4614
|
throw new Error(`Duplicate action "${action2}"`);
|
|
4537
4615
|
internal.actions[action2] = schema;
|
|
4538
4616
|
if (options) {
|
|
4617
|
+
resolveActionConfig(options);
|
|
4539
4618
|
internal.options ??= {};
|
|
4540
4619
|
internal.options[action2] = options;
|
|
4541
4620
|
}
|