UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

62 lines • 3.63 kB
import { type CallerDispatchFn } from '../context/session_context.ts'; import type { StatusWriter } from './types.ts'; import type { SessionState } from './session/session.ts'; /** * Run `fn` as the body of the line `signal` belongs to. Everything the * body awaits, down to the status write, can then ask `abortedLine` * whether its caller is still waiting, without the signal being threaded * through every handler. `shell` is the only caller. */ export declare function runWithLineAbort<T>(signal: AbortSignal | undefined, sessions: readonly SessionState[], writer: StatusWriter, fn: () => Promise<T>, stop?: AbortSignal): Promise<T>; /** * The identity of the line stamping on `session`, for `recordStatus` to * record and an aborted line to compare its snapshot against. * * Null when no line is running (a background job, a test driving a * handler directly) and null when more than one line is live on this * session, which is the case the comparison exists to refuse: with two * writers in play nothing can attribute the last stamp, so an aborted * line declines to restore rather than guess. */ export declare function lineStatusWriter(session: SessionState): StatusWriter | null; /** * The aborted signal of the line stamping on `session`, or undefined * when that line is still wanted, or when no line is running at all (a * background job, a test driving a handler directly): nobody is * waiting there and nothing is an orphan. * * Read from every live frame for the session rather than the newest * frame. On an isolating runtime the live frames are the current task's * alone, so the answer is exact. On the browser fallback the newest * frame may belong to another line that happens to overlap, so the status write * refuses only when every live line on this session has aborted: one * line's abort never reaches a concurrent line's statement, and the one * case left open is two aborted-or-not lines overlapping on one session * without task isolation, where the fallback cannot tell them apart. */ export declare function abortedLine(session: SessionState): AbortSignal | undefined; /** * A dispatch that refuses to start an op once `signal` has fired. A * cancelled asyncio task unwinds at its next await, so a Python handler * that loops over operands (`rm link1 link2`, `chmod`, `touch`) never * reaches the next one. A JS handler resumes after the await that was in * flight when the caller was released and would begin the next write. * Refusing at the dispatcher, the one seam every handler's I/O goes through, * stops it there without threading the signal through each handler. An * op already in flight settles on its own. * * The command's ops also share one yield budget: a walk the index answers * resolves each op in a microtask, which no timer or abort ever runs between, * so the budget hands the loop a task-queue turn every few milliseconds and * the abort or timeout that fired there refuses the next op. Python's * dispatcher spends the running task's budget, `task_turn`, the same way. * The ops a command issues at once (the patterns of one grep) take the first * one's answer, a turn or none, and go on together, as the tasks Python * gathers start on budgets of their own: a turn each would let one op finish * all it resolves without I/O before the next starts, and share nothing in * flight with it. */ export declare function guardDispatch(dispatch: CallerDispatchFn, signal: AbortSignal | undefined): CallerDispatchFn; /** A fresh line identity. */ export declare function newStatusWriter(): StatusWriter; //# sourceMappingURL=abort.d.ts.map