Browse Source

fix start with no db

imwald
Silberengel 3 days ago
parent
commit
1dee575c83
  1. 3
      src/components/CacheRelaysSetting/index.tsx
  2. 52
      src/services/indexed-db.service.ts

3
src/components/CacheRelaysSetting/index.tsx

@ -194,7 +194,8 @@ export default function CacheRelaysSetting() { @@ -194,7 +194,8 @@ export default function CacheRelaysSetting() {
const info = await indexedDb.getStoreInfo()
setCacheInfo(info)
} catch (error) {
logger.error('Failed to load cache info', { error })
const message = error instanceof Error ? error.message : String(error)
logger.error('Failed to load cache info', { error: message })
}
}

52
src/services/indexed-db.service.ts

@ -36,6 +36,14 @@ export const StoreNames = { @@ -36,6 +36,14 @@ export const StoreNames = {
PUBLICATION_EVENTS: 'publicationEvents'
}
/** Convert IDB request.onerror Event to a proper Error for logging and UI */
function idbEventToError(ev: Parameters<NonNullable<IDBRequest['onerror']>>[0]): Error {
const request = ev.target as IDBRequest
const domError = request?.error
const message = domError?.message ?? 'IndexedDB operation failed'
return new Error(message)
}
class IndexedDbService {
static instance: IndexedDbService
static getInstance(): IndexedDbService {
@ -51,11 +59,14 @@ class IndexedDbService { @@ -51,11 +59,14 @@ class IndexedDbService {
init(): Promise<void> {
if (!this.initPromise) {
this.initPromise = new Promise((resolve, reject) => {
this.initPromise = new Promise<void>((resolve) => {
const request = window.indexedDB.open('jumble', 17)
request.onerror = (event) => {
reject(event)
// Resolve instead of reject so the app can run without IndexedDB (e.g. mobile private mode)
logger.warn('IndexedDB unavailable, running without local cache', idbEventToError(event))
this.db = null
resolve()
}
request.onsuccess = () => {
@ -145,7 +156,7 @@ class IndexedDbService { @@ -145,7 +156,7 @@ class IndexedDbService {
await this.initPromise
return new Promise((resolve, reject) => {
if (!this.db) {
return reject('database not initialized')
return resolve(undefined)
}
const transaction = this.db.transaction(storeName, 'readwrite')
const store = transaction.objectStore(storeName)
@ -212,8 +223,7 @@ class IndexedDbService { @@ -212,8 +223,7 @@ class IndexedDbService {
return new Promise((resolve, reject) => {
if (!this.db) {
logger.error('[IndexedDB] Database not initialized', { storeName, kind: cleanEvent.kind })
return reject('database not initialized')
return resolve(cleanEvent)
}
// Check if the store exists before trying to access it
@ -326,7 +336,7 @@ class IndexedDbService { @@ -326,7 +336,7 @@ class IndexedDbService {
await this.initPromise
return new Promise((resolve, reject) => {
if (!this.db) {
return reject('database not initialized')
return resolve(undefined)
}
// Check if the store exists before trying to access it
if (!this.db.objectStoreNames.contains(storeName)) {
@ -359,9 +369,9 @@ class IndexedDbService { @@ -359,9 +369,9 @@ class IndexedDbService {
return Promise.reject('store name not found')
}
await this.initPromise
return new Promise((resolve, reject) => {
return new Promise<(Event | undefined | null)[]>((resolve) => {
if (!this.db) {
return reject('database not initialized')
return resolve(new Array(pubkeys.length).fill(undefined))
}
const transaction = this.db.transaction(storeName, 'readonly')
const store = transaction.objectStore(storeName)
@ -396,7 +406,7 @@ class IndexedDbService { @@ -396,7 +406,7 @@ class IndexedDbService {
await this.initPromise
return new Promise((resolve, reject) => {
if (!this.db) {
return reject('database not initialized')
return resolve(null)
}
const transaction = this.db.transaction(StoreNames.MUTE_DECRYPTED_TAGS, 'readonly')
const store = transaction.objectStore(StoreNames.MUTE_DECRYPTED_TAGS)
@ -418,7 +428,7 @@ class IndexedDbService { @@ -418,7 +428,7 @@ class IndexedDbService {
await this.initPromise
return new Promise((resolve, reject) => {
if (!this.db) {
return reject('database not initialized')
return resolve()
}
const transaction = this.db.transaction(StoreNames.MUTE_DECRYPTED_TAGS, 'readwrite')
const store = transaction.objectStore(StoreNames.MUTE_DECRYPTED_TAGS)
@ -471,7 +481,7 @@ class IndexedDbService { @@ -471,7 +481,7 @@ class IndexedDbService {
await this.initPromise
return new Promise((resolve, reject) => {
if (!this.db) {
return reject('database not initialized')
return resolve()
}
const transaction = this.db.transaction(StoreNames.FOLLOWING_FAVORITE_RELAYS, 'readwrite')
const store = transaction.objectStore(StoreNames.FOLLOWING_FAVORITE_RELAYS)
@ -493,7 +503,7 @@ class IndexedDbService { @@ -493,7 +503,7 @@ class IndexedDbService {
await this.initPromise
return new Promise((resolve, reject) => {
if (!this.db) {
return reject('database not initialized')
return resolve(null)
}
const transaction = this.db.transaction(StoreNames.FOLLOWING_FAVORITE_RELAYS, 'readonly')
const store = transaction.objectStore(StoreNames.FOLLOWING_FAVORITE_RELAYS)
@ -515,7 +525,7 @@ class IndexedDbService { @@ -515,7 +525,7 @@ class IndexedDbService {
await this.initPromise
return new Promise((resolve, reject) => {
if (!this.db) {
return reject('database not initialized')
return resolve()
}
const transaction = this.db.transaction(StoreNames.RELAY_INFOS, 'readwrite')
const store = transaction.objectStore(StoreNames.RELAY_INFOS)
@ -537,7 +547,7 @@ class IndexedDbService { @@ -537,7 +547,7 @@ class IndexedDbService {
await this.initPromise
return new Promise((resolve, reject) => {
if (!this.db) {
return reject('database not initialized')
return resolve(null)
}
const transaction = this.db.transaction(StoreNames.RELAY_INFOS, 'readonly')
const store = transaction.objectStore(StoreNames.RELAY_INFOS)
@ -657,7 +667,7 @@ class IndexedDbService { @@ -657,7 +667,7 @@ class IndexedDbService {
return new Promise((resolve, reject) => {
if (!this.db) {
return reject('database not initialized')
return resolve(cleanEvent)
}
if (!this.db.objectStoreNames.contains(storeName)) {
logger.warn(`Store ${storeName} not found in database. Cannot save event.`)
@ -718,7 +728,7 @@ class IndexedDbService { @@ -718,7 +728,7 @@ class IndexedDbService {
return new Promise((resolve, reject) => {
if (!this.db) {
return reject('database not initialized')
return resolve(event)
}
if (!this.db.objectStoreNames.contains(storeName)) {
logger.warn(`Store ${storeName} not found in database. Cannot save event.`)
@ -766,7 +776,7 @@ class IndexedDbService { @@ -766,7 +776,7 @@ class IndexedDbService {
await this.initPromise
return new Promise((resolve, reject) => {
if (!this.db) {
return reject('database not initialized')
return resolve(undefined)
}
if (!this.db.objectStoreNames.contains(StoreNames.PUBLICATION_EVENTS)) {
return resolve(undefined)
@ -963,7 +973,7 @@ class IndexedDbService { @@ -963,7 +973,7 @@ class IndexedDbService {
storeInfo[storeName] = request.result
resolve()
}
request.onerror = (event) => reject(event)
request.onerror = (event) => reject(idbEventToError(event))
})
})
)
@ -997,7 +1007,7 @@ class IndexedDbService { @@ -997,7 +1007,7 @@ class IndexedDbService {
async deleteStoreItem(storeName: string, key: string): Promise<void> {
await this.initPromise
if (!this.db || !this.db.objectStoreNames.contains(storeName)) {
return Promise.reject('Store not found')
return
}
return new Promise((resolve, reject) => {
@ -1020,7 +1030,7 @@ class IndexedDbService { @@ -1020,7 +1030,7 @@ class IndexedDbService {
async clearStore(storeName: string): Promise<void> {
await this.initPromise
if (!this.db || !this.db.objectStoreNames.contains(storeName)) {
return Promise.reject('Store not found')
return
}
return new Promise((resolve, reject) => {
@ -1043,7 +1053,7 @@ class IndexedDbService { @@ -1043,7 +1053,7 @@ class IndexedDbService {
async cleanupDuplicateReplaceableEvents(storeName: string): Promise<{ deleted: number; kept: number }> {
await this.initPromise
if (!this.db || !this.db.objectStoreNames.contains(storeName)) {
return Promise.reject('Store not found')
return { deleted: 0, kept: 0 }
}
// Get the kind for this store - only clean up replaceable event stores

Loading…
Cancel
Save