@upstash/redis 1.4.0-next.2 → 1.6.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/esm/pkg/commands/script_exists.js +1 -10
- package/esm/pkg/http.js +35 -7
- package/esm/platforms/cloudflare.js +5 -25
- package/esm/platforms/fastly.js +4 -25
- package/esm/platforms/node_with_fetch.js +4 -25
- package/esm/platforms/nodejs.js +4 -25
- package/package.json +25 -14
- package/script/pkg/commands/script_exists.js +1 -10
- package/script/pkg/http.js +35 -7
- package/script/platforms/cloudflare.js +5 -25
- package/script/platforms/fastly.js +4 -25
- package/script/platforms/node_with_fetch.js +4 -25
- package/script/platforms/nodejs.js +4 -25
- package/types/pkg/commands/hmset.d.ts +2 -2
- package/types/pkg/commands/script_exists.d.ts +2 -4
- package/types/pkg/commands/sinterstore.d.ts +2 -2
- package/types/pkg/commands/spop.d.ts +1 -1
- package/types/pkg/http.d.ts +27 -3
- package/types/pkg/pipeline.d.ts +2 -2
- package/types/pkg/redis.d.ts +4 -4
- package/types/platforms/cloudflare.d.ts +6 -2
- package/types/platforms/fastly.d.ts +5 -1
- package/types/platforms/node_with_fetch.d.ts +20 -1
- package/types/platforms/nodejs.d.ts +20 -1
|
@@ -5,16 +5,7 @@ import { Command } from "./command.js";
|
|
|
5
5
|
export class ScriptExistsCommand extends Command {
|
|
6
6
|
constructor(hashes, opts) {
|
|
7
7
|
super(["script", "exists", ...hashes], {
|
|
8
|
-
deserialize: (result) =>
|
|
9
|
-
/**
|
|
10
|
-
* This isn't very pretty but it does the job.
|
|
11
|
-
* The user facing api is clean and will return a single `string` if they provided
|
|
12
|
-
* a single script hash, and an array of strings of the same length when given an
|
|
13
|
-
* array of hashes.
|
|
14
|
-
*/
|
|
15
|
-
const parsed = result;
|
|
16
|
-
return parsed.length === 1 ? parsed[0] : parsed;
|
|
17
|
-
},
|
|
8
|
+
deserialize: (result) => result,
|
|
18
9
|
...opts,
|
|
19
10
|
});
|
|
20
11
|
}
|
package/esm/pkg/http.js
CHANGED
|
@@ -19,14 +19,30 @@ export class HttpClient {
|
|
|
19
19
|
writable: true,
|
|
20
20
|
value: void 0
|
|
21
21
|
});
|
|
22
|
+
Object.defineProperty(this, "retry", {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
writable: true,
|
|
26
|
+
value: void 0
|
|
27
|
+
});
|
|
22
28
|
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
23
29
|
this.headers = { "Content-Type": "application/json", ...config.headers };
|
|
24
|
-
this.options = config.options;
|
|
30
|
+
this.options = { backend: config.options?.backend };
|
|
31
|
+
if (typeof config?.retry === "boolean" && config?.retry === false) {
|
|
32
|
+
this.retry = {
|
|
33
|
+
attempts: 1,
|
|
34
|
+
backoff: () => 0,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
this.retry = {
|
|
39
|
+
attempts: config?.retry?.retries ?? 5,
|
|
40
|
+
backoff: config?.retry?.backoff ??
|
|
41
|
+
((retryCount) => Math.exp(retryCount) * 50),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
25
44
|
}
|
|
26
45
|
async request(req) {
|
|
27
|
-
if (!req.path) {
|
|
28
|
-
req.path = [];
|
|
29
|
-
}
|
|
30
46
|
const requestOptions = {
|
|
31
47
|
method: "POST",
|
|
32
48
|
headers: this.headers,
|
|
@@ -37,9 +53,21 @@ export class HttpClient {
|
|
|
37
53
|
*/
|
|
38
54
|
backend: this.options?.backend,
|
|
39
55
|
};
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
56
|
+
let res = null;
|
|
57
|
+
let error = null;
|
|
58
|
+
for (let i = 0; i <= this.retry.attempts; i++) {
|
|
59
|
+
try {
|
|
60
|
+
res = await fetch([this.baseUrl, ...(req.path ?? [])].join("/"), requestOptions);
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
error = err;
|
|
65
|
+
await new Promise((r) => setTimeout(r, this.retry.backoff(i)));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (!res) {
|
|
69
|
+
throw error ?? new Error("Exhausted all retries");
|
|
70
|
+
}
|
|
43
71
|
const body = (await res.json());
|
|
44
72
|
if (!res.ok) {
|
|
45
73
|
throw new UpstashError(body.error);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as core from "../pkg/redis.js";
|
|
2
|
-
import {
|
|
2
|
+
import { HttpClient } from "../pkg/http.js";
|
|
3
3
|
/**
|
|
4
4
|
* Serverless redis client for upstash.
|
|
5
5
|
*/
|
|
@@ -26,7 +26,8 @@ export class Redis extends core.Redis {
|
|
|
26
26
|
/\r|\n/.test(config.token)) {
|
|
27
27
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
28
28
|
}
|
|
29
|
-
const client =
|
|
29
|
+
const client = new HttpClient({
|
|
30
|
+
retry: config.retry,
|
|
30
31
|
baseUrl: config.url,
|
|
31
32
|
headers: { authorization: `Bearer ${config.token}` },
|
|
32
33
|
});
|
|
@@ -44,9 +45,8 @@ export class Redis extends core.Redis {
|
|
|
44
45
|
* ```ts
|
|
45
46
|
* const redis = Redis.fromEnv(env)
|
|
46
47
|
* ```
|
|
47
|
-
*
|
|
48
48
|
*/
|
|
49
|
-
static fromEnv(env) {
|
|
49
|
+
static fromEnv(env, opts) {
|
|
50
50
|
// @ts-ignore These will be defined by cloudflare
|
|
51
51
|
const url = env?.UPSTASH_REDIS_REST_URL ?? UPSTASH_REDIS_REST_URL;
|
|
52
52
|
// @ts-ignore These will be defined by cloudflare
|
|
@@ -57,26 +57,6 @@ export class Redis extends core.Redis {
|
|
|
57
57
|
if (!token) {
|
|
58
58
|
throw new Error("Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_TOKEN`");
|
|
59
59
|
}
|
|
60
|
-
return new Redis({ url, token });
|
|
60
|
+
return new Redis({ ...opts, url, token });
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
function defaultRequester(config) {
|
|
64
|
-
return {
|
|
65
|
-
request: async function (req) {
|
|
66
|
-
if (!req.path) {
|
|
67
|
-
req.path = [];
|
|
68
|
-
}
|
|
69
|
-
const res = await fetch([config.baseUrl, ...req.path].join("/"), {
|
|
70
|
-
method: "POST",
|
|
71
|
-
headers: { "Content-Type": "application/json", ...config.headers },
|
|
72
|
-
body: JSON.stringify(req.body),
|
|
73
|
-
keepalive: true,
|
|
74
|
-
});
|
|
75
|
-
const body = (await res.json());
|
|
76
|
-
if (!res.ok) {
|
|
77
|
-
throw new UpstashError(body.error);
|
|
78
|
-
}
|
|
79
|
-
return body;
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
}
|
package/esm/platforms/fastly.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as core from "../pkg/redis.js";
|
|
2
|
-
import {
|
|
2
|
+
import { HttpClient } from "../pkg/http.js";
|
|
3
3
|
/**
|
|
4
4
|
* Serverless redis client for upstash.
|
|
5
5
|
*/
|
|
@@ -27,35 +27,14 @@ export class Redis extends core.Redis {
|
|
|
27
27
|
/\r|\n/.test(config.token)) {
|
|
28
28
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
29
29
|
}
|
|
30
|
-
const client =
|
|
30
|
+
const client = new HttpClient({
|
|
31
31
|
baseUrl: config.url,
|
|
32
|
+
retry: config.retry,
|
|
32
33
|
headers: { authorization: `Bearer ${config.token}` },
|
|
33
|
-
backend: config.backend,
|
|
34
|
+
options: { backend: config.backend },
|
|
34
35
|
});
|
|
35
36
|
super(client, {
|
|
36
37
|
automaticDeserialization: config.automaticDeserialization,
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
|
-
function defaultRequester(config) {
|
|
41
|
-
return {
|
|
42
|
-
request: async function (req) {
|
|
43
|
-
if (!req.path) {
|
|
44
|
-
req.path = [];
|
|
45
|
-
}
|
|
46
|
-
const res = await fetch([config.baseUrl, ...req.path].join("/"), {
|
|
47
|
-
method: "POST",
|
|
48
|
-
headers: { "Content-Type": "application/json", ...config.headers },
|
|
49
|
-
body: JSON.stringify(req.body),
|
|
50
|
-
keepalive: true,
|
|
51
|
-
// @ts-expect-error fastly requires `backend`
|
|
52
|
-
backend: config.backend,
|
|
53
|
-
});
|
|
54
|
-
const body = (await res.json());
|
|
55
|
-
if (!res.ok) {
|
|
56
|
-
throw new UpstashError(body.error);
|
|
57
|
-
}
|
|
58
|
-
return body;
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// deno-lint-ignore-file
|
|
2
2
|
import * as core from "../pkg/redis.js";
|
|
3
|
-
import {
|
|
3
|
+
import { HttpClient, } from "../pkg/http.js";
|
|
4
4
|
import "isomorphic-fetch";
|
|
5
5
|
/**
|
|
6
6
|
* Serverless redis client for upstash.
|
|
@@ -21,8 +21,9 @@ export class Redis extends core.Redis {
|
|
|
21
21
|
/\r|\n/.test(configOrRequester.token)) {
|
|
22
22
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
23
23
|
}
|
|
24
|
-
const client =
|
|
24
|
+
const client = new HttpClient({
|
|
25
25
|
baseUrl: configOrRequester.url,
|
|
26
|
+
retry: configOrRequester.retry,
|
|
26
27
|
headers: { authorization: `Bearer ${configOrRequester.token}` },
|
|
27
28
|
// agent: configOrRequester.agent,
|
|
28
29
|
});
|
|
@@ -54,28 +55,6 @@ export class Redis extends core.Redis {
|
|
|
54
55
|
if (!token) {
|
|
55
56
|
throw new Error("Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`");
|
|
56
57
|
}
|
|
57
|
-
return new Redis({ url, token
|
|
58
|
+
return new Redis({ ...config, url, token });
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
|
-
function defaultRequester(config) {
|
|
61
|
-
return {
|
|
62
|
-
request: async function (req) {
|
|
63
|
-
if (!req.path) {
|
|
64
|
-
req.path = [];
|
|
65
|
-
}
|
|
66
|
-
const res = await fetch([config.baseUrl, ...req.path].join("/"), {
|
|
67
|
-
method: "POST",
|
|
68
|
-
headers: { "Content-Type": "application/json", ...config.headers },
|
|
69
|
-
body: JSON.stringify(req.body),
|
|
70
|
-
keepalive: true,
|
|
71
|
-
// @ts-ignore
|
|
72
|
-
agent: config.agent,
|
|
73
|
-
});
|
|
74
|
-
const body = (await res.json());
|
|
75
|
-
if (!res.ok) {
|
|
76
|
-
throw new UpstashError(body.error);
|
|
77
|
-
}
|
|
78
|
-
return body;
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
}
|
package/esm/platforms/nodejs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// deno-lint-ignore-file
|
|
2
2
|
import * as core from "../pkg/redis.js";
|
|
3
|
-
import {
|
|
3
|
+
import { HttpClient, } from "../pkg/http.js";
|
|
4
4
|
/**
|
|
5
5
|
* Serverless redis client for upstash.
|
|
6
6
|
*/
|
|
@@ -20,8 +20,9 @@ export class Redis extends core.Redis {
|
|
|
20
20
|
/\r|\n/.test(configOrRequester.token)) {
|
|
21
21
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
22
22
|
}
|
|
23
|
-
const client =
|
|
23
|
+
const client = new HttpClient({
|
|
24
24
|
baseUrl: configOrRequester.url,
|
|
25
|
+
retry: configOrRequester.retry,
|
|
25
26
|
headers: { authorization: `Bearer ${configOrRequester.token}` },
|
|
26
27
|
// agent: configOrRequester.agent,
|
|
27
28
|
});
|
|
@@ -53,28 +54,6 @@ export class Redis extends core.Redis {
|
|
|
53
54
|
if (!token) {
|
|
54
55
|
throw new Error("Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`");
|
|
55
56
|
}
|
|
56
|
-
return new Redis({ url, token
|
|
57
|
+
return new Redis({ ...config, url, token });
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
|
-
function defaultRequester(config) {
|
|
60
|
-
return {
|
|
61
|
-
request: async function (req) {
|
|
62
|
-
if (!req.path) {
|
|
63
|
-
req.path = [];
|
|
64
|
-
}
|
|
65
|
-
const res = await fetch([config.baseUrl, ...req.path].join("/"), {
|
|
66
|
-
method: "POST",
|
|
67
|
-
headers: { "Content-Type": "application/json", ...config.headers },
|
|
68
|
-
body: JSON.stringify(req.body),
|
|
69
|
-
keepalive: true,
|
|
70
|
-
// @ts-ignore
|
|
71
|
-
agent: config.agent,
|
|
72
|
-
});
|
|
73
|
-
const body = (await res.json());
|
|
74
|
-
if (!res.ok) {
|
|
75
|
-
throw new UpstashError(body.error);
|
|
76
|
-
}
|
|
77
|
-
return body;
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
}
|
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"main": "./script/platforms/nodejs.js",
|
|
4
4
|
"types": "./types/platforms/nodejs.d.ts",
|
|
5
5
|
"name": "@upstash/redis",
|
|
6
|
+
"version": "v1.6.0",
|
|
6
7
|
"description": "An HTTP/REST based Redis client built on top of Upstash REST API.",
|
|
7
8
|
"repository": {
|
|
8
9
|
"type": "git",
|
|
@@ -15,36 +16,43 @@
|
|
|
15
16
|
"edge",
|
|
16
17
|
"upstash"
|
|
17
18
|
],
|
|
18
|
-
"author": "Andreas Thomas <
|
|
19
|
+
"author": "Andreas Thomas <dev@chronark.com>",
|
|
19
20
|
"license": "MIT",
|
|
20
21
|
"bugs": {
|
|
21
22
|
"url": "https://github.com/upstash/upstash-redis/issues"
|
|
22
23
|
},
|
|
23
|
-
"dependencies": {
|
|
24
|
-
"isomorphic-fetch": "^3.0.0"
|
|
25
|
-
},
|
|
26
24
|
"homepage": "https://github.com/upstash/upstash-redis#readme",
|
|
27
|
-
"browser": {
|
|
28
|
-
"isomorphic-fetch": false,
|
|
29
|
-
"http": false,
|
|
30
|
-
"https": false
|
|
31
|
-
},
|
|
32
25
|
"devDependencies": {
|
|
33
26
|
"@size-limit/preset-small-lib": "latest",
|
|
34
27
|
"size-limit": "latest"
|
|
35
28
|
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"isomorphic-fetch": "^3.0.0"
|
|
31
|
+
},
|
|
32
|
+
"typesVersions": {
|
|
33
|
+
"*": {
|
|
34
|
+
"nodejs": "./types/platforms/nodejs.d.ts",
|
|
35
|
+
"cloudflare": "./types/platforms/cloudflare.d.ts",
|
|
36
|
+
"fastly": "./types/platforms/fastly.d.ts",
|
|
37
|
+
"with-fetch": "./types/platforms/node_with_fetch.d.ts"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
36
40
|
"size-limit": [
|
|
37
41
|
{
|
|
38
42
|
"path": "esm/platforms/nodejs.js",
|
|
39
|
-
"limit": "
|
|
43
|
+
"limit": "6 KB"
|
|
40
44
|
},
|
|
41
45
|
{
|
|
42
46
|
"path": "esm/platforms/fastly.js",
|
|
43
|
-
"limit": "
|
|
47
|
+
"limit": "6 KB"
|
|
44
48
|
},
|
|
45
49
|
{
|
|
46
50
|
"path": "esm/platforms/cloudflare.js",
|
|
47
|
-
"limit": "
|
|
51
|
+
"limit": "6 KB"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"path": "esm/platforms/node_with_fetch.js",
|
|
55
|
+
"limit": "15 KB"
|
|
48
56
|
},
|
|
49
57
|
{
|
|
50
58
|
"path": "script/platforms/nodejs.js",
|
|
@@ -57,6 +65,10 @@
|
|
|
57
65
|
{
|
|
58
66
|
"path": "script/platforms/cloudflare.js",
|
|
59
67
|
"limit": "10 KB"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"path": "script/platforms/node_with_fetch.js",
|
|
71
|
+
"limit": "15 KB"
|
|
60
72
|
}
|
|
61
73
|
],
|
|
62
74
|
"exports": {
|
|
@@ -85,6 +97,5 @@
|
|
|
85
97
|
"require": "./script/platforms/node_with_fetch.js",
|
|
86
98
|
"types": "./types/platforms/node_with_fetch.d.ts"
|
|
87
99
|
}
|
|
88
|
-
}
|
|
89
|
-
"version": "1.4.0-next.2"
|
|
100
|
+
}
|
|
90
101
|
}
|
|
@@ -8,16 +8,7 @@ const command_js_1 = require("./command.js");
|
|
|
8
8
|
class ScriptExistsCommand extends command_js_1.Command {
|
|
9
9
|
constructor(hashes, opts) {
|
|
10
10
|
super(["script", "exists", ...hashes], {
|
|
11
|
-
deserialize: (result) =>
|
|
12
|
-
/**
|
|
13
|
-
* This isn't very pretty but it does the job.
|
|
14
|
-
* The user facing api is clean and will return a single `string` if they provided
|
|
15
|
-
* a single script hash, and an array of strings of the same length when given an
|
|
16
|
-
* array of hashes.
|
|
17
|
-
*/
|
|
18
|
-
const parsed = result;
|
|
19
|
-
return parsed.length === 1 ? parsed[0] : parsed;
|
|
20
|
-
},
|
|
11
|
+
deserialize: (result) => result,
|
|
21
12
|
...opts,
|
|
22
13
|
});
|
|
23
14
|
}
|
package/script/pkg/http.js
CHANGED
|
@@ -22,14 +22,30 @@ class HttpClient {
|
|
|
22
22
|
writable: true,
|
|
23
23
|
value: void 0
|
|
24
24
|
});
|
|
25
|
+
Object.defineProperty(this, "retry", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
configurable: true,
|
|
28
|
+
writable: true,
|
|
29
|
+
value: void 0
|
|
30
|
+
});
|
|
25
31
|
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
26
32
|
this.headers = { "Content-Type": "application/json", ...config.headers };
|
|
27
|
-
this.options = config.options;
|
|
33
|
+
this.options = { backend: config.options?.backend };
|
|
34
|
+
if (typeof config?.retry === "boolean" && config?.retry === false) {
|
|
35
|
+
this.retry = {
|
|
36
|
+
attempts: 1,
|
|
37
|
+
backoff: () => 0,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
this.retry = {
|
|
42
|
+
attempts: config?.retry?.retries ?? 5,
|
|
43
|
+
backoff: config?.retry?.backoff ??
|
|
44
|
+
((retryCount) => Math.exp(retryCount) * 50),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
28
47
|
}
|
|
29
48
|
async request(req) {
|
|
30
|
-
if (!req.path) {
|
|
31
|
-
req.path = [];
|
|
32
|
-
}
|
|
33
49
|
const requestOptions = {
|
|
34
50
|
method: "POST",
|
|
35
51
|
headers: this.headers,
|
|
@@ -40,9 +56,21 @@ class HttpClient {
|
|
|
40
56
|
*/
|
|
41
57
|
backend: this.options?.backend,
|
|
42
58
|
};
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
59
|
+
let res = null;
|
|
60
|
+
let error = null;
|
|
61
|
+
for (let i = 0; i <= this.retry.attempts; i++) {
|
|
62
|
+
try {
|
|
63
|
+
res = await fetch([this.baseUrl, ...(req.path ?? [])].join("/"), requestOptions);
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
error = err;
|
|
68
|
+
await new Promise((r) => setTimeout(r, this.retry.backoff(i)));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (!res) {
|
|
72
|
+
throw error ?? new Error("Exhausted all retries");
|
|
73
|
+
}
|
|
46
74
|
const body = (await res.json());
|
|
47
75
|
if (!res.ok) {
|
|
48
76
|
throw new error_js_1.UpstashError(body.error);
|
|
@@ -25,7 +25,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.Redis = void 0;
|
|
27
27
|
const core = __importStar(require("../pkg/redis.js"));
|
|
28
|
-
const
|
|
28
|
+
const http_js_1 = require("../pkg/http.js");
|
|
29
29
|
/**
|
|
30
30
|
* Serverless redis client for upstash.
|
|
31
31
|
*/
|
|
@@ -52,7 +52,8 @@ class Redis extends core.Redis {
|
|
|
52
52
|
/\r|\n/.test(config.token)) {
|
|
53
53
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
54
54
|
}
|
|
55
|
-
const client =
|
|
55
|
+
const client = new http_js_1.HttpClient({
|
|
56
|
+
retry: config.retry,
|
|
56
57
|
baseUrl: config.url,
|
|
57
58
|
headers: { authorization: `Bearer ${config.token}` },
|
|
58
59
|
});
|
|
@@ -70,9 +71,8 @@ class Redis extends core.Redis {
|
|
|
70
71
|
* ```ts
|
|
71
72
|
* const redis = Redis.fromEnv(env)
|
|
72
73
|
* ```
|
|
73
|
-
*
|
|
74
74
|
*/
|
|
75
|
-
static fromEnv(env) {
|
|
75
|
+
static fromEnv(env, opts) {
|
|
76
76
|
// @ts-ignore These will be defined by cloudflare
|
|
77
77
|
const url = env?.UPSTASH_REDIS_REST_URL ?? UPSTASH_REDIS_REST_URL;
|
|
78
78
|
// @ts-ignore These will be defined by cloudflare
|
|
@@ -83,27 +83,7 @@ class Redis extends core.Redis {
|
|
|
83
83
|
if (!token) {
|
|
84
84
|
throw new Error("Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_TOKEN`");
|
|
85
85
|
}
|
|
86
|
-
return new Redis({ url, token });
|
|
86
|
+
return new Redis({ ...opts, url, token });
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
exports.Redis = Redis;
|
|
90
|
-
function defaultRequester(config) {
|
|
91
|
-
return {
|
|
92
|
-
request: async function (req) {
|
|
93
|
-
if (!req.path) {
|
|
94
|
-
req.path = [];
|
|
95
|
-
}
|
|
96
|
-
const res = await fetch([config.baseUrl, ...req.path].join("/"), {
|
|
97
|
-
method: "POST",
|
|
98
|
-
headers: { "Content-Type": "application/json", ...config.headers },
|
|
99
|
-
body: JSON.stringify(req.body),
|
|
100
|
-
keepalive: true,
|
|
101
|
-
});
|
|
102
|
-
const body = (await res.json());
|
|
103
|
-
if (!res.ok) {
|
|
104
|
-
throw new error_js_1.UpstashError(body.error);
|
|
105
|
-
}
|
|
106
|
-
return body;
|
|
107
|
-
},
|
|
108
|
-
};
|
|
109
|
-
}
|
|
@@ -25,7 +25,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.Redis = void 0;
|
|
27
27
|
const core = __importStar(require("../pkg/redis.js"));
|
|
28
|
-
const
|
|
28
|
+
const http_js_1 = require("../pkg/http.js");
|
|
29
29
|
/**
|
|
30
30
|
* Serverless redis client for upstash.
|
|
31
31
|
*/
|
|
@@ -53,10 +53,11 @@ class Redis extends core.Redis {
|
|
|
53
53
|
/\r|\n/.test(config.token)) {
|
|
54
54
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
55
55
|
}
|
|
56
|
-
const client =
|
|
56
|
+
const client = new http_js_1.HttpClient({
|
|
57
57
|
baseUrl: config.url,
|
|
58
|
+
retry: config.retry,
|
|
58
59
|
headers: { authorization: `Bearer ${config.token}` },
|
|
59
|
-
backend: config.backend,
|
|
60
|
+
options: { backend: config.backend },
|
|
60
61
|
});
|
|
61
62
|
super(client, {
|
|
62
63
|
automaticDeserialization: config.automaticDeserialization,
|
|
@@ -64,25 +65,3 @@ class Redis extends core.Redis {
|
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
67
|
exports.Redis = Redis;
|
|
67
|
-
function defaultRequester(config) {
|
|
68
|
-
return {
|
|
69
|
-
request: async function (req) {
|
|
70
|
-
if (!req.path) {
|
|
71
|
-
req.path = [];
|
|
72
|
-
}
|
|
73
|
-
const res = await fetch([config.baseUrl, ...req.path].join("/"), {
|
|
74
|
-
method: "POST",
|
|
75
|
-
headers: { "Content-Type": "application/json", ...config.headers },
|
|
76
|
-
body: JSON.stringify(req.body),
|
|
77
|
-
keepalive: true,
|
|
78
|
-
// @ts-expect-error fastly requires `backend`
|
|
79
|
-
backend: config.backend,
|
|
80
|
-
});
|
|
81
|
-
const body = (await res.json());
|
|
82
|
-
if (!res.ok) {
|
|
83
|
-
throw new error_js_1.UpstashError(body.error);
|
|
84
|
-
}
|
|
85
|
-
return body;
|
|
86
|
-
},
|
|
87
|
-
};
|
|
88
|
-
}
|
|
@@ -26,7 +26,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
26
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
27
|
exports.Redis = void 0;
|
|
28
28
|
const core = __importStar(require("../pkg/redis.js"));
|
|
29
|
-
const
|
|
29
|
+
const http_js_1 = require("../pkg/http.js");
|
|
30
30
|
require("isomorphic-fetch");
|
|
31
31
|
/**
|
|
32
32
|
* Serverless redis client for upstash.
|
|
@@ -47,8 +47,9 @@ class Redis extends core.Redis {
|
|
|
47
47
|
/\r|\n/.test(configOrRequester.token)) {
|
|
48
48
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
49
49
|
}
|
|
50
|
-
const client =
|
|
50
|
+
const client = new http_js_1.HttpClient({
|
|
51
51
|
baseUrl: configOrRequester.url,
|
|
52
|
+
retry: configOrRequester.retry,
|
|
52
53
|
headers: { authorization: `Bearer ${configOrRequester.token}` },
|
|
53
54
|
// agent: configOrRequester.agent,
|
|
54
55
|
});
|
|
@@ -80,29 +81,7 @@ class Redis extends core.Redis {
|
|
|
80
81
|
if (!token) {
|
|
81
82
|
throw new Error("Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`");
|
|
82
83
|
}
|
|
83
|
-
return new Redis({ url, token
|
|
84
|
+
return new Redis({ ...config, url, token });
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
exports.Redis = Redis;
|
|
87
|
-
function defaultRequester(config) {
|
|
88
|
-
return {
|
|
89
|
-
request: async function (req) {
|
|
90
|
-
if (!req.path) {
|
|
91
|
-
req.path = [];
|
|
92
|
-
}
|
|
93
|
-
const res = await fetch([config.baseUrl, ...req.path].join("/"), {
|
|
94
|
-
method: "POST",
|
|
95
|
-
headers: { "Content-Type": "application/json", ...config.headers },
|
|
96
|
-
body: JSON.stringify(req.body),
|
|
97
|
-
keepalive: true,
|
|
98
|
-
// @ts-ignore
|
|
99
|
-
agent: config.agent,
|
|
100
|
-
});
|
|
101
|
-
const body = (await res.json());
|
|
102
|
-
if (!res.ok) {
|
|
103
|
-
throw new error_js_1.UpstashError(body.error);
|
|
104
|
-
}
|
|
105
|
-
return body;
|
|
106
|
-
},
|
|
107
|
-
};
|
|
108
|
-
}
|
|
@@ -26,7 +26,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
26
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
27
|
exports.Redis = void 0;
|
|
28
28
|
const core = __importStar(require("../pkg/redis.js"));
|
|
29
|
-
const
|
|
29
|
+
const http_js_1 = require("../pkg/http.js");
|
|
30
30
|
/**
|
|
31
31
|
* Serverless redis client for upstash.
|
|
32
32
|
*/
|
|
@@ -46,8 +46,9 @@ class Redis extends core.Redis {
|
|
|
46
46
|
/\r|\n/.test(configOrRequester.token)) {
|
|
47
47
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
48
48
|
}
|
|
49
|
-
const client =
|
|
49
|
+
const client = new http_js_1.HttpClient({
|
|
50
50
|
baseUrl: configOrRequester.url,
|
|
51
|
+
retry: configOrRequester.retry,
|
|
51
52
|
headers: { authorization: `Bearer ${configOrRequester.token}` },
|
|
52
53
|
// agent: configOrRequester.agent,
|
|
53
54
|
});
|
|
@@ -79,29 +80,7 @@ class Redis extends core.Redis {
|
|
|
79
80
|
if (!token) {
|
|
80
81
|
throw new Error("Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`");
|
|
81
82
|
}
|
|
82
|
-
return new Redis({ url, token
|
|
83
|
+
return new Redis({ ...config, url, token });
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
exports.Redis = Redis;
|
|
86
|
-
function defaultRequester(config) {
|
|
87
|
-
return {
|
|
88
|
-
request: async function (req) {
|
|
89
|
-
if (!req.path) {
|
|
90
|
-
req.path = [];
|
|
91
|
-
}
|
|
92
|
-
const res = await fetch([config.baseUrl, ...req.path].join("/"), {
|
|
93
|
-
method: "POST",
|
|
94
|
-
headers: { "Content-Type": "application/json", ...config.headers },
|
|
95
|
-
body: JSON.stringify(req.body),
|
|
96
|
-
keepalive: true,
|
|
97
|
-
// @ts-ignore
|
|
98
|
-
agent: config.agent,
|
|
99
|
-
});
|
|
100
|
-
const body = (await res.json());
|
|
101
|
-
if (!res.ok) {
|
|
102
|
-
throw new error_js_1.UpstashError(body.error);
|
|
103
|
-
}
|
|
104
|
-
return body;
|
|
105
|
-
},
|
|
106
|
-
};
|
|
107
|
-
}
|
|
@@ -2,8 +2,8 @@ import { Command, CommandOptions } from "./command.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* @see https://redis.io/commands/hmset
|
|
4
4
|
*/
|
|
5
|
-
export declare class HMSetCommand<TData> extends Command<
|
|
5
|
+
export declare class HMSetCommand<TData> extends Command<"OK", "OK"> {
|
|
6
6
|
constructor([key, kv]: [key: string, kv: {
|
|
7
7
|
[field: string]: TData;
|
|
8
|
-
}], opts?: CommandOptions<
|
|
8
|
+
}], opts?: CommandOptions<"OK", "OK">);
|
|
9
9
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { Command, CommandOptions } from "./command.js";
|
|
2
|
-
declare type TupleOfLength<T, L extends number, R extends T[] = []> = R["length"] extends L ? R : TupleOfLength<T, L, [...R, T]>;
|
|
3
2
|
/**
|
|
4
3
|
* @see https://redis.io/commands/script-exists
|
|
5
4
|
*/
|
|
6
|
-
export declare class ScriptExistsCommand<T extends
|
|
7
|
-
constructor(hashes: T, opts?: CommandOptions<
|
|
5
|
+
export declare class ScriptExistsCommand<T extends string[]> extends Command<string[], number[]> {
|
|
6
|
+
constructor(hashes: T, opts?: CommandOptions<string[], number[]>);
|
|
8
7
|
}
|
|
9
|
-
export {};
|
|
@@ -2,6 +2,6 @@ import { Command, CommandOptions } from "./command.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* @see https://redis.io/commands/sinterstore
|
|
4
4
|
*/
|
|
5
|
-
export declare class SInterStoreCommand
|
|
6
|
-
constructor(cmd: [destination: string, key: string, ...keys: string[]], opts?: CommandOptions<
|
|
5
|
+
export declare class SInterStoreCommand extends Command<number, number> {
|
|
6
|
+
constructor(cmd: [destination: string, key: string, ...keys: string[]], opts?: CommandOptions<number, number>);
|
|
7
7
|
}
|
|
@@ -2,6 +2,6 @@ import { Command, CommandOptions } from "./command.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* @see https://redis.io/commands/spop
|
|
4
4
|
*/
|
|
5
|
-
export declare class SPopCommand<TData
|
|
5
|
+
export declare class SPopCommand<TData> extends Command<string | null, TData | null> {
|
|
6
6
|
constructor([key, count]: [key: string, count?: number], opts?: CommandOptions<string | null, TData | null>);
|
|
7
7
|
}
|
package/types/pkg/http.d.ts
CHANGED
|
@@ -12,12 +12,31 @@ export declare type UpstashResponse<TResult> = {
|
|
|
12
12
|
export interface Requester {
|
|
13
13
|
request: <TResult = unknown>(req: UpstashRequest) => Promise<UpstashResponse<TResult>>;
|
|
14
14
|
}
|
|
15
|
+
export declare type RetryConfig = false | {
|
|
16
|
+
/**
|
|
17
|
+
* The number of retries to attempt before giving up.
|
|
18
|
+
*
|
|
19
|
+
* @default 5
|
|
20
|
+
*/
|
|
21
|
+
retries?: number;
|
|
22
|
+
/**
|
|
23
|
+
* A backoff function receives the current retry cound and returns a number in milliseconds to wait before retrying.
|
|
24
|
+
*
|
|
25
|
+
* @default
|
|
26
|
+
* ```ts
|
|
27
|
+
* Math.exp(retryCount) * 50
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
backoff?: (retryCount: number) => number;
|
|
31
|
+
};
|
|
32
|
+
declare type Options = {
|
|
33
|
+
backend?: string;
|
|
34
|
+
};
|
|
15
35
|
export declare type HttpClientConfig = {
|
|
16
36
|
headers?: Record<string, string>;
|
|
17
37
|
baseUrl: string;
|
|
18
|
-
options?:
|
|
19
|
-
|
|
20
|
-
};
|
|
38
|
+
options?: Options;
|
|
39
|
+
retry?: RetryConfig;
|
|
21
40
|
};
|
|
22
41
|
export declare class HttpClient implements Requester {
|
|
23
42
|
baseUrl: string;
|
|
@@ -25,6 +44,11 @@ export declare class HttpClient implements Requester {
|
|
|
25
44
|
readonly options?: {
|
|
26
45
|
backend?: string;
|
|
27
46
|
};
|
|
47
|
+
readonly retry: {
|
|
48
|
+
attempts: number;
|
|
49
|
+
backoff: (retryCount: number) => number;
|
|
50
|
+
};
|
|
28
51
|
constructor(config: HttpClientConfig);
|
|
29
52
|
request<TResult>(req: UpstashRequest): Promise<UpstashResponse<TResult>>;
|
|
30
53
|
}
|
|
54
|
+
export {};
|
package/types/pkg/pipeline.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DelCommand, ExistsCommand, FlushAllCommand, PingCommand, ScoreMember, SetCommandOptions, TouchCommand, UnlinkCommand, ZAddCommandOptions, ZAddCommandOptionsWithIncr, ZRangeCommandOptions } from "./commands/mod.js";
|
|
1
|
+
import { DelCommand, ExistsCommand, FlushAllCommand, PingCommand, ScoreMember, ScriptExistsCommand, SetCommandOptions, TouchCommand, UnlinkCommand, ZAddCommandOptions, ZAddCommandOptionsWithIncr, ZRangeCommandOptions } from "./commands/mod.js";
|
|
2
2
|
import { CommandOptions } from "./commands/command.js";
|
|
3
3
|
import { Requester } from "./http.js";
|
|
4
4
|
import { CommandArgs } from "./types.js";
|
|
@@ -349,7 +349,7 @@ export declare class Pipeline {
|
|
|
349
349
|
/**
|
|
350
350
|
* @see https://redis.io/commands/script-exists
|
|
351
351
|
*/
|
|
352
|
-
scriptExists: (
|
|
352
|
+
scriptExists: (...args: CommandArgs<typeof ScriptExistsCommand>) => this;
|
|
353
353
|
/**
|
|
354
354
|
* @see https://redis.io/commands/script-flush
|
|
355
355
|
*/
|
package/types/pkg/redis.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CommandOptions, DelCommand, ExistsCommand, FlushAllCommand, PingCommand, ScoreMember, SetCommandOptions, TouchCommand, UnlinkCommand, ZAddCommandOptions, ZAddCommandOptionsWithIncr, ZRangeCommandOptions } from "./commands/mod.js";
|
|
1
|
+
import { CommandOptions, DelCommand, ExistsCommand, FlushAllCommand, PingCommand, ScoreMember, ScriptExistsCommand, SetCommandOptions, TouchCommand, UnlinkCommand, ZAddCommandOptions, ZAddCommandOptionsWithIncr, ZRangeCommandOptions } from "./commands/mod.js";
|
|
2
2
|
import { Requester } from "./http.js";
|
|
3
3
|
import { Pipeline } from "./pipeline.js";
|
|
4
4
|
import type { CommandArgs } from "./types.js";
|
|
@@ -160,7 +160,7 @@ export declare class Redis {
|
|
|
160
160
|
*/
|
|
161
161
|
hmset: <TData>(key: string, kv: {
|
|
162
162
|
[field: string]: TData;
|
|
163
|
-
}) => Promise<
|
|
163
|
+
}) => Promise<"OK">;
|
|
164
164
|
/**
|
|
165
165
|
* @see https://redis.io/commands/hscan
|
|
166
166
|
*/
|
|
@@ -322,7 +322,7 @@ export declare class Redis {
|
|
|
322
322
|
/**
|
|
323
323
|
* @see https://redis.io/commands/script-exists
|
|
324
324
|
*/
|
|
325
|
-
scriptExists: (
|
|
325
|
+
scriptExists: (...args: CommandArgs<typeof ScriptExistsCommand>) => Promise<number[]>;
|
|
326
326
|
/**
|
|
327
327
|
* @see https://redis.io/commands/script-flush
|
|
328
328
|
*/
|
|
@@ -366,7 +366,7 @@ export declare class Redis {
|
|
|
366
366
|
/**
|
|
367
367
|
* @see https://redis.io/commands/sinterstore
|
|
368
368
|
*/
|
|
369
|
-
sinterstore: (destination: string, key: string, ...keys: string[]) => Promise<
|
|
369
|
+
sinterstore: (destination: string, key: string, ...keys: string[]) => Promise<number>;
|
|
370
370
|
/**
|
|
371
371
|
* @see https://redis.io/commands/sismember
|
|
372
372
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as core from "../pkg/redis.js";
|
|
2
|
-
import type { Requester, UpstashRequest, UpstashResponse } from "../pkg/http.js";
|
|
2
|
+
import type { Requester, RetryConfig, UpstashRequest, UpstashResponse } from "../pkg/http.js";
|
|
3
3
|
export type { Requester, UpstashRequest, UpstashResponse };
|
|
4
4
|
/**
|
|
5
5
|
* Connection credentials for upstash redis.
|
|
@@ -14,6 +14,10 @@ export declare type RedisConfigCloudflare = {
|
|
|
14
14
|
* UPSTASH_REDIS_REST_TOKEN
|
|
15
15
|
*/
|
|
16
16
|
token: string;
|
|
17
|
+
/**
|
|
18
|
+
* Configure the retry behaviour in case of network errors
|
|
19
|
+
*/
|
|
20
|
+
retry?: RetryConfig;
|
|
17
21
|
} & core.RedisOptions;
|
|
18
22
|
/**
|
|
19
23
|
* Serverless redis client for upstash.
|
|
@@ -34,5 +38,5 @@ export declare class Redis extends core.Redis {
|
|
|
34
38
|
static fromEnv(env?: {
|
|
35
39
|
UPSTASH_REDIS_REST_URL: string;
|
|
36
40
|
UPSTASH_REDIS_REST_TOKEN: string;
|
|
37
|
-
}): Redis;
|
|
41
|
+
}, opts?: Omit<RedisConfigCloudflare, "url" | "token">): Redis;
|
|
38
42
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as core from "../pkg/redis.js";
|
|
2
|
-
import type { Requester, UpstashRequest, UpstashResponse } from "../pkg/http.js";
|
|
2
|
+
import type { Requester, RetryConfig, UpstashRequest, UpstashResponse } from "../pkg/http.js";
|
|
3
3
|
export type { Requester, UpstashRequest, UpstashResponse };
|
|
4
4
|
/**
|
|
5
5
|
* Connection credentials for upstash redis.
|
|
@@ -20,6 +20,10 @@ export declare type RedisConfigFastly = {
|
|
|
20
20
|
* referenced by name.
|
|
21
21
|
*/
|
|
22
22
|
backend: string;
|
|
23
|
+
/**
|
|
24
|
+
* Configure the retry behaviour in case of network errors
|
|
25
|
+
*/
|
|
26
|
+
retry?: RetryConfig;
|
|
23
27
|
} & core.RedisOptions;
|
|
24
28
|
/**
|
|
25
29
|
* Serverless redis client for upstash.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as core from "../pkg/redis.js";
|
|
2
|
-
import { Requester, UpstashRequest, UpstashResponse } from "../pkg/http.js";
|
|
2
|
+
import { Requester, RetryConfig, UpstashRequest, UpstashResponse } from "../pkg/http.js";
|
|
3
3
|
import "isomorphic-fetch";
|
|
4
4
|
export type { Requester, UpstashRequest, UpstashResponse };
|
|
5
5
|
/**
|
|
@@ -15,6 +15,25 @@ export declare type RedisConfigNodejs = {
|
|
|
15
15
|
* UPSTASH_REDIS_REST_TOKEN
|
|
16
16
|
*/
|
|
17
17
|
token: string;
|
|
18
|
+
/**
|
|
19
|
+
* An agent allows you to reuse connections to reduce latency for multiple sequential requests.
|
|
20
|
+
*
|
|
21
|
+
* This is a node specific implementation and is not supported in various runtimes like Vercel
|
|
22
|
+
* edge functions.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import https from "https"
|
|
27
|
+
*
|
|
28
|
+
* const options: RedisConfigNodejs = {
|
|
29
|
+
* agent: new https.Agent({ keepAlive: true })
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Configure the retry behaviour in case of network errors
|
|
35
|
+
*/
|
|
36
|
+
retry?: RetryConfig;
|
|
18
37
|
} & core.RedisOptions;
|
|
19
38
|
/**
|
|
20
39
|
* Serverless redis client for upstash.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as core from "../pkg/redis.js";
|
|
2
|
-
import { Requester, UpstashRequest, UpstashResponse } from "../pkg/http.js";
|
|
2
|
+
import { Requester, RetryConfig, UpstashRequest, UpstashResponse } from "../pkg/http.js";
|
|
3
3
|
export type { Requester, UpstashRequest, UpstashResponse };
|
|
4
4
|
/**
|
|
5
5
|
* Connection credentials for upstash redis.
|
|
@@ -14,6 +14,25 @@ export declare type RedisConfigNodejs = {
|
|
|
14
14
|
* UPSTASH_REDIS_REST_TOKEN
|
|
15
15
|
*/
|
|
16
16
|
token: string;
|
|
17
|
+
/**
|
|
18
|
+
* An agent allows you to reuse connections to reduce latency for multiple sequential requests.
|
|
19
|
+
*
|
|
20
|
+
* This is a node specific implementation and is not supported in various runtimes like Vercel
|
|
21
|
+
* edge functions.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import https from "https"
|
|
26
|
+
*
|
|
27
|
+
* const options: RedisConfigNodejs = {
|
|
28
|
+
* agent: new https.Agent({ keepAlive: true })
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* Configure the retry behaviour in case of network errors
|
|
34
|
+
*/
|
|
35
|
+
retry?: RetryConfig;
|
|
17
36
|
} & core.RedisOptions;
|
|
18
37
|
/**
|
|
19
38
|
* Serverless redis client for upstash.
|