docs: migrate web storage implementation from wa-sql to absurd-sql
- Update web platform storage solution to use absurd-sql with IndexedDB backend - Replace wa-sqlite dependencies with absurd-sql and @jlongster/sql.js - Update WebSQLiteService implementation with SQLiteFS and IndexedDBBackend - Add performance optimizations (WAL mode, mmap, temp store) - Add type-safe query method and improved error handling - Update platform capabilities matrix with new features - Add absurd-sql compatibility checks in migration service This change improves transaction support, performance, and reliability of the web platform's SQLite implementation.
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
This document outlines the implementation of secure storage for the TimeSafari app using Capacitor solutions. The implementation focuses on:
|
||||
|
||||
1. **Platform-Specific Storage Solutions**:
|
||||
- Web: wa-sqlite with IndexedDB backend
|
||||
- Web: absurd-sql with IndexedDB backend
|
||||
- iOS: SQLCipher with Keychain integration
|
||||
- Android: SQLCipher with Keystore integration
|
||||
- Electron: SQLite with secure storage
|
||||
@@ -23,8 +23,8 @@ This document outlines the implementation of secure storage for the TimeSafari a
|
||||
```bash
|
||||
# Core dependencies
|
||||
npm install @capacitor-community/sqlite@6.0.0
|
||||
npm install @wa-sqlite/sql.js@0.8.12
|
||||
npm install @wa-sqlite/sql.js-httpvfs@0.8.12
|
||||
npm install absurd-sql@latest
|
||||
npm install @jlongster/sql.js@latest
|
||||
|
||||
# Platform-specific dependencies
|
||||
npm install @capacitor/preferences@6.0.2
|
||||
@@ -218,13 +218,18 @@ try {
|
||||
|
||||
### 4. Platform-Specific Implementations
|
||||
|
||||
#### Web Platform (wa-sqlite)
|
||||
#### Web Platform (absurd-sql)
|
||||
|
||||
```typescript
|
||||
// src/services/platforms/web/WebSQLiteService.ts
|
||||
import { initSqlJs } from '@jlongster/sql.js';
|
||||
import { SQLiteFS } from 'absurd-sql';
|
||||
import IndexedDBBackend from 'absurd-sql/dist/indexeddb-backend';
|
||||
import { StorageError, StorageErrorCodes } from '../errors/StorageError';
|
||||
|
||||
export class WebSQLiteService implements PlatformService {
|
||||
private db: SQLite.Database | null = null;
|
||||
private vfs: IDBBatchAtomicVFS | null = null;
|
||||
private vfs: SQLiteFS | null = null;
|
||||
private initialized = false;
|
||||
|
||||
async initialize(): Promise<void> {
|
||||
@@ -258,8 +263,8 @@ export class WebSQLiteService implements PlatformService {
|
||||
|
||||
private async initializeSQLite(): Promise<SQLite.SqlJsStatic> {
|
||||
try {
|
||||
return await SQLite.init({
|
||||
locateFile: file => `https://cdn.jsdelivr.net/npm/@wa-sqlite/sql.js@0.8.12/dist/${file}`
|
||||
return await initSqlJs({
|
||||
locateFile: file => `https://cdn.jsdelivr.net/npm/@jlongster/sql.js@latest/dist/${file}`
|
||||
});
|
||||
} catch (error) {
|
||||
throw new StorageError(
|
||||
@@ -272,8 +277,14 @@ export class WebSQLiteService implements PlatformService {
|
||||
|
||||
private async setupVFS(sqlite3: SQLite.SqlJsStatic): Promise<void> {
|
||||
try {
|
||||
this.vfs = new IDBBatchAtomicVFS('timesafari');
|
||||
await this.vfs.registerVFS(sqlite3);
|
||||
// Initialize IndexedDB backend
|
||||
const backend = new IndexedDBBackend();
|
||||
|
||||
// Create SQLiteFS instance
|
||||
this.vfs = new SQLiteFS(backend, sqlite3);
|
||||
|
||||
// Register the VFS
|
||||
sqlite3.register_for_idb(this.vfs);
|
||||
} catch (error) {
|
||||
throw new StorageError(
|
||||
'Failed to set up IndexedDB VFS',
|
||||
@@ -292,6 +303,7 @@ export class WebSQLiteService implements PlatformService {
|
||||
}
|
||||
|
||||
try {
|
||||
// Open database with absurd-sql
|
||||
this.db = await this.vfs.openDatabase('timesafari.db');
|
||||
await this.setupPragmas();
|
||||
} catch (error) {
|
||||
@@ -312,6 +324,8 @@ export class WebSQLiteService implements PlatformService {
|
||||
PRAGMA synchronous = NORMAL;
|
||||
PRAGMA foreign_keys = ON;
|
||||
PRAGMA busy_timeout = 5000;
|
||||
PRAGMA temp_store = MEMORY;
|
||||
PRAGMA mmap_size = 30000000000;
|
||||
`);
|
||||
} catch (error) {
|
||||
throw new StorageError(
|
||||
@@ -329,6 +343,34 @@ export class WebSQLiteService implements PlatformService {
|
||||
}
|
||||
this.initialized = false;
|
||||
}
|
||||
|
||||
// Example query method
|
||||
async query<T>(sql: string, params: any[] = []): Promise<T[]> {
|
||||
if (!this.db) {
|
||||
throw new StorageError(
|
||||
'Database not initialized',
|
||||
StorageErrorCodes.INITIALIZATION_FAILED
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const stmt = this.db.prepare(sql);
|
||||
const results: T[] = [];
|
||||
|
||||
while (stmt.step()) {
|
||||
results.push(stmt.getAsObject() as T);
|
||||
}
|
||||
|
||||
stmt.free();
|
||||
return results;
|
||||
} catch (error) {
|
||||
throw new StorageError(
|
||||
'Query failed',
|
||||
StorageErrorCodes.QUERY_FAILED,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Migration strategy for web platform
|
||||
@@ -369,6 +411,14 @@ export class WebMigrationService {
|
||||
StorageErrorCodes.INITIALIZATION_FAILED
|
||||
);
|
||||
}
|
||||
|
||||
// Check absurd-sql compatibility
|
||||
if (!window.indexedDB.databases) {
|
||||
throw new StorageError(
|
||||
'Browser does not support required IndexedDB features',
|
||||
StorageErrorCodes.INITIALIZATION_FAILED
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async createBackup(): Promise<MigrationBackup> {
|
||||
@@ -916,7 +966,7 @@ CREATE INDEX idx_settings_updated_at ON settings(updated_at);
|
||||
|
||||
| Feature | Web | iOS | Android | Electron |
|
||||
|---------|-----|-----|---------|----------|
|
||||
| SQLite | wa-sqlite | SQLCipher | SQLCipher | SQLite |
|
||||
| SQLite | absurd-sql | SQLCipher | SQLCipher | SQLite |
|
||||
| Encryption | SQLCipher | SQLCipher | SQLCipher | SQLCipher |
|
||||
| Secure Storage | IndexedDB | Keychain | Keystore | Secure Storage |
|
||||
| Biometrics | No | Yes | Yes | No |
|
||||
@@ -924,6 +974,8 @@ CREATE INDEX idx_settings_updated_at ON settings(updated_at);
|
||||
| Background Sync | No | Yes | Yes | Yes |
|
||||
| Storage Quota | Yes | No | No | No |
|
||||
| Multi-tab Support | Yes | N/A | N/A | Yes |
|
||||
| WAL Mode | Yes | Yes | Yes | Yes |
|
||||
| Atomic Transactions | Yes | Yes | Yes | Yes |
|
||||
|
||||
### D. Usage Examples
|
||||
|
||||
|
||||
Reference in New Issue
Block a user