PrivateopfsPrivateindexPrivateorderPrivatetotalPrivatemaxPrivatedatasetPrivatebasePrivatecontentPrivatevalidationPrivatelastPrivatereadPrivatewritePrivatemissPrivatecanceledPrivateoversizedPrivatequotaPrivateevictionsPrivatewritePrivatecorruptedPrivateclobberPrivatebucketsPrivatemetadataPrivate Static ReadonlyMETADATA_PrivatependingPrivate StaticpendingPrivategenerationPrivatedisposedPrivateinitializedPrivatependingPrivatependingPrivatependingPrivateconsecutivePrivatebreakerPrivatetimedRun one OPFS operation under the per-op timeout, feeding the
circuit breaker. Counts ONLY the OPFS timeout rejection: any
other settlement (success or a fast error such as NotFoundError)
proves the backend is responsive and resets the count — the
breaker targets systemic stalls, not error rate. Applied to the
three hot real-I/O sites (get/set/delete) only: the init canary's
catch already degrades the store itself, the delete-barrier awaits
a delete whose own timeout already counted, and the dispose drain
runs on an already-dead store.
PrivatetripDisable the L2 tier for the rest of this store's lifetime after
repeated consecutive timeouts. Nulling opfsRoot reuses the
init-failure degradation path — every entry point already
short-circuits on it, so all later ops are instant no-ops instead
of serial full-timeout burns, and getStats().available flips the
existing opfs-unavailable badge. The pending debounced metadata
save is cancelled so its timer cannot fire a full-index write
against the hung backend and stall dispose().
StaticlistEnumerate every zarr-cache-* dataset present under the viewer's
luxar/ OPFS namespace directory. Reads each dataset's
_cache_meta.json directly — no OPFSStore instance is created. Used by
the debug-cache helpers (window.__luxarDebug) and the cache E2E suite
to inspect persisted datasets without mounting them.
Never creates the namespace directory: on a cold origin (no luxar/
yet) the lookup's NotFoundError resolves to an empty list.
Initialize OPFS directory, prove writability, and load metadata.
PrivatedoPrivateprobeProve OPFS is actually WRITABLE, not merely mounted. WebKit (Safari and
the WKWebView native launcher) implements navigator.storage .getDirectory() and directory/file handles but NOT the main-thread
FileSystemFileHandle.createWritable() — WebKit supports OPFS writes
only through worker-side createSyncAccessHandle. Without this probe
the store mounts "healthy" there and then fails EVERY put: tens of
thousands of write errors, a permanently empty L2, and an all-miss read
path (observed in the native macOS app's cache monitor). One tiny probe
write at init converts that failure mode into the ordinary
OPFS-unavailable degradation (L1-only, opfs-unavailable badge) with a
single clear warning. Timeout-wrapped like every other OPFS operation so
a hung handle cannot stall startup. Throws on failure — init()'s catch
nulls opfsRoot.
PrivateapplyPrivatemetadataPrivatereadableOptionalsignal: AbortSignalPrivatecountOptionalsignal: AbortSignalPrivatehasWrite a file to OPFS with LRU eviction.
PrivatedoInternal write implementation (called by set() after serialization).
Delete a file from OPFS.
The CALLER await is bounded by opfsOperationTimeoutMs (preserving #991 —
delete() runs inside doSet()'s eviction loops and get()'s corrupted-entry
path, none of which may stall). The chain LINK a later same-key write waits
on, however, is the REAL (un-timed-out) removeEntry settlement (doDelete),
registered in pendingDeletesByDataset: when the caller returns on timeout the
non-cancellable removeEntry keeps running, and a replacement write must not
start until it has ACTUALLY settled (#1073 clobber invariant). Index/size
are reconciled off that real settlement, never off the early timeout return.
PrivatedoReal (un-timed-out) delete of a single file plus index/size reconcile. Runs to ACTUAL settlement as a link in the per-key serialization chain so a later same-key write can never start (and then be clobbered) while this removeEntry is still in flight (#1073). Never rejects.
PrivatelruFirst key in LRU order (Map insertion order) that is not exclude. Used by
doSet()'s eviction loops to skip the key currently being written (#1073) —
see the loop comments for the self-deadlock rationale.
Clear all OPFS data for this dataset.
Uses atomic delete-and-recreate instead of iterating entries, which avoids race conditions when a previous page context still holds open file handles (e.g., quick-succession page refreshes with fire-and-forget L2 writes).
PrivatedoCheck if enough storage quota is available.
Get cache statistics.
S2: true when OPFS was reachable on init and the store is
still alive. false when init couldn't acquire a directory
handle (browser without OPFS support, private mode in some
configs), after the circuit breaker trips, or after dispose().
Drives the opfs-unavailable status badge.
true once the circuit breaker disabled the tier after
consecutive OPFS timeouts. Distinguishes "gave up after repeated
stalls" from "never had OPFS" in debug snapshots and tests; the
monitor badge keys on available alone.
Update LRU order for a key.
Set content hash for cache invalidation.
Get cached content hash.
Record the validation mode used for this dataset. Persisted to
_cache_meta.json so a follow-up session can re-evaluate (e.g.
a TTL window).
validated (default true) means a genuine validation just succeeded,
which stamps lastValidatedAt = now. The no-token/offline branch passes
validated: false: it still records the mode, but must NOT slide the TTL
clock forward on every revisit — it only establishes the baseline the
first time (when lastValidatedAt is still unset) so a headerless-server
cache can still age out.
Optionaloptions: { validated?: boolean }Read the current validation mode and last-validated timestamp. Returned together so callers can apply a TTL check atomically.
PrivatecompactRenumber all order entries to prevent orderCounter overflow. Called when orderCounter exceeds a safe threshold (1e12).
Tear down the store. Marks the store disposed, drains pending writes, awaits any in-flight metadata save, then flushes a final snapshot so a read-only session's LRU order still gets persisted.
Every caller shares ONE completion (pendingDispose): dispose() resolving is the take-over signal for a newer same-URL store, so a concurrent or repeat caller must wait for the same drain rather than resolve early on the disposed flag.
Order matters:
disposed
guard — init()'s re-checks, clear(), the validation setters — must
observe the flag from the moment dispose() is invoked, not only once
the final flush completes; otherwise a mid-init store could keep
probe-writing or orphan-cleaning the shared directory during that
window. The final flush below calls the metadata manager directly, so
it is unaffected by the flag.PrivatedoPrivateschedule
OPFS persistence layer (L2 cache) with LRU eviction and shallow bucketing.
Uses 256 bucket directories to distribute files and avoid filesystem limits. Files are stored as:
{bucket}/{base64-encoded-key}Structure (everything under the viewer's
luxar/OPFS namespace dir, seeopfs-store/opfs-root.ts):Benefits: