(function (root, factory) { if (typeof module !== 'undefined' && module.exports) module.exports = factory; else root.stackchainPrivateDeviceData = factory({ localStorage: root.localStorage, sessionStorage: root.sessionStorage, indexedDB: root.indexedDB, caches: root.caches, serviceWorker: root.navigator?.serviceWorker, MessageChannel: root.MessageChannel, }); })(typeof window !== 'undefined' ? window : this, function createPrivateDeviceDataPurger({ localStorage, sessionStorage, indexedDB, caches, serviceWorker, MessageChannel, }) { function removeOwnedStorage(storage) { if (!storage) return; const keys = []; for (let index = 0; index < storage.length; index += 1) { const key = storage.key(index); if (key?.startsWith('stackchain.')) keys.push(key); } keys.forEach(key => storage.removeItem(key)); } async function stopWorkerOutbox() { const registration = await serviceWorker?.ready; if (!registration?.active || !MessageChannel) return; await new Promise((resolve, reject) => { const channel = new MessageChannel(); const timeout = setTimeout(() => reject(new Error('Background outbox purge timed out.')), 3000); channel.port1.onmessage = event => { clearTimeout(timeout); if (event.data?.ok) resolve(); else reject(new Error(event.data?.error || 'Background outbox purge failed.')); }; registration.active.postMessage({ type: 'stackchain-purge-outbox' }, [channel.port2]); }); } function deletePrivateDatabase(name) { if (!indexedDB) return Promise.resolve(); return new Promise((resolve, reject) => { let request; try { request = indexedDB.deleteDatabase(name); } catch (error) { reject(error); return; } request.onsuccess = () => resolve(); request.onerror = () => reject(request.error || new Error('IndexedDB deletion failed.')); request.onblocked = () => reject(new Error('IndexedDB deletion was blocked.')); }); } return async function clearPrivateDeviceData() { removeOwnedStorage(localStorage); if (sessionStorage !== localStorage) removeOwnedStorage(sessionStorage); await stopWorkerOutbox(); await deletePrivateDatabase('stackchain-background-outbox-v1'); await deletePrivateDatabase('stackchain-offline-work-v2'); const keys = await caches?.keys?.() || []; await Promise.all( keys.filter(key => key.startsWith('stackchain-dashboard-')).map(key => caches.delete(key)) ); }; });