Skip to content
2 min read · 498 words

@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.size is below streamThresholdBytes (default 10 MiB), the reader calls file.text() once, splits the content on \n, and caches lines + byte count. All subsequent calls resolve from memory.
  • Streaming mode — when file.size meets or exceeds the threshold, the reader streams the file once via file.stream().getReader() to build a line-offset index (number[] of byte offsets per line), then serves each line(i) request by slicing the underlying BlobBlob.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 a FileSystemSyncAccessHandle and 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

ClassDescription
OpfsSpoolReaderReads an OPFS-backed file as a @nhtio/adk!SpoolReader.
OpfsSpoolStore"Give bytes, get a reader" persistence layer over an OPFS directory.

Interfaces

InterfaceDescription
OpfsBlobMinimal 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.
OpfsDirectoryHandleMinimal 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.
OpfsFileMinimal subset of the DOM File interface used by OpfsSpoolReader.
OpfsFileHandleMinimal 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.
OpfsReadableStreamMinimal subset of the DOM ReadableStream<Uint8Array> interface used by streaming-mode index construction.
OpfsReadableStreamReaderMinimal subset of the DOM ReadableStreamDefaultReader<Uint8Array> interface used by streaming-mode index construction.
OpfsSpoolReaderOptionsConstructor options for OpfsSpoolReader.
OpfsSpoolStoreOptionsConstructor options for OpfsSpoolStore.
OpfsWritableFileStreamMinimal subset of the DOM FileSystemWritableFileStream interface used by the OPFS battery's main-thread write path.