first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
# `node-fs`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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.