@vibesdotdev/localdb 0.0.1

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 (130) hide show
  1. package/README.md +121 -0
  2. package/SPEC.md +119 -0
  3. package/dist/cli/commands/_shared.consumer.d.ts +5 -0
  4. package/dist/cli/commands/_shared.consumer.d.ts.map +1 -0
  5. package/dist/cli/commands/_shared.consumer.js +17 -0
  6. package/dist/cli/commands/_shared.consumer.js.map +1 -0
  7. package/dist/cli/commands/migrate/dev.localdb.migrate.cli-command.descriptor.d.ts +19 -0
  8. package/dist/cli/commands/migrate/dev.localdb.migrate.cli-command.descriptor.d.ts.map +1 -0
  9. package/dist/cli/commands/migrate/dev.localdb.migrate.cli-command.descriptor.js +19 -0
  10. package/dist/cli/commands/migrate/dev.localdb.migrate.cli-command.descriptor.js.map +1 -0
  11. package/dist/cli/commands/migrate/dev.localdb.migrate.cli-command.impl.consumer.d.ts +5 -0
  12. package/dist/cli/commands/migrate/dev.localdb.migrate.cli-command.impl.consumer.d.ts.map +1 -0
  13. package/dist/cli/commands/migrate/dev.localdb.migrate.cli-command.impl.consumer.js +80 -0
  14. package/dist/cli/commands/migrate/dev.localdb.migrate.cli-command.impl.consumer.js.map +1 -0
  15. package/dist/cli/commands/namespaces/dev.localdb.namespaces.cli-command.descriptor.d.ts +19 -0
  16. package/dist/cli/commands/namespaces/dev.localdb.namespaces.cli-command.descriptor.d.ts.map +1 -0
  17. package/dist/cli/commands/namespaces/dev.localdb.namespaces.cli-command.descriptor.js +16 -0
  18. package/dist/cli/commands/namespaces/dev.localdb.namespaces.cli-command.descriptor.js.map +1 -0
  19. package/dist/cli/commands/namespaces/dev.localdb.namespaces.cli-command.impl.d.ts +5 -0
  20. package/dist/cli/commands/namespaces/dev.localdb.namespaces.cli-command.impl.d.ts.map +1 -0
  21. package/dist/cli/commands/namespaces/dev.localdb.namespaces.cli-command.impl.js +33 -0
  22. package/dist/cli/commands/namespaces/dev.localdb.namespaces.cli-command.impl.js.map +1 -0
  23. package/dist/cli/commands/pools/dev.localdb.pools.cli-command.descriptor.d.ts +15 -0
  24. package/dist/cli/commands/pools/dev.localdb.pools.cli-command.descriptor.d.ts.map +1 -0
  25. package/dist/cli/commands/pools/dev.localdb.pools.cli-command.descriptor.js +15 -0
  26. package/dist/cli/commands/pools/dev.localdb.pools.cli-command.descriptor.js.map +1 -0
  27. package/dist/cli/commands/pools/dev.localdb.pools.cli-command.impl.d.ts +5 -0
  28. package/dist/cli/commands/pools/dev.localdb.pools.cli-command.impl.d.ts.map +1 -0
  29. package/dist/cli/commands/pools/dev.localdb.pools.cli-command.impl.js +28 -0
  30. package/dist/cli/commands/pools/dev.localdb.pools.cli-command.impl.js.map +1 -0
  31. package/dist/cli/commands/query/dev.localdb.query.cli-command.descriptor.d.ts +24 -0
  32. package/dist/cli/commands/query/dev.localdb.query.cli-command.descriptor.d.ts.map +1 -0
  33. package/dist/cli/commands/query/dev.localdb.query.cli-command.descriptor.js +20 -0
  34. package/dist/cli/commands/query/dev.localdb.query.cli-command.descriptor.js.map +1 -0
  35. package/dist/cli/commands/query/dev.localdb.query.cli-command.impl.consumer.d.ts +5 -0
  36. package/dist/cli/commands/query/dev.localdb.query.cli-command.impl.consumer.d.ts.map +1 -0
  37. package/dist/cli/commands/query/dev.localdb.query.cli-command.impl.consumer.js +63 -0
  38. package/dist/cli/commands/query/dev.localdb.query.cli-command.impl.consumer.js.map +1 -0
  39. package/dist/cli/commands/status/dev.localdb.status.cli-command.descriptor.d.ts +19 -0
  40. package/dist/cli/commands/status/dev.localdb.status.cli-command.descriptor.d.ts.map +1 -0
  41. package/dist/cli/commands/status/dev.localdb.status.cli-command.descriptor.js +19 -0
  42. package/dist/cli/commands/status/dev.localdb.status.cli-command.descriptor.js.map +1 -0
  43. package/dist/cli/commands/status/dev.localdb.status.cli-command.impl.consumer.d.ts +5 -0
  44. package/dist/cli/commands/status/dev.localdb.status.cli-command.impl.consumer.d.ts.map +1 -0
  45. package/dist/cli/commands/status/dev.localdb.status.cli-command.impl.consumer.js +73 -0
  46. package/dist/cli/commands/status/dev.localdb.status.cli-command.impl.consumer.js.map +1 -0
  47. package/dist/core/connection-pool.d.ts +84 -0
  48. package/dist/core/connection-pool.d.ts.map +1 -0
  49. package/dist/core/connection-pool.js +191 -0
  50. package/dist/core/connection-pool.js.map +1 -0
  51. package/dist/core/database.d.ts +137 -0
  52. package/dist/core/database.d.ts.map +1 -0
  53. package/dist/core/database.js +347 -0
  54. package/dist/core/database.js.map +1 -0
  55. package/dist/core/error-context.d.ts +2 -0
  56. package/dist/core/error-context.d.ts.map +1 -0
  57. package/dist/core/error-context.js +17 -0
  58. package/dist/core/error-context.js.map +1 -0
  59. package/dist/core/migration-registry.d.ts +89 -0
  60. package/dist/core/migration-registry.d.ts.map +1 -0
  61. package/dist/core/migration-registry.js +226 -0
  62. package/dist/core/migration-registry.js.map +1 -0
  63. package/dist/core/runtime.d.ts +3 -0
  64. package/dist/core/runtime.d.ts.map +1 -0
  65. package/dist/core/runtime.js +17 -0
  66. package/dist/core/runtime.js.map +1 -0
  67. package/dist/dev.localdb.cli-group.descriptor.d.ts +9 -0
  68. package/dist/dev.localdb.cli-group.descriptor.d.ts.map +1 -0
  69. package/dist/dev.localdb.cli-group.descriptor.js +17 -0
  70. package/dist/dev.localdb.cli-group.descriptor.js.map +1 -0
  71. package/dist/dev.localdb.context.descriptor.d.ts +21 -0
  72. package/dist/dev.localdb.context.descriptor.d.ts.map +1 -0
  73. package/dist/dev.localdb.context.descriptor.js +12 -0
  74. package/dist/dev.localdb.context.descriptor.js.map +1 -0
  75. package/dist/dev.localdb.context.impl.consumer.d.ts +9 -0
  76. package/dist/dev.localdb.context.impl.consumer.d.ts.map +1 -0
  77. package/dist/dev.localdb.context.impl.consumer.js +10 -0
  78. package/dist/dev.localdb.context.impl.consumer.js.map +1 -0
  79. package/dist/index.d.ts +12 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +11 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/localdb.cloud.plugin.d.ts +17 -0
  84. package/dist/localdb.cloud.plugin.d.ts.map +1 -0
  85. package/dist/localdb.cloud.plugin.js +23 -0
  86. package/dist/localdb.cloud.plugin.js.map +1 -0
  87. package/dist/localdb.plugin.d.ts +8 -0
  88. package/dist/localdb.plugin.d.ts.map +1 -0
  89. package/dist/localdb.plugin.js +38 -0
  90. package/dist/localdb.plugin.js.map +1 -0
  91. package/dist/migrations/load-sql.d.ts +45 -0
  92. package/dist/migrations/load-sql.d.ts.map +1 -0
  93. package/dist/migrations/load-sql.js +117 -0
  94. package/dist/migrations/load-sql.js.map +1 -0
  95. package/dist/schemas/api.d.ts +82 -0
  96. package/dist/schemas/api.d.ts.map +1 -0
  97. package/dist/schemas/api.js +2 -0
  98. package/dist/schemas/api.js.map +1 -0
  99. package/package.json +146 -0
  100. package/src/cli/commands/_shared.consumer.ts +20 -0
  101. package/src/cli/commands/migrate/dev.localdb.migrate.cli-command.descriptor.ts +20 -0
  102. package/src/cli/commands/migrate/dev.localdb.migrate.cli-command.impl.consumer.ts +97 -0
  103. package/src/cli/commands/namespaces/dev.localdb.namespaces.cli-command.descriptor.ts +17 -0
  104. package/src/cli/commands/namespaces/dev.localdb.namespaces.cli-command.impl.ts +46 -0
  105. package/src/cli/commands/pools/dev.localdb.pools.cli-command.descriptor.ts +16 -0
  106. package/src/cli/commands/pools/dev.localdb.pools.cli-command.impl.ts +37 -0
  107. package/src/cli/commands/query/dev.localdb.query.cli-command.descriptor.ts +21 -0
  108. package/src/cli/commands/query/dev.localdb.query.cli-command.impl.consumer.ts +69 -0
  109. package/src/cli/commands/status/dev.localdb.status.cli-command.descriptor.ts +20 -0
  110. package/src/cli/commands/status/dev.localdb.status.cli-command.impl.consumer.ts +93 -0
  111. package/src/core/connection-pool.ts +240 -0
  112. package/src/core/database.ts +419 -0
  113. package/src/core/error-context.ts +19 -0
  114. package/src/core/migration-registry.ts +321 -0
  115. package/src/core/runtime.ts +17 -0
  116. package/src/dev.localdb.cli-group.descriptor.ts +20 -0
  117. package/src/dev.localdb.context.descriptor.ts +13 -0
  118. package/src/dev.localdb.context.impl.consumer.ts +12 -0
  119. package/src/index.ts +28 -0
  120. package/src/localdb.cloud.plugin.ts +24 -0
  121. package/src/localdb.plugin.ts +43 -0
  122. package/src/migrations/atlas/001-initial-schema.sql +173 -0
  123. package/src/migrations/atlas/002-lang-server-fields.sql +12 -0
  124. package/src/migrations/atlas/003-config-id-dedup.sql +31 -0
  125. package/src/migrations/atlas/004-fix-on-conflict-constraints.sql +25 -0
  126. package/src/migrations/atlas/005-diagnostics.sql +66 -0
  127. package/src/migrations/atlas/006-diagnostic-summaries.sql +65 -0
  128. package/src/migrations/atlas/007-diagnostic-slice.sql +83 -0
  129. package/src/migrations/load-sql.ts +133 -0
  130. package/src/schemas/api.ts +92 -0
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Local Database Manager
3
+ *
4
+ * High-level API for managing local SQLite databases in vibes dev.
5
+ * Provides connection pooling, migration management, and consistent configuration.
6
+ *
7
+ * Usage:
8
+ * const db = localdb.getDatabase('atlas', '.vibes/atlas/project.db');
9
+ * // db is ready to use with WAL mode, busy timeout, and migrations applied
10
+ */
11
+ import { Database } from 'bun:sqlite';
12
+ import { type Migration } from './migration-registry.ts';
13
+ export interface DatabaseOptions {
14
+ /** Namespace for migrations (e.g., 'atlas', 'session') */
15
+ namespace: string;
16
+ /** Path to database file */
17
+ dbPath: string;
18
+ /** Consumer identifier for debugging */
19
+ consumer?: string;
20
+ /** Skip migration check/run on initialization */
21
+ skipMigrations?: boolean;
22
+ /** Use connection pool (default: true) */
23
+ usePool?: boolean;
24
+ }
25
+ export declare class LocalDatabase {
26
+ private db;
27
+ private options;
28
+ private initialized;
29
+ constructor(options: DatabaseOptions);
30
+ /**
31
+ * Initialize the database connection
32
+ * - Creates directory if needed
33
+ * - Gets/creates pooled connection
34
+ * - Runs pending migrations
35
+ */
36
+ initialize(): Promise<void>;
37
+ /**
38
+ * Establish initial connection
39
+ */
40
+ private establishConnection;
41
+ /**
42
+ * Perform recovery from migration failure
43
+ * 1. Close connection
44
+ * 2. Backup corrupted DB
45
+ * 3. Delete corrupted DB
46
+ * 4. Re-initialize fresh DB
47
+ * 5. Re-run migrations
48
+ */
49
+ private performRecovery;
50
+ private pruneBackupFiles;
51
+ /**
52
+ * Configure database with optimal settings (for non-pooled connections)
53
+ */
54
+ private configureDatabase;
55
+ /**
56
+ * Get the underlying Database instance
57
+ */
58
+ getDatabase(): Database;
59
+ /**
60
+ * Close the database connection
61
+ */
62
+ close(): void;
63
+ /**
64
+ * Check if database is healthy
65
+ */
66
+ healthCheck(): boolean;
67
+ /**
68
+ * Get migration status for this database
69
+ */
70
+ getMigrationStatus(): {
71
+ namespace: string;
72
+ currentVersion: number;
73
+ targetVersion: number;
74
+ pendingMigrations: number;
75
+ migrations: Array<{
76
+ version: number;
77
+ name: string;
78
+ applied: boolean;
79
+ }>;
80
+ };
81
+ }
82
+ /**
83
+ * LocalDB Manager
84
+ * Main entry point for accessing local databases
85
+ */
86
+ declare class LocalDBManager {
87
+ private databases;
88
+ private dbPathLocks;
89
+ private withDbPathLock;
90
+ /**
91
+ * Register migrations for a namespace
92
+ * Must be called before getDatabase() for that namespace
93
+ */
94
+ registerMigrations(namespace: string, migrations: Migration[]): void;
95
+ /**
96
+ * Get or create a database instance
97
+ *
98
+ * @param namespace Migration namespace (e.g., 'atlas', 'session')
99
+ * @param dbPath Path to database file
100
+ * @param consumer Consumer identifier for debugging
101
+ * @returns Initialized database instance
102
+ */
103
+ getDatabase(namespace: string, dbPath: string, consumer?: string): Promise<LocalDatabase>;
104
+ /**
105
+ * Get a raw Database instance (auto-configured with WAL, etc.)
106
+ * For when you don't need migration management
107
+ */
108
+ getRawDatabase(dbPath: string, consumer?: string): Database;
109
+ /**
110
+ * Release a database instance
111
+ */
112
+ releaseDatabase(namespace: string, dbPath: string): Promise<void>;
113
+ /**
114
+ * Get connection pool statistics
115
+ */
116
+ getPoolStats(): import("./connection-pool.ts").ConnectionStats;
117
+ /**
118
+ * Get migration registry status
119
+ */
120
+ getMigrationStatus(): {
121
+ namespace: string;
122
+ currentVersion: number;
123
+ targetVersion: number;
124
+ pendingMigrations: number;
125
+ }[];
126
+ /**
127
+ * List all registered migration namespaces
128
+ */
129
+ listNamespaces(): string[];
130
+ /**
131
+ * Close all database connections
132
+ */
133
+ closeAll(): Promise<void>;
134
+ }
135
+ export declare const localdb: LocalDBManager;
136
+ export {};
137
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/core/database.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAqB5E,MAAM,WAAW,eAAe;IAC/B,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAElB,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IAEf,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,iDAAiD;IACjD,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAWD,qBAAa,aAAa;IACzB,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,EAAE,eAAe;IASpC;;;;;OAKG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAqCjC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;;;;;;OAOG;YACW,eAAe;YA4Df,gBAAgB;IAoB9B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;OAEG;IACH,WAAW,IAAI,QAAQ;IAOvB;;OAEG;IACH,KAAK,IAAI,IAAI;IAcb;;OAEG;IACH,WAAW,IAAI,OAAO;IAWtB;;OAEG;IACH,kBAAkB;;;;;;;;;;;CAOlB;AAED;;;GAGG;AACH,cAAM,cAAc;IACnB,OAAO,CAAC,SAAS,CAMb;IACJ,OAAO,CAAC,WAAW,CAAoC;YAEzC,cAAc;IAmB5B;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI;IAIpE;;;;;;;OAOG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA2BzF;;;OAGG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAQ,GAAG,QAAQ;IAI1D;;OAEG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcvE;;OAEG;IACH,YAAY;IAIZ;;OAEG;IACH,kBAAkB;;;;;;IAIlB;;OAEG;IACH,cAAc,IAAI,MAAM,EAAE;IAI1B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAO/B;AAGD,eAAO,MAAM,OAAO,gBAAuB,CAAC"}
@@ -0,0 +1,347 @@
1
+ /**
2
+ * Local Database Manager
3
+ *
4
+ * High-level API for managing local SQLite databases in vibes dev.
5
+ * Provides connection pooling, migration management, and consistent configuration.
6
+ *
7
+ * Usage:
8
+ * const db = localdb.getDatabase('atlas', '.vibes/atlas/project.db');
9
+ * // db is ready to use with WAL mode, busy timeout, and migrations applied
10
+ */
11
+ import { Database } from 'bun:sqlite';
12
+ import { getLogger } from '@vibesdotdev/logging';
13
+ import { connectionPool } from "./connection-pool.js";
14
+ import { migrationRegistry } from "./migration-registry.js";
15
+ import { toErrorContext } from './error-context.js';
16
+ import { isLocaldbServerRuntime } from "./runtime.js";
17
+ const logger = getLogger('localdb:database');
18
+ let mkdir;
19
+ let copyFile;
20
+ let unlink;
21
+ let readdir;
22
+ let dirname;
23
+ let basename;
24
+ const BACKUP_RETENTION_COUNT = 12;
25
+ const isServerRuntime = isLocaldbServerRuntime();
26
+ if (isServerRuntime) {
27
+ ({ mkdir, copyFile, unlink, readdir } = await import('node:fs/promises'));
28
+ ({ dirname, basename } = await import('node:path'));
29
+ }
30
+ function isFileMissingError(error) {
31
+ if (!error || typeof error !== 'object')
32
+ return false;
33
+ return error.code === 'ENOENT';
34
+ }
35
+ export class LocalDatabase {
36
+ db;
37
+ options;
38
+ initialized = false;
39
+ constructor(options) {
40
+ this.options = {
41
+ consumer: 'unknown',
42
+ skipMigrations: false,
43
+ usePool: true,
44
+ ...options
45
+ };
46
+ }
47
+ /**
48
+ * Initialize the database connection
49
+ * - Creates directory if needed
50
+ * - Gets/creates pooled connection
51
+ * - Runs pending migrations
52
+ */
53
+ async initialize() {
54
+ if (this.initialized)
55
+ return;
56
+ // Ensure directory exists
57
+ if (!isServerRuntime) {
58
+ throw new Error('LocalDatabase is not available in browser builds');
59
+ }
60
+ await mkdir(dirname(this.options.dbPath), { recursive: true });
61
+ // Get connection (pooled or direct)
62
+ this.establishConnection();
63
+ // Run migrations if needed
64
+ if (!this.options.skipMigrations) {
65
+ try {
66
+ // Check for incompatible database from old migration system
67
+ if (migrationRegistry.isIncompatibleDatabase(this.db, this.options.namespace)) {
68
+ logger.error(`[LocalDB] Detected incompatible database for ${this.options.namespace} (from legacy migration system). Initiating recovery...`);
69
+ await this.performRecovery();
70
+ }
71
+ else if (migrationRegistry.needsMigration(this.db, this.options.namespace)) {
72
+ await migrationRegistry.runMigrations(this.db, this.options.namespace);
73
+ }
74
+ }
75
+ catch (error) {
76
+ logger.error(`[LocalDB] Migration failed for ${this.options.namespace}. Initiating automatic recovery/trapdoor...`, toErrorContext(error));
77
+ await this.performRecovery();
78
+ }
79
+ }
80
+ this.initialized = true;
81
+ }
82
+ /**
83
+ * Establish initial connection
84
+ */
85
+ establishConnection() {
86
+ if (this.options.usePool) {
87
+ this.db = connectionPool.getConnection(this.options.dbPath, this.options.consumer);
88
+ }
89
+ else {
90
+ // Direct connection (for special cases)
91
+ this.db = new Database(this.options.dbPath);
92
+ this.configureDatabase(this.db);
93
+ }
94
+ }
95
+ /**
96
+ * Perform recovery from migration failure
97
+ * 1. Close connection
98
+ * 2. Backup corrupted DB
99
+ * 3. Delete corrupted DB
100
+ * 4. Re-initialize fresh DB
101
+ * 5. Re-run migrations
102
+ */
103
+ async performRecovery() {
104
+ // 1. Close the broken database
105
+ if (this.options.usePool) {
106
+ connectionPool.closeConnection(this.options.dbPath, true);
107
+ }
108
+ else {
109
+ this.db.close();
110
+ }
111
+ // 2. Backup the broken file
112
+ const backupPath = `${this.options.dbPath}.bak-${Date.now()}`;
113
+ try {
114
+ await copyFile(this.options.dbPath, backupPath);
115
+ logger.info(`[LocalDB] Backed up corrupted database to: ${backupPath}`);
116
+ await this.pruneBackupFiles();
117
+ }
118
+ catch (backupError) {
119
+ logger.error('[LocalDB] Failed to backup corrupted database:', toErrorContext(backupError));
120
+ }
121
+ // 3. Delete the broken file and WAL artifacts
122
+ try {
123
+ await unlink(this.options.dbPath);
124
+ await unlink(`${this.options.dbPath}-wal`).catch(() => { });
125
+ await unlink(`${this.options.dbPath}-shm`).catch(() => { });
126
+ logger.info('[LocalDB] Deleted corrupted database file.');
127
+ }
128
+ catch (deleteError) {
129
+ if (isFileMissingError(deleteError)) {
130
+ logger.info('[LocalDB] Corrupted database file already removed during recovery. Continuing...');
131
+ }
132
+ else {
133
+ logger.error('[LocalDB] Failed to delete corrupted database:', toErrorContext(deleteError));
134
+ throw deleteError; // If we can't delete, we can't recover.
135
+ }
136
+ }
137
+ // 4. Re-establish connection (creates new DB file)
138
+ logger.info('[LocalDB] Re-initializing fresh database...');
139
+ this.establishConnection();
140
+ // 5. Re-run migrations on fresh DB
141
+ try {
142
+ if (migrationRegistry.needsMigration(this.db, this.options.namespace)) {
143
+ await migrationRegistry.runMigrations(this.db, this.options.namespace);
144
+ }
145
+ logger.info('[LocalDB] Recovery successful. Database reset.');
146
+ }
147
+ catch (retryError) {
148
+ logger.error('[LocalDB] Recovery failed. Fresh database migration failed:', toErrorContext(retryError));
149
+ throw retryError;
150
+ }
151
+ }
152
+ async pruneBackupFiles() {
153
+ const directory = dirname(this.options.dbPath);
154
+ const filename = basename(this.options.dbPath);
155
+ const backupPrefix = `${filename}.bak-`;
156
+ const files = await readdir(directory).catch(() => []);
157
+ const backups = files
158
+ .filter((entry) => entry.startsWith(backupPrefix))
159
+ .map((entry) => ({ entry, timestamp: Number(entry.slice(backupPrefix.length)) }))
160
+ .sort((a, b) => {
161
+ if (Number.isNaN(a.timestamp) || Number.isNaN(b.timestamp)) {
162
+ return b.entry.localeCompare(a.entry);
163
+ }
164
+ return b.timestamp - a.timestamp;
165
+ });
166
+ for (const backup of backups.slice(BACKUP_RETENTION_COUNT)) {
167
+ await unlink(`${directory}/${backup.entry}`).catch(() => { });
168
+ }
169
+ }
170
+ /**
171
+ * Configure database with optimal settings (for non-pooled connections)
172
+ */
173
+ configureDatabase(db) {
174
+ db.exec('PRAGMA journal_mode = WAL;');
175
+ db.exec('PRAGMA busy_timeout = 5000;');
176
+ db.exec('PRAGMA foreign_keys = ON;');
177
+ db.exec('PRAGMA synchronous = NORMAL;');
178
+ db.exec('PRAGMA temp_store = MEMORY;');
179
+ }
180
+ /**
181
+ * Get the underlying Database instance
182
+ */
183
+ getDatabase() {
184
+ if (!this.initialized) {
185
+ throw new Error('Database not initialized. Call initialize() first.');
186
+ }
187
+ return this.db;
188
+ }
189
+ /**
190
+ * Close the database connection
191
+ */
192
+ close() {
193
+ if (!this.initialized)
194
+ return;
195
+ if (this.options.usePool) {
196
+ // Release back to pool
197
+ connectionPool.releaseConnection(this.options.dbPath);
198
+ }
199
+ else {
200
+ // Direct close
201
+ this.db.close();
202
+ }
203
+ this.initialized = false;
204
+ }
205
+ /**
206
+ * Check if database is healthy
207
+ */
208
+ healthCheck() {
209
+ if (!this.initialized)
210
+ return false;
211
+ try {
212
+ const result = this.db.query('SELECT 1').get();
213
+ return result !== null;
214
+ }
215
+ catch {
216
+ return false;
217
+ }
218
+ }
219
+ /**
220
+ * Get migration status for this database
221
+ */
222
+ getMigrationStatus() {
223
+ if (!this.initialized) {
224
+ throw new Error('Database not initialized');
225
+ }
226
+ return migrationRegistry.getDatabaseStatus(this.db, this.options.namespace);
227
+ }
228
+ }
229
+ /**
230
+ * LocalDB Manager
231
+ * Main entry point for accessing local databases
232
+ */
233
+ class LocalDBManager {
234
+ databases = new Map();
235
+ dbPathLocks = new Map();
236
+ async withDbPathLock(dbPath, task) {
237
+ const prior = this.dbPathLocks.get(dbPath) ?? Promise.resolve();
238
+ let release;
239
+ const current = new Promise((resolve) => {
240
+ release = resolve;
241
+ });
242
+ const queued = prior.then(() => current);
243
+ this.dbPathLocks.set(dbPath, queued);
244
+ await prior;
245
+ try {
246
+ return await task();
247
+ }
248
+ finally {
249
+ release?.();
250
+ if (this.dbPathLocks.get(dbPath) === queued) {
251
+ this.dbPathLocks.delete(dbPath);
252
+ }
253
+ }
254
+ }
255
+ /**
256
+ * Register migrations for a namespace
257
+ * Must be called before getDatabase() for that namespace
258
+ */
259
+ registerMigrations(namespace, migrations) {
260
+ migrationRegistry.register(namespace, migrations);
261
+ }
262
+ /**
263
+ * Get or create a database instance
264
+ *
265
+ * @param namespace Migration namespace (e.g., 'atlas', 'session')
266
+ * @param dbPath Path to database file
267
+ * @param consumer Consumer identifier for debugging
268
+ * @returns Initialized database instance
269
+ */
270
+ getDatabase(namespace, dbPath, consumer) {
271
+ const key = `${namespace}:${dbPath}`;
272
+ return this.withDbPathLock(dbPath, async () => {
273
+ const existing = this.databases.get(key);
274
+ if (existing) {
275
+ existing.references += 1;
276
+ return existing.database;
277
+ }
278
+ if (!this.databases.has(key)) {
279
+ const db = new LocalDatabase({
280
+ namespace,
281
+ dbPath,
282
+ consumer
283
+ });
284
+ await db.initialize();
285
+ this.databases.set(key, {
286
+ database: db,
287
+ references: 1
288
+ });
289
+ }
290
+ return this.databases.get(key).database;
291
+ });
292
+ }
293
+ /**
294
+ * Get a raw Database instance (auto-configured with WAL, etc.)
295
+ * For when you don't need migration management
296
+ */
297
+ getRawDatabase(dbPath, consumer = 'raw') {
298
+ return connectionPool.getConnection(dbPath, consumer);
299
+ }
300
+ /**
301
+ * Release a database instance
302
+ */
303
+ async releaseDatabase(namespace, dbPath) {
304
+ const key = `${namespace}:${dbPath}`;
305
+ await this.withDbPathLock(dbPath, async () => {
306
+ const entry = this.databases.get(key);
307
+ if (!entry)
308
+ return;
309
+ entry.references = Math.max(0, entry.references - 1);
310
+ if (entry.references === 0) {
311
+ await entry.database.close();
312
+ this.databases.delete(key);
313
+ }
314
+ });
315
+ }
316
+ /**
317
+ * Get connection pool statistics
318
+ */
319
+ getPoolStats() {
320
+ return connectionPool.getStats();
321
+ }
322
+ /**
323
+ * Get migration registry status
324
+ */
325
+ getMigrationStatus() {
326
+ return migrationRegistry.getStatus();
327
+ }
328
+ /**
329
+ * List all registered migration namespaces
330
+ */
331
+ listNamespaces() {
332
+ return migrationRegistry.listNamespaces();
333
+ }
334
+ /**
335
+ * Close all database connections
336
+ */
337
+ async closeAll() {
338
+ for (const entry of this.databases.values()) {
339
+ await entry.database.close();
340
+ }
341
+ this.databases.clear();
342
+ connectionPool.closeAll();
343
+ }
344
+ }
345
+ // Singleton instance
346
+ export const localdb = new LocalDBManager();
347
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/core/database.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function toErrorContext(error: unknown): Record<string, unknown> | undefined;
2
+ //# sourceMappingURL=error-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-context.d.ts","sourceRoot":"","sources":["../../src/core/error-context.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAkBlF"}
@@ -0,0 +1,17 @@
1
+ export function toErrorContext(error) {
2
+ if (error instanceof Error) {
3
+ return {
4
+ error: error.message,
5
+ name: error.name,
6
+ stack: error.stack
7
+ };
8
+ }
9
+ if (typeof error === 'object' && error !== null && !Array.isArray(error)) {
10
+ return error;
11
+ }
12
+ if (error === undefined) {
13
+ return undefined;
14
+ }
15
+ return { error: String(error) };
16
+ }
17
+ //# sourceMappingURL=error-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-context.js","sourceRoot":"","sources":["../../src/core/error-context.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAC,KAAc;IAC5C,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC5B,OAAO;YACN,KAAK,EAAE,KAAK,CAAC,OAAO;YACpB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,KAAK,EAAE,KAAK,CAAC,KAAK;SAClB,CAAC;IACH,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1E,OAAO,KAAgC,CAAC;IACzC,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Migration Registry
3
+ *
4
+ * Centralized registration and execution of database migrations.
5
+ * Consumers register their migrations with the registry, which ensures
6
+ * they run in order with proper error handling and version tracking.
7
+ */
8
+ import type { Database } from 'bun:sqlite';
9
+ export interface MigrationFunction {
10
+ (db: Database): void | Promise<void>;
11
+ }
12
+ export interface Migration {
13
+ version: number;
14
+ name: string;
15
+ up: MigrationFunction;
16
+ down?: MigrationFunction;
17
+ }
18
+ export interface MigrationNamespace {
19
+ namespace: string;
20
+ migrations: Migration[];
21
+ currentVersion: number;
22
+ }
23
+ declare class MigrationRegistry {
24
+ private namespaces;
25
+ private hasVersionTable;
26
+ private ensureVersionTable;
27
+ private getLegacyUserVersion;
28
+ private getTrackedSchemaVersion;
29
+ private bootstrapSchemaVersion;
30
+ /**
31
+ * Register migrations for a namespace (e.g., 'atlas', 'session')
32
+ */
33
+ register(namespace: string, migrations: Migration[]): void;
34
+ /**
35
+ * Get current schema version from database
36
+ */
37
+ getSchemaVersion(db: Database, namespace: string): number;
38
+ /**
39
+ * Set schema version in database
40
+ */
41
+ private setSchemaVersion;
42
+ /**
43
+ * Check if database needs migration
44
+ */
45
+ needsMigration(db: Database, namespace: string): boolean;
46
+ /**
47
+ * Check if database is from an incompatible/old migration system
48
+ * This happens when the version is higher than our max (legacy system)
49
+ */
50
+ isIncompatibleDatabase(db: Database, namespace: string): boolean;
51
+ /**
52
+ * Run all pending migrations for a namespace
53
+ */
54
+ runMigrations(db: Database, namespace: string): Promise<void>;
55
+ /**
56
+ * Get migration status for all namespaces
57
+ */
58
+ getStatus(): Array<{
59
+ namespace: string;
60
+ currentVersion: number;
61
+ targetVersion: number;
62
+ pendingMigrations: number;
63
+ }>;
64
+ /**
65
+ * Get migration status for a specific database and namespace
66
+ */
67
+ getDatabaseStatus(db: Database, namespace: string): {
68
+ namespace: string;
69
+ currentVersion: number;
70
+ targetVersion: number;
71
+ pendingMigrations: number;
72
+ migrations: Array<{
73
+ version: number;
74
+ name: string;
75
+ applied: boolean;
76
+ }>;
77
+ };
78
+ /**
79
+ * List all registered namespaces
80
+ */
81
+ listNamespaces(): string[];
82
+ /**
83
+ * Get migrations for a namespace
84
+ */
85
+ getMigrations(namespace: string): Migration[];
86
+ }
87
+ export declare const migrationRegistry: MigrationRegistry;
88
+ export {};
89
+ //# sourceMappingURL=migration-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-registry.d.ts","sourceRoot":"","sources":["../../src/core/migration-registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAM3C,MAAM,WAAW,iBAAiB;IACjC,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,SAAS;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,iBAAiB,CAAC;IACtB,IAAI,CAAC,EAAE,iBAAiB,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,cAAM,iBAAiB;IACtB,OAAO,CAAC,UAAU,CAAyC;IAE3D,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,oBAAoB;IAuB5B,OAAO,CAAC,uBAAuB;IAa/B,OAAO,CAAC,sBAAsB;IAuB9B;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI;IA8B1D;;OAEG;IACH,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IAIzD;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAYxB;;OAEG;IACH,cAAc,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAUxD;;;OAGG;IACH,sBAAsB,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAchE;;OAEG;IACG,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCnE;;OAEG;IACH,SAAS,IAAI,KAAK,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;KAC1B,CAAC;IAoBF;;OAEG;IACH,iBAAiB,CAChB,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,GACf;QACF,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,UAAU,EAAE,KAAK,CAAC;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;KACvE;IAsBD;;OAEG;IACH,cAAc,IAAI,MAAM,EAAE;IAI1B;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE;CAO7C;AAGD,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}