Skip to content

Commit 9ef574f

Browse files
committed
copilot comments
1 parent da5f6a8 commit 9ef574f

5 files changed

Lines changed: 53 additions & 23 deletions

File tree

src/storage/__tests__/storage.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,27 @@ function runStorageTests(name: string, createStorage: () => StorageBackend, clea
116116
expect(await storage.count('pool_leaves')).toBe(1);
117117
});
118118

119+
it('numeric keys work for get and del', async () => {
120+
await storage.put('pool_leaves', { index: 0, commitment: '0xabc' });
121+
const result = await storage.get('pool_leaves', 0);
122+
expect(result).toBeDefined();
123+
expect(result.commitment).toBe('0xabc');
124+
await storage.del('pool_leaves', 0);
125+
expect(await storage.get('pool_leaves', 0)).toBeUndefined();
126+
});
127+
128+
it('throws on unknown store name (write)', async () => {
129+
await expect(storage.put('unknown_store', { id: 'a' })).rejects.toThrow('Unknown store');
130+
});
131+
132+
it('throws on unknown store name (read)', async () => {
133+
await expect(storage.get('unknown_store', 'a')).rejects.toThrow('Unknown store');
134+
});
135+
136+
it('throws on missing key field', async () => {
137+
await expect(storage.put('user_notes', { name: 'no id field' })).rejects.toThrow('Missing key field');
138+
});
139+
119140
it('mutations to returned records do not affect storage', async () => {
120141
await storage.put('user_notes', { id: 'a', amount: '100' });
121142
const record = await storage.get('user_notes', 'a');

src/storage/filesystem.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ export class FileSystemStorage implements StorageBackend {
77
mkdirSync(dirPath, { recursive: true });
88
}
99

10+
async init(): Promise<void> {}
11+
1012
private filePath(store: string): string {
13+
if (!STORE_KEYS[store]) throw new Error(`Unknown store: ${store}`);
1114
return join(this.dirPath, `${store}.json`);
1215
}
1316

@@ -23,15 +26,16 @@ export class FileSystemStorage implements StorageBackend {
2326

2427
private getKey(store: string, value: any): string {
2528
const keyField = STORE_KEYS[store];
26-
if (keyField && value && typeof value === 'object') {
27-
return String(value[keyField]);
28-
}
29-
return String(value?.id ?? value?.key ?? '');
29+
if (!keyField) throw new Error(`Unknown store: ${store}`);
30+
const key = value?.[keyField];
31+
if (key === undefined || key === null) throw new Error(`Missing key field '${keyField}' in value for store '${store}'`);
32+
return String(key);
3033
}
3134

32-
async get(store: string, key: string): Promise<any | undefined> {
35+
async get(store: string, key: any): Promise<any | undefined> {
3336
const data = this.readStore(store);
34-
return data[String(key)] ? structuredClone(data[String(key)]) : undefined;
37+
const k = String(key);
38+
return data[k] ? structuredClone(data[k]) : undefined;
3539
}
3640

3741
async getAll(store: string): Promise<any[]> {
@@ -60,7 +64,7 @@ export class FileSystemStorage implements StorageBackend {
6064
this.writeStore(store, data);
6165
}
6266

63-
async del(store: string, key: string): Promise<void> {
67+
async del(store: string, key: any): Promise<void> {
6468
const data = this.readStore(store);
6569
delete data[String(key)];
6670
this.writeStore(store, data);

src/storage/indexeddb.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const DB_VERSION = 1;
66
export class IndexedDBStorage implements StorageBackend {
77
private db: IDBDatabase | null = null;
88

9-
async open(): Promise<void> {
9+
async init(): Promise<void> {
1010
if (this.db) return;
1111
return new Promise((resolve, reject) => {
1212
const request = indexedDB.open(DB_NAME, DB_VERSION);
@@ -39,7 +39,7 @@ export class IndexedDBStorage implements StorageBackend {
3939
});
4040
}
4141

42-
async get(store: string, key: string): Promise<any | undefined> {
42+
async get(store: string, key: any): Promise<any | undefined> {
4343
return this.req(this.tx(store, 'readonly').get(key));
4444
}
4545

@@ -68,7 +68,7 @@ export class IndexedDBStorage implements StorageBackend {
6868
});
6969
}
7070

71-
async del(store: string, key: string): Promise<void> {
71+
async del(store: string, key: any): Promise<void> {
7272
await this.req(this.tx(store, 'readwrite').delete(key));
7373
}
7474

src/storage/memory.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { STORE_KEYS, type StorageBackend } from './storage.js';
22

33
export class MemoryStorage implements StorageBackend {
4-
private stores = new Map<string, Map<string, any>>();
4+
private stores = new Map<string, Map<any, any>>();
55

6-
private getStore(name: string): Map<string, any> {
6+
async init(): Promise<void> {}
7+
8+
private getStore(name: string): Map<any, any> {
9+
if (!STORE_KEYS[name]) throw new Error(`Unknown store: ${name}`);
710
let store = this.stores.get(name);
811
if (!store) {
912
store = new Map();
@@ -12,16 +15,16 @@ export class MemoryStorage implements StorageBackend {
1215
return store;
1316
}
1417

15-
private getKey(storeName: string, value: any): string {
18+
private getKey(storeName: string, value: any): any {
1619
const keyField = STORE_KEYS[storeName];
17-
if (keyField && value && typeof value === 'object') {
18-
return String(value[keyField]);
19-
}
20-
return String(value?.id ?? value?.key ?? '');
20+
if (!keyField) throw new Error(`Unknown store: ${storeName}`);
21+
const key = value?.[keyField];
22+
if (key === undefined || key === null) throw new Error(`Missing key field '${keyField}' in value for store '${storeName}'`);
23+
return key;
2124
}
2225

23-
async get(store: string, key: string): Promise<any | undefined> {
24-
return structuredClone(this.getStore(store).get(String(key)));
26+
async get(store: string, key: any): Promise<any | undefined> {
27+
return structuredClone(this.getStore(store).get(key));
2528
}
2629

2730
async getAll(store: string): Promise<any[]> {
@@ -49,8 +52,8 @@ export class MemoryStorage implements StorageBackend {
4952
}
5053
}
5154

52-
async del(store: string, key: string): Promise<void> {
53-
this.getStore(store).delete(String(key));
55+
async del(store: string, key: any): Promise<void> {
56+
this.getStore(store).delete(key);
5457
}
5558

5659
async clear(store: string): Promise<void> {

src/storage/storage.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,14 @@ export const STORE_KEYS: Record<string, string> = {
3232
};
3333

3434
export interface StorageBackend {
35-
get(store: string, key: string): Promise<any | undefined>;
35+
/** Initialize the storage backend (e.g., open IndexedDB connection). No-op for backends that don't need it. */
36+
init(): Promise<void>;
37+
get(store: string, key: any): Promise<any | undefined>;
3638
getAll(store: string): Promise<any[]>;
3739
getAllByIndex(store: string, index: string, value: any): Promise<any[]>;
3840
put(store: string, value: any): Promise<void>;
3941
putAll(store: string, values: any[]): Promise<void>;
40-
del(store: string, key: string): Promise<void>;
42+
del(store: string, key: any): Promise<void>;
4143
clear(store: string): Promise<void>;
4244
clearAll(): Promise<void>;
4345
count(store: string): Promise<number>;

0 commit comments

Comments
 (0)