@rotorsoft/act 0.32.3 → 0.32.4

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
@@ -179,12 +179,19 @@ var BaseSchema = PackageSchema.extend({
179
179
  });
180
180
  var { NODE_ENV, LOG_LEVEL, LOG_SINGLE_LINE, SLEEP_MS } = process.env;
181
181
  var env = NODE_ENV || "development";
182
- var logLevel = LOG_LEVEL || (NODE_ENV === "test" ? "error" : NODE_ENV === "production" ? "info" : "trace");
182
+ var logLevel = LOG_LEVEL || (NODE_ENV === "test" ? "fatal" : NODE_ENV === "production" ? "info" : "trace");
183
183
  var logSingleLine = (LOG_SINGLE_LINE || "true") === "true";
184
184
  var sleepMs = parseInt(NODE_ENV === "test" ? "0" : SLEEP_MS ?? "100", 10);
185
185
  var pkg = getPackage();
186
+ var _validated;
186
187
  var config = () => {
187
- return extend({ ...pkg, env, logLevel, logSingleLine, sleepMs }, BaseSchema);
188
+ if (!_validated) {
189
+ _validated = extend(
190
+ { ...pkg, env, logLevel, logSingleLine, sleepMs },
191
+ BaseSchema
192
+ );
193
+ }
194
+ return _validated;
188
195
  };
189
196
 
190
197
  // src/utils.ts
@@ -607,7 +614,7 @@ function port(injector) {
607
614
  if (!adapters.has(injector.name)) {
608
615
  const injected = injector(adapter);
609
616
  adapters.set(injector.name, injected);
610
- console.log(`[act] + ${injector.name}:${injected.constructor.name}`);
617
+ log().info(`[act] + ${injector.name}:${injected.constructor.name}`);
611
618
  }
612
619
  return adapters.get(injector.name);
613
620
  };
@@ -633,7 +640,7 @@ async function disposeAndExit(code = "EXIT") {
633
640
  }
634
641
  for (const adapter of [...adapters.values()].reverse()) {
635
642
  await adapter.dispose();
636
- console.log(`[act] - ${adapter.constructor.name}`);
643
+ log().info(`[act] - ${adapter.constructor.name}`);
637
644
  }
638
645
  adapters.clear();
639
646
  config().env !== "test" && process.exit(code === "ERROR" ? 1 : 0);
@@ -951,6 +958,18 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
951
958
  }
952
959
 
953
960
  // src/internal/tracing.ts
961
+ var PRETTY = config().env !== "production";
962
+ var C_BLUE = "\x1B[38;5;39m";
963
+ var C_ORANGE = "\x1B[38;5;208m";
964
+ var C_GREEN = "\x1B[38;5;42m";
965
+ var C_MAGENTA = "\x1B[38;5;165m";
966
+ var C_DRAIN = "\x1B[38;5;244m";
967
+ var C_RESET = "\x1B[0m";
968
+ var es_caption = (caption, color, body) => PRETTY ? `${color}${body}${C_RESET}` : `${caption}: ${body}`;
969
+ var drain_caption = (caption) => {
970
+ const tag = `>> ${caption}`;
971
+ return PRETTY ? `${C_DRAIN}${tag}${C_RESET}` : tag;
972
+ };
954
973
  var traced = (inner, exit, entry) => (async (...args) => {
955
974
  entry?.(...args);
956
975
  const result = await inner(...args);
@@ -964,11 +983,17 @@ function buildEs(logger) {
964
983
  return {
965
984
  snap: traced(snap, void 0, (snapshot) => {
966
985
  logger.trace(
967
- `\u{1F7E0} snap ${snapshot.event.stream}@${snapshot.event.version}`
986
+ es_caption(
987
+ "snap",
988
+ C_MAGENTA,
989
+ `${snapshot.event.stream}@${snapshot.event.version}`
990
+ )
968
991
  );
969
992
  }),
970
993
  load: traced(load, void 0, (_me, stream, _cb, asOf) => {
971
- logger.trace(`\u{1F7E2} load ${stream}${asOf ? " (as-of)" : ""}`);
994
+ logger.trace(
995
+ es_caption("load", C_GREEN, `${stream}${asOf ? " (as-of)" : ""}`)
996
+ );
972
997
  }),
973
998
  action: traced(
974
999
  action,
@@ -977,12 +1002,19 @@ function buildEs(logger) {
977
1002
  if (committed.length) {
978
1003
  logger.trace(
979
1004
  committed.map((s) => s.event.data),
980
- `\u{1F534} commit ${target.stream}.${committed.map((s) => s.event.name).join(", ")}`
1005
+ es_caption(
1006
+ "committed",
1007
+ C_ORANGE,
1008
+ `${target.stream}.${committed.map((s) => s.event.name).join(", ")}`
1009
+ )
981
1010
  );
982
1011
  }
983
1012
  },
984
1013
  (_me, action2, target, payload) => {
985
- logger.trace(payload, `\u{1F535} ${target.stream}.${action2}`);
1014
+ logger.trace(
1015
+ payload,
1016
+ es_caption("action", C_BLUE, `${target.stream}.${action2}`)
1017
+ );
986
1018
  }
987
1019
  )
988
1020
  };
@@ -1003,7 +1035,7 @@ function buildDrain(logger) {
1003
1035
  const data = Object.fromEntries(
1004
1036
  leased.map(({ stream, at, retry }) => [stream, { at, retry }])
1005
1037
  );
1006
- logger.trace(data, ">> lease");
1038
+ logger.trace(data, drain_caption("claimed"));
1007
1039
  }
1008
1040
  }),
1009
1041
  fetch: traced(fetch, (fetched) => {
@@ -1016,14 +1048,14 @@ function buildDrain(logger) {
1016
1048
  return [key, value];
1017
1049
  })
1018
1050
  );
1019
- logger.trace(data, ">> fetch");
1051
+ logger.trace(data, drain_caption("fetched"));
1020
1052
  }),
1021
1053
  ack: traced(ack, (acked) => {
1022
1054
  if (acked.length) {
1023
1055
  const data = Object.fromEntries(
1024
1056
  acked.map(({ stream, at, retry }) => [stream, { at, retry }])
1025
1057
  );
1026
- logger.trace(data, ">> ack");
1058
+ logger.trace(data, drain_caption("acked"));
1027
1059
  }
1028
1060
  }),
1029
1061
  block: traced(block, (blocked) => {
@@ -1034,13 +1066,13 @@ function buildDrain(logger) {
1034
1066
  { at, retry, error }
1035
1067
  ])
1036
1068
  );
1037
- logger.trace(data, ">> block");
1069
+ logger.trace(data, drain_caption("blocked"));
1038
1070
  }
1039
1071
  }),
1040
1072
  subscribe: traced(subscribe, (result, streams) => {
1041
1073
  if (result.subscribed) {
1042
1074
  const data = streams.map(({ stream }) => stream).join(" ");
1043
- logger.trace(`>> correlate ${data}`);
1075
+ logger.trace(`${drain_caption("correlated")} ${data}`);
1044
1076
  }
1045
1077
  })
1046
1078
  };
@@ -1054,7 +1086,7 @@ var Act = class {
1054
1086
  this._batch_handlers = batchHandlers;
1055
1087
  this._es = buildEs(this._logger);
1056
1088
  this._cd = buildDrain(this._logger);
1057
- const statics = [];
1089
+ const statics = /* @__PURE__ */ new Map();
1058
1090
  for (const [name, register] of Object.entries(this.registry.events)) {
1059
1091
  if (register.reactions.size > 0) {
1060
1092
  this._reactive_events.add(name);
@@ -1063,14 +1095,13 @@ var Act = class {
1063
1095
  if (typeof reaction.resolver === "function") {
1064
1096
  this._has_dynamic_resolvers = true;
1065
1097
  } else {
1066
- statics.push({
1067
- stream: reaction.resolver.target,
1068
- source: reaction.resolver.source
1069
- });
1098
+ const { target, source } = reaction.resolver;
1099
+ const key = `${target}|${source ?? ""}`;
1100
+ if (!statics.has(key)) statics.set(key, { stream: target, source });
1070
1101
  }
1071
1102
  }
1072
1103
  }
1073
- this._static_targets = statics;
1104
+ this._static_targets = [...statics.values()];
1074
1105
  for (const merged of this._states.values()) {
1075
1106
  for (const eventName of Object.keys(merged.events)) {
1076
1107
  this._event_to_state.set(eventName, merged);
@@ -1131,6 +1162,12 @@ var Act = class {
1131
1162
  _event_to_state = /* @__PURE__ */ new Map();
1132
1163
  /** Logger resolved at construction time (after user port configuration) */
1133
1164
  _logger = log();
1165
+ /** Pre-bound IAct methods reused across drain cycles. Only `do` varies per
1166
+ * payload (it captures the triggering event for reactingTo auto-inject). */
1167
+ _bound_do = this.do.bind(this);
1168
+ _bound_load = this.load.bind(this);
1169
+ _bound_query = this.query.bind(this);
1170
+ _bound_query_array = this.query_array.bind(this);
1134
1171
  /**
1135
1172
  * Executes an action on a state instance, committing resulting events.
1136
1173
  *
@@ -1353,12 +1390,12 @@ var Act = class {
1353
1390
  const stream = lease.stream;
1354
1391
  let at = payloads.at(0).event.id, handled = 0;
1355
1392
  lease.retry > 0 && this._logger.warn(`Retrying ${stream}@${at} (${lease.retry}).`);
1356
- const doAction = this.do.bind(this);
1393
+ const doAction = this._bound_do;
1357
1394
  const scopedApp = {
1358
1395
  do: doAction,
1359
- load: this.load.bind(this),
1360
- query: this.query.bind(this),
1361
- query_array: this.query_array.bind(this)
1396
+ load: this._bound_load,
1397
+ query: this._bound_query,
1398
+ query_array: this._bound_query_array
1362
1399
  };
1363
1400
  for (const payload of payloads) {
1364
1401
  const { event, handler, options } = payload;
@@ -1491,12 +1528,13 @@ var Act = class {
1491
1528
  return { fetched: [], leased: [], acked: [], blocked: [] };
1492
1529
  }
1493
1530
  const fetched = await this._cd.fetch(leased, eventLimit);
1494
- const payloadsMap = /* @__PURE__ */ new Map();
1531
+ const fetchMap = /* @__PURE__ */ new Map();
1495
1532
  const fetch_window_at = fetched.reduce(
1496
1533
  (max, { at, events }) => Math.max(max, events.at(-1)?.id || at),
1497
1534
  0
1498
1535
  );
1499
- fetched.forEach(({ stream, events }) => {
1536
+ for (const f of fetched) {
1537
+ const { stream, events } = f;
1500
1538
  const payloads = events.flatMap((event) => {
1501
1539
  const register = this.registry.events[event.name];
1502
1540
  if (!register) return [];
@@ -1505,13 +1543,13 @@ var Act = class {
1505
1543
  return resolved && resolved.target === stream;
1506
1544
  }).map((reaction) => ({ ...reaction, event }));
1507
1545
  });
1508
- payloadsMap.set(stream, payloads);
1509
- });
1546
+ fetchMap.set(stream, { fetch: f, payloads });
1547
+ }
1510
1548
  const handled = await Promise.all(
1511
1549
  leased.map((lease) => {
1512
- const streamFetch = fetched.find((f) => f.stream === lease.stream);
1513
- const at = streamFetch?.events.at(-1)?.id || fetch_window_at;
1514
- const payloads = payloadsMap.get(lease.stream);
1550
+ const entry = fetchMap.get(lease.stream);
1551
+ const at = entry?.fetch.events.at(-1)?.id || fetch_window_at;
1552
+ const payloads = entry?.payloads ?? [];
1515
1553
  const batchHandler = this._batch_handlers.get(lease.stream);
1516
1554
  if (batchHandler && payloads.length > 0) {
1517
1555
  return this.handleBatch({ ...lease, at }, payloads, batchHandler);