import type { AbstractLevel } from 'abstract-level';
import type { EnboxPlatformAgent } from './types/agent.js';
import type { DeadLetterCategory, DeadLetterEntry, StartSyncParams, SyncConnectivityState, SyncEngine, SyncEventListener, SyncHealthSummary, SyncIdentityOptions } from './types/sync.js';
export type SyncEngineLevelParams = {
    agent?: EnboxPlatformAgent;
    dataPath?: string;
    db?: AbstractLevel<string | Buffer | Uint8Array>;
};
type SyncDirection = 'push' | 'pull';
type SyncRunOptions = {
    verifyConvergence?: boolean;
};
export declare class SyncEngineLevel implements SyncEngine {
    /**
     * Holds the instance of a `EnboxPlatformAgent` that represents the current execution context for
     * the `SyncEngineLevel`. This agent is used to interact with other Enbox agent components. It's
     * vital to ensure this instance is set to correctly contextualize operations within the broader
     * Enbox Agent framework.
     */
    private _agent?;
    /**
     * An instance of the `AgentPermissionsApi` that is used to interact with permissions grants used during sync
     */
    private _permissionsApi;
    private readonly _db;
    private _syncIntervalId?;
    private _syncLock;
    /**
     * Durable replication ledger — persists per-link checkpoint state.
     * Used by live sync to track pull progression per link.
     * Lazily initialized on first use to avoid sublevel() calls on mock dbs.
     */
    private _ledger?;
    /**
     * In-memory cache of active links, keyed by `{did}^{dwnUrl}^{protocol}`.
     * Populated from the ledger on `startLiveSync`, used by subscription handlers
     * to avoid async ledger lookups on every event.
     */
    private readonly _activeLinks;
    /**
     * Per-link in-memory delivery-order tracking for the pull path. Keyed by
     * the same link key as `_activeLinks`. Not persisted — on crash, replay
     * restarts from `contiguousAppliedToken` and idempotent apply handles
     * re-delivered events.
     */
    private readonly _linkRuntimes;
    /** Current sync mode, set by `startSync`. Reset to `undefined` by `stopSync`/`clear`. */
    private _syncMode;
    /**
     * Monotonic session generation counter. Incremented on every teardown.
     * Async operations (repair, retry timers) capture the generation at start
     * and bail if it has changed — this prevents stale work from mutating
     * state after teardown or mode switch.
     */
    private _engineGeneration;
    /** Active live pull subscriptions (remote -> local via MessagesSubscribe). */
    private _liveSubscriptions;
    /** Active local EventLog subscriptions for push-on-write (local -> remote). */
    private _localSubscriptions;
    /** Connectivity state derived from subscription health. */
    private _connectivityState;
    /** Registered event listeners for observability. */
    private readonly _eventListeners;
    /** Per-link push runtime: queue, debounce timer, retry state. */
    private readonly _pushRuntimes;
    /**
     * CIDs recently received via pull subscription, keyed by `cid|dwnUrl` to
     * scope suppression per remote endpoint. A message pulled from Provider A
     * is only suppressed for push back to Provider A — it still fans out to
     * Provider B and C. TTL: 60 seconds. Cap: 10,000 entries.
     */
    private readonly _recentlyPulledCids;
    /** TTL for echo-loop suppression entries (60 seconds). */
    private static readonly ECHO_SUPPRESS_TTL_MS;
    /** Maximum entries in the echo-loop suppression cache. */
    private static readonly ECHO_SUPPRESS_MAX_ENTRIES;
    /** Validate `SyncIdentityOptions` for `registerIdentity` and `updateIdentityOptions`. */
    private static validateSyncIdentityOptions;
    private validateSyncScopeClosure;
    private static createScopeClosureValidationState;
    private scanSyncScopeClosure;
    private scanSyncScopeProtocol;
    private static recordScopeClosureEdges;
    private static recordUsesClosureProtocols;
    private static recordDependencyClosureProtocols;
    private static enqueueScopeClosureProtocol;
    private static scopeClosureErrorDetails;
    private permissionGrantIdsForClosureProtocol;
    private fetchLocalProtocolHistory;
    private static protocolDefinitionFromMessage;
    private static isProtocolDefinition;
    private static addProtocolEdge;
    private static formatStringSet;
    private static formatProtocolEdges;
    private buildSyncTargetsForEndpoint;
    private buildSyncTargetResolutions;
    /**
     * Cached sync targets result from the last {@link getSyncTargets} call.
     * Invalidated on identity registration/unregistration/update.
     * TTL-based: cleared after 30 seconds to pick up DID document changes.
     */
    private _syncTargetsCache?;
    /**
     * Monotonic generation counter for sync target cache invalidation.
     * Bumped on every invalidation (register/unregister/update/clear/close/stopSync).
     * An in-flight `getSyncTargets()` captures the generation before awaiting
     * and only writes to the cache if it hasn't changed, preventing a
     * concurrent mutation from being masked by stale data.
     */
    private _syncTargetsCacheGeneration;
    /** TTL for the sync targets cache (30 seconds). */
    private static readonly SYNC_TARGETS_CACHE_TTL_MS;
    /** Backoff schedule for recently published did:dht records. */
    private static readonly DID_RESOLUTION_RETRY_BACKOFF_MS;
    /** Count of consecutive sync failures (for backoff in poll mode). */
    private _consecutiveFailures;
    /** Maximum consecutive failures before entering backoff. */
    private static readonly MAX_CONSECUTIVE_FAILURES;
    /** Backoff multiplier for consecutive failures (caps at 4x the configured interval). */
    private static readonly MAX_BACKOFF_MULTIPLIER;
    /**
     * Bound browser event handlers so they can be added and removed.
     * Set in `startBrowserConnectivityListeners`, cleared in `stopBrowserConnectivityListeners`.
     */
    private _onOnline?;
    private _onOffline?;
    private _onVisibilityChange?;
    constructor({ agent, dataPath, db }: SyncEngineLevelParams);
    /** Lazy accessor for the replication ledger. */
    private get ledger();
    /** LevelDB sublevel for permanently failed messages (dead letters). */
    private get _deadLetters();
    /** LevelDB sublevel for pull entries that are temporarily deferred. */
    private get _deferredPulls();
    private clearSyncDb;
    /**
     * Retrieves the `EnboxPlatformAgent` execution context.
     *
     * @returns The `EnboxPlatformAgent` instance that represents the current execution context.
     * @throws Will throw an error if the `agent` instance property is undefined.
     */
    get agent(): EnboxPlatformAgent;
    set agent(agent: EnboxPlatformAgent);
    get hasActiveSubscriptions(): boolean;
    get connectivityState(): SyncConnectivityState;
    on(listener: SyncEventListener): () => void;
    /** Emit a sync event to all registered listeners. */
    private emitEvent;
    private emitReconcileApplied;
    clear(): Promise<void>;
    close(): Promise<void>;
    registerIdentity({ did, options }: {
        did: string;
        options: SyncIdentityOptions;
    }): Promise<void>;
    unregisterIdentity(did: string): Promise<void>;
    getIdentityOptions(did: string): Promise<SyncIdentityOptions | undefined>;
    updateIdentityOptions({ did, options }: {
        did: string;
        options: SyncIdentityOptions;
    }): Promise<void>;
    sync(direction?: SyncDirection, options?: SyncRunOptions): Promise<void>;
    private syncTargetGroups;
    private static groupSyncTargetsByDwnUrl;
    private syncTargetGroupWithUrl;
    private static summarizeSyncTargetGroupResults;
    private static countSyncTargetGroupResult;
    private updateConnectivityAfterSync;
    private recordSyncSuccess;
    private recordSyncFailure;
    private static assertSyncTargetGroupsSucceeded;
    private syncTargetGroup;
    private syncSingleTarget;
    startSync(params: StartSyncParams): Promise<void>;
    /**
     * stopSync awaits the completion of the current sync operation before stopping the sync interval
     * and tearing down any live subscriptions.
     *
     * @param timeout - Maximum milliseconds to wait for an in-progress
     *   sync cycle to finish. Non-finite values (`NaN`, `Infinity`) are
     *   coerced to the default to avoid a tight poll loop or never-exit
     *   condition.
     */
    stopSync(timeout?: number): Promise<void>;
    private startPollSync;
    /**
     * Starts live sync:
     * 1. Performs an initial durable feed catch-up.
     * 2. Opens MessagesSubscribe subscriptions to each remote DWN for real-time pull.
     * 3. Subscribes to the local EventLog for push-on-write.
     * 4. Schedules an infrequent durable feed settle check at `interval`.
     */
    private startLiveSync;
    /**
     * Get or create the runtime state for a link.
     */
    private getOrCreateRuntime;
    /**
     * Drain contiguously committed ordinals from the runtime state, advancing
      * the link's pull checkpoint for each drained entry. Returns the number of
     * entries drained (0 if the next ordinal is not yet committed).
     */
    private drainCommittedPull;
    /** Maximum consecutive repair attempts before the link is paused. */
    private static readonly MAX_REPAIR_ATTEMPTS;
    /** Maximum repeated verified feed mismatches before pausing the link. */
    private static readonly MAX_FEED_CONVERGENCE_ATTEMPTS;
    /** Maximum age for a repeatedly deferred pull entry before it is dead-lettered and skipped. */
    private static readonly DEFERRED_PULL_DEAD_LETTER_AFTER_MS;
    /** Per-link repair attempt counters. */
    private readonly _repairAttempts;
    /** Per-link active repair promises — prevents concurrent repair for the same link. */
    private readonly _activeRepairs;
    /** Per-link retry timers for failed repairs below max attempts. */
    private readonly _repairRetryTimers;
    /** Repeated feed fingerprint mismatches explained by durable dead letters. */
    private readonly _feedConvergenceFailures;
    /** Backoff schedule for repair retries (milliseconds). */
    private static readonly REPAIR_BACKOFF_MS;
    /**
     * Per-link repair context — stores ProgressGap metadata for use during
     * repair. The `resumeToken` (from `gapInfo.latestAvailable`) is used as
     * the post-repair checkpoint so the reopened subscription replays from
     * a valid boundary instead of starting live-only.
     */
    private readonly _repairContext;
    /**
     * Central helper for transitioning a link to `repairing`. Encapsulates:
     * - status change
     * - optional gap context storage
     * - repair kick-off with retry scheduling on failure
     *
     * All code paths that set `repairing` should go through this helper to
     * guarantee a future retry path.
     */
    private transitionToRepairing;
    private transitionToPaused;
    private setLinkOfflineStatus;
    private clearLinkRuntimeInflight;
    /**
     * Schedule a retry for a failed repair. Uses exponential backoff.
     * No-op if the link is paused or a retry is already scheduled.
     */
    private scheduleRepairRetry;
    /**
     * Repair a single link. Deduplicates concurrent calls via `_activeRepairs`.
     * If repair is already running for this link, returns the existing promise.
     */
    private repairLink;
    /**
     * Internal repair implementation. Replays durable feed entries for a single
     * link, then attempts to re-establish live subscriptions. If repair succeeds,
     * transitions to `live`. If it fails, throws so callers can retry.
     */
    private doRepairLink;
    /**
     * Close pull and push subscriptions for a specific link.
     */
    private closeLinkSubscriptions;
    private closeLiveSubscription;
    private closeLocalSubscription;
    /**
     * Registers browser `online`, `offline`, and `visibilitychange` event
     * listeners to detect connectivity changes that WebSocket `close` events
     * miss (NAT timeout, network switch, sleep/wake). Safe to call in Node —
     * the guards skip registration when browser APIs are unavailable.
     */
    private startBrowserConnectivityListeners;
    /** Removes browser connectivity listeners if they were registered. */
    private stopBrowserConnectivityListeners;
    private teardownLiveSync;
    /**
     * Initialize a single replication link target: create or resume the durable
     * link, open pull + push subscriptions, and transition the link to `'live'`.
     */
    private initializeLinkTarget;
    private getOrCreateReplicationLink;
    private getReplicationLinkKey;
    private openLinkSubscriptions;
    private markLinkLive;
    private markLinkPolling;
    private handleInitializeLinkTargetError;
    private createActiveLinkInitializationResult;
    private cleanupFailedLinkInitialization;
    /**
     * Wrapper around {@link initializeLinkTarget} that retries on DID
     * resolution failures. Newly published `did:dht` DIDs take a few
     * seconds to propagate through the DHT network. During this window,
     * the remote DWN can't resolve the DID to verify request signatures,
     * causing a 401. Retrying with exponential backoff lets the
     * propagation settle before giving up.
     */
    private initializeLinkTargetWithRetry;
    private isDidResolutionFailure;
    /** Check whether a link key belongs to a given DID. */
    private isLinkKeyForDid;
    /** Check whether this DID has any active links. */
    private hasActiveLinksForDid;
    /** Hot-add a single identity to the active live sync session. */
    private addIdentityToLiveSync;
    /** Hot-remove a single identity from the active live sync session. */
    private removeIdentityFromLiveSync;
    private tryPruneSupersededDurableLinksForRegisteredIdentity;
    private getDurableLinkIdentityKeysForRegisteredIdentity;
    private pruneSupersededDurableLinksForIdentity;
    /**
     * Opens a MessagesSubscribe WebSocket subscription to a remote DWN.
     * Incoming events are processed locally as they arrive.
     */
    private openLivePullSubscription;
    private getInitialPullCursor;
    private isValidProgressToken;
    private createLinkStalePredicate;
    private handleLivePullMessage;
    private handleLivePullEose;
    private markPullLinkOnline;
    private handleLivePullSubscriptionError;
    private handleLivePullEvent;
    private shouldSkipLivePullEvent;
    private skipOutOfScopePullEvent;
    private startPullDelivery;
    private processLivePullEvent;
    private recordAdmissionFailure;
    private createLivePullDataStreamFactory;
    private static dataStreamFromBytes;
    private trackRecentlyPulledMessage;
    private commitPullDelivery;
    private emitPullCheckpointAdvance;
    private emitPushCheckpointAdvance;
    private handleLivePullProcessingError;
    /**
     * Subscribes to the local DWN's EventLog so that writes by the user are
     * immediately pushed to the remote DWN instead of waiting for the next poll.
     */
    private openLocalPushSubscription;
    /**
     * Flushes accumulated push CIDs to remote DWNs.
     */
    private flushPendingPushes;
    private flushPendingPushesForLink;
    private takePushFlushBatch;
    private handlePushBatchResult;
    private clearSucceededPushFailures;
    private requeueFailedPushes;
    private handleReconcilePushFailures;
    private cleanupSuccessfulPushRuntime;
    private finishPushFlush;
    /** Push retry backoff schedule: immediate, 250ms, 1s, 2s, then give up. */
    private static readonly PUSH_RETRY_BACKOFF_MS;
    private static readonly TENANT_INACTIVE_RECONCILE_DELAY_MS;
    private recordTerminalSyncPushFailures;
    /**
     * Re-queues a failed push batch for retry, or schedules a feed check when
     * retries are exhausted. Bounded to prevent infinite retry loops.
     */
    private requeueOrReconcile;
    private recordImmediateTerminalPushFailures;
    private handleVerifiedFeedDivergence;
    private clearFeedConvergenceFailure;
    private handleRepeatedFeedConvergenceMismatch;
    private getAdmissionDeadLetterCidsForTarget;
    private static deadLetterTenantRange;
    private static deadLetterMatchesTarget;
    private static feedConvergenceFailureSignature;
    private handleFeedConvergenceMismatch;
    private stopPushRuntime;
    private scheduleLinkReconcileIfActive;
    private schedulePushRetry;
    private scheduleLinkReconcile;
    private getAuthorizationGrantIds;
    private syncTargetWithDurableFeeds;
    private static emptySyncReconcileResult;
    private static mergeSyncReconcileResult;
    private static feedFingerprintsConverged;
    private verifyFeedConvergence;
    private static shouldStopAfterFeedResult;
    private pullRemoteFeedForSyncTarget;
    private pullRemoteFeedPages;
    private pullRemoteFeedDiffPages;
    private pushLocalFeedForSyncTarget;
    private pushLocalFeedPages;
    private pullRemoteFeedDiffWhenUseful;
    private pushLocalFeedDiffWithRemoteInventory;
    private pushLocalFeedDiffPages;
    private bootstrapRemotePermissionGrants;
    private localPermissionGrantCids;
    private localPermissionGrantEntries;
    private queryLocalPermissionGrantEntries;
    private collectLocalFeedCids;
    private collectRemoteFeedCids;
    private collectFeedCids;
    private queryFeedCidsPage;
    private nextFeedEnumerationCursor;
    private static feedEntriesMissingFrom;
    private admitRemoteFeedPageAndTrack;
    private pushLocalFeedPage;
    private pushLocalFeedEntry;
    private resetFeedPullAfterProgressGap;
    private resetFeedPushAfterProgressGap;
    private static assertFeedPullSucceeded;
    private static assertFeedPushSucceeded;
    private admitRemoteFeedPage;
    private trackRemoteFeedAppliedCids;
    private deadLetterExpiredDeferredPull;
    private recordDeferredPull;
    private clearDeferredPull;
    private advanceFeedPullCursor;
    private advanceFeedPushCursor;
    private assertFeedCursorProgress;
    private admitRemoteFeedEntry;
    private syncEntriesFromFeedEntry;
    private static messageFeedFiltersForScope;
    private static protocolFromFeedEntry;
    private static protocolFromDescriptor;
    private static recordsWriteRequiresRemoteData;
    private static shouldAbortReconcile;
    /** Active reconcile timers, keyed by link key. */
    private readonly _reconcileTimers;
    /** Active reconcile operations, keyed by link key (dedup). */
    private readonly _reconcileInFlight;
    /**
     * Schedule a per-link reconciliation after a short debounce. Coalesces
     * repeated requests for the same link.
     */
    private scheduleReconcile;
    /**
     * Run durable feed reconciliation for a single link. Deduplicates concurrent calls.
     * On success, emits completion. On failure, schedules retry.
     */
    private reconcileLink;
    /**
     * Internal reconciliation implementation for a single link. Runs the
     * same durable feed pull/push that `sync()` does, but scoped to one link.
     */
    private doReconcileLink;
    private getOrCreatePushRuntime;
    /**
     * Build the runtime key for a replication link.
     *
     * Live-mode subscription methods (`openLivePullSubscription`,
     * `openLocalPushSubscription`) receive `linkKey` directly and never
     * call this. The remaining callers are poll-mode `sync()` and the
     * live-mode startup/error paths that already have a projection ID and
     * authorization epoch.
     */
    private buildLinkKey;
    /**
     * Evicts expired entries from the echo-loop suppression cache.
     * Also enforces the size cap by evicting oldest entries first.
     */
    private evictExpiredEchoEntries;
    /**
     * Checks whether a CID was recently pulled from a specific remote endpoint
     * and should not be pushed back to that same endpoint (echo-loop suppression).
     * Does not suppress pushes to other endpoints — multi-provider fan-out works.
     */
    private isRecentlyPulled;
    /**
     * Reads missing messages from the local DWN and pushes them to the remote DWN
     * in dependency order.
     */
    private pushMessages;
    /**
     * Build a compound dead letter key. Different tenants and remotes can fail
     * the same CID for different reasons, so the durable key includes both.
     */
    private static deadLetterKey;
    recordDeadLetter(params: {
        messageCid: string;
        tenantDid: string;
        remoteEndpoint?: string;
        protocol?: string;
        category: DeadLetterCategory;
        errorCode?: string;
        errorDetail: string;
    }): Promise<void>;
    private hasAdmissionDeadLetter;
    getFailedMessages(tenantDid?: string): Promise<DeadLetterEntry[]>;
    clearFailedMessage(messageCid: string, remoteEndpoint?: string): Promise<boolean>;
    clearAllFailedMessages(tenantDid?: string): Promise<void>;
    getSyncHealth(): Promise<SyncHealthSummary>;
    private getCurrentDurableLinkIdentityKeys;
    private getDurableLinkIdentityKey;
    private static durableLinkIdentityKey;
    private static isUnhealthyLinkStatus;
    /**
     * Returns the list of sync targets: one canonical projection target per
     * registered DID and resolved DWN endpoint.
     * Results are cached for up to 30 seconds to avoid redundant DID resolution
     * on every sync tick. The cache is invalidated when identities are registered,
     * unregistered, or updated.
     */
    private getSyncTargets;
}
export {};
//# sourceMappingURL=sync-engine-level.d.ts.map