commandkit 1.0.0-dev.20250702022547 → 1.0.0-dev.20250702125326

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import * as child_process0 from "child_process";
1
+ import * as child_process3 from "child_process";
2
2
 
3
3
  //#region src/cli/app-process.d.ts
4
4
 
@@ -6,7 +6,7 @@ import * as child_process0 from "child_process";
6
6
  * @private
7
7
  * @internal
8
8
  */
9
- declare function createAppProcess(fileName: string, cwd: string, isDev: boolean): child_process0.ChildProcess;
9
+ declare function createAppProcess(fileName: string, cwd: string, isDev: boolean): child_process3.ChildProcess;
10
10
  //#endregion
11
11
  export { createAppProcess };
12
12
  //# sourceMappingURL=app-process.d.ts.map
@@ -29,7 +29,7 @@ import "../CommandsRouter-CoOA7hkf.js";
29
29
  import "../EventsRouter-BacqK6z3.js";
30
30
  import "../index-CUPkUUOR.js";
31
31
  import "../constants-BTttfrm3.js";
32
- import * as typescript1 from "typescript";
32
+ import * as typescript0 from "typescript";
33
33
 
34
34
  //#region src/cli/common.d.ts
35
35
  /**
@@ -57,7 +57,7 @@ declare function findPackageJSON(): any;
57
57
  * @private
58
58
  * @internal
59
59
  */
60
- declare function loadTypeScript(e?: string): Promise<typeof typescript1>;
60
+ declare function loadTypeScript(e?: string): Promise<typeof typescript0>;
61
61
  /**
62
62
  * @private
63
63
  * @internal
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require('../chunk-nOFOJqeH.js');
2
- const require_version = require('../version-CHYJXFOa.js');
2
+ const require_version = require('../version-DvvD35ov.js');
3
3
  const node_fs = require_chunk.__toESM(require("node:fs"));
4
4
  const node_path = require_chunk.__toESM(require("node:path"));
5
5
  const node_child_process = require_chunk.__toESM(require("node:child_process"));
@@ -1,4 +1,4 @@
1
- import * as child_process3 from "child_process";
1
+ import * as child_process1 from "child_process";
2
2
 
3
3
  //#region src/cli/production.d.ts
4
4
 
@@ -6,7 +6,7 @@ import * as child_process3 from "child_process";
6
6
  * @private
7
7
  * @internal
8
8
  */
9
- declare function bootstrapProductionServer(configPath?: string): Promise<child_process3.ChildProcess>;
9
+ declare function bootstrapProductionServer(configPath?: string): Promise<child_process1.ChildProcess>;
10
10
  /**
11
11
  * @private
12
12
  * @internal
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ require('./store-CyzliDXj.js');
36
36
  const require_helpers = require('./helpers-DfV6HlgI.js');
37
37
  require('./app-gCenKq8k.js');
38
38
  require('./ILogger-BMIMljYD.js');
39
- const require_version = require('./version-CHYJXFOa.js');
39
+ const require_version = require('./version-DvvD35ov.js');
40
40
  const require_feature_flags = require('./feature-flags-DJcINI5E.js');
41
41
  const require_init = require('./init-DeoDd5cK.js');
42
42
 
@@ -0,0 +1,321 @@
1
+ import { DatabaseSync } from "node:sqlite";
2
+
3
+ //#region src/kv/kv.d.ts
4
+
5
+ /**
6
+ * Configuration options for the KV store
7
+ */
8
+ interface KvOptions {
9
+ /** Enable Write-Ahead Logging for better performance and durability */
10
+ enableWAL?: boolean;
11
+ /** Namespace for the key-value store table */
12
+ namespace?: string;
13
+ }
14
+ /**
15
+ * A key-value store implementation using SQLite
16
+ *
17
+ * This class provides a simple, persistent key-value storage solution
18
+ * with support for namespaces, automatic cleanup, iteration, and expiration.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const kv = new KV('data.db');
23
+ * kv.set('user:123', JSON.stringify({ name: 'John', age: 30 }));
24
+ * const user = JSON.parse(kv.get('user:123') || '{}');
25
+ *
26
+ * // Using namespaces
27
+ * const userKv = kv.namespace('users');
28
+ * userKv.set('123', JSON.stringify({ name: 'John' }));
29
+ * ```
30
+ */
31
+ declare class KV implements Disposable, AsyncDisposable {
32
+ private options;
33
+ private db;
34
+ private statements;
35
+ /**
36
+ * Creates a new KV store instance
37
+ *
38
+ * @param path - Database file path, buffer, URL, or existing DatabaseSync instance
39
+ * @param options - Configuration options for the KV store
40
+ */
41
+ constructor(path: string | Buffer | URL | DatabaseSync, options?: KvOptions);
42
+ /**
43
+ * Gets the current timestamp in milliseconds
44
+ */
45
+ private getCurrentTime;
46
+ /**
47
+ * Checks if the database connection is open
48
+ *
49
+ * @returns `true` if the database is open, `false` otherwise
50
+ */
51
+ isOpen(): boolean;
52
+ /**
53
+ * Gets the underlying SQLite database instance
54
+ *
55
+ * @returns The DatabaseSync instance
56
+ */
57
+ getDatabase(): DatabaseSync;
58
+ /**
59
+ * Closes the database connection
60
+ */
61
+ close(): void;
62
+ /**
63
+ * Disposable implementation - closes the database when disposed
64
+ */
65
+ [Symbol.dispose](): void;
66
+ /**
67
+ * AsyncDisposable implementation - closes the database when disposed
68
+ */
69
+ [Symbol.asyncDispose](): Promise<void>;
70
+ /**
71
+ * Retrieves a value by key
72
+ *
73
+ * @param key - The key to retrieve
74
+ * @returns The value associated with the key, or `undefined` if not found or expired
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const value = kv.get('my-key');
79
+ * if (value) {
80
+ * console.log('Found:', value);
81
+ * }
82
+ * ```
83
+ */
84
+ get(key: string): string | undefined;
85
+ /**
86
+ * Sets a key-value pair
87
+ *
88
+ * @param key - The key to set
89
+ * @param value - The value to associate with the key
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * kv.set('user:123', JSON.stringify({ name: 'John' }));
94
+ * kv.set('counter', '42');
95
+ * ```
96
+ */
97
+ set(key: string, value: string): void;
98
+ /**
99
+ * Sets a key-value pair with expiration
100
+ *
101
+ * @param key - The key to set
102
+ * @param value - The value to associate with the key
103
+ * @param ttl - Time to live in milliseconds
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * // Set with 1 hour expiration
108
+ * kv.setex('session:123', 'user_data', 60 * 60 * 1000);
109
+ *
110
+ * // Set with 5 minutes expiration
111
+ * kv.setex('temp:data', 'cached_value', 5 * 60 * 1000);
112
+ * ```
113
+ */
114
+ setex(key: string, value: string, ttl: number): void;
115
+ /**
116
+ * Sets expiration for an existing key
117
+ *
118
+ * @param key - The key to set expiration for
119
+ * @param ttl - Time to live in milliseconds
120
+ * @returns `true` if the key exists and expiration was set, `false` otherwise
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * kv.set('user:123', 'user_data');
125
+ *
126
+ * // Set 30 minute expiration
127
+ * if (kv.expire('user:123', 30 * 60 * 1000)) {
128
+ * console.log('Expiration set successfully');
129
+ * }
130
+ * ```
131
+ */
132
+ expire(key: string, ttl: number): boolean;
133
+ /**
134
+ * Gets the time to live for a key
135
+ *
136
+ * @param key - The key to check
137
+ * @returns Time to live in milliseconds, or `-1` if the key doesn't exist, or `-2` if the key has no expiration
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * const ttl = kv.ttl('user:123');
142
+ * if (ttl > 0) {
143
+ * console.log(`Key expires in ${ttl}ms`);
144
+ * } else if (ttl === -2) {
145
+ * console.log('Key has no expiration');
146
+ * } else {
147
+ * console.log('Key does not exist');
148
+ * }
149
+ * ```
150
+ */
151
+ ttl(key: string): number;
152
+ /**
153
+ * Deletes a key-value pair
154
+ *
155
+ * @param key - The key to delete
156
+ *
157
+ * @example
158
+ * ```typescript
159
+ * kv.delete('user:123');
160
+ * ```
161
+ */
162
+ delete(key: string): void;
163
+ /**
164
+ * Checks if a key exists and is not expired
165
+ *
166
+ * @param key - The key to check
167
+ * @returns `true` if the key exists and is not expired, `false` otherwise
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * if (kv.has('user:123')) {
172
+ * console.log('User exists and is not expired');
173
+ * }
174
+ * ```
175
+ */
176
+ has(key: string): boolean;
177
+ /**
178
+ * Gets all keys in the current namespace (excluding expired keys)
179
+ *
180
+ * @returns Array of all non-expired keys
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * const keys = kv.keys();
185
+ * console.log('All keys:', keys);
186
+ * ```
187
+ */
188
+ keys(): string[];
189
+ /**
190
+ * Gets all values in the current namespace (excluding expired keys)
191
+ *
192
+ * @returns Array of all non-expired values
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * const values = kv.values();
197
+ * console.log('All values:', values);
198
+ * ```
199
+ */
200
+ values(): string[];
201
+ /**
202
+ * Gets the total number of key-value pairs in the current namespace (excluding expired keys)
203
+ *
204
+ * @returns The count of non-expired key-value pairs
205
+ *
206
+ * @example
207
+ * ```typescript
208
+ * const count = kv.count();
209
+ * console.log(`Total entries: ${count}`);
210
+ * ```
211
+ */
212
+ count(): number;
213
+ /**
214
+ * Removes all key-value pairs from the current namespace
215
+ *
216
+ * @example
217
+ * ```typescript
218
+ * kv.clear(); // Removes all entries in current namespace
219
+ * ```
220
+ */
221
+ clear(): void;
222
+ /**
223
+ * Gets all key-value pairs as an object (excluding expired keys)
224
+ *
225
+ * @returns Object with all non-expired key-value pairs
226
+ *
227
+ * @example
228
+ * ```typescript
229
+ * const all = kv.all();
230
+ * console.log('All entries:', all);
231
+ * // Output: { 'key1': 'value1', 'key2': 'value2' }
232
+ * ```
233
+ */
234
+ all(): Record<string, string>;
235
+ /**
236
+ * Gets all available namespaces (tables) in the database
237
+ *
238
+ * @returns Array of namespace names
239
+ *
240
+ * @example
241
+ * ```typescript
242
+ * const namespaces = kv.namespaces();
243
+ * console.log('Available namespaces:', namespaces);
244
+ * ```
245
+ */
246
+ namespaces(): string[];
247
+ /**
248
+ * Gets the current namespace name
249
+ *
250
+ * @returns The current namespace string
251
+ */
252
+ getCurrentNamespace(): string;
253
+ /**
254
+ * Creates a new KV instance with a different namespace
255
+ *
256
+ * @param namespace - The namespace to use for the new instance
257
+ * @returns A new KV instance with the specified namespace
258
+ *
259
+ * @example
260
+ * ```typescript
261
+ * const userKv = kv.namespace('users');
262
+ * const configKv = kv.namespace('config');
263
+ *
264
+ * userKv.set('123', 'John Doe');
265
+ * configKv.set('theme', 'dark');
266
+ * ```
267
+ */
268
+ namespace(namespace: string): KV;
269
+ /**
270
+ * Iterator implementation for iterating over all non-expired key-value pairs
271
+ *
272
+ * @returns Iterator yielding [key, value] tuples
273
+ *
274
+ * @example
275
+ * ```typescript
276
+ * for (const [key, value] of kv) {
277
+ * console.log(`${key}: ${value}`);
278
+ * }
279
+ *
280
+ * // Or using spread operator
281
+ * const entries = [...kv];
282
+ * ```
283
+ */
284
+ [Symbol.iterator](): Iterator<[string, string]>;
285
+ /**
286
+ * Executes a function within a transaction
287
+ *
288
+ * @param fn - Function to execute within the transaction (can be async)
289
+ * @returns The result of the function
290
+ *
291
+ * @example
292
+ * ```typescript
293
+ * // Synchronous transaction
294
+ * kv.transaction(() => {
295
+ * kv.set('user:123', JSON.stringify({ name: 'John' }));
296
+ * kv.set('user:456', JSON.stringify({ name: 'Jane' }));
297
+ * // If any operation fails, all changes are rolled back
298
+ * });
299
+ *
300
+ * // Async transaction
301
+ * await kv.transaction(async () => {
302
+ * kv.set('user:123', JSON.stringify({ name: 'John' }));
303
+ * await someAsyncOperation();
304
+ * kv.set('user:456', JSON.stringify({ name: 'Jane' }));
305
+ * // If any operation fails, all changes are rolled back
306
+ * });
307
+ * ```
308
+ */
309
+ transaction<T>(fn: () => T | Promise<T>): Promise<T>;
310
+ }
311
+ /**
312
+ * Opens a new KV instance
313
+ *
314
+ * @param path - Database file path, buffer, URL, or existing DatabaseSync instance
315
+ * @param options - Configuration options for the KV store
316
+ * @returns A new KV instance
317
+ */
318
+ declare function openKV(path?: string | Buffer | URL | DatabaseSync, options?: KvOptions): KV;
319
+ //#endregion
320
+ export { KV, KvOptions, openKV };
321
+ //# sourceMappingURL=kv.d.ts.map
package/dist/kv/kv.js ADDED
@@ -0,0 +1,428 @@
1
+ const require_chunk = require('../chunk-nOFOJqeH.js');
2
+ const node_sqlite = require_chunk.__toESM(require("node:sqlite"));
3
+
4
+ //#region src/kv/kv.ts
5
+ /**
6
+ * A key-value store implementation using SQLite
7
+ *
8
+ * This class provides a simple, persistent key-value storage solution
9
+ * with support for namespaces, automatic cleanup, iteration, and expiration.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const kv = new KV('data.db');
14
+ * kv.set('user:123', JSON.stringify({ name: 'John', age: 30 }));
15
+ * const user = JSON.parse(kv.get('user:123') || '{}');
16
+ *
17
+ * // Using namespaces
18
+ * const userKv = kv.namespace('users');
19
+ * userKv.set('123', JSON.stringify({ name: 'John' }));
20
+ * ```
21
+ */
22
+ var KV = class KV {
23
+ db;
24
+ statements = {};
25
+ /**
26
+ * Creates a new KV store instance
27
+ *
28
+ * @param path - Database file path, buffer, URL, or existing DatabaseSync instance
29
+ * @param options - Configuration options for the KV store
30
+ */
31
+ constructor(path, options = {
32
+ enableWAL: true,
33
+ namespace: "commandkit_kv"
34
+ }) {
35
+ this.options = options;
36
+ this.db = path instanceof node_sqlite.DatabaseSync ? path : new node_sqlite.DatabaseSync(path, { open: true });
37
+ if (options.enableWAL) this.db.exec(`PRAGMA journal_mode = WAL;`);
38
+ this.db.prepare(`
39
+ CREATE TABLE IF NOT EXISTS ? (
40
+ key TEXT PRIMARY KEY,
41
+ value TEXT,
42
+ expires_at INTEGER
43
+ )
44
+ `).run(options.namespace ?? "commandkit_kv");
45
+ this.statements = {
46
+ get: this.db.prepare(`SELECT value, expires_at FROM ? WHERE key = ?`),
47
+ set: this.db.prepare(`INSERT OR REPLACE INTO ? (key, value, expires_at) VALUES (?, ?, ?)`),
48
+ setex: this.db.prepare(`INSERT OR REPLACE INTO ? (key, value, expires_at) VALUES (?, ?, ?)`),
49
+ delete: this.db.prepare(`DELETE FROM ? WHERE key = ?`),
50
+ has: this.db.prepare(`SELECT COUNT(*) FROM ? WHERE key = ? AND (expires_at IS NULL OR expires_at > ?)`),
51
+ keys: this.db.prepare(`SELECT key FROM ? WHERE expires_at IS NULL OR expires_at > ?`),
52
+ values: this.db.prepare(`SELECT value FROM ? WHERE expires_at IS NULL OR expires_at > ?`),
53
+ clear: this.db.prepare(`DELETE FROM ?`),
54
+ count: this.db.prepare(`SELECT COUNT(*) FROM ? WHERE expires_at IS NULL OR expires_at > ?`),
55
+ all: this.db.prepare(`SELECT key, value FROM ? WHERE expires_at IS NULL OR expires_at > ?`),
56
+ expire: this.db.prepare(`UPDATE ? SET expires_at = ? WHERE key = ?`),
57
+ ttl: this.db.prepare(`SELECT expires_at FROM ? WHERE key = ?`),
58
+ namespaces: this.db.prepare(`SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'`),
59
+ begin: this.db.prepare(`BEGIN TRANSACTION`),
60
+ commit: this.db.prepare(`COMMIT`),
61
+ rollback: this.db.prepare(`ROLLBACK`)
62
+ };
63
+ }
64
+ /**
65
+ * Gets the current timestamp in milliseconds
66
+ */
67
+ getCurrentTime() {
68
+ return Date.now();
69
+ }
70
+ /**
71
+ * Checks if the database connection is open
72
+ *
73
+ * @returns `true` if the database is open, `false` otherwise
74
+ */
75
+ isOpen() {
76
+ return this.db.isOpen;
77
+ }
78
+ /**
79
+ * Gets the underlying SQLite database instance
80
+ *
81
+ * @returns The DatabaseSync instance
82
+ */
83
+ getDatabase() {
84
+ return this.db;
85
+ }
86
+ /**
87
+ * Closes the database connection
88
+ */
89
+ close() {
90
+ if (this.db.isOpen) this.db.close();
91
+ }
92
+ /**
93
+ * Disposable implementation - closes the database when disposed
94
+ */
95
+ [Symbol.dispose]() {
96
+ this.close();
97
+ }
98
+ /**
99
+ * AsyncDisposable implementation - closes the database when disposed
100
+ */
101
+ async [Symbol.asyncDispose]() {
102
+ this.close();
103
+ }
104
+ /**
105
+ * Retrieves a value by key
106
+ *
107
+ * @param key - The key to retrieve
108
+ * @returns The value associated with the key, or `undefined` if not found or expired
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const value = kv.get('my-key');
113
+ * if (value) {
114
+ * console.log('Found:', value);
115
+ * }
116
+ * ```
117
+ */
118
+ get(key) {
119
+ const result = this.statements.get.get(this.getCurrentNamespace(), key);
120
+ if (!result) return void 0;
121
+ if (result.expires_at && Number(result.expires_at) <= this.getCurrentTime()) {
122
+ this.delete(key);
123
+ return void 0;
124
+ }
125
+ return result.value;
126
+ }
127
+ /**
128
+ * Sets a key-value pair
129
+ *
130
+ * @param key - The key to set
131
+ * @param value - The value to associate with the key
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * kv.set('user:123', JSON.stringify({ name: 'John' }));
136
+ * kv.set('counter', '42');
137
+ * ```
138
+ */
139
+ set(key, value) {
140
+ this.statements.set.run(this.getCurrentNamespace(), key, value, null);
141
+ }
142
+ /**
143
+ * Sets a key-value pair with expiration
144
+ *
145
+ * @param key - The key to set
146
+ * @param value - The value to associate with the key
147
+ * @param ttl - Time to live in milliseconds
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * // Set with 1 hour expiration
152
+ * kv.setex('session:123', 'user_data', 60 * 60 * 1000);
153
+ *
154
+ * // Set with 5 minutes expiration
155
+ * kv.setex('temp:data', 'cached_value', 5 * 60 * 1000);
156
+ * ```
157
+ */
158
+ setex(key, value, ttl) {
159
+ const expiresAt = this.getCurrentTime() + ttl;
160
+ this.statements.setex.run(this.getCurrentNamespace(), key, value, expiresAt);
161
+ }
162
+ /**
163
+ * Sets expiration for an existing key
164
+ *
165
+ * @param key - The key to set expiration for
166
+ * @param ttl - Time to live in milliseconds
167
+ * @returns `true` if the key exists and expiration was set, `false` otherwise
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * kv.set('user:123', 'user_data');
172
+ *
173
+ * // Set 30 minute expiration
174
+ * if (kv.expire('user:123', 30 * 60 * 1000)) {
175
+ * console.log('Expiration set successfully');
176
+ * }
177
+ * ```
178
+ */
179
+ expire(key, ttl) {
180
+ if (!this.has(key)) return false;
181
+ const expiresAt = this.getCurrentTime() + ttl;
182
+ this.statements.expire.run(this.getCurrentNamespace(), expiresAt, key);
183
+ return true;
184
+ }
185
+ /**
186
+ * Gets the time to live for a key
187
+ *
188
+ * @param key - The key to check
189
+ * @returns Time to live in milliseconds, or `-1` if the key doesn't exist, or `-2` if the key has no expiration
190
+ *
191
+ * @example
192
+ * ```typescript
193
+ * const ttl = kv.ttl('user:123');
194
+ * if (ttl > 0) {
195
+ * console.log(`Key expires in ${ttl}ms`);
196
+ * } else if (ttl === -2) {
197
+ * console.log('Key has no expiration');
198
+ * } else {
199
+ * console.log('Key does not exist');
200
+ * }
201
+ * ```
202
+ */
203
+ ttl(key) {
204
+ const result = this.statements.ttl.get(this.getCurrentNamespace(), key);
205
+ if (!result) return -1;
206
+ if (!result.expires_at) return -2;
207
+ const remaining = Number(result.expires_at) - this.getCurrentTime();
208
+ return remaining > 0 ? remaining : -1;
209
+ }
210
+ /**
211
+ * Deletes a key-value pair
212
+ *
213
+ * @param key - The key to delete
214
+ *
215
+ * @example
216
+ * ```typescript
217
+ * kv.delete('user:123');
218
+ * ```
219
+ */
220
+ delete(key) {
221
+ this.statements.delete.run(this.getCurrentNamespace(), key);
222
+ }
223
+ /**
224
+ * Checks if a key exists and is not expired
225
+ *
226
+ * @param key - The key to check
227
+ * @returns `true` if the key exists and is not expired, `false` otherwise
228
+ *
229
+ * @example
230
+ * ```typescript
231
+ * if (kv.has('user:123')) {
232
+ * console.log('User exists and is not expired');
233
+ * }
234
+ * ```
235
+ */
236
+ has(key) {
237
+ const result = this.statements.has.get(this.getCurrentNamespace(), key, this.getCurrentTime());
238
+ return (result === null || result === void 0 ? void 0 : result.count) !== void 0 && result.count !== null && Number(result.count) > 0;
239
+ }
240
+ /**
241
+ * Gets all keys in the current namespace (excluding expired keys)
242
+ *
243
+ * @returns Array of all non-expired keys
244
+ *
245
+ * @example
246
+ * ```typescript
247
+ * const keys = kv.keys();
248
+ * console.log('All keys:', keys);
249
+ * ```
250
+ */
251
+ keys() {
252
+ const result = this.statements.keys.all(this.getCurrentNamespace(), this.getCurrentTime());
253
+ return result.map((row) => row.key);
254
+ }
255
+ /**
256
+ * Gets all values in the current namespace (excluding expired keys)
257
+ *
258
+ * @returns Array of all non-expired values
259
+ *
260
+ * @example
261
+ * ```typescript
262
+ * const values = kv.values();
263
+ * console.log('All values:', values);
264
+ * ```
265
+ */
266
+ values() {
267
+ const result = this.statements.values.all(this.getCurrentNamespace(), this.getCurrentTime());
268
+ return result.map((row) => row.value);
269
+ }
270
+ /**
271
+ * Gets the total number of key-value pairs in the current namespace (excluding expired keys)
272
+ *
273
+ * @returns The count of non-expired key-value pairs
274
+ *
275
+ * @example
276
+ * ```typescript
277
+ * const count = kv.count();
278
+ * console.log(`Total entries: ${count}`);
279
+ * ```
280
+ */
281
+ count() {
282
+ const result = this.statements.count.get(this.getCurrentNamespace(), this.getCurrentTime());
283
+ return Number((result === null || result === void 0 ? void 0 : result.count) ?? 0);
284
+ }
285
+ /**
286
+ * Removes all key-value pairs from the current namespace
287
+ *
288
+ * @example
289
+ * ```typescript
290
+ * kv.clear(); // Removes all entries in current namespace
291
+ * ```
292
+ */
293
+ clear() {
294
+ this.statements.clear.run(this.getCurrentNamespace());
295
+ }
296
+ /**
297
+ * Gets all key-value pairs as an object (excluding expired keys)
298
+ *
299
+ * @returns Object with all non-expired key-value pairs
300
+ *
301
+ * @example
302
+ * ```typescript
303
+ * const all = kv.all();
304
+ * console.log('All entries:', all);
305
+ * // Output: { 'key1': 'value1', 'key2': 'value2' }
306
+ * ```
307
+ */
308
+ all() {
309
+ const result = this.statements.all.all(this.getCurrentNamespace(), this.getCurrentTime());
310
+ return Object.fromEntries(result.map((row) => [row.key, row.value]));
311
+ }
312
+ /**
313
+ * Gets all available namespaces (tables) in the database
314
+ *
315
+ * @returns Array of namespace names
316
+ *
317
+ * @example
318
+ * ```typescript
319
+ * const namespaces = kv.namespaces();
320
+ * console.log('Available namespaces:', namespaces);
321
+ * ```
322
+ */
323
+ namespaces() {
324
+ const result = this.statements.namespaces.all();
325
+ return result.map((row) => row.name);
326
+ }
327
+ /**
328
+ * Gets the current namespace name
329
+ *
330
+ * @returns The current namespace string
331
+ */
332
+ getCurrentNamespace() {
333
+ return this.options.namespace ?? "commandkit_kv";
334
+ }
335
+ /**
336
+ * Creates a new KV instance with a different namespace
337
+ *
338
+ * @param namespace - The namespace to use for the new instance
339
+ * @returns A new KV instance with the specified namespace
340
+ *
341
+ * @example
342
+ * ```typescript
343
+ * const userKv = kv.namespace('users');
344
+ * const configKv = kv.namespace('config');
345
+ *
346
+ * userKv.set('123', 'John Doe');
347
+ * configKv.set('theme', 'dark');
348
+ * ```
349
+ */
350
+ namespace(namespace) {
351
+ return new KV(this.db, {
352
+ enableWAL: this.options.enableWAL,
353
+ namespace
354
+ });
355
+ }
356
+ /**
357
+ * Iterator implementation for iterating over all non-expired key-value pairs
358
+ *
359
+ * @returns Iterator yielding [key, value] tuples
360
+ *
361
+ * @example
362
+ * ```typescript
363
+ * for (const [key, value] of kv) {
364
+ * console.log(`${key}: ${value}`);
365
+ * }
366
+ *
367
+ * // Or using spread operator
368
+ * const entries = [...kv];
369
+ * ```
370
+ */
371
+ *[Symbol.iterator]() {
372
+ const result = this.statements.all.iterate(this.getCurrentNamespace(), this.getCurrentTime());
373
+ for (const row of result) yield [row.key, row.value];
374
+ }
375
+ /**
376
+ * Executes a function within a transaction
377
+ *
378
+ * @param fn - Function to execute within the transaction (can be async)
379
+ * @returns The result of the function
380
+ *
381
+ * @example
382
+ * ```typescript
383
+ * // Synchronous transaction
384
+ * kv.transaction(() => {
385
+ * kv.set('user:123', JSON.stringify({ name: 'John' }));
386
+ * kv.set('user:456', JSON.stringify({ name: 'Jane' }));
387
+ * // If any operation fails, all changes are rolled back
388
+ * });
389
+ *
390
+ * // Async transaction
391
+ * await kv.transaction(async () => {
392
+ * kv.set('user:123', JSON.stringify({ name: 'John' }));
393
+ * await someAsyncOperation();
394
+ * kv.set('user:456', JSON.stringify({ name: 'Jane' }));
395
+ * // If any operation fails, all changes are rolled back
396
+ * });
397
+ * ```
398
+ */
399
+ async transaction(fn) {
400
+ try {
401
+ this.statements.begin.run();
402
+ const result = await fn();
403
+ this.statements.commit.run();
404
+ return result;
405
+ } catch (error) {
406
+ this.statements.rollback.run();
407
+ throw error;
408
+ }
409
+ }
410
+ };
411
+ /**
412
+ * Opens a new KV instance
413
+ *
414
+ * @param path - Database file path, buffer, URL, or existing DatabaseSync instance
415
+ * @param options - Configuration options for the KV store
416
+ * @returns A new KV instance
417
+ */
418
+ function openKV(path = "commandkit_kv.db", options = {
419
+ enableWAL: true,
420
+ namespace: "commandkit_kv"
421
+ }) {
422
+ return new KV(path, options);
423
+ }
424
+
425
+ //#endregion
426
+ exports.KV = KV;
427
+ exports.openKV = openKV;
428
+ //# sourceMappingURL=kv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kv.js","names":[],"sources":["../../src/kv/kv.ts"],"sourcesContent":["import { DatabaseSync, StatementSync } from 'node:sqlite';\n\n/**\n * Configuration options for the KV store\n */\nexport interface KvOptions {\n /** Enable Write-Ahead Logging for better performance and durability */\n enableWAL?: boolean;\n /** Namespace for the key-value store table */\n namespace?: string;\n}\n\n/**\n * A key-value store implementation using SQLite\n *\n * This class provides a simple, persistent key-value storage solution\n * with support for namespaces, automatic cleanup, iteration, and expiration.\n *\n * @example\n * ```typescript\n * const kv = new KV('data.db');\n * kv.set('user:123', JSON.stringify({ name: 'John', age: 30 }));\n * const user = JSON.parse(kv.get('user:123') || '{}');\n *\n * // Using namespaces\n * const userKv = kv.namespace('users');\n * userKv.set('123', JSON.stringify({ name: 'John' }));\n * ```\n */\nexport class KV implements Disposable, AsyncDisposable {\n private db: DatabaseSync;\n private statements: Record<string, StatementSync> = {};\n\n /**\n * Creates a new KV store instance\n *\n * @param path - Database file path, buffer, URL, or existing DatabaseSync instance\n * @param options - Configuration options for the KV store\n */\n public constructor(\n path: string | Buffer | URL | DatabaseSync,\n private options: KvOptions = {\n enableWAL: true,\n namespace: 'commandkit_kv',\n },\n ) {\n this.db =\n path instanceof DatabaseSync\n ? path\n : new DatabaseSync(path, { open: true });\n\n if (options.enableWAL) {\n this.db.exec(/* sql */ `PRAGMA journal_mode = WAL;`);\n }\n\n this.db\n .prepare(\n /* sql */ `\n CREATE TABLE IF NOT EXISTS ? (\n key TEXT PRIMARY KEY,\n value TEXT,\n expires_at INTEGER\n )\n `,\n )\n .run(options.namespace ?? 'commandkit_kv');\n\n this.statements = {\n get: this.db.prepare(\n /* sql */ `SELECT value, expires_at FROM ? WHERE key = ?`,\n ),\n set: this.db.prepare(\n /* sql */ `INSERT OR REPLACE INTO ? (key, value, expires_at) VALUES (?, ?, ?)`,\n ),\n setex: this.db.prepare(\n /* sql */ `INSERT OR REPLACE INTO ? (key, value, expires_at) VALUES (?, ?, ?)`,\n ),\n delete: this.db.prepare(/* sql */ `DELETE FROM ? WHERE key = ?`),\n has: this.db.prepare(\n /* sql */ `SELECT COUNT(*) FROM ? WHERE key = ? AND (expires_at IS NULL OR expires_at > ?)`,\n ),\n keys: this.db.prepare(\n /* sql */ `SELECT key FROM ? WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n values: this.db.prepare(\n /* sql */ `SELECT value FROM ? WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n clear: this.db.prepare(/* sql */ `DELETE FROM ?`),\n count: this.db.prepare(\n /* sql */ `SELECT COUNT(*) FROM ? WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n all: this.db.prepare(\n /* sql */ `SELECT key, value FROM ? WHERE expires_at IS NULL OR expires_at > ?`,\n ),\n expire: this.db.prepare(\n /* sql */ `UPDATE ? SET expires_at = ? WHERE key = ?`,\n ),\n ttl: this.db.prepare(/* sql */ `SELECT expires_at FROM ? WHERE key = ?`),\n namespaces: this.db.prepare(\n /* sql */ `SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'`,\n ),\n begin: this.db.prepare(/* sql */ `BEGIN TRANSACTION`),\n commit: this.db.prepare(/* sql */ `COMMIT`),\n rollback: this.db.prepare(/* sql */ `ROLLBACK`),\n };\n }\n\n /**\n * Gets the current timestamp in milliseconds\n */\n private getCurrentTime(): number {\n return Date.now();\n }\n\n /**\n * Checks if the database connection is open\n *\n * @returns `true` if the database is open, `false` otherwise\n */\n public isOpen(): boolean {\n return this.db.isOpen;\n }\n\n /**\n * Gets the underlying SQLite database instance\n *\n * @returns The DatabaseSync instance\n */\n public getDatabase(): DatabaseSync {\n return this.db;\n }\n\n /**\n * Closes the database connection\n */\n public close(): void {\n if (this.db.isOpen) this.db.close();\n }\n\n /**\n * Disposable implementation - closes the database when disposed\n */\n public [Symbol.dispose]() {\n this.close();\n }\n\n /**\n * AsyncDisposable implementation - closes the database when disposed\n */\n public async [Symbol.asyncDispose]() {\n this.close();\n }\n\n /**\n * Retrieves a value by key\n *\n * @param key - The key to retrieve\n * @returns The value associated with the key, or `undefined` if not found or expired\n *\n * @example\n * ```typescript\n * const value = kv.get('my-key');\n * if (value) {\n * console.log('Found:', value);\n * }\n * ```\n */\n public get(key: string): string | undefined {\n const result = this.statements.get.get(this.getCurrentNamespace(), key);\n\n if (!result) return undefined;\n\n // Check if the key has expired\n if (\n result.expires_at &&\n Number(result.expires_at) <= this.getCurrentTime()\n ) {\n this.delete(key);\n return undefined;\n }\n\n return result.value as string;\n }\n\n /**\n * Sets a key-value pair\n *\n * @param key - The key to set\n * @param value - The value to associate with the key\n *\n * @example\n * ```typescript\n * kv.set('user:123', JSON.stringify({ name: 'John' }));\n * kv.set('counter', '42');\n * ```\n */\n public set(key: string, value: string): void {\n this.statements.set.run(this.getCurrentNamespace(), key, value, null);\n }\n\n /**\n * Sets a key-value pair with expiration\n *\n * @param key - The key to set\n * @param value - The value to associate with the key\n * @param ttl - Time to live in milliseconds\n *\n * @example\n * ```typescript\n * // Set with 1 hour expiration\n * kv.setex('session:123', 'user_data', 60 * 60 * 1000);\n *\n * // Set with 5 minutes expiration\n * kv.setex('temp:data', 'cached_value', 5 * 60 * 1000);\n * ```\n */\n public setex(key: string, value: string, ttl: number): void {\n const expiresAt = this.getCurrentTime() + ttl;\n this.statements.setex.run(\n this.getCurrentNamespace(),\n key,\n value,\n expiresAt,\n );\n }\n\n /**\n * Sets expiration for an existing key\n *\n * @param key - The key to set expiration for\n * @param ttl - Time to live in milliseconds\n * @returns `true` if the key exists and expiration was set, `false` otherwise\n *\n * @example\n * ```typescript\n * kv.set('user:123', 'user_data');\n *\n * // Set 30 minute expiration\n * if (kv.expire('user:123', 30 * 60 * 1000)) {\n * console.log('Expiration set successfully');\n * }\n * ```\n */\n public expire(key: string, ttl: number): boolean {\n if (!this.has(key)) return false;\n\n const expiresAt = this.getCurrentTime() + ttl;\n this.statements.expire.run(this.getCurrentNamespace(), expiresAt, key);\n return true;\n }\n\n /**\n * Gets the time to live for a key\n *\n * @param key - The key to check\n * @returns Time to live in milliseconds, or `-1` if the key doesn't exist, or `-2` if the key has no expiration\n *\n * @example\n * ```typescript\n * const ttl = kv.ttl('user:123');\n * if (ttl > 0) {\n * console.log(`Key expires in ${ttl}ms`);\n * } else if (ttl === -2) {\n * console.log('Key has no expiration');\n * } else {\n * console.log('Key does not exist');\n * }\n * ```\n */\n public ttl(key: string): number {\n const result = this.statements.ttl.get(this.getCurrentNamespace(), key);\n\n if (!result) return -1; // Key doesn't exist\n\n if (!result.expires_at) return -2; // No expiration\n\n const remaining = Number(result.expires_at) - this.getCurrentTime();\n return remaining > 0 ? remaining : -1; // Expired or doesn't exist\n }\n\n /**\n * Deletes a key-value pair\n *\n * @param key - The key to delete\n *\n * @example\n * ```typescript\n * kv.delete('user:123');\n * ```\n */\n public delete(key: string): void {\n this.statements.delete.run(this.getCurrentNamespace(), key);\n }\n\n /**\n * Checks if a key exists and is not expired\n *\n * @param key - The key to check\n * @returns `true` if the key exists and is not expired, `false` otherwise\n *\n * @example\n * ```typescript\n * if (kv.has('user:123')) {\n * console.log('User exists and is not expired');\n * }\n * ```\n */\n public has(key: string): boolean {\n const result = this.statements.has.get(\n this.getCurrentNamespace(),\n key,\n this.getCurrentTime(),\n );\n\n return (\n result?.count !== undefined &&\n result.count !== null &&\n Number(result.count) > 0\n );\n }\n\n /**\n * Gets all keys in the current namespace (excluding expired keys)\n *\n * @returns Array of all non-expired keys\n *\n * @example\n * ```typescript\n * const keys = kv.keys();\n * console.log('All keys:', keys);\n * ```\n */\n public keys(): string[] {\n const result = this.statements.keys.all(\n this.getCurrentNamespace(),\n this.getCurrentTime(),\n );\n\n return result.map((row) => row.key as string);\n }\n\n /**\n * Gets all values in the current namespace (excluding expired keys)\n *\n * @returns Array of all non-expired values\n *\n * @example\n * ```typescript\n * const values = kv.values();\n * console.log('All values:', values);\n * ```\n */\n public values(): string[] {\n const result = this.statements.values.all(\n this.getCurrentNamespace(),\n this.getCurrentTime(),\n );\n\n return result.map((row) => row.value as string);\n }\n\n /**\n * Gets the total number of key-value pairs in the current namespace (excluding expired keys)\n *\n * @returns The count of non-expired key-value pairs\n *\n * @example\n * ```typescript\n * const count = kv.count();\n * console.log(`Total entries: ${count}`);\n * ```\n */\n public count(): number {\n const result = this.statements.count.get(\n this.getCurrentNamespace(),\n this.getCurrentTime(),\n );\n\n return Number(result?.count ?? 0);\n }\n\n /**\n * Removes all key-value pairs from the current namespace\n *\n * @example\n * ```typescript\n * kv.clear(); // Removes all entries in current namespace\n * ```\n */\n public clear(): void {\n this.statements.clear.run(this.getCurrentNamespace());\n }\n\n /**\n * Gets all key-value pairs as an object (excluding expired keys)\n *\n * @returns Object with all non-expired key-value pairs\n *\n * @example\n * ```typescript\n * const all = kv.all();\n * console.log('All entries:', all);\n * // Output: { 'key1': 'value1', 'key2': 'value2' }\n * ```\n */\n public all(): Record<string, string> {\n const result = this.statements.all.all(\n this.getCurrentNamespace(),\n this.getCurrentTime(),\n );\n\n return Object.fromEntries(\n result.map((row) => [row.key as string, row.value as string]),\n );\n }\n\n /**\n * Gets all available namespaces (tables) in the database\n *\n * @returns Array of namespace names\n *\n * @example\n * ```typescript\n * const namespaces = kv.namespaces();\n * console.log('Available namespaces:', namespaces);\n * ```\n */\n public namespaces(): string[] {\n const result = this.statements.namespaces.all();\n\n return result.map((row) => row.name as string);\n }\n\n /**\n * Gets the current namespace name\n *\n * @returns The current namespace string\n */\n public getCurrentNamespace(): string {\n return this.options.namespace ?? 'commandkit_kv';\n }\n\n /**\n * Creates a new KV instance with a different namespace\n *\n * @param namespace - The namespace to use for the new instance\n * @returns A new KV instance with the specified namespace\n *\n * @example\n * ```typescript\n * const userKv = kv.namespace('users');\n * const configKv = kv.namespace('config');\n *\n * userKv.set('123', 'John Doe');\n * configKv.set('theme', 'dark');\n * ```\n */\n public namespace(namespace: string): KV {\n return new KV(this.db, {\n enableWAL: this.options.enableWAL,\n namespace,\n });\n }\n\n /**\n * Iterator implementation for iterating over all non-expired key-value pairs\n *\n * @returns Iterator yielding [key, value] tuples\n *\n * @example\n * ```typescript\n * for (const [key, value] of kv) {\n * console.log(`${key}: ${value}`);\n * }\n *\n * // Or using spread operator\n * const entries = [...kv];\n * ```\n */\n public *[Symbol.iterator](): Iterator<[string, string]> {\n const result = this.statements.all.iterate(\n this.getCurrentNamespace(),\n this.getCurrentTime(),\n );\n\n for (const row of result) {\n yield [row.key as string, row.value as string];\n }\n }\n\n /**\n * Executes a function within a transaction\n *\n * @param fn - Function to execute within the transaction (can be async)\n * @returns The result of the function\n *\n * @example\n * ```typescript\n * // Synchronous transaction\n * kv.transaction(() => {\n * kv.set('user:123', JSON.stringify({ name: 'John' }));\n * kv.set('user:456', JSON.stringify({ name: 'Jane' }));\n * // If any operation fails, all changes are rolled back\n * });\n *\n * // Async transaction\n * await kv.transaction(async () => {\n * kv.set('user:123', JSON.stringify({ name: 'John' }));\n * await someAsyncOperation();\n * kv.set('user:456', JSON.stringify({ name: 'Jane' }));\n * // If any operation fails, all changes are rolled back\n * });\n * ```\n */\n public async transaction<T>(fn: () => T | Promise<T>): Promise<T> {\n try {\n // Begin transaction\n this.statements.begin.run();\n\n // Execute the function\n const result = await fn();\n\n // Commit transaction\n this.statements.commit.run();\n\n return result;\n } catch (error) {\n // Rollback transaction on error\n this.statements.rollback.run();\n throw error;\n }\n }\n}\n\n/**\n * Opens a new KV instance\n *\n * @param path - Database file path, buffer, URL, or existing DatabaseSync instance\n * @param options - Configuration options for the KV store\n * @returns A new KV instance\n */\nexport function openKV(\n path: string | Buffer | URL | DatabaseSync = 'commandkit_kv.db',\n options: KvOptions = { enableWAL: true, namespace: 'commandkit_kv' },\n): KV {\n return new KV(path, options);\n}\n"],"mappings":"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"}
@@ -6,7 +6,7 @@
6
6
  /**
7
7
  * The current version of CommandKit.
8
8
  */
9
- const version = "1.0.0-dev.20250702022547";
9
+ const version = "1.0.0-dev.20250702125326";
10
10
 
11
11
  //#endregion
12
12
  Object.defineProperty(exports, 'version', {
@@ -15,4 +15,4 @@ Object.defineProperty(exports, 'version', {
15
15
  return version;
16
16
  }
17
17
  });
18
- //# sourceMappingURL=version-CHYJXFOa.js.map
18
+ //# sourceMappingURL=version-DvvD35ov.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version-CHYJXFOa.js","names":[],"sources":["../src/version.ts"],"sourcesContent":["/**\n * @private\n */\nfunction $version(): string {\n 'use macro';\n return require('../package.json').version;\n}\n\n/**\n * The current version of CommandKit.\n */\nexport const version: string = $version();\n"],"mappings":";;;;;;;;AAWA,MAAa,UAA4B"}
1
+ {"version":3,"file":"version-DvvD35ov.js","names":[],"sources":["../src/version.ts"],"sourcesContent":["/**\n * @private\n */\nfunction $version(): string {\n 'use macro';\n return require('../package.json').version;\n}\n\n/**\n * The current version of CommandKit.\n */\nexport const version: string = $version();\n"],"mappings":";;;;;;;;AAWA,MAAa,UAA4B"}
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
- const require_version = require('./version-CHYJXFOa.js');
1
+ const require_version = require('./version-DvvD35ov.js');
2
2
 
3
3
  exports.version = require_version.version;
package/kv.cjs ADDED
@@ -0,0 +1,6 @@
1
+ const { KV, openKV } = require('./dist/kv/kv.js');
2
+
3
+ module.exports = {
4
+ KV,
5
+ openKV,
6
+ };
package/kv.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './dist/kv/kv';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "commandkit",
3
3
  "description": "Beginner friendly command & event handler for Discord.js",
4
- "version": "1.0.0-dev.20250702022547",
4
+ "version": "1.0.0-dev.20250702125326",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
7
7
  "main": "./dist/index.js",
@@ -44,7 +44,9 @@
44
44
  "./semaphore.cjs",
45
45
  "./semaphore.d.ts",
46
46
  "./mutex.cjs",
47
- "./mutex.d.ts"
47
+ "./mutex.d.ts",
48
+ "./kv.cjs",
49
+ "./kv.d.ts"
48
50
  ],
49
51
  "exports": {
50
52
  ".": {
@@ -136,6 +138,11 @@
136
138
  "require": "./mutex.cjs",
137
139
  "import": "./mutex.cjs",
138
140
  "types": "./mutex.d.ts"
141
+ },
142
+ "./kv": {
143
+ "require": "./kv.cjs",
144
+ "import": "./kv.cjs",
145
+ "types": "./kv.d.ts"
139
146
  }
140
147
  },
141
148
  "repository": {
@@ -171,7 +178,7 @@
171
178
  "tsx": "^4.19.2",
172
179
  "typescript": "^5.7.3",
173
180
  "vitest": "^3.0.5",
174
- "tsconfig": "0.0.0-dev.20250702022547"
181
+ "tsconfig": "0.0.0-dev.20250702125326"
175
182
  },
176
183
  "peerDependencies": {
177
184
  "discord.js": "^14"