UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

81 lines • 4.06 kB
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