import type { LucidRawRunner } from '../stores/lucid.js';
/**
 * Text channels' short-lived state, every entry with a TTL: the provider message ids already taken
 * (so a webhook delivered twice starts one turn), a question waiting for the person's answer, an
 * outcome already relayed.
 *
 * {@link InMemoryChannelStore} only sees its own process. With several replicas a retry, an answer
 * or a settled proposal can land on another one, so use a shared store there:
 * {@link lucidChannelStore} (the default when the agent's own store is Lucid),
 * {@link redisChannelStore}, or your own.
 */
export interface ChannelStore {
    /**
     * Take `key` for `ttlMs` — atomically. `true` when it was free (now taken), `false` when someone
     * already took it.
     */
    claim(key: string, ttlMs: number): boolean | Promise<boolean>;
    /** The live value under `key`, or `null`. */
    get(key: string): string | null | Promise<string | null>;
    /** Store `value` under `key` for `ttlMs`, replacing what was there. */
    set(key: string, value: string, ttlMs: number): void | Promise<void>;
    delete(key: string): void | Promise<void>;
}
/** Process-local {@link ChannelStore}: a single replica, tests, development. */
export declare class InMemoryChannelStore implements ChannelStore {
    #private;
    private readonly maxEntries;
    /** @param maxEntries Past this many live keys, the oldest are forgotten first. */
    constructor(maxEntries?: number);
    claim(key: string, ttlMs: number): boolean;
    get(key: string): string | null;
    set(key: string, value: string, ttlMs: number): void;
    delete(key: string): void;
}
/**
 * The slice of a Redis client {@link redisChannelStore} uses — an `@adonisjs/redis` connection
 * (ioredis) has it: `redisChannelStore(redis)` or `redisChannelStore(redis.connection('main'))`.
 */
export interface ChannelStoreRedis {
    set(key: string, value: string, px: 'PX', ttlMs: number, nx: 'NX'): Promise<unknown>;
    set(key: string, value: string, px: 'PX', ttlMs: number): Promise<unknown>;
    get(key: string): Promise<string | null>;
    del(key: string): Promise<unknown>;
}
/** A {@link ChannelStore} shared by every replica, over Redis (`SET … PX … NX` for claims). */
export declare function redisChannelStore(redis: ChannelStoreRedis, options?: {
    prefix?: string;
}): ChannelStore;
export interface LucidChannelStoreOptions {
    /** A named connection of the `Database` manager. Default: the one `db` is. */
    connection?: string;
    /** Default `agent_channel_state`. */
    table?: string;
    /**
     * Create the table (and its index) on first use. Default `true`; `false` when a migration owns it
     * (`createAgentTables` and the published migration create it under the default name).
     */
    autoCreateTables?: boolean;
    /** How often a claim also deletes expired rows. Default 10 minutes. */
    purgeEveryMs?: number;
}
/** A Lucid `Database` (or one of its connections): raw SQL, and named connections when it has them. */
export type LucidChannelStoreDatabase = LucidRawRunner & {
    connection?(name?: string): LucidRawRunner;
};
/**
 * A {@link ChannelStore} in the app's SQL database through Lucid — shared by every replica, no Redis
 * needed. One row per key in `agent_channel_state`; a claim is one `INSERT` that skips on a duplicate
 * key (`ON CONFLICT DO NOTHING`, `INSERT IGNORE` on MySQL), so the primary key is the lock. Expired
 * rows are deleted as claims come in (`purgeEveryMs`), and an expired key can be taken again.
 *
 * ```ts
 * import db from '@adonisjs/lucid/services/db'
 * channels.handle(adapter, { …, store: lucidChannelStore(db) })
 * ```
 */
export declare function lucidChannelStore(database: LucidChannelStoreDatabase, options?: LucidChannelStoreOptions): ChannelStore;
//# sourceMappingURL=store.d.ts.map