diff --git a/app/entry.client.tsx b/app/entry.client.tsx index b8a6dd3da..ef8f29056 100644 --- a/app/entry.client.tsx +++ b/app/entry.client.tsx @@ -5,32 +5,59 @@ import { createScopedLogger } from '~/utils/logger'; const logger = createScopedLogger('Client'); +function isChrome(): boolean { + return /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); +} + // Initialize IndexedDB before hydration async function initIndexedDB() { if (typeof window === 'undefined' || !window.indexedDB) { logger.debug('IndexedDB not available'); + window.__BOLT_PERSISTENCE_AVAILABLE__ = false; return false; } return new Promise((resolve) => { try { - // Test if we can actually open IndexedDB - const testRequest = window.indexedDB.open('test'); - testRequest.onerror = () => { - logger.error('IndexedDB test failed'); - resolve(false); - }; + // For Chrome, we need to be more careful with initialization + if (isChrome()) { + // First, try to delete any existing database to ensure a clean state + const deleteRequest = window.indexedDB.deleteDatabase('boltHistory'); + deleteRequest.onsuccess = () => { + // Now create a fresh database + const request = window.indexedDB.open('boltHistory', 1); + request.onerror = () => { + logger.error('Failed to open database'); + window.__BOLT_PERSISTENCE_AVAILABLE__ = false; + resolve(false); + }; - testRequest.onsuccess = () => { - // Close and delete test database - const db = testRequest.result; - db.close(); - window.indexedDB.deleteDatabase('test'); + request.onupgradeneeded = (event) => { + const db = (event.target as IDBOpenDBRequest).result; + if (!db.objectStoreNames.contains('chats')) { + const store = db.createObjectStore('chats', { keyPath: 'id' }); + store.createIndex('id', 'id', { unique: true }); + store.createIndex('urlId', 'urlId', { unique: true }); + } + }; - // Now open the actual database + request.onsuccess = () => { + logger.debug('Database initialized'); + window.__BOLT_PERSISTENCE_AVAILABLE__ = true; + resolve(true); + }; + }; + deleteRequest.onerror = () => { + logger.error('Failed to delete old database'); + window.__BOLT_PERSISTENCE_AVAILABLE__ = false; + resolve(false); + }; + } else { + // For other browsers, use the standard approach const request = window.indexedDB.open('boltHistory', 1); request.onerror = () => { logger.error('Failed to open database'); + window.__BOLT_PERSISTENCE_AVAILABLE__ = false; resolve(false); }; @@ -45,21 +72,23 @@ async function initIndexedDB() { request.onsuccess = () => { logger.debug('Database initialized'); + window.__BOLT_PERSISTENCE_AVAILABLE__ = true; resolve(true); }; - }; + } } catch (error) { logger.error('Error initializing database:', error); + window.__BOLT_PERSISTENCE_AVAILABLE__ = false; resolve(false); } }); } -// Initialize IndexedDB before hydrating the app -initIndexedDB().then((success) => { - // Set a global flag for persistence status - window.__BOLT_PERSISTENCE_AVAILABLE__ = success; +// Set initial persistence state +window.__BOLT_PERSISTENCE_AVAILABLE__ = false; +// Initialize IndexedDB before hydrating the app +initIndexedDB().then(() => { startTransition(() => { hydrateRoot(document.getElementById('root')!, ); }); diff --git a/app/root.tsx b/app/root.tsx index 6d269bedd..6a57f64d2 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -53,15 +53,52 @@ const inlineThemeCode = stripIndents` // Initialize IndexedDB early if (typeof window !== 'undefined' && window.indexedDB) { - const request = window.indexedDB.open('boltHistory', 1); - request.onupgradeneeded = (event) => { - const db = event.target.result; - if (!db.objectStoreNames.contains('chats')) { - const store = db.createObjectStore('chats', { keyPath: 'id' }); - store.createIndex('id', 'id', { unique: true }); - store.createIndex('urlId', 'urlId', { unique: true }); - } - }; + window.__BOLT_PERSISTENCE_AVAILABLE__ = false; + + // Check if we're in Chrome + const isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); + + if (isChrome) { + // For Chrome, we need to be more careful with initialization + const deleteRequest = window.indexedDB.deleteDatabase('boltHistory'); + deleteRequest.onsuccess = () => { + const request = window.indexedDB.open('boltHistory', 1); + request.onupgradeneeded = (event) => { + const db = event.target.result; + if (!db.objectStoreNames.contains('chats')) { + const store = db.createObjectStore('chats', { keyPath: 'id' }); + store.createIndex('id', 'id', { unique: true }); + store.createIndex('urlId', 'urlId', { unique: true }); + } + }; + request.onsuccess = () => { + window.__BOLT_PERSISTENCE_AVAILABLE__ = true; + }; + request.onerror = () => { + window.__BOLT_PERSISTENCE_AVAILABLE__ = false; + }; + }; + deleteRequest.onerror = () => { + window.__BOLT_PERSISTENCE_AVAILABLE__ = false; + }; + } else { + // For other browsers, use the standard approach + const request = window.indexedDB.open('boltHistory', 1); + request.onupgradeneeded = (event) => { + const db = event.target.result; + if (!db.objectStoreNames.contains('chats')) { + const store = db.createObjectStore('chats', { keyPath: 'id' }); + store.createIndex('id', 'id', { unique: true }); + store.createIndex('urlId', 'urlId', { unique: true }); + } + }; + request.onsuccess = () => { + window.__BOLT_PERSISTENCE_AVAILABLE__ = true; + }; + request.onerror = () => { + window.__BOLT_PERSISTENCE_AVAILABLE__ = false; + }; + } } `; @@ -94,3 +131,10 @@ export function Layout({ children }: { children: React.ReactNode }) { export default function App() { return ; } + +// Add type declaration +declare global { + interface Window { + __BOLT_PERSISTENCE_AVAILABLE__: boolean; + } +}