/**
 * CollaborativeEngine — Multi-participant sync wrapper for HeadlessEngine.
 *
 * Wraps HeadlessEngine + SyncCoordinator to enable transparent collaboration.
 * Agent code uses the same Workbook/Worksheet API — sync is invisible.
 *
 * Three sync modes:
 * - 'immediate': push after every mutation (highest consistency)
 * - 'batch': push on flush() or after batchSize mutations
 * - 'manual': framework controls sync (for colab-eval test scenarios)
 *
 * @experimental API surface is not yet stable. Depends on internal NAPI
 * coordinator handles and raw Yrs state boot paths. Subject to breaking
 * changes in minor versions.
 */
import { type NapiAddonModule } from './boot.js';
import type { Workbook, Worksheet } from '@mog-sdk/contracts/api';
/** @experimental */
export type SyncMode = 'immediate' | 'batch' | 'manual';
/** @experimental */
export interface LockScope {
    type: 'sheet' | 'workbook' | 'structural';
    sheetId?: string;
}
/** @experimental */
export interface Lock {
    id: string;
    owner: string;
    scope: LockScope;
}
/** @experimental */
export interface CollaborativeEngineOptions {
    /** Pre-loaded napi addon module. */
    computeAddon: NapiAddonModule;
    /** Coordinator handle (from coordinator_create). If not provided, one is created. */
    coordinatorHandle?: number;
    /** How sync is triggered. Default: 'immediate'. */
    syncMode?: SyncMode;
    /** For batch mode: flush after N mutations. Default: 10. */
    batchSize?: number;
    /** XLSX buffer to import on boot. */
    xlsxSource?: Buffer;
    /** Participant ID. Defaults to random UUID. */
    participantId?: string;
    /** Document ID. Defaults to random UUID. */
    docId?: string;
    /**
     * IANA timezone for the session. Forwarded to the underlying headless
     * boot — see `HeadlessOptions.userTimezone`. Defaults to `'UTC'`.
     */
    userTimezone?: string;
}
/** @experimental */
export interface FlushResult {
    serverDiff: number[];
    ok: boolean;
}
/** @experimental */
export interface SyncResult {
    pushed: boolean;
    pulled: boolean;
}
/** @experimental */
export declare class CollaborativeEngine {
    private readonly _inner;
    private readonly _coordinator;
    private readonly _participantId;
    private readonly _syncMode;
    private readonly _batchSize;
    private _pendingMutations;
    private _touchedSheets;
    private _disposed;
    private _ownsCoordinator;
    /** @internal — use CollaborativeEngine.create() */
    private constructor();
    static create(options: CollaborativeEngineOptions): Promise<CollaborativeEngine>;
    /**
     * Create a CollaborativeEngine from the coordinator's current Yrs state.
     *
     * Used for the 2nd, 3rd, ... participants. The coordinator already has state
     * pushed by the first participant. This method:
     * 1. Gets the coordinator's raw Yrs state bytes
     * 2. Creates a HeadlessEngine from those bytes via `from_yrs_state` (same Yrs items)
     * 3. Pushes/pulls to align Yrs docs with the coordinator
     */
    static createFromCoordinator(options: {
        computeAddon: NapiAddonModule;
        coordinatorHandle: number;
        syncMode?: SyncMode;
        participantId?: string;
        userTimezone?: string;
    }): Promise<CollaborativeEngine>;
    /** The standard Workbook API. Agents use this. */
    get workbook(): Workbook;
    /** Convenience: active worksheet. */
    get ws(): Worksheet;
    /** This engine's participant ID. */
    get participantId(): string;
    /** The coordinator handle (for sharing between engines). */
    get coordinatorHandle(): number;
    /** Current sync mode. */
    get syncMode(): SyncMode;
    /** Track that a sheet was touched (for lock validation). */
    trackSheetTouch(sheetId: string): void;
    /**
     * Push local changes to the coordinator.
     * In manual mode, call this explicitly. In immediate mode, auto-called.
     */
    flush(): Promise<FlushResult>;
    /**
     * Pull remote changes from the coordinator.
     */
    pull(): Promise<void>;
    /**
     * Full sync cycle: push local changes, then pull remote changes.
     */
    sync(): Promise<SyncResult>;
    /** Acquire a lock. Returns lock ID. */
    lock(scope: LockScope, ttlSeconds?: number): Promise<string>;
    /** Release a lock. */
    unlock(lockId: string): Promise<void>;
    /** List all active locks. */
    locks(): Promise<Lock[]>;
    /**
     * Acquire a structural lock on a sheet. Only one participant can hold a
     * structural lock per sheet. This serializes insert/delete row/col operations
     * to prevent divergent posToId/idToPos maps under concurrent structural edits.
     *
     * Unlike sheet locks, structural locks do NOT block normal cell edits.
     *
     * @param sheetId UUID string of the sheet to lock
     * @param ttlSeconds Lock TTL in seconds (default 30s — structural ops should be fast)
     * @returns Lock ID string for releasing
     * @throws If another participant holds the structural lock on this sheet
     */
    acquireStructuralLock(sheetId: string, ttlSeconds?: number): Promise<string>;
    /**
     * Release a structural lock.
     * @param lockId The lock ID returned by acquireStructuralLock
     */
    releaseStructuralLock(lockId: string): Promise<void>;
    /**
     * Execute a structural operation (insert/delete rows/cols) under a structural
     * lock. Acquires the lock, runs the operation, syncs, then releases the lock.
     * If the lock cannot be acquired (held by another participant), retries up to
     * `maxRetries` times with a short delay.
     *
     * @param sheetId UUID string of the sheet
     * @param operation The structural mutation to perform
     * @param maxRetries Max lock acquisition retries (default 5)
     * @param retryDelayMs Delay between retries in ms (default 50)
     */
    withStructuralLock<T>(sheetId: string, operation: () => Promise<T>, maxRetries?: number, retryDelayMs?: number): Promise<T>;
    /** Dispose the engine — leave coordinator, release locks, dispose engine. */
    dispose(): Promise<void>;
}
/**
 * Create a coordinator and N collaborative engines sharing it.
 * All engines use manual sync mode (for test scenarios).
 *
 * @experimental
 */
export declare function createCollaborativeGroup(addon: NapiAddonModule, count: number, options?: {
    syncMode?: SyncMode;
    xlsxSource?: Buffer;
    userTimezone?: string;
}): Promise<{
    engines: CollaborativeEngine[];
    coordinatorHandle: number;
    /** Sync all engines: each flushes then pulls. */
    sync: () => Promise<void>;
    /** Dispose all engines and the coordinator. */
    dispose: () => Promise<void>;
}>;
