@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
81 lines • 4.06 kB
TypeScript
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