@sv443-network/coreutils 3.5.0 → 3.6.0

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.
@@ -284,12 +284,12 @@ var NetworkError = class extends DatedError {
284
284
  };
285
285
 
286
286
  // lib/misc.ts
287
- async function consumeGen(valGen) {
288
- return await (typeof valGen === "function" ? valGen() : valGen);
287
+ async function consumeGen(valGen, ...args) {
288
+ return await (typeof valGen === "function" ? valGen(...args) : valGen);
289
289
  }
290
- async function consumeStringGen(strGen) {
290
+ async function consumeStringGen(strGen, ...args) {
291
291
  return typeof strGen === "string" ? strGen : String(
292
- typeof strGen === "function" ? await strGen() : strGen
292
+ typeof strGen === "function" ? await strGen(...args) : strGen
293
293
  );
294
294
  }
295
295
  async function fetchAdvanced(input, options = {}) {
@@ -328,6 +328,17 @@ function pauseFor(time, signal, rejectOnAbort = false) {
328
328
  function pureObj(obj) {
329
329
  return Object.assign(/* @__PURE__ */ Object.create(null), obj ?? {});
330
330
  }
331
+ function getterifyObj(obj, asCopy = false) {
332
+ const newObj = {};
333
+ for (const key in obj) {
334
+ Object.defineProperty(newObj, key, {
335
+ get: () => obj[key],
336
+ enumerable: true,
337
+ configurable: true
338
+ });
339
+ }
340
+ return asCopy ? structuredClone(newObj) : newObj;
341
+ }
331
342
  function setImmediateInterval(callback, interval, signal) {
332
343
  let intervalId;
333
344
  const cleanup = () => clearInterval(intervalId);
@@ -686,6 +697,8 @@ var NanoEmitter = class {
686
697
  events = createNanoEvents();
687
698
  eventUnsubscribes = [];
688
699
  emitterOptions;
700
+ /** Stores the last arguments for each event listed in `catchUpEvents` */
701
+ catchUpMemory = /* @__PURE__ */ new Map();
689
702
  /** Creates a new instance of NanoEmitter - a lightweight event emitter with helper methods and a strongly typed event map */
690
703
  constructor(options = {}) {
691
704
  this.emitterOptions = {
@@ -693,6 +706,18 @@ var NanoEmitter = class {
693
706
  ...options
694
707
  };
695
708
  }
709
+ //#region emitEvent
710
+ /**
711
+ * Emits an event on this instance, bypassing the `publicEmit` guard.
712
+ * Prefer this over `this.events.emit()` in subclasses — it updates catch-up memory
713
+ * for any event listed in `catchUpEvents` so late listeners can still receive the last value.
714
+ */
715
+ emitEvent(event, ...args) {
716
+ var _a;
717
+ if ((_a = this.emitterOptions.catchUpEvents) == null ? void 0 : _a.includes(event))
718
+ this.catchUpMemory.set(event, args);
719
+ this.events.emit(event, ...args);
720
+ }
696
721
  //#region on
697
722
  /**
698
723
  * Subscribes to an event and calls the callback when it's emitted.
@@ -725,6 +750,9 @@ var NanoEmitter = class {
725
750
  };
726
751
  unsub = this.events.on(event, cb);
727
752
  this.eventUnsubscribes.push(unsub);
753
+ const memory = this.catchUpMemory.get(event);
754
+ if (memory)
755
+ cb(...memory);
728
756
  return unsubProxy;
729
757
  }
730
758
  //#region once
@@ -747,6 +775,12 @@ var NanoEmitter = class {
747
775
  * ```
748
776
  */
749
777
  once(event, cb) {
778
+ const memory = this.catchUpMemory.get(event);
779
+ if (memory) {
780
+ const args = memory;
781
+ cb == null ? void 0 : cb(...args);
782
+ return Promise.resolve(args);
783
+ }
750
784
  return new Promise((resolve) => {
751
785
  let unsub;
752
786
  const onceProxy = ((...args) => {
@@ -848,7 +882,7 @@ var NanoEmitter = class {
848
882
  */
849
883
  emit(event, ...args) {
850
884
  if (this.emitterOptions.publicEmit) {
851
- this.events.emit(event, ...args);
885
+ this.emitEvent(event, ...args);
852
886
  return true;
853
887
  }
854
888
  return false;
@@ -971,7 +1005,7 @@ var DataStore = class extends NanoEmitter {
971
1005
  if (typeof storedDataRaw !== "string" && typeof storedDataRaw !== "object" || storedDataRaw === null || isNaN(storedFmtVer)) {
972
1006
  await this.saveDefaultData(false);
973
1007
  const data = this.engine.deepCopy(this.defaultData);
974
- this.events.emit("loadData", data);
1008
+ this.emitEvent("loadData", data);
975
1009
  return data;
976
1010
  }
977
1011
  const storedData = storedDataRaw ?? JSON.stringify(this.defaultData);
@@ -981,12 +1015,12 @@ var DataStore = class extends NanoEmitter {
981
1015
  if (storedFmtVer < this.formatVersion && this.migrations)
982
1016
  parsed = await this.runMigrations(parsed, storedFmtVer);
983
1017
  const result = this.memoryCache ? this.cachedData = this.engine.deepCopy(parsed) : this.engine.deepCopy(parsed);
984
- this.events.emit("loadData", result);
1018
+ this.emitEvent("loadData", result);
985
1019
  return result;
986
1020
  } catch (err) {
987
1021
  const error = err instanceof Error ? err : new Error(String(err));
988
1022
  console.warn("Error while parsing JSON data, resetting it to the default value.", err);
989
- this.events.emit("error", error);
1023
+ this.emitEvent("error", error);
990
1024
  await this.saveDefaultData();
991
1025
  return this.defaultData;
992
1026
  }
@@ -1008,7 +1042,7 @@ var DataStore = class extends NanoEmitter {
1008
1042
  const dataCopy = this.engine.deepCopy(data);
1009
1043
  if (this.memoryCache) {
1010
1044
  this.cachedData = data;
1011
- this.events.emit("updateDataSync", dataCopy);
1045
+ this.emitEvent("updateDataSync", dataCopy);
1012
1046
  }
1013
1047
  return new Promise(async (resolve) => {
1014
1048
  const results = await Promise.allSettled([
@@ -1017,11 +1051,11 @@ var DataStore = class extends NanoEmitter {
1017
1051
  this.engine.setValue(`${this.keyPrefix}${this.id}-enf`, this.compressionFormat)
1018
1052
  ]);
1019
1053
  if (results.every((r) => r.status === "fulfilled"))
1020
- this.events.emit("updateData", dataCopy);
1054
+ this.emitEvent("updateData", dataCopy);
1021
1055
  else {
1022
1056
  const error = new Error("Error while saving data to persistent storage: " + results.map((r) => r.status === "rejected" ? r.reason : null).filter(Boolean).join("; "));
1023
1057
  console.error(error);
1024
- this.events.emit("error", error);
1058
+ this.emitEvent("error", error);
1025
1059
  }
1026
1060
  resolve();
1027
1061
  });
@@ -1040,11 +1074,11 @@ var DataStore = class extends NanoEmitter {
1040
1074
  this.engine.setValue(`${this.keyPrefix}${this.id}-enf`, this.compressionFormat)
1041
1075
  ]);
1042
1076
  if (results.every((r) => r.status === "fulfilled"))
1043
- emitEvent && this.events.emit("setDefaultData", this.defaultData);
1077
+ emitEvent && this.emitEvent("setDefaultData", this.defaultData);
1044
1078
  else {
1045
1079
  const error = new Error("Error while saving default data to persistent storage: " + results.map((r) => r.status === "rejected" ? r.reason : null).filter(Boolean).join("; "));
1046
1080
  console.error(error);
1047
- this.events.emit("error", error);
1081
+ this.emitEvent("error", error);
1048
1082
  }
1049
1083
  }
1050
1084
  //#region deleteData
@@ -1061,7 +1095,7 @@ var DataStore = class extends NanoEmitter {
1061
1095
  this.engine.deleteValue(`${this.keyPrefix}${this.id}-enf`)
1062
1096
  ]);
1063
1097
  await ((_b = (_a = this.engine).deleteStorage) == null ? void 0 : _b.call(_a));
1064
- this.events.emit("deleteData");
1098
+ this.emitEvent("deleteData");
1065
1099
  }
1066
1100
  //#region encodingEnabled
1067
1101
  /** Returns whether encoding and decoding are enabled for this DataStore instance */
@@ -1091,11 +1125,11 @@ var DataStore = class extends NanoEmitter {
1091
1125
  newData = migRes instanceof Promise ? await migRes : migRes;
1092
1126
  lastFmtVer = oldFmtVer = ver;
1093
1127
  const isFinal = ver >= this.formatVersion || i === sortedMigrations.length - 1;
1094
- this.events.emit("migrateData", ver, newData, isFinal);
1128
+ this.emitEvent("migrateData", ver, newData, isFinal);
1095
1129
  } catch (err) {
1096
1130
  const migError = new MigrationError(`Error while running migration function for format version '${fmtVer}'`, { cause: err });
1097
- this.events.emit("migrationError", ver, migError);
1098
- this.events.emit("error", migError);
1131
+ this.emitEvent("migrationError", ver, migError);
1132
+ this.emitEvent("error", migError);
1099
1133
  if (!resetOnError)
1100
1134
  throw migError;
1101
1135
  await this.saveDefaultData();
@@ -1109,7 +1143,7 @@ var DataStore = class extends NanoEmitter {
1109
1143
  this.engine.setValue(`${this.keyPrefix}${this.id}-enf`, this.compressionFormat)
1110
1144
  ]);
1111
1145
  const result = this.memoryCache ? this.cachedData = this.engine.deepCopy(newData) : this.engine.deepCopy(newData);
1112
- this.events.emit("updateData", result);
1146
+ this.emitEvent("updateData", result);
1113
1147
  return result;
1114
1148
  }
1115
1149
  //#region migrateId
@@ -1139,7 +1173,7 @@ var DataStore = class extends NanoEmitter {
1139
1173
  this.engine.deleteValue(`${this.keyPrefix}${id}-ver`),
1140
1174
  this.engine.deleteValue(`${this.keyPrefix}${id}-enf`)
1141
1175
  ]);
1142
- this.events.emit("migrateId", id, this.id);
1176
+ this.emitEvent("migrateId", id, this.id);
1143
1177
  }));
1144
1178
  }
1145
1179
  };
@@ -1382,15 +1416,20 @@ var DataStoreSerializer = class _DataStoreSerializer {
1382
1416
  addChecksum: true,
1383
1417
  ensureIntegrity: true,
1384
1418
  remapIds: {},
1419
+ stringifyData: true,
1385
1420
  ...options
1386
1421
  };
1387
1422
  }
1388
1423
  /**
1389
- * Calculates the checksum of a string. Uses {@linkcode computeHash()} with SHA-256 and digests as a hex string by default.
1424
+ * Calculates the checksum of a string or {@linkcode DataStoreData} object. Uses {@linkcode computeHash()} with SHA-256 and digests as a hex string by default.
1390
1425
  * Override this in a subclass if a custom checksum method is needed.
1391
1426
  */
1392
1427
  async calcChecksum(input) {
1393
- return computeHash(input, "SHA-256");
1428
+ try {
1429
+ return computeHash(typeof input === "string" ? input : JSON.stringify(input), "SHA-256");
1430
+ } catch (err) {
1431
+ throw new Error(`Failed to calculate checksum: ${err.message}`, { cause: err });
1432
+ }
1394
1433
  }
1395
1434
  /**
1396
1435
  * Serializes only a subset of the data stores into a string.
@@ -1405,7 +1444,7 @@ var DataStoreSerializer = class _DataStoreSerializer {
1405
1444
  for (const storeInst of filteredStores) {
1406
1445
  const encoded = Boolean(useEncoding && storeInst.encodingEnabled() && ((_a = storeInst.encodeData) == null ? void 0 : _a[1]));
1407
1446
  const rawData = storeInst.memoryCache ? storeInst.getData() : await storeInst.loadData();
1408
- const data = encoded ? await storeInst.encodeData[1](JSON.stringify(rawData)) : JSON.stringify(rawData);
1447
+ const data = encoded ? await storeInst.encodeData[1](JSON.stringify(rawData)) : this.options.stringifyData ? JSON.stringify(rawData) : rawData;
1409
1448
  serData.push({
1410
1449
  id: storeInst.id,
1411
1450
  data,
@@ -1451,11 +1490,11 @@ var DataStoreSerializer = class _DataStoreSerializer {
1451
1490
  Expected: ${storeData.checksum}
1452
1491
  Has: ${checksum}`);
1453
1492
  }
1454
- const decodedData = storeData.encoded && storeInst.encodingEnabled() ? await storeInst.decodeData[1](storeData.data) : storeData.data;
1493
+ const decodedData = storeData.encoded && storeInst.encodingEnabled() ? await storeInst.decodeData[1](typeof storeData.data === "string" ? storeData.data : JSON.stringify(storeData.data)) : storeData.data;
1455
1494
  if (storeData.formatVersion && !isNaN(Number(storeData.formatVersion)) && Number(storeData.formatVersion) < storeInst.formatVersion)
1456
- await storeInst.runMigrations(JSON.parse(decodedData), Number(storeData.formatVersion), false);
1495
+ await storeInst.runMigrations(typeof decodedData === "string" ? JSON.parse(decodedData) : decodedData, Number(storeData.formatVersion), false);
1457
1496
  else
1458
- await storeInst.setData(JSON.parse(decodedData));
1497
+ await storeInst.setData(typeof decodedData === "string" ? JSON.parse(decodedData) : decodedData);
1459
1498
  }
1460
1499
  }
1461
1500
  /**
@@ -1524,6 +1563,8 @@ var Debouncer = class extends NanoEmitter {
1524
1563
  this.timeout = timeout;
1525
1564
  this.type = type;
1526
1565
  }
1566
+ timeout;
1567
+ type;
1527
1568
  /** All registered listener functions and the time they were attached */
1528
1569
  listeners = [];
1529
1570
  /** The currently active timeout */
@@ -1551,7 +1592,7 @@ var Debouncer = class extends NanoEmitter {
1551
1592
  //#region timeout
1552
1593
  /** Sets the timeout for the debouncer */
1553
1594
  setTimeout(timeout) {
1554
- this.events.emit("change", this.timeout = timeout, this.type);
1595
+ this.emitEvent("change", this.timeout = timeout, this.type);
1555
1596
  }
1556
1597
  /** Returns the current timeout */
1557
1598
  getTimeout() {
@@ -1564,7 +1605,7 @@ var Debouncer = class extends NanoEmitter {
1564
1605
  //#region type
1565
1606
  /** Sets the edge type for the debouncer */
1566
1607
  setType(type) {
1567
- this.events.emit("change", this.timeout, this.type = type);
1608
+ this.emitEvent("change", this.timeout, this.type = type);
1568
1609
  }
1569
1610
  /** Returns the current edge type */
1570
1611
  getType() {
@@ -1575,7 +1616,7 @@ var Debouncer = class extends NanoEmitter {
1575
1616
  call(...args) {
1576
1617
  const cl = (...a) => {
1577
1618
  this.queuedCall = void 0;
1578
- this.events.emit("call", ...a);
1619
+ this.emitEvent("call", ...a);
1579
1620
  this.listeners.forEach((l) => l.call(this, ...a));
1580
1621
  };
1581
1622
  const setRepeatTimeout = () => {
@@ -1653,6 +1694,7 @@ export {
1653
1694
  formatNumber,
1654
1695
  getCallStack,
1655
1696
  getListLength,
1697
+ getterifyObj,
1656
1698
  hexToRgb,
1657
1699
  insertValues,
1658
1700
  joinArrayReadable,