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 +421 -87
- package/dist/index.js.map +2 -2
- package/dist/index.mjs +408 -83
- package/dist/index.mjs.map +2 -2
- package/index.d.ts +150 -68
- package/package.json +7 -7
- package/src/buffers.ts +9 -0
- package/src/client.ts +138 -66
- package/src/cluster.ts +24 -12
- package/src/connection.ts +1 -1
- package/src/encode.ts +1 -1
- package/src/fake.ts +222 -0
- package/src/index.ts +4 -0
- package/src/internals.ts +17 -24
- package/src/server.ts +28 -17
- package/src/types.ts +15 -9
- package/src/utils.ts +161 -0
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
|
|
30
|
-
if (
|
|
31
|
-
for (let key of __getOwnPropNames(
|
|
32
|
-
if (!__hasOwnProp.call(
|
|
33
|
-
__defProp(
|
|
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
|
|
34
|
+
return to;
|
|
36
35
|
};
|
|
37
|
-
var __toESM = (
|
|
38
|
-
|
|
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
|
|
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 =
|
|
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,
|
|
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
|
|
639
|
-
|
|
640
|
-
|
|
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
|
|
937
|
-
return this.server(key).get(key
|
|
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,
|
|
940
|
-
return this.server(key).touch(key,
|
|
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
|
|
987
|
-
var
|
|
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
|
-
|
|
1191
|
+
import_assert5.default.fail(`Unable to store value of type "${typeof value}"`);
|
|
1004
1192
|
}
|
|
1005
|
-
if (
|
|
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
|
-
|
|
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
|
|
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 /
|
|
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,
|
|
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,
|
|
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
|
|
1043
|
-
const result = await this.#adapter.get(this.#prefix + key
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
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,
|
|
1123
|
-
return this.#adapter.touch(this.#prefix + key,
|
|
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
|
-
|
|
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,
|