import { type Clock } from "./clock.js"; import { type Relation } from "./comms.js"; import type { RoostEvent } from "./events.js"; import type { JobStateName } from "./protocol.js"; /** A watch: tell `watcher` (a session key) once when job `id` is next idle, or has ended. */ export interface Watch { watcher: string; watcherName: string; /** The watching job, when a job watches (null: a foreground session). */ watcherId?: string | null; id: string; when: "idle" | "ended"; at: number; } /** The parts of a job's row a notice is made of. */ export interface WatchedRow { id: string; name: string; state: JobStateName; waitingFor: string | null; question: string | null; summary: string | null; error: string | null; } /** The sessions: the peer that asks (`P`: whatever the daemon calls a connected session) and its tree. */ export interface WatchesSessionsPort
{ /** The peer takes no agent items (a watch is told as one). */ refusesItems(peer: P): boolean; /** The peer's session key (throws what the daemon throws for a session-less peer). */ keyOf(peer: P): string; name(peer: P): string; /** The peer's job, when a job asks (null: a foreground session). */ jobId(peer: P): string | null; /** The session `to` (an id or a name) names, among those the peer reaches (throws when none, or many). */ find(peer: P, to: string): { key: string; id: string; role: string; }; } export interface WatchesJobsPort { /** The job still has a record. */ exists(id: string): boolean; row(id: string): WatchedRow | undefined; /** What the watched job's session is to the watcher's. */ relation(watcherKey: string, jobId: string): Relation; /** Hand a notice to the session `key`; `reached`: it got it (a gone watcher is not told). */ deliver(key: string, text: string, meta: { from: string; relation: Relation; }): Promise<{ outcome: string; reached: boolean; }>; } /** The file the watches live in (the daemon's writes atomically under the roost's home). */ export interface WatchesStore { read(): unknown; write(v: unknown): void; } export interface WatchesDeps
{ sessions: WatchesSessionsPort
;
jobs: WatchesJobsPort;
store: WatchesStore;
record(e: Omit {
/** Loads the file: expired watches and ones on jobs that are gone are dropped. Call once the jobs are known. */
load(): void;
/** The `watch` op of `peer`. */
add(peer: P, args: {
id?: unknown;
when?: unknown;
} | undefined): Promise (deps: WatchesDeps ): Watches ;