@rotorsoft/act 0.24.1 → 0.25.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/README.md +23 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/adapters/ConsoleLogger.d.ts +39 -0
- package/dist/@types/adapters/ConsoleLogger.d.ts.map +1 -0
- package/dist/@types/adapters/InMemoryStore.d.ts.map +1 -1
- package/dist/@types/adapters/index.d.ts +1 -0
- package/dist/@types/adapters/index.d.ts.map +1 -1
- package/dist/@types/event-sourcing.d.ts.map +1 -1
- package/dist/@types/ports.d.ts +118 -146
- package/dist/@types/ports.d.ts.map +1 -1
- package/dist/@types/types/action.d.ts +2 -1
- package/dist/@types/types/action.d.ts.map +1 -1
- package/dist/@types/types/ports.d.ts +73 -45
- package/dist/@types/types/ports.d.ts.map +1 -1
- package/dist/@types/types/schemas.d.ts +1 -0
- package/dist/@types/types/schemas.d.ts.map +1 -1
- package/dist/index.cjs +147 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +145 -41
- package/dist/index.js.map +1 -1
- package/package.json +1 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,104 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
1
|
+
// src/adapters/ConsoleLogger.ts
|
|
2
|
+
var LEVEL_VALUES = {
|
|
3
|
+
fatal: 60,
|
|
4
|
+
error: 50,
|
|
5
|
+
warn: 40,
|
|
6
|
+
info: 30,
|
|
7
|
+
debug: 20,
|
|
8
|
+
trace: 10
|
|
9
|
+
};
|
|
10
|
+
var LEVEL_COLORS = {
|
|
11
|
+
fatal: "\x1B[41m\x1B[37m",
|
|
12
|
+
// white on red bg
|
|
13
|
+
error: "\x1B[31m",
|
|
14
|
+
// red
|
|
15
|
+
warn: "\x1B[33m",
|
|
16
|
+
// yellow
|
|
17
|
+
info: "\x1B[32m",
|
|
18
|
+
// green
|
|
19
|
+
debug: "\x1B[36m",
|
|
20
|
+
// cyan
|
|
21
|
+
trace: "\x1B[90m"
|
|
22
|
+
// gray
|
|
23
|
+
};
|
|
24
|
+
var RESET = "\x1B[0m";
|
|
25
|
+
var noop = () => {
|
|
26
|
+
};
|
|
27
|
+
var ConsoleLogger = class _ConsoleLogger {
|
|
28
|
+
level;
|
|
29
|
+
_pretty;
|
|
30
|
+
fatal;
|
|
31
|
+
error;
|
|
32
|
+
warn;
|
|
33
|
+
info;
|
|
34
|
+
debug;
|
|
35
|
+
trace;
|
|
36
|
+
constructor(options = {}) {
|
|
37
|
+
const {
|
|
38
|
+
level = "info",
|
|
39
|
+
pretty = process.env.NODE_ENV !== "production",
|
|
40
|
+
bindings
|
|
41
|
+
} = options;
|
|
42
|
+
this._pretty = pretty;
|
|
43
|
+
this.level = level;
|
|
44
|
+
const threshold = LEVEL_VALUES[level] ?? 30;
|
|
45
|
+
const write = pretty ? this._prettyWrite.bind(this, bindings) : this._jsonWrite.bind(this, bindings);
|
|
46
|
+
this.fatal = write.bind(this, "fatal", 60);
|
|
47
|
+
this.error = threshold <= 50 ? write.bind(this, "error", 50) : noop;
|
|
48
|
+
this.warn = threshold <= 40 ? write.bind(this, "warn", 40) : noop;
|
|
49
|
+
this.info = threshold <= 30 ? write.bind(this, "info", 30) : noop;
|
|
50
|
+
this.debug = threshold <= 20 ? write.bind(this, "debug", 20) : noop;
|
|
51
|
+
this.trace = threshold <= 10 ? write.bind(this, "trace", 10) : noop;
|
|
52
|
+
}
|
|
53
|
+
async dispose() {
|
|
54
|
+
}
|
|
55
|
+
child(bindings) {
|
|
56
|
+
return new _ConsoleLogger({
|
|
57
|
+
level: this.level,
|
|
58
|
+
pretty: this._pretty,
|
|
59
|
+
bindings
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
_jsonWrite(bindings, level, _num, objOrMsg, msg) {
|
|
63
|
+
let obj;
|
|
64
|
+
let message;
|
|
65
|
+
if (typeof objOrMsg === "string") {
|
|
66
|
+
message = objOrMsg;
|
|
67
|
+
obj = {};
|
|
68
|
+
} else if (objOrMsg !== null && typeof objOrMsg === "object") {
|
|
69
|
+
message = msg;
|
|
70
|
+
obj = Object.fromEntries(Object.entries(objOrMsg));
|
|
71
|
+
} else {
|
|
72
|
+
message = msg;
|
|
73
|
+
obj = { value: objOrMsg };
|
|
74
|
+
}
|
|
75
|
+
const entry = Object.assign({ level, time: Date.now() }, bindings, obj);
|
|
76
|
+
if (message) entry.msg = message;
|
|
77
|
+
process.stdout.write(JSON.stringify(entry) + "\n");
|
|
78
|
+
}
|
|
79
|
+
_prettyWrite(bindings, level, _num, objOrMsg, msg) {
|
|
80
|
+
const color = LEVEL_COLORS[level];
|
|
81
|
+
const tag = `${color}${level.toUpperCase().padEnd(5)}${RESET}`;
|
|
82
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
83
|
+
let message;
|
|
84
|
+
let data;
|
|
85
|
+
if (typeof objOrMsg === "string") {
|
|
86
|
+
message = objOrMsg;
|
|
87
|
+
} else {
|
|
88
|
+
message = msg ?? "";
|
|
89
|
+
if (objOrMsg !== void 0 && objOrMsg !== null) {
|
|
90
|
+
try {
|
|
91
|
+
data = JSON.stringify(objOrMsg);
|
|
92
|
+
} catch {
|
|
93
|
+
data = "[unserializable]";
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const bindStr = bindings && Object.keys(bindings).length ? ` ${JSON.stringify(bindings)}` : "";
|
|
98
|
+
const parts = [ts, tag, message, data, bindStr].filter(Boolean);
|
|
99
|
+
process.stdout.write(parts.join(" ") + "\n");
|
|
100
|
+
}
|
|
101
|
+
};
|
|
3
102
|
|
|
4
103
|
// src/adapters/InMemoryCache.ts
|
|
5
104
|
var InMemoryCache = class {
|
|
@@ -126,7 +225,8 @@ var QuerySchema = z.object({
|
|
|
126
225
|
created_after: z.date().optional(),
|
|
127
226
|
backward: z.boolean().optional(),
|
|
128
227
|
correlation: z.string().optional(),
|
|
129
|
-
with_snaps: z.boolean().optional()
|
|
228
|
+
with_snaps: z.boolean().optional(),
|
|
229
|
+
stream_exact: z.boolean().optional()
|
|
130
230
|
}).readonly();
|
|
131
231
|
|
|
132
232
|
// src/types/index.ts
|
|
@@ -307,8 +407,11 @@ var InMemoryStore = class {
|
|
|
307
407
|
this._streams = /* @__PURE__ */ new Map();
|
|
308
408
|
}
|
|
309
409
|
in_query(query, e) {
|
|
310
|
-
if (query.stream
|
|
311
|
-
|
|
410
|
+
if (query.stream) {
|
|
411
|
+
if (query.stream_exact) {
|
|
412
|
+
if (e.stream !== query.stream) return false;
|
|
413
|
+
} else if (!RegExp(`^${query.stream}$`).test(e.stream)) return false;
|
|
414
|
+
}
|
|
312
415
|
if (query.names && !query.names.includes(e.name)) return false;
|
|
313
416
|
if (query.correlation && e.meta?.correlation !== query.correlation)
|
|
314
417
|
return false;
|
|
@@ -467,28 +570,30 @@ var InMemoryStore = class {
|
|
|
467
570
|
|
|
468
571
|
// src/ports.ts
|
|
469
572
|
var ExitCodes = ["ERROR", "EXIT"];
|
|
470
|
-
var logger = pino({
|
|
471
|
-
transport: config().env !== "production" ? {
|
|
472
|
-
target: "pino-pretty",
|
|
473
|
-
options: {
|
|
474
|
-
ignore: "pid,hostname",
|
|
475
|
-
singleLine: config().logSingleLine,
|
|
476
|
-
colorize: true
|
|
477
|
-
}
|
|
478
|
-
} : void 0,
|
|
479
|
-
level: config().logLevel
|
|
480
|
-
});
|
|
481
573
|
var adapters = /* @__PURE__ */ new Map();
|
|
482
574
|
function port(injector) {
|
|
483
575
|
return function(adapter) {
|
|
484
576
|
if (!adapters.has(injector.name)) {
|
|
485
577
|
const injected = injector(adapter);
|
|
486
578
|
adapters.set(injector.name, injected);
|
|
487
|
-
|
|
579
|
+
console.log(`[act] + ${injector.name}:${injected.constructor.name}`);
|
|
488
580
|
}
|
|
489
581
|
return adapters.get(injector.name);
|
|
490
582
|
};
|
|
491
583
|
}
|
|
584
|
+
var log = port(function log2(adapter) {
|
|
585
|
+
const cfg = config();
|
|
586
|
+
return adapter || new ConsoleLogger({
|
|
587
|
+
level: cfg.logLevel,
|
|
588
|
+
pretty: cfg.env !== "production"
|
|
589
|
+
});
|
|
590
|
+
});
|
|
591
|
+
var store = port(function store2(adapter) {
|
|
592
|
+
return adapter || new InMemoryStore();
|
|
593
|
+
});
|
|
594
|
+
var cache = port(function cache2(adapter) {
|
|
595
|
+
return adapter || new InMemoryCache();
|
|
596
|
+
});
|
|
492
597
|
var disposers = [];
|
|
493
598
|
async function disposeAndExit(code = "EXIT") {
|
|
494
599
|
if (code === "ERROR" && config().env === "production") return;
|
|
@@ -496,7 +601,7 @@ async function disposeAndExit(code = "EXIT") {
|
|
|
496
601
|
await Promise.all(
|
|
497
602
|
[...adapters.values()].reverse().map(async (adapter) => {
|
|
498
603
|
await adapter.dispose();
|
|
499
|
-
|
|
604
|
+
console.log(`[act] - ${adapter.constructor.name}`);
|
|
500
605
|
})
|
|
501
606
|
);
|
|
502
607
|
adapters.clear();
|
|
@@ -507,14 +612,9 @@ function dispose(disposer) {
|
|
|
507
612
|
return disposeAndExit;
|
|
508
613
|
}
|
|
509
614
|
var SNAP_EVENT = "__snapshot__";
|
|
510
|
-
var store = port(function store2(adapter) {
|
|
511
|
-
return adapter || new InMemoryStore();
|
|
512
|
-
});
|
|
513
|
-
var cache = port(function cache2(adapter) {
|
|
514
|
-
return adapter || new InMemoryCache();
|
|
515
|
-
});
|
|
516
615
|
function build_tracer(logLevel2) {
|
|
517
616
|
if (logLevel2 === "trace") {
|
|
617
|
+
const logger4 = log();
|
|
518
618
|
return {
|
|
519
619
|
fetched: (fetched) => {
|
|
520
620
|
const data = Object.fromEntries(
|
|
@@ -526,23 +626,23 @@ function build_tracer(logLevel2) {
|
|
|
526
626
|
return [key, value];
|
|
527
627
|
})
|
|
528
628
|
);
|
|
529
|
-
|
|
629
|
+
logger4.trace(data, ">> fetch");
|
|
530
630
|
},
|
|
531
631
|
correlated: (streams) => {
|
|
532
632
|
const data = streams.map(({ stream }) => stream).join(" ");
|
|
533
|
-
|
|
633
|
+
logger4.trace(`>> correlate ${data}`);
|
|
534
634
|
},
|
|
535
635
|
leased: (leases) => {
|
|
536
636
|
const data = Object.fromEntries(
|
|
537
637
|
leases.map(({ stream, at, retry }) => [stream, { at, retry }])
|
|
538
638
|
);
|
|
539
|
-
|
|
639
|
+
logger4.trace(data, ">> lease");
|
|
540
640
|
},
|
|
541
641
|
acked: (leases) => {
|
|
542
642
|
const data = Object.fromEntries(
|
|
543
643
|
leases.map(({ stream, at, retry }) => [stream, { at, retry }])
|
|
544
644
|
);
|
|
545
|
-
|
|
645
|
+
logger4.trace(data, ">> ack");
|
|
546
646
|
},
|
|
547
647
|
blocked: (leases) => {
|
|
548
648
|
const data = Object.fromEntries(
|
|
@@ -551,7 +651,7 @@ function build_tracer(logLevel2) {
|
|
|
551
651
|
{ at, retry, error }
|
|
552
652
|
])
|
|
553
653
|
);
|
|
554
|
-
|
|
654
|
+
logger4.trace(data, ">> block");
|
|
555
655
|
}
|
|
556
656
|
};
|
|
557
657
|
} else {
|
|
@@ -571,6 +671,7 @@ function build_tracer(logLevel2) {
|
|
|
571
671
|
}
|
|
572
672
|
|
|
573
673
|
// src/signals.ts
|
|
674
|
+
var logger = log();
|
|
574
675
|
process.once("SIGINT", async (arg) => {
|
|
575
676
|
logger.info(arg, "SIGINT");
|
|
576
677
|
await disposeAndExit("EXIT");
|
|
@@ -595,6 +696,7 @@ import EventEmitter from "events";
|
|
|
595
696
|
// src/event-sourcing.ts
|
|
596
697
|
import { patch } from "@rotorsoft/act-patch";
|
|
597
698
|
import { randomUUID } from "crypto";
|
|
699
|
+
var logger2 = log();
|
|
598
700
|
async function snap(snapshot) {
|
|
599
701
|
try {
|
|
600
702
|
const { id, stream, name, meta, version } = snapshot.event;
|
|
@@ -608,9 +710,9 @@ async function snap(snapshot) {
|
|
|
608
710
|
version
|
|
609
711
|
// IMPORTANT! - state events are committed right after the snapshot event
|
|
610
712
|
);
|
|
611
|
-
|
|
713
|
+
logger2.trace(snapped, "\u{1F7E0} snap");
|
|
612
714
|
} catch (error) {
|
|
613
|
-
|
|
715
|
+
logger2.error(error);
|
|
614
716
|
}
|
|
615
717
|
}
|
|
616
718
|
async function load(me, stream, callback) {
|
|
@@ -632,9 +734,9 @@ async function load(me, stream, callback) {
|
|
|
632
734
|
}
|
|
633
735
|
callback && callback({ event, state: state2, patches, snaps });
|
|
634
736
|
},
|
|
635
|
-
{ stream, with_snaps: !cached, after: cached?.event_id }
|
|
737
|
+
{ stream, with_snaps: !cached, after: cached?.event_id, stream_exact: true }
|
|
636
738
|
);
|
|
637
|
-
|
|
739
|
+
logger2.trace(
|
|
638
740
|
state2,
|
|
639
741
|
`\u{1F7E2} load ${stream}${cached && count === 0 ? " (cached)" : ""}`
|
|
640
742
|
);
|
|
@@ -646,7 +748,7 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
646
748
|
payload = skipValidation ? payload : validate(action2, payload, me.actions[action2]);
|
|
647
749
|
const snapshot = await load(me, stream);
|
|
648
750
|
const expected = expectedVersion || snapshot.event?.version;
|
|
649
|
-
|
|
751
|
+
logger2.trace(
|
|
650
752
|
payload,
|
|
651
753
|
`\u{1F535} ${stream}.${action2}${typeof expected === "number" ? `.${expected}` : ""}`
|
|
652
754
|
);
|
|
@@ -689,7 +791,7 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
689
791
|
} : void 0
|
|
690
792
|
}
|
|
691
793
|
};
|
|
692
|
-
|
|
794
|
+
logger2.trace(
|
|
693
795
|
emitted.map((e) => e.data),
|
|
694
796
|
`\u{1F534} commit ${stream}.${emitted.map((e) => e.name).join(", ")}`
|
|
695
797
|
);
|
|
@@ -729,6 +831,7 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
729
831
|
}
|
|
730
832
|
|
|
731
833
|
// src/act.ts
|
|
834
|
+
var logger3 = log();
|
|
732
835
|
var tracer = build_tracer(config().logLevel);
|
|
733
836
|
var Act = class {
|
|
734
837
|
constructor(registry, _states = /* @__PURE__ */ new Map()) {
|
|
@@ -1009,7 +1112,7 @@ var Act = class {
|
|
|
1009
1112
|
if (payloads.length === 0) return { lease, handled: 0, at: lease.at };
|
|
1010
1113
|
const stream = lease.stream;
|
|
1011
1114
|
let at = payloads.at(0).event.id, handled = 0;
|
|
1012
|
-
lease.retry > 0 &&
|
|
1115
|
+
lease.retry > 0 && logger3.warn(`Retrying ${stream}@${at} (${lease.retry}).`);
|
|
1013
1116
|
for (const payload of payloads) {
|
|
1014
1117
|
const { event, handler, options } = payload;
|
|
1015
1118
|
try {
|
|
@@ -1017,9 +1120,9 @@ var Act = class {
|
|
|
1017
1120
|
at = event.id;
|
|
1018
1121
|
handled++;
|
|
1019
1122
|
} catch (error) {
|
|
1020
|
-
|
|
1123
|
+
logger3.error(error);
|
|
1021
1124
|
const block = lease.retry >= options.maxRetries && options.blockOnError;
|
|
1022
|
-
block &&
|
|
1125
|
+
block && logger3.error(`Blocking ${stream} after ${lease.retry} retries.`);
|
|
1023
1126
|
return {
|
|
1024
1127
|
lease,
|
|
1025
1128
|
handled,
|
|
@@ -1163,7 +1266,7 @@ var Act = class {
|
|
|
1163
1266
|
this._needs_drain = false;
|
|
1164
1267
|
return result;
|
|
1165
1268
|
} catch (error) {
|
|
1166
|
-
|
|
1269
|
+
logger3.error(error);
|
|
1167
1270
|
} finally {
|
|
1168
1271
|
this._drain_locked = false;
|
|
1169
1272
|
}
|
|
@@ -1436,7 +1539,7 @@ var Act = class {
|
|
|
1436
1539
|
if (!lastDrain.acked.length && !lastDrain.blocked.length) break;
|
|
1437
1540
|
}
|
|
1438
1541
|
if (lastDrain) this.emit("settled", lastDrain);
|
|
1439
|
-
})().catch((err) =>
|
|
1542
|
+
})().catch((err) => logger3.error(err)).finally(() => {
|
|
1440
1543
|
this._settling = false;
|
|
1441
1544
|
});
|
|
1442
1545
|
}, debounceMs);
|
|
@@ -1877,6 +1980,7 @@ export {
|
|
|
1877
1980
|
CausationEventSchema,
|
|
1878
1981
|
CommittedMetaSchema,
|
|
1879
1982
|
ConcurrencyError,
|
|
1983
|
+
ConsoleLogger,
|
|
1880
1984
|
Environments,
|
|
1881
1985
|
Errors,
|
|
1882
1986
|
EventMetaSchema,
|
|
@@ -1898,7 +2002,7 @@ export {
|
|
|
1898
2002
|
dispose,
|
|
1899
2003
|
disposeAndExit,
|
|
1900
2004
|
extend,
|
|
1901
|
-
|
|
2005
|
+
log,
|
|
1902
2006
|
port,
|
|
1903
2007
|
projection,
|
|
1904
2008
|
sleep,
|