File tree Expand file tree Collapse file tree 3 files changed +37
-4
lines changed Expand file tree Collapse file tree 3 files changed +37
-4
lines changed Original file line number Diff line number Diff line change @@ -132,6 +132,27 @@ export class LockedAsyncDatabaseAdapter
132132 this . requiresHolds = ( this . _config as ResolvedWASQLiteOpenFactoryOptions ) . vfs == WASQLiteVFS . IDBBatchAtomicVFS ;
133133 }
134134
135+ protected _reOpen ( ) {
136+ this . databaseOpenPromise = this . openInternalDB ( ) . finally ( ( ) => {
137+ this . databaseOpenPromise = null ;
138+ } ) ;
139+ return this . databaseOpenPromise ;
140+ }
141+
142+ /**
143+ * Re-opens the underlying database.
144+ * Returns a pending operation if one is already in progress.
145+ */
146+ async reOpenInternalDB ( ) : Promise < void > {
147+ if ( ! this . options . reOpenOnConnectionClosed ) {
148+ throw new Error ( `Cannot re-open underlying database, reOpenOnConnectionClosed is not enabled` ) ;
149+ }
150+ if ( this . databaseOpenPromise ) {
151+ return this . databaseOpenPromise ;
152+ }
153+ return this . _reOpen ( ) ;
154+ }
155+
135156 protected async _init ( ) {
136157 await this . openInternalDB ( ) ;
137158 this . iterateListeners ( ( cb ) => cb . initialized ?.( ) ) ;
@@ -277,9 +298,7 @@ export class LockedAsyncDatabaseAdapter
277298 if ( ex instanceof ConnectionClosedError ) {
278299 if ( this . options . reOpenOnConnectionClosed && ! this . databaseOpenPromise && ! this . closing ) {
279300 // Immediately re-open the database. We need to miss as little table updates as possible.
280- this . databaseOpenPromise = this . openInternalDB ( ) . finally ( ( ) => {
281- this . databaseOpenPromise = null ;
282- } ) ;
301+ this . reOpenInternalDB ( ) ;
283302 }
284303 }
285304 throw ex ;
Original file line number Diff line number Diff line change 1+ import { BaseObserver } from '@powersync/common' ;
12import * as Comlink from 'comlink' ;
23import {
34 AsyncDatabaseConnection ,
@@ -24,17 +25,23 @@ export type WrappedWorkerConnectionOptions<Config extends ResolvedWebSQLOpenOpti
2425 onClose ?: ( ) => void ;
2526} ;
2627
28+ export type WorkerWrappedAsyncDatabaseConnectionListener = {
29+ closing : ( ) => void ;
30+ } ;
2731/**
2832 * Wraps a provided instance of {@link AsyncDatabaseConnection}, providing necessary proxy
2933 * functions for worker listeners.
3034 */
3135export class WorkerWrappedAsyncDatabaseConnection < Config extends ResolvedWebSQLOpenOptions = ResolvedWebSQLOpenOptions >
36+ extends BaseObserver < WorkerWrappedAsyncDatabaseConnectionListener >
3237 implements AsyncDatabaseConnection
3338{
3439 protected lockAbortController = new AbortController ( ) ;
3540 protected notifyRemoteClosed : AbortController | undefined ;
3641
3742 constructor ( protected options : WrappedWorkerConnectionOptions < Config > ) {
43+ super ( ) ;
44+
3845 if ( options . remoteCanCloseUnexpectedly ) {
3946 this . notifyRemoteClosed = new AbortController ( ) ;
4047 }
@@ -169,6 +176,7 @@ export class WorkerWrappedAsyncDatabaseConnection<Config extends ResolvedWebSQLO
169176 } finally {
170177 this . options . remote [ Comlink . releaseProxy ] ( ) ;
171178 this . options . onClose ?.( ) ;
179+ this . iterateListeners ( ( l ) => l . closing ?.( ) ) ;
172180 }
173181 }
174182
Original file line number Diff line number Diff line change @@ -247,7 +247,13 @@ export class SharedSyncImplementation extends BaseObserver<SharedSyncImplementat
247247 name : params . dbParams . dbFilename ,
248248 openConnection : async ( ) => {
249249 // Gets a connection from the clients when a new connection is requested.
250- return await this . openInternalDB ( ) ;
250+ const db = await this . openInternalDB ( ) ;
251+ db . registerListener ( {
252+ closing : ( ) => {
253+ lockedAdapter . reOpenInternalDB ( ) ;
254+ }
255+ } ) ;
256+ return db ;
251257 } ,
252258 logger : this . logger ,
253259 reOpenOnConnectionClosed : true
You can’t perform that action at this time.
0 commit comments