/** * Browser-origin persistent storage shared by every MolVis engine. * * Single owner of the molvis OPFS namespace: everything persisted under * the user's origin lives at `/molvis/v1//`. Bumping the * version segment lets formats evolve without leaking stale files — a * release that needs `v2` ignores `v1`, and {@link clearOpfsCache} is the * maintenance pass that removes whatever earlier versions left behind. * * This lives in `core` rather than an engine because `sketch` and `stage` * are peers that must not import each other, so anything both can use has * to sit below them. Engine-specific *contents* stay with their engine — * stage owns the trajectory index sidecar (`.molidx`) and its codec; core * owns only the namespace, the byte bucket, and the sweep helpers. * * All entry points return `null` (or a zeroed usage) when OPFS is * unavailable — older browsers, extension-only contexts, ServiceWorker * scopes that opted out. Callers treat that as "no cache" and degrade * gracefully; the data still loads, just without the fast path. * * Diagnostics go to `console.warn` rather than a logging library: core * carries exactly one dependency on purpose, and this subpath must stay * tree-shakeable for consumers that never touch OPFS. */ export type OpfsBucket = "idx" | "blob"; /** Every bucket MolVis writes; the sweep helpers iterate this. */ export declare const OPFS_BUCKETS: readonly OpfsBucket[]; export declare function getOpfsRoot(): Promise; export declare function getOpfsBucket(bucket: OpfsBucket): Promise; /** * Best-effort `getFileHandle` returning `null` for both a missing bucket * and a missing file. Unexpected errors surface via the console so the * caller can stay terse. */ export declare function getFileIfExists(bucket: OpfsBucket, filename: string): Promise; /** * Idempotent `removeEntry`: missing keys — and missing buckets — are not * an error. Other failures surface via the console. */ export declare function removeEntryIfExists(bucket: OpfsBucket, filename: string): Promise; /** What a cache sweep found, or freed. */ export interface OpfsCacheUsage { files: number; bytes: number; } /** * Measure everything MolVis holds in OPFS across all buckets. * * Counts the *current* version root only; {@link clearOpfsCache} is what * reaches stale ones. */ export declare function readOpfsCacheUsage(): Promise; /** * Delete the whole MolVis OPFS namespace and report what was freed. * * Removes `/molvis` outright instead of walking the current version's * buckets, so roots orphaned by an older release go with it. * * Everything stored here is derived: index sidecars and cached request * bytes are rebuilt on the next load, just more slowly. That is why this * is a plain action rather than an undoable command — there is no prior * state to restore. */ export declare function clearOpfsCache(): Promise; /** True when an OPFS handle threw because the entry did not exist. */ export declare function isNotFound(err: unknown): boolean; /** * Filesystem-safe key — strips characters that may not round-trip on * every platform. Defense in depth: production fingerprints already pass * through `encodeURIComponent`, but maintenance UIs and tests can supply * arbitrary keys. */ export declare function safeKey(fingerprint: string): string; export type Fingerprint = string; /** * Fingerprint a source file so the cache can recognise it across page * reloads. Real `File` objects (drag-drop, ``) carry * name + size + lastModified, which together are a good-enough key. * * `kind` distinguishes otherwise-identical files cached by different * readers (a trajectory format, a sketch document type, …) so engines * cannot collide on one key. * * On a false positive — the user edits a file in place without bumping * mtime — the cached entry is stale and the consumer surfaces a parse * error. Degraded, not corrupted. * * Anonymous `Blob`s (no name, no mtime) cannot be fingerprinted * reliably; callers branch on `file instanceof File` and skip caching. */ export declare function fingerprintFile(file: File, kind: string): Fingerprint; /** * Byte bucket: a persistent copy of source bytes, readable by a worker * through a `FileSystemSyncAccessHandle`. * * Why cache source bytes when the consumer already caches its index? * Re-opening a known file still produces a fresh `Blob`, backed either by * the original filesystem entry (drag-drop) or a network response (the * VSCode extension) — the latter would re-download. Persistent storage * gives the network case a 1-RTT skip on every reload and lets a worker * read straight into WASM linear memory. * * Opt-in on purpose: auto-promoting every file the user opens would * saturate the origin's quota on a large trajectory. */ export declare const OpfsBlobCache: { has(fingerprint: string): Promise; set(fingerprint: string, blob: Blob): Promise; evict(fingerprint: string): Promise; /** * Worker side: open a cached file as a `FileSystemSyncAccessHandle`. * `null` on cache miss or where sync access is unavailable. */ openSync(fingerprint: string): Promise; };