State sharing and KV store for Terminator workflows
npm install @mediar-ai/kvA lightweight, pluggable Key-Value store for Terminator workflows. This package enables state sharing between concurrent workflow executions, allowing for coordination, locking, and progress tracking.
* Pluggable Backends: Switch between Redis (production), File-system (local persistence), and Memory (testing) without changing code.
* Unified API: Simple get, set, del API inspired by Vercel KV / Redis.
* Atomic Operations: Supports NX (Not Exists) and XX (Already Exists) for locking.
* Zero Config: Defaults to a local file-based store if no configuration is provided.
``bash`
npm install @mediar-ai/kv
`typescript
import { kv } from '@mediar-ai/kv';
async function main() {
// Set a value
await kv.set('user:123', 'Alice');
// Get a value
const user = await kv.get('user:123');
console.log(user); // 'Alice'
// Atomic Lock (useful for preventing race conditions)
const acquired = await kv.set('lock:resource:A', 'locked', { nx: true, ex: 60 });
if (acquired) {
try {
console.log('Lock acquired, doing work...');
} finally {
await kv.del('lock:resource:A');
}
} else {
console.log('Could not acquire lock.');
}
}
`
`typescript`
await kv.lpush('queue:invoices', 'inv_001', 'inv_002');
const nextItem = await kv.rpop('queue:invoices');
`typescript
await kv.hset('invoice:inv_001', {
status: 'processing',
amount: 100.50,
vendor: 'Acme Corp'
});
const status = await kv.hget('invoice:inv_001', 'status');
const allData = await kv.hgetall('invoice:inv_001');
`
The client automatically detects the configuration based on environment variables or defaults.
Set KV_URL or REDIS_URL to configure the backend.
* Redis: redis://localhost:6379file://./my-db.json
* File: memory://
* Memory:
You can also create a custom client instance:
`typescript
import { createClient } from '@mediar-ai/kv';
// Redis
const redisKv = createClient({ url: 'redis://user:pass@host:6379' });
// File (Persistent local JSON file)
const fileKv = createClient({ url: 'file://./data/workflow-state.json' });
// Memory (Ephemeral, good for tests)
const memKv = createClient({ backend: 'memory' });
`
* set(key, value, { ex?, nx?, xx? }): Set value with optional TTL (seconds) and conditions.get(key)
* : Get string value.del(key)
* : Delete key.expire(key, seconds)
* : Set expiry on existing key.incr(key)
* : Increment integer value.lpush(key, ...elements)
* : Prepend to list.rpush(key, ...elements)
* : Append to list.lpop(key)
* : Remove and return first element.rpop(key)
* : Remove and return last element.hset(key, field, value)
* or hset(key, object): Set hash fields.hget(key, field)
* : Get hash field.hgetall(key)
* : Get all fields in hash.hincrby(key, field, increment)`: Increment hash field.
*
MIT