import { ActivityStore, ArtifactStore, BlobStore, GenerationRunStore, InterruptStore, LogRecord, LogSnapshot, LogStore, MessageStore, MetadataStore, RunStore, SessionIndexStore } from './types.js';
/**
 * The ownership record of a log that a host acquired. The record stays after
 * a release, because the epoch never goes down.
 */
interface Ownership {
    harness: string;
    ownerId: string;
    epoch: number;
    /** Epoch milliseconds, from the store clock. */
    expiresAt: number;
    released: boolean;
    /** Epoch milliseconds, from `release({ wakeInMs })`. */
    wakeAt?: number;
}
/** An input that a host offered to a log. */
interface Offer {
    record: LogRecord;
    /** Epoch milliseconds, from the store clock. */
    offeredAt: number;
    /** True after an append consumed it. The id stays, so a retry is a duplicate. */
    consumed: boolean;
}
/** The offers of one log. */
interface Lane {
    /** The harness of the first offer, for `listLogsWithoutOwner`. */
    harness: string;
    /** By input id, in offer order. */
    inputs: Map<string, Offer>;
}
/** The records that a log keeps. A truncate drops the first ones. */
interface KeptLog {
    /** The position of `records[0]`. A truncate moves it up. */
    firstSeq: number;
    records: Array<LogRecord>;
}
/** The listeners of one store instance, by log id. */
type Listeners = Map<string, Set<() => void>>;
/**
 * The state of the memory log, shared by every store instance on it. Make one
 * with {@link memoryLogState}. Two instances on one state act as two machines
 * on one database: they see the same records, owners, offers, and snapshots,
 * and a write on one calls the listeners of both.
 */
declare class MemoryLogState {
    /** The store clock, in epoch milliseconds. */
    readonly now: () => number;
    readonly logs: Map<string, KeptLog>;
    readonly snapshots: Map<string, LogSnapshot>;
    readonly owners: Map<string, Ownership>;
    readonly affinities: Map<string, string>;
    /** The deleted logs. Only an `acquireOwnership` lets a write or an offer in again. */
    readonly deleted: Set<string>;
    /** When the heartbeat of each host expires, by its host id. */
    readonly hosts: Map<string, number>;
    readonly lanes: Map<string, Lane>;
    /** The listeners of each store instance on this backend. */
    readonly instances: Set<Listeners>;
    constructor(now: () => number);
    /**
     * Call the listeners of `logId` on every store instance. The write is done,
     * so a listener error must not fail it or stop the other listeners.
     */
    notify(logId: string): void;
}
/** The type of the shared state from {@link memoryLogState}. */
export type { MemoryLogState };
/**
 * In-process reference {@link LogStore}, for tests and one-process hosts. The
 * log is lost when the process stops. Records are JSON-copied in and out.
 *
 * `memoryPersistence()` has one. Make your own to share a
 * {@link memoryLogState} between two stores.
 *
 * @param options.state - The log state to use. Pass one
 *   {@link memoryLogState} to two stores, and they act as two machines on
 *   one database. Without it, the store makes its own state.
 *
 * @example
 * ```ts
 * const state = memoryLogState()
 * const machineA = defineAIPersistence({
 *   stores: { ...memoryPersistence().stores, log: memoryLogStore({ state }) },
 * })
 * ```
 */
export declare function memoryLogStore({ state, }?: {
    state?: MemoryLogState;
}): LogStore;
/**
 * A new log state for {@link memoryLogStore}. Give one state to two stores
 * to test two hosts in one process: an append on one store calls the
 * listeners on the other, and both see one owner per log.
 *
 * @example
 * ```ts
 * const state = memoryLogState()
 * const hostA = memoryLogStore({ state })
 * const hostB = memoryLogStore({ state })
 * hostB.subscribe({ logId: 'session-1', listener: () => console.log('new') })
 * await hostA.append({
 *   logId: 'session-1',
 *   seq: 1,
 *   epoch: NO_OWNER_EPOCH,
 *   records: [{ type: 'hello' }],
 * })
 * // The listener on hostB ran.
 * ```
 *
 * @param options.now - The store clock, in epoch milliseconds. Ownership
 *   expiry, wake times, and offer times use it. Default: `Date.now()`. Give a
 *   test clock to move time in a test.
 *
 * @example
 * ```ts
 * let clock = 0
 * const state = memoryLogState({ now: () => clock })
 * // A wake time of 5 s from now is due after this:
 * clock += 5_000
 * ```
 */
export declare function memoryLogState({ now }?: {
    now?: () => number;
}): MemoryLogState;
interface MemoryPersistenceStores {
    messages: MessageStore;
    activities: ActivityStore;
    runs: RunStore;
    generationRuns: GenerationRunStore;
    interrupts: InterruptStore;
    metadata: MetadataStore;
    artifacts: ArtifactStore;
    blobs: BlobStore;
    sessions: SessionIndexStore;
    log: LogStore;
}
/**
 * In-process reference backend for the full state + generation store set.
 *
 * Returns messages + activities + runs + generationRuns + interrupts +
 * metadata + artifacts + blobs + sessions + log.
 * Plain `chat()` does not use `log`. A harness host keeps each session in
 * `log` and does not use `messages`. Locks are not included. Use
 * `InMemoryLockStore` + `withLocks` from `@tanstack/ai` when a test or
 * single-process app needs coordination.
 *
 * @example
 * ```ts
 * const persistence = memoryPersistence()
 * ```
 */
export declare function memoryPersistence(): import('./types.js').AIPersistence<MemoryPersistenceStores>;
