/** * hosting/sessionRetention — the ONE feature detection for the port's * retention member, and the refusal a store that has none produces. * * ── Why this is a function and not `sessions.retention?.()` ────────────────── * Because `?.()` answers `undefined`, and `undefined` is exactly the wrong * answer here. Every other optional member on this port is asked for behind a * door that refuses by name when it is absent — `session-list` does not report * "you have no conversations" when a store keeps no index — and retention needs * that more than either of them, not less: a cleanup job whose call returned * without complaining looks precisely like a cleanup job that is working. The * difference surfaces the day somebody asks how long conversations are kept, * and by then the answer is "all of them, since the beginning". * * So the detection lives here, once, and produces * {@link SessionRetentionUnavailableError} rather than a value that reads as * "fine". A caller that wants the silent shape can still write * `sessions.retention?.()` — the port is honest about what it has — but nothing * in this package does, and the door somebody reaches for first refuses. * * ── What it deliberately does not do ──────────────────────────────────────── * It does not sweep, schedule, or decide a cutoff. The cutoff is a policy * decision — a jurisdiction, a contract, a retention schedule somebody signed — * and a library that shipped a default would be answering a legal question with * a constant. It hands back what the store can do; WHEN is yours. */ import type { SessionLifecycle, SessionRetention } from './types.js'; /** * How a store's conversations stop existing — or a refusal that names the * store's limitation. * * The same detection every door in this package uses (`typeof … === * 'function'`), in the one place a consumer reaches for it, so a store that * implements the member and a store that does not are told apart once rather * than at every call site. * * @param sessions The store to ask. * @param purpose What you are doing, in your own words. It becomes the first * clause of the refusal, so an operator reading a log knows which job stopped * — the same reason the session-history refusals carry their op name. * * @throws SessionRetentionUnavailableError when the store implements no * `retention()`. Never returns `undefined`: a caller cannot mistake "this * store cannot expire anything" for "there was nothing to expire". * * @example A nightly job, against whatever store this deployment was built with * const policy = sessionRetention(sessions, 'the nightly retention job'); * if (policy.deletedBy === 'this-store') { * let more = true; * while (more) ({ more } = await policy.forgetOlderThan(Date.now() - THIRTY_DAYS)); * } else { * // Nothing to run: the backend expires them. Log what turns it on. * console.log(policy.active ? 'expiry is armed' : policy.enableWith); * } */ export declare function sessionRetention(sessions: SessionLifecycle, purpose?: string): SessionRetention; //# sourceMappingURL=sessionRetention.d.ts.map