Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1 @@
export { registerNodeFsProvider } from "./registry.js";

View File

@@ -0,0 +1,49 @@
# `registry`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Registers `NodeFsStorage` against the module-augmentation registry maintained by `@suaveplan/storage/factory`. After `registerNodeFsProvider()` runs once, the `createStorage({ type: "file", config: NodeFsStorageOptions })` factory dispatches to `new NodeFsStorage(config)` with full TypeScript narrowing on the `file` slot.
## Features
- Registers the `file` provider type with the storage factory.
- Idempotent — repeated `registerNodeFsProvider()` calls are no-ops, so the function is safe to call from any consumer's startup path without worrying about double-registration.
- Declaration-merges `StorageProviderRegistry` and `StorageProviderConfig` so `createStorage` is fully typed.
## Usage: Basic Example
```ts
import { registerNodeFsProvider } from "@suaveplan/storage-file";
import { createStorage } from "@suaveplan/storage/factory";
registerNodeFsProvider();
const storage = createStorage({ type: "file", config: { rootDir: "/tmp/store" } });
```
## Usage: Advanced Example
```ts
import { registerNodeFsProvider, NodeFsStorage } from "@suaveplan/storage-file";
import { createStorage } from "@suaveplan/storage/factory";
// Safe in any startup module — idempotent.
registerNodeFsProvider();
registerNodeFsProvider();
const storage = createStorage({ type: "file", config: { rootDir: "/var/lib/app/storage", retry: { maxAttempts: 5 } } });
console.log(storage instanceof NodeFsStorage); // → true
```
## API Reference
- `registerNodeFsProvider(): void` — register the `file` provider. Idempotent.
## Implementation Notes
- The registration delegates to `registerStorageProvider("file", NodeFsStorage)` from `@suaveplan/storage/factory`. The cast through `unknown` is required because the factory's loose `ProviderCtor` signature accepts `unknown` for config — `NodeFsStorage` accepts a stricter type but is structurally compatible.
- Registration is NOT triggered on import — consumers must call `registerNodeFsProvider()` explicitly. This keeps `import "@suaveplan/storage-file"` side-effect-free per `"sideEffects": false`.
- The module-augmentation `declare module "@suaveplan/storage/factory"` is type-only — it does not require the consumer to import this file at runtime to benefit from the typing.

View File

@@ -0,0 +1,52 @@
import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import {
clearStorageProviders,
createStorage,
hasStorageProvider,
} from "@suaveplan/storage/factory";
import {
afterEach,
beforeEach,
describe,
expect,
it,
} from "@suaveplan/testing/runner";
import { NodeFsStorage } from "../node-fs-storage/node-fs-storage.js";
import { registerNodeFsProvider } from "./registry.js";
describe("registerNodeFsProvider", () => {
let root: string;
beforeEach(async () => {
root = await mkdtemp(join(tmpdir(), "nfs-registry-"));
clearStorageProviders();
});
afterEach(async () => {
clearStorageProviders();
await rm(root, { recursive: true, force: true });
});
it("registers the file provider and resolves it via createStorage", {
timeout: 10000,
}, async () => {
registerNodeFsProvider();
expect(hasStorageProvider("file")).toBe(true);
const storage = createStorage({
type: "file" as never,
config: { rootDir: root } as never,
});
expect(storage).toBeInstanceOf(NodeFsStorage);
await storage.set("k", new Uint8Array([1]));
expect(await storage.get("k")).toEqual(new Uint8Array([1]));
});
it("is idempotent across repeated registerNodeFsProvider calls", {
timeout: 5000,
}, () => {
registerNodeFsProvider();
registerNodeFsProvider();
registerNodeFsProvider();
expect(hasStorageProvider("file")).toBe(true);
});
});

View File

@@ -0,0 +1,31 @@
import {
hasStorageProvider,
registerStorageProvider,
} from "@suaveplan/storage/factory";
import { NodeFsStorage } from "../node-fs-storage/node-fs-storage.js";
import type { NodeFsStorageOptions } from "../types/node-fs-storage.types.js";
declare module "@suaveplan/storage/factory" {
interface StorageProviderRegistry {
file: NodeFsStorage;
}
interface StorageProviderConfig {
file: NodeFsStorageOptions;
}
}
/**
* Register `NodeFsStorage` against the `@suaveplan/storage` factory under
* the canonical type slot `"file"`. Idempotent — repeated calls do nothing
* once the slot is occupied, and re-register cleanly after a downstream
* `clearStorageProviders()` call.
*/
export function registerNodeFsProvider(): void {
if (hasStorageProvider("file")) return;
registerStorageProvider(
"file",
NodeFsStorage as unknown as new (
config?: unknown
) => NodeFsStorage
);
}