@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.cjs
CHANGED
|
@@ -35,6 +35,7 @@ __export(index_exports, {
|
|
|
35
35
|
CausationEventSchema: () => CausationEventSchema,
|
|
36
36
|
CommittedMetaSchema: () => CommittedMetaSchema,
|
|
37
37
|
ConcurrencyError: () => ConcurrencyError,
|
|
38
|
+
ConsoleLogger: () => ConsoleLogger,
|
|
38
39
|
Environments: () => Environments,
|
|
39
40
|
Errors: () => Errors,
|
|
40
41
|
EventMetaSchema: () => EventMetaSchema,
|
|
@@ -56,7 +57,7 @@ __export(index_exports, {
|
|
|
56
57
|
dispose: () => dispose,
|
|
57
58
|
disposeAndExit: () => disposeAndExit,
|
|
58
59
|
extend: () => extend,
|
|
59
|
-
|
|
60
|
+
log: () => log,
|
|
60
61
|
port: () => port,
|
|
61
62
|
projection: () => projection,
|
|
62
63
|
sleep: () => sleep,
|
|
@@ -67,8 +68,107 @@ __export(index_exports, {
|
|
|
67
68
|
});
|
|
68
69
|
module.exports = __toCommonJS(index_exports);
|
|
69
70
|
|
|
70
|
-
// src/
|
|
71
|
-
var
|
|
71
|
+
// src/adapters/ConsoleLogger.ts
|
|
72
|
+
var LEVEL_VALUES = {
|
|
73
|
+
fatal: 60,
|
|
74
|
+
error: 50,
|
|
75
|
+
warn: 40,
|
|
76
|
+
info: 30,
|
|
77
|
+
debug: 20,
|
|
78
|
+
trace: 10
|
|
79
|
+
};
|
|
80
|
+
var LEVEL_COLORS = {
|
|
81
|
+
fatal: "\x1B[41m\x1B[37m",
|
|
82
|
+
// white on red bg
|
|
83
|
+
error: "\x1B[31m",
|
|
84
|
+
// red
|
|
85
|
+
warn: "\x1B[33m",
|
|
86
|
+
// yellow
|
|
87
|
+
info: "\x1B[32m",
|
|
88
|
+
// green
|
|
89
|
+
debug: "\x1B[36m",
|
|
90
|
+
// cyan
|
|
91
|
+
trace: "\x1B[90m"
|
|
92
|
+
// gray
|
|
93
|
+
};
|
|
94
|
+
var RESET = "\x1B[0m";
|
|
95
|
+
var noop = () => {
|
|
96
|
+
};
|
|
97
|
+
var ConsoleLogger = class _ConsoleLogger {
|
|
98
|
+
level;
|
|
99
|
+
_pretty;
|
|
100
|
+
fatal;
|
|
101
|
+
error;
|
|
102
|
+
warn;
|
|
103
|
+
info;
|
|
104
|
+
debug;
|
|
105
|
+
trace;
|
|
106
|
+
constructor(options = {}) {
|
|
107
|
+
const {
|
|
108
|
+
level = "info",
|
|
109
|
+
pretty = process.env.NODE_ENV !== "production",
|
|
110
|
+
bindings
|
|
111
|
+
} = options;
|
|
112
|
+
this._pretty = pretty;
|
|
113
|
+
this.level = level;
|
|
114
|
+
const threshold = LEVEL_VALUES[level] ?? 30;
|
|
115
|
+
const write = pretty ? this._prettyWrite.bind(this, bindings) : this._jsonWrite.bind(this, bindings);
|
|
116
|
+
this.fatal = write.bind(this, "fatal", 60);
|
|
117
|
+
this.error = threshold <= 50 ? write.bind(this, "error", 50) : noop;
|
|
118
|
+
this.warn = threshold <= 40 ? write.bind(this, "warn", 40) : noop;
|
|
119
|
+
this.info = threshold <= 30 ? write.bind(this, "info", 30) : noop;
|
|
120
|
+
this.debug = threshold <= 20 ? write.bind(this, "debug", 20) : noop;
|
|
121
|
+
this.trace = threshold <= 10 ? write.bind(this, "trace", 10) : noop;
|
|
122
|
+
}
|
|
123
|
+
async dispose() {
|
|
124
|
+
}
|
|
125
|
+
child(bindings) {
|
|
126
|
+
return new _ConsoleLogger({
|
|
127
|
+
level: this.level,
|
|
128
|
+
pretty: this._pretty,
|
|
129
|
+
bindings
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
_jsonWrite(bindings, level, _num, objOrMsg, msg) {
|
|
133
|
+
let obj;
|
|
134
|
+
let message;
|
|
135
|
+
if (typeof objOrMsg === "string") {
|
|
136
|
+
message = objOrMsg;
|
|
137
|
+
obj = {};
|
|
138
|
+
} else if (objOrMsg !== null && typeof objOrMsg === "object") {
|
|
139
|
+
message = msg;
|
|
140
|
+
obj = Object.fromEntries(Object.entries(objOrMsg));
|
|
141
|
+
} else {
|
|
142
|
+
message = msg;
|
|
143
|
+
obj = { value: objOrMsg };
|
|
144
|
+
}
|
|
145
|
+
const entry = Object.assign({ level, time: Date.now() }, bindings, obj);
|
|
146
|
+
if (message) entry.msg = message;
|
|
147
|
+
process.stdout.write(JSON.stringify(entry) + "\n");
|
|
148
|
+
}
|
|
149
|
+
_prettyWrite(bindings, level, _num, objOrMsg, msg) {
|
|
150
|
+
const color = LEVEL_COLORS[level];
|
|
151
|
+
const tag = `${color}${level.toUpperCase().padEnd(5)}${RESET}`;
|
|
152
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
153
|
+
let message;
|
|
154
|
+
let data;
|
|
155
|
+
if (typeof objOrMsg === "string") {
|
|
156
|
+
message = objOrMsg;
|
|
157
|
+
} else {
|
|
158
|
+
message = msg ?? "";
|
|
159
|
+
if (objOrMsg !== void 0 && objOrMsg !== null) {
|
|
160
|
+
try {
|
|
161
|
+
data = JSON.stringify(objOrMsg);
|
|
162
|
+
} catch {
|
|
163
|
+
data = "[unserializable]";
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const bindStr = bindings && Object.keys(bindings).length ? ` ${JSON.stringify(bindings)}` : "";
|
|
168
|
+
const parts = [ts, tag, message, data, bindStr].filter(Boolean);
|
|
169
|
+
process.stdout.write(parts.join(" ") + "\n");
|
|
170
|
+
}
|
|
171
|
+
};
|
|
72
172
|
|
|
73
173
|
// src/adapters/InMemoryCache.ts
|
|
74
174
|
var InMemoryCache = class {
|
|
@@ -195,7 +295,8 @@ var QuerySchema = import_zod.z.object({
|
|
|
195
295
|
created_after: import_zod.z.date().optional(),
|
|
196
296
|
backward: import_zod.z.boolean().optional(),
|
|
197
297
|
correlation: import_zod.z.string().optional(),
|
|
198
|
-
with_snaps: import_zod.z.boolean().optional()
|
|
298
|
+
with_snaps: import_zod.z.boolean().optional(),
|
|
299
|
+
stream_exact: import_zod.z.boolean().optional()
|
|
199
300
|
}).readonly();
|
|
200
301
|
|
|
201
302
|
// src/types/index.ts
|
|
@@ -376,8 +477,11 @@ var InMemoryStore = class {
|
|
|
376
477
|
this._streams = /* @__PURE__ */ new Map();
|
|
377
478
|
}
|
|
378
479
|
in_query(query, e) {
|
|
379
|
-
if (query.stream
|
|
380
|
-
|
|
480
|
+
if (query.stream) {
|
|
481
|
+
if (query.stream_exact) {
|
|
482
|
+
if (e.stream !== query.stream) return false;
|
|
483
|
+
} else if (!RegExp(`^${query.stream}$`).test(e.stream)) return false;
|
|
484
|
+
}
|
|
381
485
|
if (query.names && !query.names.includes(e.name)) return false;
|
|
382
486
|
if (query.correlation && e.meta?.correlation !== query.correlation)
|
|
383
487
|
return false;
|
|
@@ -536,28 +640,30 @@ var InMemoryStore = class {
|
|
|
536
640
|
|
|
537
641
|
// src/ports.ts
|
|
538
642
|
var ExitCodes = ["ERROR", "EXIT"];
|
|
539
|
-
var logger = (0, import_pino.pino)({
|
|
540
|
-
transport: config().env !== "production" ? {
|
|
541
|
-
target: "pino-pretty",
|
|
542
|
-
options: {
|
|
543
|
-
ignore: "pid,hostname",
|
|
544
|
-
singleLine: config().logSingleLine,
|
|
545
|
-
colorize: true
|
|
546
|
-
}
|
|
547
|
-
} : void 0,
|
|
548
|
-
level: config().logLevel
|
|
549
|
-
});
|
|
550
643
|
var adapters = /* @__PURE__ */ new Map();
|
|
551
644
|
function port(injector) {
|
|
552
645
|
return function(adapter) {
|
|
553
646
|
if (!adapters.has(injector.name)) {
|
|
554
647
|
const injected = injector(adapter);
|
|
555
648
|
adapters.set(injector.name, injected);
|
|
556
|
-
|
|
649
|
+
console.log(`[act] + ${injector.name}:${injected.constructor.name}`);
|
|
557
650
|
}
|
|
558
651
|
return adapters.get(injector.name);
|
|
559
652
|
};
|
|
560
653
|
}
|
|
654
|
+
var log = port(function log2(adapter) {
|
|
655
|
+
const cfg = config();
|
|
656
|
+
return adapter || new ConsoleLogger({
|
|
657
|
+
level: cfg.logLevel,
|
|
658
|
+
pretty: cfg.env !== "production"
|
|
659
|
+
});
|
|
660
|
+
});
|
|
661
|
+
var store = port(function store2(adapter) {
|
|
662
|
+
return adapter || new InMemoryStore();
|
|
663
|
+
});
|
|
664
|
+
var cache = port(function cache2(adapter) {
|
|
665
|
+
return adapter || new InMemoryCache();
|
|
666
|
+
});
|
|
561
667
|
var disposers = [];
|
|
562
668
|
async function disposeAndExit(code = "EXIT") {
|
|
563
669
|
if (code === "ERROR" && config().env === "production") return;
|
|
@@ -565,7 +671,7 @@ async function disposeAndExit(code = "EXIT") {
|
|
|
565
671
|
await Promise.all(
|
|
566
672
|
[...adapters.values()].reverse().map(async (adapter) => {
|
|
567
673
|
await adapter.dispose();
|
|
568
|
-
|
|
674
|
+
console.log(`[act] - ${adapter.constructor.name}`);
|
|
569
675
|
})
|
|
570
676
|
);
|
|
571
677
|
adapters.clear();
|
|
@@ -576,14 +682,9 @@ function dispose(disposer) {
|
|
|
576
682
|
return disposeAndExit;
|
|
577
683
|
}
|
|
578
684
|
var SNAP_EVENT = "__snapshot__";
|
|
579
|
-
var store = port(function store2(adapter) {
|
|
580
|
-
return adapter || new InMemoryStore();
|
|
581
|
-
});
|
|
582
|
-
var cache = port(function cache2(adapter) {
|
|
583
|
-
return adapter || new InMemoryCache();
|
|
584
|
-
});
|
|
585
685
|
function build_tracer(logLevel2) {
|
|
586
686
|
if (logLevel2 === "trace") {
|
|
687
|
+
const logger4 = log();
|
|
587
688
|
return {
|
|
588
689
|
fetched: (fetched) => {
|
|
589
690
|
const data = Object.fromEntries(
|
|
@@ -595,23 +696,23 @@ function build_tracer(logLevel2) {
|
|
|
595
696
|
return [key, value];
|
|
596
697
|
})
|
|
597
698
|
);
|
|
598
|
-
|
|
699
|
+
logger4.trace(data, ">> fetch");
|
|
599
700
|
},
|
|
600
701
|
correlated: (streams) => {
|
|
601
702
|
const data = streams.map(({ stream }) => stream).join(" ");
|
|
602
|
-
|
|
703
|
+
logger4.trace(`>> correlate ${data}`);
|
|
603
704
|
},
|
|
604
705
|
leased: (leases) => {
|
|
605
706
|
const data = Object.fromEntries(
|
|
606
707
|
leases.map(({ stream, at, retry }) => [stream, { at, retry }])
|
|
607
708
|
);
|
|
608
|
-
|
|
709
|
+
logger4.trace(data, ">> lease");
|
|
609
710
|
},
|
|
610
711
|
acked: (leases) => {
|
|
611
712
|
const data = Object.fromEntries(
|
|
612
713
|
leases.map(({ stream, at, retry }) => [stream, { at, retry }])
|
|
613
714
|
);
|
|
614
|
-
|
|
715
|
+
logger4.trace(data, ">> ack");
|
|
615
716
|
},
|
|
616
717
|
blocked: (leases) => {
|
|
617
718
|
const data = Object.fromEntries(
|
|
@@ -620,7 +721,7 @@ function build_tracer(logLevel2) {
|
|
|
620
721
|
{ at, retry, error }
|
|
621
722
|
])
|
|
622
723
|
);
|
|
623
|
-
|
|
724
|
+
logger4.trace(data, ">> block");
|
|
624
725
|
}
|
|
625
726
|
};
|
|
626
727
|
} else {
|
|
@@ -640,6 +741,7 @@ function build_tracer(logLevel2) {
|
|
|
640
741
|
}
|
|
641
742
|
|
|
642
743
|
// src/signals.ts
|
|
744
|
+
var logger = log();
|
|
643
745
|
process.once("SIGINT", async (arg) => {
|
|
644
746
|
logger.info(arg, "SIGINT");
|
|
645
747
|
await disposeAndExit("EXIT");
|
|
@@ -664,6 +766,7 @@ var import_events = __toESM(require("events"), 1);
|
|
|
664
766
|
// src/event-sourcing.ts
|
|
665
767
|
var import_act_patch = require("@rotorsoft/act-patch");
|
|
666
768
|
var import_crypto = require("crypto");
|
|
769
|
+
var logger2 = log();
|
|
667
770
|
async function snap(snapshot) {
|
|
668
771
|
try {
|
|
669
772
|
const { id, stream, name, meta, version } = snapshot.event;
|
|
@@ -677,9 +780,9 @@ async function snap(snapshot) {
|
|
|
677
780
|
version
|
|
678
781
|
// IMPORTANT! - state events are committed right after the snapshot event
|
|
679
782
|
);
|
|
680
|
-
|
|
783
|
+
logger2.trace(snapped, "\u{1F7E0} snap");
|
|
681
784
|
} catch (error) {
|
|
682
|
-
|
|
785
|
+
logger2.error(error);
|
|
683
786
|
}
|
|
684
787
|
}
|
|
685
788
|
async function load(me, stream, callback) {
|
|
@@ -701,9 +804,9 @@ async function load(me, stream, callback) {
|
|
|
701
804
|
}
|
|
702
805
|
callback && callback({ event, state: state2, patches, snaps });
|
|
703
806
|
},
|
|
704
|
-
{ stream, with_snaps: !cached, after: cached?.event_id }
|
|
807
|
+
{ stream, with_snaps: !cached, after: cached?.event_id, stream_exact: true }
|
|
705
808
|
);
|
|
706
|
-
|
|
809
|
+
logger2.trace(
|
|
707
810
|
state2,
|
|
708
811
|
`\u{1F7E2} load ${stream}${cached && count === 0 ? " (cached)" : ""}`
|
|
709
812
|
);
|
|
@@ -715,7 +818,7 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
715
818
|
payload = skipValidation ? payload : validate(action2, payload, me.actions[action2]);
|
|
716
819
|
const snapshot = await load(me, stream);
|
|
717
820
|
const expected = expectedVersion || snapshot.event?.version;
|
|
718
|
-
|
|
821
|
+
logger2.trace(
|
|
719
822
|
payload,
|
|
720
823
|
`\u{1F535} ${stream}.${action2}${typeof expected === "number" ? `.${expected}` : ""}`
|
|
721
824
|
);
|
|
@@ -758,7 +861,7 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
758
861
|
} : void 0
|
|
759
862
|
}
|
|
760
863
|
};
|
|
761
|
-
|
|
864
|
+
logger2.trace(
|
|
762
865
|
emitted.map((e) => e.data),
|
|
763
866
|
`\u{1F534} commit ${stream}.${emitted.map((e) => e.name).join(", ")}`
|
|
764
867
|
);
|
|
@@ -798,6 +901,7 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
798
901
|
}
|
|
799
902
|
|
|
800
903
|
// src/act.ts
|
|
904
|
+
var logger3 = log();
|
|
801
905
|
var tracer = build_tracer(config().logLevel);
|
|
802
906
|
var Act = class {
|
|
803
907
|
constructor(registry, _states = /* @__PURE__ */ new Map()) {
|
|
@@ -1078,7 +1182,7 @@ var Act = class {
|
|
|
1078
1182
|
if (payloads.length === 0) return { lease, handled: 0, at: lease.at };
|
|
1079
1183
|
const stream = lease.stream;
|
|
1080
1184
|
let at = payloads.at(0).event.id, handled = 0;
|
|
1081
|
-
lease.retry > 0 &&
|
|
1185
|
+
lease.retry > 0 && logger3.warn(`Retrying ${stream}@${at} (${lease.retry}).`);
|
|
1082
1186
|
for (const payload of payloads) {
|
|
1083
1187
|
const { event, handler, options } = payload;
|
|
1084
1188
|
try {
|
|
@@ -1086,9 +1190,9 @@ var Act = class {
|
|
|
1086
1190
|
at = event.id;
|
|
1087
1191
|
handled++;
|
|
1088
1192
|
} catch (error) {
|
|
1089
|
-
|
|
1193
|
+
logger3.error(error);
|
|
1090
1194
|
const block = lease.retry >= options.maxRetries && options.blockOnError;
|
|
1091
|
-
block &&
|
|
1195
|
+
block && logger3.error(`Blocking ${stream} after ${lease.retry} retries.`);
|
|
1092
1196
|
return {
|
|
1093
1197
|
lease,
|
|
1094
1198
|
handled,
|
|
@@ -1232,7 +1336,7 @@ var Act = class {
|
|
|
1232
1336
|
this._needs_drain = false;
|
|
1233
1337
|
return result;
|
|
1234
1338
|
} catch (error) {
|
|
1235
|
-
|
|
1339
|
+
logger3.error(error);
|
|
1236
1340
|
} finally {
|
|
1237
1341
|
this._drain_locked = false;
|
|
1238
1342
|
}
|
|
@@ -1505,7 +1609,7 @@ var Act = class {
|
|
|
1505
1609
|
if (!lastDrain.acked.length && !lastDrain.blocked.length) break;
|
|
1506
1610
|
}
|
|
1507
1611
|
if (lastDrain) this.emit("settled", lastDrain);
|
|
1508
|
-
})().catch((err) =>
|
|
1612
|
+
})().catch((err) => logger3.error(err)).finally(() => {
|
|
1509
1613
|
this._settling = false;
|
|
1510
1614
|
});
|
|
1511
1615
|
}, debounceMs);
|
|
@@ -1947,6 +2051,7 @@ function action_builder(state2) {
|
|
|
1947
2051
|
CausationEventSchema,
|
|
1948
2052
|
CommittedMetaSchema,
|
|
1949
2053
|
ConcurrencyError,
|
|
2054
|
+
ConsoleLogger,
|
|
1950
2055
|
Environments,
|
|
1951
2056
|
Errors,
|
|
1952
2057
|
EventMetaSchema,
|
|
@@ -1968,7 +2073,7 @@ function action_builder(state2) {
|
|
|
1968
2073
|
dispose,
|
|
1969
2074
|
disposeAndExit,
|
|
1970
2075
|
extend,
|
|
1971
|
-
|
|
2076
|
+
log,
|
|
1972
2077
|
port,
|
|
1973
2078
|
projection,
|
|
1974
2079
|
sleep,
|