@abraca/dabra 1.0.18 → 1.0.19

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/dist/index.d.ts CHANGED
@@ -699,7 +699,7 @@ declare class AbracadabraProvider extends AbracadabraBaseProvider {
699
699
  */
700
700
  loadChild(childId: string): Promise<AbracadabraProvider>;
701
701
  private _doLoadChild;
702
- private unloadChild;
702
+ unloadChild(childId: string): void;
703
703
  /** Return all currently-loaded child providers. */
704
704
  get children(): Map<string, AbracadabraProvider>;
705
705
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abraca/dabra",
3
- "version": "1.0.18",
3
+ "version": "1.0.19",
4
4
  "description": "abracadabra provider",
5
5
  "keywords": [
6
6
  "abracadabra",
@@ -497,7 +497,7 @@ export class AbracadabraProvider extends AbracadabraBaseProvider {
497
497
  return childProvider;
498
498
  }
499
499
 
500
- private unloadChild(childId: string) {
500
+ unloadChild(childId: string) {
501
501
  const provider = this.childProviders.get(childId);
502
502
  if (provider) {
503
503
  provider.destroy();
@@ -391,7 +391,9 @@ export class BackgroundSyncManager extends EventEmitter {
391
391
  }
392
392
 
393
393
  private async _syncNonE2EDoc(docId: string): Promise<DocSyncState> {
394
- // loadChild() returns cached provider if already open
394
+ // Check if the provider already exists (user is viewing it) before loading.
395
+ const alreadyCached = this.rootProvider.children.has(docId);
396
+
395
397
  const childProvider = await this.rootProvider.loadChild(docId);
396
398
 
397
399
  // Wait for ready (offline snapshot loaded) then synced (server sync done)
@@ -403,6 +405,13 @@ export class BackgroundSyncManager extends EventEmitter {
403
405
  this._prefetchDocFiles(docId, childProvider.document).catch(() => null);
404
406
  }
405
407
 
408
+ // Release provider if it was created solely for background sync.
409
+ // This closes its IDB database, freeing the file descriptor.
410
+ // Providers that were already cached (user is viewing them) are kept alive.
411
+ if (!alreadyCached) {
412
+ this.rootProvider.unloadChild(docId);
413
+ }
414
+
406
415
  return { docId, status: "synced", lastSynced: Date.now(), isE2E: false };
407
416
  }
408
417
 
@@ -277,11 +277,15 @@ export class OfflineStore {
277
277
 
278
278
  destroy() {
279
279
  // Set the destroyed flag first so getDb() returns null for any new operations.
280
- // Do NOT call db.close() here — in-flight IDB transactions hold their own
281
- // reference to the database and closing it prematurely causes InvalidStateError.
282
- // The DB will be closed and garbage-collected once all transactions complete.
283
280
  this._destroyed = true;
281
+ const db = this.db;
284
282
  this.db = null;
285
283
  this.dbPromise = null;
284
+ // Close the IDB connection to free the file descriptor. Deferred to the
285
+ // next microtask so any in-flight transaction callbacks settle first.
286
+ // IDB spec: close() waits for running transactions to finish before closing.
287
+ if (db) {
288
+ Promise.resolve().then(() => db.close());
289
+ }
286
290
  }
287
291
  }