@framers/sql-storage-adapter 0.4.2 → 0.5.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.
- package/README.md +94 -2
- package/dist/adapters/electron/electronMainAdapter.d.ts +241 -0
- package/dist/adapters/electron/electronMainAdapter.d.ts.map +1 -0
- package/dist/adapters/electron/electronMainAdapter.js +442 -0
- package/dist/adapters/electron/electronMainAdapter.js.map +1 -0
- package/dist/adapters/electron/electronRendererAdapter.d.ts +177 -0
- package/dist/adapters/electron/electronRendererAdapter.d.ts.map +1 -0
- package/dist/adapters/electron/electronRendererAdapter.js +339 -0
- package/dist/adapters/electron/electronRendererAdapter.js.map +1 -0
- package/dist/adapters/electron/index.d.ts +74 -0
- package/dist/adapters/electron/index.d.ts.map +1 -0
- package/dist/adapters/electron/index.js +96 -0
- package/dist/adapters/electron/index.js.map +1 -0
- package/dist/adapters/electron/ipc/channels.d.ts +196 -0
- package/dist/adapters/electron/ipc/channels.d.ts.map +1 -0
- package/dist/adapters/electron/ipc/channels.js +121 -0
- package/dist/adapters/electron/ipc/channels.js.map +1 -0
- package/dist/adapters/electron/ipc/index.d.ts +11 -0
- package/dist/adapters/electron/ipc/index.d.ts.map +1 -0
- package/dist/adapters/electron/ipc/index.js +11 -0
- package/dist/adapters/electron/ipc/index.js.map +1 -0
- package/dist/adapters/electron/ipc/protocol.d.ts +78 -0
- package/dist/adapters/electron/ipc/protocol.d.ts.map +1 -0
- package/dist/adapters/electron/ipc/protocol.js +347 -0
- package/dist/adapters/electron/ipc/protocol.js.map +1 -0
- package/dist/adapters/electron/ipc/types.d.ts +248 -0
- package/dist/adapters/electron/ipc/types.d.ts.map +1 -0
- package/dist/adapters/electron/ipc/types.js +8 -0
- package/dist/adapters/electron/ipc/types.js.map +1 -0
- package/dist/adapters/electron/migration/autoMigrator.d.ts +184 -0
- package/dist/adapters/electron/migration/autoMigrator.d.ts.map +1 -0
- package/dist/adapters/electron/migration/autoMigrator.js +478 -0
- package/dist/adapters/electron/migration/autoMigrator.js.map +1 -0
- package/dist/adapters/electron/migration/index.d.ts +9 -0
- package/dist/adapters/electron/migration/index.d.ts.map +1 -0
- package/dist/adapters/electron/migration/index.js +9 -0
- package/dist/adapters/electron/migration/index.js.map +1 -0
- package/dist/adapters/electron/preload.d.ts +126 -0
- package/dist/adapters/electron/preload.d.ts.map +1 -0
- package/dist/adapters/electron/preload.js +254 -0
- package/dist/adapters/electron/preload.js.map +1 -0
- package/dist/adapters/electron/recovery/corruptionDetector.d.ts +214 -0
- package/dist/adapters/electron/recovery/corruptionDetector.d.ts.map +1 -0
- package/dist/adapters/electron/recovery/corruptionDetector.js +410 -0
- package/dist/adapters/electron/recovery/corruptionDetector.js.map +1 -0
- package/dist/adapters/electron/recovery/index.d.ts +11 -0
- package/dist/adapters/electron/recovery/index.d.ts.map +1 -0
- package/dist/adapters/electron/recovery/index.js +11 -0
- package/dist/adapters/electron/recovery/index.js.map +1 -0
- package/dist/adapters/electron/recovery/walCheckpoint.d.ts +186 -0
- package/dist/adapters/electron/recovery/walCheckpoint.d.ts.map +1 -0
- package/dist/adapters/electron/recovery/walCheckpoint.js +302 -0
- package/dist/adapters/electron/recovery/walCheckpoint.js.map +1 -0
- package/dist/adapters/electron/window/index.d.ts +9 -0
- package/dist/adapters/electron/window/index.d.ts.map +1 -0
- package/dist/adapters/electron/window/index.js +9 -0
- package/dist/adapters/electron/window/index.js.map +1 -0
- package/dist/adapters/electron/window/windowManager.d.ts +190 -0
- package/dist/adapters/electron/window/windowManager.d.ts.map +1 -0
- package/dist/adapters/electron/window/windowManager.js +358 -0
- package/dist/adapters/electron/window/windowManager.js.map +1 -0
- package/dist/core/contracts/context.d.ts +2 -2
- package/dist/core/contracts/context.d.ts.map +1 -1
- package/dist/core/database.d.ts +19 -0
- package/dist/core/database.d.ts.map +1 -1
- package/dist/core/database.js +4 -0
- package/dist/core/database.js.map +1 -1
- package/dist/core/resolver.d.ts +3 -0
- package/dist/core/resolver.d.ts.map +1 -1
- package/dist/core/resolver.js +39 -3
- package/dist/core/resolver.js.map +1 -1
- package/dist/features/sync/conflicts/conflictResolver.d.ts +222 -0
- package/dist/features/sync/conflicts/conflictResolver.d.ts.map +1 -0
- package/dist/features/sync/conflicts/conflictResolver.js +396 -0
- package/dist/features/sync/conflicts/conflictResolver.js.map +1 -0
- package/dist/features/sync/conflicts/index.d.ts +9 -0
- package/dist/features/sync/conflicts/index.d.ts.map +1 -0
- package/dist/features/sync/conflicts/index.js +9 -0
- package/dist/features/sync/conflicts/index.js.map +1 -0
- package/dist/features/sync/crossPlatformSync.d.ts +281 -0
- package/dist/features/sync/crossPlatformSync.d.ts.map +1 -0
- package/dist/features/sync/crossPlatformSync.js +623 -0
- package/dist/features/sync/crossPlatformSync.js.map +1 -0
- package/dist/features/sync/devices/deviceManager.d.ts +243 -0
- package/dist/features/sync/devices/deviceManager.d.ts.map +1 -0
- package/dist/features/sync/devices/deviceManager.js +494 -0
- package/dist/features/sync/devices/deviceManager.js.map +1 -0
- package/dist/features/sync/devices/index.d.ts +10 -0
- package/dist/features/sync/devices/index.d.ts.map +1 -0
- package/dist/features/sync/devices/index.js +10 -0
- package/dist/features/sync/devices/index.js.map +1 -0
- package/dist/features/sync/index.d.ts +37 -0
- package/dist/features/sync/index.d.ts.map +1 -0
- package/dist/features/sync/index.js +47 -0
- package/dist/features/sync/index.js.map +1 -0
- package/dist/features/sync/protocol/index.d.ts +11 -0
- package/dist/features/sync/protocol/index.d.ts.map +1 -0
- package/dist/features/sync/protocol/index.js +11 -0
- package/dist/features/sync/protocol/index.js.map +1 -0
- package/dist/features/sync/protocol/messages.d.ts +348 -0
- package/dist/features/sync/protocol/messages.d.ts.map +1 -0
- package/dist/features/sync/protocol/messages.js +216 -0
- package/dist/features/sync/protocol/messages.js.map +1 -0
- package/dist/features/sync/protocol/vectorClock.d.ts +164 -0
- package/dist/features/sync/protocol/vectorClock.d.ts.map +1 -0
- package/dist/features/sync/protocol/vectorClock.js +286 -0
- package/dist/features/sync/protocol/vectorClock.js.map +1 -0
- package/dist/features/sync/tables/index.d.ts +10 -0
- package/dist/features/sync/tables/index.d.ts.map +1 -0
- package/dist/features/sync/tables/index.js +10 -0
- package/dist/features/sync/tables/index.js.map +1 -0
- package/dist/features/sync/tables/syncLogManager.d.ts +216 -0
- package/dist/features/sync/tables/syncLogManager.d.ts.map +1 -0
- package/dist/features/sync/tables/syncLogManager.js +456 -0
- package/dist/features/sync/tables/syncLogManager.js.map +1 -0
- package/dist/features/sync/transport/httpTransport.d.ts +123 -0
- package/dist/features/sync/transport/httpTransport.d.ts.map +1 -0
- package/dist/features/sync/transport/httpTransport.js +380 -0
- package/dist/features/sync/transport/httpTransport.js.map +1 -0
- package/dist/features/sync/transport/index.d.ts +12 -0
- package/dist/features/sync/transport/index.d.ts.map +1 -0
- package/dist/features/sync/transport/index.js +12 -0
- package/dist/features/sync/transport/index.js.map +1 -0
- package/dist/features/sync/transport/transport.d.ts +259 -0
- package/dist/features/sync/transport/transport.d.ts.map +1 -0
- package/dist/features/sync/transport/transport.js +153 -0
- package/dist/features/sync/transport/transport.js.map +1 -0
- package/dist/features/sync/transport/websocketTransport.d.ts +126 -0
- package/dist/features/sync/transport/websocketTransport.d.ts.map +1 -0
- package/dist/features/sync/transport/websocketTransport.js +374 -0
- package/dist/features/sync/transport/websocketTransport.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/package.json +21 -1
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Electron Main Process Storage Adapter.
|
|
3
|
+
*
|
|
4
|
+
* Wraps BetterSqliteAdapter for use in Electron's main process.
|
|
5
|
+
* Handles IPC communication, WAL management, crash recovery,
|
|
6
|
+
* and multi-window coordination.
|
|
7
|
+
*
|
|
8
|
+
* ## Architecture
|
|
9
|
+
* This adapter runs in the main process and owns the actual database connection.
|
|
10
|
+
* Renderer processes communicate with it via IPC using ElectronRendererAdapter.
|
|
11
|
+
*
|
|
12
|
+
* ## Features
|
|
13
|
+
* - WAL mode with configurable checkpointing
|
|
14
|
+
* - Integrity checking and auto-repair
|
|
15
|
+
* - Multi-window change broadcasting
|
|
16
|
+
* - Cloud backup scheduling
|
|
17
|
+
* - Auto-migration on app updates
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { createElectronMainAdapter } from '@framers/sql-storage-adapter/electron';
|
|
22
|
+
* import { app } from 'electron';
|
|
23
|
+
* import path from 'path';
|
|
24
|
+
*
|
|
25
|
+
* const db = await createElectronMainAdapter({
|
|
26
|
+
* filePath: path.join(app.getPath('userData'), 'app.db'),
|
|
27
|
+
* wal: { enabled: true, checkpointInterval: 300000 },
|
|
28
|
+
* recovery: { enabled: true, checkOnOpen: true },
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* await db.open();
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
import path from 'path';
|
|
35
|
+
import { BrowserWindow } from 'electron';
|
|
36
|
+
import { createBetterSqliteAdapter } from '../betterSqliteAdapter.js';
|
|
37
|
+
import { initializeIpcProtocol, disposeIpcProtocol } from './ipc/protocol.js';
|
|
38
|
+
import { BROADCAST_CHANNELS } from './ipc/channels.js';
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// Default Configurations
|
|
41
|
+
// ============================================================================
|
|
42
|
+
const DEFAULT_WAL_CONFIG = {
|
|
43
|
+
enabled: true,
|
|
44
|
+
checkpointInterval: 300000, // 5 minutes
|
|
45
|
+
autoCheckpointPages: 1000,
|
|
46
|
+
synchronous: 'NORMAL',
|
|
47
|
+
};
|
|
48
|
+
const DEFAULT_RECOVERY_CONFIG = {
|
|
49
|
+
enabled: true,
|
|
50
|
+
checkOnOpen: true,
|
|
51
|
+
autoRepair: true,
|
|
52
|
+
integrityCheckTimeout: 30000,
|
|
53
|
+
};
|
|
54
|
+
const DEFAULT_MULTI_WINDOW_CONFIG = {
|
|
55
|
+
enabled: true,
|
|
56
|
+
broadcastChanges: true,
|
|
57
|
+
};
|
|
58
|
+
// ============================================================================
|
|
59
|
+
// Electron Main Adapter
|
|
60
|
+
// ============================================================================
|
|
61
|
+
/**
|
|
62
|
+
* Electron Main Process Storage Adapter.
|
|
63
|
+
*
|
|
64
|
+
* This adapter is designed to run exclusively in Electron's main process.
|
|
65
|
+
* It wraps BetterSqliteAdapter and adds Electron-specific features like
|
|
66
|
+
* IPC handling, multi-window coordination, and crash recovery.
|
|
67
|
+
*/
|
|
68
|
+
export class ElectronMainAdapter {
|
|
69
|
+
constructor(options) {
|
|
70
|
+
this.kind = 'electron-main';
|
|
71
|
+
this.isInitialized = false;
|
|
72
|
+
this.walCheckpointTimer = null;
|
|
73
|
+
this.backupTimer = null;
|
|
74
|
+
this.options = options;
|
|
75
|
+
// Merge configs with defaults
|
|
76
|
+
this.walConfig = { ...DEFAULT_WAL_CONFIG, ...options.wal };
|
|
77
|
+
this.recoveryConfig = { ...DEFAULT_RECOVERY_CONFIG, ...options.recovery };
|
|
78
|
+
this.multiWindowConfig = { ...DEFAULT_MULTI_WINDOW_CONFIG, ...options.multiWindow };
|
|
79
|
+
// Create inner adapter
|
|
80
|
+
this.innerAdapter = createBetterSqliteAdapter(options.filePath);
|
|
81
|
+
// Add electron-specific capabilities
|
|
82
|
+
const baseCapabilities = new Set(this.innerAdapter.capabilities);
|
|
83
|
+
baseCapabilities.add('batch');
|
|
84
|
+
this.capabilities = baseCapabilities;
|
|
85
|
+
}
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// Lifecycle Methods
|
|
88
|
+
// ============================================================================
|
|
89
|
+
/**
|
|
90
|
+
* Open the database and initialize all subsystems.
|
|
91
|
+
*/
|
|
92
|
+
async open(openOptions) {
|
|
93
|
+
if (this.isInitialized) {
|
|
94
|
+
this.log('Already initialized, skipping open()');
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
// Open the underlying database
|
|
99
|
+
await this.innerAdapter.open(openOptions);
|
|
100
|
+
// Run integrity check if enabled
|
|
101
|
+
if (this.recoveryConfig.enabled && this.recoveryConfig.checkOnOpen) {
|
|
102
|
+
await this.runIntegrityCheck();
|
|
103
|
+
}
|
|
104
|
+
// Configure WAL mode
|
|
105
|
+
if (this.walConfig.enabled) {
|
|
106
|
+
await this.configureWalMode();
|
|
107
|
+
this.startWalCheckpointTimer();
|
|
108
|
+
}
|
|
109
|
+
// Initialize IPC protocol for renderer communication
|
|
110
|
+
initializeIpcProtocol(this);
|
|
111
|
+
// Start backup scheduler if enabled
|
|
112
|
+
if (this.options.backup?.enabled && this.options.backup.provider) {
|
|
113
|
+
this.startBackupScheduler();
|
|
114
|
+
}
|
|
115
|
+
this.isInitialized = true;
|
|
116
|
+
this.log('Electron Main Adapter initialized successfully');
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
this.log(`Failed to initialize: ${error}`);
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Close the database and cleanup all subsystems.
|
|
125
|
+
*/
|
|
126
|
+
async close() {
|
|
127
|
+
if (!this.isInitialized) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
// Stop timers
|
|
132
|
+
if (this.walCheckpointTimer) {
|
|
133
|
+
clearInterval(this.walCheckpointTimer);
|
|
134
|
+
this.walCheckpointTimer = null;
|
|
135
|
+
}
|
|
136
|
+
if (this.backupTimer) {
|
|
137
|
+
clearInterval(this.backupTimer);
|
|
138
|
+
this.backupTimer = null;
|
|
139
|
+
}
|
|
140
|
+
// Final WAL checkpoint before closing
|
|
141
|
+
if (this.walConfig.enabled) {
|
|
142
|
+
await this.runWalCheckpoint();
|
|
143
|
+
}
|
|
144
|
+
// Dispose IPC handlers
|
|
145
|
+
disposeIpcProtocol();
|
|
146
|
+
// Close inner adapter
|
|
147
|
+
await this.innerAdapter.close();
|
|
148
|
+
this.isInitialized = false;
|
|
149
|
+
this.log('Electron Main Adapter closed');
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
this.log(`Error during close: ${error}`);
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// ============================================================================
|
|
157
|
+
// Storage Adapter Interface
|
|
158
|
+
// ============================================================================
|
|
159
|
+
async run(statement, parameters) {
|
|
160
|
+
const result = await this.innerAdapter.run(statement, parameters);
|
|
161
|
+
// Broadcast change to all windows
|
|
162
|
+
if (this.multiWindowConfig.enabled && this.multiWindowConfig.broadcastChanges) {
|
|
163
|
+
this.broadcastChange({
|
|
164
|
+
type: this.detectMutationType(statement),
|
|
165
|
+
tables: this.extractTables(statement),
|
|
166
|
+
changes: result.changes,
|
|
167
|
+
timestamp: Date.now(),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
async get(statement, parameters) {
|
|
173
|
+
return this.innerAdapter.get(statement, parameters);
|
|
174
|
+
}
|
|
175
|
+
async all(statement, parameters) {
|
|
176
|
+
return this.innerAdapter.all(statement, parameters);
|
|
177
|
+
}
|
|
178
|
+
async exec(script) {
|
|
179
|
+
await this.innerAdapter.exec(script);
|
|
180
|
+
// Broadcast change for exec operations
|
|
181
|
+
if (this.multiWindowConfig.enabled && this.multiWindowConfig.broadcastChanges) {
|
|
182
|
+
this.broadcastChange({
|
|
183
|
+
type: 'transaction',
|
|
184
|
+
tables: [],
|
|
185
|
+
changes: 0,
|
|
186
|
+
timestamp: Date.now(),
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async transaction(fn) {
|
|
191
|
+
const result = await this.innerAdapter.transaction(fn);
|
|
192
|
+
// Broadcast change after transaction
|
|
193
|
+
if (this.multiWindowConfig.enabled && this.multiWindowConfig.broadcastChanges) {
|
|
194
|
+
this.broadcastChange({
|
|
195
|
+
type: 'transaction',
|
|
196
|
+
tables: [],
|
|
197
|
+
changes: 0,
|
|
198
|
+
timestamp: Date.now(),
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
203
|
+
async batch(operations) {
|
|
204
|
+
if (!this.innerAdapter.batch) {
|
|
205
|
+
throw new Error('Batch operations not supported');
|
|
206
|
+
}
|
|
207
|
+
const result = await this.innerAdapter.batch(operations);
|
|
208
|
+
// Broadcast change
|
|
209
|
+
if (this.multiWindowConfig.enabled && this.multiWindowConfig.broadcastChanges) {
|
|
210
|
+
this.broadcastChange({
|
|
211
|
+
type: 'transaction',
|
|
212
|
+
tables: operations.flatMap(op => this.extractTables(op.statement)),
|
|
213
|
+
changes: result.successful,
|
|
214
|
+
timestamp: Date.now(),
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
prepare(statement) {
|
|
220
|
+
if (!this.innerAdapter.prepare) {
|
|
221
|
+
throw new Error('Prepared statements not supported');
|
|
222
|
+
}
|
|
223
|
+
return this.innerAdapter.prepare(statement);
|
|
224
|
+
}
|
|
225
|
+
// ============================================================================
|
|
226
|
+
// WAL Management
|
|
227
|
+
// ============================================================================
|
|
228
|
+
/**
|
|
229
|
+
* Configure WAL mode on the database.
|
|
230
|
+
*/
|
|
231
|
+
async configureWalMode() {
|
|
232
|
+
await this.innerAdapter.exec(`
|
|
233
|
+
PRAGMA journal_mode = WAL;
|
|
234
|
+
PRAGMA synchronous = ${this.walConfig.synchronous};
|
|
235
|
+
PRAGMA wal_autocheckpoint = ${this.walConfig.autoCheckpointPages};
|
|
236
|
+
`);
|
|
237
|
+
this.log('WAL mode configured');
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Start the WAL checkpoint timer.
|
|
241
|
+
*/
|
|
242
|
+
startWalCheckpointTimer() {
|
|
243
|
+
if (this.walCheckpointTimer) {
|
|
244
|
+
clearInterval(this.walCheckpointTimer);
|
|
245
|
+
}
|
|
246
|
+
this.walCheckpointTimer = setInterval(() => this.runWalCheckpoint().catch(err => this.log(`WAL checkpoint error: ${err}`)), this.walConfig.checkpointInterval);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Run a WAL checkpoint.
|
|
250
|
+
*/
|
|
251
|
+
async runWalCheckpoint() {
|
|
252
|
+
const result = await this.innerAdapter.get('PRAGMA wal_checkpoint(PASSIVE)');
|
|
253
|
+
const checkpointResult = {
|
|
254
|
+
framesCheckpointed: result?.checkpointed ?? 0,
|
|
255
|
+
totalFrames: result?.log ?? 0,
|
|
256
|
+
};
|
|
257
|
+
this.log(`WAL checkpoint: ${checkpointResult.framesCheckpointed}/${checkpointResult.totalFrames} frames`);
|
|
258
|
+
return checkpointResult;
|
|
259
|
+
}
|
|
260
|
+
// ============================================================================
|
|
261
|
+
// Integrity Check & Recovery
|
|
262
|
+
// ============================================================================
|
|
263
|
+
/**
|
|
264
|
+
* Run an integrity check on the database.
|
|
265
|
+
*/
|
|
266
|
+
async runIntegrityCheck() {
|
|
267
|
+
const results = await this.innerAdapter.all('PRAGMA integrity_check');
|
|
268
|
+
const issues = results
|
|
269
|
+
.map(r => r.integrity_check)
|
|
270
|
+
.filter(msg => msg !== 'ok');
|
|
271
|
+
const ok = issues.length === 0;
|
|
272
|
+
if (!ok) {
|
|
273
|
+
this.log(`Integrity check found ${issues.length} issues`);
|
|
274
|
+
if (this.recoveryConfig.autoRepair) {
|
|
275
|
+
await this.attemptRepair();
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
this.log('Integrity check passed');
|
|
280
|
+
}
|
|
281
|
+
return { ok, issues };
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Attempt to repair the database.
|
|
285
|
+
*/
|
|
286
|
+
async attemptRepair() {
|
|
287
|
+
this.log('Attempting database repair...');
|
|
288
|
+
try {
|
|
289
|
+
// Try VACUUM to rebuild the database
|
|
290
|
+
await this.innerAdapter.exec('VACUUM');
|
|
291
|
+
this.log('VACUUM completed successfully');
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
this.log(`Repair failed: ${error}`);
|
|
295
|
+
throw new Error(`Database repair failed: ${error}`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// ============================================================================
|
|
299
|
+
// Backup Management
|
|
300
|
+
// ============================================================================
|
|
301
|
+
/**
|
|
302
|
+
* Start the backup scheduler.
|
|
303
|
+
*/
|
|
304
|
+
startBackupScheduler() {
|
|
305
|
+
const interval = this.options.backup?.interval ?? 3600000;
|
|
306
|
+
this.backupTimer = setInterval(() => this.runBackup().catch(err => this.log(`Backup error: ${err}`)), interval);
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Run a backup.
|
|
310
|
+
*/
|
|
311
|
+
async runBackup() {
|
|
312
|
+
if (!this.options.backup?.provider) {
|
|
313
|
+
throw new Error('No backup provider configured');
|
|
314
|
+
}
|
|
315
|
+
const backupPath = `${this.options.filePath}.backup`;
|
|
316
|
+
const remotePath = `backups/${path.basename(this.options.filePath)}_${Date.now()}.db`;
|
|
317
|
+
// Create a backup using VACUUM INTO
|
|
318
|
+
await this.innerAdapter.exec(`VACUUM INTO '${backupPath}'`);
|
|
319
|
+
// Upload to cloud
|
|
320
|
+
await this.options.backup.provider.upload(backupPath, remotePath);
|
|
321
|
+
// Cleanup old backups
|
|
322
|
+
await this.cleanupOldBackups();
|
|
323
|
+
this.log(`Backup completed: ${remotePath}`);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Cleanup old backups beyond the retention limit.
|
|
327
|
+
*/
|
|
328
|
+
async cleanupOldBackups() {
|
|
329
|
+
if (!this.options.backup?.provider)
|
|
330
|
+
return;
|
|
331
|
+
const maxBackups = this.options.backup.maxBackups ?? 7;
|
|
332
|
+
const backups = await this.options.backup.provider.list();
|
|
333
|
+
if (backups.length > maxBackups) {
|
|
334
|
+
// Sort by date, oldest first
|
|
335
|
+
backups.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
|
336
|
+
// Delete oldest backups
|
|
337
|
+
const toDelete = backups.slice(0, backups.length - maxBackups);
|
|
338
|
+
for (const backup of toDelete) {
|
|
339
|
+
await this.options.backup.provider.delete(backup.path);
|
|
340
|
+
this.log(`Deleted old backup: ${backup.path}`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
// ============================================================================
|
|
345
|
+
// Multi-Window Broadcasting
|
|
346
|
+
// ============================================================================
|
|
347
|
+
/**
|
|
348
|
+
* Broadcast a database change to all windows.
|
|
349
|
+
*/
|
|
350
|
+
broadcastChange(change) {
|
|
351
|
+
const allWindows = BrowserWindow.getAllWindows();
|
|
352
|
+
for (const win of allWindows) {
|
|
353
|
+
if (!win.isDestroyed()) {
|
|
354
|
+
win.webContents.send(BROADCAST_CHANNELS.DB_CHANGE, change);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
// ============================================================================
|
|
359
|
+
// Helper Methods
|
|
360
|
+
// ============================================================================
|
|
361
|
+
/**
|
|
362
|
+
* Detect mutation type from SQL statement.
|
|
363
|
+
*/
|
|
364
|
+
detectMutationType(statement) {
|
|
365
|
+
const upper = statement.trim().toUpperCase();
|
|
366
|
+
if (upper.startsWith('INSERT'))
|
|
367
|
+
return 'insert';
|
|
368
|
+
if (upper.startsWith('UPDATE'))
|
|
369
|
+
return 'update';
|
|
370
|
+
if (upper.startsWith('DELETE'))
|
|
371
|
+
return 'delete';
|
|
372
|
+
return 'transaction';
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Extract table names from SQL statement.
|
|
376
|
+
*/
|
|
377
|
+
extractTables(statement) {
|
|
378
|
+
const tables = [];
|
|
379
|
+
const patterns = [
|
|
380
|
+
/FROM\s+([^\s,;(]+)/gi,
|
|
381
|
+
/INSERT\s+INTO\s+([^\s(]+)/i,
|
|
382
|
+
/UPDATE\s+([^\s]+)/i,
|
|
383
|
+
/DELETE\s+FROM\s+([^\s]+)/i,
|
|
384
|
+
];
|
|
385
|
+
for (const pattern of patterns) {
|
|
386
|
+
const matches = statement.matchAll(pattern);
|
|
387
|
+
for (const match of matches) {
|
|
388
|
+
if (match[1]) {
|
|
389
|
+
tables.push(match[1].toLowerCase().replace(/["`[\]]/g, ''));
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return [...new Set(tables)];
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Log a message if verbose mode is enabled.
|
|
397
|
+
*/
|
|
398
|
+
log(message) {
|
|
399
|
+
if (this.options.verbose) {
|
|
400
|
+
console.log(`[ElectronMainAdapter] ${message}`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// ============================================================================
|
|
404
|
+
// Public Utilities
|
|
405
|
+
// ============================================================================
|
|
406
|
+
/**
|
|
407
|
+
* Check if the adapter is initialized.
|
|
408
|
+
*/
|
|
409
|
+
isOpen() {
|
|
410
|
+
return this.isInitialized;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Get the database file path.
|
|
414
|
+
*/
|
|
415
|
+
getFilePath() {
|
|
416
|
+
return this.options.filePath;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
// ============================================================================
|
|
420
|
+
// Factory Function
|
|
421
|
+
// ============================================================================
|
|
422
|
+
/**
|
|
423
|
+
* Create an Electron Main Process Storage Adapter.
|
|
424
|
+
*
|
|
425
|
+
* @param options - Adapter configuration
|
|
426
|
+
* @returns ElectronMainAdapter instance
|
|
427
|
+
*
|
|
428
|
+
* @example
|
|
429
|
+
* ```typescript
|
|
430
|
+
* const db = createElectronMainAdapter({
|
|
431
|
+
* filePath: path.join(app.getPath('userData'), 'app.db'),
|
|
432
|
+
* wal: { enabled: true },
|
|
433
|
+
* recovery: { checkOnOpen: true },
|
|
434
|
+
* });
|
|
435
|
+
*
|
|
436
|
+
* await db.open();
|
|
437
|
+
* ```
|
|
438
|
+
*/
|
|
439
|
+
export function createElectronMainAdapter(options) {
|
|
440
|
+
return new ElectronMainAdapter(options);
|
|
441
|
+
}
|
|
442
|
+
//# sourceMappingURL=electronMainAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"electronMainAdapter.js","sourceRoot":"","sources":["../../../src/adapters/electron/electronMainAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Electron Renderer Process Storage Adapter.
|
|
3
|
+
*
|
|
4
|
+
* Provides the same StorageAdapter interface to renderer processes
|
|
5
|
+
* by proxying all operations to the main process via IPC.
|
|
6
|
+
*
|
|
7
|
+
* ## Architecture
|
|
8
|
+
* This adapter runs in renderer processes and communicates with
|
|
9
|
+
* ElectronMainAdapter in the main process via the preload script API.
|
|
10
|
+
*
|
|
11
|
+
* ## Requirements
|
|
12
|
+
* - Preload script must be loaded and expose `window.sqlStorage`
|
|
13
|
+
* - Main process must have ElectronMainAdapter initialized
|
|
14
|
+
*
|
|
15
|
+
* ## Usage
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { createElectronRendererAdapter } from '@framers/sql-storage-adapter/electron';
|
|
18
|
+
*
|
|
19
|
+
* const db = createElectronRendererAdapter({
|
|
20
|
+
* onDatabaseChange: (change) => {
|
|
21
|
+
* console.log('Database changed:', change);
|
|
22
|
+
* // React to changes from other windows
|
|
23
|
+
* },
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* await db.open();
|
|
27
|
+
* const users = await db.all('SELECT * FROM users');
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
import type { StorageAdapter, StorageCapability, StorageOpenOptions, StorageParameters, StorageRunResult, BatchOperation, BatchResult, PreparedStatement } from '../../core/contracts';
|
|
31
|
+
import type { DbChangeEvent, SyncStatus } from './ipc/types';
|
|
32
|
+
/**
|
|
33
|
+
* Options for ElectronRendererAdapter.
|
|
34
|
+
*/
|
|
35
|
+
export interface ElectronRendererAdapterOptions {
|
|
36
|
+
/**
|
|
37
|
+
* Callback when database changes from another window.
|
|
38
|
+
* Use this to invalidate caches or refresh UI.
|
|
39
|
+
*/
|
|
40
|
+
onDatabaseChange?: (event: DbChangeEvent) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Callback when sync progress updates.
|
|
43
|
+
*/
|
|
44
|
+
onSyncProgress?: (progress: number) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Callback when sync completes.
|
|
47
|
+
*/
|
|
48
|
+
onSyncComplete?: () => void;
|
|
49
|
+
/**
|
|
50
|
+
* Callback when sync encounters an error.
|
|
51
|
+
*/
|
|
52
|
+
onSyncError?: (error: Error) => void;
|
|
53
|
+
/**
|
|
54
|
+
* Enable verbose logging (default: false).
|
|
55
|
+
*/
|
|
56
|
+
verbose?: boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Storage adapter for Electron renderer processes.
|
|
60
|
+
*
|
|
61
|
+
* Proxies all database operations to the main process via IPC.
|
|
62
|
+
* Implements the same StorageAdapter interface as other adapters.
|
|
63
|
+
*/
|
|
64
|
+
export declare class ElectronRendererAdapter implements StorageAdapter {
|
|
65
|
+
readonly kind = "electron-renderer";
|
|
66
|
+
capabilities: ReadonlySet<StorageCapability>;
|
|
67
|
+
private readonly options;
|
|
68
|
+
private eventUnsubscribers;
|
|
69
|
+
private isInitialized;
|
|
70
|
+
private cachedCapabilities;
|
|
71
|
+
constructor(options?: ElectronRendererAdapterOptions);
|
|
72
|
+
/**
|
|
73
|
+
* Get the preload API, throwing if not available.
|
|
74
|
+
*/
|
|
75
|
+
private getApi;
|
|
76
|
+
/**
|
|
77
|
+
* Log a message if verbose mode is enabled.
|
|
78
|
+
*/
|
|
79
|
+
private log;
|
|
80
|
+
/**
|
|
81
|
+
* Open connection to the database via main process.
|
|
82
|
+
*/
|
|
83
|
+
open(options?: StorageOpenOptions): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Close connection.
|
|
86
|
+
*/
|
|
87
|
+
close(): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Subscribe to database events from main process.
|
|
90
|
+
*/
|
|
91
|
+
private subscribeToEvents;
|
|
92
|
+
/**
|
|
93
|
+
* Execute a mutation statement (INSERT, UPDATE, DELETE).
|
|
94
|
+
*/
|
|
95
|
+
run(statement: string, parameters?: StorageParameters): Promise<StorageRunResult>;
|
|
96
|
+
/**
|
|
97
|
+
* Get a single row.
|
|
98
|
+
*/
|
|
99
|
+
get<T = unknown>(statement: string, parameters?: StorageParameters): Promise<T | null>;
|
|
100
|
+
/**
|
|
101
|
+
* Get all matching rows.
|
|
102
|
+
*/
|
|
103
|
+
all<T = unknown>(statement: string, parameters?: StorageParameters): Promise<T[]>;
|
|
104
|
+
/**
|
|
105
|
+
* Execute a SQL script.
|
|
106
|
+
*/
|
|
107
|
+
exec(script: string): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Execute operations within a transaction.
|
|
110
|
+
*/
|
|
111
|
+
transaction<T>(fn: (trx: StorageAdapter) => Promise<T>): Promise<T>;
|
|
112
|
+
/**
|
|
113
|
+
* Execute batch operations.
|
|
114
|
+
*/
|
|
115
|
+
batch(operations: BatchOperation[]): Promise<BatchResult>;
|
|
116
|
+
/**
|
|
117
|
+
* Prepared statements are not directly supported in renderer.
|
|
118
|
+
* Use the main process adapter for prepared statements.
|
|
119
|
+
*/
|
|
120
|
+
prepare?<T = unknown>(_statement: string): PreparedStatement<T>;
|
|
121
|
+
/**
|
|
122
|
+
* Get current sync status.
|
|
123
|
+
*/
|
|
124
|
+
getSyncStatus(): Promise<SyncStatus>;
|
|
125
|
+
/**
|
|
126
|
+
* Trigger a manual sync.
|
|
127
|
+
*/
|
|
128
|
+
triggerSync(): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* Assert that the adapter is open.
|
|
131
|
+
*/
|
|
132
|
+
private assertOpen;
|
|
133
|
+
/**
|
|
134
|
+
* Check if the adapter is open.
|
|
135
|
+
*/
|
|
136
|
+
isOpen(): boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Check if the main process database is open.
|
|
139
|
+
*/
|
|
140
|
+
isMainProcessOpen(): Promise<boolean>;
|
|
141
|
+
/**
|
|
142
|
+
* Add an event listener for database changes.
|
|
143
|
+
*/
|
|
144
|
+
onDatabaseChange(callback: (event: DbChangeEvent) => void): () => void;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Create an Electron Renderer Process Storage Adapter.
|
|
148
|
+
*
|
|
149
|
+
* This adapter proxies all database operations to the main process
|
|
150
|
+
* via IPC. Use it in renderer processes to access the shared database.
|
|
151
|
+
*
|
|
152
|
+
* @param options - Adapter configuration
|
|
153
|
+
* @returns ElectronRendererAdapter instance
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* const db = createElectronRendererAdapter({
|
|
158
|
+
* onDatabaseChange: (change) => {
|
|
159
|
+
* console.log('Database changed:', change);
|
|
160
|
+
* // Refresh data or invalidate caches
|
|
161
|
+
* },
|
|
162
|
+
* });
|
|
163
|
+
*
|
|
164
|
+
* await db.open();
|
|
165
|
+
* const users = await db.all('SELECT * FROM users');
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
export declare function createElectronRendererAdapter(options?: ElectronRendererAdapterOptions): ElectronRendererAdapter;
|
|
169
|
+
/**
|
|
170
|
+
* Helper to detect if running in Electron renderer.
|
|
171
|
+
*/
|
|
172
|
+
export declare function isElectronRenderer(): boolean;
|
|
173
|
+
/**
|
|
174
|
+
* Helper to check if preload API is available.
|
|
175
|
+
*/
|
|
176
|
+
export declare function isPreloadApiAvailable(): boolean;
|
|
177
|
+
//# sourceMappingURL=electronRendererAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"electronRendererAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/electron/electronRendererAdapter.ts"],"names":[],"mappings":"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"}
|