memx 0.0.2 → 0.0.6

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
@@ -21,39 +21,37 @@ var __spreadValues = (a, b) => {
21
21
  return a;
22
22
  };
23
23
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
- var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
25
24
  var __export = (target, all) => {
26
25
  for (var name in all)
27
26
  __defProp(target, name, { get: all[name], enumerable: true });
28
27
  };
29
- var __reExport = (target, module2, copyDefault, desc) => {
30
- if (module2 && typeof module2 === "object" || typeof module2 === "function") {
31
- for (let key of __getOwnPropNames(module2))
32
- if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default"))
33
- __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
28
+ var __copyProps = (to, from, except, desc) => {
29
+ if (from && typeof from === "object" || typeof from === "function") {
30
+ for (let key of __getOwnPropNames(from))
31
+ if (!__hasOwnProp.call(to, key) && key !== except)
32
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
34
33
  }
35
- return target;
34
+ return to;
36
35
  };
37
- var __toESM = (module2, isNodeMode) => {
38
- return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", !isNodeMode && module2 && module2.__esModule ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
39
- };
40
- var __toCommonJS = /* @__PURE__ */ ((cache) => {
41
- return (module2, temp) => {
42
- return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp);
43
- };
44
- })(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0);
36
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
37
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
45
38
 
46
39
  // src/index.ts
47
40
  var src_exports = {};
48
41
  __export(src_exports, {
42
+ Bundle: () => Bundle,
49
43
  Client: () => Client,
50
44
  ClusterAdapter: () => ClusterAdapter,
45
+ Factory: () => Factory,
46
+ FakeAdapter: () => FakeAdapter,
47
+ PoorManLock: () => PoorManLock,
51
48
  ServerAdapter: () => ServerAdapter,
52
49
  connection: () => connection_exports,
53
50
  constants: () => constants_exports,
54
51
  decode: () => decode_exports,
55
52
  encode: () => encode_exports
56
53
  });
54
+ module.exports = __toCommonJS(src_exports);
57
55
 
58
56
  // src/decode.ts
59
57
  var decode_exports = {};
@@ -307,15 +305,18 @@ __export(connection_exports, {
307
305
 
308
306
  // src/internals.ts
309
307
  var import_assert2 = __toESM(require("assert"));
310
- var import_types = require("util/types");
308
+ var import_util = require("util");
311
309
  var socketFinalizationRegistry = new FinalizationRegistry((socket) => {
312
310
  if (!socket.destroyed)
313
311
  socket.destroy();
314
312
  });
315
313
  function typedArrayFlags(value) {
316
- const flags = (0, import_types.isUint8Array)(value) ? 3402235920 /* UINT8ARRAY */ : (0, import_types.isUint8ClampedArray)(value) ? 3402235921 /* UINT8CLAMPEDARRAY */ : (0, import_types.isUint16Array)(value) ? 3402235922 /* UINT16ARRAY */ : (0, import_types.isUint32Array)(value) ? 3402235923 /* UINT32ARRAY */ : (0, import_types.isInt8Array)(value) ? 3402235924 /* INT8ARRAY */ : (0, import_types.isInt16Array)(value) ? 3402235925 /* INT16ARRAY */ : (0, import_types.isInt32Array)(value) ? 3402235926 /* INT32ARRAY */ : (0, import_types.isBigUint64Array)(value) ? 3402235927 /* BIGUINT64ARRAY */ : (0, import_types.isBigInt64Array)(value) ? 3402235928 /* BIGINT64ARRAY */ : (0, import_types.isFloat32Array)(value) ? 3402235929 /* FLOAT32ARRAY */ : (0, import_types.isFloat64Array)(value) ? 3402235930 /* FLOAT64ARRAY */ : import_assert2.default.fail("Unsupported kind of TypedArray");
314
+ const flags = import_util.types.isUint8Array(value) ? 3402235920 /* UINT8ARRAY */ : import_util.types.isUint8ClampedArray(value) ? 3402235921 /* UINT8CLAMPEDARRAY */ : import_util.types.isUint16Array(value) ? 3402235922 /* UINT16ARRAY */ : import_util.types.isUint32Array(value) ? 3402235923 /* UINT32ARRAY */ : import_util.types.isInt8Array(value) ? 3402235924 /* INT8ARRAY */ : import_util.types.isInt16Array(value) ? 3402235925 /* INT16ARRAY */ : import_util.types.isInt32Array(value) ? 3402235926 /* INT32ARRAY */ : import_util.types.isBigUint64Array(value) ? 3402235927 /* BIGUINT64ARRAY */ : import_util.types.isBigInt64Array(value) ? 3402235928 /* BIGINT64ARRAY */ : import_util.types.isFloat32Array(value) ? 3402235929 /* FLOAT32ARRAY */ : import_util.types.isFloat64Array(value) ? 3402235930 /* FLOAT64ARRAY */ : import_assert2.default.fail("Unsupported kind of TypedArray");
317
315
  return flags;
318
316
  }
317
+ function logPromiseError(promise, message) {
318
+ return promise.catch((error) => console.log(message, error)).then(() => void 0);
319
+ }
319
320
 
320
321
  // src/connection.ts
321
322
  var import_assert3 = __toESM(require("assert"));
@@ -459,6 +460,153 @@ var Connection = class {
459
460
  }
460
461
  };
461
462
 
463
+ // src/fake.ts
464
+ function toExp(ttl = 0) {
465
+ if (ttl === 0)
466
+ return Number.MAX_SAFE_INTEGER;
467
+ return Date.now() + ttl * 1e3;
468
+ }
469
+ var FakeAdapter = class {
470
+ #cache = /* @__PURE__ */ new Map();
471
+ #cas = 1n;
472
+ ttl = 0;
473
+ #get(key) {
474
+ if (key.length > 250)
475
+ throw new TypeError(`Key too long (len=${key.length})`);
476
+ const entry = this.#cache.get(key);
477
+ if (!entry)
478
+ return;
479
+ if (Date.now() > entry.exp) {
480
+ this.#cache.delete(key);
481
+ return;
482
+ }
483
+ return entry;
484
+ }
485
+ #set(key, value, flags, ttl) {
486
+ this.#cache.set(key, {
487
+ value,
488
+ flags: flags || 0,
489
+ cas: ++this.#cas,
490
+ exp: toExp(ttl)
491
+ });
492
+ return this.#cas;
493
+ }
494
+ async get(key) {
495
+ const entry = this.#get(key);
496
+ if (!entry)
497
+ return;
498
+ return {
499
+ value: entry.value,
500
+ flags: entry.flags,
501
+ cas: entry.cas,
502
+ recycle: () => void 0
503
+ };
504
+ }
505
+ async gat(key, ttl) {
506
+ const entry = this.#get(key);
507
+ if (!entry)
508
+ return;
509
+ entry.exp = toExp(ttl);
510
+ return {
511
+ value: entry.value,
512
+ flags: entry.flags,
513
+ cas: entry.cas,
514
+ recycle: () => void 0
515
+ };
516
+ }
517
+ async touch(key, ttl) {
518
+ const entry = this.#get(key);
519
+ if (entry)
520
+ entry.exp = toExp(ttl);
521
+ return !!entry;
522
+ }
523
+ async set(key, value, options = {}) {
524
+ const entry = this.#get(key);
525
+ if (entry && options.cas !== void 0 && entry.cas !== options.cas) {
526
+ return;
527
+ }
528
+ return this.#set(key, value, options.flags, options.ttl);
529
+ }
530
+ async add(key, value, options = {}) {
531
+ if (this.#get(key))
532
+ return;
533
+ return this.#set(key, value, options.flags, options.ttl);
534
+ }
535
+ async replace(key, value, options = {}) {
536
+ if (!this.#get(key))
537
+ return;
538
+ return this.#set(key, value, options.flags, options.ttl);
539
+ }
540
+ async append(key, value, options = {}) {
541
+ const entry = this.#get(key);
542
+ if (!entry)
543
+ return false;
544
+ if (options.cas !== void 0 && options.cas !== entry.cas)
545
+ return false;
546
+ entry.value = Buffer.concat([entry.value, value]);
547
+ return true;
548
+ }
549
+ async prepend(key, value, options = {}) {
550
+ const entry = this.#get(key);
551
+ if (!entry)
552
+ return false;
553
+ if (options.cas !== void 0 && options.cas !== entry.cas)
554
+ return false;
555
+ entry.value = Buffer.concat([value, entry.value]);
556
+ return true;
557
+ }
558
+ async #counter(key, delta, options) {
559
+ const entry = this.#get(key);
560
+ if (!entry) {
561
+ if (options.initial !== void 0) {
562
+ const value = Buffer.from(options.initial.toString());
563
+ this.#set(key, value, void 0, options.ttl);
564
+ return { value: BigInt(options.initial), cas: this.#cas };
565
+ } else {
566
+ return;
567
+ }
568
+ }
569
+ if (options.cas !== void 0 && options.cas !== entry.cas)
570
+ return;
571
+ try {
572
+ const value = BigInt(entry.value.toString("utf-8")) + BigInt(delta);
573
+ this.#set(key, Buffer.from(value.toString()), void 0, options.ttl);
574
+ return { value, cas: this.#cas };
575
+ } catch (error) {
576
+ throw new TypeError(`${error.message} (status=NON_NUMERIC_VALUE, key=${key})`);
577
+ }
578
+ }
579
+ increment(key, delta = 1n, options = {}) {
580
+ return this.#counter(key, delta, options);
581
+ }
582
+ decrement(key, delta = 1n, options = {}) {
583
+ return this.#counter(key, -delta, options);
584
+ }
585
+ async delete(key, options = {}) {
586
+ const entry = this.#get(key);
587
+ if (entry && options.cas !== void 0 && entry.cas !== options.cas) {
588
+ return false;
589
+ }
590
+ return this.#cache.delete(key);
591
+ }
592
+ async flush(ttl) {
593
+ if (!ttl)
594
+ return this.#cache.clear();
595
+ const wait = toExp(ttl) - Date.now();
596
+ setTimeout(() => this.#cache.clear(), wait);
597
+ }
598
+ async noop() {
599
+ }
600
+ async quit() {
601
+ }
602
+ async version() {
603
+ return { fake: "0.0.0-fake" };
604
+ }
605
+ async stats() {
606
+ return { fake: { version: "0.0.0-fake" } };
607
+ }
608
+ };
609
+
462
610
  // src/server.ts
463
611
  var statsBigInt = [
464
612
  "auth_cmds",
@@ -606,10 +754,9 @@ var ServerAdapter = class {
606
754
  throw new Error(`Key too long (len=${keyLength})`);
607
755
  return keyLength;
608
756
  }
609
- async get(key, options = {}) {
610
- const { ttl } = options;
757
+ async #get(key, ttl) {
611
758
  let keyOffset = 0;
612
- if (ttl)
759
+ if (ttl !== void 0)
613
760
  keyOffset = this.#buffer.writeUInt32BE(ttl);
614
761
  const keyLength = this.#writeKey(key, keyOffset);
615
762
  const [response] = await this.#connection.send({
@@ -635,9 +782,15 @@ var ServerAdapter = class {
635
782
  fail(response, key);
636
783
  }
637
784
  }
638
- async touch(key, options = {}) {
639
- const { ttl = this.#ttl } = options;
640
- const keyOffset = this.#buffer.writeUInt32BE(ttl);
785
+ async get(key) {
786
+ return this.#get(key);
787
+ }
788
+ async gat(key, ttl) {
789
+ return this.#get(key, ttl || 2592e3);
790
+ }
791
+ async touch(key, ttl) {
792
+ const timeToLive = ttl ?? this.#ttl;
793
+ const keyOffset = this.#buffer.writeUInt32BE(timeToLive);
641
794
  const keyLength = this.#writeKey(key, keyOffset);
642
795
  const [response] = await this.#connection.send({
643
796
  opcode: 28 /* TOUCH */,
@@ -884,6 +1037,7 @@ var ServerAdapter = class {
884
1037
  };
885
1038
 
886
1039
  // src/cluster.ts
1040
+ var import_assert4 = __toESM(require("assert"));
887
1041
  function parseHosts(hosts) {
888
1042
  const result = [];
889
1043
  if (!hosts)
@@ -897,6 +1051,7 @@ function parseHosts(hosts) {
897
1051
  }
898
1052
  var ClusterAdapter = class {
899
1053
  servers;
1054
+ ttl;
900
1055
  constructor(serversOrOptions) {
901
1056
  if (Array.isArray(serversOrOptions)) {
902
1057
  this.servers = [...serversOrOptions];
@@ -924,6 +1079,10 @@ var ClusterAdapter = class {
924
1079
  throw new Error("No hosts configured");
925
1080
  if (this.servers.length === 1)
926
1081
  this.server = () => this.servers[0];
1082
+ this.ttl = this.servers[0].ttl;
1083
+ this.servers.slice(1).forEach((server) => {
1084
+ import_assert4.default.equal(server.ttl, this.ttl, `TTL Mismatch (${server.ttl} != ${this.ttl})`);
1085
+ });
927
1086
  Object.freeze(this.servers);
928
1087
  }
929
1088
  server(key) {
@@ -933,11 +1092,14 @@ var ClusterAdapter = class {
933
1092
  hash = hash * 31 + key.charCodeAt(i);
934
1093
  return this.servers[hash % this.servers.length];
935
1094
  }
936
- get(key, options) {
937
- return this.server(key).get(key, options);
1095
+ get(key) {
1096
+ return this.server(key).get(key);
1097
+ }
1098
+ gat(key, ttl) {
1099
+ return this.server(key).gat(key, ttl);
938
1100
  }
939
- touch(key, options) {
940
- return this.server(key).touch(key, options);
1101
+ touch(key, ttl) {
1102
+ return this.server(key).touch(key, ttl);
941
1103
  }
942
1104
  set(key, value, options) {
943
1105
  return this.server(key).set(key, value, options);
@@ -983,8 +1145,34 @@ var ClusterAdapter = class {
983
1145
  };
984
1146
 
985
1147
  // src/client.ts
986
- var import_assert4 = __toESM(require("assert"));
987
- var import_types4 = require("util/types");
1148
+ var import_assert5 = __toESM(require("assert"));
1149
+ var import_util2 = require("util");
1150
+ function replacer(key, value) {
1151
+ if (typeof this[key] === "bigint")
1152
+ return ["\0__$BIGINT$__\0", this[key].toString()];
1153
+ if (this[key] instanceof Date)
1154
+ return ["\0__$DATE$__\0", this[key].toISOString()];
1155
+ if (this[key] instanceof Set)
1156
+ return ["\0__$SET$__\0", ...value];
1157
+ if (this[key] instanceof Map)
1158
+ return ["\0__$MAP$__\0", ...value.entries()];
1159
+ return value;
1160
+ }
1161
+ function reviver(key, value) {
1162
+ if (Array.isArray(value)) {
1163
+ switch (value[0]) {
1164
+ case "\0__$BIGINT$__\0":
1165
+ return BigInt(value[1]);
1166
+ case "\0__$DATE$__\0":
1167
+ return new Date(value[1]);
1168
+ case "\0__$SET$__\0":
1169
+ return new Set(value.slice(1));
1170
+ case "\0__$MAP$__\0":
1171
+ return new Map(value.slice(1));
1172
+ }
1173
+ }
1174
+ return value;
1175
+ }
988
1176
  function toBuffer(value, options) {
989
1177
  if (Buffer.isBuffer(value))
990
1178
  return [value, __spreadProps(__spreadValues({}, options), { flags: 0 /* BUFFER */ })];
@@ -1000,21 +1188,68 @@ function toBuffer(value, options) {
1000
1188
  case "object":
1001
1189
  break;
1002
1190
  default:
1003
- import_assert4.default.fail(`Unable to store value of type "${typeof value}"`);
1191
+ import_assert5.default.fail(`Unable to store value of type "${typeof value}"`);
1004
1192
  }
1005
- if ((0, import_types4.isTypedArray)(value)) {
1193
+ if (import_util2.types.isTypedArray(value)) {
1006
1194
  const flags = typedArrayFlags(value);
1007
1195
  const buffer = Buffer.from(value.buffer, value.byteOffset, value.byteLength);
1008
1196
  return [buffer, __spreadProps(__spreadValues({}, options), { flags })];
1009
1197
  }
1010
1198
  if (value === null)
1011
1199
  return [EMPTY_BUFFER, __spreadProps(__spreadValues({}, options), { flags: 3402235918 /* NULL */ })];
1012
- return [Buffer.from(JSON.stringify(value), "utf-8"), __spreadProps(__spreadValues({}, options), { flags: 3402235919 /* JSON */ })];
1200
+ const json = JSON.stringify(value, replacer);
1201
+ return [Buffer.from(json, "utf-8"), __spreadProps(__spreadValues({}, options), { flags: 3402235919 /* JSON */ })];
1202
+ }
1203
+ function fromBuffer(result) {
1204
+ try {
1205
+ const { flags, value, cas } = result;
1206
+ switch (flags) {
1207
+ case 3402235904 /* BIGINT */:
1208
+ return { value: BigInt(value.toString("utf-8")), cas };
1209
+ case 3402235905 /* BOOLEAN */:
1210
+ return { value: !!value[0], cas };
1211
+ case 3402235906 /* NUMBER */:
1212
+ return { value: Number(value.toString("utf-8")), cas };
1213
+ case 3402235907 /* STRING */:
1214
+ return { value: value.toString("utf-8"), cas };
1215
+ case 3402235918 /* NULL */:
1216
+ return { value: null, cas };
1217
+ case 3402235919 /* JSON */:
1218
+ return { value: JSON.parse(value.toString("utf-8"), reviver), cas };
1219
+ case 3402235920 /* UINT8ARRAY */:
1220
+ return { value: makeTypedArray(Uint8Array, value), cas };
1221
+ case 3402235921 /* UINT8CLAMPEDARRAY */:
1222
+ return { value: makeTypedArray(Uint8ClampedArray, value), cas };
1223
+ case 3402235922 /* UINT16ARRAY */:
1224
+ return { value: makeTypedArray(Uint16Array, value), cas };
1225
+ case 3402235923 /* UINT32ARRAY */:
1226
+ return { value: makeTypedArray(Uint32Array, value), cas };
1227
+ case 3402235924 /* INT8ARRAY */:
1228
+ return { value: makeTypedArray(Int8Array, value), cas };
1229
+ case 3402235925 /* INT16ARRAY */:
1230
+ return { value: makeTypedArray(Int16Array, value), cas };
1231
+ case 3402235926 /* INT32ARRAY */:
1232
+ return { value: makeTypedArray(Int32Array, value), cas };
1233
+ case 3402235927 /* BIGUINT64ARRAY */:
1234
+ return { value: makeTypedArray(BigUint64Array, value), cas };
1235
+ case 3402235928 /* BIGINT64ARRAY */:
1236
+ return { value: makeTypedArray(BigInt64Array, value), cas };
1237
+ case 3402235929 /* FLOAT32ARRAY */:
1238
+ return { value: makeTypedArray(Float32Array, value), cas };
1239
+ case 3402235930 /* FLOAT64ARRAY */:
1240
+ return { value: makeTypedArray(Float64Array, value), cas };
1241
+ case 0 /* BUFFER */:
1242
+ default:
1243
+ return { value: Buffer.from(value), cas };
1244
+ }
1245
+ } finally {
1246
+ result.recycle();
1247
+ }
1013
1248
  }
1014
- function makeTypedArray(constructor, source, bytesPerValue) {
1249
+ function makeTypedArray(constructor, source) {
1015
1250
  const clone = Buffer.from(source);
1016
1251
  const { buffer, byteOffset, byteLength } = clone;
1017
- return new constructor(buffer, byteOffset, byteLength / bytesPerValue);
1252
+ return new constructor(buffer, byteOffset, byteLength / constructor.BYTES_PER_ELEMENT);
1018
1253
  }
1019
1254
  var Client = class {
1020
1255
  #adapter;
@@ -1028,65 +1263,35 @@ var Client = class {
1028
1263
  this.#adapter = new ClusterAdapter(adapterOrOptions);
1029
1264
  }
1030
1265
  this.#prefix = "";
1031
- (0, import_assert4.default)(this.#adapter, "Invalid client constructor arguments");
1266
+ (0, import_assert5.default)(this.#adapter, "Invalid client constructor arguments");
1032
1267
  }
1033
1268
  get adapter() {
1034
1269
  return this.#adapter;
1035
1270
  }
1271
+ get prefix() {
1272
+ return this.#prefix;
1273
+ }
1036
1274
  withPrefix(prefix) {
1037
- (0, import_assert4.default)(prefix, "Invalid prefix");
1275
+ (0, import_assert5.default)(prefix, "Invalid prefix");
1038
1276
  const client = new Client(this.#adapter);
1039
1277
  client.#prefix = prefix;
1040
1278
  return client;
1041
1279
  }
1042
- async get(key, options) {
1043
- const result = await this.#adapter.get(this.#prefix + key, options);
1044
- if (!result)
1045
- return;
1046
- try {
1047
- const { flags, value, cas } = result;
1048
- switch (flags) {
1049
- case 3402235904 /* BIGINT */:
1050
- return { value: BigInt(value.toString("utf-8")), cas };
1051
- case 3402235905 /* BOOLEAN */:
1052
- return { value: !!value[0], cas };
1053
- case 3402235906 /* NUMBER */:
1054
- return { value: Number(value.toString("utf-8")), cas };
1055
- case 3402235907 /* STRING */:
1056
- return { value: value.toString("utf-8"), cas };
1057
- case 3402235918 /* NULL */:
1058
- return { value: null, cas };
1059
- case 3402235919 /* JSON */:
1060
- return { value: JSON.parse(value.toString("utf-8")), cas };
1061
- case 3402235920 /* UINT8ARRAY */:
1062
- return { value: makeTypedArray(Uint8Array, value, 1), cas };
1063
- case 3402235921 /* UINT8CLAMPEDARRAY */:
1064
- return { value: makeTypedArray(Uint8ClampedArray, value, 1), cas };
1065
- case 3402235922 /* UINT16ARRAY */:
1066
- return { value: makeTypedArray(Uint16Array, value, 2), cas };
1067
- case 3402235923 /* UINT32ARRAY */:
1068
- return { value: makeTypedArray(Uint32Array, value, 4), cas };
1069
- case 3402235924 /* INT8ARRAY */:
1070
- return { value: makeTypedArray(Int8Array, value, 1), cas };
1071
- case 3402235925 /* INT16ARRAY */:
1072
- return { value: makeTypedArray(Int16Array, value, 2), cas };
1073
- case 3402235926 /* INT32ARRAY */:
1074
- return { value: makeTypedArray(Int32Array, value, 4), cas };
1075
- case 3402235927 /* BIGUINT64ARRAY */:
1076
- return { value: makeTypedArray(BigUint64Array, value, 8), cas };
1077
- case 3402235928 /* BIGINT64ARRAY */:
1078
- return { value: makeTypedArray(BigInt64Array, value, 8), cas };
1079
- case 3402235929 /* FLOAT32ARRAY */:
1080
- return { value: makeTypedArray(Float32Array, value, 4), cas };
1081
- case 3402235930 /* FLOAT64ARRAY */:
1082
- return { value: makeTypedArray(Float64Array, value, 8), cas };
1083
- case 0 /* BUFFER */:
1084
- default:
1085
- return { value: Buffer.from(value), cas };
1086
- }
1087
- } finally {
1088
- result.recycle();
1089
- }
1280
+ async get(key) {
1281
+ const result = await this.#adapter.get(this.#prefix + key);
1282
+ return result && fromBuffer(result).value;
1283
+ }
1284
+ async gat(key, ttl) {
1285
+ const result = await this.#adapter.gat(this.#prefix + key, ttl);
1286
+ return result && fromBuffer(result).value;
1287
+ }
1288
+ async getc(key) {
1289
+ const result = await this.#adapter.get(this.#prefix + key);
1290
+ return result && fromBuffer(result);
1291
+ }
1292
+ async gatc(key, ttl) {
1293
+ const result = await this.#adapter.gat(this.#prefix + key, ttl);
1294
+ return result && fromBuffer(result);
1090
1295
  }
1091
1296
  async set(key, value, options) {
1092
1297
  return this.#adapter.set(this.#prefix + key, ...toBuffer(value, options));
@@ -1119,8 +1324,8 @@ var Client = class {
1119
1324
  }
1120
1325
  return counter;
1121
1326
  }
1122
- touch(key, options) {
1123
- return this.#adapter.touch(this.#prefix + key, options);
1327
+ touch(key, ttl) {
1328
+ return this.#adapter.touch(this.#prefix + key, ttl);
1124
1329
  }
1125
1330
  delete(key, options) {
1126
1331
  return this.#adapter.delete(this.#prefix + key, options);
@@ -1141,11 +1346,140 @@ var Client = class {
1141
1346
  return this.#adapter.stats();
1142
1347
  }
1143
1348
  };
1144
- module.exports = __toCommonJS(src_exports);
1349
+
1350
+ // src/utils.ts
1351
+ var import_assert6 = __toESM(require("assert"));
1352
+ var Factory = class {
1353
+ #factory;
1354
+ #client;
1355
+ #ttl;
1356
+ constructor(client, factory, ttl) {
1357
+ (0, import_assert6.default)(typeof factory === "function", "Invalid or no factory specified");
1358
+ (0, import_assert6.default)(client, "No client specified");
1359
+ this.#factory = factory;
1360
+ this.#client = client;
1361
+ this.#ttl = ttl;
1362
+ }
1363
+ async get(key) {
1364
+ const cached = await this.#client.getc(key);
1365
+ if (cached) {
1366
+ void logPromiseError(this.#client.touch(key), `Factory error touching key "${this.#client.prefix}${key}"`);
1367
+ return cached.value;
1368
+ }
1369
+ const created = await this.#factory(key);
1370
+ if (created) {
1371
+ void logPromiseError(this.#client.set(key, created, { ttl: this.#ttl }), `Factory error setting key "${this.#client.prefix}${key}"`);
1372
+ }
1373
+ return created;
1374
+ }
1375
+ };
1376
+ var Bundle = class {
1377
+ #client;
1378
+ #name;
1379
+ #ttl;
1380
+ constructor(client, name, ttl) {
1381
+ (0, import_assert6.default)(client, "No client specified");
1382
+ (0, import_assert6.default)(name, "No bundle name specified");
1383
+ this.#client = client;
1384
+ this.#name = name;
1385
+ this.#ttl = ttl || 0;
1386
+ }
1387
+ async #appendKey(key) {
1388
+ await logPromiseError((async () => {
1389
+ const added = await this.#client.add(this.#name, key, { ttl: this.#ttl });
1390
+ if (!added) {
1391
+ await this.#client.append(this.#name, `\0${key}`);
1392
+ await this.#client.touch(this.#name, this.#ttl);
1393
+ }
1394
+ })(), `Bundle "${this.#client.prefix}${this.#name}" error recording key "${key}"`);
1395
+ }
1396
+ async #removeKey(key) {
1397
+ await logPromiseError((async () => {
1398
+ const result = await this.#client.getc(this.#name);
1399
+ if (!result)
1400
+ return;
1401
+ const keys = result.value.split("\0").filter((k) => k !== key).join("\0");
1402
+ await this.#client.set(this.#name, keys, { cas: result.cas, ttl: this.#ttl });
1403
+ })(), `Bundle "${this.#client.prefix}${this.#name}" error clearing key "${key}"`);
1404
+ }
1405
+ async add(key, value) {
1406
+ await this.#client.set(`${this.#name}:${key}`, value, { ttl: this.#ttl });
1407
+ await this.#appendKey(key);
1408
+ }
1409
+ async get(key) {
1410
+ const result = await this.#client.getc(`${this.#name}:${key}`);
1411
+ if (result)
1412
+ return result.value;
1413
+ await this.#removeKey(key);
1414
+ }
1415
+ async delete(key) {
1416
+ await this.#client.delete(`${this.#name}:${key}`);
1417
+ await this.#removeKey(key);
1418
+ }
1419
+ async list() {
1420
+ const result = await this.#client.getc(this.#name);
1421
+ if (!result)
1422
+ return {};
1423
+ const results = {};
1424
+ const promises = [];
1425
+ for (const key of new Set(result.value.split("\0"))) {
1426
+ promises.push(this.#client.getc(`${this.#name}:${key}`).then((result2) => {
1427
+ if (result2)
1428
+ results[key] = result2.value;
1429
+ }));
1430
+ }
1431
+ await Promise.all(promises);
1432
+ await logPromiseError(this.#client.set(this.#name, Object.keys(results).join("\0"), { cas: result.cas, ttl: this.#ttl }), `Bundle "${this.#client.prefix}${this.#name}" error compacting keys`);
1433
+ return results;
1434
+ }
1435
+ };
1436
+ var PoorManLock = class {
1437
+ #client;
1438
+ #name;
1439
+ constructor(client, name) {
1440
+ (0, import_assert6.default)(client, "No client specified");
1441
+ (0, import_assert6.default)(name, "No lock name specified");
1442
+ this.#client = client;
1443
+ this.#name = name;
1444
+ }
1445
+ async execute(executor, options) {
1446
+ const { timeout = 5e3, owner = false } = options || {};
1447
+ const end = Date.now() + timeout;
1448
+ let cas;
1449
+ do {
1450
+ cas = await this.#client.add(this.#name, owner, { ttl: 2 });
1451
+ if (cas !== void 0)
1452
+ break;
1453
+ await new Promise((resolve) => setTimeout(resolve, 100));
1454
+ } while (Date.now() < end);
1455
+ if (cas === void 0) {
1456
+ const other = await this.#client.getc(this.#name);
1457
+ const owner2 = other && other.value ? `"${other.value}"` : "anonymous";
1458
+ throw new Error(`Lock "${this.#client.prefix}${this.#name}" timeout (owner=${owner2})`);
1459
+ }
1460
+ const interval = setInterval(() => {
1461
+ void logPromiseError((async () => {
1462
+ const replaced = await this.#client.replace(this.#name, owner, { ttl: 2, cas });
1463
+ (0, import_assert6.default)(replaced !== void 0, `Lock "${this.#client.prefix}${this.#name}" not replaced`);
1464
+ cas = replaced;
1465
+ })(), `Error extending lock "${this.#client.prefix}${this.#name}"`);
1466
+ }, 100);
1467
+ try {
1468
+ return await executor();
1469
+ } finally {
1470
+ clearInterval(interval);
1471
+ await logPromiseError(this.#client.delete(this.#name, { cas }), `Error deleting lock "${this.#client.prefix}${this.#name}"`);
1472
+ }
1473
+ }
1474
+ };
1145
1475
  // Annotate the CommonJS export names for ESM import in node:
1146
1476
  0 && (module.exports = {
1477
+ Bundle,
1147
1478
  Client,
1148
1479
  ClusterAdapter,
1480
+ Factory,
1481
+ FakeAdapter,
1482
+ PoorManLock,
1149
1483
  ServerAdapter,
1150
1484
  connection,
1151
1485
  constants,