@fairfox/polly 0.14.0 → 0.15.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.
Files changed (32) hide show
  1. package/dist/src/background/index.js +342 -3
  2. package/dist/src/background/index.js.map +7 -4
  3. package/dist/src/background/message-router.js +342 -3
  4. package/dist/src/background/message-router.js.map +7 -4
  5. package/dist/src/index.js +402 -99
  6. package/dist/src/index.js.map +8 -5
  7. package/dist/src/shared/adapters/index.d.ts +3 -0
  8. package/dist/src/shared/adapters/index.js +356 -4
  9. package/dist/src/shared/adapters/index.js.map +7 -4
  10. package/dist/src/shared/lib/adapter-factory.d.ts +80 -0
  11. package/dist/src/shared/lib/context-helpers.js +342 -3
  12. package/dist/src/shared/lib/context-helpers.js.map +7 -4
  13. package/dist/src/shared/lib/message-bus.js +342 -3
  14. package/dist/src/shared/lib/message-bus.js.map +7 -4
  15. package/dist/src/shared/lib/state.d.ts +5 -1
  16. package/dist/src/shared/lib/state.js +274 -1173
  17. package/dist/src/shared/lib/state.js.map +6 -19
  18. package/dist/src/shared/lib/storage-adapter.d.ts +42 -0
  19. package/dist/src/shared/lib/sync-adapter.d.ts +79 -0
  20. package/dist/src/shared/state/app-state.js +294 -1173
  21. package/dist/src/shared/state/app-state.js.map +6 -18
  22. package/dist/tools/analysis/src/extract/handlers.d.ts +48 -1
  23. package/dist/tools/analysis/src/types/core.d.ts +20 -0
  24. package/dist/tools/teach/src/cli.js +454 -7
  25. package/dist/tools/teach/src/cli.js.map +4 -4
  26. package/dist/tools/teach/src/index.js +232 -7
  27. package/dist/tools/teach/src/index.js.map +3 -3
  28. package/dist/tools/verify/src/cli.js +234 -9
  29. package/dist/tools/verify/src/cli.js.map +4 -4
  30. package/dist/tools/visualize/src/cli.js +232 -7
  31. package/dist/tools/visualize/src/cli.js.map +3 -3
  32. package/package.json +1 -1
@@ -48,6 +48,293 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
48
48
  throw Error('Dynamic require of "' + x + '" is not supported');
49
49
  });
50
50
 
51
+ // src/shared/lib/storage-adapter.ts
52
+ var exports_storage_adapter = {};
53
+ __export(exports_storage_adapter, {
54
+ createStorageAdapter: () => createStorageAdapter,
55
+ MemoryStorageAdapter: () => MemoryStorageAdapter,
56
+ IndexedDBAdapter: () => IndexedDBAdapter,
57
+ ChromeStorageAdapter: () => ChromeStorageAdapter2
58
+ });
59
+
60
+ class IndexedDBAdapter {
61
+ dbName;
62
+ storeName = "state";
63
+ dbPromise = null;
64
+ constructor(dbName = "polly-state") {
65
+ this.dbName = dbName;
66
+ }
67
+ getDB() {
68
+ if (this.dbPromise)
69
+ return this.dbPromise;
70
+ this.dbPromise = new Promise((resolve, reject) => {
71
+ const request = indexedDB.open(this.dbName, 1);
72
+ request.onerror = () => reject(request.error);
73
+ request.onsuccess = () => resolve(request.result);
74
+ request.onupgradeneeded = (event) => {
75
+ const db = event.target.result;
76
+ if (!db.objectStoreNames.contains(this.storeName)) {
77
+ db.createObjectStore(this.storeName);
78
+ }
79
+ };
80
+ });
81
+ return this.dbPromise;
82
+ }
83
+ async get(keys) {
84
+ try {
85
+ const db = await this.getDB();
86
+ const result = {};
87
+ await Promise.all(keys.map((key) => new Promise((resolve, reject) => {
88
+ const transaction = db.transaction([this.storeName], "readonly");
89
+ const store = transaction.objectStore(this.storeName);
90
+ const request = store.get(key);
91
+ request.onerror = () => reject(request.error);
92
+ request.onsuccess = () => {
93
+ if (request.result !== undefined) {
94
+ result[key] = request.result;
95
+ }
96
+ resolve();
97
+ };
98
+ })));
99
+ return result;
100
+ } catch (error) {
101
+ console.warn("[Polly] IndexedDB get failed:", error);
102
+ return {};
103
+ }
104
+ }
105
+ async set(items) {
106
+ try {
107
+ const db = await this.getDB();
108
+ await Promise.all(Object.entries(items).map(([key, value]) => new Promise((resolve, reject) => {
109
+ const transaction = db.transaction([this.storeName], "readwrite");
110
+ const store = transaction.objectStore(this.storeName);
111
+ const request = store.put(value, key);
112
+ request.onerror = () => reject(request.error);
113
+ request.onsuccess = () => resolve();
114
+ })));
115
+ } catch (error) {
116
+ console.warn("[Polly] IndexedDB set failed:", error);
117
+ }
118
+ }
119
+ async remove(keys) {
120
+ try {
121
+ const db = await this.getDB();
122
+ await Promise.all(keys.map((key) => new Promise((resolve, reject) => {
123
+ const transaction = db.transaction([this.storeName], "readwrite");
124
+ const store = transaction.objectStore(this.storeName);
125
+ const request = store.delete(key);
126
+ request.onerror = () => reject(request.error);
127
+ request.onsuccess = () => resolve();
128
+ })));
129
+ } catch (error) {
130
+ console.warn("[Polly] IndexedDB remove failed:", error);
131
+ }
132
+ }
133
+ }
134
+
135
+ class ChromeStorageAdapter2 {
136
+ async get(keys) {
137
+ if (typeof chrome === "undefined" || !chrome.storage) {
138
+ return {};
139
+ }
140
+ try {
141
+ return await chrome.storage.local.get(keys);
142
+ } catch (error) {
143
+ console.warn("[Polly] Chrome storage get failed:", error);
144
+ return {};
145
+ }
146
+ }
147
+ async set(items) {
148
+ if (typeof chrome === "undefined" || !chrome.storage) {
149
+ return;
150
+ }
151
+ try {
152
+ await chrome.storage.local.set(items);
153
+ } catch (error) {
154
+ console.warn("[Polly] Chrome storage set failed:", error);
155
+ }
156
+ }
157
+ async remove(keys) {
158
+ if (typeof chrome === "undefined" || !chrome.storage) {
159
+ return;
160
+ }
161
+ try {
162
+ await chrome.storage.local.remove(keys);
163
+ } catch (error) {
164
+ console.warn("[Polly] Chrome storage remove failed:", error);
165
+ }
166
+ }
167
+ }
168
+
169
+ class MemoryStorageAdapter {
170
+ storage = new Map;
171
+ async get(keys) {
172
+ const result = {};
173
+ for (const key of keys) {
174
+ const value = this.storage.get(key);
175
+ if (value !== undefined) {
176
+ result[key] = value;
177
+ }
178
+ }
179
+ return result;
180
+ }
181
+ async set(items) {
182
+ for (const [key, value] of Object.entries(items)) {
183
+ this.storage.set(key, value);
184
+ }
185
+ }
186
+ async remove(keys) {
187
+ for (const key of keys) {
188
+ this.storage.delete(key);
189
+ }
190
+ }
191
+ }
192
+ function createStorageAdapter() {
193
+ if (typeof chrome !== "undefined" && chrome.storage && chrome.runtime) {
194
+ return new ChromeStorageAdapter2;
195
+ }
196
+ if (typeof indexedDB !== "undefined") {
197
+ return new IndexedDBAdapter;
198
+ }
199
+ return new MemoryStorageAdapter;
200
+ }
201
+
202
+ // src/shared/lib/sync-adapter.ts
203
+ var exports_sync_adapter = {};
204
+ __export(exports_sync_adapter, {
205
+ createSyncAdapter: () => createSyncAdapter,
206
+ NoOpSyncAdapter: () => NoOpSyncAdapter,
207
+ ChromeRuntimeSyncAdapter: () => ChromeRuntimeSyncAdapter,
208
+ BroadcastChannelSyncAdapter: () => BroadcastChannelSyncAdapter
209
+ });
210
+
211
+ class NoOpSyncAdapter {
212
+ broadcast(_message) {}
213
+ onMessage(_callback) {
214
+ return () => {};
215
+ }
216
+ }
217
+
218
+ class ChromeRuntimeSyncAdapter {
219
+ listeners = [];
220
+ port = null;
221
+ constructor() {
222
+ if (typeof chrome !== "undefined" && chrome.runtime) {
223
+ chrome.runtime.onMessage.addListener((message, _sender, _sendResponse) => {
224
+ if (message.type === "STATE_SYNC") {
225
+ this.listeners.forEach((listener) => {
226
+ listener(message);
227
+ });
228
+ }
229
+ });
230
+ }
231
+ }
232
+ broadcast(message) {
233
+ if (typeof chrome === "undefined" || !chrome.runtime) {
234
+ console.warn("[SyncAdapter] chrome.runtime not available");
235
+ return;
236
+ }
237
+ try {
238
+ chrome.runtime.sendMessage({
239
+ type: "STATE_SYNC",
240
+ key: message.key,
241
+ value: message.value,
242
+ clock: message.clock
243
+ });
244
+ } catch (error) {
245
+ console.warn("[SyncAdapter] Failed to broadcast state update:", error);
246
+ }
247
+ }
248
+ onMessage(callback) {
249
+ this.listeners.push(callback);
250
+ return () => {
251
+ const index = this.listeners.indexOf(callback);
252
+ if (index > -1) {
253
+ this.listeners.splice(index, 1);
254
+ }
255
+ };
256
+ }
257
+ connect() {
258
+ return Promise.resolve();
259
+ }
260
+ disconnect() {
261
+ this.listeners = [];
262
+ if (this.port) {
263
+ this.port.disconnect();
264
+ this.port = null;
265
+ }
266
+ }
267
+ isConnected() {
268
+ return typeof chrome !== "undefined" && !!chrome.runtime;
269
+ }
270
+ }
271
+
272
+ class BroadcastChannelSyncAdapter {
273
+ channel = null;
274
+ listeners = [];
275
+ constructor(channelName = "polly-sync") {
276
+ if (typeof BroadcastChannel !== "undefined") {
277
+ this.channel = new BroadcastChannel(channelName);
278
+ this.channel.onmessage = (event) => {
279
+ if (event.data.type === "STATE_SYNC") {
280
+ this.listeners.forEach((listener) => {
281
+ listener(event.data);
282
+ });
283
+ }
284
+ };
285
+ } else {
286
+ console.warn("[SyncAdapter] BroadcastChannel not available");
287
+ }
288
+ }
289
+ broadcast(message) {
290
+ if (!this.channel) {
291
+ console.warn("[SyncAdapter] BroadcastChannel not initialized");
292
+ return;
293
+ }
294
+ try {
295
+ this.channel.postMessage({
296
+ type: "STATE_SYNC",
297
+ key: message.key,
298
+ value: message.value,
299
+ clock: message.clock
300
+ });
301
+ } catch (error) {
302
+ console.warn("[SyncAdapter] Failed to broadcast state update:", error);
303
+ }
304
+ }
305
+ onMessage(callback) {
306
+ this.listeners.push(callback);
307
+ return () => {
308
+ const index = this.listeners.indexOf(callback);
309
+ if (index > -1) {
310
+ this.listeners.splice(index, 1);
311
+ }
312
+ };
313
+ }
314
+ connect() {
315
+ return Promise.resolve();
316
+ }
317
+ disconnect() {
318
+ this.listeners = [];
319
+ if (this.channel) {
320
+ this.channel.close();
321
+ this.channel = null;
322
+ }
323
+ }
324
+ isConnected() {
325
+ return this.channel !== null;
326
+ }
327
+ }
328
+ function createSyncAdapter() {
329
+ if (typeof chrome !== "undefined" && chrome.runtime) {
330
+ return new ChromeRuntimeSyncAdapter;
331
+ }
332
+ if (typeof BroadcastChannel !== "undefined") {
333
+ return new BroadcastChannelSyncAdapter;
334
+ }
335
+ return new NoOpSyncAdapter;
336
+ }
337
+
51
338
  // src/shared/lib/constraints.ts
52
339
  var exports_constraints = {};
53
340
  __export(exports_constraints, {
@@ -413,8 +700,60 @@ class MessageLoggerAdapter {
413
700
  }
414
701
  }
415
702
 
703
+ // src/shared/lib/adapter-factory.ts
704
+ function createStateAdapters(options = {}) {
705
+ if (options.storage && options.sync) {
706
+ return {
707
+ storage: options.storage,
708
+ sync: options.sync
709
+ };
710
+ }
711
+ const storage = options.storage || createStorageAdapter();
712
+ let sync;
713
+ if (options.sync) {
714
+ sync = options.sync;
715
+ } else if (options.singleTab) {
716
+ const { NoOpSyncAdapter: NoOpSyncAdapter2 } = __toCommonJS(exports_sync_adapter);
717
+ sync = new NoOpSyncAdapter2;
718
+ } else {
719
+ sync = createSyncAdapter();
720
+ }
721
+ return { storage, sync };
722
+ }
723
+ function createChromeAdapters() {
724
+ const { ChromeStorageAdapter: ChromeStorageAdapter3 } = __toCommonJS(exports_storage_adapter);
725
+ const { ChromeRuntimeSyncAdapter: ChromeRuntimeSyncAdapter2 } = __toCommonJS(exports_sync_adapter);
726
+ return {
727
+ storage: new ChromeStorageAdapter3,
728
+ sync: new ChromeRuntimeSyncAdapter2
729
+ };
730
+ }
731
+ function createWebAdapters(options = {}) {
732
+ const { IndexedDBAdapter: IndexedDBAdapter2 } = __toCommonJS(exports_storage_adapter);
733
+ const { BroadcastChannelSyncAdapter: BroadcastChannelSyncAdapter2, NoOpSyncAdapter: NoOpSyncAdapter2 } = __toCommonJS(exports_sync_adapter);
734
+ const storage = new IndexedDBAdapter2(options.dbName);
735
+ const sync = options.singleTab ? new NoOpSyncAdapter2 : new BroadcastChannelSyncAdapter2(options.channelName);
736
+ return { storage, sync };
737
+ }
738
+ function createNodeAdapters() {
739
+ const { MemoryStorageAdapter: MemoryStorageAdapter2 } = __toCommonJS(exports_storage_adapter);
740
+ const { NoOpSyncAdapter: NoOpSyncAdapter2 } = __toCommonJS(exports_sync_adapter);
741
+ return {
742
+ storage: new MemoryStorageAdapter2,
743
+ sync: new NoOpSyncAdapter2
744
+ };
745
+ }
746
+ function createMockAdapters() {
747
+ const { MemoryStorageAdapter: MemoryStorageAdapter2 } = __toCommonJS(exports_storage_adapter);
748
+ const { NoOpSyncAdapter: NoOpSyncAdapter2 } = __toCommonJS(exports_sync_adapter);
749
+ return {
750
+ storage: new MemoryStorageAdapter2,
751
+ sync: new NoOpSyncAdapter2
752
+ };
753
+ }
754
+
416
755
  // src/shared/adapters/index.ts
417
- function createChromeAdapters(context, options) {
756
+ function createChromeAdapters2(context, options) {
418
757
  const runtime2 = new ChromeRuntimeAdapter;
419
758
  return {
420
759
  runtime: runtime2,
@@ -812,7 +1151,7 @@ class MessageBus {
812
1151
  messageListener = null;
813
1152
  constructor(context, adapters, options) {
814
1153
  this.context = context;
815
- this.adapters = adapters || createChromeAdapters(context);
1154
+ this.adapters = adapters || createChromeAdapters2(context);
816
1155
  this.errorHandler = new ErrorHandler(this.adapters.logger);
817
1156
  this.helpers = this.createContextHelpers();
818
1157
  if (!options?.skipListenerSetup) {
@@ -1480,4 +1819,4 @@ export {
1480
1819
  MessageRouter
1481
1820
  };
1482
1821
 
1483
- //# debugId=6D0BF9905E57154464756E2164756E21
1822
+ //# debugId=55057EE1E1BCC1B964756E2164756E21