@fedify/redis
Version:
Redis drivers for Fedify
63 lines (59 loc) • 1.9 kB
JavaScript
import { Temporal } from "@js-temporal/polyfill";
import { JsonCodec } from "./codec.js";
import { Buffer } from "node:buffer";
//#region src/kv.ts
/**
* A key–value store that uses Redis as the underlying storage.
*
* @example
* ```ts ignore
* import { createFederation } from "@fedify/fedify";
* import { RedisKvStore } from "@fedify/redis";
* import { Redis } from "ioredis";
*
* const federation = createFederation({
* // ...
* kv: new RedisKvStore(new Redis()),
* });
* ```
*/
var RedisKvStore = class {
#redis;
#keyPrefix;
#codec;
#textEncoder = new TextEncoder();
/**
* Creates a new Redis key–value store.
* @param redis The Redis client to use.
* @param options The options for the key–value store.
*/
constructor(redis, options = {}) {
this.#redis = redis;
this.#keyPrefix = options.keyPrefix ?? "fedify::";
this.#codec = options.codec ?? new JsonCodec();
}
#serializeKey(key) {
const suffix = key.map((part) => part.replaceAll(":", "_:")).join("::");
if (typeof this.#keyPrefix === "string") return `${this.#keyPrefix}${suffix}`;
const suffixBytes = this.#textEncoder.encode(suffix);
return Buffer.concat([new Uint8Array(this.#keyPrefix), suffixBytes]);
}
async get(key) {
const serializedKey = this.#serializeKey(key);
const encodedValue = await this.#redis.getBuffer(serializedKey);
if (encodedValue == null) return void 0;
return this.#codec.decode(encodedValue);
}
async set(key, value, options) {
const serializedKey = this.#serializeKey(key);
const encodedValue = this.#codec.encode(value);
if (options?.ttl != null) await this.#redis.setex(serializedKey, options.ttl.total("second"), encodedValue);
else await this.#redis.set(serializedKey, encodedValue);
}
async delete(key) {
const serializedKey = this.#serializeKey(key);
await this.#redis.del(serializedKey);
}
};
//#endregion
export { RedisKvStore };