import type { z } from 'zod';
import type { CapabilityDefinition } from '../capabilities/capability-definition.js';
import type { IDeviceRuntimeState } from './device-runtime-state.js';
/**
 * Bridge a cap's `runtimeState` slice to its read-side methods.
 *
 * Pattern: provider keeps the camera fetch / write path, but delegates
 * stale-check + slice read + cold-start fallback to this helper. Cuts
 * the boilerplate that every provider would otherwise repeat across
 * `getStatus`, `getSettings`, and any other read-side cap method.
 *
 * Convention: the cap's `runtimeState` schema must include a numeric
 * `lastFetchedAt` field (ms epoch) so the helper can drive the
 * stale-check. The field is stripped from the value returned by
 * `getStatus` so the cap's status schema (which doesn't carry it)
 * still parses cleanly.
 *
 * Usage in a provider:
 * ```ts
 * const bridge = createRuntimeStateBridge({
 *   runtimeState: this.runtimeState,
 *   cap: ptzAutotrackCapability,
 *   ownDeviceId: this.id,
 *   refresh: () => this.refreshAutotrackFromCamera(),
 *   staleMs: 10_000,
 *   empty: () => emptyAutotrackStatus(),
 * })
 *
 * const provider: InferNativeProvider<typeof ptzAutotrackCapability> = {
 *   getStatus: bridge.getStatus,
 *   getSettings: async ({ deviceId }) => {
 *     if (deviceId !== this.id) return null
 *     await bridge.ensureFresh()
 *     return this.runtimeState.getCapState<...>(...)?.currentSettings ?? null
 *   },
 *   setEnabled: async (...) => { ... ; await this.refreshAutotrackFromCamera() },
 *   setSettings: async (...) => { ... ; await this.refreshAutotrackFromCamera() },
 * }
 * ```
 *
 * Single-flight (collapsing concurrent `refresh()` invocations) lives
 * INSIDE `refresh` — the camera client owns its own promise slot. This
 * helper stays thin so a single provider can host multiple cap-bridged
 * readers without fighting over a shared promise.
 */
export interface RuntimeStateBridge<TStatus> {
    /** Run a stale-check; if the slice is missing or older than
     *  `staleMs`, await `refresh()`. Idempotent within the freshness
     *  window — back-to-back calls touch zero camera I/O. */
    readonly ensureFresh: () => Promise<void>;
    /** Drop-in `getStatus` provider method. Includes the cross-device
     *  guard + freshness check + status projection from the slice. */
    readonly getStatus: (input: {
        readonly deviceId: number;
    }) => Promise<TStatus>;
}
export declare function createRuntimeStateBridge<TCap extends CapabilityDefinition & {
    status: {
        schema: z.ZodType;
    };
}>(params: {
    readonly runtimeState: IDeviceRuntimeState;
    readonly cap: TCap;
    readonly ownDeviceId: number;
    readonly refresh: () => Promise<void>;
    readonly staleMs: number;
    readonly empty: () => z.infer<TCap['status']['schema']>;
}): RuntimeStateBridge<z.infer<TCap['status']['schema']>>;
//# sourceMappingURL=runtime-state-helpers.d.ts.map