import type { EnvironmentAdapter, PowerLineConnection, ProvisionEvent } from "./adapter.js"; /** * Lifecycle state for a single environment managed by an adapter. * * - `idle` — no active infrastructure or connection. * - `provisioning` — provision or reconnect in progress (mutex held). * - `provisioned` — infrastructure ready, not yet connected. * - `connected` — gRPC connection to PowerLine is established. */ export type AdapterLifecycleState = "idle" | "provisioning" | "provisioned" | "connected"; /** * Abstract base class for environment adapters that enforces lifecycle state * transitions and prevents concurrent operations on the same environment. * * Subclasses implement the `do*` template methods; {@link BaseAdapter} wraps * each with state guards and a per-environment mutex. * * The {@link EnvironmentAdapter} interface is unchanged — callers see the * same API. `reconnect` is NOT defined here because * {@link reconnectOrProvision} checks `adapter.reconnect` to decide whether * to attempt fast reconnect. Subclasses that support reconnect should define * their own `reconnect` method and use `withProvisionLock` for the * same mutex/state semantics as `provision`. */ export declare abstract class BaseAdapter implements EnvironmentAdapter { abstract type: string; private readonly states; private readonly locks; /** Return the lifecycle state for an environment (`idle` if unknown). */ getState(environmentId: string): AdapterLifecycleState; /** * Provision infrastructure and yield progress events. * * Acquires a per-environment mutex for the duration of provisioning. * On success the state moves to `provisioned`; on error it resets to `idle`. */ provision(environmentId: string, config: Record, powerlineToken: string): AsyncGenerator; /** * Establish a connection to the PowerLine. * * Allowed from any non-locked state. Docker attach calls this from `idle` * after a server restart (re-resolves connectivity on the fly). */ connect(environmentId: string, config: Record, powerlineToken: string): Promise; /** * Release connection resources. Idempotent — safe to call from any * non-locked state. Throws if a provision/reconnect is in progress to * prevent tearing down resources while they are being set up. */ disconnect(environmentId: string): Promise; /** * Stop the environment's compute. Idempotent — resets state to `idle`. * Throws if a provision/reconnect is in progress. */ stop(environmentId: string, config: Record): Promise; /** * Destroy the environment's compute. Idempotent — removes all state. * Throws if a provision/reconnect is in progress. */ destroy(environmentId: string, config: Record): Promise; /** Return true if the PowerLine is reachable. Subclasses must implement. */ abstract healthCheck(connection: PowerLineConnection): Promise; protected abstract doProvision(environmentId: string, config: Record, powerlineToken: string): AsyncGenerator; protected abstract doConnect(environmentId: string, config: Record, powerlineToken: string): Promise; protected abstract doDisconnect(environmentId: string): Promise; protected abstract doStop(environmentId: string, config: Record): Promise; protected abstract doDestroy(environmentId: string, config: Record): Promise; /** * Wrap an async generator (provision or reconnect) with the lifecycle mutex. * * Acquires a per-environment lock, sets state to `provisioning`, yields all * events from the wrapped generator, then sets state to `provisioned`. * On error the state resets to `idle`. Subclasses that support `reconnect` * should use this in their own `reconnect` method: * * ```ts * public async *reconnect(envId, config, token) { * yield* this.withProvisionLock(envId, this.doReconnect(envId, config, token)); * } * ``` */ protected withProvisionLock(environmentId: string, generator: AsyncGenerator): AsyncGenerator; private assertNotLocked; } //# sourceMappingURL=base-adapter.d.ts.map