import { all, first } from "../db"; import { accountDb, repoDb, type ScopedDb } from "../scoped-db"; import { locate, type LocatorKind } from "../scoped-db/locators"; /** Ids of runs, jobs and runners never move between scopes, so a resolved scope can be remembered per isolate. */ const cache = new Map(); const CACHE_LIMIT = 5000; async function cachedLocate(kind: LocatorKind, key: string): Promise { const cacheKey = `${kind}:${key}`; const hit = cache.get(cacheKey); if (hit) return hit; const scopeId = await locate(kind, key); if (scopeId) { if (cache.size >= CACHE_LIMIT) cache.clear(); cache.set(cacheKey, scopeId); } return scopeId; } /** Remembers a scope just registered so the next lookup in this isolate skips D1. */ export function rememberScope(kind: LocatorKind, key: string, scopeId: string): void { if (cache.size >= CACHE_LIMIT) cache.clear(); cache.set(`${kind}:${key}`, scopeId); } export function jobRepoId(jobId: string): Promise { return cachedLocate("workflow_job", jobId); } export function runRepoId(runId: string): Promise { return cachedLocate("workflow_run", runId); } /** The repository database holding a job, or null for an unknown job. */ export async function jobDb(jobId: string): Promise { const repoId = await jobRepoId(jobId); return repoId ? repoDb(repoId) : null; } export async function runDb(runId: string): Promise { const repoId = await runRepoId(runId); return repoId ? repoDb(repoId) : null; } /** The account whose AccountState stores a runner (its owner, or the owner of its repository). */ export function runnerAccountId(runnerId: string): Promise { return cachedLocate("runner", runnerId); } export async function runnerDb(runnerId: string): Promise { const accountId = await runnerAccountId(runnerId); return accountId ? accountDb(accountId) : null; } export async function repoOwnerId(repoId: string): Promise { const row = await first<{ owner_id: string }>("SELECT owner_id FROM repos WHERE id = ?", repoId); return row?.owner_id ?? null; } /** Ids of every repository an account owns, from the D1 directory. */ export async function ownerRepoIds(ownerId: string): Promise { const rows = await all<{ id: string }>("SELECT id FROM repos WHERE owner_id = ?", ownerId); return rows.map((row) => row.id); }