memx 0.0.1 → 0.0.5

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 CHANGED
@@ -1 +1,2 @@
1
-
1
+ # MEMX
2
+ Simple and fast memcached client
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 = {};
@@ -316,6 +314,9 @@ function typedArrayFlags(value) {
316
314
  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");
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);
938
1097
  }
939
- touch(key, options) {
940
- return this.server(key).touch(key, options);
1098
+ gat(key, ttl) {
1099
+ return this.server(key).gat(key, ttl);
1100
+ }
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_types5 = require("util/types");
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,24 +1188,72 @@ 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 ((0, import_types5.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 */ })];
1013
1202
  }
1014
- function makeTypedArray(constructor, source, bytesPerValue) {
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
+ }
1248
+ }
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;
1256
+ #prefix;
1021
1257
  constructor(adapterOrOptions) {
1022
1258
  if (!adapterOrOptions) {
1023
1259
  this.#adapter = new ClusterAdapter();
@@ -1026,96 +1262,73 @@ var Client = class {
1026
1262
  } else if ("hosts" in adapterOrOptions) {
1027
1263
  this.#adapter = new ClusterAdapter(adapterOrOptions);
1028
1264
  }
1029
- (0, import_assert4.default)(this.#adapter, "Invalid client constructor arguments");
1265
+ this.#prefix = "";
1266
+ (0, import_assert5.default)(this.#adapter, "Invalid client constructor arguments");
1030
1267
  }
1031
1268
  get adapter() {
1032
1269
  return this.#adapter;
1033
1270
  }
1034
- async get(key, options) {
1035
- const result = await this.#adapter.get(key, options);
1036
- if (!result)
1037
- return;
1038
- try {
1039
- const { flags, value, cas } = result;
1040
- switch (flags) {
1041
- case 3402235904 /* BIGINT */:
1042
- return { value: BigInt(value.toString("utf-8")), cas };
1043
- case 3402235905 /* BOOLEAN */:
1044
- return { value: !!value[0], cas };
1045
- case 3402235906 /* NUMBER */:
1046
- return { value: Number(value.toString("utf-8")), cas };
1047
- case 3402235907 /* STRING */:
1048
- return { value: value.toString("utf-8"), cas };
1049
- case 3402235918 /* NULL */:
1050
- return { value: null, cas };
1051
- case 3402235919 /* JSON */:
1052
- return { value: JSON.parse(value.toString("utf-8")), cas };
1053
- case 3402235920 /* UINT8ARRAY */:
1054
- return { value: makeTypedArray(Uint8Array, value, 1), cas };
1055
- case 3402235921 /* UINT8CLAMPEDARRAY */:
1056
- return { value: makeTypedArray(Uint8ClampedArray, value, 1), cas };
1057
- case 3402235922 /* UINT16ARRAY */:
1058
- return { value: makeTypedArray(Uint16Array, value, 2), cas };
1059
- case 3402235923 /* UINT32ARRAY */:
1060
- return { value: makeTypedArray(Uint32Array, value, 4), cas };
1061
- case 3402235924 /* INT8ARRAY */:
1062
- return { value: makeTypedArray(Int8Array, value, 1), cas };
1063
- case 3402235925 /* INT16ARRAY */:
1064
- return { value: makeTypedArray(Int16Array, value, 2), cas };
1065
- case 3402235926 /* INT32ARRAY */:
1066
- return { value: makeTypedArray(Int32Array, value, 4), cas };
1067
- case 3402235927 /* BIGUINT64ARRAY */:
1068
- return { value: makeTypedArray(BigUint64Array, value, 8), cas };
1069
- case 3402235928 /* BIGINT64ARRAY */:
1070
- return { value: makeTypedArray(BigInt64Array, value, 8), cas };
1071
- case 3402235929 /* FLOAT32ARRAY */:
1072
- return { value: makeTypedArray(Float32Array, value, 4), cas };
1073
- case 3402235930 /* FLOAT64ARRAY */:
1074
- return { value: makeTypedArray(Float64Array, value, 8), cas };
1075
- case 0 /* BUFFER */:
1076
- default:
1077
- return { value: Buffer.from(value), cas };
1078
- }
1079
- } finally {
1080
- result.recycle();
1081
- }
1271
+ get prefix() {
1272
+ return this.#prefix;
1273
+ }
1274
+ withPrefix(prefix) {
1275
+ (0, import_assert5.default)(prefix, "Invalid prefix");
1276
+ const client = new Client(this.#adapter);
1277
+ client.#prefix = prefix;
1278
+ return client;
1279
+ }
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);
1082
1295
  }
1083
1296
  async set(key, value, options) {
1084
- return this.#adapter.set(key, ...toBuffer(value, options));
1297
+ return this.#adapter.set(this.#prefix + key, ...toBuffer(value, options));
1085
1298
  }
1086
1299
  async add(key, value, options) {
1087
- return this.#adapter.add(key, ...toBuffer(value, options));
1300
+ return this.#adapter.add(this.#prefix + key, ...toBuffer(value, options));
1088
1301
  }
1089
1302
  async replace(key, value, options) {
1090
- return this.#adapter.replace(key, ...toBuffer(value, options));
1303
+ return this.#adapter.replace(this.#prefix + key, ...toBuffer(value, options));
1091
1304
  }
1092
1305
  append(key, value, options) {
1093
- return this.#adapter.append(key, ...toBuffer(value, options));
1306
+ return this.#adapter.append(this.#prefix + key, ...toBuffer(value, options));
1094
1307
  }
1095
1308
  prepend(key, value, options) {
1096
- return this.#adapter.prepend(key, ...toBuffer(value, options));
1309
+ return this.#adapter.prepend(this.#prefix + key, ...toBuffer(value, options));
1097
1310
  }
1098
1311
  async increment(key, delta, options) {
1099
- const counter = await this.#adapter.increment(key, delta, options);
1100
- if (counter && options && options.initial !== void 0 && counter.value === BigInt(options.initial)) {
1312
+ const counter = await this.#adapter.increment(this.#prefix + key, delta, options);
1313
+ if ((options == null ? void 0 : options.initial) !== void 0 && (counter == null ? void 0 : counter.value) === BigInt(options.initial)) {
1101
1314
  const cas = await this.replace(key, counter.value, { cas: counter.cas, ttl: options.ttl });
1102
1315
  counter.cas = cas ?? counter.cas;
1103
1316
  }
1104
1317
  return counter;
1105
1318
  }
1106
1319
  async decrement(key, delta, options) {
1107
- const counter = await this.#adapter.decrement(key, delta, options);
1108
- if (counter && options && options.initial !== void 0 && counter.value === BigInt(options.initial)) {
1320
+ const counter = await this.#adapter.decrement(this.#prefix + key, delta, options);
1321
+ if ((options == null ? void 0 : options.initial) !== void 0 && (counter == null ? void 0 : counter.value) === BigInt(options.initial)) {
1109
1322
  const cas = await this.replace(key, counter.value, { cas: counter.cas, ttl: options.ttl });
1110
1323
  counter.cas = cas ?? counter.cas;
1111
1324
  }
1112
1325
  return counter;
1113
1326
  }
1114
- touch(key, options) {
1115
- return this.#adapter.touch(key, options);
1327
+ touch(key, ttl) {
1328
+ return this.#adapter.touch(this.#prefix + key, ttl);
1116
1329
  }
1117
1330
  delete(key, options) {
1118
- return this.#adapter.delete(key, options);
1331
+ return this.#adapter.delete(this.#prefix + key, options);
1119
1332
  }
1120
1333
  flush(ttl) {
1121
1334
  return this.#adapter.flush(ttl);
@@ -1133,11 +1346,140 @@ var Client = class {
1133
1346
  return this.#adapter.stats();
1134
1347
  }
1135
1348
  };
1136
- 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
+ };
1137
1475
  // Annotate the CommonJS export names for ESM import in node:
1138
1476
  0 && (module.exports = {
1477
+ Bundle,
1139
1478
  Client,
1140
1479
  ClusterAdapter,
1480
+ Factory,
1481
+ FakeAdapter,
1482
+ PoorManLock,
1141
1483
  ServerAdapter,
1142
1484
  connection,
1143
1485
  constants,