10 KiB
@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.
Documentation tree
- abstract — (no submodules) - namespace —
NamespacedStoragewraps any `Abstract… - errors — (no submodules)
- errors — (no submodules)
- factory — (no submodules)
- factory — (no submodules)
- memory — (no submodules)
- memory — (no submodules)
- types — (no submodules)
-
abstract — (no submodules)- namespace —
NamespacedStoragewraps any `Abstract… -
namespace —
NamespacedStoragewraps anyAbstractStorageinstance and prefixes all key operations with a caller-supplied namespa… -
errors — (no submodules)- errors — (no submodules)- factory — (no submodules)- factory — (no submodules)- memory — (no submodules)- memory — (no submodules)- types — (no submodules)- schemas — Provides Zod schemas for every value-type in
@suaveplan/storagethat crosses a runtime boundary — factory configurati…- types — (no submodules)- namespace —
NamespacedStoragewraps any `Abstract…
- types — (no submodules)- namespace —
-
abstract — (no submodules)- namespace —
NamespacedStoragewraps any `Abstract… -
namespace —
NamespacedStoragewraps anyAbstractStorageinstance and prefixes all key operations with a caller-supplied namespa… -
errors — (no submodules)- errors — (no submodules)- factory — (no submodules)- factory — (no submodules)- memory — (no submodules)- memory — (no submodules)- types — (no submodules)- schemas — Provides Zod schemas for every value-type in
@suaveplan/storagethat crosses a runtime boundary — factory configurati…- types — (no submodules)- namespace —
NamespacedStoragewraps any `Abstract…
- types — (no submodules)- namespace —
-
abstract — (no submodules)- namespace —
NamespacedStoragewraps any `Abstract… -
namespace —
NamespacedStoragewraps anyAbstractStorageinstance and prefixes all key operations with a caller-supplied namespa… -
errors — (no submodules)- errors — (no submodules)- factory — (no submodules)- factory — (no submodules)- memory — (no submodules)- memory — (no submodules)- types — (no submodules)- schemas — Provides Zod schemas for every value-type in
@suaveplan/storagethat crosses a runtime boundary — factory configurati… -
errors — (no submodules) - errors — (no submodules)- factory — (no submodules) - factory — (no submodules)- memory — (no submodules) - memory — (no submodules)- types — (no submodules) - schemas — Provides Zod schemas for every value-type in
@suaveplan/storagethat crosses a runtime boundary — factory configurati…- types — (no submodules)
Installation
bun add @suaveplan/storage
Quick Start
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
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
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
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
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 — STORAGE.* error codes and classes
- Types — Generic and functional type definitions
- Schemas — Zod schemas for runtime validation
- AbstractStorage — Base class and streaming defaults
- NamespacedStorage — Scoped key prefix wrapper
- MemoryStorage — In-process TTL storage with zero-copy streaming
- StorageFactory — 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 |