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); updateConfig(config: Partial): void; /** Register a cleanup hook (idempotent — last wins). */ setCleanupHook(hook: (record: ShareRecord) => void): void; getConfig(): ShareConfig; create(params: CreateShareParams & { workspaceRoot: string; gatewayTokenHash: string; }): Promise; 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; /** 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): ShareStore; export declare function resetShareStoreForTests(): void;