feat(storage): add InMemoryKVStore, InMemoryStore accepts optional KVStore

This commit is contained in:
Yuqing Bai 2026-04-05 10:06:51 +08:00
parent 2a20961a14
commit d7a5862722
2 changed files with 76 additions and 1 deletions

View File

@ -7,7 +7,35 @@
* in production by satisfying the same {@link MemoryStore} interface.
*/
import type { MemoryEntry, MemoryStore } from '../types.js'
import type { KVStore, MemoryEntry, MemoryStore } from '../types.js'
// ---------------------------------------------------------------------------
// InMemoryKVStore
// ---------------------------------------------------------------------------
export class InMemoryKVStore implements KVStore {
private readonly data = new Map<string, string>()
async get(key: string): Promise<string | null> {
return this.data.get(key) ?? null
}
async set(key: string, value: string): Promise<void> {
this.data.set(key, value)
}
async delete(key: string): Promise<void> {
this.data.delete(key)
}
async list(): Promise<string[]> {
return Array.from(this.data.keys())
}
async clear(): Promise<void> {
this.data.clear()
}
}
// ---------------------------------------------------------------------------
// InMemoryStore
@ -31,6 +59,8 @@ import type { MemoryEntry, MemoryStore } from '../types.js'
export class InMemoryStore implements MemoryStore {
private readonly data = new Map<string, MemoryEntry>()
constructor(_kvStore?: KVStore) {}
// ---------------------------------------------------------------------------
// MemoryStore interface
// ---------------------------------------------------------------------------

45
tests/kv-store.test.ts Normal file
View File

@ -0,0 +1,45 @@
import { describe, it, expect } from 'vitest'
import { InMemoryKVStore } from '../src/memory/store.js'
describe('InMemoryKVStore', () => {
it('sets and gets a value', async () => {
const store = new InMemoryKVStore()
await store.set('k1', 'v1')
expect(await store.get('k1')).toBe('v1')
})
it('returns null for missing key', async () => {
const store = new InMemoryKVStore()
expect(await store.get('nope')).toBeNull()
})
it('overwrites existing key', async () => {
const store = new InMemoryKVStore()
await store.set('k', 'first')
await store.set('k', 'second')
expect(await store.get('k')).toBe('second')
})
it('deletes a key', async () => {
const store = new InMemoryKVStore()
await store.set('k', 'v')
await store.delete('k')
expect(await store.get('k')).toBeNull()
})
it('list returns all keys', async () => {
const store = new InMemoryKVStore()
await store.set('a', '1')
await store.set('b', '2')
const keys = await store.list()
expect(keys.sort()).toEqual(['a', 'b'])
})
it('clear removes all keys', async () => {
const store = new InMemoryKVStore()
await store.set('a', '1')
await store.set('b', '2')
await store.clear()
expect(await store.list()).toEqual([])
})
})