@aurora/runtime-storage (0.3.3)
Published 2025-12-27 10:44:41 +00:00 by vlad
Installation
@aurora:registry=npm install @aurora/runtime-storage@0.3.3"@aurora/runtime-storage": "0.3.3"About this package
@aurora/runtime-storage
Storage abstraction and tiered storage for Aurora applications.
Overview
Aurora's storage package provides:
- Storage abstraction interface
- Memory storage (testing/dev)
- Repository pattern
- Tiered storage (hot/warm/cold)
- Archiver interface for data lifecycle
Installation
bun add @aurora/runtime-storage
Storage Interface
interface Storage<K, V> {
get(key: K): Promise<V | null>;
set(key: K, value: V): Promise<void>;
delete(key: K): Promise<void>;
has(key: K): Promise<boolean>;
clear(): Promise<void>;
}
Memory Storage
import { MemoryStorage } from "@aurora/runtime-storage";
const storage = new MemoryStorage<string, any>();
await storage.set("key-1", { value: 42 });
const value = await storage.get("key-1");
console.log(value); // { value: 42 }
await storage.delete("key-1");
await storage.clear();
Repository Pattern
Creating Repository
import { Repository } from "@aurora/runtime-storage";
interface OrderKey {
tenantId: string;
orderId: string;
}
interface OrderValue {
tenantId: string;
orderId: string;
status: string;
amount: number;
}
class OrderRepository extends Repository<OrderKey, OrderValue> {
constructor(storage: Storage<OrderKey, OrderValue>) {
super(storage);
}
// Custom methods
async findByTenant(tenantId: string): Promise<OrderValue[]> {
const orders: OrderValue[] = [];
for await (const [key, value] of this.scan()) {
if (key.tenantId === tenantId) {
orders.push(value);
}
}
return orders;
}
}
Using Repository
const storage = new MemoryStorage<OrderKey, OrderValue>();
const repo = new OrderRepository(storage);
await repo.set({ tenantId: "tenant-1", orderId: "order-1" }, {
tenantId: "tenant-1",
orderId: "order-1",
status: "pending",
amount: 100,
});
const order = await repo.get({ tenantId: "tenant-1", orderId: "order-1" });
const tenantOrders = await repo.findByTenant("tenant-1");
Tiered Storage
Hot Storage
Fast read-optimized storage (LMDBX):
import { HotStorage } from "@aurora/runtime-storage";
const hotStorage = new HotStorage({
path: "./data/hot",
retentionDays: 90,
});
await hotStorage.set("order-123", { /* ... */ });
const order = await hotStorage.get("order-123");
Warm Storage
Write-optimized storage (RocksDB):
import { WarmStorage } from "@aurora/runtime-storage";
const warmStorage = new WarmStorage({
path: "./data/warm",
compression: true,
});
await warmStorage.append("order-123", event);
const history = await warmStorage.getHistory("order-123");
Cold Storage
Archival storage (S3, Blob):
import { ColdStorage } from "@aurora/runtime-storage";
const coldStorage = new ColdStorage({
type: "s3",
config: {
bucket: "aurora-archive",
region: "us-east-1",
},
});
await coldStorage.archive("orders-2024-01", data);
const data = await coldStorage.retrieve("orders-2024-01");
Archiver
Creating Archiver
import { Archiver } from "@aurora/runtime-storage";
const archiver = new Archiver({
hot: hotStorage,
warm: warmStorage,
cold: coldStorage,
policies: {
hotRetentionDays: 90,
warmRetentionDays: 365,
archiveAfter: 90,
},
});
Archiving Data
// Archive old data
await archiver.archive("order-123");
// Restore from archive
await archiver.restore("order-123");
Projection Storage
Hot Projections
import { ProjectionStorage } from "@aurora/runtime-storage";
const projection = new ProjectionStorage({
name: "OrderReadModel",
hot: hotStorage,
warm: warmStorage,
});
// Update projection
await projection.update("order-123", (current) => ({
...current,
status: "completed",
}));
// Get current state
const order = await projection.get("order-123");
Projection History
// Append event to history
await projection.appendEvent("order-123", event);
// Get event history
const history = await projection.getHistory("order-123");
Scan Operations
import { MemoryStorage } from "@aurora/runtime-storage";
const storage = new MemoryStorage<string, any>();
// Scan all
for await (const [key, value] of storage.scan()) {
console.log(key, value);
}
// Scan with filter
for await (const [key, value] of storage.scan()) {
if (value.tenantId === "tenant-1") {
console.log(key, value);
}
}
// Scan with prefix
for await (const [key, value] of storage.scan({ prefix: "tenant-1" })) {
console.log(key, value);
}
Transactions
const storage = new MemoryStorage<string, any>();
await storage.transaction(async (tx) => {
await tx.set("key-1", { value: 1 });
await tx.set("key-2", { value: 2 });
await tx.set("key-3", { value: 3 });
// All or nothing
});
Indexes
Creating Index
import { MemoryStorage } from "@aurora/runtime-storage";
const storage = new MemoryStorage<string, Order>();
// Create index on tenantId
storage.createIndex("tenantId", (key, value) => value.tenantId);
// Query by index
const tenantOrders = storage.queryByIndex("tenantId", "tenant-1");
Testing
import { test, expect } from "bun:test";
import { MemoryStorage } from "@aurora/runtime-storage";
test("storage get/set works", async () => {
const storage = new MemoryStorage<string, any>();
await storage.set("key-1", { value: 42 });
const value = await storage.get("key-1");
expect(value).toEqual({ value: 42 });
});
License
MIT
Dependencies
Dependencies
| ID | Version |
|---|---|
| @aurora/runtime-effect | 0.3.3 |