Skip to content

Commit 8a1e1a2

Browse files
committed
add back close state
1 parent b7a9d0f commit 8a1e1a2

File tree

1 file changed

+72
-17
lines changed

1 file changed

+72
-17
lines changed

packages/firestore/src/local/simple_db.ts

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -162,24 +162,57 @@ export interface IdbDatabaseDebugIdPair {
162162

163163
class SimpleDbStateNew {
164164
readonly name = 'new' as const;
165+
166+
constructor(
167+
readonly databaseDeletedListener: DatabaseDeletedListener | null
168+
) {}
169+
170+
withDatabaseDeletedListener(
171+
databaseDeletedListener: DatabaseDeletedListener
172+
): SimpleDbStateNew {
173+
return new SimpleDbStateNew(databaseDeletedListener);
174+
}
165175
}
166176

167177
class SimpleDbStateOpening {
168178
readonly name = 'opening' as const;
169179

170-
constructor(readonly promise: Promise<unknown>) {}
180+
constructor(
181+
readonly promise: Promise<unknown>,
182+
readonly databaseDeletedListener: DatabaseDeletedListener | null
183+
) {}
184+
185+
withDatabaseDeletedListener(
186+
databaseDeletedListener: DatabaseDeletedListener
187+
): SimpleDbStateOpening {
188+
return new SimpleDbStateOpening(this.promise, databaseDeletedListener);
189+
}
171190
}
172191

173192
class SimpleDbStateOpened {
174193
readonly name = 'opened' as const;
175194

176-
constructor(readonly db: IdbDatabaseDebugIdPair) {}
195+
constructor(
196+
readonly db: IdbDatabaseDebugIdPair,
197+
readonly databaseDeletedListener: DatabaseDeletedListener | null
198+
) {}
199+
200+
withDatabaseDeletedListener(
201+
databaseDeletedListener: DatabaseDeletedListener
202+
): SimpleDbStateOpened {
203+
return new SimpleDbStateOpened(this.db, databaseDeletedListener);
204+
}
205+
}
206+
207+
class SimpleDbStateClosed {
208+
readonly name = 'closed' as const;
177209
}
178210

179211
type SimpleDbState =
180212
| SimpleDbStateNew
181213
| SimpleDbStateOpened
182-
| SimpleDbStateOpening;
214+
| SimpleDbStateOpening
215+
| SimpleDbStateClosed;
183216

184217
/**
185218
* Provides a wrapper around IndexedDb with a simplified interface that uses
@@ -190,8 +223,7 @@ type SimpleDbState =
190223
*/
191224
export class SimpleDb {
192225
readonly debugId = `SimpleDb@${generateUniqueDebugId()}`;
193-
private state: SimpleDbState = new SimpleDbStateNew();
194-
private databaseDeletedListener: DatabaseDeletedListener | null = null;
226+
private state: SimpleDbState = new SimpleDbStateNew(null);
195227

196228
/** Deletes the specified database. */
197229
static delete(name: string): Promise<void> {
@@ -331,26 +363,41 @@ export class SimpleDb {
331363
async ensureDb(action: string): Promise<IdbDatabaseDebugIdPair> {
332364
while (true) {
333365
const currentState = this.state;
334-
if (currentState.name === 'opening') {
366+
if (currentState.name === 'closed') {
367+
console.trace(
368+
`zzyzx ${this.debugId} ` +
369+
`ensureDb(${JSON.stringify(action)}) called after close()`
370+
);
371+
dumpLogBuffer('SimpleDb.ensureDb after close');
372+
throw new Error(`${this.debugId} has been closed`);
373+
} else if (currentState.name === 'opening') {
335374
await currentState.promise.catch(_ => {});
336375
} else if (currentState.name === 'opened') {
337376
return currentState.db;
338377
} else {
339378
hardAssert(currentState.name === 'new', 0x56e8, { state: this.state });
340379
const promise = this.openDb(action);
341-
const openingState = new SimpleDbStateOpening(promise);
380+
const openingState = new SimpleDbStateOpening(
381+
promise,
382+
currentState.databaseDeletedListener
383+
);
342384
this.state = openingState;
343385
try {
344386
const db = await promise;
345387
if (this.state === openingState) {
346-
this.state = new SimpleDbStateOpened(db);
388+
this.state = new SimpleDbStateOpened(
389+
db,
390+
openingState.databaseDeletedListener
391+
);
347392
return db;
348393
} else {
349394
db.idbDatabase.close();
350395
}
351396
} catch (e) {
352397
if (this.state === openingState) {
353-
this.state = new SimpleDbStateNew();
398+
this.state = new SimpleDbStateNew(
399+
this.state.databaseDeletedListener
400+
);
354401
throw e;
355402
}
356403
}
@@ -454,7 +501,9 @@ export class SimpleDb {
454501
`Received "versionchange" event with newVersion===null; ` +
455502
'notifying the registered DatabaseDeletedListener, if any'
456503
);
457-
this.databaseDeletedListener?.();
504+
if ('databaseDeletedListener' in this.state) {
505+
this.state.databaseDeletedListener?.();
506+
}
458507
}
459508
},
460509
{ passive: true }
@@ -471,9 +520,6 @@ export class SimpleDb {
471520
`in a web browser.`
472521
);
473522
dumpLogBuffer('SimpleDbCloseEvent');
474-
if (this.state.name === 'opened' && this.state.db.idbDatabase === db) {
475-
this.state = new SimpleDbStateNew();
476-
}
477523
},
478524
{ passive: true }
479525
);
@@ -484,10 +530,15 @@ export class SimpleDb {
484530
setDatabaseDeletedListener(
485531
databaseDeletedListener: DatabaseDeletedListener
486532
): void {
487-
if (this.databaseDeletedListener) {
533+
if (!('databaseDeletedListener' in this.state)) {
534+
return;
535+
}
536+
if (this.state.databaseDeletedListener) {
488537
throw new Error('setDatabaseDeletedListener() has already been called');
489538
}
490-
this.databaseDeletedListener = databaseDeletedListener;
539+
this.state = this.state.withDatabaseDeletedListener(
540+
databaseDeletedListener
541+
);
491542
}
492543

493544
async runTransaction<T>(
@@ -568,7 +619,7 @@ export class SimpleDb {
568619
);
569620

570621
if ('db' in this.state && dbBefore === this.state.db) {
571-
this.state = new SimpleDbStateNew();
622+
this.state = new SimpleDbStateNew(this.state.databaseDeletedListener);
572623
logWarn(
573624
this.debugId,
574625
`Transaction transactionId=${transactionId} closing IDBDatabase ` +
@@ -586,11 +637,15 @@ export class SimpleDb {
586637
}
587638

588639
close(): void {
640+
if (this.state.name === 'closed') {
641+
dumpLogBuffer('SimpleDb.close');
642+
return;
643+
}
589644
logDebug(this.debugId, 'close()');
590645
if ('db' in this.state) {
591646
this.state.db.idbDatabase.close();
592647
}
593-
this.state = new SimpleDbStateNew();
648+
this.state = new SimpleDbStateClosed();
594649
}
595650
}
596651

0 commit comments

Comments
 (0)