
Company News
Jerod Santo Joins Socket as Head of Media
Allow myself to introduce... myself.
@device-router/storage
Advanced tools
Storage adapters (memory, Redis) for persisting device profiles in DeviceRouter
Storage adapters for persisting device profiles in DeviceRouter. Ships with in-memory and Redis adapters.
pnpm add @device-router/storage
For Redis support:
pnpm add @device-router/storage ioredis
Profiles are stored in a Map with automatic TTL expiration. Suitable for single-process development and testing.
import { MemoryStorageAdapter } from '@device-router/storage';
const storage = new MemoryStorageAdapter();
For multi-process and multi-server deployments. Uses Redis EX for TTL.
import { RedisStorageAdapter } from '@device-router/storage';
import Redis from 'ioredis';
const redis = new Redis();
const storage = new RedisStorageAdapter({
client: redis,
keyPrefix: 'dr:profile:', // default
});
The client option accepts any object with get, set, del, exists, and keys methods matching the ioredis interface. This means you can use any Redis-compatible client.
The client may also provide an optional scan(cursor, ...args) method. When available, clear(), count(), and keys() use SCAN-based iteration instead of the blocking KEYS command. This is recommended for production to avoid blocking the Redis event loop on large datasets.
Implement the StorageAdapter interface:
import type { StorageAdapter } from '@device-router/storage';
import type { DeviceProfile } from '@device-router/types';
class MyAdapter implements StorageAdapter {
async get(sessionToken: string): Promise<DeviceProfile | null> {
/* ... */
}
async set(sessionToken: string, profile: DeviceProfile, ttlSeconds: number): Promise<void> {
/* ... */
}
async delete(sessionToken: string): Promise<void> {
/* ... */
}
async exists(sessionToken: string): Promise<boolean> {
/* ... */
}
async clear(): Promise<void> {
/* ... */
}
async count(): Promise<number> {
/* ... */
}
async keys(): Promise<string[]> {
/* ... */
}
}
StorageAdapter interface| Method | Signature | Description |
|---|---|---|
get | (sessionToken: string) => Promise<DeviceProfile | null> | Retrieve a profile |
set | (sessionToken: string, profile: DeviceProfile, ttl: number) => Promise<void> | Store with TTL (seconds) |
delete | (sessionToken: string) => Promise<void> | Remove a profile |
exists | (sessionToken: string) => Promise<boolean> | Check if a profile exists |
clear | () => Promise<void> | Remove all entries |
count | () => Promise<number> | Count stored profiles |
keys | () => Promise<string[]> | List session tokens |
MemoryStorageAdapterImplements StorageAdapter plus:
clear() — Remove all entries and cancel timerscount() — Count stored profileskeys() — List session tokensRedisStorageAdapterConstructor options:
| Option | Type | Default | Description |
|---|---|---|---|
client | object | (required) | Redis-compatible client |
keyPrefix | string | 'dr:profile:' | Key prefix for all entries |
MIT
FAQs
Storage adapters (memory, Redis) for persisting device profiles in DeviceRouter
We found that @device-router/storage demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Allow myself to introduce... myself.

Research
/Security News
A Twitch browser extension on Chrome and Firefox forwards users’ live OAuth session tokens through proxies controlled by a Russian bot service.

Security News
Anthropic found biased reasoning and recklessness drove Claude Mythos 5 to publish malware on PyPI and compromise a security vendor.