37 lines
1.7 KiB
TypeScript
37 lines
1.7 KiB
TypeScript
export * as SessionExecution from "./execution"
|
|
|
|
import { Context, Effect, Layer } from "effect"
|
|
import { LayerNode } from "../effect/layer-node"
|
|
import { Node } from "../effect/app-node"
|
|
import { SessionRunner } from "./runner/index"
|
|
import { SessionSchema } from "./schema"
|
|
|
|
export interface Interface {
|
|
/** Snapshots active execution owned by this process. */
|
|
readonly active: Effect.Effect<ReadonlySet<SessionSchema.ID>>
|
|
/** Starts execution while idle or joins the active execution. */
|
|
readonly resume: (sessionID: SessionSchema.ID) => Effect.Effect<void, SessionRunner.RunError>
|
|
/** Registers newly recorded work. Repeated wakeups may coalesce. */
|
|
readonly wake: (sessionID: SessionSchema.ID) => Effect.Effect<void>
|
|
/** Interrupt active work owned by this process. Idle interruption is a no-op. */
|
|
readonly interrupt: (sessionID: SessionSchema.ID) => Effect.Effect<void>
|
|
/** Resolves once this process owns no active execution for the Session. Returns immediately when idle and never starts work. */
|
|
readonly awaitIdle: (sessionID: SessionSchema.ID) => Effect.Effect<void>
|
|
}
|
|
|
|
/** Routes execution from a Session ID to the runner owned by that Session's Location. */
|
|
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/SessionExecution") {}
|
|
|
|
export const node = LayerNode.unbound(Service, Node.tags.values.global)
|
|
|
|
/** Low-level compatibility layer for callers that only need durable Session recording. */
|
|
export const noopLayer = Layer.succeed(
|
|
Service,
|
|
Service.of({
|
|
active: Effect.succeed(new Set()),
|
|
resume: () => Effect.void,
|
|
wake: () => Effect.void,
|
|
interrupt: () => Effect.void,
|
|
awaitIdle: () => Effect.void,
|
|
}),
|
|
)
|