@nhtio/adk/batteries/storage/opfs
Browser-only Origin Private File System storage for spooled artifacts.
Remarks
Opt-in browser-only storage battery backed by the Origin Private File System (OPFS). Provides OpfsSpoolReader (a @nhtio/adk!SpoolReader over a OpfsFileHandle) and OpfsSpoolStore (a write(callId, bytes) → reader persistence layer that wraps an OPFS directory).
The reader has two modes selected lazily on first method invocation based on the size of the underlying file:
- Eager mode — when
file.sizeis belowstreamThresholdBytes(default 10 MiB), the reader callsfile.text()once, splits the content on\n, and caches lines + byte count. All subsequent calls resolve from memory. - Streaming mode — when
file.sizemeets or exceeds the threshold, the reader streams the file once viafile.stream().getReader()to build a line-offset index (number[]of byte offsets per line), then serves eachline(i)request by slicing the underlyingBlob—Blob.slice(start, end).text()decodes only the requested range, no head-of-file scan. Caps RAM at one index + one line buffer regardless of file size.
The store auto-selects its write API by execution scope:
- In worker scopes (
self instanceof WorkerGlobalScope), it acquires aFileSystemSyncAccessHandleand writes synchronously. Sync handles are the only API available in workers and the fastest path for the spool-write hot path. - On the main thread, it uses
OpfsFileHandle.createWritable()and the async stream API. Sync access handles are not exposed on the main thread.
This module assumes a browser-equivalent runtime — navigator.storage, OpfsFileHandle, TextEncoder/TextDecoder, and Blob must all exist. It must not be imported from Node code; do so and you will fail at resolve time when navigator is referenced.
Example
ts
import { OpfsSpoolStore } from "@nhtio/adk/batteries/storage/opfs";
const store = new OpfsSpoolStore({ keyPrefix: "agent-runs/" });
const reader = await store.write(callId, bytes);
const Ctor = tool.artifactConstructor?.() ?? SpooledArtifact;
const artifact = new Ctor(reader);Classes
| Class | Description |
|---|---|
| OpfsSpoolReader | Reads an OPFS-backed file as a @nhtio/adk!SpoolReader. |
| OpfsSpoolStore | "Give bytes, get a reader" persistence layer over an OPFS directory. |
Interfaces
| Interface | Description |
|---|---|
| OpfsBlob | Minimal subset of the DOM Blob interface used by OpfsSpoolReader streaming-mode random-access reads. Real OPFS handles return a File here; we narrow to the methods we actually call. |
| OpfsDirectoryHandle | Minimal subset of the File System Access OpfsDirectoryHandle interface that this module touches at runtime. Structurally compatible with the DOM-lib OpfsDirectoryHandle — at call sites you pass real OPFS handles directly. |
| OpfsFile | Minimal subset of the DOM File interface used by OpfsSpoolReader. |
| OpfsFileHandle | Minimal subset of the File System Access OpfsFileHandle interface that this module touches at runtime. Structurally compatible with the DOM-lib OpfsFileHandle — at call sites you pass real OPFS handles directly. |
| OpfsReadableStream | Minimal subset of the DOM ReadableStream<Uint8Array> interface used by streaming-mode index construction. |
| OpfsReadableStreamReader | Minimal subset of the DOM ReadableStreamDefaultReader<Uint8Array> interface used by streaming-mode index construction. |
| OpfsSpoolReaderOptions | Constructor options for OpfsSpoolReader. |
| OpfsSpoolStoreOptions | Constructor options for OpfsSpoolStore. |
| OpfsWritableFileStream | Minimal subset of the DOM FileSystemWritableFileStream interface used by the OPFS battery's main-thread write path. |