@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.
Files changed (3) hide show
  1. package/package.json +2 -1
  2. package/src/db.ts +107 -0
  3. 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.14",
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";