/** * kernel operation lifecycle helpers (M0). * * The three methods exposed here (`cancel`, `close`, `finished`) are * standalone functions that the `KernelOperationBackend` implementation * delegates to. Keeping them in this dedicated file lets the parallel * impl-results work (which owns the fetch-* methods on * `KernelOperationBackend`) land independently — at merge time it can * either import these helpers from here or inline them, with no * conflicts on the call sites. * * Mapping to the existing `DBSQLOperation` semantics: * - `cancel()` → ` driver.cancelOperation(...)` on Thrift today * (`lib/DBSQLOperation.ts:241-259`). For kernel this is a one-shot * forward to the napi `Statement.cancel()` which in turn calls * `ExecutedStatementHandle::cancel(&self).await` in the kernel. * - `close()` → `driver.closeOperation(...)` on Thrift today * (`lib/DBSQLOperation.ts:265-284`). For kernel this is the napi * `Statement.close()` which awaits the server-side delete. * - `finished({progress, callback})` → the 100ms polling loop in * `DBSQLOperation.waitUntilReady` today (`lib/DBSQLOperation.ts:337-391`). * For M0 the kernel's `Statement::execute().await` already blocks * until the statement is in a terminal state, so by the time the JS * side has an `ExecutedStatement` (and therefore a binding-level * `Statement`) the underlying operation is already finished. The * M0 implementation here therefore resolves immediately, optionally * firing the progress callback once with a synthesized "finished" * response so callers that wire a progress UI still see a single * completion tick. */ import Status from '../dto/Status'; import { OperationStatus } from '../contracts/OperationStatus'; import IClientContext from '../contracts/IClientContext'; /** * Minimal shape of the napi `Statement` that the lifecycle helpers * depend on. Declared structurally so unit tests can hand in a mock * without pulling the real native binding into the test process. * * The real binding's `Statement` (see `native/kernel/index.d.ts`) has * additional methods (`fetchNextBatch`, `schema`) which the lifecycle * helpers deliberately don't touch — those belong to the results * feature's surface. */ export interface KernelStatementHandle { cancel(): Promise; close(): Promise; } /** * Internal lifecycle state shared between the operation backend and * these helpers. `KernelOperationBackend` keeps an instance of this and * passes it to each helper call. Centralising the flags here means * the helpers stay pure (no `this`) and the backend stays * straightforward. */ export interface KernelOperationLifecycleState { /** True once `cancel()` has succeeded — subsequent fetch* must throw. */ isCancelled: boolean; /** True once `close()` has been called (idempotent). */ isClosed: boolean; } /** * Factory for a fresh lifecycle-state record. Helps keep test setup * tidy. */ export declare function createLifecycleState(): KernelOperationLifecycleState; /** * Cancel an in-flight kernel operation. * * Mirrors `DBSQLOperation.cancel` semantics * (`lib/DBSQLOperation.ts:241-259`): * - idempotent: returns success if already cancelled or closed * (no-ops are not bubbled to the kernel because the binding's * `Statement::cancel` already treats already-finished statements as * a no-op, but we still want to avoid a network round-trip here), * - sets the cancelled flag _before_ awaiting the napi call so that a * concurrent `fetchChunk()` observing the flag short-circuits as * soon as the await yields (matches the Thrift flag-set ordering * at `lib/DBSQLOperation.ts:254`), * - returns a `Status.success()` on success (no rich Thrift status * payload is available from the kernel side). */ export declare function kernelCancel(state: KernelOperationLifecycleState, statement: KernelStatementHandle, context: IClientContext, operationId: string): Promise; /** * Close a kernel operation. * * Mirrors `DBSQLOperation.close` semantics * (`lib/DBSQLOperation.ts:265-284`) without the Thrift-only * direct-results-prefetch optimisation: * - idempotent: a second call is a no-op, * - awaits the binding's `Statement::close` (which goes through to * the kernel's `delete_statement` RPC), * - sets the closed flag _before_ awaiting so a concurrent fetch * sees the closed state as soon as the await yields. */ export declare function kernelClose(state: KernelOperationLifecycleState, statement: KernelStatementHandle, context: IClientContext, operationId: string): Promise; /** * `IOperation.finished({progress, callback})` M0 implementation. * * The Thrift implementation is a 100ms polling loop over * `getOperationStatus` (`lib/DBSQLOperation.ts:337-391`). For kernel M0, * the kernel's `Statement::execute().await` already blocks until the * statement reaches a terminal state — by the time the JS layer has * a `Statement` handle, the operation has already finished. * * Therefore the M0 implementation resolves immediately. If the * caller supplied a progress callback we still invoke it once (a * single completion tick) so progress-UI consumers see the same * "operation is now finished" signal they'd get from the polling * Thrift path — just without the intermediate `RUNNING_STATE` * notifications. * * If the operation is already cancelled or closed, this is a no-op * (matches the Thrift `failIfClosed` / cancelled-state semantics * without throwing; throwing is the responsibility of subsequent * fetch calls). */ export declare function kernelFinished(state: KernelOperationLifecycleState, options?: { progress?: boolean; callback?: (status: OperationStatus) => unknown; }, richFields?: () => Promise>): Promise; /** * Pre-flight check used by fetch* methods on `KernelOperationBackend`. * If the operation has been cancelled or closed, throw the same * `OperationStateError` classes the facade uses. Keeping these typed lets * callers branch on `OperationStateErrorCode` consistently for Thrift and kernel. * * Exported so impl-results can call it at the top of every fetch * call without duplicating the if/throw logic. */ export declare function failIfNotActive(state: KernelOperationLifecycleState): void;