@rotorsoft/act 0.6.0 → 0.6.1
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 +2 -12
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/adapters/InMemoryStore.d.ts +2 -1
- package/dist/@types/adapters/InMemoryStore.d.ts.map +1 -1
- package/dist/@types/ports.d.ts +13 -1
- package/dist/@types/ports.d.ts.map +1 -1
- package/dist/@types/types/ports.d.ts +3 -2
- package/dist/@types/types/ports.d.ts.map +1 -1
- package/dist/@types/types/reaction.d.ts +5 -2
- package/dist/@types/types/reaction.d.ts.map +1 -1
- package/dist/index.cjs +82 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +81 -63
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -367,11 +367,12 @@ var InMemoryStore = class {
|
|
|
367
367
|
/**
|
|
368
368
|
* Polls the store for unblocked streams needing processing, ordered by lease watermark ascending.
|
|
369
369
|
* @param limit - Maximum number of streams to poll.
|
|
370
|
+
* @param descending - Whether to poll streams in descending order (aka poll the most advanced first).
|
|
370
371
|
* @returns The polled streams.
|
|
371
372
|
*/
|
|
372
|
-
async poll(limit) {
|
|
373
|
+
async poll(limit, descending = false) {
|
|
373
374
|
await sleep();
|
|
374
|
-
return [...this._streams.values()].filter((s) => s.is_avaliable).sort((a, b) => a.at - b.at).slice(0, limit).map(({ stream, source, at }) => ({ stream, source, at }));
|
|
375
|
+
return [...this._streams.values()].filter((s) => s.is_avaliable).sort((a, b) => descending ? b.at - a.at : a.at - b.at).slice(0, limit).map(({ stream, source, at }) => ({ stream, source, at }));
|
|
375
376
|
}
|
|
376
377
|
/**
|
|
377
378
|
* Lease streams for processing (e.g., for distributed consumers).
|
|
@@ -455,6 +456,62 @@ var SNAP_EVENT = "__snapshot__";
|
|
|
455
456
|
var store = port(function store2(adapter) {
|
|
456
457
|
return adapter || new InMemoryStore();
|
|
457
458
|
});
|
|
459
|
+
function build_tracer(logLevel2) {
|
|
460
|
+
if (logLevel2 === "trace") {
|
|
461
|
+
return {
|
|
462
|
+
fetched: (fetched) => {
|
|
463
|
+
const data = Object.fromEntries(
|
|
464
|
+
fetched.map(({ stream, source, events }) => {
|
|
465
|
+
const key = source ? `${stream}<-${source}` : stream;
|
|
466
|
+
const value = Object.fromEntries(
|
|
467
|
+
events.map(({ id, stream: stream2, name }) => [id, { [stream2]: name }])
|
|
468
|
+
);
|
|
469
|
+
return [key, value];
|
|
470
|
+
})
|
|
471
|
+
);
|
|
472
|
+
logger.trace(data, "\u26A1\uFE0F fetch");
|
|
473
|
+
},
|
|
474
|
+
correlated: (leases) => {
|
|
475
|
+
const data = leases.map(({ stream }) => stream).join(" ");
|
|
476
|
+
logger.trace(`\u26A1\uFE0F correlate ${data}`);
|
|
477
|
+
},
|
|
478
|
+
leased: (leases) => {
|
|
479
|
+
const data = Object.fromEntries(
|
|
480
|
+
leases.map(({ stream, at, retry }) => [stream, { at, retry }])
|
|
481
|
+
);
|
|
482
|
+
logger.trace(data, "\u26A1\uFE0F lease");
|
|
483
|
+
},
|
|
484
|
+
acked: (leases) => {
|
|
485
|
+
const data = Object.fromEntries(
|
|
486
|
+
leases.map(({ stream, at, retry }) => [stream, { at, retry }])
|
|
487
|
+
);
|
|
488
|
+
logger.trace(data, "\u26A1\uFE0F ack");
|
|
489
|
+
},
|
|
490
|
+
blocked: (leases) => {
|
|
491
|
+
const data = Object.fromEntries(
|
|
492
|
+
leases.map(({ stream, at, retry, error }) => [
|
|
493
|
+
stream,
|
|
494
|
+
{ at, retry, error }
|
|
495
|
+
])
|
|
496
|
+
);
|
|
497
|
+
logger.trace(data, "\u26A1\uFE0F block");
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
} else {
|
|
501
|
+
return {
|
|
502
|
+
fetched: () => {
|
|
503
|
+
},
|
|
504
|
+
correlated: () => {
|
|
505
|
+
},
|
|
506
|
+
leased: () => {
|
|
507
|
+
},
|
|
508
|
+
acked: () => {
|
|
509
|
+
},
|
|
510
|
+
blocked: () => {
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
}
|
|
458
515
|
|
|
459
516
|
// src/signals.ts
|
|
460
517
|
process.once("SIGINT", async (arg) => {
|
|
@@ -593,40 +650,7 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
593
650
|
}
|
|
594
651
|
|
|
595
652
|
// src/act.ts
|
|
596
|
-
|
|
597
|
-
const data = Object.fromEntries(
|
|
598
|
-
fetch.map(({ stream, source, events }) => {
|
|
599
|
-
const key = source ? `${stream}<-${source}` : stream;
|
|
600
|
-
const value = Object.fromEntries(
|
|
601
|
-
events.map(({ id, stream: stream2, name }) => [id, { [stream2]: name }])
|
|
602
|
-
);
|
|
603
|
-
return [key, value];
|
|
604
|
-
})
|
|
605
|
-
);
|
|
606
|
-
logger.trace(data, "\u26A1\uFE0F fetch");
|
|
607
|
-
}
|
|
608
|
-
function traceCorrelated(leases) {
|
|
609
|
-
const data = leases.map(({ stream }) => stream).join(" ");
|
|
610
|
-
logger.trace(`\u26A1\uFE0F correlate ${data}`);
|
|
611
|
-
}
|
|
612
|
-
function traceLeased(leases) {
|
|
613
|
-
const data = Object.fromEntries(
|
|
614
|
-
leases.map(({ stream, at, retry }) => [stream, { at, retry }])
|
|
615
|
-
);
|
|
616
|
-
logger.trace(data, "\u26A1\uFE0F lease");
|
|
617
|
-
}
|
|
618
|
-
function traceAcked(leases) {
|
|
619
|
-
const data = Object.fromEntries(
|
|
620
|
-
leases.map(({ stream, at, retry }) => [stream, { at, retry }])
|
|
621
|
-
);
|
|
622
|
-
logger.trace(data, "\u26A1\uFE0F ack");
|
|
623
|
-
}
|
|
624
|
-
function traceBlocked(leases) {
|
|
625
|
-
const data = Object.fromEntries(
|
|
626
|
-
leases.map(({ stream, at, retry, error }) => [stream, { at, retry, error }])
|
|
627
|
-
);
|
|
628
|
-
logger.trace(data, "\u26A1\uFE0F block");
|
|
629
|
-
}
|
|
653
|
+
var tracer = build_tracer(config().logLevel);
|
|
630
654
|
var Act = class {
|
|
631
655
|
/**
|
|
632
656
|
* Create a new Act orchestrator.
|
|
@@ -770,24 +794,6 @@ var Act = class {
|
|
|
770
794
|
}
|
|
771
795
|
return { lease, at };
|
|
772
796
|
}
|
|
773
|
-
/**
|
|
774
|
-
* Fetches new events from store according to the fetch options.
|
|
775
|
-
* @param options - Fetch options.
|
|
776
|
-
* @returns Fetched streams with next events to process.
|
|
777
|
-
*/
|
|
778
|
-
async fetch({ streamLimit = 10, eventLimit = 10 }) {
|
|
779
|
-
const polled = await store().poll(streamLimit);
|
|
780
|
-
return Promise.all(
|
|
781
|
-
polled.map(async ({ stream, source, at }) => {
|
|
782
|
-
const events = await this.query_array({
|
|
783
|
-
stream: source,
|
|
784
|
-
after: at,
|
|
785
|
-
limit: eventLimit
|
|
786
|
-
});
|
|
787
|
-
return { stream, source, events };
|
|
788
|
-
})
|
|
789
|
-
);
|
|
790
|
-
}
|
|
791
797
|
/**
|
|
792
798
|
* Drains and processes events from the store, triggering reactions and updating state.
|
|
793
799
|
*
|
|
@@ -801,14 +807,25 @@ var Act = class {
|
|
|
801
807
|
async drain({
|
|
802
808
|
streamLimit = 10,
|
|
803
809
|
eventLimit = 10,
|
|
804
|
-
leaseMillis = 1e4
|
|
810
|
+
leaseMillis = 1e4,
|
|
811
|
+
descending = false
|
|
805
812
|
} = {}) {
|
|
806
813
|
if (!this._drain_locked) {
|
|
807
814
|
try {
|
|
808
815
|
this._drain_locked = true;
|
|
809
|
-
const
|
|
810
|
-
|
|
811
|
-
|
|
816
|
+
const polled = await store().poll(streamLimit, descending);
|
|
817
|
+
const fetched = await Promise.all(
|
|
818
|
+
polled.map(async ({ stream, source, at }) => {
|
|
819
|
+
const events = await this.query_array({
|
|
820
|
+
stream: source,
|
|
821
|
+
after: at,
|
|
822
|
+
limit: eventLimit
|
|
823
|
+
});
|
|
824
|
+
return { stream, source, events };
|
|
825
|
+
})
|
|
826
|
+
);
|
|
827
|
+
fetched.length && tracer.fetched(fetched);
|
|
828
|
+
const [last_at, count] = fetched.reduce(
|
|
812
829
|
([last_at2, count2], { events }) => [
|
|
813
830
|
Math.max(last_at2, events.at(-1)?.id || 0),
|
|
814
831
|
count2 + events.length
|
|
@@ -817,7 +834,7 @@ var Act = class {
|
|
|
817
834
|
);
|
|
818
835
|
if (count > 0) {
|
|
819
836
|
const leases = /* @__PURE__ */ new Map();
|
|
820
|
-
|
|
837
|
+
fetched.forEach(({ stream, events }) => {
|
|
821
838
|
const payloads = events.flatMap((event) => {
|
|
822
839
|
const register = this.registry.events[event.name];
|
|
823
840
|
if (!register) return [];
|
|
@@ -847,7 +864,7 @@ var Act = class {
|
|
|
847
864
|
leaseMillis
|
|
848
865
|
);
|
|
849
866
|
if (leased.length) {
|
|
850
|
-
|
|
867
|
+
tracer.leased(leased);
|
|
851
868
|
const handled = await Promise.all(
|
|
852
869
|
leased.map(
|
|
853
870
|
(lease) => this.handle(lease, leases.get(lease.stream).payloads)
|
|
@@ -857,14 +874,14 @@ var Act = class {
|
|
|
857
874
|
handled.filter(({ error }) => !error).map(({ at, lease }) => ({ ...lease, at }))
|
|
858
875
|
);
|
|
859
876
|
if (acked.length) {
|
|
860
|
-
|
|
877
|
+
tracer.acked(acked);
|
|
861
878
|
this.emit("acked", acked);
|
|
862
879
|
}
|
|
863
880
|
const blocked = await store().block(
|
|
864
881
|
handled.filter(({ block }) => block).map(({ lease, error }) => ({ ...lease, error }))
|
|
865
882
|
);
|
|
866
883
|
if (blocked.length) {
|
|
867
|
-
|
|
884
|
+
tracer.blocked(blocked);
|
|
868
885
|
this.emit("blocked", blocked);
|
|
869
886
|
}
|
|
870
887
|
return { leased, acked, blocked };
|
|
@@ -908,7 +925,7 @@ var Act = class {
|
|
|
908
925
|
payloads
|
|
909
926
|
}));
|
|
910
927
|
const leased = await store().lease(leases, 0);
|
|
911
|
-
leased.length &&
|
|
928
|
+
leased.length && tracer.correlated(leased);
|
|
912
929
|
return { leased, last_id };
|
|
913
930
|
}
|
|
914
931
|
return { leased: [], last_id };
|
|
@@ -1108,6 +1125,7 @@ export {
|
|
|
1108
1125
|
ValidationError,
|
|
1109
1126
|
ZodEmpty,
|
|
1110
1127
|
act,
|
|
1128
|
+
build_tracer,
|
|
1111
1129
|
config,
|
|
1112
1130
|
dispose,
|
|
1113
1131
|
disposeAndExit,
|