Files
indiekit-endpoint-activitypub/lib/kv-store.js
Ricardo dd9bba711f feat: migrate to Fedify 2.0 with debug dashboard and modular imports
- Upgrade @fedify/fedify, @fedify/redis to ^2.0.0
- Add @fedify/debugger ^2.0.0 for live federation traffic dashboard
- Move all vocab type imports to @fedify/fedify/vocab (13 files)
- Move crypto imports (exportJwk, importJwk, generateCryptoKeyPair) to @fedify/fedify/sig
- Replace removed importSpki() with local Web Crypto API helper
- Add KvStore.list() async generator required by Fedify 2.0
- Add setOutboxPermanentFailureHandler for delivery failure logging
- Add debugDashboard/debugPassword config options
- Skip manual LogTape configure when debugger auto-configures it
- Fix Express-Fedify bridge to reconstruct body from req.body when
  Express body parser has already consumed the stream (fixes debug
  dashboard login TypeError)
- Add response.bodyUsed safety check in sendFedifyResponse
- Remove @fedify/express dependency (custom bridge handles sub-path mounting)
2026-02-22 14:28:31 +01:00

77 lines
1.9 KiB
JavaScript

/**
* MongoDB-backed KvStore adapter for Fedify.
*
* Implements Fedify's KvStore interface using a MongoDB collection.
* Keys are string arrays (e.g. ["keypair", "rsa", "rick"]) — we serialize
* them as a joined path string for MongoDB's _id field.
*/
/**
* @implements {import("@fedify/fedify").KvStore}
*/
export class MongoKvStore {
/** @param {import("mongodb").Collection} collection */
constructor(collection) {
this.collection = collection;
}
/**
* Serialize a Fedify key (string[]) to a MongoDB document _id.
* @param {string[]} key
* @returns {string}
*/
_serializeKey(key) {
return key.join("/");
}
/**
* @param {string[]} key
* @returns {Promise<unknown>}
*/
async get(key) {
const doc = await this.collection.findOne({ _id: this._serializeKey(key) });
return doc ? doc.value : undefined;
}
/**
* @param {string[]} key
* @param {unknown} value
*/
async set(key, value) {
const id = this._serializeKey(key);
await this.collection.updateOne(
{ _id: id },
{ $set: { _id: id, value, updatedAt: new Date().toISOString() } },
{ upsert: true },
);
}
/**
* @param {string[]} key
*/
async delete(key) {
await this.collection.deleteOne({ _id: this._serializeKey(key) });
}
/**
* List all entries whose key starts with the given prefix.
* Required by Fedify 2.0's KvStore interface.
*
* @param {string[]} [prefix=[]]
* @returns {AsyncIterable<{ key: string[], value: unknown }>}
*/
async *list(prefix = []) {
const prefixStr = this._serializeKey(prefix);
const filter = prefixStr
? { _id: { $regex: `^${prefixStr.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}` } }
: {};
const cursor = this.collection.find(filter);
for await (const doc of cursor) {
yield {
key: doc._id.split("/"),
value: doc.value,
};
}
}
}