@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.
@@ -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/storage-adapter.ts
73
168
  var exports_storage_adapter = {};
74
169
  __export(exports_storage_adapter, {
@@ -81,68 +176,32 @@ __export(exports_storage_adapter, {
81
176
  class IndexedDBAdapter {
82
177
  dbName;
83
178
  storeName = "state";
84
- dbPromise = null;
179
+ dbRef = { promise: null };
85
180
  constructor(dbName = "polly-state") {
86
181
  this.dbName = dbName;
87
182
  }
88
183
  getDB() {
89
- if (this.dbPromise)
90
- return this.dbPromise;
91
- const pending = new Promise((resolve, reject) => {
92
- const start = Date.now();
93
- const request = indexedDB.open(this.dbName, 1);
94
- let settled = false;
95
- const timer = setTimeout(() => {
96
- if (settled)
97
- return;
98
- settled = true;
99
- const elapsedMs = Date.now() - start;
100
- reject(new Error(`Polly IndexedDB open of '${this.dbName}' timed out after ${elapsedMs}ms (cross-tab lock or zombie connection?)`));
101
- }, IDB_OPEN_TIMEOUT_MS);
102
- request.onerror = () => {
103
- if (settled)
104
- return;
105
- settled = true;
106
- clearTimeout(timer);
107
- reject(request.error);
108
- };
109
- request.onsuccess = () => {
110
- if (settled)
111
- return;
112
- settled = true;
113
- clearTimeout(timer);
114
- resolve(request.result);
115
- };
116
- request.onupgradeneeded = (event) => {
117
- const db = event.target.result;
184
+ return cachedOpen(this.dbRef, {
185
+ name: this.dbName,
186
+ version: 1,
187
+ upgrade: (db) => {
118
188
  if (!db.objectStoreNames.contains(this.storeName)) {
119
189
  db.createObjectStore(this.storeName);
120
190
  }
121
- };
122
- });
123
- pending.catch(() => {
124
- if (this.dbPromise === pending)
125
- this.dbPromise = null;
191
+ }
126
192
  });
127
- this.dbPromise = pending;
128
- return pending;
129
193
  }
130
194
  async get(keys) {
131
195
  try {
132
196
  const db = await this.getDB();
197
+ const tx = db.transaction(this.storeName, "readonly");
198
+ const store = tx.objectStore(this.storeName);
199
+ const pairs = await Promise.all(keys.map(async (key) => [key, await runRequest(store.get(key))]));
133
200
  const result = {};
134
- await Promise.all(keys.map((key) => new Promise((resolve, reject) => {
135
- const transaction = db.transaction([this.storeName], "readonly");
136
- const store = transaction.objectStore(this.storeName);
137
- const request = store.get(key);
138
- request.onerror = () => reject(request.error);
139
- request.onsuccess = () => {
140
- if (request.result !== undefined) {
141
- result[key] = request.result;
142
- }
143
- resolve();
144
- };
145
- })));
201
+ for (const [key, value] of pairs) {
202
+ if (value !== undefined)
203
+ result[key] = value;
204
+ }
146
205
  return result;
147
206
  } catch (error) {
148
207
  console.warn("[Polly] IndexedDB get failed:", error);
@@ -152,13 +211,11 @@ class IndexedDBAdapter {
152
211
  async set(items) {
153
212
  try {
154
213
  const db = await this.getDB();
155
- await Promise.all(Object.entries(items).map(([key, value]) => new Promise((resolve, reject) => {
156
- const transaction = db.transaction([this.storeName], "readwrite");
157
- const store = transaction.objectStore(this.storeName);
158
- const request = store.put(value, key);
159
- request.onerror = () => reject(request.error);
160
- request.onsuccess = () => resolve();
161
- })));
214
+ await runTx(db, this.storeName, "readwrite", (store) => {
215
+ for (const [key, value] of Object.entries(items)) {
216
+ store.put(value, key);
217
+ }
218
+ });
162
219
  } catch (error) {
163
220
  console.warn("[Polly] IndexedDB set failed:", error);
164
221
  }
@@ -166,13 +223,10 @@ class IndexedDBAdapter {
166
223
  async remove(keys) {
167
224
  try {
168
225
  const db = await this.getDB();
169
- await Promise.all(keys.map((key) => new Promise((resolve, reject) => {
170
- const transaction = db.transaction([this.storeName], "readwrite");
171
- const store = transaction.objectStore(this.storeName);
172
- const request = store.delete(key);
173
- request.onerror = () => reject(request.error);
174
- request.onsuccess = () => resolve();
175
- })));
226
+ await runTx(db, this.storeName, "readwrite", (store) => {
227
+ for (const key of keys)
228
+ store.delete(key);
229
+ });
176
230
  } catch (error) {
177
231
  console.warn("[Polly] IndexedDB remove failed:", error);
178
232
  }
@@ -245,7 +299,9 @@ function createStorageAdapter() {
245
299
  }
246
300
  return new MemoryStorageAdapter;
247
301
  }
248
- var IDB_OPEN_TIMEOUT_MS = 5000;
302
+ var init_storage_adapter = __esm(() => {
303
+ init_idb_helpers();
304
+ });
249
305
 
250
306
  // src/shared/lib/sync-adapter.ts
251
307
  var exports_sync_adapter = {};
@@ -749,6 +805,7 @@ class MessageLoggerAdapter {
749
805
  }
750
806
 
751
807
  // src/shared/lib/adapter-factory.ts
808
+ init_storage_adapter();
752
809
  function createStateAdapters(options = {}) {
753
810
  if (options.storage && options.sync) {
754
811
  return {
@@ -769,7 +826,7 @@ function createStateAdapters(options = {}) {
769
826
  return { storage, sync };
770
827
  }
771
828
  function createChromeAdapters() {
772
- const { ChromeStorageAdapter: ChromeStorageAdapter3 } = __toCommonJS(exports_storage_adapter);
829
+ const { ChromeStorageAdapter: ChromeStorageAdapter3 } = (init_storage_adapter(), __toCommonJS(exports_storage_adapter));
773
830
  const { ChromeRuntimeSyncAdapter: ChromeRuntimeSyncAdapter2 } = __toCommonJS(exports_sync_adapter);
774
831
  return {
775
832
  storage: new ChromeStorageAdapter3,
@@ -777,14 +834,14 @@ function createChromeAdapters() {
777
834
  };
778
835
  }
779
836
  function createWebAdapters(options = {}) {
780
- const { IndexedDBAdapter: IndexedDBAdapter2 } = __toCommonJS(exports_storage_adapter);
837
+ const { IndexedDBAdapter: IndexedDBAdapter2 } = (init_storage_adapter(), __toCommonJS(exports_storage_adapter));
781
838
  const { BroadcastChannelSyncAdapter: BroadcastChannelSyncAdapter2, NoOpSyncAdapter: NoOpSyncAdapter2 } = __toCommonJS(exports_sync_adapter);
782
839
  const storage = new IndexedDBAdapter2(options.dbName);
783
840
  const sync = options.singleTab ? new NoOpSyncAdapter2 : new BroadcastChannelSyncAdapter2(options.channelName);
784
841
  return { storage, sync };
785
842
  }
786
843
  function createNodeAdapters() {
787
- const { MemoryStorageAdapter: MemoryStorageAdapter2 } = __toCommonJS(exports_storage_adapter);
844
+ const { MemoryStorageAdapter: MemoryStorageAdapter2 } = (init_storage_adapter(), __toCommonJS(exports_storage_adapter));
788
845
  const { NoOpSyncAdapter: NoOpSyncAdapter2 } = __toCommonJS(exports_sync_adapter);
789
846
  return {
790
847
  storage: new MemoryStorageAdapter2,
@@ -792,7 +849,7 @@ function createNodeAdapters() {
792
849
  };
793
850
  }
794
851
  function createMockAdapters() {
795
- const { MemoryStorageAdapter: MemoryStorageAdapter2 } = __toCommonJS(exports_storage_adapter);
852
+ const { MemoryStorageAdapter: MemoryStorageAdapter2 } = (init_storage_adapter(), __toCommonJS(exports_storage_adapter));
796
853
  const { NoOpSyncAdapter: NoOpSyncAdapter2 } = __toCommonJS(exports_sync_adapter);
797
854
  return {
798
855
  storage: new MemoryStorageAdapter2,
@@ -801,6 +858,7 @@ function createMockAdapters() {
801
858
  }
802
859
 
803
860
  // src/shared/adapters/index.ts
861
+ init_storage_adapter();
804
862
  function createChromeAdapters2(context, options) {
805
863
  const runtime2 = new ChromeRuntimeAdapter;
806
864
  return {
@@ -1857,4 +1915,4 @@ export {
1857
1915
  MessageRouter
1858
1916
  };
1859
1917
 
1860
- //# debugId=8B9539FBFEA7D97464756E2164756E21
1918
+ //# debugId=545665F5DC5E412964756E2164756E21