@shetty4l/core 0.1.14 → 0.1.15
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.
- package/package.json +2 -1
- package/src/db.ts +107 -0
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shetty4l/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"description": "Shared infrastructure primitives for Bun/TypeScript services",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"./signals": "./src/signals.ts",
|
|
17
17
|
"./cli": "./src/cli.ts",
|
|
18
18
|
"./daemon": "./src/daemon.ts",
|
|
19
|
+
"./db": "./src/db.ts",
|
|
19
20
|
"./http": "./src/http.ts"
|
|
20
21
|
},
|
|
21
22
|
"files": [
|
package/src/db.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite database lifecycle management.
|
|
3
|
+
*
|
|
4
|
+
* Provides a minimal singleton wrapper around bun:sqlite Database
|
|
5
|
+
* with automatic directory creation, WAL mode, schema execution,
|
|
6
|
+
* and optional migration callback.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { Database } from "bun:sqlite";
|
|
10
|
+
import { existsSync, mkdirSync } from "fs";
|
|
11
|
+
import { dirname } from "path";
|
|
12
|
+
|
|
13
|
+
export interface DatabaseOpts {
|
|
14
|
+
/** Path to SQLite database file. Use ":memory:" for in-memory databases. */
|
|
15
|
+
path: string;
|
|
16
|
+
/** SQL to execute after opening (e.g. CREATE TABLE IF NOT EXISTS statements). */
|
|
17
|
+
schema?: string;
|
|
18
|
+
/** Optional callback for migrations after schema execution. */
|
|
19
|
+
migrate?: (db: Database) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface DatabaseManager {
|
|
23
|
+
/** Get the database instance. Throws if not initialized. */
|
|
24
|
+
db(): Database;
|
|
25
|
+
/** Initialize the database. Idempotent — returns existing instance if already open. */
|
|
26
|
+
init(pathOverride?: string): Database;
|
|
27
|
+
/** Close the database connection and clear the singleton. */
|
|
28
|
+
close(): void;
|
|
29
|
+
/** Clear the singleton reference without closing (for tests). */
|
|
30
|
+
reset(): void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Create a database manager with singleton lifecycle.
|
|
35
|
+
*
|
|
36
|
+
* Usage:
|
|
37
|
+
* ```ts
|
|
38
|
+
* const manager = createDatabaseManager({
|
|
39
|
+
* path: "~/.local/share/myapp/data.db",
|
|
40
|
+
* schema: "CREATE TABLE IF NOT EXISTS items (id TEXT PRIMARY KEY)",
|
|
41
|
+
* migrate: (db) => { ... },
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* manager.init(); // open + schema + migrate
|
|
45
|
+
* const db = manager.db(); // get the instance
|
|
46
|
+
* manager.close(); // cleanup
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function createDatabaseManager(opts: DatabaseOpts): DatabaseManager {
|
|
50
|
+
let instance: Database | null = null;
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
db(): Database {
|
|
54
|
+
if (!instance) {
|
|
55
|
+
throw new Error("Database not initialized. Call init() first.");
|
|
56
|
+
}
|
|
57
|
+
return instance;
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
init(pathOverride?: string): Database {
|
|
61
|
+
if (instance) {
|
|
62
|
+
return instance;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const path = pathOverride ?? opts.path;
|
|
66
|
+
|
|
67
|
+
// Ensure parent directory exists for file-based databases
|
|
68
|
+
if (path !== ":memory:") {
|
|
69
|
+
const dir = dirname(path);
|
|
70
|
+
if (!existsSync(dir)) {
|
|
71
|
+
mkdirSync(dir, { recursive: true });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const db = new Database(path);
|
|
76
|
+
|
|
77
|
+
// Enable WAL mode for better concurrent access (not applicable to :memory:)
|
|
78
|
+
if (path !== ":memory:") {
|
|
79
|
+
db.exec("PRAGMA journal_mode = WAL;");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Execute schema SQL
|
|
83
|
+
if (opts.schema) {
|
|
84
|
+
db.exec(opts.schema);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Run migrations
|
|
88
|
+
if (opts.migrate) {
|
|
89
|
+
opts.migrate(db);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
instance = db;
|
|
93
|
+
return db;
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
close(): void {
|
|
97
|
+
if (instance) {
|
|
98
|
+
instance.close();
|
|
99
|
+
instance = null;
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
reset(): void {
|
|
104
|
+
instance = null;
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ export * as cli from "./cli";
|
|
|
12
12
|
// Domain modules — exported as namespaces
|
|
13
13
|
export * as config from "./config";
|
|
14
14
|
export * as daemon from "./daemon";
|
|
15
|
+
export * as db from "./db";
|
|
15
16
|
export * as http from "./http";
|
|
16
17
|
export type { Err, Ok, Port, Result } from "./result";
|
|
17
18
|
export { err, ok } from "./result";
|