this repo has no description
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: live update on sync

authored by

Anish Lakhwara and committed by
sōm
d907c3d8 2da88321

+85 -16
+1 -1
mast-react-vite/src/App.tsx
··· 57 57 const todos = useQuery( 58 58 ctx, 59 59 `SELECT * FROM active_todos ${whereClause ? "WHERE " + whereClause : ""}`, 60 - newParams, 60 + newParams, 61 61 ).data; 62 62 63 63 useEffect(() => {
+1
mast-react-vite/src/hooks/use-sync.ts
··· 56 56 setLastSyncTime(new Date()); 57 57 break; 58 58 case 'CHANGES_APPLIED': 59 + case 'DB_UPDATED': 59 60 setChangesReceived(prev => prev + (count || 0)); 60 61 setLastSyncTime(new Date()); 61 62 break;
+70 -3
mast-react-vite/src/main.tsx
··· 2 2 import "./index.css"; 3 3 import App from "./App.tsx"; 4 4 import { Helmet } from "react-helmet"; 5 - import { DBAsync } from "@vlcn.io/xplat-api"; 5 + import { DBAsync, UPDATE_TYPE, UpdateType } from "@vlcn.io/xplat-api"; 6 6 import initWasm from "@vlcn.io/crsqlite-wasm"; 7 7 import wasmUrl from "@vlcn.io/crsqlite-wasm/crsqlite.wasm?url"; 8 8 import tblrx from "@vlcn.io/rx-tbl"; 9 9 import { SelectionProvider } from "@/contexts/selection-context"; 10 10 import { useCustomSync } from "@/hooks/use-sync"; 11 11 import { SyncStatus } from "@/components/ui/sync-status"; 12 + 13 + // Create a module-scoped registry for database instances 14 + const dbRegistry = new Map<string, { rx: any, db: any }>(); 15 + 16 + // Function to notify database listeners for a specific database 17 + export function notifyDbListeners(dbname: string) { 18 + const ctx = dbRegistry.get(dbname); 19 + if (ctx) { 20 + console.log(`Notifying listeners for database: ${dbname}`); 21 + 22 + // Get all tables in the database 23 + // For simplicity, we'll just use the todos table since we know it exists 24 + const tables = ["todos"]; 25 + 26 + // Create synthetic changes for each table 27 + // This tells the system that each table has been updated 28 + const changes: [number, string, bigint][] = tables.map(table => [ 29 + UPDATE_TYPE.UPDATE, // We use UPDATE as a general change type 30 + table, // Table name 31 + 0n // Using 0n as a generic rowid 32 + ]); 33 + 34 + // Call the internal notify function 35 + // First try with changes parameter 36 + try { 37 + console.log(`Calling __internalNotifyListeners with ${changes.length} changes`); 38 + ctx.rx.__internalNotifyListeners(changes); 39 + } catch (error) { 40 + console.error('Error with changes parameter:', error); 41 + 42 + // Fallback to no parameters 43 + try { 44 + console.log('Calling __internalNotifyListeners with no parameters'); 45 + ctx.rx.__internalNotifyListeners(); 46 + } catch (error) { 47 + console.error('Error with no parameters:', error); 48 + } 49 + } 50 + return true; 51 + } 52 + console.warn(`No database context found for ${dbname}`); 53 + return false; 54 + } 12 55 13 56 // Create a worker instance only once 14 57 import SyncWorker from './worker/sync-worker.ts?worker'; ··· 263 306 WHERE completed = 0; 264 307 `); 265 308 const rx = tblrx(db); 309 + 310 + // Register the database context 311 + dbRegistry.set(dbname, { db, rx }); 312 + console.log(`Registered database ${dbname} in registry`); 313 + 314 + // Add cleanup when the component unmounts 315 + window.addEventListener('beforeunload', () => { 316 + const ctx = dbRegistry.get(dbname); 317 + if (ctx) { 318 + // Proper cleanup 319 + ctx.db.close(); 320 + dbRegistry.delete(dbname); 321 + } 322 + }); 323 + 266 324 return { db, rx, roomId, dbname }; 267 325 }; 268 326 ··· 372 430 373 431 // Handle worker messages 374 432 syncWorker.addEventListener('message', async (event) => { 375 - const { type, dbname, payload, room } = event.data; 433 + const { type, dbname, payload, room, count } = event.data; 376 434 377 435 if (type === 'REQUEST_SIGNATURE') { 378 436 console.log('Received request for signature', { dbname, room }); ··· 405 463 message: authMessage 406 464 }); 407 465 }, 0); 466 + } else if (type === 'DB_UPDATED') { 467 + console.log(`🔄 SYNC: Received DB_UPDATED for ${dbname}`); 468 + const result = notifyDbListeners(dbname); 469 + console.log(`🔄 SYNC: Notification result: ${result ? 'success' : 'failed'}`); 408 470 } 409 471 }); 410 472 473 + // Export the function so it can be used elsewhere if needed 474 + (window as any).notifyDbListeners = notifyDbListeners; 475 + 411 476 const init = async () => { 412 477 const ctx = await initDb(); 413 478 414 - // Make the worker available globally for debugging 479 + // Make useful objects available globally for debugging 415 480 (window as any).syncWorker = syncWorker; 481 + (window as any).notifyDbListeners = notifyDbListeners; 482 + (window as any).dbRegistry = dbRegistry; 416 483 417 484 createRoot(document.getElementById("root") as HTMLElement).render( 418 485 <>
+13 -12
mast-react-vite/src/worker/sync-worker.ts
··· 363 363 // Notify main thread that changes were sent 364 364 self.postMessage({ type: 'CHANGES_SENT', dbname, count: changes.length }); 365 365 366 + // Notify main thread that database was updated 367 + logDebug(`🔄 DATABASE UPDATED: Notifying main thread for ${dbname} after sending ${changes.length} changes`); 368 + self.postMessage({ 369 + type: 'DB_UPDATED', 370 + dbname 371 + }); 372 + 366 373 } catch (error) { 367 374 logError(`Error sending changes:`, error); 368 375 self.postMessage({ type: 'SYNC_ERROR', dbname, error: 'Failed to send changes' }); ··· 447 454 logDebug(`Updated lastSyncVersion to ${maxVersion}`); 448 455 } 449 456 450 - // Notify main thread that changes were applied and force a query refresh 451 - try { 452 - // This will trigger a database update event that @vlcn.io/rx-tbl will detect 453 - // Force a dummy statement that touches the database to trigger update subscriptions 454 - // Creating a temporary table will cause SQLite to touch the database file 455 - await connection.db.exec('SELECT 1;'); 456 - } catch (error) { 457 - logError('Error triggering database refresh:', error); 458 - } 459 - 460 - // Notify main thread that changes were applied 461 - self.postMessage({ type: 'CHANGES_APPLIED', dbname, count: changes.length }); 457 + // Notify main thread that database was updated 458 + logDebug(`🔄 DATABASE UPDATED: Notifying main thread for ${dbname} with ${changes.length} changes`); 459 + self.postMessage({ 460 + type: 'DB_UPDATED', 461 + dbname 462 + }); 462 463 463 464 } catch (error) { 464 465 logError(`Error applying changes:`, error);