@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/dist/index.js CHANGED
@@ -1,5 +1,104 @@
1
- // src/ports.ts
2
- import { pino } from "pino";
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 && !RegExp(`^${query.stream}$`).test(e.stream))
311
- return false;
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
- logger.info(`\u{1F50C} injected ${injector.name}:${injected.constructor.name}`);
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
- logger.info(`\u{1F50C} disposed ${adapter.constructor.name}`);
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
- logger.trace(data, "\u26A1\uFE0F fetch");
629
+ logger4.trace(data, ">> fetch");
530
630
  },
531
631
  correlated: (streams) => {
532
632
  const data = streams.map(({ stream }) => stream).join(" ");
533
- logger.trace(`\u26A1\uFE0F correlate ${data}`);
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
- logger.trace(data, "\u26A1\uFE0F lease");
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
- logger.trace(data, "\u26A1\uFE0F ack");
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
- logger.trace(data, "\u26A1\uFE0F block");
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
- logger.trace(snapped, "\u{1F7E0} snap");
713
+ logger2.trace(snapped, "\u{1F7E0} snap");
612
714
  } catch (error) {
613
- logger.error(error);
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
- logger.trace(
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
- logger.trace(
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
- logger.trace(
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 && logger.warn(`Retrying ${stream}@${at} (${lease.retry}).`);
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
- logger.error(error);
1123
+ logger3.error(error);
1021
1124
  const block = lease.retry >= options.maxRetries && options.blockOnError;
1022
- block && logger.error(`Blocking ${stream} after ${lease.retry} retries.`);
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
- logger.error(error);
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) => logger.error(err)).finally(() => {
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
- logger,
2005
+ log,
1902
2006
  port,
1903
2007
  projection,
1904
2008
  sleep,