@bopen-io/wallet-toolbox 1.7.20-idb-fix.4 → 1.7.20-idb-fix.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bopen-io/wallet-toolbox",
3
- "version": "1.7.20-idb-fix.4",
3
+ "version": "1.7.20-idb-fix.5",
4
4
  "description": "BRC100 conforming wallet, wallet storage and wallet signer components",
5
5
  "main": "./out/src/index.js",
6
6
  "types": "./out/src/index.d.ts",
@@ -844,38 +844,55 @@ export class WalletStorageManager implements sdk.WalletStorage {
844
844
 
845
845
  log += progLog('\n')
846
846
 
847
- log += await this.runAsSync(async sync => {
848
- let log = ''
849
-
850
- if (this._conflictingActives!.length > 0) {
851
- // Merge state from conflicting actives into `newActive`.
852
-
853
- // Handle case where new active is current active to resolve conflicts.
854
- // And where new active is one of the current conflict actives.
855
- this._conflictingActives!.push(this._active!)
856
- // Remove the new active from conflicting actives and
857
- // set new active as the conflicting active that matches the target `storageIdentityKey`
858
- this._conflictingActives = this._conflictingActives!.filter(ca => {
859
- const isNewActive = ca.settings!.storageIdentityKey === storageIdentityKey
860
- return !isNewActive
861
- })
862
-
863
- // Merge state from conflicting actives into `newActive`.
864
- for (const conflict of this._conflictingActives) {
865
- log += progLog('MERGING STATE FROM CONFLICTING ACTIVES:\n')
866
- const sfr = await this.syncToWriter(
867
- { identityKey, userId: newActive.user!.userId, isActive: false },
868
- newActive.storage,
869
- conflict.storage,
870
- undefined,
871
- progLog
872
- )
873
- log += sfr.log
847
+ // Handle conflicting actives OUTSIDE runAsSync to avoid IDB timeout.
848
+ // Network calls to remote storage can take longer than IDB transaction timeout.
849
+ if (this._conflictingActives!.length > 0) {
850
+ // Handle case where new active is current active to resolve conflicts.
851
+ // And where new active is one of the current conflict actives.
852
+ this._conflictingActives!.push(this._active!)
853
+ // Remove the new active from conflicting actives
854
+ this._conflictingActives = this._conflictingActives!.filter(ca => {
855
+ const isNewActive = ca.settings!.storageIdentityKey === storageIdentityKey
856
+ return !isNewActive
857
+ })
858
+
859
+ // Merge state from each conflicting active into newActive.
860
+ // Network calls happen here, outside any held IDB transaction.
861
+ for (const conflict of this._conflictingActives) {
862
+ log += progLog('MERGING STATE FROM CONFLICTING ACTIVES:\n')
863
+ const readerSettings = await conflict.storage.makeAvailable()
864
+ const writerSettings = await newActive.storage.makeAvailable()
865
+
866
+ let i = -1
867
+ for (;;) {
868
+ i++
869
+ // Get sync state from writer (newActive) - brief local read
870
+ const ss = await EntitySyncState.fromStorage(newActive.storage, identityKey, readerSettings)
871
+ const args = ss.makeRequestSyncChunkArgs(identityKey, writerSettings.storageIdentityKey)
872
+
873
+ // Network call to conflict (reader) - outside transaction
874
+ const chunk = await conflict.storage.getSyncChunk(args)
875
+ log += EntitySyncState.syncChunkSummary(chunk)
876
+
877
+ // Preserve activeStorage - merging from reader cannot change active
878
+ if (chunk.user) {
879
+ chunk.user.activeStorage = storageIdentityKey
880
+ }
881
+
882
+ // Brief local write per chunk
883
+ const r = await newActive.storage.processSyncChunk(args, chunk)
884
+ log += progLog(`chunk ${i} inserted ${r.inserts} updated ${r.updates} ${r.maxUpdated_at}\n`)
885
+ if (r.done) break
874
886
  }
875
- log += progLog('PROPAGATE MERGED ACTIVE STATE TO NON-ACTIVES\n')
876
- } else {
877
- log += progLog('BACKUP CURRENT ACTIVE STATE THEN SET NEW ACTIVE\n')
878
887
  }
888
+ log += progLog('PROPAGATE MERGED ACTIVE STATE TO NON-ACTIVES\n')
889
+ } else {
890
+ log += progLog('BACKUP CURRENT ACTIVE STATE THEN SET NEW ACTIVE\n')
891
+ }
892
+
893
+ // Continue with local-only operations in runAsSync
894
+ log += await this.runAsSync(async sync => {
895
+ let innerLog = ''
879
896
 
880
897
  // If there were conflicting actives,
881
898
  // Push state merged from all merged actives into newActive to all stores other than the now single active.
@@ -896,18 +913,18 @@ export class WalletStorageManager implements sdk.WalletStorage {
896
913
  const stwr = await this.syncToWriter(
897
914
  { identityKey, userId: store.user!.userId, isActive: false },
898
915
  store.storage,
899
- backupSource.storage,
916
+ sync,
900
917
  undefined,
901
918
  progLog
902
919
  )
903
- log += stwr.log
920
+ innerLog += stwr.log
904
921
  }
905
922
  }
906
923
 
907
924
  this._isAvailable = false
908
925
  await this.makeAvailable()
909
926
 
910
- return log
927
+ return innerLog
911
928
  })
912
929
 
913
930
  return log