@@ -64,6 +64,24 @@ const STORAGE_ERRORS = [...IDB_STORAGE_ERRORS, ...SQLITE_STORAGE_ERRORS];
6464// Max number of retries for failed storage operations
6565const MAX_STORAGE_OPERATION_RETRY_ATTEMPTS = 5 ;
6666
67+ // Connection/state errors where the DB needs time to recover — backoff helps, eviction does not
68+ const IDB_CONNECTION_ERRORS = [
69+ 'internal error opening backing store' , // Chrome/Edge: corrupted IDB state
70+ 'connection to indexed database server lost' , // Safari: IDB connection dropped
71+ 'the database connection is closing' , // Cross-browser: DB closing during write
72+ ] as const ;
73+
74+ const SQLITE_CONNECTION_ERRORS = [
75+ 'disk i/o error' , // Native: filesystem/device stress
76+ 'database is locked' , // Native: concurrent access contention
77+ ] as const ;
78+
79+ const CONNECTION_ERRORS = [ ...IDB_CONNECTION_ERRORS , ...SQLITE_CONNECTION_ERRORS ] ;
80+
81+ // Retry backoff configuration
82+ const RETRY_BASE_DELAY_MS = 100 ;
83+ const RETRY_JITTER_FACTOR = 0.25 ;
84+
6785type OnyxMethod = ValueOf < typeof METHOD > ;
6886
6987// Key/value store of Onyx key and arrays of values to merge
@@ -763,6 +781,26 @@ function remove<TKey extends OnyxKey>(key: TKey, isProcessingCollectionUpdate?:
763781 return Storage . removeItem ( key ) . then ( ( ) => undefined ) ;
764782}
765783
784+ /**
785+ * Returns a promise that resolves after the given number of milliseconds.
786+ */
787+ function wait ( ms : number ) : Promise < void > {
788+ return new Promise ( ( resolve ) => {
789+ setTimeout ( resolve , ms ) ;
790+ } ) ;
791+ }
792+
793+ /**
794+ * Calculates exponential backoff delay with jitter for a given retry attempt.
795+ * Formula: baseDelay * 2^attempt ± jitter
796+ * Attempt 0: ~100ms, Attempt 1: ~200ms, ..., Attempt 4: ~1600ms
797+ */
798+ function getRetryDelay ( attempt : number ) : number {
799+ const baseDelay = RETRY_BASE_DELAY_MS * 2 ** attempt ;
800+ const jitter = baseDelay * RETRY_JITTER_FACTOR * ( 2 * Math . random ( ) - 1 ) ;
801+ return Math . round ( baseDelay + jitter ) ;
802+ }
803+
766804function reportStorageQuota ( error ?: Error ) : Promise < void > {
767805 return Storage . getDatabaseSize ( )
768806 . then ( ( { bytesUsed, bytesRemaining} ) => {
0 commit comments