@upstash/redis 0.0.0-ci.ff7a0b135b28ff50a7e2634a78123684be3ed71f-20241105152627 → 0.0.0-ci.ff91bb10adb82f9d009471b11db70c40b6dbf5f8-20251205205412
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/{chunk-O2BCOVQA.mjs → chunk-WTYE7OV3.mjs} +779 -68
- package/cloudflare.d.mts +3 -3
- package/cloudflare.d.ts +3 -3
- package/cloudflare.js +780 -79
- package/cloudflare.mjs +2 -2
- package/fastly.d.mts +2 -2
- package/fastly.d.ts +2 -2
- package/fastly.js +779 -78
- package/fastly.mjs +1 -1
- package/nodejs.d.mts +14 -6
- package/nodejs.d.ts +14 -6
- package/nodejs.js +787 -82
- package/nodejs.mjs +9 -5
- package/package.json +1 -1
- package/{zmscore-Dc6Llqgr.d.mts → zmscore-DhpQcqpW.d.mts} +599 -46
- package/{zmscore-Dc6Llqgr.d.ts → zmscore-DhpQcqpW.d.ts} +599 -46
|
@@ -8,11 +8,12 @@ var __export = (target, all) => {
|
|
|
8
8
|
var error_exports = {};
|
|
9
9
|
__export(error_exports, {
|
|
10
10
|
UpstashError: () => UpstashError,
|
|
11
|
+
UpstashJSONParseError: () => UpstashJSONParseError,
|
|
11
12
|
UrlError: () => UrlError
|
|
12
13
|
});
|
|
13
14
|
var UpstashError = class extends Error {
|
|
14
|
-
constructor(message) {
|
|
15
|
-
super(message);
|
|
15
|
+
constructor(message, options) {
|
|
16
|
+
super(message, options);
|
|
16
17
|
this.name = "UpstashError";
|
|
17
18
|
}
|
|
18
19
|
};
|
|
@@ -24,6 +25,58 @@ var UrlError = class extends Error {
|
|
|
24
25
|
this.name = "UrlError";
|
|
25
26
|
}
|
|
26
27
|
};
|
|
28
|
+
var UpstashJSONParseError = class extends UpstashError {
|
|
29
|
+
constructor(body, options) {
|
|
30
|
+
const truncatedBody = body.length > 200 ? body.slice(0, 200) + "..." : body;
|
|
31
|
+
super(`Unable to parse response body: ${truncatedBody}`, options);
|
|
32
|
+
this.name = "UpstashJSONParseError";
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// pkg/util.ts
|
|
37
|
+
function parseRecursive(obj) {
|
|
38
|
+
const parsed = Array.isArray(obj) ? obj.map((o) => {
|
|
39
|
+
try {
|
|
40
|
+
return parseRecursive(o);
|
|
41
|
+
} catch {
|
|
42
|
+
return o;
|
|
43
|
+
}
|
|
44
|
+
}) : JSON.parse(obj);
|
|
45
|
+
if (typeof parsed === "number" && parsed.toString() !== obj) {
|
|
46
|
+
return obj;
|
|
47
|
+
}
|
|
48
|
+
return parsed;
|
|
49
|
+
}
|
|
50
|
+
function parseResponse(result) {
|
|
51
|
+
try {
|
|
52
|
+
return parseRecursive(result);
|
|
53
|
+
} catch {
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function deserializeScanResponse(result) {
|
|
58
|
+
return [result[0], ...parseResponse(result.slice(1))];
|
|
59
|
+
}
|
|
60
|
+
function deserializeScanWithTypesResponse(result) {
|
|
61
|
+
const [cursor, keys] = result;
|
|
62
|
+
const parsedKeys = [];
|
|
63
|
+
for (let i = 0; i < keys.length; i += 2) {
|
|
64
|
+
parsedKeys.push({ key: keys[i], type: keys[i + 1] });
|
|
65
|
+
}
|
|
66
|
+
return [cursor, parsedKeys];
|
|
67
|
+
}
|
|
68
|
+
function mergeHeaders(...headers) {
|
|
69
|
+
const merged = {};
|
|
70
|
+
for (const header of headers) {
|
|
71
|
+
if (!header) continue;
|
|
72
|
+
for (const [key, value] of Object.entries(header)) {
|
|
73
|
+
if (value !== void 0 && value !== null) {
|
|
74
|
+
merged[key] = value;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return merged;
|
|
79
|
+
}
|
|
27
80
|
|
|
28
81
|
// pkg/http.ts
|
|
29
82
|
var HttpClient = class {
|
|
@@ -73,15 +126,20 @@ var HttpClient = class {
|
|
|
73
126
|
this.headers = merge(this.headers, "Upstash-Telemetry-Sdk", telemetry.sdk);
|
|
74
127
|
}
|
|
75
128
|
async request(req) {
|
|
129
|
+
const requestHeaders = mergeHeaders(this.headers, req.headers ?? {});
|
|
130
|
+
const requestUrl = [this.baseUrl, ...req.path ?? []].join("/");
|
|
131
|
+
const isEventStream = requestHeaders.Accept === "text/event-stream";
|
|
132
|
+
const signal = req.signal ?? this.options.signal;
|
|
133
|
+
const isSignalFunction = typeof signal === "function";
|
|
76
134
|
const requestOptions = {
|
|
77
135
|
//@ts-expect-error this should throw due to bun regression
|
|
78
136
|
cache: this.options.cache,
|
|
79
137
|
method: "POST",
|
|
80
|
-
headers:
|
|
138
|
+
headers: requestHeaders,
|
|
81
139
|
body: JSON.stringify(req.body),
|
|
82
140
|
keepalive: this.options.keepAlive,
|
|
83
141
|
agent: this.options.agent,
|
|
84
|
-
signal:
|
|
142
|
+
signal: isSignalFunction ? signal() : signal,
|
|
85
143
|
/**
|
|
86
144
|
* Fastly specific
|
|
87
145
|
*/
|
|
@@ -100,16 +158,18 @@ var HttpClient = class {
|
|
|
100
158
|
let error = null;
|
|
101
159
|
for (let i = 0; i <= this.retry.attempts; i++) {
|
|
102
160
|
try {
|
|
103
|
-
res = await fetch(
|
|
161
|
+
res = await fetch(requestUrl, requestOptions);
|
|
104
162
|
break;
|
|
105
163
|
} catch (error_) {
|
|
106
|
-
if (
|
|
164
|
+
if (requestOptions.signal?.aborted && isSignalFunction) {
|
|
165
|
+
throw error_;
|
|
166
|
+
} else if (requestOptions.signal?.aborted) {
|
|
107
167
|
const myBlob = new Blob([
|
|
108
|
-
JSON.stringify({ result:
|
|
168
|
+
JSON.stringify({ result: requestOptions.signal.reason ?? "Aborted" })
|
|
109
169
|
]);
|
|
110
170
|
const myOptions = {
|
|
111
171
|
status: 200,
|
|
112
|
-
statusText:
|
|
172
|
+
statusText: requestOptions.signal.reason ?? "Aborted"
|
|
113
173
|
};
|
|
114
174
|
res = new Response(myBlob, myOptions);
|
|
115
175
|
break;
|
|
@@ -123,14 +183,58 @@ var HttpClient = class {
|
|
|
123
183
|
if (!res) {
|
|
124
184
|
throw error ?? new Error("Exhausted all retries");
|
|
125
185
|
}
|
|
126
|
-
const body = await res.json();
|
|
127
186
|
if (!res.ok) {
|
|
128
|
-
|
|
187
|
+
let body2;
|
|
188
|
+
const rawBody2 = await res.text();
|
|
189
|
+
try {
|
|
190
|
+
body2 = JSON.parse(rawBody2);
|
|
191
|
+
} catch (error2) {
|
|
192
|
+
throw new UpstashJSONParseError(rawBody2, { cause: error2 });
|
|
193
|
+
}
|
|
194
|
+
throw new UpstashError(`${body2.error}, command was: ${JSON.stringify(req.body)}`);
|
|
129
195
|
}
|
|
130
196
|
if (this.readYourWrites) {
|
|
131
197
|
const headers = res.headers;
|
|
132
198
|
this.upstashSyncToken = headers.get("upstash-sync-token") ?? "";
|
|
133
199
|
}
|
|
200
|
+
if (isEventStream && req && req.onMessage && res.body) {
|
|
201
|
+
const reader = res.body.getReader();
|
|
202
|
+
const decoder = new TextDecoder();
|
|
203
|
+
(async () => {
|
|
204
|
+
try {
|
|
205
|
+
while (true) {
|
|
206
|
+
const { value, done } = await reader.read();
|
|
207
|
+
if (done) break;
|
|
208
|
+
const chunk = decoder.decode(value);
|
|
209
|
+
const lines = chunk.split("\n");
|
|
210
|
+
for (const line of lines) {
|
|
211
|
+
if (line.startsWith("data: ")) {
|
|
212
|
+
const data = line.slice(6);
|
|
213
|
+
req.onMessage?.(data);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
} catch (error2) {
|
|
218
|
+
if (error2 instanceof Error && error2.name === "AbortError") {
|
|
219
|
+
} else {
|
|
220
|
+
console.error("Stream reading error:", error2);
|
|
221
|
+
}
|
|
222
|
+
} finally {
|
|
223
|
+
try {
|
|
224
|
+
await reader.cancel();
|
|
225
|
+
} catch {
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
})();
|
|
229
|
+
return { result: 1 };
|
|
230
|
+
}
|
|
231
|
+
let body;
|
|
232
|
+
const rawBody = await res.text();
|
|
233
|
+
try {
|
|
234
|
+
body = JSON.parse(rawBody);
|
|
235
|
+
} catch (error2) {
|
|
236
|
+
throw new UpstashJSONParseError(rawBody, { cause: error2 });
|
|
237
|
+
}
|
|
134
238
|
if (this.readYourWrites) {
|
|
135
239
|
const headers = res.headers;
|
|
136
240
|
this.upstashSyncToken = headers.get("upstash-sync-token") ?? "";
|
|
@@ -201,31 +305,6 @@ function merge(obj, key, value) {
|
|
|
201
305
|
return obj;
|
|
202
306
|
}
|
|
203
307
|
|
|
204
|
-
// pkg/util.ts
|
|
205
|
-
function parseRecursive(obj) {
|
|
206
|
-
const parsed = Array.isArray(obj) ? obj.map((o) => {
|
|
207
|
-
try {
|
|
208
|
-
return parseRecursive(o);
|
|
209
|
-
} catch {
|
|
210
|
-
return o;
|
|
211
|
-
}
|
|
212
|
-
}) : JSON.parse(obj);
|
|
213
|
-
if (typeof parsed === "number" && parsed.toString() !== obj) {
|
|
214
|
-
return obj;
|
|
215
|
-
}
|
|
216
|
-
return parsed;
|
|
217
|
-
}
|
|
218
|
-
function parseResponse(result) {
|
|
219
|
-
try {
|
|
220
|
-
return parseRecursive(result);
|
|
221
|
-
} catch {
|
|
222
|
-
return result;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
function deserializeScanResponse(result) {
|
|
226
|
-
return [result[0], ...parseResponse(result.slice(1))];
|
|
227
|
-
}
|
|
228
|
-
|
|
229
308
|
// pkg/commands/command.ts
|
|
230
309
|
var defaultSerializer = (c) => {
|
|
231
310
|
switch (typeof c) {
|
|
@@ -243,6 +322,11 @@ var Command = class {
|
|
|
243
322
|
command;
|
|
244
323
|
serialize;
|
|
245
324
|
deserialize;
|
|
325
|
+
headers;
|
|
326
|
+
path;
|
|
327
|
+
onMessage;
|
|
328
|
+
isStreaming;
|
|
329
|
+
signal;
|
|
246
330
|
/**
|
|
247
331
|
* Create a new command instance.
|
|
248
332
|
*
|
|
@@ -252,6 +336,11 @@ var Command = class {
|
|
|
252
336
|
this.serialize = defaultSerializer;
|
|
253
337
|
this.deserialize = opts?.automaticDeserialization === void 0 || opts.automaticDeserialization ? opts?.deserialize ?? parseResponse : (x) => x;
|
|
254
338
|
this.command = command.map((c) => this.serialize(c));
|
|
339
|
+
this.headers = opts?.headers;
|
|
340
|
+
this.path = opts?.path;
|
|
341
|
+
this.onMessage = opts?.streamOptions?.onMessage;
|
|
342
|
+
this.isStreaming = opts?.streamOptions?.isStreaming ?? false;
|
|
343
|
+
this.signal = opts?.streamOptions?.signal;
|
|
255
344
|
if (opts?.latencyLogging) {
|
|
256
345
|
const originalExec = this.exec.bind(this);
|
|
257
346
|
this.exec = async (client) => {
|
|
@@ -272,7 +361,12 @@ var Command = class {
|
|
|
272
361
|
async exec(client) {
|
|
273
362
|
const { result, error } = await client.request({
|
|
274
363
|
body: this.command,
|
|
275
|
-
|
|
364
|
+
path: this.path,
|
|
365
|
+
upstashSyncToken: client.upstashSyncToken,
|
|
366
|
+
headers: this.headers,
|
|
367
|
+
onMessage: this.onMessage,
|
|
368
|
+
isStreaming: this.isStreaming,
|
|
369
|
+
signal: this.signal
|
|
276
370
|
});
|
|
277
371
|
if (error) {
|
|
278
372
|
throw new UpstashError(error);
|
|
@@ -290,9 +384,9 @@ function deserialize(result) {
|
|
|
290
384
|
return null;
|
|
291
385
|
}
|
|
292
386
|
const obj = {};
|
|
293
|
-
|
|
294
|
-
const key = result
|
|
295
|
-
const value = result
|
|
387
|
+
for (let i = 0; i < result.length; i += 2) {
|
|
388
|
+
const key = result[i];
|
|
389
|
+
const value = result[i + 1];
|
|
296
390
|
try {
|
|
297
391
|
obj[key] = JSON.parse(value);
|
|
298
392
|
} catch {
|
|
@@ -434,6 +528,13 @@ var EchoCommand = class extends Command {
|
|
|
434
528
|
}
|
|
435
529
|
};
|
|
436
530
|
|
|
531
|
+
// pkg/commands/evalRo.ts
|
|
532
|
+
var EvalROCommand = class extends Command {
|
|
533
|
+
constructor([script, keys, args], opts) {
|
|
534
|
+
super(["eval_ro", script, keys.length, ...keys, ...args ?? []], opts);
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
|
|
437
538
|
// pkg/commands/eval.ts
|
|
438
539
|
var EvalCommand = class extends Command {
|
|
439
540
|
constructor([script, keys, args], opts) {
|
|
@@ -441,6 +542,13 @@ var EvalCommand = class extends Command {
|
|
|
441
542
|
}
|
|
442
543
|
};
|
|
443
544
|
|
|
545
|
+
// pkg/commands/evalshaRo.ts
|
|
546
|
+
var EvalshaROCommand = class extends Command {
|
|
547
|
+
constructor([sha, keys, args], opts) {
|
|
548
|
+
super(["evalsha_ro", sha, keys.length, ...keys, ...args ?? []], opts);
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
|
|
444
552
|
// pkg/commands/evalsha.ts
|
|
445
553
|
var EvalshaCommand = class extends Command {
|
|
446
554
|
constructor([sha, keys, args], opts) {
|
|
@@ -448,6 +556,14 @@ var EvalshaCommand = class extends Command {
|
|
|
448
556
|
}
|
|
449
557
|
};
|
|
450
558
|
|
|
559
|
+
// pkg/commands/exec.ts
|
|
560
|
+
var ExecCommand = class extends Command {
|
|
561
|
+
constructor(cmd, opts) {
|
|
562
|
+
const normalizedCmd = cmd.map((arg) => typeof arg === "string" ? arg : String(arg));
|
|
563
|
+
super(normalizedCmd, opts);
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
|
|
451
567
|
// pkg/commands/exists.ts
|
|
452
568
|
var ExistsCommand = class extends Command {
|
|
453
569
|
constructor(cmd, opts) {
|
|
@@ -664,6 +780,27 @@ var GetDelCommand = class extends Command {
|
|
|
664
780
|
}
|
|
665
781
|
};
|
|
666
782
|
|
|
783
|
+
// pkg/commands/getex.ts
|
|
784
|
+
var GetExCommand = class extends Command {
|
|
785
|
+
constructor([key, opts], cmdOpts) {
|
|
786
|
+
const command = ["getex", key];
|
|
787
|
+
if (opts) {
|
|
788
|
+
if ("ex" in opts && typeof opts.ex === "number") {
|
|
789
|
+
command.push("ex", opts.ex);
|
|
790
|
+
} else if ("px" in opts && typeof opts.px === "number") {
|
|
791
|
+
command.push("px", opts.px);
|
|
792
|
+
} else if ("exat" in opts && typeof opts.exat === "number") {
|
|
793
|
+
command.push("exat", opts.exat);
|
|
794
|
+
} else if ("pxat" in opts && typeof opts.pxat === "number") {
|
|
795
|
+
command.push("pxat", opts.pxat);
|
|
796
|
+
} else if ("persist" in opts && opts.persist) {
|
|
797
|
+
command.push("persist");
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
super(command, cmdOpts);
|
|
801
|
+
}
|
|
802
|
+
};
|
|
803
|
+
|
|
667
804
|
// pkg/commands/getrange.ts
|
|
668
805
|
var GetRangeCommand = class extends Command {
|
|
669
806
|
constructor(cmd, opts) {
|
|
@@ -692,6 +829,122 @@ var HExistsCommand = class extends Command {
|
|
|
692
829
|
}
|
|
693
830
|
};
|
|
694
831
|
|
|
832
|
+
// pkg/commands/hexpire.ts
|
|
833
|
+
var HExpireCommand = class extends Command {
|
|
834
|
+
constructor(cmd, opts) {
|
|
835
|
+
const [key, fields, seconds, option] = cmd;
|
|
836
|
+
const fieldArray = Array.isArray(fields) ? fields : [fields];
|
|
837
|
+
super(
|
|
838
|
+
[
|
|
839
|
+
"hexpire",
|
|
840
|
+
key,
|
|
841
|
+
seconds,
|
|
842
|
+
...option ? [option] : [],
|
|
843
|
+
"FIELDS",
|
|
844
|
+
fieldArray.length,
|
|
845
|
+
...fieldArray
|
|
846
|
+
],
|
|
847
|
+
opts
|
|
848
|
+
);
|
|
849
|
+
}
|
|
850
|
+
};
|
|
851
|
+
|
|
852
|
+
// pkg/commands/hexpireat.ts
|
|
853
|
+
var HExpireAtCommand = class extends Command {
|
|
854
|
+
constructor(cmd, opts) {
|
|
855
|
+
const [key, fields, timestamp, option] = cmd;
|
|
856
|
+
const fieldArray = Array.isArray(fields) ? fields : [fields];
|
|
857
|
+
super(
|
|
858
|
+
[
|
|
859
|
+
"hexpireat",
|
|
860
|
+
key,
|
|
861
|
+
timestamp,
|
|
862
|
+
...option ? [option] : [],
|
|
863
|
+
"FIELDS",
|
|
864
|
+
fieldArray.length,
|
|
865
|
+
...fieldArray
|
|
866
|
+
],
|
|
867
|
+
opts
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
|
|
872
|
+
// pkg/commands/hexpiretime.ts
|
|
873
|
+
var HExpireTimeCommand = class extends Command {
|
|
874
|
+
constructor(cmd, opts) {
|
|
875
|
+
const [key, fields] = cmd;
|
|
876
|
+
const fieldArray = Array.isArray(fields) ? fields : [fields];
|
|
877
|
+
super(["hexpiretime", key, "FIELDS", fieldArray.length, ...fieldArray], opts);
|
|
878
|
+
}
|
|
879
|
+
};
|
|
880
|
+
|
|
881
|
+
// pkg/commands/hpersist.ts
|
|
882
|
+
var HPersistCommand = class extends Command {
|
|
883
|
+
constructor(cmd, opts) {
|
|
884
|
+
const [key, fields] = cmd;
|
|
885
|
+
const fieldArray = Array.isArray(fields) ? fields : [fields];
|
|
886
|
+
super(["hpersist", key, "FIELDS", fieldArray.length, ...fieldArray], opts);
|
|
887
|
+
}
|
|
888
|
+
};
|
|
889
|
+
|
|
890
|
+
// pkg/commands/hpexpire.ts
|
|
891
|
+
var HPExpireCommand = class extends Command {
|
|
892
|
+
constructor(cmd, opts) {
|
|
893
|
+
const [key, fields, milliseconds, option] = cmd;
|
|
894
|
+
const fieldArray = Array.isArray(fields) ? fields : [fields];
|
|
895
|
+
super(
|
|
896
|
+
[
|
|
897
|
+
"hpexpire",
|
|
898
|
+
key,
|
|
899
|
+
milliseconds,
|
|
900
|
+
...option ? [option] : [],
|
|
901
|
+
"FIELDS",
|
|
902
|
+
fieldArray.length,
|
|
903
|
+
...fieldArray
|
|
904
|
+
],
|
|
905
|
+
opts
|
|
906
|
+
);
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
|
|
910
|
+
// pkg/commands/hpexpireat.ts
|
|
911
|
+
var HPExpireAtCommand = class extends Command {
|
|
912
|
+
constructor(cmd, opts) {
|
|
913
|
+
const [key, fields, timestamp, option] = cmd;
|
|
914
|
+
const fieldArray = Array.isArray(fields) ? fields : [fields];
|
|
915
|
+
super(
|
|
916
|
+
[
|
|
917
|
+
"hpexpireat",
|
|
918
|
+
key,
|
|
919
|
+
timestamp,
|
|
920
|
+
...option ? [option] : [],
|
|
921
|
+
"FIELDS",
|
|
922
|
+
fieldArray.length,
|
|
923
|
+
...fieldArray
|
|
924
|
+
],
|
|
925
|
+
opts
|
|
926
|
+
);
|
|
927
|
+
}
|
|
928
|
+
};
|
|
929
|
+
|
|
930
|
+
// pkg/commands/hpexpiretime.ts
|
|
931
|
+
var HPExpireTimeCommand = class extends Command {
|
|
932
|
+
constructor(cmd, opts) {
|
|
933
|
+
const [key, fields] = cmd;
|
|
934
|
+
const fieldArray = Array.isArray(fields) ? fields : [fields];
|
|
935
|
+
super(["hpexpiretime", key, "FIELDS", fieldArray.length, ...fieldArray], opts);
|
|
936
|
+
}
|
|
937
|
+
};
|
|
938
|
+
|
|
939
|
+
// pkg/commands/hpttl.ts
|
|
940
|
+
var HPTtlCommand = class extends Command {
|
|
941
|
+
constructor(cmd, opts) {
|
|
942
|
+
const [key, fields] = cmd;
|
|
943
|
+
const fieldArray = Array.isArray(fields) ? fields : [fields];
|
|
944
|
+
super(["hpttl", key, "FIELDS", fieldArray.length, ...fieldArray], opts);
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
|
|
695
948
|
// pkg/commands/hget.ts
|
|
696
949
|
var HGetCommand = class extends Command {
|
|
697
950
|
constructor(cmd, opts) {
|
|
@@ -705,9 +958,9 @@ function deserialize2(result) {
|
|
|
705
958
|
return null;
|
|
706
959
|
}
|
|
707
960
|
const obj = {};
|
|
708
|
-
|
|
709
|
-
const key = result
|
|
710
|
-
const value = result
|
|
961
|
+
for (let i = 0; i < result.length; i += 2) {
|
|
962
|
+
const key = result[i];
|
|
963
|
+
const value = result[i + 1];
|
|
711
964
|
try {
|
|
712
965
|
const valueIsNumberAndNotSafeInteger = !Number.isNaN(Number(value)) && !Number.isSafeInteger(Number(value));
|
|
713
966
|
obj[key] = valueIsNumberAndNotSafeInteger ? value : JSON.parse(value);
|
|
@@ -823,6 +1076,15 @@ var HStrLenCommand = class extends Command {
|
|
|
823
1076
|
}
|
|
824
1077
|
};
|
|
825
1078
|
|
|
1079
|
+
// pkg/commands/httl.ts
|
|
1080
|
+
var HTtlCommand = class extends Command {
|
|
1081
|
+
constructor(cmd, opts) {
|
|
1082
|
+
const [key, fields] = cmd;
|
|
1083
|
+
const fieldArray = Array.isArray(fields) ? fields : [fields];
|
|
1084
|
+
super(["httl", key, "FIELDS", fieldArray.length, ...fieldArray], opts);
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
|
|
826
1088
|
// pkg/commands/hvals.ts
|
|
827
1089
|
var HValsCommand = class extends Command {
|
|
828
1090
|
constructor(cmd, opts) {
|
|
@@ -942,6 +1204,14 @@ var JsonGetCommand = class extends Command {
|
|
|
942
1204
|
}
|
|
943
1205
|
};
|
|
944
1206
|
|
|
1207
|
+
// pkg/commands/json_merge.ts
|
|
1208
|
+
var JsonMergeCommand = class extends Command {
|
|
1209
|
+
constructor(cmd, opts) {
|
|
1210
|
+
const command = ["JSON.MERGE", ...cmd];
|
|
1211
|
+
super(command, opts);
|
|
1212
|
+
}
|
|
1213
|
+
};
|
|
1214
|
+
|
|
945
1215
|
// pkg/commands/json_mget.ts
|
|
946
1216
|
var JsonMGetCommand = class extends Command {
|
|
947
1217
|
constructor(cmd, opts) {
|
|
@@ -1302,11 +1572,14 @@ var ScanCommand = class extends Command {
|
|
|
1302
1572
|
if (typeof opts?.count === "number") {
|
|
1303
1573
|
command.push("count", opts.count);
|
|
1304
1574
|
}
|
|
1305
|
-
if (opts
|
|
1575
|
+
if (opts && "withType" in opts && opts.withType === true) {
|
|
1576
|
+
command.push("withtype");
|
|
1577
|
+
} else if (opts && "type" in opts && opts.type && opts.type.length > 0) {
|
|
1306
1578
|
command.push("type", opts.type);
|
|
1307
1579
|
}
|
|
1308
1580
|
super(command, {
|
|
1309
|
-
|
|
1581
|
+
// @ts-expect-error ignore types here
|
|
1582
|
+
deserialize: opts?.withType ? deserializeScanWithTypesResponse : deserializeScanResponse,
|
|
1310
1583
|
...cmdOpts
|
|
1311
1584
|
});
|
|
1312
1585
|
}
|
|
@@ -1732,15 +2005,15 @@ var XPendingCommand = class extends Command {
|
|
|
1732
2005
|
function deserialize4(result) {
|
|
1733
2006
|
const obj = {};
|
|
1734
2007
|
for (const e of result) {
|
|
1735
|
-
|
|
1736
|
-
const streamId = e
|
|
1737
|
-
const entries = e
|
|
2008
|
+
for (let i = 0; i < e.length; i += 2) {
|
|
2009
|
+
const streamId = e[i];
|
|
2010
|
+
const entries = e[i + 1];
|
|
1738
2011
|
if (!(streamId in obj)) {
|
|
1739
2012
|
obj[streamId] = {};
|
|
1740
2013
|
}
|
|
1741
|
-
|
|
1742
|
-
const field = entries
|
|
1743
|
-
const value = entries
|
|
2014
|
+
for (let j = 0; j < entries.length; j += 2) {
|
|
2015
|
+
const field = entries[j];
|
|
2016
|
+
const value = entries[j + 1];
|
|
1744
2017
|
try {
|
|
1745
2018
|
obj[streamId][field] = JSON.parse(value);
|
|
1746
2019
|
} catch {
|
|
@@ -1829,15 +2102,15 @@ var XRevRangeCommand = class extends Command {
|
|
|
1829
2102
|
function deserialize5(result) {
|
|
1830
2103
|
const obj = {};
|
|
1831
2104
|
for (const e of result) {
|
|
1832
|
-
|
|
1833
|
-
const streamId = e
|
|
1834
|
-
const entries = e
|
|
2105
|
+
for (let i = 0; i < e.length; i += 2) {
|
|
2106
|
+
const streamId = e[i];
|
|
2107
|
+
const entries = e[i + 1];
|
|
1835
2108
|
if (!(streamId in obj)) {
|
|
1836
2109
|
obj[streamId] = {};
|
|
1837
2110
|
}
|
|
1838
|
-
|
|
1839
|
-
const field = entries
|
|
1840
|
-
const value = entries
|
|
2111
|
+
for (let j = 0; j < entries.length; j += 2) {
|
|
2112
|
+
const field = entries[j];
|
|
2113
|
+
const value = entries[j + 1];
|
|
1841
2114
|
try {
|
|
1842
2115
|
obj[streamId][field] = JSON.parse(value);
|
|
1843
2116
|
} catch {
|
|
@@ -2236,10 +2509,18 @@ var Pipeline = class {
|
|
|
2236
2509
|
* @see https://redis.io/commands/echo
|
|
2237
2510
|
*/
|
|
2238
2511
|
echo = (...args) => this.chain(new EchoCommand(args, this.commandOptions));
|
|
2512
|
+
/**
|
|
2513
|
+
* @see https://redis.io/commands/eval_ro
|
|
2514
|
+
*/
|
|
2515
|
+
evalRo = (...args) => this.chain(new EvalROCommand(args, this.commandOptions));
|
|
2239
2516
|
/**
|
|
2240
2517
|
* @see https://redis.io/commands/eval
|
|
2241
2518
|
*/
|
|
2242
2519
|
eval = (...args) => this.chain(new EvalCommand(args, this.commandOptions));
|
|
2520
|
+
/**
|
|
2521
|
+
* @see https://redis.io/commands/evalsha_ro
|
|
2522
|
+
*/
|
|
2523
|
+
evalshaRo = (...args) => this.chain(new EvalshaROCommand(args, this.commandOptions));
|
|
2243
2524
|
/**
|
|
2244
2525
|
* @see https://redis.io/commands/evalsha
|
|
2245
2526
|
*/
|
|
@@ -2300,6 +2581,10 @@ var Pipeline = class {
|
|
|
2300
2581
|
* @see https://redis.io/commands/getdel
|
|
2301
2582
|
*/
|
|
2302
2583
|
getdel = (...args) => this.chain(new GetDelCommand(args, this.commandOptions));
|
|
2584
|
+
/**
|
|
2585
|
+
* @see https://redis.io/commands/getex
|
|
2586
|
+
*/
|
|
2587
|
+
getex = (...args) => this.chain(new GetExCommand(args, this.commandOptions));
|
|
2303
2588
|
/**
|
|
2304
2589
|
* @see https://redis.io/commands/getrange
|
|
2305
2590
|
*/
|
|
@@ -2316,6 +2601,42 @@ var Pipeline = class {
|
|
|
2316
2601
|
* @see https://redis.io/commands/hexists
|
|
2317
2602
|
*/
|
|
2318
2603
|
hexists = (...args) => this.chain(new HExistsCommand(args, this.commandOptions));
|
|
2604
|
+
/**
|
|
2605
|
+
* @see https://redis.io/commands/hexpire
|
|
2606
|
+
*/
|
|
2607
|
+
hexpire = (...args) => this.chain(new HExpireCommand(args, this.commandOptions));
|
|
2608
|
+
/**
|
|
2609
|
+
* @see https://redis.io/commands/hexpireat
|
|
2610
|
+
*/
|
|
2611
|
+
hexpireat = (...args) => this.chain(new HExpireAtCommand(args, this.commandOptions));
|
|
2612
|
+
/**
|
|
2613
|
+
* @see https://redis.io/commands/hexpiretime
|
|
2614
|
+
*/
|
|
2615
|
+
hexpiretime = (...args) => this.chain(new HExpireTimeCommand(args, this.commandOptions));
|
|
2616
|
+
/**
|
|
2617
|
+
* @see https://redis.io/commands/httl
|
|
2618
|
+
*/
|
|
2619
|
+
httl = (...args) => this.chain(new HTtlCommand(args, this.commandOptions));
|
|
2620
|
+
/**
|
|
2621
|
+
* @see https://redis.io/commands/hpexpire
|
|
2622
|
+
*/
|
|
2623
|
+
hpexpire = (...args) => this.chain(new HPExpireCommand(args, this.commandOptions));
|
|
2624
|
+
/**
|
|
2625
|
+
* @see https://redis.io/commands/hpexpireat
|
|
2626
|
+
*/
|
|
2627
|
+
hpexpireat = (...args) => this.chain(new HPExpireAtCommand(args, this.commandOptions));
|
|
2628
|
+
/**
|
|
2629
|
+
* @see https://redis.io/commands/hpexpiretime
|
|
2630
|
+
*/
|
|
2631
|
+
hpexpiretime = (...args) => this.chain(new HPExpireTimeCommand(args, this.commandOptions));
|
|
2632
|
+
/**
|
|
2633
|
+
* @see https://redis.io/commands/hpttl
|
|
2634
|
+
*/
|
|
2635
|
+
hpttl = (...args) => this.chain(new HPTtlCommand(args, this.commandOptions));
|
|
2636
|
+
/**
|
|
2637
|
+
* @see https://redis.io/commands/hpersist
|
|
2638
|
+
*/
|
|
2639
|
+
hpersist = (...args) => this.chain(new HPersistCommand(args, this.commandOptions));
|
|
2319
2640
|
/**
|
|
2320
2641
|
* @see https://redis.io/commands/hget
|
|
2321
2642
|
*/
|
|
@@ -2833,6 +3154,10 @@ var Pipeline = class {
|
|
|
2833
3154
|
* @see https://redis.io/commands/json.get
|
|
2834
3155
|
*/
|
|
2835
3156
|
get: (...args) => this.chain(new JsonGetCommand(args, this.commandOptions)),
|
|
3157
|
+
/**
|
|
3158
|
+
* @see https://redis.io/commands/json.merge
|
|
3159
|
+
*/
|
|
3160
|
+
merge: (...args) => this.chain(new JsonMergeCommand(args, this.commandOptions)),
|
|
2836
3161
|
/**
|
|
2837
3162
|
* @see https://redis.io/commands/json.mget
|
|
2838
3163
|
*/
|
|
@@ -2886,6 +3211,24 @@ var Pipeline = class {
|
|
|
2886
3211
|
};
|
|
2887
3212
|
|
|
2888
3213
|
// pkg/auto-pipeline.ts
|
|
3214
|
+
var EXCLUDE_COMMANDS = /* @__PURE__ */ new Set([
|
|
3215
|
+
"scan",
|
|
3216
|
+
"keys",
|
|
3217
|
+
"flushdb",
|
|
3218
|
+
"flushall",
|
|
3219
|
+
"dbsize",
|
|
3220
|
+
"hscan",
|
|
3221
|
+
"hgetall",
|
|
3222
|
+
"hkeys",
|
|
3223
|
+
"lrange",
|
|
3224
|
+
"sscan",
|
|
3225
|
+
"smembers",
|
|
3226
|
+
"xrange",
|
|
3227
|
+
"xrevrange",
|
|
3228
|
+
"zscan",
|
|
3229
|
+
"zrange",
|
|
3230
|
+
"exec"
|
|
3231
|
+
]);
|
|
2889
3232
|
function createAutoPipelineProxy(_redis, json) {
|
|
2890
3233
|
const redis = _redis;
|
|
2891
3234
|
if (!redis.autoPipelineExecutor) {
|
|
@@ -2900,7 +3243,8 @@ function createAutoPipelineProxy(_redis, json) {
|
|
|
2900
3243
|
return createAutoPipelineProxy(redis2, true);
|
|
2901
3244
|
}
|
|
2902
3245
|
const commandInRedisButNotPipeline = command in redis2 && !(command in redis2.autoPipelineExecutor.pipeline);
|
|
2903
|
-
|
|
3246
|
+
const isCommandExcluded = EXCLUDE_COMMANDS.has(command);
|
|
3247
|
+
if (commandInRedisButNotPipeline || isCommandExcluded) {
|
|
2904
3248
|
return redis2[command];
|
|
2905
3249
|
}
|
|
2906
3250
|
const isFunction = json ? typeof redis2.autoPipelineExecutor.pipeline.json[command] === "function" : typeof redis2.autoPipelineExecutor.pipeline[command] === "function";
|
|
@@ -2964,28 +3308,230 @@ var AutoPipelineExecutor = class {
|
|
|
2964
3308
|
}
|
|
2965
3309
|
};
|
|
2966
3310
|
|
|
3311
|
+
// pkg/commands/psubscribe.ts
|
|
3312
|
+
var PSubscribeCommand = class extends Command {
|
|
3313
|
+
constructor(cmd, opts) {
|
|
3314
|
+
const sseHeaders = {
|
|
3315
|
+
Accept: "text/event-stream",
|
|
3316
|
+
"Cache-Control": "no-cache",
|
|
3317
|
+
Connection: "keep-alive"
|
|
3318
|
+
};
|
|
3319
|
+
super([], {
|
|
3320
|
+
...opts,
|
|
3321
|
+
headers: sseHeaders,
|
|
3322
|
+
path: ["psubscribe", ...cmd],
|
|
3323
|
+
streamOptions: {
|
|
3324
|
+
isStreaming: true,
|
|
3325
|
+
onMessage: opts?.streamOptions?.onMessage,
|
|
3326
|
+
signal: opts?.streamOptions?.signal
|
|
3327
|
+
}
|
|
3328
|
+
});
|
|
3329
|
+
}
|
|
3330
|
+
};
|
|
3331
|
+
|
|
3332
|
+
// pkg/commands/subscribe.ts
|
|
3333
|
+
var Subscriber = class extends EventTarget {
|
|
3334
|
+
subscriptions;
|
|
3335
|
+
client;
|
|
3336
|
+
listeners;
|
|
3337
|
+
opts;
|
|
3338
|
+
constructor(client, channels, isPattern = false, opts) {
|
|
3339
|
+
super();
|
|
3340
|
+
this.client = client;
|
|
3341
|
+
this.subscriptions = /* @__PURE__ */ new Map();
|
|
3342
|
+
this.listeners = /* @__PURE__ */ new Map();
|
|
3343
|
+
this.opts = opts;
|
|
3344
|
+
for (const channel of channels) {
|
|
3345
|
+
if (isPattern) {
|
|
3346
|
+
this.subscribeToPattern(channel);
|
|
3347
|
+
} else {
|
|
3348
|
+
this.subscribeToChannel(channel);
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3351
|
+
}
|
|
3352
|
+
subscribeToChannel(channel) {
|
|
3353
|
+
const controller = new AbortController();
|
|
3354
|
+
const command = new SubscribeCommand([channel], {
|
|
3355
|
+
streamOptions: {
|
|
3356
|
+
signal: controller.signal,
|
|
3357
|
+
onMessage: (data) => this.handleMessage(data, false)
|
|
3358
|
+
}
|
|
3359
|
+
});
|
|
3360
|
+
command.exec(this.client).catch((error) => {
|
|
3361
|
+
if (error.name !== "AbortError") {
|
|
3362
|
+
this.dispatchToListeners("error", error);
|
|
3363
|
+
}
|
|
3364
|
+
});
|
|
3365
|
+
this.subscriptions.set(channel, {
|
|
3366
|
+
command,
|
|
3367
|
+
controller,
|
|
3368
|
+
isPattern: false
|
|
3369
|
+
});
|
|
3370
|
+
}
|
|
3371
|
+
subscribeToPattern(pattern) {
|
|
3372
|
+
const controller = new AbortController();
|
|
3373
|
+
const command = new PSubscribeCommand([pattern], {
|
|
3374
|
+
streamOptions: {
|
|
3375
|
+
signal: controller.signal,
|
|
3376
|
+
onMessage: (data) => this.handleMessage(data, true)
|
|
3377
|
+
}
|
|
3378
|
+
});
|
|
3379
|
+
command.exec(this.client).catch((error) => {
|
|
3380
|
+
if (error.name !== "AbortError") {
|
|
3381
|
+
this.dispatchToListeners("error", error);
|
|
3382
|
+
}
|
|
3383
|
+
});
|
|
3384
|
+
this.subscriptions.set(pattern, {
|
|
3385
|
+
command,
|
|
3386
|
+
controller,
|
|
3387
|
+
isPattern: true
|
|
3388
|
+
});
|
|
3389
|
+
}
|
|
3390
|
+
handleMessage(data, isPattern) {
|
|
3391
|
+
const messageData = data.replace(/^data:\s*/, "");
|
|
3392
|
+
const firstCommaIndex = messageData.indexOf(",");
|
|
3393
|
+
const secondCommaIndex = messageData.indexOf(",", firstCommaIndex + 1);
|
|
3394
|
+
const thirdCommaIndex = isPattern ? messageData.indexOf(",", secondCommaIndex + 1) : -1;
|
|
3395
|
+
if (firstCommaIndex !== -1 && secondCommaIndex !== -1) {
|
|
3396
|
+
const type = messageData.slice(0, firstCommaIndex);
|
|
3397
|
+
if (isPattern && type === "pmessage" && thirdCommaIndex !== -1) {
|
|
3398
|
+
const pattern = messageData.slice(firstCommaIndex + 1, secondCommaIndex);
|
|
3399
|
+
const channel = messageData.slice(secondCommaIndex + 1, thirdCommaIndex);
|
|
3400
|
+
const messageStr = messageData.slice(thirdCommaIndex + 1);
|
|
3401
|
+
try {
|
|
3402
|
+
const message = this.opts?.automaticDeserialization === false ? messageStr : JSON.parse(messageStr);
|
|
3403
|
+
this.dispatchToListeners("pmessage", { pattern, channel, message });
|
|
3404
|
+
this.dispatchToListeners(`pmessage:${pattern}`, { pattern, channel, message });
|
|
3405
|
+
} catch (error) {
|
|
3406
|
+
this.dispatchToListeners("error", new Error(`Failed to parse message: ${error}`));
|
|
3407
|
+
}
|
|
3408
|
+
} else {
|
|
3409
|
+
const channel = messageData.slice(firstCommaIndex + 1, secondCommaIndex);
|
|
3410
|
+
const messageStr = messageData.slice(secondCommaIndex + 1);
|
|
3411
|
+
try {
|
|
3412
|
+
if (type === "subscribe" || type === "psubscribe" || type === "unsubscribe" || type === "punsubscribe") {
|
|
3413
|
+
const count = Number.parseInt(messageStr);
|
|
3414
|
+
this.dispatchToListeners(type, count);
|
|
3415
|
+
} else {
|
|
3416
|
+
const message = this.opts?.automaticDeserialization === false ? messageStr : parseWithTryCatch(messageStr);
|
|
3417
|
+
this.dispatchToListeners(type, { channel, message });
|
|
3418
|
+
this.dispatchToListeners(`${type}:${channel}`, { channel, message });
|
|
3419
|
+
}
|
|
3420
|
+
} catch (error) {
|
|
3421
|
+
this.dispatchToListeners("error", new Error(`Failed to parse message: ${error}`));
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
dispatchToListeners(type, data) {
|
|
3427
|
+
const listeners = this.listeners.get(type);
|
|
3428
|
+
if (listeners) {
|
|
3429
|
+
for (const listener of listeners) {
|
|
3430
|
+
listener(data);
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3433
|
+
}
|
|
3434
|
+
on(type, listener) {
|
|
3435
|
+
if (!this.listeners.has(type)) {
|
|
3436
|
+
this.listeners.set(type, /* @__PURE__ */ new Set());
|
|
3437
|
+
}
|
|
3438
|
+
this.listeners.get(type)?.add(listener);
|
|
3439
|
+
}
|
|
3440
|
+
removeAllListeners() {
|
|
3441
|
+
this.listeners.clear();
|
|
3442
|
+
}
|
|
3443
|
+
async unsubscribe(channels) {
|
|
3444
|
+
if (channels) {
|
|
3445
|
+
for (const channel of channels) {
|
|
3446
|
+
const subscription = this.subscriptions.get(channel);
|
|
3447
|
+
if (subscription) {
|
|
3448
|
+
try {
|
|
3449
|
+
subscription.controller.abort();
|
|
3450
|
+
} catch {
|
|
3451
|
+
}
|
|
3452
|
+
this.subscriptions.delete(channel);
|
|
3453
|
+
}
|
|
3454
|
+
}
|
|
3455
|
+
} else {
|
|
3456
|
+
for (const subscription of this.subscriptions.values()) {
|
|
3457
|
+
try {
|
|
3458
|
+
subscription.controller.abort();
|
|
3459
|
+
} catch {
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
this.subscriptions.clear();
|
|
3463
|
+
this.removeAllListeners();
|
|
3464
|
+
}
|
|
3465
|
+
}
|
|
3466
|
+
getSubscribedChannels() {
|
|
3467
|
+
return [...this.subscriptions.keys()];
|
|
3468
|
+
}
|
|
3469
|
+
};
|
|
3470
|
+
var SubscribeCommand = class extends Command {
|
|
3471
|
+
constructor(cmd, opts) {
|
|
3472
|
+
const sseHeaders = {
|
|
3473
|
+
Accept: "text/event-stream",
|
|
3474
|
+
"Cache-Control": "no-cache",
|
|
3475
|
+
Connection: "keep-alive"
|
|
3476
|
+
};
|
|
3477
|
+
super([], {
|
|
3478
|
+
...opts,
|
|
3479
|
+
headers: sseHeaders,
|
|
3480
|
+
path: ["subscribe", ...cmd],
|
|
3481
|
+
streamOptions: {
|
|
3482
|
+
isStreaming: true,
|
|
3483
|
+
onMessage: opts?.streamOptions?.onMessage,
|
|
3484
|
+
signal: opts?.streamOptions?.signal
|
|
3485
|
+
}
|
|
3486
|
+
});
|
|
3487
|
+
}
|
|
3488
|
+
};
|
|
3489
|
+
var parseWithTryCatch = (str) => {
|
|
3490
|
+
try {
|
|
3491
|
+
return JSON.parse(str);
|
|
3492
|
+
} catch {
|
|
3493
|
+
return str;
|
|
3494
|
+
}
|
|
3495
|
+
};
|
|
3496
|
+
|
|
2967
3497
|
// pkg/script.ts
|
|
2968
|
-
import
|
|
2969
|
-
import sha1 from "crypto-js/sha1.js";
|
|
3498
|
+
import { subtle } from "uncrypto";
|
|
2970
3499
|
var Script = class {
|
|
2971
3500
|
script;
|
|
3501
|
+
/**
|
|
3502
|
+
* @deprecated This property is initialized to an empty string and will be set in the init method
|
|
3503
|
+
* asynchronously. Do not use this property immidiately after the constructor.
|
|
3504
|
+
*
|
|
3505
|
+
* This property is only exposed for backwards compatibility and will be removed in the
|
|
3506
|
+
* future major release.
|
|
3507
|
+
*/
|
|
2972
3508
|
sha1;
|
|
2973
3509
|
redis;
|
|
2974
3510
|
constructor(redis, script) {
|
|
2975
3511
|
this.redis = redis;
|
|
2976
|
-
this.sha1 = this.digest(script);
|
|
2977
3512
|
this.script = script;
|
|
3513
|
+
this.sha1 = "";
|
|
3514
|
+
void this.init(script);
|
|
3515
|
+
}
|
|
3516
|
+
/**
|
|
3517
|
+
* Initialize the script by computing its SHA-1 hash.
|
|
3518
|
+
*/
|
|
3519
|
+
async init(script) {
|
|
3520
|
+
if (this.sha1) return;
|
|
3521
|
+
this.sha1 = await this.digest(script);
|
|
2978
3522
|
}
|
|
2979
3523
|
/**
|
|
2980
3524
|
* Send an `EVAL` command to redis.
|
|
2981
3525
|
*/
|
|
2982
3526
|
async eval(keys, args) {
|
|
3527
|
+
await this.init(this.script);
|
|
2983
3528
|
return await this.redis.eval(this.script, keys, args);
|
|
2984
3529
|
}
|
|
2985
3530
|
/**
|
|
2986
3531
|
* Calculates the sha1 hash of the script and then calls `EVALSHA`.
|
|
2987
3532
|
*/
|
|
2988
3533
|
async evalsha(keys, args) {
|
|
3534
|
+
await this.init(this.script);
|
|
2989
3535
|
return await this.redis.evalsha(this.sha1, keys, args);
|
|
2990
3536
|
}
|
|
2991
3537
|
/**
|
|
@@ -2995,6 +3541,7 @@ var Script = class {
|
|
|
2995
3541
|
* Following calls will be able to use the cached script
|
|
2996
3542
|
*/
|
|
2997
3543
|
async exec(keys, args) {
|
|
3544
|
+
await this.init(this.script);
|
|
2998
3545
|
const res = await this.redis.evalsha(this.sha1, keys, args).catch(async (error) => {
|
|
2999
3546
|
if (error instanceof Error && error.message.toLowerCase().includes("noscript")) {
|
|
3000
3547
|
return await this.redis.eval(this.script, keys, args);
|
|
@@ -3006,8 +3553,75 @@ var Script = class {
|
|
|
3006
3553
|
/**
|
|
3007
3554
|
* Compute the sha1 hash of the script and return its hex representation.
|
|
3008
3555
|
*/
|
|
3009
|
-
digest(s) {
|
|
3010
|
-
|
|
3556
|
+
async digest(s) {
|
|
3557
|
+
const data = new TextEncoder().encode(s);
|
|
3558
|
+
const hashBuffer = await subtle.digest("SHA-1", data);
|
|
3559
|
+
const hashArray = [...new Uint8Array(hashBuffer)];
|
|
3560
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3561
|
+
}
|
|
3562
|
+
};
|
|
3563
|
+
|
|
3564
|
+
// pkg/scriptRo.ts
|
|
3565
|
+
import { subtle as subtle2 } from "uncrypto";
|
|
3566
|
+
var ScriptRO = class {
|
|
3567
|
+
script;
|
|
3568
|
+
/**
|
|
3569
|
+
* @deprecated This property is initialized to an empty string and will be set in the init method
|
|
3570
|
+
* asynchronously. Do not use this property immidiately after the constructor.
|
|
3571
|
+
*
|
|
3572
|
+
* This property is only exposed for backwards compatibility and will be removed in the
|
|
3573
|
+
* future major release.
|
|
3574
|
+
*/
|
|
3575
|
+
sha1;
|
|
3576
|
+
redis;
|
|
3577
|
+
constructor(redis, script) {
|
|
3578
|
+
this.redis = redis;
|
|
3579
|
+
this.sha1 = "";
|
|
3580
|
+
this.script = script;
|
|
3581
|
+
void this.init(script);
|
|
3582
|
+
}
|
|
3583
|
+
async init(script) {
|
|
3584
|
+
if (this.sha1) return;
|
|
3585
|
+
this.sha1 = await this.digest(script);
|
|
3586
|
+
}
|
|
3587
|
+
/**
|
|
3588
|
+
* Send an `EVAL_RO` command to redis.
|
|
3589
|
+
*/
|
|
3590
|
+
async evalRo(keys, args) {
|
|
3591
|
+
await this.init(this.script);
|
|
3592
|
+
return await this.redis.evalRo(this.script, keys, args);
|
|
3593
|
+
}
|
|
3594
|
+
/**
|
|
3595
|
+
* Calculates the sha1 hash of the script and then calls `EVALSHA_RO`.
|
|
3596
|
+
*/
|
|
3597
|
+
async evalshaRo(keys, args) {
|
|
3598
|
+
await this.init(this.script);
|
|
3599
|
+
return await this.redis.evalshaRo(this.sha1, keys, args);
|
|
3600
|
+
}
|
|
3601
|
+
/**
|
|
3602
|
+
* Optimistically try to run `EVALSHA_RO` first.
|
|
3603
|
+
* If the script is not loaded in redis, it will fall back and try again with `EVAL_RO`.
|
|
3604
|
+
*
|
|
3605
|
+
* Following calls will be able to use the cached script
|
|
3606
|
+
*/
|
|
3607
|
+
async exec(keys, args) {
|
|
3608
|
+
await this.init(this.script);
|
|
3609
|
+
const res = await this.redis.evalshaRo(this.sha1, keys, args).catch(async (error) => {
|
|
3610
|
+
if (error instanceof Error && error.message.toLowerCase().includes("noscript")) {
|
|
3611
|
+
return await this.redis.evalRo(this.script, keys, args);
|
|
3612
|
+
}
|
|
3613
|
+
throw error;
|
|
3614
|
+
});
|
|
3615
|
+
return res;
|
|
3616
|
+
}
|
|
3617
|
+
/**
|
|
3618
|
+
* Compute the sha1 hash of the script and return its hex representation.
|
|
3619
|
+
*/
|
|
3620
|
+
async digest(s) {
|
|
3621
|
+
const data = new TextEncoder().encode(s);
|
|
3622
|
+
const hashBuffer = await subtle2.digest("SHA-1", data);
|
|
3623
|
+
const hashArray = [...new Uint8Array(hashBuffer)];
|
|
3624
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3011
3625
|
}
|
|
3012
3626
|
};
|
|
3013
3627
|
|
|
@@ -3085,6 +3699,10 @@ var Redis = class {
|
|
|
3085
3699
|
* @see https://redis.io/commands/json.get
|
|
3086
3700
|
*/
|
|
3087
3701
|
get: (...args) => new JsonGetCommand(args, this.opts).exec(this.client),
|
|
3702
|
+
/**
|
|
3703
|
+
* @see https://redis.io/commands/json.merge
|
|
3704
|
+
*/
|
|
3705
|
+
merge: (...args) => new JsonMergeCommand(args, this.opts).exec(this.client),
|
|
3088
3706
|
/**
|
|
3089
3707
|
* @see https://redis.io/commands/json.mget
|
|
3090
3708
|
*/
|
|
@@ -3154,8 +3772,36 @@ var Redis = class {
|
|
|
3154
3772
|
} catch {
|
|
3155
3773
|
}
|
|
3156
3774
|
};
|
|
3157
|
-
|
|
3158
|
-
|
|
3775
|
+
/**
|
|
3776
|
+
* Creates a new script.
|
|
3777
|
+
*
|
|
3778
|
+
* Scripts offer the ability to optimistically try to execute a script without having to send the
|
|
3779
|
+
* entire script to the server. If the script is loaded on the server, it tries again by sending
|
|
3780
|
+
* the entire script. Afterwards, the script is cached on the server.
|
|
3781
|
+
*
|
|
3782
|
+
* @param script - The script to create
|
|
3783
|
+
* @param opts - Optional options to pass to the script `{ readonly?: boolean }`
|
|
3784
|
+
* @returns A new script
|
|
3785
|
+
*
|
|
3786
|
+
* @example
|
|
3787
|
+
* ```ts
|
|
3788
|
+
* const redis = new Redis({...})
|
|
3789
|
+
*
|
|
3790
|
+
* const script = redis.createScript<string>("return ARGV[1];")
|
|
3791
|
+
* const arg1 = await script.eval([], ["Hello World"])
|
|
3792
|
+
* expect(arg1, "Hello World")
|
|
3793
|
+
* ```
|
|
3794
|
+
* @example
|
|
3795
|
+
* ```ts
|
|
3796
|
+
* const redis = new Redis({...})
|
|
3797
|
+
*
|
|
3798
|
+
* const script = redis.createScript<string>("return ARGV[1];", { readonly: true })
|
|
3799
|
+
* const arg1 = await script.evalRo([], ["Hello World"])
|
|
3800
|
+
* expect(arg1, "Hello World")
|
|
3801
|
+
* ```
|
|
3802
|
+
*/
|
|
3803
|
+
createScript(script, opts) {
|
|
3804
|
+
return opts?.readonly ? new ScriptRO(this, script) : new Script(this, script);
|
|
3159
3805
|
}
|
|
3160
3806
|
/**
|
|
3161
3807
|
* Create a new pipeline that allows you to send requests in bulk.
|
|
@@ -3242,14 +3888,26 @@ var Redis = class {
|
|
|
3242
3888
|
* @see https://redis.io/commands/echo
|
|
3243
3889
|
*/
|
|
3244
3890
|
echo = (...args) => new EchoCommand(args, this.opts).exec(this.client);
|
|
3891
|
+
/**
|
|
3892
|
+
* @see https://redis.io/commands/eval_ro
|
|
3893
|
+
*/
|
|
3894
|
+
evalRo = (...args) => new EvalROCommand(args, this.opts).exec(this.client);
|
|
3245
3895
|
/**
|
|
3246
3896
|
* @see https://redis.io/commands/eval
|
|
3247
3897
|
*/
|
|
3248
3898
|
eval = (...args) => new EvalCommand(args, this.opts).exec(this.client);
|
|
3899
|
+
/**
|
|
3900
|
+
* @see https://redis.io/commands/evalsha_ro
|
|
3901
|
+
*/
|
|
3902
|
+
evalshaRo = (...args) => new EvalshaROCommand(args, this.opts).exec(this.client);
|
|
3249
3903
|
/**
|
|
3250
3904
|
* @see https://redis.io/commands/evalsha
|
|
3251
3905
|
*/
|
|
3252
3906
|
evalsha = (...args) => new EvalshaCommand(args, this.opts).exec(this.client);
|
|
3907
|
+
/**
|
|
3908
|
+
* Generic method to execute any Redis command.
|
|
3909
|
+
*/
|
|
3910
|
+
exec = (args) => new ExecCommand(args, this.opts).exec(this.client);
|
|
3253
3911
|
/**
|
|
3254
3912
|
* @see https://redis.io/commands/exists
|
|
3255
3913
|
*/
|
|
@@ -3306,6 +3964,10 @@ var Redis = class {
|
|
|
3306
3964
|
* @see https://redis.io/commands/getdel
|
|
3307
3965
|
*/
|
|
3308
3966
|
getdel = (...args) => new GetDelCommand(args, this.opts).exec(this.client);
|
|
3967
|
+
/**
|
|
3968
|
+
* @see https://redis.io/commands/getex
|
|
3969
|
+
*/
|
|
3970
|
+
getex = (...args) => new GetExCommand(args, this.opts).exec(this.client);
|
|
3309
3971
|
/**
|
|
3310
3972
|
* @see https://redis.io/commands/getrange
|
|
3311
3973
|
*/
|
|
@@ -3322,6 +3984,42 @@ var Redis = class {
|
|
|
3322
3984
|
* @see https://redis.io/commands/hexists
|
|
3323
3985
|
*/
|
|
3324
3986
|
hexists = (...args) => new HExistsCommand(args, this.opts).exec(this.client);
|
|
3987
|
+
/**
|
|
3988
|
+
* @see https://redis.io/commands/hexpire
|
|
3989
|
+
*/
|
|
3990
|
+
hexpire = (...args) => new HExpireCommand(args, this.opts).exec(this.client);
|
|
3991
|
+
/**
|
|
3992
|
+
* @see https://redis.io/commands/hexpireat
|
|
3993
|
+
*/
|
|
3994
|
+
hexpireat = (...args) => new HExpireAtCommand(args, this.opts).exec(this.client);
|
|
3995
|
+
/**
|
|
3996
|
+
* @see https://redis.io/commands/hexpiretime
|
|
3997
|
+
*/
|
|
3998
|
+
hexpiretime = (...args) => new HExpireTimeCommand(args, this.opts).exec(this.client);
|
|
3999
|
+
/**
|
|
4000
|
+
* @see https://redis.io/commands/httl
|
|
4001
|
+
*/
|
|
4002
|
+
httl = (...args) => new HTtlCommand(args, this.opts).exec(this.client);
|
|
4003
|
+
/**
|
|
4004
|
+
* @see https://redis.io/commands/hpexpire
|
|
4005
|
+
*/
|
|
4006
|
+
hpexpire = (...args) => new HPExpireCommand(args, this.opts).exec(this.client);
|
|
4007
|
+
/**
|
|
4008
|
+
* @see https://redis.io/commands/hpexpireat
|
|
4009
|
+
*/
|
|
4010
|
+
hpexpireat = (...args) => new HPExpireAtCommand(args, this.opts).exec(this.client);
|
|
4011
|
+
/**
|
|
4012
|
+
* @see https://redis.io/commands/hpexpiretime
|
|
4013
|
+
*/
|
|
4014
|
+
hpexpiretime = (...args) => new HPExpireTimeCommand(args, this.opts).exec(this.client);
|
|
4015
|
+
/**
|
|
4016
|
+
* @see https://redis.io/commands/hpttl
|
|
4017
|
+
*/
|
|
4018
|
+
hpttl = (...args) => new HPTtlCommand(args, this.opts).exec(this.client);
|
|
4019
|
+
/**
|
|
4020
|
+
* @see https://redis.io/commands/hpersist
|
|
4021
|
+
*/
|
|
4022
|
+
hpersist = (...args) => new HPersistCommand(args, this.opts).exec(this.client);
|
|
3325
4023
|
/**
|
|
3326
4024
|
* @see https://redis.io/commands/hget
|
|
3327
4025
|
*/
|
|
@@ -3490,6 +4188,13 @@ var Redis = class {
|
|
|
3490
4188
|
* @see https://redis.io/commands/psetex
|
|
3491
4189
|
*/
|
|
3492
4190
|
psetex = (key, ttl, value) => new PSetEXCommand([key, ttl, value], this.opts).exec(this.client);
|
|
4191
|
+
/**
|
|
4192
|
+
* @see https://redis.io/commands/psubscribe
|
|
4193
|
+
*/
|
|
4194
|
+
psubscribe = (patterns) => {
|
|
4195
|
+
const patternArray = Array.isArray(patterns) ? patterns : [patterns];
|
|
4196
|
+
return new Subscriber(this.client, patternArray, true, this.opts);
|
|
4197
|
+
};
|
|
3493
4198
|
/**
|
|
3494
4199
|
* @see https://redis.io/commands/pttl
|
|
3495
4200
|
*/
|
|
@@ -3526,10 +4231,9 @@ var Redis = class {
|
|
|
3526
4231
|
* @see https://redis.io/commands/sadd
|
|
3527
4232
|
*/
|
|
3528
4233
|
sadd = (key, member, ...members) => new SAddCommand([key, member, ...members], this.opts).exec(this.client);
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
scan = (...args) => new ScanCommand(args, this.opts).exec(this.client);
|
|
4234
|
+
scan(cursor, opts) {
|
|
4235
|
+
return new ScanCommand([cursor, opts], this.opts).exec(this.client);
|
|
4236
|
+
}
|
|
3533
4237
|
/**
|
|
3534
4238
|
* @see https://redis.io/commands/scard
|
|
3535
4239
|
*/
|
|
@@ -3618,6 +4322,13 @@ var Redis = class {
|
|
|
3618
4322
|
* @see https://redis.io/commands/strlen
|
|
3619
4323
|
*/
|
|
3620
4324
|
strlen = (...args) => new StrLenCommand(args, this.opts).exec(this.client);
|
|
4325
|
+
/**
|
|
4326
|
+
* @see https://redis.io/commands/subscribe
|
|
4327
|
+
*/
|
|
4328
|
+
subscribe = (channels) => {
|
|
4329
|
+
const channelArray = Array.isArray(channels) ? channels : [channels];
|
|
4330
|
+
return new Subscriber(this.client, channelArray, false, this.opts);
|
|
4331
|
+
};
|
|
3621
4332
|
/**
|
|
3622
4333
|
* @see https://redis.io/commands/sunion
|
|
3623
4334
|
*/
|