Files
skills/docs/persistence/storage/storage-browser-opfs/src/opfs-adapter/opfs-adapter.md
2026-05-29 08:20:56 +01:00

2.3 KiB

opfs-adapter — default OpfsLike and feature detector

(no submodules)

Purpose

Provides the production binding of the OpfsLike structural interface to the browser's navigator.storage.getDirectory() API, plus a side-effect-free feature detector consumers call before constructing an OpfsStorage. Keeping this in its own module — rather than inside OpfsStorage — lets the storage class take an injected OpfsLike and stay environment-agnostic, while the production path resolves the real browser API lazily on first getDirectory().

Features

  • defaultOpfs() returns an OpfsLike whose getDirectory() calls the live browser API.
  • Missing API surfaces as OpfsError(OPFS.UNAVAILABLE) rather than TypeError from a missing-property access.
  • isOpfsAvailable() is synchronous, has no side effects, and never throws — safe to call during render.
  • Resolves navigator from globalThis so the module loads cleanly in Node, Bun, and worker environments.

Usage: Basic Example

import {
    defaultOpfs,
    isOpfsAvailable,
    OpfsStorage,
} from "@suaveplan/storage-browser-opfs";

if (!isOpfsAvailable()) {
    // Fall back to MemoryStorage or another adapter.
}
const storage = new OpfsStorage({ opfs: defaultOpfs() });

Usage: Advanced Example

import {
    defaultOpfs,
    isOpfsAvailable,
    MemoryStorage,
    OpfsStorage,
} from "@suaveplan/storage-browser-opfs";
import type { AbstractStorage } from "@suaveplan/storage/abstract";

export function pickStorage(): AbstractStorage {
    if (isOpfsAvailable()) return new OpfsStorage({ opfs: defaultOpfs() });
    return new MemoryStorage();
}

API Reference

  • defaultOpfs(): OpfsLike — getDirectory() throws OpfsError(OPFS.UNAVAILABLE) when missing.
  • isOpfsAvailable(): boolean — pure feature detector.

Implementation Notes

defaultOpfs() returns a fresh OpfsLike object on every call so callers can hold different references; the underlying getDirectory getter is read at each invocation so consumers that polyfill navigator.storage after this module loads still benefit. The Boolean detector deliberately checks typeof getDirectory === "function" rather than "getDirectory" in storage to weed out polyfills that stub the property without a callable.