import type { ShareRecord, ShareConfig, CreateShareParams } from './share-types.js';
export interface DirectoryListingEntry {
    name: string;
    /** Workspace/share-relative POSIX path. */
    path: string;
    isDirectory: boolean;
    size: number;
    mtime: string;
    mimeType: string;
}
export interface DirectoryListing {
    /** Share-relative path of the listed dir ('' for root). */
    path: string;
    entries: DirectoryListingEntry[];
    truncated: boolean;
}
export declare class ShareStore {
    private shares;
    private tokenIndex;
    private dirty;
    private debounceTimer;
    private cleanupTimer;
    private config;
    private listingCache;
    /** Optional cleanup hook invoked when a share record is dropped (e.g. delete thumbnail). */
    private onCleanup;
    constructor(config?: Partial<ShareConfig>);
    updateConfig(config: Partial<ShareConfig>): void;
    /** Register a cleanup hook (idempotent — last wins). */
    setCleanupHook(hook: (record: ShareRecord) => void): void;
    getConfig(): ShareConfig;
    create(params: CreateShareParams & {
        workspaceRoot: string;
        gatewayTokenHash: string;
    }): Promise<ShareRecord>;
    private createFileShare;
    private createDirectoryShare;
    private buildRecord;
    private persistAndAudit;
    getById(id: string): ShareRecord | null;
    getByToken(token: string): ShareRecord | null;
    /** Validate a share is still accessible for download. Returns null reason if valid. */
    validateAccess(record: ShareRecord): {
        valid: boolean;
        reason?: string;
    };
    /** Increment download counter (used by directory & file downloads). Debounced persist. */
    incrementDownloadCount(id: string): void;
    /** Check if the file still exists and inode matches. */
    validateFileIntegrity(record: ShareRecord): Promise<{
        valid: boolean;
        reason?: string;
    }>;
    /**
     * Resolve a child path inside a directory share. Returns the absolute path
     * if it stays within both the share root and the workspace.
     */
    resolveDirectoryChild(record: ShareRecord, relativePath: string): Promise<{
        ok: true;
        absolutePath: string;
    } | {
        ok: false;
        reason: string;
    }>;
    /** List a single directory level (cached, share-root-relative). */
    listDirectory(record: ShareRecord, relativePath: string): Promise<DirectoryListing>;
    /** Update thumbnail status. Persists immediately so generator restart is safe. */
    setThumbnailStatus(id: string, status: 'pending' | 'ready' | 'failed'): void;
    /** Drop the listing cache for a share (used on revoke/update). */
    invalidateListingCache(shareId: string): void;
    revoke(id: string): boolean;
    revokeMany(ids: string[]): number;
    revokeExpired(): number;
    update(id: string, patch: {
        extendTtlMs?: number;
        maxViews?: number | null;
    }): ShareRecord | null;
    getActiveShares(): ShareRecord[];
    getAllShares(): ShareRecord[];
    private load;
    private persistSync;
    private scheduleDebouncedPersist;
    private startCleanupTimer;
    private cleanupExpired;
    shutdown(): void;
    private resolveAndValidatePath;
}
export declare function resolveMimeType(fileName: string): string;
/** HTTP Content-Type with charset for text-like bodies (browser inline preview). */
export declare function shareResponseContentType(mime: string): string;
export declare function getShareStore(config?: Partial<ShareConfig>): ShareStore;
export declare function resetShareStoreForTests(): void;
