# `node-fs` _(no submodules)_ ## Purpose Provides the default `NodeFsLike` implementation backed by `node:fs/promises` and the two stream constructors from `node:fs`. The factory is the single binding point between this package and Node's filesystem APIs — every other module talks to the structural `NodeFsLike` interface so tests can substitute real in-memory or hooked adapters without `vi.mock`. ## Features - Returns a fresh `NodeFsLike` object per call so callers can spread-and-override individual methods without mutating shared state. - Forwards `readFile` results through `new Uint8Array(buffer, byteOffset, byteLength)` so consumers get a stable `Uint8Array` view regardless of the underlying Buffer subclass. - Wraps `node:fs/promises.open` so the returned handle matches the structural `NodeFsFileHandleLike` interface (only `read` + `close`). - Translates `readdir(path, { recursive: true, withFileTypes: true })` Dirent entries into the lighter `NodeFsReaddirEntry` shape exposed to the rest of the package. - Translates `stat` into the lighter `NodeFsStatLike` shape exposing only the four fields the adapter reads. ## Usage: Basic Example ```ts import { defaultNodeFs } from "@suaveplan/storage-file"; const fs = defaultNodeFs(); await fs.mkdir("/tmp/store", { recursive: true }); await fs.writeFile("/tmp/store/hello.data", new TextEncoder().encode("hi")); const data = await fs.readFile("/tmp/store/hello.data"); ``` ## Usage: Advanced Example ```ts import { defaultNodeFs, NodeFsStorage } from "@suaveplan/storage-file"; import type { NodeFsLike } from "@suaveplan/storage-file/types"; const base = defaultNodeFs(); // Wrap stat to ensure mtimes never go backwards under wall-clock skew. const monotonicStat: NodeFsLike = { ...base, async stat(path) { const s = await base.stat(path); return { ...s, mtimeMs: Math.max(s.mtimeMs, Date.now()) }; }, }; const storage = new NodeFsStorage({ rootDir: "/tmp/store", fs: monotonicStat }); ``` ## API Reference - `defaultNodeFs(): NodeFsLike` — returns a fresh adapter object. Every method on the returned object forwards to its `node:fs/promises` counterpart with minimal shape translation. See `fs-adapter.types.md` for the full method list. ## Implementation Notes - The factory pattern (vs a module-level singleton) is deliberate: returning a fresh object lets tests construct independent adapters per `it(...)` block and verify ownership semantics. - The factory is dependency-free at module evaluation time — every Node import is at the top of the file, but `defaultNodeFs()` itself doesn't reach into globals or open any handles. Callers can build the storage adapter at import time without paying any filesystem cost. - The lazy buffer-view translation in `readFile` avoids a copy when callers operate on the result via DataView or pass it back into a hash function.