@fairfox/polly 0.61.0 → 0.62.0

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/src/mesh.js CHANGED
@@ -69,6 +69,90 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
69
69
  throw Error('Dynamic require of "' + x + '" is not supported');
70
70
  });
71
71
 
72
+ // src/shared/lib/idb-helpers.ts
73
+ function openIDB(options) {
74
+ return new Promise((resolve, reject) => {
75
+ const start = Date.now();
76
+ const request = indexedDB.open(options.name, options.version);
77
+ let settled = false;
78
+ const timer = setTimeout(() => {
79
+ if (settled)
80
+ return;
81
+ settled = true;
82
+ const elapsedMs = Date.now() - start;
83
+ reject(new Error(`Polly IndexedDB open of '${options.name}' timed out after ${elapsedMs}ms (cross-tab lock or zombie connection?)`));
84
+ }, IDB_OPEN_TIMEOUT_MS);
85
+ request.onerror = () => {
86
+ if (settled)
87
+ return;
88
+ settled = true;
89
+ clearTimeout(timer);
90
+ reject(request.error);
91
+ };
92
+ request.onsuccess = () => {
93
+ if (settled)
94
+ return;
95
+ settled = true;
96
+ clearTimeout(timer);
97
+ resolve(request.result);
98
+ };
99
+ request.onupgradeneeded = (event) => {
100
+ const db = event.target.result;
101
+ options.upgrade(db, event);
102
+ };
103
+ });
104
+ }
105
+ function cachedOpen(ref, options) {
106
+ if (ref.promise)
107
+ return ref.promise;
108
+ const pending = openIDB(options);
109
+ pending.catch(() => {
110
+ if (ref.promise === pending)
111
+ ref.promise = null;
112
+ });
113
+ ref.promise = pending;
114
+ return pending;
115
+ }
116
+ function runRequest(request) {
117
+ return new Promise((resolve, reject) => {
118
+ request.onsuccess = () => resolve(request.result);
119
+ request.onerror = () => reject(request.error);
120
+ });
121
+ }
122
+ function runTx(db, storeName, mode, fn) {
123
+ return new Promise((resolve, reject) => {
124
+ const tx = db.transaction(storeName, mode);
125
+ const store = tx.objectStore(storeName);
126
+ tx.oncomplete = () => resolve();
127
+ tx.onerror = () => reject(tx.error);
128
+ tx.onabort = () => reject(tx.error);
129
+ try {
130
+ fn(store);
131
+ } catch (err) {
132
+ try {
133
+ tx.abort();
134
+ } catch {}
135
+ reject(err);
136
+ }
137
+ });
138
+ }
139
+ function iterateCursor(db, storeName, visit) {
140
+ return new Promise((resolve, reject) => {
141
+ const tx = db.transaction(storeName, "readonly");
142
+ const store = tx.objectStore(storeName);
143
+ const request = store.openCursor();
144
+ request.onsuccess = () => {
145
+ const cursor = request.result;
146
+ if (!cursor)
147
+ return resolve();
148
+ visit(cursor.key, cursor.value);
149
+ cursor.continue();
150
+ };
151
+ request.onerror = () => reject(request.error);
152
+ });
153
+ }
154
+ var IDB_OPEN_TIMEOUT_MS = 5000;
155
+
72
156
  // src/shared/lib/encryption.ts
73
157
  var exports_encryption = {};
74
158
  __export(exports_encryption, {
@@ -255,69 +339,28 @@ class IndexedDBBlobCache {
255
339
  static DB_NAME = "polly-blobs";
256
340
  static DB_VERSION = 1;
257
341
  static STORE_NAME = "blobs";
258
- dbPromise = null;
342
+ dbRef = { promise: null };
259
343
  urls = new Map;
260
- static OPEN_TIMEOUT_MS = 5000;
261
344
  openDB() {
262
- if (this.dbPromise)
263
- return this.dbPromise;
264
- const pending = new Promise((resolve, reject) => {
265
- const start = Date.now();
266
- const request = indexedDB.open(IndexedDBBlobCache.DB_NAME, IndexedDBBlobCache.DB_VERSION);
267
- let settled = false;
268
- const timer = setTimeout(() => {
269
- if (settled)
270
- return;
271
- settled = true;
272
- const elapsedMs = Date.now() - start;
273
- reject(new Error(`Polly IndexedDB open of '${IndexedDBBlobCache.DB_NAME}' timed out after ${elapsedMs}ms (cross-tab lock or zombie connection?)`));
274
- }, IndexedDBBlobCache.OPEN_TIMEOUT_MS);
275
- request.onerror = () => {
276
- if (settled)
277
- return;
278
- settled = true;
279
- clearTimeout(timer);
280
- reject(request.error);
281
- };
282
- request.onsuccess = () => {
283
- if (settled)
284
- return;
285
- settled = true;
286
- clearTimeout(timer);
287
- resolve(request.result);
288
- };
289
- request.onupgradeneeded = (event) => {
290
- const db = event.target.result;
345
+ return cachedOpen(this.dbRef, {
346
+ name: IndexedDBBlobCache.DB_NAME,
347
+ version: IndexedDBBlobCache.DB_VERSION,
348
+ upgrade: (db) => {
291
349
  if (!db.objectStoreNames.contains(IndexedDBBlobCache.STORE_NAME)) {
292
350
  db.createObjectStore(IndexedDBBlobCache.STORE_NAME);
293
351
  }
294
- };
295
- });
296
- pending.catch(() => {
297
- if (this.dbPromise === pending)
298
- this.dbPromise = null;
352
+ }
299
353
  });
300
- this.dbPromise = pending;
301
- return pending;
302
354
  }
303
355
  async getRecord(hash) {
304
356
  const db = await this.openDB();
305
- return new Promise((resolve, reject) => {
306
- const tx = db.transaction(IndexedDBBlobCache.STORE_NAME, "readonly");
307
- const store = tx.objectStore(IndexedDBBlobCache.STORE_NAME);
308
- const request = store.get(hash);
309
- request.onsuccess = () => resolve(request.result);
310
- request.onerror = () => reject(request.error);
311
- });
357
+ const tx = db.transaction(IndexedDBBlobCache.STORE_NAME, "readonly");
358
+ return runRequest(tx.objectStore(IndexedDBBlobCache.STORE_NAME).get(hash));
312
359
  }
313
360
  async putRecord(hash, record) {
314
361
  const db = await this.openDB();
315
- return new Promise((resolve, reject) => {
316
- const tx = db.transaction(IndexedDBBlobCache.STORE_NAME, "readwrite");
317
- const store = tx.objectStore(IndexedDBBlobCache.STORE_NAME);
362
+ await runTx(db, IndexedDBBlobCache.STORE_NAME, "readwrite", (store) => {
318
363
  store.put(record, hash);
319
- tx.oncomplete = () => resolve();
320
- tx.onerror = () => reject(tx.error);
321
364
  });
322
365
  }
323
366
  async get(hash) {
@@ -338,13 +381,9 @@ class IndexedDBBlobCache {
338
381
  }
339
382
  async has(hash) {
340
383
  const db = await this.openDB();
341
- return new Promise((resolve, reject) => {
342
- const tx = db.transaction(IndexedDBBlobCache.STORE_NAME, "readonly");
343
- const store = tx.objectStore(IndexedDBBlobCache.STORE_NAME);
344
- const request = store.count(hash);
345
- request.onsuccess = () => resolve(request.result > 0);
346
- request.onerror = () => reject(request.error);
347
- });
384
+ const tx = db.transaction(IndexedDBBlobCache.STORE_NAME, "readonly");
385
+ const count = await runRequest(tx.objectStore(IndexedDBBlobCache.STORE_NAME).count(hash));
386
+ return count > 0;
348
387
  }
349
388
  async delete(hash) {
350
389
  const url = this.urls.get(hash);
@@ -353,12 +392,8 @@ class IndexedDBBlobCache {
353
392
  this.urls.delete(hash);
354
393
  }
355
394
  const db = await this.openDB();
356
- return new Promise((resolve, reject) => {
357
- const tx = db.transaction(IndexedDBBlobCache.STORE_NAME, "readwrite");
358
- const store = tx.objectStore(IndexedDBBlobCache.STORE_NAME);
395
+ await runTx(db, IndexedDBBlobCache.STORE_NAME, "readwrite", (store) => {
359
396
  store.delete(hash);
360
- tx.oncomplete = () => resolve();
361
- tx.onerror = () => reject(tx.error);
362
397
  });
363
398
  }
364
399
  async pin(hash) {
@@ -375,50 +410,25 @@ class IndexedDBBlobCache {
375
410
  }
376
411
  async size() {
377
412
  const db = await this.openDB();
378
- return new Promise((resolve, reject) => {
379
- const tx = db.transaction(IndexedDBBlobCache.STORE_NAME, "readonly");
380
- const store = tx.objectStore(IndexedDBBlobCache.STORE_NAME);
381
- const request = store.openCursor();
382
- let total = 0;
383
- request.onsuccess = () => {
384
- const cursor = request.result;
385
- if (cursor) {
386
- const value = cursor.value;
387
- total += value.size;
388
- cursor.continue();
389
- } else {
390
- resolve(total);
391
- }
392
- };
393
- request.onerror = () => reject(request.error);
413
+ let total = 0;
414
+ await iterateCursor(db, IndexedDBBlobCache.STORE_NAME, (_key, value) => {
415
+ total += value.size;
394
416
  });
417
+ return total;
395
418
  }
396
419
  async evict(maxBytes) {
397
420
  const db = await this.openDB();
398
421
  const candidates = [];
399
422
  let totalSize = 0;
400
- await new Promise((resolve, reject) => {
401
- const tx = db.transaction(IndexedDBBlobCache.STORE_NAME, "readonly");
402
- const store = tx.objectStore(IndexedDBBlobCache.STORE_NAME);
403
- const request = store.openCursor();
404
- request.onsuccess = () => {
405
- const cursor = request.result;
406
- if (cursor) {
407
- const value = cursor.value;
408
- totalSize += value.size;
409
- if (!value.pinned) {
410
- candidates.push({
411
- hash: cursor.key,
412
- accessedAt: value.accessedAt,
413
- size: value.size
414
- });
415
- }
416
- cursor.continue();
417
- } else {
418
- resolve();
419
- }
420
- };
421
- request.onerror = () => reject(request.error);
423
+ await iterateCursor(db, IndexedDBBlobCache.STORE_NAME, (key, value) => {
424
+ totalSize += value.size;
425
+ if (!value.pinned) {
426
+ candidates.push({
427
+ hash: key,
428
+ accessedAt: value.accessedAt,
429
+ size: value.size
430
+ });
431
+ }
422
432
  });
423
433
  if (totalSize <= maxBytes)
424
434
  return 0;
@@ -3656,4 +3666,4 @@ export {
3656
3666
  $meshCounter
3657
3667
  };
3658
3668
 
3659
- //# debugId=81CAD9639A4786EB64756E2164756E21
3669
+ //# debugId=EFE12C3DC2653D4B64756E2164756E21