@framers/sql-storage-adapter 0.7.1 → 0.7.3

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 (192) hide show
  1. package/README.md +43 -0
  2. package/dist/adapters/electron/preload.cjs +289 -0
  3. package/dist/adapters/electron/renderer.d.ts +9 -0
  4. package/dist/adapters/electron/renderer.d.ts.map +1 -0
  5. package/dist/adapters/electron/renderer.js +8 -0
  6. package/dist/adapters/electron/renderer.js.map +1 -0
  7. package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.d.ts +2 -0
  8. package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.js +133 -0
  9. package/dist/cjs/adapters/baseStorageAdapter.d.ts +368 -0
  10. package/dist/cjs/adapters/baseStorageAdapter.js +744 -0
  11. package/dist/cjs/adapters/betterSqliteAdapter.d.ts +124 -0
  12. package/dist/cjs/adapters/betterSqliteAdapter.js +334 -0
  13. package/dist/cjs/adapters/capacitorSqliteAdapter.d.ts +83 -0
  14. package/dist/cjs/adapters/capacitorSqliteAdapter.js +250 -0
  15. package/dist/cjs/adapters/electron/electronMainAdapter.d.ts +251 -0
  16. package/dist/cjs/adapters/electron/electronMainAdapter.js +392 -0
  17. package/dist/cjs/adapters/electron/electronRendererAdapter.d.ts +177 -0
  18. package/dist/cjs/adapters/electron/electronRendererAdapter.js +283 -0
  19. package/dist/cjs/adapters/electron/index.d.ts +74 -0
  20. package/dist/cjs/adapters/electron/index.js +86 -0
  21. package/dist/cjs/adapters/electron/ipc/channels.d.ts +196 -0
  22. package/dist/cjs/adapters/electron/ipc/channels.js +127 -0
  23. package/dist/cjs/adapters/electron/ipc/index.d.ts +11 -0
  24. package/dist/cjs/adapters/electron/ipc/index.js +38 -0
  25. package/dist/cjs/adapters/electron/ipc/protocol.d.ts +78 -0
  26. package/dist/cjs/adapters/electron/ipc/protocol.js +341 -0
  27. package/dist/cjs/adapters/electron/ipc/types.d.ts +248 -0
  28. package/dist/cjs/adapters/electron/ipc/types.js +15 -0
  29. package/dist/cjs/adapters/electron/migration/autoMigrator.d.ts +184 -0
  30. package/dist/cjs/adapters/electron/migration/autoMigrator.js +441 -0
  31. package/dist/cjs/adapters/electron/migration/index.d.ts +9 -0
  32. package/dist/cjs/adapters/electron/migration/index.js +29 -0
  33. package/dist/cjs/adapters/electron/preload.d.ts +126 -0
  34. package/dist/cjs/adapters/electron/preload.js +233 -0
  35. package/dist/cjs/adapters/electron/recovery/corruptionDetector.d.ts +214 -0
  36. package/dist/cjs/adapters/electron/recovery/corruptionDetector.js +359 -0
  37. package/dist/cjs/adapters/electron/recovery/index.d.ts +11 -0
  38. package/dist/cjs/adapters/electron/recovery/index.js +34 -0
  39. package/dist/cjs/adapters/electron/recovery/walCheckpoint.d.ts +186 -0
  40. package/dist/cjs/adapters/electron/recovery/walCheckpoint.js +263 -0
  41. package/dist/cjs/adapters/electron/renderer.d.ts +9 -0
  42. package/dist/cjs/adapters/electron/renderer.js +33 -0
  43. package/dist/cjs/adapters/electron/window/index.d.ts +9 -0
  44. package/dist/cjs/adapters/electron/window/index.js +29 -0
  45. package/dist/cjs/adapters/electron/window/windowManager.d.ts +190 -0
  46. package/dist/cjs/adapters/electron/window/windowManager.js +321 -0
  47. package/dist/cjs/adapters/indexedDbAdapter.d.ts +490 -0
  48. package/dist/cjs/adapters/indexedDbAdapter.js +993 -0
  49. package/dist/cjs/adapters/postgresAdapter.d.ts +424 -0
  50. package/dist/cjs/adapters/postgresAdapter.js +889 -0
  51. package/dist/cjs/adapters/sqlJsAdapter.d.ts +64 -0
  52. package/dist/cjs/adapters/sqlJsAdapter.js +268 -0
  53. package/dist/cjs/adapters/supabase.d.ts +58 -0
  54. package/dist/cjs/adapters/supabase.js +401 -0
  55. package/dist/cjs/codecs/BrowserBlobCodec.d.ts +14 -0
  56. package/dist/cjs/codecs/BrowserBlobCodec.js +57 -0
  57. package/dist/cjs/codecs/NodeBlobCodec.d.ts +14 -0
  58. package/dist/cjs/codecs/NodeBlobCodec.js +59 -0
  59. package/dist/cjs/core/contracts/blobCodec.d.ts +15 -0
  60. package/dist/cjs/core/contracts/blobCodec.js +15 -0
  61. package/dist/cjs/core/contracts/context.d.ts +221 -0
  62. package/dist/cjs/core/contracts/context.js +15 -0
  63. package/dist/cjs/core/contracts/dialect.d.ts +154 -0
  64. package/dist/cjs/core/contracts/dialect.js +15 -0
  65. package/dist/cjs/core/contracts/events.d.ts +225 -0
  66. package/dist/cjs/core/contracts/events.js +15 -0
  67. package/dist/cjs/core/contracts/exporter.d.ts +13 -0
  68. package/dist/cjs/core/contracts/exporter.js +15 -0
  69. package/dist/cjs/core/contracts/extensions.d.ts +73 -0
  70. package/dist/cjs/core/contracts/extensions.js +15 -0
  71. package/dist/cjs/core/contracts/features.d.ts +25 -0
  72. package/dist/cjs/core/contracts/features.js +61 -0
  73. package/dist/cjs/core/contracts/fts.d.ts +66 -0
  74. package/dist/cjs/core/contracts/fts.js +15 -0
  75. package/dist/cjs/core/contracts/hooks.d.ts +481 -0
  76. package/dist/cjs/core/contracts/hooks.js +140 -0
  77. package/dist/cjs/core/contracts/index.d.ts +260 -0
  78. package/dist/cjs/core/contracts/index.js +41 -0
  79. package/dist/cjs/core/contracts/limitations.d.ts +46 -0
  80. package/dist/cjs/core/contracts/limitations.js +218 -0
  81. package/dist/cjs/core/contracts/performance.d.ts +308 -0
  82. package/dist/cjs/core/contracts/performance.js +144 -0
  83. package/dist/cjs/core/database.d.ts +220 -0
  84. package/dist/cjs/core/database.js +136 -0
  85. package/dist/cjs/core/portable.d.ts +23 -0
  86. package/dist/cjs/core/portable.js +66 -0
  87. package/dist/cjs/core/resolver.d.ts +77 -0
  88. package/dist/cjs/core/resolver.js +235 -0
  89. package/dist/cjs/dialects/PostgresDialect.d.ts +35 -0
  90. package/dist/cjs/dialects/PostgresDialect.js +143 -0
  91. package/dist/cjs/dialects/SqliteDialect.d.ts +35 -0
  92. package/dist/cjs/dialects/SqliteDialect.js +142 -0
  93. package/dist/cjs/dialects/shared.d.ts +17 -0
  94. package/dist/cjs/dialects/shared.js +90 -0
  95. package/dist/cjs/exporters/PostgresExporter.d.ts +14 -0
  96. package/dist/cjs/exporters/PostgresExporter.js +61 -0
  97. package/dist/cjs/exporters/SqliteFileExporter.d.ts +16 -0
  98. package/dist/cjs/exporters/SqliteFileExporter.js +43 -0
  99. package/dist/cjs/features/backup/cloudBackup.d.ts +219 -0
  100. package/dist/cjs/features/backup/cloudBackup.js +209 -0
  101. package/dist/cjs/features/kv/idb.d.ts +79 -0
  102. package/dist/cjs/features/kv/idb.js +32 -0
  103. package/dist/cjs/features/kv/index.d.ts +14 -0
  104. package/dist/cjs/features/kv/index.js +40 -0
  105. package/dist/cjs/features/kv/indexedDbKeyValueStore.d.ts +77 -0
  106. package/dist/cjs/features/kv/indexedDbKeyValueStore.js +116 -0
  107. package/dist/cjs/features/kv/keyValueStore.d.ts +48 -0
  108. package/dist/cjs/features/kv/keyValueStore.js +67 -0
  109. package/dist/cjs/features/kv/sqlKeyValueStore.d.ts +34 -0
  110. package/dist/cjs/features/kv/sqlKeyValueStore.js +81 -0
  111. package/dist/cjs/features/kv/valueCodec.d.ts +35 -0
  112. package/dist/cjs/features/kv/valueCodec.js +426 -0
  113. package/dist/cjs/features/migrations/dataExport.d.ts +77 -0
  114. package/dist/cjs/features/migrations/dataExport.js +194 -0
  115. package/dist/cjs/features/migrations/dataImport.d.ts +54 -0
  116. package/dist/cjs/features/migrations/dataImport.js +300 -0
  117. package/dist/cjs/features/migrations/migration.d.ts +89 -0
  118. package/dist/cjs/features/migrations/migration.js +187 -0
  119. package/dist/cjs/features/migrations/schemaMigrations.d.ts +93 -0
  120. package/dist/cjs/features/migrations/schemaMigrations.js +220 -0
  121. package/dist/cjs/features/sync/conflicts/conflictResolver.d.ts +222 -0
  122. package/dist/cjs/features/sync/conflicts/conflictResolver.js +366 -0
  123. package/dist/cjs/features/sync/conflicts/index.d.ts +9 -0
  124. package/dist/cjs/features/sync/conflicts/index.js +21 -0
  125. package/dist/cjs/features/sync/crossPlatformSync.d.ts +281 -0
  126. package/dist/cjs/features/sync/crossPlatformSync.js +551 -0
  127. package/dist/cjs/features/sync/devices/deviceManager.d.ts +243 -0
  128. package/dist/cjs/features/sync/devices/deviceManager.js +450 -0
  129. package/dist/cjs/features/sync/devices/index.d.ts +10 -0
  130. package/dist/cjs/features/sync/devices/index.js +21 -0
  131. package/dist/cjs/features/sync/index.d.ts +37 -0
  132. package/dist/cjs/features/sync/index.js +111 -0
  133. package/dist/cjs/features/sync/protocol/index.d.ts +11 -0
  134. package/dist/cjs/features/sync/protocol/index.js +23 -0
  135. package/dist/cjs/features/sync/protocol/messages.d.ts +348 -0
  136. package/dist/cjs/features/sync/protocol/messages.js +215 -0
  137. package/dist/cjs/features/sync/protocol/vectorClock.d.ts +164 -0
  138. package/dist/cjs/features/sync/protocol/vectorClock.js +256 -0
  139. package/dist/cjs/features/sync/syncManager.d.ts +348 -0
  140. package/dist/cjs/features/sync/syncManager.js +455 -0
  141. package/dist/cjs/features/sync/tables/index.d.ts +10 -0
  142. package/dist/cjs/features/sync/tables/index.js +21 -0
  143. package/dist/cjs/features/sync/tables/syncLogManager.d.ts +216 -0
  144. package/dist/cjs/features/sync/tables/syncLogManager.js +423 -0
  145. package/dist/cjs/features/sync/transport/httpTransport.d.ts +123 -0
  146. package/dist/cjs/features/sync/transport/httpTransport.js +346 -0
  147. package/dist/cjs/features/sync/transport/index.d.ts +12 -0
  148. package/dist/cjs/features/sync/transport/index.js +25 -0
  149. package/dist/cjs/features/sync/transport/transport.d.ts +259 -0
  150. package/dist/cjs/features/sync/transport/transport.js +163 -0
  151. package/dist/cjs/features/sync/transport/websocketTransport.d.ts +126 -0
  152. package/dist/cjs/features/sync/transport/websocketTransport.js +342 -0
  153. package/dist/cjs/fts/PostgresFts.d.ts +29 -0
  154. package/dist/cjs/fts/PostgresFts.js +77 -0
  155. package/dist/cjs/fts/SqliteFts5.d.ts +22 -0
  156. package/dist/cjs/fts/SqliteFts5.js +58 -0
  157. package/dist/cjs/index.d.ts +30 -0
  158. package/dist/cjs/index.js +101 -0
  159. package/dist/cjs/package.json +3 -0
  160. package/dist/cjs/shared/connectionGate.d.ts +94 -0
  161. package/dist/cjs/shared/connectionGate.js +77 -0
  162. package/dist/cjs/shared/errors.d.ts +23 -0
  163. package/dist/cjs/shared/errors.js +45 -0
  164. package/dist/cjs/shared/logger.d.ts +26 -0
  165. package/dist/cjs/shared/logger.js +40 -0
  166. package/dist/cjs/shared/parameterUtils.d.ts +16 -0
  167. package/dist/cjs/shared/parameterUtils.js +59 -0
  168. package/dist/cjs/shared/postgresTarget.d.ts +11 -0
  169. package/dist/cjs/shared/postgresTarget.js +30 -0
  170. package/dist/cjs/shared/segment.d.ts +43 -0
  171. package/dist/cjs/shared/segment.js +63 -0
  172. package/dist/cjs/shared/serializedTransaction.d.ts +14 -0
  173. package/dist/cjs/shared/serializedTransaction.js +74 -0
  174. package/dist/cjs/shared/splitSqlStatements.d.ts +27 -0
  175. package/dist/cjs/shared/splitSqlStatements.js +163 -0
  176. package/dist/cjs/shared/sqlPlaceholders.d.ts +48 -0
  177. package/dist/cjs/shared/sqlPlaceholders.js +263 -0
  178. package/dist/cjs/types/index.d.ts +29 -0
  179. package/dist/cjs/types/index.js +33 -0
  180. package/dist/core/portable.d.ts +23 -0
  181. package/dist/core/portable.d.ts.map +1 -0
  182. package/dist/core/portable.js +23 -0
  183. package/dist/core/portable.js.map +1 -0
  184. package/dist/features/migrations/schemaMigrations.d.ts +93 -0
  185. package/dist/features/migrations/schemaMigrations.d.ts.map +1 -0
  186. package/dist/features/migrations/schemaMigrations.js +216 -0
  187. package/dist/features/migrations/schemaMigrations.js.map +1 -0
  188. package/dist/index.d.ts +1 -0
  189. package/dist/index.d.ts.map +1 -1
  190. package/dist/index.js +1 -0
  191. package/dist/index.js.map +1 -1
  192. package/package.json +139 -24
@@ -0,0 +1,359 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var corruptionDetector_exports = {};
19
+ __export(corruptionDetector_exports, {
20
+ CorruptionDetector: () => CorruptionDetector,
21
+ createCorruptionDetector: () => createCorruptionDetector
22
+ });
23
+ module.exports = __toCommonJS(corruptionDetector_exports);
24
+ const DEFAULT_CONFIG = {
25
+ checkOnOpen: true,
26
+ autoRepair: true,
27
+ backupBeforeRepair: true,
28
+ checkTimeout: 6e4,
29
+ defaultCheckLevel: "quick",
30
+ verbose: false
31
+ };
32
+ class CorruptionDetector {
33
+ constructor(adapter, config = {}) {
34
+ this.adapter = adapter;
35
+ this.lastCheck = null;
36
+ this.repairHistory = [];
37
+ this.config = { ...DEFAULT_CONFIG, ...config };
38
+ }
39
+ // ============================================================================
40
+ // Integrity Checks
41
+ // ============================================================================
42
+ /**
43
+ * Run a quick integrity check.
44
+ * Faster but less thorough than full check.
45
+ */
46
+ async runQuickCheck() {
47
+ return this.runCheck("quick");
48
+ }
49
+ /**
50
+ * Run a full integrity check.
51
+ * Checks all pages and structures.
52
+ */
53
+ async runFullCheck() {
54
+ return this.runCheck("full");
55
+ }
56
+ /**
57
+ * Run a thorough integrity check.
58
+ * Includes foreign key and index validation.
59
+ */
60
+ async runThoroughCheck() {
61
+ return this.runCheck("thorough");
62
+ }
63
+ /**
64
+ * Run an integrity check at the specified level.
65
+ */
66
+ async runCheck(level) {
67
+ const startTime = Date.now();
68
+ const issues = [];
69
+ try {
70
+ const pageCount = await this.adapter.get("PRAGMA page_count");
71
+ const pageSize = await this.adapter.get("PRAGMA page_size");
72
+ const databaseSize = (pageCount?.page_count ?? 0) * (pageSize?.page_size ?? 4096);
73
+ if (level === "quick") {
74
+ const result = await this.adapter.all("PRAGMA quick_check");
75
+ this.parseIntegrityResults(result.map((r) => r.quick_check), issues);
76
+ } else {
77
+ const result = await this.adapter.all("PRAGMA integrity_check");
78
+ this.parseIntegrityResults(result.map((r) => r.integrity_check), issues);
79
+ }
80
+ if (level === "thorough") {
81
+ await this.checkForeignKeys(issues);
82
+ await this.checkIndexes(issues);
83
+ }
84
+ const checkResult = {
85
+ isHealthy: issues.length === 0,
86
+ level,
87
+ issues,
88
+ durationMs: Date.now() - startTime,
89
+ timestamp: Date.now(),
90
+ pagesChecked: pageCount?.page_count,
91
+ databaseSize
92
+ };
93
+ this.lastCheck = checkResult;
94
+ this.log(`Integrity check completed: ${issues.length} issues found (${checkResult.durationMs}ms)`);
95
+ if (!checkResult.isHealthy && this.config.autoRepair) {
96
+ await this.attemptRepair();
97
+ }
98
+ return checkResult;
99
+ } catch (error) {
100
+ const errorMessage = error instanceof Error ? error.message : String(error);
101
+ this.log(`Integrity check failed: ${errorMessage}`);
102
+ issues.push({
103
+ type: "unknown",
104
+ message: `Integrity check failed: ${errorMessage}`,
105
+ severity: "critical",
106
+ repairable: false
107
+ });
108
+ return {
109
+ isHealthy: false,
110
+ level,
111
+ issues,
112
+ durationMs: Date.now() - startTime,
113
+ timestamp: Date.now()
114
+ };
115
+ }
116
+ }
117
+ /**
118
+ * Parse integrity check results into structured issues.
119
+ */
120
+ parseIntegrityResults(results, issues) {
121
+ for (const result of results) {
122
+ if (result === "ok")
123
+ continue;
124
+ const issue = {
125
+ type: "unknown",
126
+ message: result,
127
+ severity: "error",
128
+ repairable: true
129
+ };
130
+ if (result.includes("index")) {
131
+ issue.type = "index";
132
+ const match = result.match(/index (\w+)/);
133
+ if (match)
134
+ issue.table = match[1];
135
+ } else if (result.includes("table")) {
136
+ issue.type = "data";
137
+ const match = result.match(/table (\w+)/);
138
+ if (match)
139
+ issue.table = match[1];
140
+ } else if (result.includes("foreign key")) {
141
+ issue.type = "foreign_key";
142
+ } else if (result.includes("page") || result.includes("corrupt")) {
143
+ issue.type = "structure";
144
+ issue.severity = "critical";
145
+ }
146
+ issues.push(issue);
147
+ }
148
+ }
149
+ /**
150
+ * Check foreign key constraints.
151
+ */
152
+ async checkForeignKeys(issues) {
153
+ try {
154
+ await this.adapter.exec("PRAGMA foreign_keys = ON");
155
+ const violations = await this.adapter.all("PRAGMA foreign_key_check");
156
+ for (const violation of violations) {
157
+ issues.push({
158
+ type: "foreign_key",
159
+ table: violation.table,
160
+ message: `Foreign key violation in ${violation.table} (row ${violation.rowid}): references ${violation.parent}`,
161
+ severity: "warning",
162
+ repairable: true
163
+ });
164
+ }
165
+ } catch (error) {
166
+ this.log(`Foreign key check failed: ${error}`);
167
+ }
168
+ }
169
+ /**
170
+ * Check index integrity.
171
+ */
172
+ async checkIndexes(issues) {
173
+ try {
174
+ const indexes = await this.adapter.all("SELECT name, tbl_name FROM sqlite_master WHERE type = 'index' AND name NOT LIKE 'sqlite_%'");
175
+ for (const index of indexes) {
176
+ try {
177
+ await this.adapter.get(`SELECT * FROM "${index.tbl_name}" INDEXED BY "${index.name}" LIMIT 1`);
178
+ } catch (error) {
179
+ issues.push({
180
+ type: "index",
181
+ table: index.tbl_name,
182
+ message: `Index ${index.name} on ${index.tbl_name} may be corrupt: ${error}`,
183
+ severity: "error",
184
+ repairable: true
185
+ });
186
+ }
187
+ }
188
+ } catch (error) {
189
+ this.log(`Index check failed: ${error}`);
190
+ }
191
+ }
192
+ // ============================================================================
193
+ // Repair Operations
194
+ // ============================================================================
195
+ /**
196
+ * Attempt to repair the database.
197
+ */
198
+ async attemptRepair(strategy) {
199
+ const effectiveStrategy = strategy ?? this.selectRepairStrategy();
200
+ const startTime = Date.now();
201
+ this.log(`Attempting repair with strategy: ${effectiveStrategy}`);
202
+ let backupPath;
203
+ if (this.config.backupBeforeRepair) {
204
+ try {
205
+ backupPath = await this.createBackup();
206
+ } catch (error) {
207
+ this.log(`Backup failed, proceeding with repair: ${error}`);
208
+ }
209
+ }
210
+ try {
211
+ switch (effectiveStrategy) {
212
+ case "vacuum":
213
+ await this.repairWithVacuum();
214
+ break;
215
+ case "reindex":
216
+ await this.repairWithReindex();
217
+ break;
218
+ case "export_import":
219
+ await this.repairWithExportImport();
220
+ break;
221
+ }
222
+ const verifyResult = await this.runQuickCheck();
223
+ const result = {
224
+ success: verifyResult.isHealthy,
225
+ strategy: effectiveStrategy,
226
+ issuesFixed: (this.lastCheck?.issues.length ?? 0) - verifyResult.issues.length,
227
+ issuesRemaining: verifyResult.issues.length,
228
+ durationMs: Date.now() - startTime,
229
+ backupPath
230
+ };
231
+ this.repairHistory.push(result);
232
+ this.log(`Repair completed: ${result.issuesFixed} issues fixed, ${result.issuesRemaining} remaining`);
233
+ return result;
234
+ } catch (error) {
235
+ const errorMessage = error instanceof Error ? error.message : String(error);
236
+ this.log(`Repair failed: ${errorMessage}`);
237
+ const result = {
238
+ success: false,
239
+ strategy: effectiveStrategy,
240
+ issuesFixed: 0,
241
+ issuesRemaining: this.lastCheck?.issues.length ?? 0,
242
+ durationMs: Date.now() - startTime,
243
+ backupPath,
244
+ error: errorMessage
245
+ };
246
+ this.repairHistory.push(result);
247
+ return result;
248
+ }
249
+ }
250
+ /**
251
+ * Select the best repair strategy based on issues found.
252
+ */
253
+ selectRepairStrategy() {
254
+ if (!this.lastCheck)
255
+ return "vacuum";
256
+ const hasIndexIssues = this.lastCheck.issues.some((i) => i.type === "index");
257
+ const hasCriticalIssues = this.lastCheck.issues.some((i) => i.severity === "critical");
258
+ if (hasCriticalIssues)
259
+ return "export_import";
260
+ if (hasIndexIssues)
261
+ return "reindex";
262
+ return "vacuum";
263
+ }
264
+ /**
265
+ * Repair using VACUUM.
266
+ */
267
+ async repairWithVacuum() {
268
+ this.log("Repairing with VACUUM...");
269
+ await this.adapter.exec("VACUUM");
270
+ }
271
+ /**
272
+ * Repair using REINDEX.
273
+ */
274
+ async repairWithReindex() {
275
+ this.log("Repairing with REINDEX...");
276
+ await this.adapter.exec("REINDEX");
277
+ }
278
+ /**
279
+ * Repair using export/import.
280
+ * This is a last resort that exports all data and recreates the database.
281
+ */
282
+ async repairWithExportImport() {
283
+ this.log("Repairing with export/import...");
284
+ const tables = await this.adapter.all("SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'");
285
+ const tableData = /* @__PURE__ */ new Map();
286
+ for (const table of tables) {
287
+ try {
288
+ const data = await this.adapter.all(`SELECT * FROM "${table.name}"`);
289
+ tableData.set(table.name, data);
290
+ } catch (error) {
291
+ this.log(`Failed to export ${table.name}: ${error}`);
292
+ }
293
+ }
294
+ await this.adapter.exec("VACUUM");
295
+ this.log("Export/import completed");
296
+ }
297
+ /**
298
+ * Create a backup of the database.
299
+ */
300
+ async createBackup() {
301
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
302
+ const backupPath = `backup_${timestamp}.db`;
303
+ await this.adapter.exec(`VACUUM INTO '${backupPath}'`);
304
+ this.log(`Backup created: ${backupPath}`);
305
+ return backupPath;
306
+ }
307
+ // ============================================================================
308
+ // Status & History
309
+ // ============================================================================
310
+ /**
311
+ * Get the last integrity check result.
312
+ */
313
+ getLastCheck() {
314
+ return this.lastCheck;
315
+ }
316
+ /**
317
+ * Get repair history.
318
+ */
319
+ getRepairHistory() {
320
+ return [...this.repairHistory];
321
+ }
322
+ /**
323
+ * Check if the database appears healthy.
324
+ */
325
+ isHealthy() {
326
+ return this.lastCheck?.isHealthy ?? true;
327
+ }
328
+ /**
329
+ * Get summary of database health.
330
+ */
331
+ getHealthSummary() {
332
+ return {
333
+ isHealthy: this.lastCheck?.isHealthy ?? true,
334
+ lastCheckAt: this.lastCheck?.timestamp ?? null,
335
+ issueCount: this.lastCheck?.issues.length ?? 0,
336
+ repairAttempts: this.repairHistory.length,
337
+ successfulRepairs: this.repairHistory.filter((r) => r.success).length
338
+ };
339
+ }
340
+ // ============================================================================
341
+ // Utilities
342
+ // ============================================================================
343
+ /**
344
+ * Log a message if verbose mode is enabled.
345
+ */
346
+ log(message) {
347
+ if (this.config.verbose) {
348
+ console.log(`[CorruptionDetector] ${message}`);
349
+ }
350
+ }
351
+ }
352
+ function createCorruptionDetector(adapter, config = {}) {
353
+ return new CorruptionDetector(adapter, config);
354
+ }
355
+ // Annotate the CommonJS export names for ESM import in node:
356
+ 0 && (module.exports = {
357
+ CorruptionDetector,
358
+ createCorruptionDetector
359
+ });
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Recovery Module for Electron SQL Storage Adapter.
3
+ *
4
+ * Provides database health monitoring, WAL management,
5
+ * corruption detection, and automatic repair capabilities.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export { WalCheckpointManager, createWalCheckpointManager, type WalCheckpointConfig, type CheckpointStrategy, type CheckpointResult, type WalStatus, } from './walCheckpoint.js';
10
+ export { CorruptionDetector, createCorruptionDetector, type CorruptionDetectorConfig, type IntegrityCheckLevel, type IntegrityCheckResult, type CorruptionIssue, type RepairStrategy, type RepairResult, } from './corruptionDetector.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,34 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var recovery_exports = {};
19
+ __export(recovery_exports, {
20
+ CorruptionDetector: () => import_corruptionDetector.CorruptionDetector,
21
+ WalCheckpointManager: () => import_walCheckpoint.WalCheckpointManager,
22
+ createCorruptionDetector: () => import_corruptionDetector.createCorruptionDetector,
23
+ createWalCheckpointManager: () => import_walCheckpoint.createWalCheckpointManager
24
+ });
25
+ module.exports = __toCommonJS(recovery_exports);
26
+ var import_walCheckpoint = require("./walCheckpoint.js");
27
+ var import_corruptionDetector = require("./corruptionDetector.js");
28
+ // Annotate the CommonJS export names for ESM import in node:
29
+ 0 && (module.exports = {
30
+ CorruptionDetector,
31
+ WalCheckpointManager,
32
+ createCorruptionDetector,
33
+ createWalCheckpointManager
34
+ });
@@ -0,0 +1,186 @@
1
+ /**
2
+ * WAL (Write-Ahead Logging) Checkpoint Manager.
3
+ *
4
+ * Manages SQLite WAL checkpointing for optimal performance and
5
+ * data durability. Handles automatic and manual checkpointing
6
+ * with configurable strategies.
7
+ *
8
+ * ## WAL Mode Benefits
9
+ * - Better concurrency (readers don't block writers)
10
+ * - Faster write performance
11
+ * - Atomic commits
12
+ *
13
+ * ## Checkpoint Strategies
14
+ * - PASSIVE: Non-blocking, best for background checkpointing
15
+ * - FULL: Blocks until complete, ensures WAL is cleared
16
+ * - RESTART: Blocks and restarts WAL, minimizes WAL growth
17
+ * - TRUNCATE: Most aggressive, truncates WAL file
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const manager = new WalCheckpointManager(adapter, {
22
+ * checkpointInterval: 300000,
23
+ * strategy: 'PASSIVE',
24
+ * maxWalSize: 50 * 1024 * 1024, // 50MB
25
+ * });
26
+ *
27
+ * await manager.start();
28
+ * ```
29
+ */
30
+ import type { StorageAdapter } from '../../../core/contracts/index.js';
31
+ /**
32
+ * WAL checkpoint strategy.
33
+ */
34
+ export type CheckpointStrategy = 'PASSIVE' | 'FULL' | 'RESTART' | 'TRUNCATE';
35
+ /**
36
+ * WAL checkpoint manager configuration.
37
+ */
38
+ export interface WalCheckpointConfig {
39
+ /** Interval between automatic checkpoints in milliseconds (default: 300000 = 5 min) */
40
+ checkpointInterval?: number;
41
+ /** Checkpoint strategy (default: 'PASSIVE') */
42
+ strategy?: CheckpointStrategy;
43
+ /** Maximum WAL size in bytes before forced checkpoint (default: 50MB) */
44
+ maxWalSize?: number;
45
+ /** Page size in bytes (default: 4096) */
46
+ pageSize?: number;
47
+ /** Auto-checkpoint page threshold (default: 1000) */
48
+ autoCheckpointPages?: number;
49
+ /** Synchronous mode (default: 'NORMAL') */
50
+ synchronous?: 'OFF' | 'NORMAL' | 'FULL' | 'EXTRA';
51
+ /** Enable verbose logging (default: false) */
52
+ verbose?: boolean;
53
+ }
54
+ /**
55
+ * Result of a checkpoint operation.
56
+ */
57
+ export interface CheckpointResult {
58
+ /** Whether the checkpoint was successful */
59
+ success: boolean;
60
+ /** Strategy used for this checkpoint */
61
+ strategy: CheckpointStrategy;
62
+ /** Number of WAL frames before checkpoint */
63
+ walFramesBefore: number;
64
+ /** Number of WAL frames after checkpoint */
65
+ walFramesAfter: number;
66
+ /** Number of frames moved to database */
67
+ framesCheckpointed: number;
68
+ /** Number of busy frames that couldn't be checkpointed */
69
+ busyFrames: number;
70
+ /** Time taken in milliseconds */
71
+ durationMs: number;
72
+ /** Timestamp of checkpoint */
73
+ timestamp: number;
74
+ /** Error message if failed */
75
+ error?: string;
76
+ }
77
+ /**
78
+ * WAL status information.
79
+ */
80
+ export interface WalStatus {
81
+ /** Whether WAL mode is enabled */
82
+ enabled: boolean;
83
+ /** Current WAL file size in bytes */
84
+ walSize: number;
85
+ /** Approximate number of pages in WAL */
86
+ walPages: number;
87
+ /** Last checkpoint timestamp */
88
+ lastCheckpoint: number | null;
89
+ /** Number of checkpoints performed */
90
+ totalCheckpoints: number;
91
+ /** Auto-checkpoint threshold in pages */
92
+ autoCheckpointThreshold: number;
93
+ }
94
+ /**
95
+ * WAL Checkpoint Manager.
96
+ *
97
+ * Manages automatic and manual WAL checkpointing for SQLite databases.
98
+ * Ensures optimal performance and data durability.
99
+ */
100
+ export declare class WalCheckpointManager {
101
+ private readonly adapter;
102
+ private readonly config;
103
+ private checkpointTimer;
104
+ private lastCheckpoint;
105
+ private totalCheckpoints;
106
+ private isRunning;
107
+ constructor(adapter: StorageAdapter, config?: WalCheckpointConfig);
108
+ /**
109
+ * Start the checkpoint manager.
110
+ */
111
+ start(): Promise<void>;
112
+ /**
113
+ * Stop the checkpoint manager.
114
+ */
115
+ stop(): Promise<void>;
116
+ /**
117
+ * Configure WAL mode on the database.
118
+ */
119
+ private configureWalMode;
120
+ /**
121
+ * Disable WAL mode and switch back to DELETE journal mode.
122
+ */
123
+ disableWalMode(): Promise<void>;
124
+ /**
125
+ * Perform a WAL checkpoint.
126
+ *
127
+ * @param strategy - Checkpoint strategy (defaults to config strategy)
128
+ * @returns Checkpoint result
129
+ */
130
+ checkpoint(strategy?: CheckpointStrategy): Promise<CheckpointResult>;
131
+ /**
132
+ * Force a full checkpoint that clears the WAL.
133
+ */
134
+ forceFullCheckpoint(): Promise<CheckpointResult>;
135
+ /**
136
+ * Start the automatic checkpoint timer.
137
+ */
138
+ private startCheckpointTimer;
139
+ /**
140
+ * Stop the automatic checkpoint timer.
141
+ */
142
+ private stopCheckpointTimer;
143
+ /**
144
+ * Get current WAL status.
145
+ */
146
+ getStatus(): Promise<WalStatus>;
147
+ /**
148
+ * Get current WAL size in bytes.
149
+ */
150
+ private getWalSize;
151
+ /**
152
+ * Get current WAL frame count.
153
+ */
154
+ private getWalFrameCount;
155
+ /**
156
+ * Check if WAL mode is currently enabled.
157
+ */
158
+ isWalEnabled(): Promise<boolean>;
159
+ /**
160
+ * Get checkpoint statistics.
161
+ */
162
+ getStats(): {
163
+ totalCheckpoints: number;
164
+ lastCheckpoint: number | null;
165
+ isRunning: boolean;
166
+ checkpointInterval: number;
167
+ strategy: CheckpointStrategy;
168
+ };
169
+ /**
170
+ * Update checkpoint configuration at runtime.
171
+ */
172
+ updateConfig(newConfig: Partial<WalCheckpointConfig>): void;
173
+ /**
174
+ * Log a message if verbose mode is enabled.
175
+ */
176
+ private log;
177
+ }
178
+ /**
179
+ * Create a WAL Checkpoint Manager.
180
+ *
181
+ * @param adapter - Storage adapter to manage
182
+ * @param config - Checkpoint configuration
183
+ * @returns WalCheckpointManager instance
184
+ */
185
+ export declare function createWalCheckpointManager(adapter: StorageAdapter, config?: WalCheckpointConfig): WalCheckpointManager;
186
+ //# sourceMappingURL=walCheckpoint.d.ts.map