@@ -13,7 +13,10 @@ import {
1313import { getNavigatorLocks } from '../..//shared/navigator' ;
1414import { AsyncDatabaseConnection } from './AsyncDatabaseConnection' ;
1515import { SharedConnectionWorker , WebDBAdapter } from './WebDBAdapter' ;
16- import { WorkerWrappedAsyncDatabaseConnection } from './WorkerWrappedAsyncDatabaseConnection' ;
16+ import {
17+ WorkerConnectionClosedError ,
18+ WorkerWrappedAsyncDatabaseConnection
19+ } from './WorkerWrappedAsyncDatabaseConnection' ;
1720import { WASQLiteVFS } from './wa-sqlite/WASQLiteConnection' ;
1821import { ResolvedWASQLiteOpenFactoryOptions } from './wa-sqlite/WASQLiteOpenFactory' ;
1922import { ResolvedWebSQLOpenOptions } from './web-sql-flags' ;
@@ -52,6 +55,7 @@ export class LockedAsyncDatabaseAdapter
5255 private _config : ResolvedWebSQLOpenOptions | null = null ;
5356 protected pendingAbortControllers : Set < AbortController > ;
5457 protected requiresHolds : boolean | null ;
58+ protected requiresReOpen : boolean ;
5559
5660 closing : boolean ;
5761 closed : boolean ;
@@ -64,6 +68,7 @@ export class LockedAsyncDatabaseAdapter
6468 this . closed = false ;
6569 this . closing = false ;
6670 this . requiresHolds = null ;
71+ this . requiresReOpen = false ;
6772 // Set the name if provided. We can query for the name if not available yet
6873 this . debugMode = options . debugMode ?? false ;
6974 if ( this . debugMode ) {
@@ -106,18 +111,26 @@ export class LockedAsyncDatabaseAdapter
106111 return this . initPromise ;
107112 }
108113
109- protected async _init ( ) {
114+ protected async openInternalDB ( ) {
115+ // Dispose any previous table change listener.
116+ this . _disposeTableChangeListener ?.( ) ;
117+ this . _disposeTableChangeListener = null ;
118+
110119 this . _db = await this . options . openConnection ( ) ;
111120 await this . _db . init ( ) ;
112121 this . _config = await this . _db . getConfig ( ) ;
113122 await this . registerOnChangeListener ( this . _db ) ;
114- this . iterateListeners ( ( cb ) => cb . initialized ?.( ) ) ;
115123 /**
116124 * This is only required for the long-lived shared IndexedDB connections.
117125 */
118126 this . requiresHolds = ( this . _config as ResolvedWASQLiteOpenFactoryOptions ) . vfs == WASQLiteVFS . IDBBatchAtomicVFS ;
119127 }
120128
129+ protected async _init ( ) {
130+ await this . openInternalDB ( ) ;
131+ this . iterateListeners ( ( cb ) => cb . initialized ?.( ) ) ;
132+ }
133+
121134 getConfiguration ( ) : ResolvedWebSQLOpenOptions {
122135 if ( ! this . _config ) {
123136 throw new Error ( `Cannot get config before initialization is completed` ) ;
@@ -223,7 +236,7 @@ export class LockedAsyncDatabaseAdapter
223236 this . pendingAbortControllers . add ( abortController ) ;
224237 const { timeoutMs } = options ?? { } ;
225238
226- const timoutId = timeoutMs
239+ const timeoutId = timeoutMs
227240 ? setTimeout ( ( ) => {
228241 abortController . abort ( `Timeout after ${ timeoutMs } ms` ) ;
229242 this . pendingAbortControllers . delete ( abortController ) ;
@@ -235,12 +248,21 @@ export class LockedAsyncDatabaseAdapter
235248 { signal : abortController . signal } ,
236249 async ( ) => {
237250 this . pendingAbortControllers . delete ( abortController ) ;
238- if ( timoutId ) {
239- clearTimeout ( timoutId ) ;
251+ if ( timeoutId ) {
252+ clearTimeout ( timeoutId ) ;
240253 }
241254 const holdId = this . requiresHolds ? await this . baseDB . markHold ( ) : null ;
242255 try {
256+ if ( this . requiresReOpen ) {
257+ await this . openInternalDB ( ) ;
258+ this . requiresReOpen = false ;
259+ }
243260 return await callback ( ) ;
261+ } catch ( ex ) {
262+ if ( ex instanceof WorkerConnectionClosedError ) {
263+ this . requiresReOpen = true ;
264+ }
265+ throw ex ;
244266 } finally {
245267 if ( holdId ) {
246268 await this . baseDB . releaseHold ( holdId ) ;
0 commit comments