memx 0.0.7 → 0.1.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.
- package/dist/buffers.cjs +50 -0
- package/dist/buffers.cjs.map +6 -0
- package/dist/buffers.d.ts +14 -0
- package/dist/buffers.mjs +25 -0
- package/dist/buffers.mjs.map +6 -0
- package/dist/client.cjs +251 -0
- package/dist/client.cjs.map +6 -0
- package/dist/client.d.ts +76 -0
- package/dist/client.mjs +216 -0
- package/dist/client.mjs.map +6 -0
- package/dist/cluster.cjs +147 -0
- package/dist/cluster.cjs.map +6 -0
- package/dist/cluster.d.ts +60 -0
- package/dist/cluster.mjs +112 -0
- package/dist/cluster.mjs.map +6 -0
- package/dist/connection.cjs +186 -0
- package/dist/connection.cjs.map +6 -0
- package/dist/connection.d.ts +18 -0
- package/dist/connection.mjs +151 -0
- package/dist/connection.mjs.map +6 -0
- package/dist/constants.cjs +140 -0
- package/dist/constants.cjs.map +6 -0
- package/dist/constants.d.ts +87 -0
- package/dist/constants.mjs +107 -0
- package/dist/constants.mjs.map +6 -0
- package/dist/decode.cjs +101 -0
- package/dist/decode.cjs.map +6 -0
- package/dist/decode.d.ts +16 -0
- package/dist/decode.mjs +66 -0
- package/dist/decode.mjs.map +6 -0
- package/dist/encode.cjs +70 -0
- package/dist/encode.cjs.map +6 -0
- package/dist/encode.d.ts +20 -0
- package/dist/encode.mjs +45 -0
- package/dist/encode.mjs.map +6 -0
- package/dist/fake.cjs +183 -0
- package/dist/fake.cjs.map +6 -0
- package/dist/fake.d.ts +53 -0
- package/dist/fake.mjs +157 -0
- package/dist/fake.mjs.map +6 -0
- package/dist/index.cjs +57 -0
- package/dist/index.cjs.map +6 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.mjs +15 -1460
- package/dist/index.mjs.map +2 -2
- package/dist/internals.cjs +58 -0
- package/dist/internals.cjs.map +6 -0
- package/dist/internals.d.ts +7 -0
- package/dist/internals.mjs +21 -0
- package/dist/internals.mjs.map +6 -0
- package/dist/server.cjs +468 -0
- package/dist/server.cjs.map +6 -0
- package/dist/server.d.ts +59 -0
- package/dist/server.mjs +443 -0
- package/dist/server.mjs.map +6 -0
- package/dist/types.cjs +19 -0
- package/dist/types.cjs.map +6 -0
- package/dist/types.d.ts +239 -0
- package/dist/types.mjs +1 -0
- package/dist/types.mjs.map +6 -0
- package/dist/utils.cjs +182 -0
- package/dist/utils.cjs.map +6 -0
- package/dist/utils.d.ts +22 -0
- package/dist/utils.mjs +145 -0
- package/dist/utils.mjs.map +6 -0
- package/package.json +29 -27
- package/src/client.ts +25 -23
- package/src/cluster.ts +6 -3
- package/src/connection.ts +8 -4
- package/src/decode.ts +5 -2
- package/src/encode.ts +5 -2
- package/src/fake.ts +34 -33
- package/src/internals.ts +7 -7
- package/src/server.ts +47 -45
- package/src/utils.ts +7 -4
- package/dist/index.js +0 -1496
- package/dist/index.js.map +0 -6
- package/index.d.ts +0 -710
package/dist/index.js
DELETED
|
@@ -1,1496 +0,0 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __defProps = Object.defineProperties;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
11
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
|
-
var __spreadValues = (a, b) => {
|
|
13
|
-
for (var prop in b || (b = {}))
|
|
14
|
-
if (__hasOwnProp.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
if (__getOwnPropSymbols)
|
|
17
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
-
if (__propIsEnum.call(b, prop))
|
|
19
|
-
__defNormalProp(a, prop, b[prop]);
|
|
20
|
-
}
|
|
21
|
-
return a;
|
|
22
|
-
};
|
|
23
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
24
|
-
var __export = (target, all) => {
|
|
25
|
-
for (var name in all)
|
|
26
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
27
|
-
};
|
|
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 });
|
|
33
|
-
}
|
|
34
|
-
return to;
|
|
35
|
-
};
|
|
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);
|
|
38
|
-
|
|
39
|
-
// src/index.ts
|
|
40
|
-
var src_exports = {};
|
|
41
|
-
__export(src_exports, {
|
|
42
|
-
Bundle: () => Bundle,
|
|
43
|
-
ClusterAdapter: () => ClusterAdapter,
|
|
44
|
-
Factory: () => Factory,
|
|
45
|
-
FakeAdapter: () => FakeAdapter,
|
|
46
|
-
MemxClient: () => MemxClient,
|
|
47
|
-
MemxFakeClient: () => MemxFakeClient,
|
|
48
|
-
PoorManLock: () => PoorManLock,
|
|
49
|
-
ServerAdapter: () => ServerAdapter,
|
|
50
|
-
connection: () => connection_exports,
|
|
51
|
-
constants: () => constants_exports,
|
|
52
|
-
decode: () => decode_exports,
|
|
53
|
-
encode: () => encode_exports
|
|
54
|
-
});
|
|
55
|
-
module.exports = __toCommonJS(src_exports);
|
|
56
|
-
|
|
57
|
-
// src/decode.ts
|
|
58
|
-
var decode_exports = {};
|
|
59
|
-
__export(decode_exports, {
|
|
60
|
-
Decoder: () => Decoder
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// src/constants.ts
|
|
64
|
-
var constants_exports = {};
|
|
65
|
-
__export(constants_exports, {
|
|
66
|
-
BUFFERS: () => BUFFERS,
|
|
67
|
-
DATA_TYPE: () => DATA_TYPE,
|
|
68
|
-
EMPTY_BUFFER: () => EMPTY_BUFFER,
|
|
69
|
-
FLAGS: () => FLAGS,
|
|
70
|
-
MAGIC: () => MAGIC,
|
|
71
|
-
OFFSETS: () => OFFSETS,
|
|
72
|
-
OPCODE: () => OPCODE,
|
|
73
|
-
STATUS: () => STATUS,
|
|
74
|
-
VBUCKET: () => VBUCKET
|
|
75
|
-
});
|
|
76
|
-
var EMPTY_BUFFER = Buffer.alloc(0);
|
|
77
|
-
var FLAGS = /* @__PURE__ */ ((FLAGS2) => {
|
|
78
|
-
FLAGS2[FLAGS2["BUFFER"] = 0] = "BUFFER";
|
|
79
|
-
FLAGS2[FLAGS2["BIGINT"] = 3402235904] = "BIGINT";
|
|
80
|
-
FLAGS2[FLAGS2["BOOLEAN"] = 3402235905] = "BOOLEAN";
|
|
81
|
-
FLAGS2[FLAGS2["NUMBER"] = 3402235906] = "NUMBER";
|
|
82
|
-
FLAGS2[FLAGS2["STRING"] = 3402235907] = "STRING";
|
|
83
|
-
FLAGS2[FLAGS2["NULL"] = 3402235918] = "NULL";
|
|
84
|
-
FLAGS2[FLAGS2["JSON"] = 3402235919] = "JSON";
|
|
85
|
-
FLAGS2[FLAGS2["UINT8ARRAY"] = 3402235920] = "UINT8ARRAY";
|
|
86
|
-
FLAGS2[FLAGS2["UINT8CLAMPEDARRAY"] = 3402235921] = "UINT8CLAMPEDARRAY";
|
|
87
|
-
FLAGS2[FLAGS2["UINT16ARRAY"] = 3402235922] = "UINT16ARRAY";
|
|
88
|
-
FLAGS2[FLAGS2["UINT32ARRAY"] = 3402235923] = "UINT32ARRAY";
|
|
89
|
-
FLAGS2[FLAGS2["INT8ARRAY"] = 3402235924] = "INT8ARRAY";
|
|
90
|
-
FLAGS2[FLAGS2["INT16ARRAY"] = 3402235925] = "INT16ARRAY";
|
|
91
|
-
FLAGS2[FLAGS2["INT32ARRAY"] = 3402235926] = "INT32ARRAY";
|
|
92
|
-
FLAGS2[FLAGS2["BIGUINT64ARRAY"] = 3402235927] = "BIGUINT64ARRAY";
|
|
93
|
-
FLAGS2[FLAGS2["BIGINT64ARRAY"] = 3402235928] = "BIGINT64ARRAY";
|
|
94
|
-
FLAGS2[FLAGS2["FLOAT32ARRAY"] = 3402235929] = "FLOAT32ARRAY";
|
|
95
|
-
FLAGS2[FLAGS2["FLOAT64ARRAY"] = 3402235930] = "FLOAT64ARRAY";
|
|
96
|
-
return FLAGS2;
|
|
97
|
-
})(FLAGS || {});
|
|
98
|
-
var BUFFERS = /* @__PURE__ */ ((BUFFERS2) => {
|
|
99
|
-
BUFFERS2[BUFFERS2["POOL_SIZE"] = 64] = "POOL_SIZE";
|
|
100
|
-
BUFFERS2[BUFFERS2["BUFFER_SIZE"] = 8192] = "BUFFER_SIZE";
|
|
101
|
-
BUFFERS2[BUFFERS2["HEADER_SIZE"] = 24] = "HEADER_SIZE";
|
|
102
|
-
BUFFERS2[BUFFERS2["KEY_SIZE"] = 250] = "KEY_SIZE";
|
|
103
|
-
BUFFERS2[BUFFERS2["KEY_TOO_BIG"] = 251] = "KEY_TOO_BIG";
|
|
104
|
-
return BUFFERS2;
|
|
105
|
-
})(BUFFERS || {});
|
|
106
|
-
var OFFSETS = /* @__PURE__ */ ((OFFSETS2) => {
|
|
107
|
-
OFFSETS2[OFFSETS2["MAGIC_$8"] = 0] = "MAGIC_$8";
|
|
108
|
-
OFFSETS2[OFFSETS2["OPCODE_$8"] = 1] = "OPCODE_$8";
|
|
109
|
-
OFFSETS2[OFFSETS2["KEY_LENGTH_$16"] = 2] = "KEY_LENGTH_$16";
|
|
110
|
-
OFFSETS2[OFFSETS2["EXTRAS_LENGTH_$8"] = 4] = "EXTRAS_LENGTH_$8";
|
|
111
|
-
OFFSETS2[OFFSETS2["DATA_TYPE_$8"] = 5] = "DATA_TYPE_$8";
|
|
112
|
-
OFFSETS2[OFFSETS2["STATUS_$16"] = 6] = "STATUS_$16";
|
|
113
|
-
OFFSETS2[OFFSETS2["BODY_LENGTH_$32"] = 8] = "BODY_LENGTH_$32";
|
|
114
|
-
OFFSETS2[OFFSETS2["SEQUENCE_$32"] = 12] = "SEQUENCE_$32";
|
|
115
|
-
OFFSETS2[OFFSETS2["CAS_$64"] = 16] = "CAS_$64";
|
|
116
|
-
OFFSETS2[OFFSETS2["BODY"] = 24] = "BODY";
|
|
117
|
-
return OFFSETS2;
|
|
118
|
-
})(OFFSETS || {});
|
|
119
|
-
var MAGIC = /* @__PURE__ */ ((MAGIC2) => {
|
|
120
|
-
MAGIC2[MAGIC2["REQUEST"] = 128] = "REQUEST";
|
|
121
|
-
MAGIC2[MAGIC2["RESPONSE"] = 129] = "RESPONSE";
|
|
122
|
-
return MAGIC2;
|
|
123
|
-
})(MAGIC || {});
|
|
124
|
-
var STATUS = /* @__PURE__ */ ((STATUS2) => {
|
|
125
|
-
STATUS2[STATUS2["OK"] = 0] = "OK";
|
|
126
|
-
STATUS2[STATUS2["KEY_NOT_FOUND"] = 1] = "KEY_NOT_FOUND";
|
|
127
|
-
STATUS2[STATUS2["KEY_EXISTS"] = 2] = "KEY_EXISTS";
|
|
128
|
-
STATUS2[STATUS2["TOO_LARGE"] = 3] = "TOO_LARGE";
|
|
129
|
-
STATUS2[STATUS2["INVALID_ARGS"] = 4] = "INVALID_ARGS";
|
|
130
|
-
STATUS2[STATUS2["ITEM_NOT_STORED"] = 5] = "ITEM_NOT_STORED";
|
|
131
|
-
STATUS2[STATUS2["NON_NUMERIC_VALUE"] = 6] = "NON_NUMERIC_VALUE";
|
|
132
|
-
STATUS2[STATUS2["WRONG_VBUCKET"] = 7] = "WRONG_VBUCKET";
|
|
133
|
-
STATUS2[STATUS2["AUTH_ERROR"] = 8] = "AUTH_ERROR";
|
|
134
|
-
STATUS2[STATUS2["AUTH_CONTINUE"] = 9] = "AUTH_CONTINUE";
|
|
135
|
-
STATUS2[STATUS2["UNKNOWN_COMMAND"] = 129] = "UNKNOWN_COMMAND";
|
|
136
|
-
STATUS2[STATUS2["OUT_OF_MEMORY"] = 130] = "OUT_OF_MEMORY";
|
|
137
|
-
STATUS2[STATUS2["NOT_SUPPORTED"] = 131] = "NOT_SUPPORTED";
|
|
138
|
-
STATUS2[STATUS2["INTERNAL_ERROR"] = 132] = "INTERNAL_ERROR";
|
|
139
|
-
STATUS2[STATUS2["BUSY"] = 133] = "BUSY";
|
|
140
|
-
STATUS2[STATUS2["TEMPORARY_FAILURE"] = 134] = "TEMPORARY_FAILURE";
|
|
141
|
-
return STATUS2;
|
|
142
|
-
})(STATUS || {});
|
|
143
|
-
var OPCODE = /* @__PURE__ */ ((OPCODE3) => {
|
|
144
|
-
OPCODE3[OPCODE3["GET"] = 0] = "GET";
|
|
145
|
-
OPCODE3[OPCODE3["SET"] = 1] = "SET";
|
|
146
|
-
OPCODE3[OPCODE3["ADD"] = 2] = "ADD";
|
|
147
|
-
OPCODE3[OPCODE3["REPLACE"] = 3] = "REPLACE";
|
|
148
|
-
OPCODE3[OPCODE3["DELETE"] = 4] = "DELETE";
|
|
149
|
-
OPCODE3[OPCODE3["INCREMENT"] = 5] = "INCREMENT";
|
|
150
|
-
OPCODE3[OPCODE3["DECREMENT"] = 6] = "DECREMENT";
|
|
151
|
-
OPCODE3[OPCODE3["QUIT"] = 7] = "QUIT";
|
|
152
|
-
OPCODE3[OPCODE3["FLUSH"] = 8] = "FLUSH";
|
|
153
|
-
OPCODE3[OPCODE3["NOOP"] = 10] = "NOOP";
|
|
154
|
-
OPCODE3[OPCODE3["VERSION"] = 11] = "VERSION";
|
|
155
|
-
OPCODE3[OPCODE3["APPEND"] = 14] = "APPEND";
|
|
156
|
-
OPCODE3[OPCODE3["PREPEND"] = 15] = "PREPEND";
|
|
157
|
-
OPCODE3[OPCODE3["STAT"] = 16] = "STAT";
|
|
158
|
-
OPCODE3[OPCODE3["TOUCH"] = 28] = "TOUCH";
|
|
159
|
-
OPCODE3[OPCODE3["GAT"] = 29] = "GAT";
|
|
160
|
-
return OPCODE3;
|
|
161
|
-
})(OPCODE || {});
|
|
162
|
-
var DATA_TYPE = /* @__PURE__ */ ((DATA_TYPE2) => {
|
|
163
|
-
DATA_TYPE2[DATA_TYPE2["RAW"] = 0] = "RAW";
|
|
164
|
-
return DATA_TYPE2;
|
|
165
|
-
})(DATA_TYPE || {});
|
|
166
|
-
var VBUCKET = /* @__PURE__ */ ((VBUCKET2) => {
|
|
167
|
-
VBUCKET2[VBUCKET2["NIL"] = 0] = "NIL";
|
|
168
|
-
return VBUCKET2;
|
|
169
|
-
})(VBUCKET || {});
|
|
170
|
-
|
|
171
|
-
// src/buffers.ts
|
|
172
|
-
var pool = new Array(64 /* POOL_SIZE */);
|
|
173
|
-
var offset = -1;
|
|
174
|
-
function allocateBuffer(size) {
|
|
175
|
-
if (size > 8192 /* BUFFER_SIZE */) {
|
|
176
|
-
const buffer2 = Buffer.allocUnsafeSlow(size);
|
|
177
|
-
buffer2.recycle = () => void 0;
|
|
178
|
-
return buffer2;
|
|
179
|
-
}
|
|
180
|
-
const buffer = offset >= 0 ? pool[offset--] : Buffer.allocUnsafeSlow(8192 /* BUFFER_SIZE */);
|
|
181
|
-
const recyclable = buffer.subarray(0, size);
|
|
182
|
-
let recycled = false;
|
|
183
|
-
recyclable.recycle = () => queueMicrotask(() => {
|
|
184
|
-
if (offset >= 64 /* POOL_SIZE */ || recycled)
|
|
185
|
-
return;
|
|
186
|
-
pool[++offset] = buffer;
|
|
187
|
-
recycled = true;
|
|
188
|
-
});
|
|
189
|
-
return recyclable;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// src/decode.ts
|
|
193
|
-
var import_assert = __toESM(require("assert"));
|
|
194
|
-
var Decoder = class {
|
|
195
|
-
#consumer;
|
|
196
|
-
#header = Buffer.allocUnsafeSlow(24);
|
|
197
|
-
#body;
|
|
198
|
-
#pos = 0;
|
|
199
|
-
constructor(consumer) {
|
|
200
|
-
this.#consumer = consumer;
|
|
201
|
-
}
|
|
202
|
-
append(buffer, start, end) {
|
|
203
|
-
const header = this.#header;
|
|
204
|
-
while (start < end) {
|
|
205
|
-
if (this.#pos < 24) {
|
|
206
|
-
const copied = buffer.copy(header, this.#pos, start, end);
|
|
207
|
-
this.#pos += copied;
|
|
208
|
-
start += copied;
|
|
209
|
-
}
|
|
210
|
-
if (this.#pos < 24)
|
|
211
|
-
return;
|
|
212
|
-
let extras = EMPTY_BUFFER;
|
|
213
|
-
let key = EMPTY_BUFFER;
|
|
214
|
-
let value = EMPTY_BUFFER;
|
|
215
|
-
let recycle = () => void 0;
|
|
216
|
-
const bodyLength = header.readUInt32BE(8 /* BODY_LENGTH_$32 */);
|
|
217
|
-
if (bodyLength) {
|
|
218
|
-
const body = this.#body || (this.#body = allocateBuffer(bodyLength));
|
|
219
|
-
const copied = buffer.copy(body, this.#pos - 24, start, end);
|
|
220
|
-
this.#pos += copied;
|
|
221
|
-
start += copied;
|
|
222
|
-
if (this.#pos - 24 < body.length)
|
|
223
|
-
return;
|
|
224
|
-
const keyLength = header.readUInt16BE(2 /* KEY_LENGTH_$16 */);
|
|
225
|
-
const extrasLength = header.readUInt8(4 /* EXTRAS_LENGTH_$8 */);
|
|
226
|
-
const valueLength = bodyLength - keyLength - extrasLength;
|
|
227
|
-
key = keyLength ? body.subarray(extrasLength, extrasLength + keyLength) : EMPTY_BUFFER;
|
|
228
|
-
value = valueLength ? body.subarray(extrasLength + keyLength) : EMPTY_BUFFER;
|
|
229
|
-
extras = extrasLength ? body.subarray(0, extrasLength) : EMPTY_BUFFER;
|
|
230
|
-
recycle = () => void body.recycle();
|
|
231
|
-
}
|
|
232
|
-
const packet = {
|
|
233
|
-
opcode: header.readUInt8(1 /* OPCODE_$8 */),
|
|
234
|
-
status: header.readUInt16BE(6 /* STATUS_$16 */),
|
|
235
|
-
sequence: header.readUInt32BE(12 /* SEQUENCE_$32 */),
|
|
236
|
-
cas: header.readBigUInt64BE(16 /* CAS_$64 */),
|
|
237
|
-
extras,
|
|
238
|
-
key,
|
|
239
|
-
value,
|
|
240
|
-
recycle
|
|
241
|
-
};
|
|
242
|
-
const magic = header.readUInt8(0 /* MAGIC_$8 */);
|
|
243
|
-
const dataType = header.readUInt8(5 /* DATA_TYPE_$8 */);
|
|
244
|
-
import_assert.default.equal(magic, 129 /* RESPONSE */, "Invalid magic in header");
|
|
245
|
-
import_assert.default.equal(dataType, 0 /* RAW */, "Invalid data type in header");
|
|
246
|
-
this.#pos = 0;
|
|
247
|
-
this.#body = void 0;
|
|
248
|
-
this.#consumer(packet);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
// src/encode.ts
|
|
254
|
-
var encode_exports = {};
|
|
255
|
-
__export(encode_exports, {
|
|
256
|
-
Encoder: () => Encoder
|
|
257
|
-
});
|
|
258
|
-
var CONSTANTS = /* @__PURE__ */ ((CONSTANTS2) => {
|
|
259
|
-
CONSTANTS2[CONSTANTS2["HEADER_SIZE"] = 24] = "HEADER_SIZE";
|
|
260
|
-
return CONSTANTS2;
|
|
261
|
-
})(CONSTANTS || {});
|
|
262
|
-
var Encoder = class {
|
|
263
|
-
encode(packet, seq = 0) {
|
|
264
|
-
const {
|
|
265
|
-
opcode,
|
|
266
|
-
sequence = seq,
|
|
267
|
-
cas = 0n,
|
|
268
|
-
extras = EMPTY_BUFFER,
|
|
269
|
-
extrasOffset = 0,
|
|
270
|
-
extrasLength = extras.length,
|
|
271
|
-
key = EMPTY_BUFFER,
|
|
272
|
-
keyOffset = 0,
|
|
273
|
-
keyLength = key.length,
|
|
274
|
-
value = EMPTY_BUFFER,
|
|
275
|
-
valueOffset = 0,
|
|
276
|
-
valueLength = value.length
|
|
277
|
-
} = packet;
|
|
278
|
-
const bodyLength = extrasLength + keyLength + valueLength;
|
|
279
|
-
const length = bodyLength + 24 /* HEADER_SIZE */;
|
|
280
|
-
const buffer = allocateBuffer(length);
|
|
281
|
-
buffer.writeUInt8(128 /* REQUEST */, 0 /* MAGIC_$8 */);
|
|
282
|
-
buffer.writeUInt8(opcode, 1 /* OPCODE_$8 */);
|
|
283
|
-
buffer.writeUInt16BE(keyLength, 2 /* KEY_LENGTH_$16 */);
|
|
284
|
-
buffer.writeUInt8(extrasLength, 4 /* EXTRAS_LENGTH_$8 */);
|
|
285
|
-
buffer.writeUInt8(0 /* RAW */, 5 /* DATA_TYPE_$8 */);
|
|
286
|
-
buffer.writeUInt16BE(0 /* NIL */, 6 /* STATUS_$16 */);
|
|
287
|
-
buffer.writeUInt32BE(bodyLength, 8 /* BODY_LENGTH_$32 */);
|
|
288
|
-
buffer.writeUInt32BE(sequence, 12 /* SEQUENCE_$32 */);
|
|
289
|
-
buffer.writeBigUInt64BE(cas, 16 /* CAS_$64 */);
|
|
290
|
-
let pos = 24;
|
|
291
|
-
if (extrasLength)
|
|
292
|
-
pos += extras.copy(buffer, pos, extrasOffset, extrasOffset + extrasLength);
|
|
293
|
-
if (keyLength)
|
|
294
|
-
pos += key.copy(buffer, pos, keyOffset, keyOffset + keyLength);
|
|
295
|
-
if (valueLength)
|
|
296
|
-
pos += value.copy(buffer, pos, valueOffset, valueOffset + valueLength);
|
|
297
|
-
return buffer;
|
|
298
|
-
}
|
|
299
|
-
};
|
|
300
|
-
|
|
301
|
-
// src/connection.ts
|
|
302
|
-
var connection_exports = {};
|
|
303
|
-
__export(connection_exports, {
|
|
304
|
-
Connection: () => Connection
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
// src/internals.ts
|
|
308
|
-
var import_assert2 = __toESM(require("assert"));
|
|
309
|
-
var import_util = require("util");
|
|
310
|
-
var socketFinalizationRegistry = new FinalizationRegistry((socket) => {
|
|
311
|
-
if (!socket.destroyed)
|
|
312
|
-
socket.destroy();
|
|
313
|
-
});
|
|
314
|
-
function typedArrayFlags(value) {
|
|
315
|
-
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");
|
|
316
|
-
return flags;
|
|
317
|
-
}
|
|
318
|
-
function logPromiseError(promise, message) {
|
|
319
|
-
return promise.catch((error) => console.log(message, error)).then(() => void 0);
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// src/connection.ts
|
|
323
|
-
var import_assert3 = __toESM(require("assert"));
|
|
324
|
-
var import_net = __toESM(require("net"));
|
|
325
|
-
var Deferred = class {
|
|
326
|
-
#resolve;
|
|
327
|
-
#reject;
|
|
328
|
-
#packets = [];
|
|
329
|
-
promise;
|
|
330
|
-
opcode;
|
|
331
|
-
constructor(opcode) {
|
|
332
|
-
this.opcode = opcode;
|
|
333
|
-
this.promise = new Promise((resolve, reject) => {
|
|
334
|
-
this.#resolve = resolve;
|
|
335
|
-
this.#reject = reject;
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
append(packet) {
|
|
339
|
-
this.#packets.push(packet);
|
|
340
|
-
}
|
|
341
|
-
resolve(packet) {
|
|
342
|
-
this.#packets.push(packet);
|
|
343
|
-
this.#resolve(this.#packets);
|
|
344
|
-
}
|
|
345
|
-
reject(error) {
|
|
346
|
-
this.#reject(error);
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
|
-
var Connection = class {
|
|
350
|
-
#decoder = new Decoder((packet) => this.#receive(packet));
|
|
351
|
-
#encoder = new Encoder();
|
|
352
|
-
#buffer = Buffer.allocUnsafeSlow(8192 /* BUFFER_SIZE */);
|
|
353
|
-
#defers = /* @__PURE__ */ new Map();
|
|
354
|
-
#factory;
|
|
355
|
-
#socket;
|
|
356
|
-
#sequence = 0;
|
|
357
|
-
#timeout;
|
|
358
|
-
#host;
|
|
359
|
-
#port;
|
|
360
|
-
constructor(options) {
|
|
361
|
-
(0, import_assert3.default)(options, "No options specified");
|
|
362
|
-
const {
|
|
363
|
-
host,
|
|
364
|
-
port = 11211,
|
|
365
|
-
timeout = 1e3,
|
|
366
|
-
factory = import_net.default.connect
|
|
367
|
-
} = options;
|
|
368
|
-
this.#factory = factory;
|
|
369
|
-
(0, import_assert3.default)(host, "No host name specified");
|
|
370
|
-
(0, import_assert3.default)(port > 0 && port < 65536 && Math.floor(port) == port, `Invalid port ${port}`);
|
|
371
|
-
this.#timeout = timeout;
|
|
372
|
-
this.#host = host;
|
|
373
|
-
this.#port = port;
|
|
374
|
-
}
|
|
375
|
-
get connected() {
|
|
376
|
-
return !!this.#socket;
|
|
377
|
-
}
|
|
378
|
-
get host() {
|
|
379
|
-
return this.#host;
|
|
380
|
-
}
|
|
381
|
-
get port() {
|
|
382
|
-
return this.#port;
|
|
383
|
-
}
|
|
384
|
-
get timeout() {
|
|
385
|
-
return this.#timeout;
|
|
386
|
-
}
|
|
387
|
-
#connect() {
|
|
388
|
-
return this.#socket || (this.#socket = new Promise((resolve, reject) => {
|
|
389
|
-
const socket = this.#factory({
|
|
390
|
-
host: this.#host,
|
|
391
|
-
port: this.#port,
|
|
392
|
-
timeout: this.#timeout,
|
|
393
|
-
onread: {
|
|
394
|
-
buffer: this.#buffer,
|
|
395
|
-
callback: (bytes, buffer) => {
|
|
396
|
-
this.#decoder.append(buffer, 0, bytes);
|
|
397
|
-
return true;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
});
|
|
401
|
-
socket.on("timeout", () => socket.destroy(new Error("Timeout")));
|
|
402
|
-
socket.on("error", reject);
|
|
403
|
-
socket.on("close", () => {
|
|
404
|
-
socketFinalizationRegistry.unregister(this);
|
|
405
|
-
this.#socket = void 0;
|
|
406
|
-
});
|
|
407
|
-
socket.on("connect", () => {
|
|
408
|
-
socketFinalizationRegistry.register(this, socket, this);
|
|
409
|
-
socket.off("error", reject);
|
|
410
|
-
socket.on("error", (error) => {
|
|
411
|
-
for (const deferred of this.#defers.values()) {
|
|
412
|
-
process.nextTick(() => deferred.reject(error));
|
|
413
|
-
}
|
|
414
|
-
this.#defers.clear();
|
|
415
|
-
this.#socket = void 0;
|
|
416
|
-
});
|
|
417
|
-
socket.unref();
|
|
418
|
-
resolve(socket);
|
|
419
|
-
});
|
|
420
|
-
}));
|
|
421
|
-
}
|
|
422
|
-
#receive(packet) {
|
|
423
|
-
const deferred = this.#defers.get(packet.sequence);
|
|
424
|
-
if (deferred) {
|
|
425
|
-
if (deferred.opcode === packet.opcode) {
|
|
426
|
-
if (packet.opcode === 16 /* STAT */ && packet.key.length !== 0) {
|
|
427
|
-
return deferred.append(packet);
|
|
428
|
-
}
|
|
429
|
-
return deferred.resolve(packet);
|
|
430
|
-
} else {
|
|
431
|
-
const sent = `0x${deferred.opcode.toString(16).padStart(2, "0")}`;
|
|
432
|
-
const received = `0x${packet.opcode.toString(16).padStart(2, "0")}`;
|
|
433
|
-
return deferred.reject(new Error(`Opcode mismatch (sent=${sent}, received=${received})`));
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
async send(packet) {
|
|
438
|
-
const sequence = ++this.#sequence;
|
|
439
|
-
const buffer = this.#encoder.encode(packet, sequence);
|
|
440
|
-
const deferred = new Deferred(packet.opcode);
|
|
441
|
-
this.#defers.set(sequence, deferred);
|
|
442
|
-
const socket = await this.#connect();
|
|
443
|
-
socket.write(buffer, (error) => {
|
|
444
|
-
buffer.recycle();
|
|
445
|
-
if (error)
|
|
446
|
-
return deferred.reject(error);
|
|
447
|
-
});
|
|
448
|
-
const timeout = setTimeout(() => deferred.reject(new Error("No response")), this.#timeout);
|
|
449
|
-
return deferred.promise.finally(() => {
|
|
450
|
-
clearTimeout(timeout);
|
|
451
|
-
this.#defers.delete(sequence);
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
async destroy() {
|
|
455
|
-
const socket = await this.#socket;
|
|
456
|
-
if (!socket)
|
|
457
|
-
return false;
|
|
458
|
-
return new Promise((resolve, reject) => {
|
|
459
|
-
socket.once("error", reject).once("close", resolve).destroy();
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
};
|
|
463
|
-
|
|
464
|
-
// src/server.ts
|
|
465
|
-
var statsBigInt = [
|
|
466
|
-
"auth_cmds",
|
|
467
|
-
"auth_errors",
|
|
468
|
-
"bytes",
|
|
469
|
-
"bytes_read",
|
|
470
|
-
"bytes_written",
|
|
471
|
-
"cas_badval",
|
|
472
|
-
"cas_hits",
|
|
473
|
-
"cas_misses",
|
|
474
|
-
"cmd_flush",
|
|
475
|
-
"cmd_get",
|
|
476
|
-
"cmd_set",
|
|
477
|
-
"cmd_touch",
|
|
478
|
-
"conn_yields",
|
|
479
|
-
"crawler_items_checked",
|
|
480
|
-
"crawler_reclaimed",
|
|
481
|
-
"curr_items",
|
|
482
|
-
"decr_hits",
|
|
483
|
-
"decr_misses",
|
|
484
|
-
"delete_hits",
|
|
485
|
-
"delete_misses",
|
|
486
|
-
"direct_reclaims",
|
|
487
|
-
"evicted_active",
|
|
488
|
-
"evicted_unfetched",
|
|
489
|
-
"evictions",
|
|
490
|
-
"expired_unfetched",
|
|
491
|
-
"get_expired",
|
|
492
|
-
"get_flushed",
|
|
493
|
-
"get_hits",
|
|
494
|
-
"get_misses",
|
|
495
|
-
"hash_bytes",
|
|
496
|
-
"idle_kicks",
|
|
497
|
-
"incr_hits",
|
|
498
|
-
"incr_misses",
|
|
499
|
-
"limit_maxbytes",
|
|
500
|
-
"listen_disabled_num",
|
|
501
|
-
"log_watcher_sent",
|
|
502
|
-
"log_watcher_skipped",
|
|
503
|
-
"log_watchers",
|
|
504
|
-
"log_worker_dropped",
|
|
505
|
-
"log_worker_written",
|
|
506
|
-
"lru_crawler_running",
|
|
507
|
-
"lru_crawler_starts",
|
|
508
|
-
"lru_maintainer_juggles",
|
|
509
|
-
"lrutail_reflocked",
|
|
510
|
-
"malloc_fails",
|
|
511
|
-
"moves_to_cold",
|
|
512
|
-
"moves_to_warm",
|
|
513
|
-
"moves_within_lru",
|
|
514
|
-
"read_buf_bytes",
|
|
515
|
-
"read_buf_bytes_free",
|
|
516
|
-
"read_buf_count",
|
|
517
|
-
"read_buf_oom",
|
|
518
|
-
"reclaimed",
|
|
519
|
-
"rejected_connections",
|
|
520
|
-
"response_obj_bytes",
|
|
521
|
-
"response_obj_count",
|
|
522
|
-
"response_obj_oom",
|
|
523
|
-
"round_robin_fallback",
|
|
524
|
-
"slab_reassign_busy_deletes",
|
|
525
|
-
"slab_reassign_busy_items",
|
|
526
|
-
"slab_reassign_chunk_rescues",
|
|
527
|
-
"slab_reassign_evictions_nomem",
|
|
528
|
-
"slab_reassign_inline_reclaim",
|
|
529
|
-
"slab_reassign_rescues",
|
|
530
|
-
"slabs_moved",
|
|
531
|
-
"store_no_memory",
|
|
532
|
-
"store_too_large",
|
|
533
|
-
"time_in_listen_disabled_us",
|
|
534
|
-
"total_items",
|
|
535
|
-
"touch_hits",
|
|
536
|
-
"touch_misses",
|
|
537
|
-
"unexpected_napi_ids"
|
|
538
|
-
];
|
|
539
|
-
var statsNumber = [
|
|
540
|
-
"connection_structures",
|
|
541
|
-
"curr_connections",
|
|
542
|
-
"hash_power_level",
|
|
543
|
-
"max_connections",
|
|
544
|
-
"pid",
|
|
545
|
-
"pointer_size",
|
|
546
|
-
"reserved_fds",
|
|
547
|
-
"slab_global_page_pool",
|
|
548
|
-
"threads",
|
|
549
|
-
"time",
|
|
550
|
-
"total_connections",
|
|
551
|
-
"uptime"
|
|
552
|
-
];
|
|
553
|
-
var statsBoolean = ["accepting_conns", "hash_is_expanding", "slab_reassign_running"];
|
|
554
|
-
var statsMicroseconds = ["rusage_system", "rusage_user"];
|
|
555
|
-
function injectStats(key, value, stats) {
|
|
556
|
-
if (!key)
|
|
557
|
-
return stats;
|
|
558
|
-
if (statsBigInt.includes(key)) {
|
|
559
|
-
stats[key] = BigInt(value);
|
|
560
|
-
} else if (statsNumber.includes(key)) {
|
|
561
|
-
stats[key] = Number(value);
|
|
562
|
-
} else if (statsBoolean.includes(key)) {
|
|
563
|
-
stats[key] = !!Number(value);
|
|
564
|
-
} else if (statsMicroseconds.includes(key)) {
|
|
565
|
-
const splits = value.split(".");
|
|
566
|
-
stats[key] = BigInt(`${splits[0]}${splits[1].padEnd(6, "0")}`);
|
|
567
|
-
} else {
|
|
568
|
-
stats[key] = value;
|
|
569
|
-
}
|
|
570
|
-
return stats;
|
|
571
|
-
}
|
|
572
|
-
function fail(packet, key) {
|
|
573
|
-
const message = packet.value.toString("utf-8") || "Unknown Error";
|
|
574
|
-
const status = STATUS[packet.status] || `0x${packet.status.toString(16).padStart(4, "0")}`;
|
|
575
|
-
throw new Error(`${message} (status=${status}${key ? `, key=${key}` : ""})`);
|
|
576
|
-
}
|
|
577
|
-
var ServerAdapter = class {
|
|
578
|
-
#buffer = Buffer.alloc(251 /* KEY_TOO_BIG */ + 20);
|
|
579
|
-
#connection;
|
|
580
|
-
#ttl;
|
|
581
|
-
#id;
|
|
582
|
-
constructor(options) {
|
|
583
|
-
this.#connection = new Connection(options);
|
|
584
|
-
this.#ttl = options.ttl || 0;
|
|
585
|
-
this.#id = `${this.#connection.host}:${this.#connection.port}`;
|
|
586
|
-
}
|
|
587
|
-
get connected() {
|
|
588
|
-
return this.#connection.connected;
|
|
589
|
-
}
|
|
590
|
-
get host() {
|
|
591
|
-
return this.#connection.host;
|
|
592
|
-
}
|
|
593
|
-
get port() {
|
|
594
|
-
return this.#connection.port;
|
|
595
|
-
}
|
|
596
|
-
get timeout() {
|
|
597
|
-
return this.#connection.timeout;
|
|
598
|
-
}
|
|
599
|
-
get ttl() {
|
|
600
|
-
return this.#ttl;
|
|
601
|
-
}
|
|
602
|
-
get id() {
|
|
603
|
-
return this.#id;
|
|
604
|
-
}
|
|
605
|
-
#writeKey(key, offset2 = 0) {
|
|
606
|
-
const keyLength = this.#buffer.write(key, offset2, 251 /* KEY_TOO_BIG */, "utf-8");
|
|
607
|
-
if (keyLength > 250 /* KEY_SIZE */)
|
|
608
|
-
throw new Error(`Key too long (len=${keyLength})`);
|
|
609
|
-
return keyLength;
|
|
610
|
-
}
|
|
611
|
-
async #get(key, ttl) {
|
|
612
|
-
let keyOffset = 0;
|
|
613
|
-
if (ttl !== void 0)
|
|
614
|
-
keyOffset = this.#buffer.writeUInt32BE(ttl);
|
|
615
|
-
const keyLength = this.#writeKey(key, keyOffset);
|
|
616
|
-
const [response] = await this.#connection.send({
|
|
617
|
-
opcode: ttl ? 29 /* GAT */ : 0 /* GET */,
|
|
618
|
-
extras: this.#buffer,
|
|
619
|
-
extrasOffset: 0,
|
|
620
|
-
extrasLength: keyOffset,
|
|
621
|
-
key: this.#buffer,
|
|
622
|
-
keyOffset,
|
|
623
|
-
keyLength
|
|
624
|
-
});
|
|
625
|
-
switch (response.status) {
|
|
626
|
-
case 0 /* OK */:
|
|
627
|
-
return {
|
|
628
|
-
value: response.value,
|
|
629
|
-
flags: response.extras.readUInt32BE(),
|
|
630
|
-
cas: response.cas,
|
|
631
|
-
recycle: () => response.recycle()
|
|
632
|
-
};
|
|
633
|
-
case 1 /* KEY_NOT_FOUND */:
|
|
634
|
-
return;
|
|
635
|
-
default:
|
|
636
|
-
fail(response, key);
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
async get(key) {
|
|
640
|
-
return this.#get(key);
|
|
641
|
-
}
|
|
642
|
-
async gat(key, ttl) {
|
|
643
|
-
return this.#get(key, ttl || 2592e3);
|
|
644
|
-
}
|
|
645
|
-
async touch(key, ttl) {
|
|
646
|
-
const timeToLive = ttl ?? this.#ttl;
|
|
647
|
-
const keyOffset = this.#buffer.writeUInt32BE(timeToLive);
|
|
648
|
-
const keyLength = this.#writeKey(key, keyOffset);
|
|
649
|
-
const [response] = await this.#connection.send({
|
|
650
|
-
opcode: 28 /* TOUCH */,
|
|
651
|
-
extras: this.#buffer,
|
|
652
|
-
extrasOffset: 0,
|
|
653
|
-
extrasLength: keyOffset,
|
|
654
|
-
key: this.#buffer,
|
|
655
|
-
keyOffset,
|
|
656
|
-
keyLength
|
|
657
|
-
});
|
|
658
|
-
try {
|
|
659
|
-
switch (response.status) {
|
|
660
|
-
case 0 /* OK */:
|
|
661
|
-
return true;
|
|
662
|
-
case 1 /* KEY_NOT_FOUND */:
|
|
663
|
-
return false;
|
|
664
|
-
default:
|
|
665
|
-
fail(response, key);
|
|
666
|
-
}
|
|
667
|
-
} finally {
|
|
668
|
-
response.recycle();
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
async #sar(opcode, key, value, options) {
|
|
672
|
-
const { flags = 0, cas = 0n, ttl = this.#ttl } = options;
|
|
673
|
-
let keyOffset;
|
|
674
|
-
keyOffset = this.#buffer.writeUInt32BE(flags);
|
|
675
|
-
keyOffset = this.#buffer.writeUInt32BE(ttl, keyOffset);
|
|
676
|
-
const keyLength = this.#writeKey(key, keyOffset);
|
|
677
|
-
const [response] = await this.#connection.send({
|
|
678
|
-
opcode,
|
|
679
|
-
cas,
|
|
680
|
-
extras: this.#buffer,
|
|
681
|
-
extrasOffset: 0,
|
|
682
|
-
extrasLength: keyOffset,
|
|
683
|
-
key: this.#buffer,
|
|
684
|
-
keyOffset,
|
|
685
|
-
keyLength,
|
|
686
|
-
value
|
|
687
|
-
});
|
|
688
|
-
try {
|
|
689
|
-
switch (response.status) {
|
|
690
|
-
case 0 /* OK */:
|
|
691
|
-
return response.cas;
|
|
692
|
-
case 1 /* KEY_NOT_FOUND */:
|
|
693
|
-
case 2 /* KEY_EXISTS */:
|
|
694
|
-
return;
|
|
695
|
-
default:
|
|
696
|
-
fail(response, key);
|
|
697
|
-
}
|
|
698
|
-
} finally {
|
|
699
|
-
response.recycle();
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
set(key, value, options = {}) {
|
|
703
|
-
return this.#sar(1 /* SET */, key, value, options);
|
|
704
|
-
}
|
|
705
|
-
add(key, value, options = {}) {
|
|
706
|
-
return this.#sar(2 /* ADD */, key, value, options);
|
|
707
|
-
}
|
|
708
|
-
replace(key, value, options = {}) {
|
|
709
|
-
return this.#sar(3 /* REPLACE */, key, value, options);
|
|
710
|
-
}
|
|
711
|
-
async #pend(opcode, key, value, options) {
|
|
712
|
-
const { cas = 0n } = options;
|
|
713
|
-
const keyLength = this.#writeKey(key);
|
|
714
|
-
const [response] = await this.#connection.send({
|
|
715
|
-
opcode,
|
|
716
|
-
cas,
|
|
717
|
-
key: Buffer.from(key, "utf-8"),
|
|
718
|
-
keyOffset: 0,
|
|
719
|
-
keyLength,
|
|
720
|
-
value
|
|
721
|
-
});
|
|
722
|
-
try {
|
|
723
|
-
switch (response.status) {
|
|
724
|
-
case 0 /* OK */:
|
|
725
|
-
return true;
|
|
726
|
-
case 5 /* ITEM_NOT_STORED */:
|
|
727
|
-
case 2 /* KEY_EXISTS */:
|
|
728
|
-
return false;
|
|
729
|
-
default:
|
|
730
|
-
fail(response, key);
|
|
731
|
-
}
|
|
732
|
-
} finally {
|
|
733
|
-
response.recycle();
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
append(key, value, options = {}) {
|
|
737
|
-
return this.#pend(14 /* APPEND */, key, value, options);
|
|
738
|
-
}
|
|
739
|
-
prepend(key, value, options = {}) {
|
|
740
|
-
return this.#pend(15 /* PREPEND */, key, value, options);
|
|
741
|
-
}
|
|
742
|
-
async #counter(opcode, key, delta, options) {
|
|
743
|
-
const {
|
|
744
|
-
initial,
|
|
745
|
-
cas = 0n,
|
|
746
|
-
ttl = this.#ttl
|
|
747
|
-
} = options;
|
|
748
|
-
let keyOffset;
|
|
749
|
-
keyOffset = this.#buffer.writeBigUInt64BE(BigInt(delta));
|
|
750
|
-
keyOffset = this.#buffer.writeBigUInt64BE(BigInt(initial || 0n), keyOffset);
|
|
751
|
-
keyOffset = this.#buffer.writeUInt32BE(initial == void 0 ? 4294967295 : ttl, keyOffset);
|
|
752
|
-
const keyLength = this.#writeKey(key, keyOffset);
|
|
753
|
-
const [response] = await this.#connection.send({
|
|
754
|
-
opcode,
|
|
755
|
-
extras: this.#buffer,
|
|
756
|
-
extrasOffset: 0,
|
|
757
|
-
extrasLength: keyOffset,
|
|
758
|
-
key: this.#buffer,
|
|
759
|
-
keyOffset,
|
|
760
|
-
keyLength,
|
|
761
|
-
cas
|
|
762
|
-
});
|
|
763
|
-
try {
|
|
764
|
-
switch (response.status) {
|
|
765
|
-
case 0 /* OK */:
|
|
766
|
-
return {
|
|
767
|
-
value: response.value.readBigUInt64BE(0),
|
|
768
|
-
cas: response.cas
|
|
769
|
-
};
|
|
770
|
-
case 1 /* KEY_NOT_FOUND */:
|
|
771
|
-
case 2 /* KEY_EXISTS */:
|
|
772
|
-
return;
|
|
773
|
-
default:
|
|
774
|
-
fail(response, key);
|
|
775
|
-
}
|
|
776
|
-
} finally {
|
|
777
|
-
response.recycle();
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
increment(key, delta = 1, options = {}) {
|
|
781
|
-
return this.#counter(5 /* INCREMENT */, key, delta, options);
|
|
782
|
-
}
|
|
783
|
-
decrement(key, delta = 1, options = {}) {
|
|
784
|
-
return this.#counter(6 /* DECREMENT */, key, delta, options);
|
|
785
|
-
}
|
|
786
|
-
async delete(key, options = {}) {
|
|
787
|
-
const { cas = 0n } = options;
|
|
788
|
-
const keyLength = this.#writeKey(key);
|
|
789
|
-
const [response] = await this.#connection.send({
|
|
790
|
-
opcode: 4 /* DELETE */,
|
|
791
|
-
key: this.#buffer,
|
|
792
|
-
keyOffset: 0,
|
|
793
|
-
keyLength,
|
|
794
|
-
cas
|
|
795
|
-
});
|
|
796
|
-
try {
|
|
797
|
-
switch (response.status) {
|
|
798
|
-
case 0 /* OK */:
|
|
799
|
-
return true;
|
|
800
|
-
case 1 /* KEY_NOT_FOUND */:
|
|
801
|
-
case 2 /* KEY_EXISTS */:
|
|
802
|
-
return false;
|
|
803
|
-
default:
|
|
804
|
-
fail(response, key);
|
|
805
|
-
}
|
|
806
|
-
} finally {
|
|
807
|
-
response.recycle();
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
async flush(ttl = 0) {
|
|
811
|
-
const extrasLength = ttl ? this.#buffer.writeUInt32BE(ttl) : 0;
|
|
812
|
-
const [response] = await this.#connection.send({
|
|
813
|
-
opcode: 8 /* FLUSH */,
|
|
814
|
-
extras: this.#buffer,
|
|
815
|
-
extrasOffset: 0,
|
|
816
|
-
extrasLength
|
|
817
|
-
});
|
|
818
|
-
try {
|
|
819
|
-
switch (response.status) {
|
|
820
|
-
case 0 /* OK */:
|
|
821
|
-
return;
|
|
822
|
-
default:
|
|
823
|
-
fail(response);
|
|
824
|
-
}
|
|
825
|
-
} finally {
|
|
826
|
-
response.recycle();
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
async noop() {
|
|
830
|
-
const [response] = await this.#connection.send({
|
|
831
|
-
opcode: 10 /* NOOP */
|
|
832
|
-
});
|
|
833
|
-
try {
|
|
834
|
-
switch (response.status) {
|
|
835
|
-
case 0 /* OK */:
|
|
836
|
-
return;
|
|
837
|
-
default:
|
|
838
|
-
fail(response);
|
|
839
|
-
}
|
|
840
|
-
} finally {
|
|
841
|
-
response.recycle();
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
async quit() {
|
|
845
|
-
const [response] = await this.#connection.send({
|
|
846
|
-
opcode: 7 /* QUIT */
|
|
847
|
-
});
|
|
848
|
-
try {
|
|
849
|
-
switch (response.status) {
|
|
850
|
-
case 0 /* OK */:
|
|
851
|
-
return;
|
|
852
|
-
default:
|
|
853
|
-
fail(response);
|
|
854
|
-
}
|
|
855
|
-
} finally {
|
|
856
|
-
response.recycle();
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
async version() {
|
|
860
|
-
const [response] = await this.#connection.send({
|
|
861
|
-
opcode: 11 /* VERSION */
|
|
862
|
-
});
|
|
863
|
-
try {
|
|
864
|
-
switch (response.status) {
|
|
865
|
-
case 0 /* OK */:
|
|
866
|
-
return { [this.#id]: response.value.toString("utf-8") };
|
|
867
|
-
default:
|
|
868
|
-
fail(response);
|
|
869
|
-
}
|
|
870
|
-
} finally {
|
|
871
|
-
response.recycle();
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
async stats() {
|
|
875
|
-
const responses = await this.#connection.send({
|
|
876
|
-
opcode: 16 /* STAT */
|
|
877
|
-
});
|
|
878
|
-
const stats = responses.reduce((result, packet) => {
|
|
879
|
-
try {
|
|
880
|
-
if (packet.status !== 0 /* OK */)
|
|
881
|
-
fail(packet);
|
|
882
|
-
const key = packet.key.toString("utf-8");
|
|
883
|
-
const value = packet.value.toString("utf-8");
|
|
884
|
-
return injectStats(key, value, result);
|
|
885
|
-
} finally {
|
|
886
|
-
packet.recycle();
|
|
887
|
-
}
|
|
888
|
-
}, {});
|
|
889
|
-
return { [this.#id]: stats };
|
|
890
|
-
}
|
|
891
|
-
};
|
|
892
|
-
|
|
893
|
-
// src/cluster.ts
|
|
894
|
-
var import_assert4 = __toESM(require("assert"));
|
|
895
|
-
function parseHosts(hosts) {
|
|
896
|
-
const result = [];
|
|
897
|
-
if (!hosts)
|
|
898
|
-
return result;
|
|
899
|
-
for (const part of hosts.split(",")) {
|
|
900
|
-
const [host, p] = part.split(":");
|
|
901
|
-
const port = parseInt(p) || void 0;
|
|
902
|
-
result.push({ host, port });
|
|
903
|
-
}
|
|
904
|
-
return result;
|
|
905
|
-
}
|
|
906
|
-
var ClusterAdapter = class {
|
|
907
|
-
servers;
|
|
908
|
-
ttl;
|
|
909
|
-
constructor(serversOrOptions) {
|
|
910
|
-
if (Array.isArray(serversOrOptions)) {
|
|
911
|
-
this.servers = [...serversOrOptions];
|
|
912
|
-
} else if (serversOrOptions) {
|
|
913
|
-
const { ttl, timeout, hosts: defs } = serversOrOptions;
|
|
914
|
-
const hosts = [];
|
|
915
|
-
if (Array.isArray(defs)) {
|
|
916
|
-
defs.forEach((def) => {
|
|
917
|
-
if (typeof def === "string")
|
|
918
|
-
hosts.push(...parseHosts(def));
|
|
919
|
-
else
|
|
920
|
-
hosts.push(__spreadValues({ port: 11211 }, def));
|
|
921
|
-
});
|
|
922
|
-
} else {
|
|
923
|
-
hosts.push(...parseHosts(defs));
|
|
924
|
-
}
|
|
925
|
-
this.servers = hosts.map((host) => new ServerAdapter(__spreadValues({ ttl, timeout }, host)));
|
|
926
|
-
} else {
|
|
927
|
-
const hosts = parseHosts(process.env.MEMCACHED_HOSTS);
|
|
928
|
-
const ttl = process.env.MEMCACHED_TTL && parseInt(process.env.MEMCACHED_TTL) || void 0;
|
|
929
|
-
const timeout = process.env.MEMCACHED_TIMEOUT && parseInt(process.env.MEMCACHED_TIMEOUT) || void 0;
|
|
930
|
-
this.servers = hosts.map((host) => new ServerAdapter(__spreadValues({ ttl, timeout }, host)));
|
|
931
|
-
}
|
|
932
|
-
if (this.servers.length < 1)
|
|
933
|
-
throw new Error("No hosts configured");
|
|
934
|
-
if (this.servers.length === 1)
|
|
935
|
-
this.server = () => this.servers[0];
|
|
936
|
-
this.ttl = this.servers[0].ttl;
|
|
937
|
-
this.servers.slice(1).forEach((server) => {
|
|
938
|
-
import_assert4.default.equal(server.ttl, this.ttl, `TTL Mismatch (${server.ttl} != ${this.ttl})`);
|
|
939
|
-
});
|
|
940
|
-
Object.freeze(this.servers);
|
|
941
|
-
}
|
|
942
|
-
server(key) {
|
|
943
|
-
const length = key.length;
|
|
944
|
-
let hash = 0;
|
|
945
|
-
for (let i = 0; i < length; i++)
|
|
946
|
-
hash = hash * 31 + key.charCodeAt(i);
|
|
947
|
-
return this.servers[hash % this.servers.length];
|
|
948
|
-
}
|
|
949
|
-
get(key) {
|
|
950
|
-
return this.server(key).get(key);
|
|
951
|
-
}
|
|
952
|
-
gat(key, ttl) {
|
|
953
|
-
return this.server(key).gat(key, ttl);
|
|
954
|
-
}
|
|
955
|
-
touch(key, ttl) {
|
|
956
|
-
return this.server(key).touch(key, ttl);
|
|
957
|
-
}
|
|
958
|
-
set(key, value, options) {
|
|
959
|
-
return this.server(key).set(key, value, options);
|
|
960
|
-
}
|
|
961
|
-
add(key, value, options) {
|
|
962
|
-
return this.server(key).add(key, value, options);
|
|
963
|
-
}
|
|
964
|
-
replace(key, value, options) {
|
|
965
|
-
return this.server(key).replace(key, value, options);
|
|
966
|
-
}
|
|
967
|
-
append(key, value, options) {
|
|
968
|
-
return this.server(key).append(key, value, options);
|
|
969
|
-
}
|
|
970
|
-
prepend(key, value, options) {
|
|
971
|
-
return this.server(key).prepend(key, value, options);
|
|
972
|
-
}
|
|
973
|
-
increment(key, delta, options) {
|
|
974
|
-
return this.server(key).increment(key, delta, options);
|
|
975
|
-
}
|
|
976
|
-
decrement(key, delta, options) {
|
|
977
|
-
return this.server(key).decrement(key, delta, options);
|
|
978
|
-
}
|
|
979
|
-
delete(key, options) {
|
|
980
|
-
return this.server(key).delete(key, options);
|
|
981
|
-
}
|
|
982
|
-
async flush(ttl) {
|
|
983
|
-
await Promise.all(this.servers.map((server) => server.flush(ttl)));
|
|
984
|
-
}
|
|
985
|
-
async noop() {
|
|
986
|
-
await Promise.all(this.servers.map((server) => server.noop()));
|
|
987
|
-
}
|
|
988
|
-
async quit() {
|
|
989
|
-
await Promise.all(this.servers.map((server) => server.quit()));
|
|
990
|
-
}
|
|
991
|
-
async version() {
|
|
992
|
-
const versions = await Promise.all(this.servers.map((server) => server.version()));
|
|
993
|
-
return versions.reduce((v1, v2) => __spreadValues(__spreadValues({}, v1), v2));
|
|
994
|
-
}
|
|
995
|
-
async stats() {
|
|
996
|
-
const stats = await Promise.all(this.servers.map((server) => server.stats()));
|
|
997
|
-
return stats.reduce((v1, v2) => __spreadValues(__spreadValues({}, v1), v2));
|
|
998
|
-
}
|
|
999
|
-
};
|
|
1000
|
-
|
|
1001
|
-
// src/client.ts
|
|
1002
|
-
var import_assert5 = __toESM(require("assert"));
|
|
1003
|
-
var import_util2 = require("util");
|
|
1004
|
-
function replacer(key, value) {
|
|
1005
|
-
if (typeof this[key] === "bigint")
|
|
1006
|
-
return ["\0__$BIGINT$__\0", this[key].toString()];
|
|
1007
|
-
if (this[key] instanceof Date)
|
|
1008
|
-
return ["\0__$DATE$__\0", this[key].toISOString()];
|
|
1009
|
-
if (this[key] instanceof Set)
|
|
1010
|
-
return ["\0__$SET$__\0", ...value];
|
|
1011
|
-
if (this[key] instanceof Map)
|
|
1012
|
-
return ["\0__$MAP$__\0", ...value.entries()];
|
|
1013
|
-
return value;
|
|
1014
|
-
}
|
|
1015
|
-
function reviver(key, value) {
|
|
1016
|
-
if (Array.isArray(value)) {
|
|
1017
|
-
switch (value[0]) {
|
|
1018
|
-
case "\0__$BIGINT$__\0":
|
|
1019
|
-
return BigInt(value[1]);
|
|
1020
|
-
case "\0__$DATE$__\0":
|
|
1021
|
-
return new Date(value[1]);
|
|
1022
|
-
case "\0__$SET$__\0":
|
|
1023
|
-
return new Set(value.slice(1));
|
|
1024
|
-
case "\0__$MAP$__\0":
|
|
1025
|
-
return new Map(value.slice(1));
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
return value;
|
|
1029
|
-
}
|
|
1030
|
-
function toBuffer(value, options) {
|
|
1031
|
-
if (Buffer.isBuffer(value))
|
|
1032
|
-
return [value, __spreadProps(__spreadValues({}, options), { flags: 0 /* BUFFER */ })];
|
|
1033
|
-
switch (typeof value) {
|
|
1034
|
-
case "bigint":
|
|
1035
|
-
return [Buffer.from(value.toString(), "utf-8"), __spreadProps(__spreadValues({}, options), { flags: 3402235904 /* BIGINT */ })];
|
|
1036
|
-
case "boolean":
|
|
1037
|
-
return [Buffer.alloc(1, value ? 255 : 0), __spreadProps(__spreadValues({}, options), { flags: 3402235905 /* BOOLEAN */ })];
|
|
1038
|
-
case "number":
|
|
1039
|
-
return [Buffer.from(value.toString(), "utf-8"), __spreadProps(__spreadValues({}, options), { flags: 3402235906 /* NUMBER */ })];
|
|
1040
|
-
case "string":
|
|
1041
|
-
return [Buffer.from(value, "utf-8"), __spreadProps(__spreadValues({}, options), { flags: 3402235907 /* STRING */ })];
|
|
1042
|
-
case "object":
|
|
1043
|
-
break;
|
|
1044
|
-
default:
|
|
1045
|
-
import_assert5.default.fail(`Unable to store value of type "${typeof value}"`);
|
|
1046
|
-
}
|
|
1047
|
-
if (import_util2.types.isTypedArray(value)) {
|
|
1048
|
-
const flags = typedArrayFlags(value);
|
|
1049
|
-
const buffer = Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
1050
|
-
return [buffer, __spreadProps(__spreadValues({}, options), { flags })];
|
|
1051
|
-
}
|
|
1052
|
-
if (value === null)
|
|
1053
|
-
return [EMPTY_BUFFER, __spreadProps(__spreadValues({}, options), { flags: 3402235918 /* NULL */ })];
|
|
1054
|
-
const json = JSON.stringify(value, replacer);
|
|
1055
|
-
return [Buffer.from(json, "utf-8"), __spreadProps(__spreadValues({}, options), { flags: 3402235919 /* JSON */ })];
|
|
1056
|
-
}
|
|
1057
|
-
function fromBuffer(result) {
|
|
1058
|
-
try {
|
|
1059
|
-
const { flags, value, cas } = result;
|
|
1060
|
-
switch (flags) {
|
|
1061
|
-
case 3402235904 /* BIGINT */:
|
|
1062
|
-
return { value: BigInt(value.toString("utf-8")), cas };
|
|
1063
|
-
case 3402235905 /* BOOLEAN */:
|
|
1064
|
-
return { value: !!value[0], cas };
|
|
1065
|
-
case 3402235906 /* NUMBER */:
|
|
1066
|
-
return { value: Number(value.toString("utf-8")), cas };
|
|
1067
|
-
case 3402235907 /* STRING */:
|
|
1068
|
-
return { value: value.toString("utf-8"), cas };
|
|
1069
|
-
case 3402235918 /* NULL */:
|
|
1070
|
-
return { value: null, cas };
|
|
1071
|
-
case 3402235919 /* JSON */:
|
|
1072
|
-
return { value: JSON.parse(value.toString("utf-8"), reviver), cas };
|
|
1073
|
-
case 3402235920 /* UINT8ARRAY */:
|
|
1074
|
-
return { value: makeTypedArray(Uint8Array, value), cas };
|
|
1075
|
-
case 3402235921 /* UINT8CLAMPEDARRAY */:
|
|
1076
|
-
return { value: makeTypedArray(Uint8ClampedArray, value), cas };
|
|
1077
|
-
case 3402235922 /* UINT16ARRAY */:
|
|
1078
|
-
return { value: makeTypedArray(Uint16Array, value), cas };
|
|
1079
|
-
case 3402235923 /* UINT32ARRAY */:
|
|
1080
|
-
return { value: makeTypedArray(Uint32Array, value), cas };
|
|
1081
|
-
case 3402235924 /* INT8ARRAY */:
|
|
1082
|
-
return { value: makeTypedArray(Int8Array, value), cas };
|
|
1083
|
-
case 3402235925 /* INT16ARRAY */:
|
|
1084
|
-
return { value: makeTypedArray(Int16Array, value), cas };
|
|
1085
|
-
case 3402235926 /* INT32ARRAY */:
|
|
1086
|
-
return { value: makeTypedArray(Int32Array, value), cas };
|
|
1087
|
-
case 3402235927 /* BIGUINT64ARRAY */:
|
|
1088
|
-
return { value: makeTypedArray(BigUint64Array, value), cas };
|
|
1089
|
-
case 3402235928 /* BIGINT64ARRAY */:
|
|
1090
|
-
return { value: makeTypedArray(BigInt64Array, value), cas };
|
|
1091
|
-
case 3402235929 /* FLOAT32ARRAY */:
|
|
1092
|
-
return { value: makeTypedArray(Float32Array, value), cas };
|
|
1093
|
-
case 3402235930 /* FLOAT64ARRAY */:
|
|
1094
|
-
return { value: makeTypedArray(Float64Array, value), cas };
|
|
1095
|
-
case 0 /* BUFFER */:
|
|
1096
|
-
default:
|
|
1097
|
-
return { value: Buffer.from(value), cas };
|
|
1098
|
-
}
|
|
1099
|
-
} finally {
|
|
1100
|
-
result.recycle();
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
function makeTypedArray(constructor, source) {
|
|
1104
|
-
const clone = Buffer.from(source);
|
|
1105
|
-
const { buffer, byteOffset, byteLength } = clone;
|
|
1106
|
-
return new constructor(buffer, byteOffset, byteLength / constructor.BYTES_PER_ELEMENT);
|
|
1107
|
-
}
|
|
1108
|
-
var MemxClient = class {
|
|
1109
|
-
#adapter;
|
|
1110
|
-
#prefix;
|
|
1111
|
-
constructor(adapterOrOptions) {
|
|
1112
|
-
if (!adapterOrOptions) {
|
|
1113
|
-
this.#adapter = new ClusterAdapter();
|
|
1114
|
-
} else if ("get" in adapterOrOptions) {
|
|
1115
|
-
this.#adapter = adapterOrOptions;
|
|
1116
|
-
} else if ("hosts" in adapterOrOptions) {
|
|
1117
|
-
this.#adapter = new ClusterAdapter(adapterOrOptions);
|
|
1118
|
-
}
|
|
1119
|
-
this.#prefix = "";
|
|
1120
|
-
(0, import_assert5.default)(this.#adapter, "Invalid client constructor arguments");
|
|
1121
|
-
}
|
|
1122
|
-
get adapter() {
|
|
1123
|
-
return this.#adapter;
|
|
1124
|
-
}
|
|
1125
|
-
get prefix() {
|
|
1126
|
-
return this.#prefix;
|
|
1127
|
-
}
|
|
1128
|
-
withPrefix(prefix) {
|
|
1129
|
-
(0, import_assert5.default)(prefix, "Invalid prefix");
|
|
1130
|
-
const client = new MemxClient(this.#adapter);
|
|
1131
|
-
client.#prefix = prefix;
|
|
1132
|
-
return client;
|
|
1133
|
-
}
|
|
1134
|
-
async get(key) {
|
|
1135
|
-
const result = await this.#adapter.get(this.#prefix + key);
|
|
1136
|
-
return result && fromBuffer(result).value;
|
|
1137
|
-
}
|
|
1138
|
-
async gat(key, ttl) {
|
|
1139
|
-
const result = await this.#adapter.gat(this.#prefix + key, ttl);
|
|
1140
|
-
return result && fromBuffer(result).value;
|
|
1141
|
-
}
|
|
1142
|
-
async getc(key) {
|
|
1143
|
-
const result = await this.#adapter.get(this.#prefix + key);
|
|
1144
|
-
return result && fromBuffer(result);
|
|
1145
|
-
}
|
|
1146
|
-
async gatc(key, ttl) {
|
|
1147
|
-
const result = await this.#adapter.gat(this.#prefix + key, ttl);
|
|
1148
|
-
return result && fromBuffer(result);
|
|
1149
|
-
}
|
|
1150
|
-
async set(key, value, options) {
|
|
1151
|
-
return this.#adapter.set(this.#prefix + key, ...toBuffer(value, options));
|
|
1152
|
-
}
|
|
1153
|
-
async add(key, value, options) {
|
|
1154
|
-
return this.#adapter.add(this.#prefix + key, ...toBuffer(value, options));
|
|
1155
|
-
}
|
|
1156
|
-
async replace(key, value, options) {
|
|
1157
|
-
return this.#adapter.replace(this.#prefix + key, ...toBuffer(value, options));
|
|
1158
|
-
}
|
|
1159
|
-
append(key, value, options) {
|
|
1160
|
-
return this.#adapter.append(this.#prefix + key, ...toBuffer(value, options));
|
|
1161
|
-
}
|
|
1162
|
-
prepend(key, value, options) {
|
|
1163
|
-
return this.#adapter.prepend(this.#prefix + key, ...toBuffer(value, options));
|
|
1164
|
-
}
|
|
1165
|
-
async increment(key, delta, options) {
|
|
1166
|
-
const counter = await this.#adapter.increment(this.#prefix + key, delta, options);
|
|
1167
|
-
if ((options == null ? void 0 : options.initial) !== void 0 && (counter == null ? void 0 : counter.value) === BigInt(options.initial)) {
|
|
1168
|
-
const cas = await this.replace(key, counter.value, { cas: counter.cas, ttl: options.ttl });
|
|
1169
|
-
counter.cas = cas ?? counter.cas;
|
|
1170
|
-
}
|
|
1171
|
-
return counter;
|
|
1172
|
-
}
|
|
1173
|
-
async decrement(key, delta, options) {
|
|
1174
|
-
const counter = await this.#adapter.decrement(this.#prefix + key, delta, options);
|
|
1175
|
-
if ((options == null ? void 0 : options.initial) !== void 0 && (counter == null ? void 0 : counter.value) === BigInt(options.initial)) {
|
|
1176
|
-
const cas = await this.replace(key, counter.value, { cas: counter.cas, ttl: options.ttl });
|
|
1177
|
-
counter.cas = cas ?? counter.cas;
|
|
1178
|
-
}
|
|
1179
|
-
return counter;
|
|
1180
|
-
}
|
|
1181
|
-
touch(key, ttl) {
|
|
1182
|
-
return this.#adapter.touch(this.#prefix + key, ttl);
|
|
1183
|
-
}
|
|
1184
|
-
delete(key, options) {
|
|
1185
|
-
return this.#adapter.delete(this.#prefix + key, options);
|
|
1186
|
-
}
|
|
1187
|
-
flush(ttl) {
|
|
1188
|
-
return this.#adapter.flush(ttl);
|
|
1189
|
-
}
|
|
1190
|
-
noop() {
|
|
1191
|
-
return this.#adapter.noop();
|
|
1192
|
-
}
|
|
1193
|
-
quit() {
|
|
1194
|
-
return this.#adapter.quit();
|
|
1195
|
-
}
|
|
1196
|
-
version() {
|
|
1197
|
-
return this.#adapter.version();
|
|
1198
|
-
}
|
|
1199
|
-
stats() {
|
|
1200
|
-
return this.#adapter.stats();
|
|
1201
|
-
}
|
|
1202
|
-
};
|
|
1203
|
-
|
|
1204
|
-
// src/fake.ts
|
|
1205
|
-
function toExp(ttl = 0) {
|
|
1206
|
-
if (ttl === 0)
|
|
1207
|
-
return Number.MAX_SAFE_INTEGER;
|
|
1208
|
-
return Date.now() + ttl * 1e3;
|
|
1209
|
-
}
|
|
1210
|
-
var FakeAdapter = class {
|
|
1211
|
-
#cache = /* @__PURE__ */ new Map();
|
|
1212
|
-
#cas = 1n;
|
|
1213
|
-
ttl = 0;
|
|
1214
|
-
#get(key) {
|
|
1215
|
-
if (key.length > 250)
|
|
1216
|
-
throw new TypeError(`Key too long (len=${key.length})`);
|
|
1217
|
-
const entry = this.#cache.get(key);
|
|
1218
|
-
if (!entry)
|
|
1219
|
-
return;
|
|
1220
|
-
if (Date.now() > entry.exp) {
|
|
1221
|
-
this.#cache.delete(key);
|
|
1222
|
-
return;
|
|
1223
|
-
}
|
|
1224
|
-
return entry;
|
|
1225
|
-
}
|
|
1226
|
-
#set(key, value, flags, ttl) {
|
|
1227
|
-
this.#cache.set(key, {
|
|
1228
|
-
value,
|
|
1229
|
-
flags: flags || 0,
|
|
1230
|
-
cas: ++this.#cas,
|
|
1231
|
-
exp: toExp(ttl)
|
|
1232
|
-
});
|
|
1233
|
-
return this.#cas;
|
|
1234
|
-
}
|
|
1235
|
-
async get(key) {
|
|
1236
|
-
const entry = this.#get(key);
|
|
1237
|
-
if (!entry)
|
|
1238
|
-
return;
|
|
1239
|
-
return {
|
|
1240
|
-
value: entry.value,
|
|
1241
|
-
flags: entry.flags,
|
|
1242
|
-
cas: entry.cas,
|
|
1243
|
-
recycle: () => void 0
|
|
1244
|
-
};
|
|
1245
|
-
}
|
|
1246
|
-
async gat(key, ttl) {
|
|
1247
|
-
const entry = this.#get(key);
|
|
1248
|
-
if (!entry)
|
|
1249
|
-
return;
|
|
1250
|
-
entry.exp = toExp(ttl);
|
|
1251
|
-
return {
|
|
1252
|
-
value: entry.value,
|
|
1253
|
-
flags: entry.flags,
|
|
1254
|
-
cas: entry.cas,
|
|
1255
|
-
recycle: () => void 0
|
|
1256
|
-
};
|
|
1257
|
-
}
|
|
1258
|
-
async touch(key, ttl) {
|
|
1259
|
-
const entry = this.#get(key);
|
|
1260
|
-
if (entry)
|
|
1261
|
-
entry.exp = toExp(ttl);
|
|
1262
|
-
return !!entry;
|
|
1263
|
-
}
|
|
1264
|
-
async set(key, value, options = {}) {
|
|
1265
|
-
const entry = this.#get(key);
|
|
1266
|
-
if (entry && options.cas !== void 0 && entry.cas !== options.cas) {
|
|
1267
|
-
return;
|
|
1268
|
-
}
|
|
1269
|
-
return this.#set(key, value, options.flags, options.ttl);
|
|
1270
|
-
}
|
|
1271
|
-
async add(key, value, options = {}) {
|
|
1272
|
-
if (this.#get(key))
|
|
1273
|
-
return;
|
|
1274
|
-
return this.#set(key, value, options.flags, options.ttl);
|
|
1275
|
-
}
|
|
1276
|
-
async replace(key, value, options = {}) {
|
|
1277
|
-
if (!this.#get(key))
|
|
1278
|
-
return;
|
|
1279
|
-
return this.#set(key, value, options.flags, options.ttl);
|
|
1280
|
-
}
|
|
1281
|
-
async append(key, value, options = {}) {
|
|
1282
|
-
const entry = this.#get(key);
|
|
1283
|
-
if (!entry)
|
|
1284
|
-
return false;
|
|
1285
|
-
if (options.cas !== void 0 && options.cas !== entry.cas)
|
|
1286
|
-
return false;
|
|
1287
|
-
entry.value = Buffer.concat([entry.value, value]);
|
|
1288
|
-
return true;
|
|
1289
|
-
}
|
|
1290
|
-
async prepend(key, value, options = {}) {
|
|
1291
|
-
const entry = this.#get(key);
|
|
1292
|
-
if (!entry)
|
|
1293
|
-
return false;
|
|
1294
|
-
if (options.cas !== void 0 && options.cas !== entry.cas)
|
|
1295
|
-
return false;
|
|
1296
|
-
entry.value = Buffer.concat([value, entry.value]);
|
|
1297
|
-
return true;
|
|
1298
|
-
}
|
|
1299
|
-
async #counter(key, delta, options) {
|
|
1300
|
-
const entry = this.#get(key);
|
|
1301
|
-
if (!entry) {
|
|
1302
|
-
if (options.initial !== void 0) {
|
|
1303
|
-
const value = Buffer.from(options.initial.toString());
|
|
1304
|
-
this.#set(key, value, void 0, options.ttl);
|
|
1305
|
-
return { value: BigInt(options.initial), cas: this.#cas };
|
|
1306
|
-
} else {
|
|
1307
|
-
return;
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
if (options.cas !== void 0 && options.cas !== entry.cas)
|
|
1311
|
-
return;
|
|
1312
|
-
try {
|
|
1313
|
-
const value = BigInt(entry.value.toString("utf-8")) + BigInt(delta);
|
|
1314
|
-
this.#set(key, Buffer.from(value.toString()), void 0, options.ttl);
|
|
1315
|
-
return { value, cas: this.#cas };
|
|
1316
|
-
} catch (error) {
|
|
1317
|
-
throw new TypeError(`${error.message} (status=NON_NUMERIC_VALUE, key=${key})`);
|
|
1318
|
-
}
|
|
1319
|
-
}
|
|
1320
|
-
increment(key, delta = 1n, options = {}) {
|
|
1321
|
-
return this.#counter(key, delta, options);
|
|
1322
|
-
}
|
|
1323
|
-
decrement(key, delta = 1n, options = {}) {
|
|
1324
|
-
return this.#counter(key, -delta, options);
|
|
1325
|
-
}
|
|
1326
|
-
async delete(key, options = {}) {
|
|
1327
|
-
const entry = this.#get(key);
|
|
1328
|
-
if (entry && options.cas !== void 0 && entry.cas !== options.cas) {
|
|
1329
|
-
return false;
|
|
1330
|
-
}
|
|
1331
|
-
return this.#cache.delete(key);
|
|
1332
|
-
}
|
|
1333
|
-
async flush(ttl) {
|
|
1334
|
-
if (!ttl)
|
|
1335
|
-
return this.#cache.clear();
|
|
1336
|
-
const wait = toExp(ttl) - Date.now();
|
|
1337
|
-
setTimeout(() => this.#cache.clear(), wait);
|
|
1338
|
-
}
|
|
1339
|
-
async noop() {
|
|
1340
|
-
}
|
|
1341
|
-
async quit() {
|
|
1342
|
-
}
|
|
1343
|
-
async version() {
|
|
1344
|
-
return { fake: "0.0.0-fake" };
|
|
1345
|
-
}
|
|
1346
|
-
async stats() {
|
|
1347
|
-
return { fake: { version: "0.0.0-fake" } };
|
|
1348
|
-
}
|
|
1349
|
-
};
|
|
1350
|
-
var MemxFakeClient = class extends MemxClient {
|
|
1351
|
-
constructor() {
|
|
1352
|
-
super(new FakeAdapter());
|
|
1353
|
-
}
|
|
1354
|
-
};
|
|
1355
|
-
|
|
1356
|
-
// src/utils.ts
|
|
1357
|
-
var import_assert6 = __toESM(require("assert"));
|
|
1358
|
-
var Factory = class {
|
|
1359
|
-
#factory;
|
|
1360
|
-
#client;
|
|
1361
|
-
#ttl;
|
|
1362
|
-
constructor(client, factory, ttl) {
|
|
1363
|
-
(0, import_assert6.default)(typeof factory === "function", "Invalid or no factory specified");
|
|
1364
|
-
(0, import_assert6.default)(client, "No client specified");
|
|
1365
|
-
this.#factory = factory;
|
|
1366
|
-
this.#client = client;
|
|
1367
|
-
this.#ttl = ttl;
|
|
1368
|
-
}
|
|
1369
|
-
async get(key) {
|
|
1370
|
-
const cached = await this.#client.getc(key);
|
|
1371
|
-
if (cached) {
|
|
1372
|
-
void logPromiseError(this.#client.touch(key), `Factory error touching key "${this.#client.prefix}${key}"`);
|
|
1373
|
-
return cached.value;
|
|
1374
|
-
}
|
|
1375
|
-
const created = await this.#factory(key);
|
|
1376
|
-
if (created) {
|
|
1377
|
-
void logPromiseError(this.#client.set(key, created, { ttl: this.#ttl }), `Factory error setting key "${this.#client.prefix}${key}"`);
|
|
1378
|
-
}
|
|
1379
|
-
return created;
|
|
1380
|
-
}
|
|
1381
|
-
};
|
|
1382
|
-
var Bundle = class {
|
|
1383
|
-
#client;
|
|
1384
|
-
#name;
|
|
1385
|
-
#ttl;
|
|
1386
|
-
constructor(client, name, ttl) {
|
|
1387
|
-
(0, import_assert6.default)(client, "No client specified");
|
|
1388
|
-
(0, import_assert6.default)(name, "No bundle name specified");
|
|
1389
|
-
this.#client = client;
|
|
1390
|
-
this.#name = name;
|
|
1391
|
-
this.#ttl = ttl || 0;
|
|
1392
|
-
}
|
|
1393
|
-
async #appendKey(key) {
|
|
1394
|
-
await logPromiseError((async () => {
|
|
1395
|
-
const added = await this.#client.add(this.#name, key, { ttl: this.#ttl });
|
|
1396
|
-
if (!added) {
|
|
1397
|
-
await this.#client.append(this.#name, `\0${key}`);
|
|
1398
|
-
await this.#client.touch(this.#name, this.#ttl);
|
|
1399
|
-
}
|
|
1400
|
-
})(), `Bundle "${this.#client.prefix}${this.#name}" error recording key "${key}"`);
|
|
1401
|
-
}
|
|
1402
|
-
async #removeKey(key) {
|
|
1403
|
-
await logPromiseError((async () => {
|
|
1404
|
-
const result = await this.#client.getc(this.#name);
|
|
1405
|
-
if (!result)
|
|
1406
|
-
return;
|
|
1407
|
-
const keys = result.value.split("\0").filter((k) => k !== key).join("\0");
|
|
1408
|
-
await this.#client.set(this.#name, keys, { cas: result.cas, ttl: this.#ttl });
|
|
1409
|
-
})(), `Bundle "${this.#client.prefix}${this.#name}" error clearing key "${key}"`);
|
|
1410
|
-
}
|
|
1411
|
-
async add(key, value) {
|
|
1412
|
-
await this.#client.set(`${this.#name}:${key}`, value, { ttl: this.#ttl });
|
|
1413
|
-
await this.#appendKey(key);
|
|
1414
|
-
}
|
|
1415
|
-
async get(key) {
|
|
1416
|
-
const result = await this.#client.getc(`${this.#name}:${key}`);
|
|
1417
|
-
if (result)
|
|
1418
|
-
return result.value;
|
|
1419
|
-
await this.#removeKey(key);
|
|
1420
|
-
}
|
|
1421
|
-
async delete(key) {
|
|
1422
|
-
await this.#client.delete(`${this.#name}:${key}`);
|
|
1423
|
-
await this.#removeKey(key);
|
|
1424
|
-
}
|
|
1425
|
-
async list() {
|
|
1426
|
-
const result = await this.#client.getc(this.#name);
|
|
1427
|
-
if (!result)
|
|
1428
|
-
return {};
|
|
1429
|
-
const results = {};
|
|
1430
|
-
const promises = [];
|
|
1431
|
-
for (const key of new Set(result.value.split("\0"))) {
|
|
1432
|
-
promises.push(this.#client.getc(`${this.#name}:${key}`).then((result2) => {
|
|
1433
|
-
if (result2)
|
|
1434
|
-
results[key] = result2.value;
|
|
1435
|
-
}));
|
|
1436
|
-
}
|
|
1437
|
-
await Promise.all(promises);
|
|
1438
|
-
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`);
|
|
1439
|
-
return results;
|
|
1440
|
-
}
|
|
1441
|
-
};
|
|
1442
|
-
var PoorManLock = class {
|
|
1443
|
-
#client;
|
|
1444
|
-
#name;
|
|
1445
|
-
constructor(client, name) {
|
|
1446
|
-
(0, import_assert6.default)(client, "No client specified");
|
|
1447
|
-
(0, import_assert6.default)(name, "No lock name specified");
|
|
1448
|
-
this.#client = client;
|
|
1449
|
-
this.#name = name;
|
|
1450
|
-
}
|
|
1451
|
-
async execute(executor, options) {
|
|
1452
|
-
const { timeout = 5e3, owner = false } = options || {};
|
|
1453
|
-
const end = Date.now() + timeout;
|
|
1454
|
-
let cas;
|
|
1455
|
-
do {
|
|
1456
|
-
cas = await this.#client.add(this.#name, owner, { ttl: 2 });
|
|
1457
|
-
if (cas !== void 0)
|
|
1458
|
-
break;
|
|
1459
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1460
|
-
} while (Date.now() < end);
|
|
1461
|
-
if (cas === void 0) {
|
|
1462
|
-
const other = await this.#client.getc(this.#name);
|
|
1463
|
-
const owner2 = other && other.value ? `"${other.value}"` : "anonymous";
|
|
1464
|
-
throw new Error(`Lock "${this.#client.prefix}${this.#name}" timeout (owner=${owner2})`);
|
|
1465
|
-
}
|
|
1466
|
-
const interval = setInterval(() => {
|
|
1467
|
-
void logPromiseError((async () => {
|
|
1468
|
-
const replaced = await this.#client.replace(this.#name, owner, { ttl: 2, cas });
|
|
1469
|
-
(0, import_assert6.default)(replaced !== void 0, `Lock "${this.#client.prefix}${this.#name}" not replaced`);
|
|
1470
|
-
cas = replaced;
|
|
1471
|
-
})(), `Error extending lock "${this.#client.prefix}${this.#name}"`);
|
|
1472
|
-
}, 100);
|
|
1473
|
-
try {
|
|
1474
|
-
return await executor();
|
|
1475
|
-
} finally {
|
|
1476
|
-
clearInterval(interval);
|
|
1477
|
-
await logPromiseError(this.#client.delete(this.#name, { cas }), `Error deleting lock "${this.#client.prefix}${this.#name}"`);
|
|
1478
|
-
}
|
|
1479
|
-
}
|
|
1480
|
-
};
|
|
1481
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
1482
|
-
0 && (module.exports = {
|
|
1483
|
-
Bundle,
|
|
1484
|
-
ClusterAdapter,
|
|
1485
|
-
Factory,
|
|
1486
|
-
FakeAdapter,
|
|
1487
|
-
MemxClient,
|
|
1488
|
-
MemxFakeClient,
|
|
1489
|
-
PoorManLock,
|
|
1490
|
-
ServerAdapter,
|
|
1491
|
-
connection,
|
|
1492
|
-
constants,
|
|
1493
|
-
decode,
|
|
1494
|
-
encode
|
|
1495
|
-
});
|
|
1496
|
-
//# sourceMappingURL=index.js.map
|