@fedify/redis 2.4.0-dev.1964 → 2.4.0-dev.1988
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/kv.cjs +37 -1
- package/dist/kv.d.cts +9 -0
- package/dist/kv.d.ts +9 -0
- package/dist/kv.js +37 -1
- package/package.json +4 -4
package/dist/kv.cjs
CHANGED
|
@@ -4,6 +4,33 @@ const require_codec = require("./codec.cjs");
|
|
|
4
4
|
let node_buffer = require("node:buffer");
|
|
5
5
|
//#region src/kv.ts
|
|
6
6
|
/**
|
|
7
|
+
* Turns a TTL into the whole number of seconds Redis `SETEX` requires.
|
|
8
|
+
*
|
|
9
|
+
* The one-second granularity is `SETEX`'s, not Redis's: Redis can express a
|
|
10
|
+
* millisecond expiry through `SET` with `PX`, and `SETEX` is simply the
|
|
11
|
+
* command this adapter uses. Within that command a duration which is not a
|
|
12
|
+
* whole number of seconds has to be approximated.
|
|
13
|
+
*
|
|
14
|
+
* It is rounded up rather than to the nearest second, because every other
|
|
15
|
+
* {@link KvStore} implementation keeps a value for at least as long as it was
|
|
16
|
+
* asked to, and expiring early is the direction that can change behaviour
|
|
17
|
+
* rather than just cost a refetch — a TTL used to suppress duplicate work
|
|
18
|
+
* would start letting duplicates through.
|
|
19
|
+
*
|
|
20
|
+
* The result is clamped to 1, the smallest expiry `SETEX` accepts. A
|
|
21
|
+
* sub-second duration therefore stores the value for one second instead of
|
|
22
|
+
* being rejected, and so do **zero and negative durations**, which `SETEX`
|
|
23
|
+
* rejects outright. That last part is a policy choice rather than a
|
|
24
|
+
* consequence of the rounding: the other {@link KvStore} implementations read
|
|
25
|
+
* a non-positive TTL as already expired, whereas this one keeps the value for
|
|
26
|
+
* the shortest lifetime the command can express. Storing it briefly is closer
|
|
27
|
+
* to the caller's request than failing the write, which is what happened
|
|
28
|
+
* before.
|
|
29
|
+
*/
|
|
30
|
+
function expirySeconds(ttl) {
|
|
31
|
+
return Math.max(1, Math.ceil(ttl.total("second")));
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
7
34
|
* A key–value store that uses Redis as the underlying storage.
|
|
8
35
|
*
|
|
9
36
|
* @example
|
|
@@ -59,10 +86,19 @@ var RedisKvStore = class {
|
|
|
59
86
|
if (encodedValue == null) return void 0;
|
|
60
87
|
return this.#codec.decode(encodedValue);
|
|
61
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* {@inheritDoc KvStore.set}
|
|
91
|
+
*
|
|
92
|
+
* The `ttl` option is stored through Redis `SETEX`, which takes a whole
|
|
93
|
+
* number of seconds, so a duration with a finer resolution is rounded up to
|
|
94
|
+
* the next second. A zero or negative duration stores the value for one
|
|
95
|
+
* second, the shortest expiry the command can express, rather than failing
|
|
96
|
+
* the write or deleting the key.
|
|
97
|
+
*/
|
|
62
98
|
async set(key, value, options) {
|
|
63
99
|
const serializedKey = this.#serializeKey(key);
|
|
64
100
|
const encodedValue = this.#codec.encode(value);
|
|
65
|
-
if (options?.ttl != null) await this.#redis.setex(serializedKey, options.ttl
|
|
101
|
+
if (options?.ttl != null) await this.#redis.setex(serializedKey, expirySeconds(options.ttl), encodedValue);
|
|
66
102
|
else await this.#redis.set(serializedKey, encodedValue);
|
|
67
103
|
}
|
|
68
104
|
async delete(key) {
|
package/dist/kv.d.cts
CHANGED
|
@@ -55,6 +55,15 @@ declare class RedisKvStore implements KvStore {
|
|
|
55
55
|
*/
|
|
56
56
|
constructor(redis: Redis | Cluster, options?: RedisKvStoreOptions);
|
|
57
57
|
get<T = unknown>(key: KvKey): Promise<T | undefined>;
|
|
58
|
+
/**
|
|
59
|
+
* {@inheritDoc KvStore.set}
|
|
60
|
+
*
|
|
61
|
+
* The `ttl` option is stored through Redis `SETEX`, which takes a whole
|
|
62
|
+
* number of seconds, so a duration with a finer resolution is rounded up to
|
|
63
|
+
* the next second. A zero or negative duration stores the value for one
|
|
64
|
+
* second, the shortest expiry the command can express, rather than failing
|
|
65
|
+
* the write or deleting the key.
|
|
66
|
+
*/
|
|
58
67
|
set(key: KvKey, value: unknown, options?: KvStoreSetOptions | undefined): Promise<void>;
|
|
59
68
|
delete(key: KvKey): Promise<void>;
|
|
60
69
|
/**
|
package/dist/kv.d.ts
CHANGED
|
@@ -55,6 +55,15 @@ declare class RedisKvStore implements KvStore {
|
|
|
55
55
|
*/
|
|
56
56
|
constructor(redis: Redis | Cluster, options?: RedisKvStoreOptions);
|
|
57
57
|
get<T = unknown>(key: KvKey): Promise<T | undefined>;
|
|
58
|
+
/**
|
|
59
|
+
* {@inheritDoc KvStore.set}
|
|
60
|
+
*
|
|
61
|
+
* The `ttl` option is stored through Redis `SETEX`, which takes a whole
|
|
62
|
+
* number of seconds, so a duration with a finer resolution is rounded up to
|
|
63
|
+
* the next second. A zero or negative duration stores the value for one
|
|
64
|
+
* second, the shortest expiry the command can express, rather than failing
|
|
65
|
+
* the write or deleting the key.
|
|
66
|
+
*/
|
|
58
67
|
set(key: KvKey, value: unknown, options?: KvStoreSetOptions | undefined): Promise<void>;
|
|
59
68
|
delete(key: KvKey): Promise<void>;
|
|
60
69
|
/**
|
package/dist/kv.js
CHANGED
|
@@ -3,6 +3,33 @@ import { JsonCodec } from "./codec.js";
|
|
|
3
3
|
import { Buffer } from "node:buffer";
|
|
4
4
|
//#region src/kv.ts
|
|
5
5
|
/**
|
|
6
|
+
* Turns a TTL into the whole number of seconds Redis `SETEX` requires.
|
|
7
|
+
*
|
|
8
|
+
* The one-second granularity is `SETEX`'s, not Redis's: Redis can express a
|
|
9
|
+
* millisecond expiry through `SET` with `PX`, and `SETEX` is simply the
|
|
10
|
+
* command this adapter uses. Within that command a duration which is not a
|
|
11
|
+
* whole number of seconds has to be approximated.
|
|
12
|
+
*
|
|
13
|
+
* It is rounded up rather than to the nearest second, because every other
|
|
14
|
+
* {@link KvStore} implementation keeps a value for at least as long as it was
|
|
15
|
+
* asked to, and expiring early is the direction that can change behaviour
|
|
16
|
+
* rather than just cost a refetch — a TTL used to suppress duplicate work
|
|
17
|
+
* would start letting duplicates through.
|
|
18
|
+
*
|
|
19
|
+
* The result is clamped to 1, the smallest expiry `SETEX` accepts. A
|
|
20
|
+
* sub-second duration therefore stores the value for one second instead of
|
|
21
|
+
* being rejected, and so do **zero and negative durations**, which `SETEX`
|
|
22
|
+
* rejects outright. That last part is a policy choice rather than a
|
|
23
|
+
* consequence of the rounding: the other {@link KvStore} implementations read
|
|
24
|
+
* a non-positive TTL as already expired, whereas this one keeps the value for
|
|
25
|
+
* the shortest lifetime the command can express. Storing it briefly is closer
|
|
26
|
+
* to the caller's request than failing the write, which is what happened
|
|
27
|
+
* before.
|
|
28
|
+
*/
|
|
29
|
+
function expirySeconds(ttl) {
|
|
30
|
+
return Math.max(1, Math.ceil(ttl.total("second")));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
6
33
|
* A key–value store that uses Redis as the underlying storage.
|
|
7
34
|
*
|
|
8
35
|
* @example
|
|
@@ -58,10 +85,19 @@ var RedisKvStore = class {
|
|
|
58
85
|
if (encodedValue == null) return void 0;
|
|
59
86
|
return this.#codec.decode(encodedValue);
|
|
60
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* {@inheritDoc KvStore.set}
|
|
90
|
+
*
|
|
91
|
+
* The `ttl` option is stored through Redis `SETEX`, which takes a whole
|
|
92
|
+
* number of seconds, so a duration with a finer resolution is rounded up to
|
|
93
|
+
* the next second. A zero or negative duration stores the value for one
|
|
94
|
+
* second, the shortest expiry the command can express, rather than failing
|
|
95
|
+
* the write or deleting the key.
|
|
96
|
+
*/
|
|
61
97
|
async set(key, value, options) {
|
|
62
98
|
const serializedKey = this.#serializeKey(key);
|
|
63
99
|
const encodedValue = this.#codec.encode(value);
|
|
64
|
-
if (options?.ttl != null) await this.#redis.setex(serializedKey, options.ttl
|
|
100
|
+
if (options?.ttl != null) await this.#redis.setex(serializedKey, expirySeconds(options.ttl), encodedValue);
|
|
65
101
|
else await this.#redis.set(serializedKey, encodedValue);
|
|
66
102
|
}
|
|
67
103
|
async delete(key) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/redis",
|
|
3
|
-
"version": "2.4.0-dev.
|
|
3
|
+
"version": "2.4.0-dev.1988+c5c9d617",
|
|
4
4
|
"description": "Redis drivers for Fedify",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fedify",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
},
|
|
80
80
|
"peerDependencies": {
|
|
81
81
|
"ioredis": "^5.8.2",
|
|
82
|
-
"@fedify/fedify": "^2.4.0-dev.
|
|
82
|
+
"@fedify/fedify": "^2.4.0-dev.1988+c5c9d617"
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
85
|
"@std/async": "npm:@jsr/std__async@^1.0.13",
|
|
@@ -87,8 +87,8 @@
|
|
|
87
87
|
"@types/node": "^22.17.0",
|
|
88
88
|
"tsdown": "^0.22.0",
|
|
89
89
|
"typescript": "^6.0.0",
|
|
90
|
-
"@fedify/
|
|
91
|
-
"@fedify/
|
|
90
|
+
"@fedify/fixture": "^2.0.0",
|
|
91
|
+
"@fedify/testing": "^2.4.0-dev.1988+c5c9d617"
|
|
92
92
|
},
|
|
93
93
|
"scripts": {
|
|
94
94
|
"build:self": "tsdown",
|