Initial Commit
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
# Add Bun-native filesystem adapter to `@suaveplan/storage-file`
|
||||
|
||||
- **Capability**: `storage-file`
|
||||
- **Status**: PROPOSED
|
||||
- **Design**: ./design.md
|
||||
- **Spec delta**: ./specs/storage-file/spec.md
|
||||
|
||||
## Why
|
||||
|
||||
`@suaveplan/storage-file` currently ships a single `NodeFsLike` implementation —
|
||||
`defaultNodeFs()` in `src/node-fs/node-fs.ts` — bound to `node:fs/promises` plus
|
||||
the two `node:fs` stream constructors. Genesis is a Bun-first monorepo. Bun
|
||||
provides a faster, non-emulated filesystem path for the common read-and-write
|
||||
hot loop via `Bun.file()` / `Bun.write()` that skips the `node:fs`
|
||||
emulation layer entirely. Today every read/write inside `NodeFsStorage` takes
|
||||
the slower compatibility path even when running under Bun.
|
||||
|
||||
This change adds a sibling `defaultBunFs()` factory that satisfies the same
|
||||
`NodeFsLike` structural contract but routes `readFile`/`writeFile` through
|
||||
Bun's native APIs. Operations that have no Bun-specific equivalent
|
||||
(`mkdir`, `readdir`, `rename`, `unlink`, `stat`, `access`, `open`,
|
||||
`createReadStream`, `createWriteStream`) continue to use `node:fs/promises` —
|
||||
under Bun those calls already dispatch to Bun's native Zig implementation.
|
||||
|
||||
`resolveConfig` gains a runtime-probed default: when the caller does not
|
||||
inject an `fs` and `globalThis.Bun` is present, `defaultBunFs()` is used;
|
||||
otherwise `defaultNodeFs()` is used. Both factories remain explicitly
|
||||
exported so callers can wire either one directly (e.g. forcing the Node
|
||||
path in tests, or in mixed-runtime SSR pipelines).
|
||||
|
||||
## What changes
|
||||
|
||||
- New module `src/bun-fs/bun-fs.ts` exporting `defaultBunFs(): NodeFsLike`.
|
||||
- `readFile` uses `Bun.file(path).bytes()`.
|
||||
- `writeFile` uses `Bun.write(path, data)`.
|
||||
- All other methods delegate to `node:fs/promises` (the same calls
|
||||
`defaultNodeFs()` makes), so the surface stays identical.
|
||||
- New module `src/bun-fs/bun-fs.md` (sibling doc, §4 conformant).
|
||||
- New module `src/bun-fs/bun-fs.test.ts` (`@suaveplan/testing/runner`).
|
||||
- New barrel `src/bun-fs/index.ts` (explicit named re-export per §6a).
|
||||
- `resolveConfig` in `src/node-fs-storage/node-fs-storage.helpers.ts` gains a
|
||||
Bun-vs-Node default selector. Behaviour is unchanged when callers pass
|
||||
`fs` explicitly.
|
||||
- `src/index.ts` re-exports `defaultBunFs` next to `defaultNodeFs`.
|
||||
- `package.json` `exports` map gains `./bun-fs/bun-fs`.
|
||||
- `README.md` Modules section gets a new row.
|
||||
|
||||
## Migration
|
||||
|
||||
No consumer behaviour changes if `fs` is passed explicitly. Consumers that
|
||||
relied on the implicit default got a `node:fs/promises`-backed implementation
|
||||
before this change and continue to get one when running under Node. Under Bun
|
||||
they transparently get the faster path. The `NodeFsLike` contract, all
|
||||
`STORAGE_FILE.*` codes, the `recordOp` instrumentation, and the spec-conformance
|
||||
suite are unchanged.
|
||||
|
||||
To force the Node path under Bun (e.g. for parity testing):
|
||||
|
||||
```ts
|
||||
import { defaultNodeFs, NodeFsStorage } from "@suaveplan/storage-file";
|
||||
|
||||
const storage = new NodeFsStorage({ rootDir, fs: defaultNodeFs() });
|
||||
```
|
||||
|
||||
## Impact
|
||||
|
||||
### Affected dependents
|
||||
|
||||
Run `bunx turbo ls --filter=...@suaveplan/storage-file` to enumerate. As of
|
||||
authoring, `@suaveplan/storage-file` has no in-repo dependents (it is consumed
|
||||
by the upstream `@suaveplan/storage` factory via the optional registry path).
|
||||
|
||||
- No in-repo dependents — verified by `bunx turbo ls --filter=...@suaveplan/storage-file`.
|
||||
Storage-cdn-bunnycdn and storage-cdn-rackspace consume `@suaveplan/storage`,
|
||||
not `storage-file` directly; their behaviour is unaffected.
|
||||
Reference in New Issue
Block a user