174 lines
10 KiB
Markdown
174 lines
10 KiB
Markdown
# @suaveplan/storage - Enterprise key-value storage abstractions: AbstractStorage (StorageLike + streaming + hooks + OTel), MemoryStorage (TTL, zero-copy streams), NamespacedStorage, StorageFactory with module-augmentation provider registry, structured STORAGE.* errors.
|
|
|
|
## Summary
|
|
|
|
Enterprise key-value storage abstractions for Suaveplan. Provides `AbstractStorage` (implementing `StorageLike`), `MemoryStorage` with TTL and zero-copy streaming, `NamespacedStorage` with scoped operations, and `StorageFactory` with a module-augmentation provider registry.
|
|
|
|
<!-- begin:auto-docs -->
|
|
## Documentation tree
|
|
|
|
- [abstract](./src/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs --> - namespace — `NamespacedStorage` wraps any `Abstract…
|
|
- [abstract](./src/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs --> - namespace — `NamespacedStorage` wraps any `Abstract…
|
|
- [namespace](./src/abstract/namespace.md) — `NamespacedStorage` wraps any `AbstractStorage` instance and prefixes all key operations with a caller-supplied namespa…
|
|
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [memory](./src/memory/memory.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [memory](./src/memory/memory.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [schemas](./src/types/schemas.md) — Provides Zod schemas for every value-type in `@suaveplan/storage` that crosses a runtime boundary — factory configurati…
|
|
- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
<!-- end:auto-docs --> - namespace — `NamespacedStorage` wraps any `Abstract…
|
|
- [abstract](./src/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- namespace — `NamespacedStorage` wraps any `Abstract…
|
|
- [namespace](./src/abstract/namespace.md) — `NamespacedStorage` wraps any `AbstractStorage` instance and prefixes all key operations with a caller-supplied namespa…
|
|
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [memory](./src/memory/memory.md) — <!-- begin:auto-docs --> _(no submodules)_- [memory](./src/memory/memory.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [schemas](./src/types/schemas.md) — Provides Zod schemas for every value-type in `@suaveplan/storage` that crosses a runtime boundary — factory configurati…
|
|
- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- namespace — `NamespacedStorage` wraps any `Abstract…
|
|
|
|
- [abstract](./src/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- namespace — `NamespacedStorage` wraps any `Abstract…
|
|
- [namespace](./src/abstract/namespace.md) — `NamespacedStorage` wraps any `AbstractStorage` instance and prefixes all key operations with a caller-supplied namespa…
|
|
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [memory](./src/memory/memory.md) — <!-- begin:auto-docs --> _(no submodules)_- [memory](./src/memory/memory.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [schemas](./src/types/schemas.md) — Provides Zod schemas for every value-type in `@suaveplan/storage` that crosses a runtime boundary — factory configurati…
|
|
- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- namespace — `NamespacedStorage` wraps any `Abstract…
|
|
|
|
- [abstract](./src/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- namespace — `NamespacedStorage` wraps any `Abstract…
|
|
- [namespace](./src/abstract/namespace.md) — `NamespacedStorage` wraps any `AbstractStorage` instance and prefixes all key operations with a caller-supplied namespa…
|
|
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [memory](./src/memory/memory.md) — <!-- begin:auto-docs --> _(no submodules)_- [memory](./src/memory/memory.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [schemas](./src/types/schemas.md) — Provides Zod schemas for every value-type in `@suaveplan/storage` that crosses a runtime boundary — factory configurati…
|
|
- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [abstract](./src/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- [namespace](./src/abstract/namespace.md) — `NamespacedStorage` wraps any `AbstractStorage` instance and prefixes all key operations with a caller-supplied namespa…
|
|
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ - [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_ - [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [memory](./src/memory/memory.md) — <!-- begin:auto-docs --> _(no submodules)_ - [memory](./src/memory/memory.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_ - [schemas](./src/types/schemas.md) — Provides Zod schemas for every value-type in `@suaveplan/storage` that crosses a runtime boundary — factory configurati…
|
|
- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_
|
|
## Installation
|
|
|
|
```bash
|
|
bun add @suaveplan/storage
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
```typescript
|
|
import { MemoryStorage } from '@suaveplan/storage/memory';
|
|
|
|
const store = new MemoryStorage();
|
|
const enc = new TextEncoder();
|
|
|
|
await store.set('user:1', enc.encode('{"name":"Alice"}'));
|
|
const buf = await store.get('user:1');
|
|
console.log(new TextDecoder().decode(buf!)); // {"name":"Alice"}
|
|
|
|
// TTL — expires after 5 seconds
|
|
await store.set('session:xyz', enc.encode('token'), { ttl: 5000 });
|
|
|
|
store.destroy(); // stop background cleanup timer
|
|
```
|
|
|
|
## Streaming
|
|
|
|
```typescript
|
|
import { MemoryStorage } from '@suaveplan/storage/memory';
|
|
|
|
const store = new MemoryStorage();
|
|
|
|
// Write via WritableStream
|
|
const ws = store.createWriteStream('blob');
|
|
const writer = ws.getWriter();
|
|
await writer.write(new Uint8Array([1, 2, 3]));
|
|
await writer.write(new Uint8Array([4, 5, 6]));
|
|
await writer.close(); // flushes to storage
|
|
|
|
// Read via ReadableStream
|
|
const rs = store.createReadStream('blob');
|
|
const reader = rs.getReader();
|
|
const { value } = await reader.read(); // Uint8Array([1, 2, 3, 4, 5, 6])
|
|
|
|
// Byte-range read
|
|
const slice = await store.getPartial('blob', 2, 3); // bytes [2, 5)
|
|
```
|
|
|
|
## Namespaces
|
|
|
|
```typescript
|
|
import { MemoryStorage } from '@suaveplan/storage/memory';
|
|
|
|
const store = new MemoryStorage();
|
|
const users = store.namespace('user');
|
|
const sessions = store.namespace('session');
|
|
|
|
await users.set('alice', new Uint8Array([1]));
|
|
await sessions.set('alice', new Uint8Array([2]));
|
|
|
|
// No cross-namespace leakage
|
|
await sessions.get('alice'); // Uint8Array([2])
|
|
await users.get('alice'); // Uint8Array([1])
|
|
|
|
// clear() is scoped
|
|
await users.clear(); // removes only user:* keys
|
|
await sessions.get('alice'); // still Uint8Array([2])
|
|
```
|
|
|
|
## Factory / Custom Provider
|
|
|
|
```typescript
|
|
import { StorageFactory } from '@suaveplan/storage/factory';
|
|
import { AbstractStorage } from '@suaveplan/storage/abstract';
|
|
|
|
// Register a custom provider
|
|
class RedisStorage extends AbstractStorage { /* ... */ }
|
|
StorageFactory.register('redis', RedisStorage);
|
|
|
|
// Module augmentation for full type safety
|
|
declare module '@suaveplan/storage/factory' {
|
|
interface StorageProviderRegistry { redis: RedisStorage; }
|
|
}
|
|
|
|
const store = StorageFactory.create({ type: 'redis' });
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
```typescript
|
|
import {
|
|
StorageNotFoundError,
|
|
StorageQuotaError,
|
|
StorageInvalidKeyError,
|
|
STORAGE_CODES,
|
|
} from '@suaveplan/storage/errors';
|
|
|
|
try {
|
|
await store.set('../escape', new Uint8Array([1]));
|
|
} catch (err) {
|
|
if (err instanceof StorageInvalidKeyError) {
|
|
console.error(err.code); // STORAGE.INVALID_KEY
|
|
console.error(err.key); // "../escape"
|
|
}
|
|
}
|
|
|
|
// Quota
|
|
store.setMaxValueSize(100);
|
|
try {
|
|
await store.set('big', new Uint8Array(200));
|
|
} catch (err) {
|
|
if (err instanceof StorageQuotaError) { /* handle */ }
|
|
}
|
|
```
|
|
|
|
## Module Docs
|
|
|
|
- [Errors](src/errors/errors.md) — STORAGE.* error codes and classes
|
|
- [Types](src/types/types.md) — Generic and functional type definitions
|
|
- [Schemas](src/types/schemas.md) — Zod schemas for runtime validation
|
|
- [AbstractStorage](src/abstract/abstract.md) — Base class and streaming defaults
|
|
- [NamespacedStorage](src/abstract/namespace.md) — Scoped key prefix wrapper
|
|
- [MemoryStorage](src/memory/memory.md) — In-process TTL storage with zero-copy streaming
|
|
- [StorageFactory](src/factory/factory.md) — Provider registry and factory functions
|
|
|
|
## Dependencies
|
|
|
|
| Dependency | Purpose |
|
|
|-----------|---------|
|
|
| `@suaveplan/error` | `SuaveplanError` base class, `defineCodes`, wire format |
|
|
| `@suaveplan/types` | `StorageLike`, `EventBusLike` interfaces |
|
|
| `@suaveplan/events` | Default `EventBus` for lifecycle events |
|
|
| `@opentelemetry/api` | `storage.ops` counter, `storage.op.duration_ms` histogram |
|
|
| `zod` | Schema validation for config and options |
|
|
| `tslib` | TypeScript runtime helpers |
|
|
|