@fairfox/polly 0.61.0 → 0.63.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,101 @@ 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, openFn = defaultOpenFn) {
74
+ return new Promise((resolve, reject) => {
75
+ const start = Date.now();
76
+ const request = openFn(options.name, options.version);
77
+ let settled = false;
78
+ const elapsed = () => Date.now() - start;
79
+ const rejectWith = (reason, cause) => {
80
+ if (settled)
81
+ return;
82
+ settled = true;
83
+ clearTimeout(timer);
84
+ reject(new IDBOpenError(reason, options.name, elapsed(), cause));
85
+ };
86
+ const timer = setTimeout(() => rejectWith("timeout"), IDB_OPEN_TIMEOUT_MS);
87
+ request.onerror = () => rejectWith("error", request.error);
88
+ request.onblocked = () => rejectWith("blocked");
89
+ request.onsuccess = () => {
90
+ if (settled)
91
+ return;
92
+ settled = true;
93
+ clearTimeout(timer);
94
+ resolve(request.result);
95
+ };
96
+ request.onupgradeneeded = (event) => {
97
+ const db = event.target.result;
98
+ options.upgrade(db, event);
99
+ };
100
+ });
101
+ }
102
+ function cachedOpen(ref, options, openFn) {
103
+ if (ref.promise)
104
+ return ref.promise;
105
+ const pending = openIDB(options, openFn);
106
+ pending.catch(() => {
107
+ if (ref.promise === pending)
108
+ ref.promise = null;
109
+ });
110
+ ref.promise = pending;
111
+ return pending;
112
+ }
113
+ function runRequest(request) {
114
+ return new Promise((resolve, reject) => {
115
+ request.onsuccess = () => resolve(request.result);
116
+ request.onerror = () => reject(request.error);
117
+ });
118
+ }
119
+ function runTx(db, storeName, mode, fn) {
120
+ return new Promise((resolve, reject) => {
121
+ const tx = db.transaction(storeName, mode);
122
+ const store = tx.objectStore(storeName);
123
+ tx.oncomplete = () => resolve();
124
+ tx.onerror = () => reject(tx.error);
125
+ tx.onabort = () => reject(tx.error);
126
+ try {
127
+ fn(store);
128
+ } catch (err) {
129
+ try {
130
+ tx.abort();
131
+ } catch {}
132
+ reject(err);
133
+ }
134
+ });
135
+ }
136
+ function iterateCursor(db, storeName, visit) {
137
+ return new Promise((resolve, reject) => {
138
+ const tx = db.transaction(storeName, "readonly");
139
+ const store = tx.objectStore(storeName);
140
+ const request = store.openCursor();
141
+ request.onsuccess = () => {
142
+ const cursor = request.result;
143
+ if (!cursor)
144
+ return resolve();
145
+ visit(cursor.key, cursor.value);
146
+ cursor.continue();
147
+ };
148
+ request.onerror = () => reject(request.error);
149
+ });
150
+ }
151
+ var IDB_OPEN_TIMEOUT_MS = 5000, IDBOpenError, defaultOpenFn = (name, version) => indexedDB.open(name, version);
152
+ var init_idb_helpers = __esm(() => {
153
+ IDBOpenError = class IDBOpenError extends Error {
154
+ reason;
155
+ dbName;
156
+ elapsedMs;
157
+ constructor(reason, dbName, elapsedMs, cause) {
158
+ super(`Polly IndexedDB open of '${dbName}' ${reason} after ${elapsedMs}ms`, cause === undefined ? undefined : { cause });
159
+ this.name = "IDBOpenError";
160
+ this.reason = reason;
161
+ this.dbName = dbName;
162
+ this.elapsedMs = elapsedMs;
163
+ }
164
+ };
165
+ });
166
+
72
167
  // src/shared/lib/encryption.ts
73
168
  var exports_encryption = {};
74
169
  __export(exports_encryption, {
@@ -169,6 +264,8 @@ var wasmUrl = new URL(wasmPath, import.meta.url).href;
169
264
  await initializeWasm(wasmUrl);
170
265
 
171
266
  // src/shared/lib/blob-cache.ts
267
+ init_idb_helpers();
268
+
172
269
  class MemoryBlobCache {
173
270
  store = new Map;
174
271
  pinned = new Set;
@@ -255,69 +352,28 @@ class IndexedDBBlobCache {
255
352
  static DB_NAME = "polly-blobs";
256
353
  static DB_VERSION = 1;
257
354
  static STORE_NAME = "blobs";
258
- dbPromise = null;
355
+ dbRef = { promise: null };
259
356
  urls = new Map;
260
- static OPEN_TIMEOUT_MS = 5000;
261
357
  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;
358
+ return cachedOpen(this.dbRef, {
359
+ name: IndexedDBBlobCache.DB_NAME,
360
+ version: IndexedDBBlobCache.DB_VERSION,
361
+ upgrade: (db) => {
291
362
  if (!db.objectStoreNames.contains(IndexedDBBlobCache.STORE_NAME)) {
292
363
  db.createObjectStore(IndexedDBBlobCache.STORE_NAME);
293
364
  }
294
- };
295
- });
296
- pending.catch(() => {
297
- if (this.dbPromise === pending)
298
- this.dbPromise = null;
365
+ }
299
366
  });
300
- this.dbPromise = pending;
301
- return pending;
302
367
  }
303
368
  async getRecord(hash) {
304
369
  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
- });
370
+ const tx = db.transaction(IndexedDBBlobCache.STORE_NAME, "readonly");
371
+ return runRequest(tx.objectStore(IndexedDBBlobCache.STORE_NAME).get(hash));
312
372
  }
313
373
  async putRecord(hash, record) {
314
374
  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);
375
+ await runTx(db, IndexedDBBlobCache.STORE_NAME, "readwrite", (store) => {
318
376
  store.put(record, hash);
319
- tx.oncomplete = () => resolve();
320
- tx.onerror = () => reject(tx.error);
321
377
  });
322
378
  }
323
379
  async get(hash) {
@@ -338,13 +394,9 @@ class IndexedDBBlobCache {
338
394
  }
339
395
  async has(hash) {
340
396
  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
- });
397
+ const tx = db.transaction(IndexedDBBlobCache.STORE_NAME, "readonly");
398
+ const count = await runRequest(tx.objectStore(IndexedDBBlobCache.STORE_NAME).count(hash));
399
+ return count > 0;
348
400
  }
349
401
  async delete(hash) {
350
402
  const url = this.urls.get(hash);
@@ -353,12 +405,8 @@ class IndexedDBBlobCache {
353
405
  this.urls.delete(hash);
354
406
  }
355
407
  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);
408
+ await runTx(db, IndexedDBBlobCache.STORE_NAME, "readwrite", (store) => {
359
409
  store.delete(hash);
360
- tx.oncomplete = () => resolve();
361
- tx.onerror = () => reject(tx.error);
362
410
  });
363
411
  }
364
412
  async pin(hash) {
@@ -375,50 +423,25 @@ class IndexedDBBlobCache {
375
423
  }
376
424
  async size() {
377
425
  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);
426
+ let total = 0;
427
+ await iterateCursor(db, IndexedDBBlobCache.STORE_NAME, (_key, value) => {
428
+ total += value.size;
394
429
  });
430
+ return total;
395
431
  }
396
432
  async evict(maxBytes) {
397
433
  const db = await this.openDB();
398
434
  const candidates = [];
399
435
  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);
436
+ await iterateCursor(db, IndexedDBBlobCache.STORE_NAME, (key, value) => {
437
+ totalSize += value.size;
438
+ if (!value.pinned) {
439
+ candidates.push({
440
+ hash: key,
441
+ accessedAt: value.accessedAt,
442
+ size: value.size
443
+ });
444
+ }
422
445
  });
423
446
  if (totalSize <= maxBytes)
424
447
  return 0;
@@ -1812,6 +1835,7 @@ function resetMeshState() {
1812
1835
  lastLoadedRejection = undefined;
1813
1836
  lastStorageOpenError = undefined;
1814
1837
  lazyWrappers = [];
1838
+ docIdResolver = undefined;
1815
1839
  }
1816
1840
  function isMeshStateConfigured() {
1817
1841
  return defaultRepo !== undefined;
@@ -1917,8 +1941,18 @@ function deriveDocumentId(key) {
1917
1941
  const bytes = digest.slice(0, 16);
1918
1942
  return interpretAsDocumentId(bytes);
1919
1943
  }
1944
+ var docIdResolver;
1945
+ function registerDocIdResolver(resolver) {
1946
+ docIdResolver = resolver;
1947
+ }
1948
+ function getDocIdResolver() {
1949
+ return docIdResolver;
1950
+ }
1951
+ function resolveDocumentId(key) {
1952
+ return docIdResolver?.(key) ?? deriveDocumentId(key);
1953
+ }
1920
1954
  function buildHandleFactory(repo, key, initialDoc) {
1921
- const documentId = deriveDocumentId(key);
1955
+ const documentId = resolveDocumentId(key);
1922
1956
  return async () => {
1923
1957
  lazyInvocations++;
1924
1958
  let exitReason = "threw";
@@ -3594,7 +3628,9 @@ export {
3594
3628
  serialisePairingToken,
3595
3629
  serialiseKeyring,
3596
3630
  revokePeerLocally,
3631
+ resolveDocumentId,
3597
3632
  resetMeshState,
3633
+ registerDocIdResolver,
3598
3634
  parsePairingToken,
3599
3635
  memoryKeyringStorage,
3600
3636
  isPairingTokenExpired,
@@ -3607,12 +3643,14 @@ export {
3607
3643
  getLazyInvocations,
3608
3644
  getLastLoadedRejection,
3609
3645
  getLastConfiguredRepoPeerId,
3646
+ getDocIdResolver,
3610
3647
  generateSigningKeyPair,
3611
3648
  generateDocumentKey,
3612
3649
  encrypt,
3613
3650
  encodeRevocation,
3614
3651
  encodePairingToken,
3615
3652
  deserialiseKeyring,
3653
+ deriveDocumentId,
3616
3654
  decryptOrThrow,
3617
3655
  decrypt,
3618
3656
  decodeRevocation,
@@ -3656,4 +3694,4 @@ export {
3656
3694
  $meshCounter
3657
3695
  };
3658
3696
 
3659
- //# debugId=81CAD9639A4786EB64756E2164756E21
3697
+ //# debugId=82752400E00815C464756E2164756E21