import type { ConsoleStore } from '../console/index.ts';
import type { RecordFields } from '../../workspace/record/types.ts';
/**
 * Storage seam for the job plane: each session's job list, each job's
 * console, which owners still run their jobs, and the processes each owner
 * runs.
 *
 * A session's list is one record, `{"next": n, "jobs": {id: job}}`,
 * written under a generation CAS the way the session table is, so two
 * workspaces that start a job on one session at once never hand out the
 * same number. A job's console is a stream the record names; any workspace
 * on the same store attaches to it by that name, follows it, and ends it
 * to kill the job. A lease says an owner is still alive: a job whose
 * owner's lease lapsed with no ending was lost with it. Each owner
 * publishes the processes it runs, so every workspace on the store lists
 * them and asks the owner to stop one; another workspace stops a lapsed
 * owner's native runs itself.
 *
 * Subclasses are infra adapters (RAM, Redis); everything above (job
 * numbers, waits, kills, hangups) is the table's, mirroring the
 * NamespaceStore design. Mirrors Python's `JobStore`.
 */
export declare abstract class JobStore {
    readonly leaseSeconds: number | null;
    /**
     * @param leaseSeconds how long an owner's renewal keeps it alive; null
     *   means owners never lapse, which holds where every owner shares one
     *   process.
     */
    constructor(leaseSeconds?: number | null);
    /** Read one session's job list; null when never written. */
    abstract load(sessionId: string): Promise<RecordFields | null>;
    /**
     * Write one session's job list iff its generation matches. Same contract
     * as `NamespaceStore.casSet`: a missing record counts as generation 0.
     */
    abstract casSet(sessionId: string, fields: RecordFields, expectedGeneration: number): Promise<boolean>;
    /**
     * Drop one session's job list (the session closed) iff its generation
     * matches, so a job another workspace started after the list was read
     * is never dropped unstopped. True when the list is gone, false on
     * conflict.
     */
    abstract delete(sessionId: string, expectedGeneration: number): Promise<boolean>;
    /**
     * The console stream a job list names. Every call for one name reaches
     * the same stream, so the job's owner writes it and any other workspace
     * reads or ends it.
     */
    abstract console(name: string): ConsoleStore;
    /**
     * Keep an owner alive for another `leaseSeconds`, and the consoles of
     * the jobs it still runs with it. A store that expires consoles pushes
     * their expiry out here, so a quiet job keeps its output while its owner
     * lives, and loses it a while after the owner dies with nobody left to
     * end it.
     */
    abstract renew(owner: string, consoles?: readonly string[]): Promise<void>;
    /** Whether an owner's lease still holds. */
    abstract alive(owner: string): Promise<boolean>;
    /**
     * Replace the processes an owner runs (PID to process); none drops its
     * record. A record outlives its owner's lease, so a workspace that finds
     * the owner lapsed still reads what it left running.
     */
    abstract publish(owner: string, processes: Readonly<Record<string, RecordFields>>): Promise<void>;
    /** Every owner's published processes: owner to PID to process. */
    abstract processes(): Promise<Record<string, Record<string, RecordFields>>>;
    /** Ask an owner to stop one of its processes, by its PID, with `signal`. */
    abstract requestStop(owner: string, pid: number, signal: number): Promise<void>;
    /**
     * The stops asked of an owner since it last took them, as [PID, signal]
     * pairs; taking them clears them.
     */
    abstract takeStops(owner: string): Promise<[number, number][]>;
    /** Delete every job list, console, lease and process record. */
    abstract clear(): Promise<void>;
    /** Release any held connections. */
    abstract close(): Promise<void>;
}
//# sourceMappingURL=store.d.ts.map