/** * Patch: replace countDocuments() with estimatedDocumentCount() in * federation-setup.js followers/following collection dispatchers. * * All four calls are already wrapped in cachedQuery(), but on cache miss * countDocuments() runs a full aggregate scan. estimatedDocumentCount() * reads collection metadata — O(1). * * Covers: ap_followers (×2) and ap_following (×2) in collection pagination * and counter dispatchers. */ import { access, readFile, writeFile } from "node:fs/promises"; const candidates = [ "node_modules/@rmdes/indiekit-endpoint-activitypub/lib/federation-setup.js", "node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-activitypub/lib/federation-setup.js", ]; const MARKER = "// [patch] collection-count-estimate"; const replacements = [ { old: ` const t = await collections.ap_followers.countDocuments(); return [d, t];`, new: ` const t = await collections.ap_followers.estimatedDocumentCount(); ${MARKER} return [d, t];`, }, { old: ` return await collections.ap_followers.countDocuments();`, new: ` return await collections.ap_followers.estimatedDocumentCount(); ${MARKER}`, }, { old: ` const t = await collections.ap_following.countDocuments(); return [d, t];`, new: ` const t = await collections.ap_following.estimatedDocumentCount(); ${MARKER} return [d, t];`, }, { old: ` return await collections.ap_following.countDocuments();`, new: ` return await collections.ap_following.estimatedDocumentCount(); ${MARKER}`, }, ]; async function exists(p) { try { await access(p); return true; } catch { return false; } } let patched = false; for (const filePath of candidates) { if (!(await exists(filePath))) continue; let src = await readFile(filePath, "utf8"); if (src.includes(MARKER)) { console.log(`[postinstall] patch-ap-collection-count-estimate: already applied in ${filePath}`); patched = true; break; } let changed = 0; for (const { old, new: replacement } of replacements) { if (src.includes(old)) { src = src.replace(old, replacement); changed++; } } if (changed === 0) { console.log(`[postinstall] patch-ap-collection-count-estimate: target snippets not found in ${filePath}`); continue; } await writeFile(filePath, src, "utf8"); console.log(`[postinstall] patch-ap-collection-count-estimate: applied ${changed}/4 replacements in ${filePath}`); patched = true; break; } if (!patched) { console.log("[postinstall] patch-ap-collection-count-estimate: no target file found"); }