Skip to content

Commit 209562b

Browse files
author
Jeremie Poisson
committed
Eagerly create multi-entry/fulltext index object stores in transaction constructor
1 parent 861413e commit 209562b

1 file changed

Lines changed: 32 additions & 4 deletions

File tree

src/IndexedDbProvider.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,7 @@ export class IndexedDbProvider extends DbProvider {
746746
// DbTransaction implementation for the IndexedDB DbProvider.
747747
export class IndexedDbTransaction implements DbTransaction {
748748
private _stores: IDBObjectStore[];
749+
private _indexStoreMap: Map<string, IDBObjectStore>;
749750

750751
constructor(
751752
private _trans: IDBTransaction,
@@ -760,6 +761,28 @@ export class IndexedDbTransaction implements DbTransaction {
760761
this._trans.objectStore(storeName)
761762
);
762763

764+
// Eagerly capture multi-entry/fullText index object stores while the transaction is still
765+
// in "active" state. Deferring this to getStore() risks an InvalidStateError if the event
766+
// loop runs between openTransaction() and the first getStore() call, causing the IDB
767+
// transaction to auto-commit before the objectStore() call.
768+
this._indexStoreMap = new Map<string, IDBObjectStore>();
769+
if (_fakeComplicatedKeys) {
770+
each(this._transToken.storeNames, (storeName) => {
771+
const storeSchema = find(_schema.stores, (s) => s.name === storeName);
772+
if (storeSchema?.indexes) {
773+
each(storeSchema.indexes, (indexSchema) => {
774+
if (indexSchema.multiEntry || indexSchema.fullText) {
775+
const indexStoreName = storeSchema.name + "_" + indexSchema.name;
776+
this._indexStoreMap.set(
777+
indexStoreName,
778+
this._trans.objectStore(indexStoreName)
779+
);
780+
}
781+
});
782+
}
783+
});
784+
}
785+
763786
if (lockHelper) {
764787
// Chromium seems to have a bug in their indexeddb implementation that lets it start a timeout
765788
// while the app is in the middle of a commit (it does a two-phase commit). It can then finish
@@ -847,12 +870,17 @@ export class IndexedDbTransaction implements DbTransaction {
847870

848871
const indexStores: IDBObjectStore[] = [];
849872
if (this._fakeComplicatedKeys && storeSchema.indexes) {
850-
// Pull the alternate multientry stores in as well
873+
// Pull the alternate multientry stores in as well, using the map populated eagerly in the
874+
// constructor to avoid calling objectStore() after an async yield (which would throw
875+
// InvalidStateError if the transaction has already auto-committed).
851876
each(storeSchema.indexes, (indexSchema) => {
852877
if (indexSchema.multiEntry || indexSchema.fullText) {
853-
indexStores.push(
854-
this._trans.objectStore(storeSchema.name + "_" + indexSchema.name)
855-
);
878+
const indexStoreName = storeSchema.name + "_" + indexSchema.name;
879+
const indexStore = this._indexStoreMap.get(indexStoreName);
880+
if (!indexStore) {
881+
throw new Error("Index store not found in transaction: " + indexStoreName);
882+
}
883+
indexStores.push(indexStore);
856884
}
857885
});
858886
}

0 commit comments

Comments
 (0)