import path from "node:path"; import { resolveStateDir } from "../config/paths.js"; export { createAsyncLock, readJsonFile, writeJsonAtomic } from "./json-files.js"; export function resolvePairingPaths(baseDir: string | undefined, subdir: string) { const root = baseDir ?? resolveStateDir(); const dir = path.join(root, subdir); return { dir, pendingPath: path.join(dir, "pending.json"), pairedPath: path.join(dir, "paired.json"), }; } export function pruneExpiredPending( pendingById: Record, nowMs: number, ttlMs: number, ) { for (const [id, req] of Object.entries(pendingById)) { if (nowMs - req.ts > ttlMs) { delete pendingById[id]; } } } export type PendingPairingRequestResult = { status: "pending"; request: TPending; created: boolean; }; export async function upsertPendingPairingRequest(params: { pendingById: Record; isExisting: (pending: TPending) => boolean; createRequest: (isRepair: boolean) => TPending; isRepair: boolean; persist: () => Promise; }): Promise> { const existing = Object.values(params.pendingById).find(params.isExisting); if (existing) { return { status: "pending", request: existing, created: false }; } const request = params.createRequest(params.isRepair); params.pendingById[request.requestId] = request; await params.persist(); return { status: "pending", request, created: true }; }