@fedify/redis 2.4.0-dev.1962 → 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 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.total("second"), encodedValue);
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.total("second"), encodedValue);
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.1962+8aaa5348",
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.1962+8aaa5348"
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",
@@ -88,7 +88,7 @@
88
88
  "tsdown": "^0.22.0",
89
89
  "typescript": "^6.0.0",
90
90
  "@fedify/fixture": "^2.0.0",
91
- "@fedify/testing": "^2.4.0-dev.1962+8aaa5348"
91
+ "@fedify/testing": "^2.4.0-dev.1988+c5c9d617"
92
92
  },
93
93
  "scripts": {
94
94
  "build:self": "tsdown",