import { env } from "cloudflare:workers";
import { all, first } from "./db";
import { countD1, timed } from "./perf";
const countReplica = (ms: number) => countD1(ms, true);
type D1Value = string | number | null;
function session(): D1DatabaseSession | null {
const db = (env as { DB?: D1Database }).DB;
return typeof db?.withSession === "function" ? db.withSession("first-unconstrained") : null;
}
/**
* Directory reads that tolerate a few seconds of replica lag (account name search, display names) go through the
* D1 Sessions API so read replication can serve them. Anything that gates access, filters by visibility (a repo
* just made private must vanish at once) or follows a write uses `first`/`all` from ./db, which always hit the
* primary. Falls back to the primary where sessions are unavailable.
*/
export const replica = {
async first<T>(sql: string, ...params: D1Value[]): Promise<T | null> {
const live = session();
if (!live) return first<T>(sql, ...params);
return timed(countReplica, () =>
live
.prepare(sql)
.bind(...params)
.first<T>(),
);
},
async all<T>(sql: string, ...params: D1Value[]): Promise<T[]> {
const live = session();
if (!live) return all<T>(sql, ...params);
const result = await timed(countReplica, () =>
live
.prepare(sql)
.bind(...params)
.all<T>(),
);
return result.results;