/**
 * Sequence-numbered runner for optimistic save flows where the user can fire
 * the next action before the previous save resolves. Each invocation gets a
 * fresh sequence number from a shared `nextSequence` callback; the runner
 * only commits success / failure when its sequence is still the latest.
 *
 * Used by the Style configurator: tapping personality A then quickly tapping
 * personality B should land B's save even if A's network round-trip is
 * slower, and A's late-arriving response must not clobber B's local state.
 */
export type OptimisticActionRun<TSuccess> = Readonly<{
    /**
     * Pure result computed locally before the network call fires (the
     * optimistic "this is what the world will look like" snapshot). Skipped
     * if the runner has already been superseded.
     */
    optimistic?: () => void;
    /** The network call. Resolves with the persisted payload. */
    network: () => Promise<TSuccess>;
    /**
     * Invoked when `network` resolves AND this run is still the latest.
     * Stale runs swallow the success silently — the next run will reconcile.
     */
    onSuccess: (success: TSuccess) => void;
    /**
     * Invoked when `network` rejects AND this run is still the latest. Stale
     * failures are ignored on the same principle.
     */
    onError: (error: unknown) => void;
}>;
export type OptimisticActionRunner = Readonly<{
    /** Schedule a new run; returns its sequence number for debugging / tests. */
    run: <TSuccess>(action: OptimisticActionRun<TSuccess>) => Promise<number>;
    /** Force the runner into a known sequence — useful for unmount sentinels. */
    invalidate: () => void;
    /** Read the latest sequence. Test/debug only; UI should not branch on it. */
    current: () => number;
}>;
/**
 * Create a runner. The runner is stateful (holds the latest sequence)
 * but the inputs to each `run` call are pure data — so individual actions
 * remain easy to unit-test by stubbing `network`.
 */
export declare function createOptimisticActionRunner(): OptimisticActionRunner;
