@@ -13,25 +13,33 @@ import MemberDescription from '@site/src/components/MemberDescription';
13
13
14
14
## KV
15
15
16
- <GenerationInfo sourceFile = " packages/commandkit/src/kv/kv.ts" sourceLine = " 30 " packageName = " commandkit" />
16
+ <GenerationInfo sourceFile = " packages/commandkit/src/kv/kv.ts" sourceLine = " 42 " packageName = " commandkit" />
17
17
18
18
A key-value store implementation using SQLite
19
19
20
20
This class provides a simple, persistent key-value storage solution
21
- with support for namespaces, automatic cleanup, iteration, and expiration .
21
+ with support for namespaces, automatic cleanup, iteration, expiration, and JSON serialization .
22
22
23
23
24
24
25
25
* Example*
26
26
27
27
``` typescript
28
28
const kv = new KV (' data.db' );
29
- kv .set (' user:123' , JSON .stringify ({ name: ' John' , age: 30 }));
30
- const user = JSON .parse (kv .get (' user:123' ) || ' {}' );
31
29
32
- // Using namespaces
33
- const userKv = kv .namespace (' users' );
34
- userKv .set (' 123' , JSON .stringify ({ name: ' John' }));
30
+ // Store any JSON-serializable data
31
+ kv .set (' user:123' , { name: ' John' , age: 30 });
32
+ kv .set (' counter' , 42 );
33
+ kv .set (' active' , true );
34
+ kv .set (' dates' , [new Date (), new Date ()]);
35
+
36
+ // Use dot notation for nested properties
37
+ kv .set (' user:123.name' , ' John' );
38
+ kv .set (' user:123.settings.theme' , ' dark' );
39
+
40
+ // Retrieve data
41
+ const user = kv .get (' user:123' ); // { name: 'John', age: 30, settings: { theme: 'dark' } }
42
+ const name = kv .get (' user:123.name' ); // 'John'
35
43
```
36
44
37
45
``` ts title="Signature"
@@ -45,22 +53,22 @@ class KV implements Disposable, AsyncDisposable {
45
53
close() => void ;
46
54
[Symbol .dispose ]() => ;
47
55
[Symbol .asyncDispose ]() => ;
48
- get(key : string ) => string | undefined ;
49
- set(key : string , value : string ) => void ;
50
- setex(key : string , value : string , ttl : number ) => void ;
56
+ get(key : string ) => T | undefined ;
57
+ set(key : string , value : any ) => void ;
58
+ setex(key : string , value : any , ttl : number ) => void ;
51
59
expire(key : string , ttl : number ) => boolean ;
52
60
ttl(key : string ) => number ;
53
61
delete(key : string ) => void ;
54
62
has(key : string ) => boolean ;
55
63
keys() => string [];
56
- values() => string [];
64
+ values() => any [];
57
65
count() => number ;
58
66
clear() => void ;
59
- all() => Record <string , string >;
67
+ all() => Record <string , any >;
60
68
namespaces() => string [];
61
69
getCurrentNamespace() => string ;
62
70
namespace(namespace : string ) => KV ;
63
- [Symbol .iterator ]() => Iterator <[string , string ]>;
71
+ [Symbol .iterator ]() => Iterator <[string , any ]>;
64
72
transaction(fn : () => T | Promise <T >) => Promise <T >;
65
73
}
66
74
```
@@ -105,7 +113,7 @@ Disposable implementation - closes the database when disposed
105
113
AsyncDisposable implementation - closes the database when disposed
106
114
### get
107
115
108
- <MemberInfo kind = " method" type = { ` (key: string) => string | undefined ` } />
116
+ <MemberInfo kind = " method" type = { ` (key: string) => T | undefined ` } />
109
117
110
118
Retrieves a value by key
111
119
@@ -114,14 +122,20 @@ Retrieves a value by key
114
122
* Example*
115
123
116
124
``` typescript
117
- const value = kv .get (' my-key' );
118
- if (value ) {
119
- console .log (' Found:' , value );
120
- }
125
+ // Store an object
126
+ kv .set (' user:123' , { name: ' John' , age: 30 , settings: { theme: ' dark' } });
127
+
128
+ // Get the entire object
129
+ const user = kv .get (' user:123' );
130
+ // { name: 'John', age: 30, settings: { theme: 'dark' } }
131
+
132
+ // Get nested properties using dot notation
133
+ const name = kv .get (' user:123.name' ); // 'John'
134
+ const theme = kv .get (' user:123.settings.theme' ); // 'dark'
121
135
```
122
136
### set
123
137
124
- <MemberInfo kind = " method" type = { ` (key: string, value: string ) => void ` } />
138
+ <MemberInfo kind = " method" type = { ` (key: string, value: any ) => void ` } />
125
139
126
140
Sets a key-value pair
127
141
@@ -130,12 +144,31 @@ Sets a key-value pair
130
144
* Example*
131
145
132
146
``` typescript
133
- kv .set (' user:123' , JSON .stringify ({ name: ' John' }));
134
- kv .set (' counter' , ' 42' );
147
+ // Store primitive values
148
+ kv .set (' counter' , 42 );
149
+ kv .set (' active' , true );
150
+ kv .set (' name' , ' John' );
151
+
152
+ // Store objects
153
+ kv .set (' user:123' , { name: ' John' , age: 30 });
154
+
155
+ // Store arrays
156
+ kv .set (' tags' , [' javascript' , ' typescript' , ' sqlite' ]);
157
+
158
+ // Store dates
159
+ kv .set (' created' , new Date ());
160
+
161
+ // Store maps and sets
162
+ kv .set (' permissions' , new Map ([[' admin' , true ], [' user' , false ]]));
163
+ kv .set (' unique_ids' , new Set ([1 , 2 , 3 , 4 , 5 ]));
164
+
165
+ // Use dot notation for nested properties
166
+ kv .set (' user:123.settings.theme' , ' dark' );
167
+ kv .set (' user:123.settings.notifications' , true );
135
168
```
136
169
### setex
137
170
138
- <MemberInfo kind = " method" type = { ` (key: string, value: string , ttl: number) => void ` } />
171
+ <MemberInfo kind = " method" type = { ` (key: string, value: any , ttl: number) => void ` } />
139
172
140
173
Sets a key-value pair with expiration
141
174
@@ -145,10 +178,13 @@ Sets a key-value pair with expiration
145
178
146
179
``` typescript
147
180
// Set with 1 hour expiration
148
- kv .setex (' session:123' , ' user_data ' , 60 * 60 * 1000 );
181
+ kv .setex (' session:123' , { userId: 123 , token: ' abc123 ' } , 60 * 60 * 1000 );
149
182
150
183
// Set with 5 minutes expiration
151
- kv .setex (' temp:data' , ' cached_value' , 5 * 60 * 1000 );
184
+ kv .setex (' temp:data' , { cached: true , timestamp: Date .now () }, 5 * 60 * 1000 );
185
+
186
+ // Use dot notation with expiration
187
+ kv .setex (' user:123.temp_settings' , { theme: ' light' }, 30 * 60 * 1000 );
152
188
```
153
189
### expire
154
190
@@ -161,7 +197,7 @@ Sets expiration for an existing key
161
197
* Example*
162
198
163
199
``` typescript
164
- kv .set (' user:123' , ' user_data ' );
200
+ kv .set (' user:123' , { name: ' John ' , age: 30 } );
165
201
166
202
// Set 30 minute expiration
167
203
if (kv .expire (' user:123' , 30 * 60 * 1000 )) {
@@ -200,6 +236,7 @@ Deletes a key-value pair
200
236
201
237
``` typescript
202
238
kv .delete (' user:123' );
239
+ kv .delete (' user:123.settings.theme' ); // Delete nested property
203
240
```
204
241
### has
205
242
@@ -215,6 +252,10 @@ Checks if a key exists and is not expired
215
252
if (kv .has (' user:123' )) {
216
253
console .log (' User exists and is not expired' );
217
254
}
255
+
256
+ if (kv .has (' user:123.settings.theme' )) {
257
+ console .log (' Theme setting exists' );
258
+ }
218
259
```
219
260
### keys
220
261
@@ -232,7 +273,7 @@ console.log('All keys:', keys);
232
273
```
233
274
### values
234
275
235
- <MemberInfo kind = " method" type = { ` () => string [] ` } />
276
+ <MemberInfo kind = " method" type = { ` () => any [] ` } />
236
277
237
278
Gets all values in the current namespace (excluding expired keys)
238
279
@@ -273,7 +314,7 @@ kv.clear(); // Removes all entries in current namespace
273
314
```
274
315
### all
275
316
276
- <MemberInfo kind = " method" type = { ` () => Record<string, string > ` } />
317
+ <MemberInfo kind = " method" type = { ` () => Record<string, any > ` } />
277
318
278
319
Gets all key-value pairs as an object (excluding expired keys)
279
320
@@ -284,7 +325,7 @@ Gets all key-value pairs as an object (excluding expired keys)
284
325
``` typescript
285
326
const all = kv .all ();
286
327
console .log (' All entries:' , all );
287
- // Output: { 'key1': ' value1' , 'key2': ' value2' }
328
+ // Output: { 'key1': value1, 'key2': value2 }
288
329
```
289
330
### namespaces
290
331
@@ -319,12 +360,12 @@ Creates a new KV instance with a different namespace
319
360
const userKv = kv .namespace (' users' );
320
361
const configKv = kv .namespace (' config' );
321
362
322
- userKv .set (' 123' , ' John Doe ' );
363
+ userKv .set (' 123' , { name: ' John' , age: 30 } );
323
364
configKv .set (' theme' , ' dark' );
324
365
```
325
366
### \[ Symbol.iterator]
326
367
327
- <MemberInfo kind = " method" type = { ` () => Iterator<[string, string ]> ` } />
368
+ <MemberInfo kind = " method" type = { ` () => Iterator<[string, any ]> ` } />
328
369
329
370
Iterator implementation for iterating over all non-expired key-value pairs
330
371
@@ -334,7 +375,7 @@ Iterator implementation for iterating over all non-expired key-value pairs
334
375
335
376
``` typescript
336
377
for (const [key, value] of kv ) {
337
- console .log (` ${key }: ${ value } ` );
378
+ console .log (` ${key }: ` , value );
338
379
}
339
380
340
381
// Or using spread operator
@@ -353,16 +394,16 @@ Executes a function within a transaction
353
394
``` typescript
354
395
// Synchronous transaction
355
396
kv .transaction (() => {
356
- kv .set (' user:123' , JSON . stringify ( { name: ' John' }) );
357
- kv .set (' user:456' , JSON . stringify ( { name: ' Jane' }) );
397
+ kv .set (' user:123' , { name: ' John' , age: 30 } );
398
+ kv .set (' user:456' , { name: ' Jane' , age: 25 } );
358
399
// If any operation fails, all changes are rolled back
359
400
});
360
401
361
402
// Async transaction
362
403
await kv .transaction (async () => {
363
- kv .set (' user:123' , JSON . stringify ( { name: ' John' }) );
404
+ kv .set (' user:123' , { name: ' John' , age: 30 } );
364
405
await someAsyncOperation ();
365
- kv .set (' user:456' , JSON . stringify ( { name: ' Jane' }) );
406
+ kv .set (' user:456' , { name: ' Jane' , age: 25 } );
366
407
// If any operation fails, all changes are rolled back
367
408
});
368
409
```
0 commit comments