@sweidos/eidos 2.2.0 → 2.3.1

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/devtools.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { useCallback, useState, useSyncExternalStore } from "react";
2
+ import { useCallback, useEffect, useState, useSyncExternalStore } from "react";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/types.ts
5
5
  function emptyReliabilityStats() {
@@ -187,6 +187,9 @@ function useEidosReliabilityStats() {
187
187
  //#region src/sw-bridge.ts
188
188
  var _registration = null;
189
189
  var _pendingMessages = [];
190
+ function getSwRegistration() {
191
+ return _registration;
192
+ }
190
193
  function sendToWorker(message) {
191
194
  const sw = _registration?.active;
192
195
  if (sw) sw.postMessage(message);
@@ -199,6 +202,14 @@ function setOfflineSimulation(enabled) {
199
202
  });
200
203
  useEidosStore.getState().setOnline(!enabled);
201
204
  }
205
+ /**
206
+ * Tells the waiting service worker to activate immediately, then reloads the page.
207
+ * Only relevant when `skipWaiting: false` — call this after the user confirms
208
+ * a "reload to update" toast shown via `onUpdateAvailable`.
209
+ */
210
+ function triggerSwUpdate() {
211
+ _registration?.waiting?.postMessage({ type: "EIDOS_SKIP_WAITING" });
212
+ }
202
213
  //#endregion
203
214
  //#region src/idb.ts
204
215
  var DB_NAME = "eidos";
@@ -752,7 +763,9 @@ var ICONS = {
752
763
  clock: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM12 6v6l4 2",
753
764
  x: "M18 6 6 18M6 6l12 12",
754
765
  rotateCcw: "M3 12a9 9 0 1 0 2.6-6.4M3 12V5m0 7h7",
755
- activity: "M22 12h-4l-3 9L9 3l-3 9H2"
766
+ activity: "M22 12h-4l-3 9L9 3l-3 9H2",
767
+ shield: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",
768
+ refreshCw: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8M21 3v5h-5M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16M3 21v-5h5"
756
769
  };
757
770
  function positionStyle(p) {
758
771
  const base = {
@@ -996,7 +1009,8 @@ function EidosDevtools({ position = "bottom-right", defaultOpen = false }) {
996
1009
  children: [
997
1010
  "queue",
998
1011
  "cache",
999
- "reliability"
1012
+ "reliability",
1013
+ "sw"
1000
1014
  ].map((t) => /* @__PURE__ */ jsx("button", {
1001
1015
  role: "tab",
1002
1016
  "aria-selected": tab === t,
@@ -1018,7 +1032,7 @@ function EidosDevtools({ position = "bottom-right", defaultOpen = false }) {
1018
1032
  letterSpacing: "0.05em",
1019
1033
  transition: "color 0.15s, border-color 0.15s"
1020
1034
  },
1021
- children: t === "queue" ? `Queue (${queue.length})` : t === "cache" ? `Cache (${resourceList.length})` : "Reliability"
1035
+ children: t === "queue" ? `Queue (${queue.length})` : t === "cache" ? `Cache (${resourceList.length})` : t === "reliability" ? "Reliability" : "SW"
1022
1036
  }, t))
1023
1037
  }),
1024
1038
  /* @__PURE__ */ jsx("div", {
@@ -1031,7 +1045,7 @@ function EidosDevtools({ position = "bottom-right", defaultOpen = false }) {
1031
1045
  queue,
1032
1046
  onReplay: handleReplay,
1033
1047
  onClear: handleClear
1034
- }) : tab === "cache" ? /* @__PURE__ */ jsx(CacheTab, { resources: resourceList }) : /* @__PURE__ */ jsx(ReliabilityTab, { stats: reliability })
1048
+ }) : tab === "cache" ? /* @__PURE__ */ jsx(CacheTab, { resources: resourceList }) : tab === "reliability" ? /* @__PURE__ */ jsx(ReliabilityTab, { stats: reliability }) : /* @__PURE__ */ jsx(SwTab, { resources: resourceList })
1035
1049
  })
1036
1050
  ]
1037
1051
  }), toggleBtn]
@@ -1384,5 +1398,171 @@ function ReliabilityTab({ stats }) {
1384
1398
  })
1385
1399
  ] });
1386
1400
  }
1401
+ function readSwSnapshot() {
1402
+ const reg = getSwRegistration();
1403
+ if (!reg) return {
1404
+ activeUrl: null,
1405
+ hasWaiting: false,
1406
+ hasInstalling: false
1407
+ };
1408
+ return {
1409
+ activeUrl: reg.active?.scriptURL ?? null,
1410
+ hasWaiting: reg.waiting !== null,
1411
+ hasInstalling: reg.installing !== null
1412
+ };
1413
+ }
1414
+ function SwTab({ resources }) {
1415
+ const [snap, setSnap] = useState(readSwSnapshot);
1416
+ useEffect(() => {
1417
+ const id = setInterval(() => setSnap(readSwSnapshot()), 1e3);
1418
+ return () => clearInterval(id);
1419
+ }, []);
1420
+ const buckets = resources.reduce((acc, res) => {
1421
+ const name = res.strategy.cacheName;
1422
+ acc[name] = (acc[name] ?? 0) + 1;
1423
+ return acc;
1424
+ }, {});
1425
+ const bucketList = Object.entries(buckets);
1426
+ const swState = snap.hasInstalling ? "installing" : snap.hasWaiting ? "waiting" : snap.activeUrl ? "active" : "none";
1427
+ const stateColor = swState === "active" ? C.green : swState === "waiting" || swState === "installing" ? C.yellow : C.muted;
1428
+ const shortUrl = snap.activeUrl ? snap.activeUrl.replace(/^https?:\/\/[^/]+/, "") || snap.activeUrl : null;
1429
+ return /* @__PURE__ */ jsxs("div", { children: [
1430
+ /* @__PURE__ */ jsxs("div", {
1431
+ style: {
1432
+ display: "flex",
1433
+ alignItems: "center",
1434
+ gap: 8,
1435
+ padding: "8px 12px",
1436
+ borderBottom: `1px solid ${C.border}`
1437
+ },
1438
+ children: [
1439
+ /* @__PURE__ */ jsx("span", {
1440
+ style: {
1441
+ color: C.muted,
1442
+ display: "inline-flex"
1443
+ },
1444
+ children: /* @__PURE__ */ jsx(Icon, {
1445
+ path: ICONS.shield,
1446
+ size: 12
1447
+ })
1448
+ }),
1449
+ /* @__PURE__ */ jsx("span", {
1450
+ style: pill(stateColor),
1451
+ children: swState
1452
+ }),
1453
+ shortUrl !== null ? /* @__PURE__ */ jsx("span", {
1454
+ title: snap.activeUrl ?? void 0,
1455
+ style: {
1456
+ flex: 1,
1457
+ color: C.muted,
1458
+ fontSize: 10,
1459
+ overflow: "hidden",
1460
+ textOverflow: "ellipsis",
1461
+ whiteSpace: "nowrap"
1462
+ },
1463
+ children: shortUrl
1464
+ }) : /* @__PURE__ */ jsx("span", {
1465
+ style: {
1466
+ flex: 1,
1467
+ color: C.muted,
1468
+ fontSize: 10
1469
+ },
1470
+ children: "No SW registered"
1471
+ }),
1472
+ /* @__PURE__ */ jsx("button", {
1473
+ onClick: () => setSnap(readSwSnapshot()),
1474
+ title: "Refresh SW state",
1475
+ "aria-label": "Refresh SW state",
1476
+ ...withFocusRing(),
1477
+ style: {
1478
+ ...btn("ghost"),
1479
+ padding: "2px 6px",
1480
+ minHeight: 20
1481
+ },
1482
+ children: /* @__PURE__ */ jsx(Icon, {
1483
+ path: ICONS.refreshCw,
1484
+ size: 10
1485
+ })
1486
+ })
1487
+ ]
1488
+ }),
1489
+ snap.hasWaiting ? /* @__PURE__ */ jsxs("div", {
1490
+ style: {
1491
+ display: "flex",
1492
+ alignItems: "center",
1493
+ gap: 8,
1494
+ padding: "8px 12px",
1495
+ borderBottom: `1px solid ${C.border}`,
1496
+ background: `${C.yellow}11`
1497
+ },
1498
+ children: [/* @__PURE__ */ jsx("span", {
1499
+ style: {
1500
+ color: C.yellow,
1501
+ fontSize: 10,
1502
+ flex: 1
1503
+ },
1504
+ children: "Update ready — new SW is waiting to activate."
1505
+ }), /* @__PURE__ */ jsx("button", {
1506
+ onClick: triggerSwUpdate,
1507
+ title: "Activate the waiting SW now",
1508
+ ...withFocusRing(),
1509
+ style: {
1510
+ ...btn("primary"),
1511
+ minHeight: 22,
1512
+ fontSize: 10
1513
+ },
1514
+ children: "Force update"
1515
+ })]
1516
+ }) : null,
1517
+ /* @__PURE__ */ jsxs("div", {
1518
+ style: {
1519
+ padding: "6px 12px",
1520
+ color: C.muted,
1521
+ fontSize: 10,
1522
+ borderBottom: `1px solid ${C.border}`
1523
+ },
1524
+ children: [
1525
+ "Cache buckets (",
1526
+ bucketList.length,
1527
+ ")"
1528
+ ]
1529
+ }),
1530
+ bucketList.length === 0 ? /* @__PURE__ */ jsx("div", {
1531
+ style: {
1532
+ padding: "16px 12px",
1533
+ textAlign: "center",
1534
+ color: C.muted,
1535
+ fontSize: 10
1536
+ },
1537
+ children: "No resources registered"
1538
+ }) : bucketList.map(([name, count]) => /* @__PURE__ */ jsxs("div", {
1539
+ style: {
1540
+ display: "flex",
1541
+ alignItems: "center",
1542
+ justifyContent: "space-between",
1543
+ padding: "7px 12px",
1544
+ borderBottom: `1px solid ${C.border}`
1545
+ },
1546
+ children: [/* @__PURE__ */ jsx("span", {
1547
+ style: {
1548
+ color: C.text,
1549
+ fontSize: 10,
1550
+ overflow: "hidden",
1551
+ textOverflow: "ellipsis",
1552
+ whiteSpace: "nowrap",
1553
+ flex: 1
1554
+ },
1555
+ children: name
1556
+ }), /* @__PURE__ */ jsxs("span", {
1557
+ style: pill(C.blue),
1558
+ children: [
1559
+ count,
1560
+ " resource",
1561
+ count !== 1 ? "s" : ""
1562
+ ]
1563
+ })]
1564
+ }, name))
1565
+ ] });
1566
+ }
1387
1567
  //#endregion
1388
1568
  export { EidosDevtools };
package/dist/eidos-sw.js CHANGED
@@ -1,4 +1,4 @@
1
- //#region ../core/src/internal/url-base64.ts
1
+ //#region src/internal/url-base64.ts
2
2
  /** Decodes a base64url string (e.g. a VAPID public key) into raw bytes. */
3
3
  function urlBase64ToUint8Array(base64Url) {
4
4
  const base64 = (base64Url + "=".repeat((4 - base64Url.length % 4) % 4)).replace(/-/g, "+").replace(/_/g, "/");
@@ -13,9 +13,7 @@ var runtimeConfig = {
13
13
  resources: /* @__PURE__ */ new Map(),
14
14
  simulateOffline: false
15
15
  };
16
- self.addEventListener("install", (event) => {
17
- event.waitUntil(self.skipWaiting());
18
- });
16
+ self.addEventListener("install", () => {});
19
17
  self.addEventListener("activate", (event) => {
20
18
  event.waitUntil(Promise.all([self.clients.claim(), caches.keys().then((keys) => Promise.all(keys.filter((k) => k.startsWith(CACHE_PREFIX) && !k.endsWith(CACHE_VERSION)).map((k) => caches.delete(k))))]));
21
19
  });
@@ -29,7 +27,10 @@ self.addEventListener("message", (event) => {
29
27
  runtimeConfig.resources.set(url, {
30
28
  strategy: data.strategy,
31
29
  cacheName: data.cacheName ?? `${CACHE_PREFIX}-resources-${CACHE_VERSION}`,
32
- ...patternSrc !== void 0 && { pattern: new RegExp(patternSrc) }
30
+ ...patternSrc !== void 0 && { pattern: new RegExp(patternSrc) },
31
+ ...data.maxAge !== void 0 && { maxAge: data.maxAge },
32
+ ...data.maxEntries !== void 0 && { maxEntries: data.maxEntries },
33
+ ...data.networkTimeoutMs !== void 0 && { networkTimeoutMs: data.networkTimeoutMs }
33
34
  });
34
35
  event.source?.postMessage({
35
36
  type: "EIDOS_RESOURCE_REGISTERED",
@@ -65,6 +66,9 @@ self.addEventListener("message", (event) => {
65
66
  });
66
67
  break;
67
68
  }
69
+ case "EIDOS_SKIP_WAITING":
70
+ self.skipWaiting();
71
+ break;
68
72
  case "EIDOS_PING":
69
73
  event.source?.postMessage({ type: "EIDOS_PONG" });
70
74
  break;
@@ -88,7 +92,7 @@ self.addEventListener("fetch", (event) => {
88
92
  }
89
93
  if (!reg) return;
90
94
  if (reg.strategy === "stale-while-revalidate" && !runtimeConfig.simulateOffline) {
91
- event.respondWith(staleWhileRevalidate(event, event.request, pathname, reg.cacheName));
95
+ event.respondWith(staleWhileRevalidate(event, event.request, pathname, reg));
92
96
  return;
93
97
  }
94
98
  event.respondWith(handleFetch(event.request, pathname, reg));
@@ -96,16 +100,45 @@ self.addEventListener("fetch", (event) => {
96
100
  async function handleFetch(request, pathname, reg) {
97
101
  if (runtimeConfig.simulateOffline) return serveOffline(request, pathname, reg.cacheName);
98
102
  switch (reg.strategy) {
99
- case "cache-first": return cacheFirst(request, pathname, reg.cacheName);
100
- case "stale-while-revalidate": return staleWhileRevalidate(null, request, pathname, reg.cacheName);
101
- case "network-first": return networkFirst(request, pathname, reg.cacheName);
103
+ case "cache-first": return cacheFirst(request, pathname, reg);
104
+ case "stale-while-revalidate": return staleWhileRevalidate(null, request, pathname, reg);
105
+ case "network-first": return networkFirst(request, pathname, reg);
102
106
  default: return fetch(request);
103
107
  }
104
108
  }
105
- async function cacheFirst(request, pathname, cacheName) {
109
+ var CACHED_AT_HEADER = "X-Eidos-Cached-At";
110
+ /**
111
+ * Puts a response into cache with a `X-Eidos-Cached-At` timestamp header so
112
+ * the SW can enforce `maxAge` on subsequent cache hits.
113
+ * Caller must pass a clone of the response — `response.body` is consumed here.
114
+ */
115
+ async function putCached(cache, request, response) {
116
+ const headers = new Headers(response.headers);
117
+ headers.set(CACHED_AT_HEADER, String(Date.now()));
118
+ await cache.put(request, new Response(response.body, {
119
+ status: response.status,
120
+ statusText: response.statusText,
121
+ headers
122
+ }));
123
+ }
124
+ /** Returns true if the cached response has exceeded `maxAge`. */
125
+ function isExpired(cached, maxAge) {
126
+ if (maxAge === void 0) return false;
127
+ const cachedAt = Number(cached.headers.get(CACHED_AT_HEADER) ?? "0");
128
+ return cachedAt > 0 && Date.now() - cachedAt > maxAge;
129
+ }
130
+ /** Evicts the oldest (first-inserted) entries when the cache exceeds `maxEntries`. */
131
+ async function evictIfNeeded(cache, maxEntries) {
132
+ if (maxEntries === void 0) return;
133
+ const keys = await cache.keys();
134
+ const overflow = keys.length - maxEntries;
135
+ if (overflow > 0) await Promise.all(keys.slice(0, overflow).map((k) => cache.delete(k)));
136
+ }
137
+ async function cacheFirst(request, pathname, reg) {
138
+ const { cacheName, maxAge, maxEntries } = reg;
106
139
  const cache = await caches.open(cacheName);
107
140
  const cached = await cache.match(request);
108
- if (cached) {
141
+ if (cached && !isExpired(cached, maxAge)) {
109
142
  notifyClients({
110
143
  type: "EIDOS_CACHE_HIT",
111
144
  url: pathname,
@@ -113,10 +146,12 @@ async function cacheFirst(request, pathname, cacheName) {
113
146
  });
114
147
  return cached;
115
148
  }
149
+ if (cached) await cache.delete(request);
116
150
  try {
117
151
  const response = await fetch(request);
118
152
  if (response.ok) {
119
- await cache.put(request, response.clone());
153
+ await putCached(cache, request, response.clone());
154
+ await evictIfNeeded(cache, maxEntries);
120
155
  notifyClients({
121
156
  type: "EIDOS_CACHE_UPDATED",
122
157
  url: pathname,
@@ -132,12 +167,17 @@ async function cacheFirst(request, pathname, cacheName) {
132
167
  return offlineErrorResponse(pathname);
133
168
  }
134
169
  }
135
- async function staleWhileRevalidate(event, request, pathname, cacheName) {
170
+ async function staleWhileRevalidate(event, request, pathname, reg) {
171
+ const { cacheName, maxAge, maxEntries } = reg;
136
172
  const cache = await caches.open(cacheName);
137
173
  const cached = await cache.match(request);
174
+ const expired = cached ? isExpired(cached, maxAge) : false;
175
+ if (expired) await cache.delete(request);
176
+ const effectiveCached = expired ? null : cached;
138
177
  const revalidatePromise = fetch(request).then(async (response) => {
139
178
  if (response.ok) {
140
- await cache.put(request, response.clone());
179
+ await putCached(cache, request, response.clone());
180
+ await evictIfNeeded(cache, maxEntries);
141
181
  notifyClients({
142
182
  type: "EIDOS_CACHE_UPDATED",
143
183
  url: pathname,
@@ -152,23 +192,25 @@ async function staleWhileRevalidate(event, request, pathname, cacheName) {
152
192
  strategy: "stale-while-revalidate"
153
193
  });
154
194
  });
155
- if (cached) {
195
+ if (effectiveCached) {
156
196
  event?.waitUntil(revalidatePromise);
157
197
  notifyClients({
158
198
  type: "EIDOS_CACHE_HIT",
159
199
  url: pathname,
160
200
  strategy: "stale-while-revalidate"
161
201
  });
162
- return cached;
202
+ return effectiveCached;
163
203
  }
164
204
  return await revalidatePromise ?? offlineErrorResponse(pathname);
165
205
  }
166
- async function networkFirst(request, pathname, cacheName) {
206
+ async function networkFirst(request, pathname, reg) {
207
+ const { cacheName, maxAge, maxEntries, networkTimeoutMs = 3e3 } = reg;
167
208
  const cache = await caches.open(cacheName);
168
209
  try {
169
- const response = await fetch(request, { signal: AbortSignal.timeout(3e3) });
210
+ const response = await fetch(request, { signal: AbortSignal.timeout(networkTimeoutMs) });
170
211
  if (response.ok) {
171
- await cache.put(request, response.clone());
212
+ await putCached(cache, request, response.clone());
213
+ await evictIfNeeded(cache, maxEntries);
172
214
  notifyClients({
173
215
  type: "EIDOS_CACHE_UPDATED",
174
216
  url: pathname,
@@ -178,7 +220,7 @@ async function networkFirst(request, pathname, cacheName) {
178
220
  return response;
179
221
  } catch {
180
222
  const cached = await cache.match(request);
181
- if (cached) {
223
+ if (cached && !isExpired(cached, maxAge)) {
182
224
  notifyClients({
183
225
  type: "EIDOS_CACHE_HIT",
184
226
  url: pathname,
package/dist/eidos.cjs CHANGED
@@ -1,15 +1,15 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let R=require("react"),F=require("react/jsx-runtime");function J(){return{queued:0,succeeded:0,failed:0,retried:0,conflicted:0,cancelled:0}}function X(e){let t=0,n=0,r=0;for(const a of e)a.status==="pending"?t++:a.status==="failed"?n++:a.status==="replaying"&&r++;return{pending:t,failed:n,replaying:r,total:e.length}}function we(e){return{registerResource:(t,n)=>e(r=>({resources:{...r.resources,[t]:n}})),updateResource:(t,n)=>e(r=>({resources:{...r.resources,[t]:r.resources[t]?{...r.resources[t],...n}:r.resources[t]}})),unregisterResource:t=>e(n=>({resources:Object.fromEntries(Object.entries(n.resources).filter(([r])=>r!==t))}))}}function ve(e){return{addQueueItem:t=>e(n=>({queue:[...n.queue,t]})),updateQueueItem:(t,n)=>e(r=>({queue:r.queue.map(a=>a.id===t?{...a,...n}:a)})),batchUpdateQueueItems:t=>e(n=>{const r=new Map(t.map(a=>[a.id,a.update]));return{queue:n.queue.map(a=>{const s=r.get(a.id);return s?{...a,...s}:a})}}),removeQueueItem:t=>e(n=>({queue:n.queue.filter(r=>r.id!==t)})),hydrateQueue:t=>e(()=>({queue:t}))}}function me(e){return{recordReliabilityEvent:t=>e(n=>({reliability:{...n.reliability,[t]:n.reliability[t]+1}})),resetReliabilityStats:()=>e(()=>({reliability:J()}))}}var g,T=new Set;function z(){T.forEach(e=>e())}function E(e){g={...g,...e(g)},z()}g={isOnline:typeof navigator>"u"||navigator.onLine!==!1,swStatus:"idle",swError:void 0,resources:{},queue:[],reliability:J(),setOnline:e=>E(()=>({isOnline:e})),setSwStatus:(e,t)=>E(()=>({swStatus:e,swError:t})),...we(E),...ve(E),...me(E)};function Se(){return g}function be(e){return T.add(e),()=>{T.delete(e)}}var o={getState:Se,subscribe:be,setState:e=>{const t=typeof e=="function"?e(g):e;g={...g,...t},z()}},v=null,M=[];function Z(){return v}async function Ee(e){if(typeof navigator>"u"||!("serviceWorker"in navigator)){o.getState().setSwStatus("unsupported");return}const t=o.getState();t.setSwStatus("registering");try{v=await navigator.serviceWorker.register(e,{scope:"/"}),await Re(v),t.setSwStatus("active"),navigator.serviceWorker.addEventListener("message",Oe),window.addEventListener("online",()=>t.setOnline(!0)),window.addEventListener("offline",()=>t.setOnline(!1)),qe()}catch(n){t.setSwStatus("error",String(n))}}function Re(e){return new Promise(t=>{if(e.active){t();return}const n=e.installing??e.waiting;if(!n){t();return}const r=setTimeout(t,1e4);n.addEventListener("statechange",function a(){n.state==="activated"&&(clearTimeout(r),n.removeEventListener("statechange",a),t())})})}function _(e){const t=v?.active;t?t.postMessage(e):M.push(e)}var ee=null;function Ie(e){ee=e}function _e(){try{return typeof navigator<"u"&&"serviceWorker"in navigator&&v!==null&&"sync"in v}catch{return!1}}var j={};function ke(e){j=e}function Oe(e){const t=e.data;if(!t?.type)return;const n=o.getState(),{type:r,url:a}=t;if(r==="EIDOS_BACKGROUND_SYNC"){ee?.();return}if(r==="EIDOS_NOTIFICATION_CLICK"){j.onNotificationClick?.(t.data);return}if(r==="EIDOS_SUBSCRIPTION_EXPIRED"){j.onSubscriptionExpired?.(t.subscription);return}if(a)switch(r){case"EIDOS_CACHE_HIT":{const s=n.resources[a];n.updateResource(a,{status:"fresh",lastEvent:"cache-hit",cacheHits:(s?.cacheHits??0)+1});break}case"EIDOS_CACHE_UPDATED":n.updateResource(a,{status:"fresh",lastEvent:"cache-updated",cachedAt:Date.now()});break;case"EIDOS_NETWORK_ERROR":n.updateResource(a,{status:"error",lastEvent:"network-error"});break}}function Ae(e){_({type:"EIDOS_SIMULATE_OFFLINE",enabled:e}),o.getState().setOnline(!e)}function qe(){const e=v?.active;if(e){for(const t of M)e.postMessage(t);M=[]}}var w=new Map,x=new Map,te=null;function Qe(e){te=e}function C(e){return e.includes("*")||/:[^/]+/.test(e)}function Ce(e){return"^"+e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,".+").replace(/\*/g,"[^/]+").replace(/:[^/]+/g,"[^/]+")+"$"}function ne(e,t){const n=Ne(t),r=C(e)?Ce(e):void 0,a={url:e,config:t,strategy:n,status:"idle",cacheHits:0,cacheMisses:0};return o.getState().registerResource(e,a),_({type:"EIDOS_REGISTER_RESOURCE",url:e,strategy:n.swStrategy,cacheName:n.cacheName,...r!==void 0&&{pattern:r}}),{strategy:n,regexStr:r}}function re(e,t,n){return async()=>{_({type:"EIDOS_CLEAR_CACHE",url:e});const r=await caches.open(t.cacheName).catch(()=>null);if(r){const a=await r.keys(),s=n?new RegExp(n):null,i=e.startsWith("http");await Promise.all(a.filter(c=>{const u=c.url,f=new URL(u).pathname;return s?s.test(i?u:f):i?u===e:u===e||f===e}).map(c=>r.delete(c)))}C(e)||o.getState().updateResource(e,{status:"stale",cachedAt:void 0,lastEvent:"cache-cleared",cacheHits:0,cacheMisses:0}),te?.(["eidos",e])}}function ae(e){return()=>{w.delete(e),_({type:"EIDOS_UNREGISTER_RESOURCE",url:e}),o.getState().unregisterResource(e)}}function xe(e,t){if(C(e))throw new Error(`[eidos] resource('${e}') is a URL pattern — use resourcePattern('${e}', config) instead. Pattern handles only support invalidate()/unregister(); the SW intercepts matching requests automatically.`);if(w.has(e))return w.get(e);const{strategy:n}=ne(e,t),r={url:e,config:t,strategy:n,fetch:async()=>{const a=x.get(e);if(a)return a.then(i=>i.clone());const s=De(e,t,n);return x.set(e,s),s.finally(()=>x.delete(e)).catch(()=>{}),s.then(i=>i.clone())},json:async()=>(await r.fetch()).json(),query:()=>({queryKey:["eidos",e],queryFn:()=>r.json()}),prefetch:async()=>{await r.fetch()},invalidate:re(e,n,void 0),unregister:ae(e)};return w.set(e,r),r}function Pe(e,t){if(!C(e))throw new Error(`[eidos] resourcePattern('${e}') is not a URL pattern — use resource('${e}', config) instead.`);if(w.has(e))return w.get(e);const{strategy:n,regexStr:r}=ne(e,t),a={url:e,config:t,strategy:n,invalidate:re(e,n,r),unregister:ae(e)};return w.set(e,a),a}async function De(e,t,n){const r=o.getState();r.updateResource(e,{status:"fetching",fetchedAt:Date.now()});const a=await caches.open(n.cacheName).catch(()=>null);try{if(n.swStrategy!=="network-first"){const c=a?await a.match(e).catch(()=>null):null,u=o.getState().resources[e],f=t.maxAge!==void 0&&u?.cachedAt!==void 0&&Date.now()-u.cachedAt>t.maxAge;if(c&&!f)return r.updateResource(e,{status:"fresh",lastEvent:"cache-hit",cacheHits:(u?.cacheHits??0)+1}),n.swStrategy==="stale-while-revalidate"&&fetch(e,{signal:AbortSignal.timeout(5e3)}).then(async S=>{S.ok&&a&&(await a.put(e,S.clone()),o.getState().updateResource(e,{cachedAt:Date.now(),lastEvent:"cache-updated"}))}).catch(()=>{}),c;const p=o.getState().resources[e];r.updateResource(e,{cacheMisses:(p?.cacheMisses??0)+1})}const s=await fetch(e);if(s.ok)return a&&await a.put(e,s.clone()),r.updateResource(e,{status:"fresh",cachedAt:Date.now(),lastEvent:"cache-updated"}),s;r.updateResource(e,{status:s.status===503?"offline":"error"});const i=s.headers.get("X-Eidos-Offline")==="true";throw new Error(i?`offline: no cached response for ${e}`:`${s.status} ${s.statusText}`)}catch(s){const i=a?await a.match(e).catch(()=>null):null;if(i){const c=o.getState().resources[e];return r.updateResource(e,{status:"fresh",lastEvent:"cache-hit",cacheHits:(c?.cacheHits??0)+1}),i}throw r.updateResource(e,{status:"error"}),s}}function Ne(e){const t=e.strategy;return e.offline?V(t??"stale-while-revalidate",e.cacheName,e.version):V(t??"network-first",e.cacheName,e.version)}var Te={"stale-while-revalidate":"StaleWhileRevalidate","cache-first":"CacheFirst","network-first":"NetworkFirst"},Me={"stale-while-revalidate":{reasoning:"offline: true signals resilience. SWR returns cached data instantly while revalidating in the background — the best tradeoff between speed and freshness for offline-capable resources.",behavior:["Cache hit → return immediately, kick off background revalidation","Cache miss → fetch from network, cache the response, return it","Offline → return cached version if available, 503 if not","Reconnect → next request triggers a background refresh"],equivalentCode:`// Workbox equivalent
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let R=require("react"),V=require("react/jsx-runtime");function X(){return{queued:0,succeeded:0,failed:0,retried:0,conflicted:0,cancelled:0}}function z(e){let t=0,n=0,r=0;for(const a of e)a.status==="pending"?t++:a.status==="failed"?n++:a.status==="replaying"&&r++;return{pending:t,failed:n,replaying:r,total:e.length}}function ve(e){return{registerResource:(t,n)=>e(r=>({resources:{...r.resources,[t]:n}})),updateResource:(t,n)=>e(r=>({resources:{...r.resources,[t]:r.resources[t]?{...r.resources[t],...n}:r.resources[t]}})),unregisterResource:t=>e(n=>({resources:Object.fromEntries(Object.entries(n.resources).filter(([r])=>r!==t))}))}}function me(e){return{addQueueItem:t=>e(n=>({queue:[...n.queue,t]})),updateQueueItem:(t,n)=>e(r=>({queue:r.queue.map(a=>a.id===t?{...a,...n}:a)})),batchUpdateQueueItems:t=>e(n=>{const r=new Map(t.map(a=>[a.id,a.update]));return{queue:n.queue.map(a=>{const s=r.get(a.id);return s?{...a,...s}:a})}}),removeQueueItem:t=>e(n=>({queue:n.queue.filter(r=>r.id!==t)})),hydrateQueue:t=>e(()=>({queue:t}))}}function Se(e){return{recordReliabilityEvent:t=>e(n=>({reliability:{...n.reliability,[t]:n.reliability[t]+1}})),resetReliabilityStats:()=>e(()=>({reliability:X()}))}}var w,M=new Set;function Z(){M.forEach(e=>e())}function E(e){w={...w,...e(w)},Z()}w={isOnline:typeof navigator>"u"||navigator.onLine!==!1,swStatus:"idle",swError:void 0,resources:{},queue:[],reliability:X(),setOnline:e=>E(()=>({isOnline:e})),setSwStatus:(e,t)=>E(()=>({swStatus:e,swError:t})),...ve(E),...me(E),...Se(E)};function be(){return w}function Ee(e){return M.add(e),()=>{M.delete(e)}}var o={getState:be,subscribe:Ee,setState:e=>{const t=typeof e=="function"?e(w):e;w={...w,...t},Z()}},h=null,T=[];function H(){return h}async function Re(e,t={skipWaiting:!0}){if(typeof navigator>"u"||!("serviceWorker"in navigator)){o.getState().setSwStatus("unsupported");return}const n=o.getState();n.setSwStatus("registering");try{h=await navigator.serviceWorker.register(e,{scope:"/"}),await Ae(h),n.setSwStatus("active"),navigator.serviceWorker.addEventListener("message",Oe),window.addEventListener("online",()=>n.setOnline(!0)),window.addEventListener("offline",()=>n.setOnline(!1)),qe(),Ce(h,t)}catch(r){n.setSwStatus("error",String(r))}}function Ae(e){return new Promise(t=>{if(e.active){t();return}const n=e.installing??e.waiting;if(!n){t();return}const r=setTimeout(t,1e4);n.addEventListener("statechange",function a(){n.state==="activated"&&(clearTimeout(r),n.removeEventListener("statechange",a),t())})})}function I(e){const t=h?.active;t?t.postMessage(e):T.push(e)}var ee=null;function Ie(e){ee=e}function ke(){try{return typeof navigator<"u"&&"serviceWorker"in navigator&&h!==null&&"sync"in h}catch{return!1}}var U={};function _e(e){U=e}function Oe(e){const t=e.data;if(!t?.type)return;const n=o.getState(),{type:r,url:a}=t;if(r==="EIDOS_BACKGROUND_SYNC"){ee?.();return}if(r==="EIDOS_NOTIFICATION_CLICK"){U.onNotificationClick?.(t.data);return}if(r==="EIDOS_SUBSCRIPTION_EXPIRED"){U.onSubscriptionExpired?.(t.subscription);return}if(a)switch(r){case"EIDOS_CACHE_HIT":{const s=n.resources[a];n.updateResource(a,{status:"fresh",lastEvent:"cache-hit",cacheHits:(s?.cacheHits??0)+1});break}case"EIDOS_CACHE_UPDATED":n.updateResource(a,{status:"fresh",lastEvent:"cache-updated",cachedAt:Date.now()});break;case"EIDOS_NETWORK_ERROR":n.updateResource(a,{status:"error",lastEvent:"network-error"});break}}function xe(e){I({type:"EIDOS_SIMULATE_OFFLINE",enabled:e}),o.getState().setOnline(!e)}function qe(){const e=h?.active;if(e){for(const t of T)e.postMessage(t);T=[]}}function Ce(e,t){const n=r=>{t.skipWaiting?r.waiting?.postMessage({type:"EIDOS_SKIP_WAITING"}):t.onUpdateAvailable?.(r)};e.waiting&&navigator.serviceWorker.controller&&n(e),e.addEventListener("updatefound",()=>{const r=e.installing;r&&r.addEventListener("statechange",()=>{r.state==="installed"&&navigator.serviceWorker.controller&&n(e)})})}function Qe(){h?.waiting?.postMessage({type:"EIDOS_SKIP_WAITING"})}var v=new Map,Q=new Map,te=null;function Pe(e){te=e}function C(e){return e.includes("*")||/:[^/]+/.test(e)}function De(e){return"^"+e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,".+").replace(/\*/g,"[^/]+").replace(/:[^/]+/g,"[^/]+")+"$"}function ne(e,t){const n=Ue(t),r=C(e)?De(e):void 0,a={url:e,config:t,strategy:n,status:"idle",cacheHits:0,cacheMisses:0};return o.getState().registerResource(e,a),I({type:"EIDOS_REGISTER_RESOURCE",url:e,strategy:n.swStrategy,cacheName:n.cacheName,...r!==void 0&&{pattern:r},...t.maxAge!==void 0&&{maxAge:t.maxAge},...t.maxEntries!==void 0&&{maxEntries:t.maxEntries},...t.networkTimeoutMs!==void 0&&{networkTimeoutMs:t.networkTimeoutMs}}),{strategy:n,regexStr:r}}function re(e,t,n){return async()=>{I({type:"EIDOS_CLEAR_CACHE",url:e});const r=await caches.open(t.cacheName).catch(()=>null);if(r){const a=await r.keys(),s=n?new RegExp(n):null,i=e.startsWith("http");await Promise.all(a.filter(c=>{const u=c.url,f=new URL(u).pathname;return s?s.test(i?u:f):i?u===e:u===e||f===e}).map(c=>r.delete(c)))}C(e)||o.getState().updateResource(e,{status:"stale",cachedAt:void 0,lastEvent:"cache-cleared",cacheHits:0,cacheMisses:0}),te?.(["eidos",e])}}function ae(e){return()=>{v.delete(e),I({type:"EIDOS_UNREGISTER_RESOURCE",url:e}),o.getState().unregisterResource(e)}}function Ne(e,t){if(C(e))throw new Error(`[eidos] resource('${e}') is a URL pattern — use resourcePattern('${e}', config) instead. Pattern handles only support invalidate()/unregister(); the SW intercepts matching requests automatically.`);if(v.has(e))return v.get(e);const{strategy:n}=ne(e,t),r={url:e,config:t,strategy:n,fetch:async()=>{const a=Q.get(e);if(a)return a.then(i=>i.clone());const s=Te(e,t,n);return Q.set(e,s),s.finally(()=>Q.delete(e)).catch(()=>{}),s.then(i=>i.clone())},json:async()=>(await r.fetch()).json(),query:()=>({queryKey:["eidos",e],queryFn:()=>r.json()}),prefetch:async()=>{await r.fetch()},invalidate:re(e,n,void 0),unregister:ae(e)};return v.set(e,r),r}function Me(e,t){if(!C(e))throw new Error(`[eidos] resourcePattern('${e}') is not a URL pattern — use resource('${e}', config) instead.`);if(v.has(e))return v.get(e);const{strategy:n,regexStr:r}=ne(e,t),a={url:e,config:t,strategy:n,invalidate:re(e,n,r),unregister:ae(e)};return v.set(e,a),a}async function Te(e,t,n){const r=o.getState();r.updateResource(e,{status:"fetching",fetchedAt:Date.now()});const a=await caches.open(n.cacheName).catch(()=>null);try{if(n.swStrategy!=="network-first"){const c=a?await a.match(e).catch(()=>null):null,u=o.getState().resources[e],f=t.maxAge!==void 0&&u?.cachedAt!==void 0&&Date.now()-u.cachedAt>t.maxAge;if(c&&!f)return r.updateResource(e,{status:"fresh",lastEvent:"cache-hit",cacheHits:(u?.cacheHits??0)+1}),n.swStrategy==="stale-while-revalidate"&&fetch(e,{signal:AbortSignal.timeout(t.networkTimeoutMs??3e3)}).then(async S=>{S.ok&&a&&(await a.put(e,S.clone()),o.getState().updateResource(e,{cachedAt:Date.now(),lastEvent:"cache-updated"}))}).catch(()=>{}),c;const p=o.getState().resources[e];r.updateResource(e,{cacheMisses:(p?.cacheMisses??0)+1})}const s=await fetch(e);if(s.ok)return a&&await a.put(e,s.clone()),r.updateResource(e,{status:"fresh",cachedAt:Date.now(),lastEvent:"cache-updated"}),s;r.updateResource(e,{status:s.status===503?"offline":"error"});const i=s.headers.get("X-Eidos-Offline")==="true";throw new Error(i?`offline: no cached response for ${e}`:`${s.status} ${s.statusText}`)}catch(s){const i=a?await a.match(e).catch(()=>null):null;if(i){const c=o.getState().resources[e];return r.updateResource(e,{status:"fresh",lastEvent:"cache-hit",cacheHits:(c?.cacheHits??0)+1}),i}throw r.updateResource(e,{status:"error"}),s}}function Ue(e){const t=e.strategy;return e.offline?G(t??"stale-while-revalidate",e.cacheName,e.version):G(t??"network-first",e.cacheName,e.version)}var je={"stale-while-revalidate":"StaleWhileRevalidate","cache-first":"CacheFirst","network-first":"NetworkFirst"},Ke={"stale-while-revalidate":{reasoning:"offline: true signals resilience. SWR returns cached data instantly while revalidating in the background — the best tradeoff between speed and freshness for offline-capable resources.",behavior:["Cache hit → return immediately, kick off background revalidation","Cache miss → fetch from network, cache the response, return it","Offline → return cached version if available, 503 if not","Reconnect → next request triggers a background refresh"],equivalentCode:`// Workbox equivalent (maxEntries/maxAge are configured via ResourceConfig)
2
2
  new StaleWhileRevalidate({
3
3
  cacheName: 'eidos-resources-v1',
4
- plugins: [new ExpirationPlugin({ maxEntries: 60 })],
5
- })`},"cache-first":{reasoning:"cache-first maximises speed and offline availability. Network is consulted only on cache miss. Best for static or infrequently-updated data.",behavior:["Cache hit → return immediately, no network request made","Cache miss → fetch from network, cache the response, return it","Offline → return cached version, 503 if cache is empty","Cache never expires unless explicitly invalidated"],equivalentCode:`// Workbox equivalent
4
+ plugins: [new ExpirationPlugin({ maxEntries: config.maxEntries, maxAgeSeconds: config.maxAge && config.maxAge / 1000 })],
5
+ })`},"cache-first":{reasoning:"cache-first maximises speed and offline availability. Network is consulted only on cache miss. Best for static or infrequently-updated data.",behavior:["Cache hit → return immediately, no network request made","Cache miss → fetch from network, cache the response, return it","Offline → return cached version, 503 if cache is empty","Cache never expires unless maxAge is set or explicitly invalidated"],equivalentCode:`// Workbox equivalent (maxEntries/maxAge are configured via ResourceConfig)
6
6
  new CacheFirst({
7
7
  cacheName: 'eidos-resources-v1',
8
- plugins: [new ExpirationPlugin({ maxEntries: 60 })],
8
+ plugins: [new ExpirationPlugin({ maxEntries: config.maxEntries, maxAgeSeconds: config.maxAge && config.maxAge / 1000 })],
9
9
  })`},"network-first":{reasoning:"network-first prioritises fresh data. Cache acts as a safety net when offline. Best for frequently-updated resources where stale data causes problems.",behavior:["Always try network first","Network success → update cache, return fresh response","Network failure → fall back to cached version","Offline with empty cache → return 503 error response"],equivalentCode:`// Workbox equivalent
10
10
  new NetworkFirst({
11
11
  cacheName: 'eidos-resources-v1',
12
- networkTimeoutSeconds: 3,
13
- })`}};function V(e,t,n){const r=Me[e],a=t??"eidos-resources-v1";return{name:Te[e],swStrategy:e,cacheName:n!==void 0?`${a}-v${n}`:a,reasoning:r.reasoning,behavior:r.behavior,equivalentCode:""}}async function je(e){const t=await Promise.allSettled(e.map(r=>r.prefetch())),n=t.filter(r=>r.status==="rejected").map(r=>r.reason);return{warmed:t.filter(r=>r.status==="fulfilled").length,failed:n.length,errors:n}}var Ue="eidos",Ke=1,l="action-queue",P=null;function b(){return P?Promise.resolve(P):new Promise((e,t)=>{const n=indexedDB.open(Ue,Ke);n.onupgradeneeded=r=>{const a=r.target.result;if(!a.objectStoreNames.contains(l)){const s=a.createObjectStore(l,{keyPath:"id"});s.createIndex("status","status",{unique:!1}),s.createIndex("actionId","actionId",{unique:!1})}},n.onsuccess=()=>{P=n.result,e(n.result)},n.onerror=()=>t(n.error)})}async function $e(e){const t=await b();return new Promise((n,r)=>{const a=t.transaction(l,"readwrite");a.objectStore(l).add(e),a.oncomplete=()=>n(),a.onerror=()=>r(a.error)})}async function se(){const e=await b();return new Promise((t,n)=>{const r=e.transaction(l,"readonly").objectStore(l).getAll();r.onsuccess=()=>t(r.result),r.onerror=()=>n(r.error)})}async function Le(e,t){const n=await b();return new Promise((r,a)=>{const s=n.transaction(l,"readwrite"),i=s.objectStore(l),c=i.get(e);c.onsuccess=()=>{c.result&&i.put({...c.result,...t})},s.oncomplete=()=>r(),s.onerror=()=>a(s.error)})}async function We(e){const t=await b();return new Promise((n,r)=>{const a=t.transaction(l,"readwrite");a.objectStore(l).delete(e),a.oncomplete=()=>n(),a.onerror=()=>r(a.error)})}async function Be(){const e=await b();function t(a){return new Promise((s,i)=>{const c=e.transaction(l,"readonly").objectStore(l).index("status"),u=[],f=c.openCursor(IDBKeyRange.only(a));f.onsuccess=p=>{const S=p.target.result;S?(u.push(S.value),S.continue()):s(u)},f.onerror=()=>i(f.error)})}const[n,r]=await Promise.all([t("pending"),t("failed")]);return[...n,...r]}async function He(){const e=await b();return new Promise((t,n)=>{const r=e.transaction(l,"readwrite");r.objectStore(l).clear(),r.oncomplete=()=>t(),r.onerror=()=>n(r.error)})}var ie={add:$e,getAll:se,getPending:Be,update:Le,remove:We,clear:He},oe=null;function Fe(e){oe=e}function B(){return oe}var Ve="eidos-queue-sync",k;function ce(){return k!==void 0||(k=typeof BroadcastChannel>"u"?null:new BroadcastChannel(Ve)),k}function h(e){ce()?.postMessage(e)}function Ge(){const e=ce();if(!e)return()=>{};const t=n=>{const r=o.getState(),a=n.data;switch(a.type){case"update":r.updateQueueItem(a.id,a.update);break;case"batchUpdate":r.batchUpdateQueueItems(a.updates);break;case"remove":r.removeQueueItem(a.id);break}};return e.addEventListener("message",t),()=>e.removeEventListener("message",t)}var q=new Map,ue=new Map,de=new Map,le=new Map,I=new Map;function d(){return B()??ie}function U(){return crypto.randomUUID()}function K(e,t,n){return e(...t,n)}function Ye(e,t){const n=t.name||e.name||U(),r=t.namespace?`${t.namespace}::${n}`:n;if(q.has(r))throw new Error(`[eidos] duplicate action id "${r}" — an action with this id is already registered. Pass a unique config.name or config.namespace.`);q.set(r,e),le.set(r,t),t.onRollback&&ue.set(r,t.onRollback),t.conflict&&de.set(r,t.conflict);const a=async(...s)=>{const{isOnline:i}=o.getState(),c=U();let u;if(t.cancellable){const p=new AbortController;I.set(c,p),u=p.signal}const f={idempotencyKey:c,attempt:0,signal:u};t.onOptimistic?.(...s,f);try{if(t.reliability==="neverLose"){if(!i)return G(r,r,s,t,c);try{return await K(e,s,f)}catch(p){if(pe(p))throw p;return G(r,r,s,t,c)}}try{return await K(e,s,f)}catch(p){throw t.onRollback?.(...s,f),p}}finally{t.cancellable&&I.delete(c)}};return Object.defineProperty(a,"id",{value:r,writable:!1}),Object.defineProperty(a,"config",{value:t,writable:!1}),Object.defineProperty(a,"cancel",{value:fe,writable:!1}),a}async function fe(e){const t=I.get(e);if(t)return t.abort(),!0;const n=(await d().getAll()).find(r=>r.idempotencyKey===e&&r.status==="pending");return n?(o.getState().removeQueueItem(n.id),h({type:"remove",id:n.id}),await d().remove(n.id),!0):!1}async function Je(e){const t=(await d().getAll()).find(r=>r.id===e);if(!t||t.status!=="failed")return!1;const n={status:"pending",error:void 0,nextRetryAt:void 0,retryCount:0};return o.getState().updateQueueItem(e,n),h({type:"update",id:e,update:n}),await d().update(e,n),!0}async function G(e,t,n,r,a){const s=U(),i={schemaVersion:2,id:s,actionId:e,actionName:t,idempotencyKey:a,args:n,queuedAt:Date.now(),retryCount:0,maxRetries:r.maxRetries??3,status:"pending",priority:r.priority??"normal"};await d().add(i),o.getState().addQueueItem(i),o.getState().recordReliabilityEvent("queued");try{const c=Z();c&&"sync"in c&&await c.sync.register("eidos-queue-replay")}catch{}return{queued:!0,id:s,message:`"${t}" queued — will execute when online`}}function pe(e){return e instanceof DOMException&&e.name==="AbortError"}function Xe(e){if(e instanceof Response)return e.status>=400&&e.status<500;if(typeof e=="object"&&e!==null){const t=e.status;if(typeof t=="number")return t>=400&&t<500}return!1}function ze(e){return Math.min(2e3*2**e,3e5)*(.8+Math.random()*.4)}function O(){return{attempted:0,succeeded:0,failed:0,retrying:0,skipped:0,conflicted:0,cancelled:0}}var D=!1,Ze="eidos-queue-replay";async function Q(){const e=o.getState();if(!e.isOnline)return O();if(typeof navigator<"u"&&navigator.locks)return navigator.locks.request(Ze,{ifAvailable:!0},async t=>t?Y(e):O());if(D)return O();D=!0;try{return await Y(e)}finally{D=!1}}async function et(e,t){const n=Date.now();t.updateQueueItem(e.id,{status:"succeeded",completedAt:n}),t.recordReliabilityEvent("succeeded"),h({type:"update",id:e.id,update:{status:"succeeded",completedAt:n}}),await d().update(e.id,{status:"succeeded",completedAt:n}),setTimeout(()=>{t.removeQueueItem(e.id),h({type:"remove",id:e.id}),d().remove(e.id)},3e3)}async function tt(e,t,n){const r=de.get(e.actionId);let a;if(r)switch(r.strategy){case"serverWins":a="skip";break;case"clientWins":a="retry";break;case"merge":case"custom":{const s={error:n,args:e.args,attempt:e.retryCount,idempotencyKey:e.idempotencyKey};a=r.resolve?.(s)??"retry";break}}if(a==="skip")return t.removeQueueItem(e.id),t.recordReliabilityEvent("conflicted"),h({type:"remove",id:e.id}),await d().remove(e.id),"conflicted";a&&typeof a=="object"&&(e.args=a.resolved,t.updateQueueItem(e.id,{args:a.resolved}),h({type:"update",id:e.id,update:{args:a.resolved}}),await d().update(e.id,{args:a.resolved}))}async function nt(e,t,n){const r=e.retryCount+1;if(r>=e.maxRetries){const s={status:"failed",error:String(n),retryCount:r};t.updateQueueItem(e.id,s),t.recordReliabilityEvent("failed"),h({type:"update",id:e.id,update:s}),await d().update(e.id,s);const i={idempotencyKey:e.idempotencyKey,attempt:r};return ue.get(e.actionId)?.(...e.args,i),"failed"}const a={status:"pending",retryCount:r,nextRetryAt:Date.now()+ze(r)};return t.updateQueueItem(e.id,a),t.recordReliabilityEvent("retried"),h({type:"update",id:e.id,update:a}),await d().update(e.id,a),"retrying"}async function rt(e,t){const n=q.get(e.actionId);if(!n)return"skipped";const r=le.get(e.actionId)?.cancellable;let a;if(r){const i=new AbortController;I.set(e.idempotencyKey,i),a=i.signal}const s={idempotencyKey:e.idempotencyKey,attempt:e.retryCount,signal:a};try{return await K(n,e.args,s),await et(e,t),"succeeded"}catch(i){if(pe(i))return t.removeQueueItem(e.id),t.recordReliabilityEvent("cancelled"),h({type:"remove",id:e.id}),await d().remove(e.id),"cancelled";if(Xe(i)){const c=await tt(e,t,i);if(c)return c}return nt(e,t,i)}finally{r&&I.delete(e.idempotencyKey)}}async function at(e,t,n){if(e.length===0)return;const r=e.filter(s=>q.has(s.actionId));if(n.skipped+=e.length-r.length,r.length>0){const s=r.map(i=>({id:i.id,update:{status:"replaying"}}));t.batchUpdateQueueItems(s),h({type:"batchUpdate",updates:s});for(const i of r)d().update(i.id,{status:"replaying"})}const a=await Promise.allSettled(r.map(s=>rt(s,t)));for(const s of a){const i=s.status==="fulfilled"?s.value:"failed";i==="skipped"?n.skipped++:i==="conflicted"?n.conflicted++:i==="cancelled"?n.cancelled++:(n.attempted++,n[i]++)}}async function Y(e){const t=await d().getPending(),n=Date.now(),r=t.filter(s=>s.retryCount<s.maxRetries&&(!s.nextRetryAt||s.nextRetryAt<=n)),a=O();for(const s of["high","normal","low"])await at(r.filter(i=>(i.priority??"normal")===s),e,a);return a}async function st(){await d().clear(),o.getState().hydrateQueue([])}function ye(){let e=o.getState().isOnline;const t=o.subscribe(()=>{const{isOnline:a}=o.getState(),s=a&&!e;e=a,s&&setTimeout(Q,600)}),n=o.getState(),r=n.queue.some(a=>a.status==="pending");return n.isOnline&&r&&setTimeout(Q,1200),t}async function it(e){if(e.schemaVersion===2&&e.idempotencyKey)return e;const t={...e,schemaVersion:2,idempotencyKey:e.idempotencyKey??crypto.randomUUID()};return await(B()??ie).update(t.id,{schemaVersion:t.schemaVersion,idempotencyKey:t.idempotencyKey}).catch(()=>{}),t}var $=!1,L=null,W=null,A=null;async function he(e={}){if(typeof window>"u"||$)return;$=!0;const t=e.swPath??"/eidos-sw.js",n=e.autoReplay??!0;try{const r=await se();if(r.length>0){const a=await Promise.all(r.map(it));o.getState().hydrateQueue(a)}}catch{}try{await Ee(t)}catch{}if(Ie(()=>{o.getState().isOnline&&setTimeout(Q,200)}),n&&(L=ye()),W=Ge(),e.onReliabilityReport){const r=e.reliabilityReportInterval??6e4,a=e.onReliabilityReport;A=setInterval(()=>{a(o.getState().reliability)},r)}}function ot(){L?.(),L=null,W?.(),W=null,A&&clearInterval(A),A=null,$=!1}var N="@eidos:queue",ct=class{constructor(e){this.storage=e}async readAll(){try{const e=await this.storage.getItem(N);return e?JSON.parse(e):[]}catch{return[]}}async writeAll(e){await this.storage.setItem(N,JSON.stringify(e))}async add(e){const t=await this.readAll();t.push(e),await this.writeAll(t)}async getAll(){return this.readAll()}async getPending(){return(await this.readAll()).filter(e=>e.status==="pending"||e.status==="failed")}async update(e,t){const n=await this.readAll(),r=n.findIndex(a=>a.id===e);r!==-1&&(n[r]={...n[r],...t}),await this.writeAll(n)}async remove(e){const t=await this.readAll();await this.writeAll(t.filter(n=>n.id!==e))}async clear(){await this.storage.removeItem(N)}};function ut({children:e,swPath:t,autoReplay:n}){return(0,R.useEffect)(()=>{he({swPath:t,autoReplay:n})},[]),(0,F.jsx)(F.Fragment,{children:e})}function dt(e,t){const n=Object.keys(e);if(n.length!==Object.keys(t).length)return!1;for(const r of n)if(e[r]!==t[r])return!1;return!0}function H(e,t){return dt(e,t)}function m(e,t=Object.is){return{subscribe(n){let r=e(o.getState());return n(r),o.subscribe(()=>{const a=e(o.getState());t(r,a)||(r=a,n(a))})},getState(){return e(o.getState())}}}var lt=m(e=>e),ft=m(e=>e.queue),pt=m(e=>({isOnline:e.isOnline,swStatus:e.swStatus,swError:e.swError}),H),yt=m(e=>X(e.queue),H),ht=m(e=>e.reliability,H);function gt(e){return m(t=>t.resources[e])}function wt(e){return m(t=>t.queue.find(n=>n.id===e))}function ge(e){let t=o.getState().queue.length;return o.subscribe(()=>{const n=o.getState().queue.length;t>0&&n===0&&e(),t=n})}function y(e){const t=e??(n=>n);return(0,R.useSyncExternalStore)(o.subscribe,()=>t(o.getState()))}function vt(){return y()}function mt(){return y(e=>e.resources)}function St(e){return y(t=>t.resources[e])}function bt(){return y(e=>e.queue)}function Et(e){return y(t=>t.queue.find(n=>n.id===e))}function Rt(){return{isOnline:y(e=>e.isOnline),swStatus:y(e=>e.swStatus),swError:y(e=>e.swError)}}function It(){const[e,t,n,r]=y(a=>{const{pending:s,failed:i,replaying:c,total:u}=X(a.queue);return`${s},${i},${c},${u}`}).split(",");return{pending:+e,failed:+t,replaying:+n,total:+r}}function _t(){return y(e=>e.reliability)}function kt(e){const t=(0,R.useRef)(e);(0,R.useEffect)(()=>{t.current=e}),(0,R.useEffect)(()=>ge(()=>t.current()),[])}var Ot="2.2.0";exports.AsyncStorageQueueStorage=ct;exports.EidosProvider=ut;exports.VERSION=Ot;exports._getQueueStorage=B;exports._resetEidos=ot;exports.action=Ye;exports.cancelByIdempotencyKey=fe;exports.clearQueue=st;exports.eidosAction=wt;exports.eidosQueue=ft;exports.eidosQueueStats=yt;exports.eidosReliabilityStats=ht;exports.eidosResource=gt;exports.eidosStatus=pt;exports.eidosStore=lt;exports.getSwRegistration=Z;exports.initEidos=he;exports.isBgSyncSupported=_e;exports.onQueueDrain=ge;exports.registerPushCallbacks=ke;exports.replayQueue=Q;exports.requeueItem=Je;exports.resource=xe;exports.resourcePattern=Pe;exports.sendToWorker=_;exports.setOfflineSimulation=Ae;exports.setQueryInvalidator=Qe;exports.setQueueStorage=Fe;exports.subscribeReplayOnReconnect=ye;exports.useEidos=vt;exports.useEidosAction=Et;exports.useEidosOnDrain=kt;exports.useEidosQueue=bt;exports.useEidosQueueStats=It;exports.useEidosReliabilityStats=_t;exports.useEidosResource=St;exports.useEidosResources=mt;exports.useEidosStatus=Rt;exports.useEidosStore=o;exports.warmCache=je;
12
+ networkTimeoutSeconds: 3, // controlled via ResourceConfig.networkTimeoutMs (default 3000)
13
+ })`}};function G(e,t,n){const r=Ke[e],a=t??"eidos-resources-v1";return{name:je[e],swStrategy:e,cacheName:n!==void 0?`${a}-v${n}`:a,reasoning:r.reasoning,behavior:r.behavior,equivalentCode:""}}async function We(e){const t=await Promise.allSettled(e.map(r=>r.prefetch())),n=t.filter(r=>r.status==="rejected").map(r=>r.reason);return{warmed:t.filter(r=>r.status==="fulfilled").length,failed:n.length,errors:n}}var Le="eidos",$e=1,l="action-queue",P=null;function b(){return P?Promise.resolve(P):new Promise((e,t)=>{const n=indexedDB.open(Le,$e);n.onupgradeneeded=r=>{const a=r.target.result;if(!a.objectStoreNames.contains(l)){const s=a.createObjectStore(l,{keyPath:"id"});s.createIndex("status","status",{unique:!1}),s.createIndex("actionId","actionId",{unique:!1})}},n.onsuccess=()=>{P=n.result,e(n.result)},n.onerror=()=>t(n.error)})}async function He(e){const t=await b();return new Promise((n,r)=>{const a=t.transaction(l,"readwrite");a.objectStore(l).add(e),a.oncomplete=()=>n(),a.onerror=()=>r(a.error)})}async function se(){const e=await b();return new Promise((t,n)=>{const r=e.transaction(l,"readonly").objectStore(l).getAll();r.onsuccess=()=>t(r.result),r.onerror=()=>n(r.error)})}async function Be(e,t){const n=await b();return new Promise((r,a)=>{const s=n.transaction(l,"readwrite"),i=s.objectStore(l),c=i.get(e);c.onsuccess=()=>{c.result&&i.put({...c.result,...t})},s.oncomplete=()=>r(),s.onerror=()=>a(s.error)})}async function Fe(e){const t=await b();return new Promise((n,r)=>{const a=t.transaction(l,"readwrite");a.objectStore(l).delete(e),a.oncomplete=()=>n(),a.onerror=()=>r(a.error)})}async function Ve(){const e=await b();function t(a){return new Promise((s,i)=>{const c=e.transaction(l,"readonly").objectStore(l).index("status"),u=[],f=c.openCursor(IDBKeyRange.only(a));f.onsuccess=p=>{const S=p.target.result;S?(u.push(S.value),S.continue()):s(u)},f.onerror=()=>i(f.error)})}const[n,r]=await Promise.all([t("pending"),t("failed")]);return[...n,...r]}async function Ge(){const e=await b();return new Promise((t,n)=>{const r=e.transaction(l,"readwrite");r.objectStore(l).clear(),r.oncomplete=()=>t(),r.onerror=()=>n(r.error)})}var ie={add:He,getAll:se,getPending:Ve,update:Be,remove:Fe,clear:Ge},oe=null;function Ye(e){oe=e}function B(){return oe}var Je="eidos-queue-sync",k;function ce(){return k!==void 0||(k=typeof BroadcastChannel>"u"?null:new BroadcastChannel(Je)),k}function g(e){ce()?.postMessage(e)}function Xe(){const e=ce();if(!e)return()=>{};const t=n=>{const r=o.getState(),a=n.data;switch(a.type){case"update":r.updateQueueItem(a.id,a.update);break;case"batchUpdate":r.batchUpdateQueueItems(a.updates);break;case"remove":r.removeQueueItem(a.id);break}};return e.addEventListener("message",t),()=>e.removeEventListener("message",t)}var x=new Map,ue=new Map,de=new Map,le=new Map,A=new Map;function d(){return B()??ie}function j(){return crypto.randomUUID()}function K(e,t,n){return e(...t,n)}function ze(e,t){const n=t.name||e.name||j(),r=t.namespace?`${t.namespace}::${n}`:n;if(x.has(r))throw new Error(`[eidos] duplicate action id "${r}" — an action with this id is already registered. Pass a unique config.name or config.namespace.`);x.set(r,e),le.set(r,t),t.onRollback&&ue.set(r,t.onRollback),t.conflict&&de.set(r,t.conflict);const a=async(...s)=>{const{isOnline:i}=o.getState(),c=j();let u;if(t.cancellable){const p=new AbortController;A.set(c,p),u=p.signal}const f={idempotencyKey:c,attempt:0,signal:u};t.onOptimistic?.(...s,f);try{if(t.reliability==="neverLose"){if(!i)return Y(r,r,s,t,c);try{return await K(e,s,f)}catch(p){if(pe(p))throw p;return Y(r,r,s,t,c)}}try{return await K(e,s,f)}catch(p){throw t.onRollback?.(...s,f),p}}finally{t.cancellable&&A.delete(c)}};return Object.defineProperty(a,"id",{value:r,writable:!1}),Object.defineProperty(a,"config",{value:t,writable:!1}),Object.defineProperty(a,"cancel",{value:fe,writable:!1}),a}async function fe(e){const t=A.get(e);if(t)return t.abort(),!0;const n=(await d().getAll()).find(r=>r.idempotencyKey===e&&r.status==="pending");return n?(o.getState().removeQueueItem(n.id),g({type:"remove",id:n.id}),await d().remove(n.id),!0):!1}async function Ze(e){const t=(await d().getAll()).find(r=>r.id===e);if(!t||t.status!=="failed")return!1;const n={status:"pending",error:void 0,nextRetryAt:void 0,retryCount:0};return o.getState().updateQueueItem(e,n),g({type:"update",id:e,update:n}),await d().update(e,n),!0}async function Y(e,t,n,r,a){const s=j(),i={schemaVersion:2,id:s,actionId:e,actionName:t,idempotencyKey:a,args:n,queuedAt:Date.now(),retryCount:0,maxRetries:r.maxRetries??3,status:"pending",priority:r.priority??"normal"};await d().add(i),o.getState().addQueueItem(i),o.getState().recordReliabilityEvent("queued");try{const c=H();c&&"sync"in c&&await c.sync.register("eidos-queue-replay")}catch{}return{queued:!0,id:s,message:`"${t}" queued — will execute when online`}}function pe(e){return e instanceof DOMException&&e.name==="AbortError"}function et(e){if(e instanceof Response)return e.status>=400&&e.status<500;if(typeof e=="object"&&e!==null){const t=e.status;if(typeof t=="number")return t>=400&&t<500}return!1}function tt(e){return Math.min(2e3*2**e,3e5)*(.8+Math.random()*.4)}function _(){return{attempted:0,succeeded:0,failed:0,retrying:0,skipped:0,conflicted:0,cancelled:0}}var D=!1,nt="eidos-queue-replay";async function q(){const e=o.getState();if(!e.isOnline)return _();if(typeof navigator<"u"&&navigator.locks)return navigator.locks.request(nt,{ifAvailable:!0},async t=>t?J(e):_());if(D)return _();D=!0;try{return await J(e)}finally{D=!1}}async function rt(e,t){const n=Date.now();t.updateQueueItem(e.id,{status:"succeeded",completedAt:n}),t.recordReliabilityEvent("succeeded"),g({type:"update",id:e.id,update:{status:"succeeded",completedAt:n}}),await d().update(e.id,{status:"succeeded",completedAt:n}),setTimeout(()=>{t.removeQueueItem(e.id),g({type:"remove",id:e.id}),d().remove(e.id)},3e3)}async function at(e,t,n){const r=de.get(e.actionId);let a;if(r)switch(r.strategy){case"serverWins":a="skip";break;case"clientWins":a="retry";break;case"merge":case"custom":{const s={error:n,args:e.args,attempt:e.retryCount,idempotencyKey:e.idempotencyKey};a=r.resolve?.(s)??"retry";break}}if(a==="skip")return t.removeQueueItem(e.id),t.recordReliabilityEvent("conflicted"),g({type:"remove",id:e.id}),await d().remove(e.id),"conflicted";a&&typeof a=="object"&&(e.args=a.resolved,t.updateQueueItem(e.id,{args:a.resolved}),g({type:"update",id:e.id,update:{args:a.resolved}}),await d().update(e.id,{args:a.resolved}))}async function st(e,t,n){const r=e.retryCount+1;if(r>=e.maxRetries){const s={status:"failed",error:String(n),retryCount:r};t.updateQueueItem(e.id,s),t.recordReliabilityEvent("failed"),g({type:"update",id:e.id,update:s}),await d().update(e.id,s);const i={idempotencyKey:e.idempotencyKey,attempt:r};return ue.get(e.actionId)?.(...e.args,i),"failed"}const a={status:"pending",retryCount:r,nextRetryAt:Date.now()+tt(r)};return t.updateQueueItem(e.id,a),t.recordReliabilityEvent("retried"),g({type:"update",id:e.id,update:a}),await d().update(e.id,a),"retrying"}async function it(e,t){const n=x.get(e.actionId);if(!n)return"skipped";const r=le.get(e.actionId)?.cancellable;let a;if(r){const i=new AbortController;A.set(e.idempotencyKey,i),a=i.signal}const s={idempotencyKey:e.idempotencyKey,attempt:e.retryCount,signal:a};try{return await K(n,e.args,s),await rt(e,t),"succeeded"}catch(i){if(pe(i))return t.removeQueueItem(e.id),t.recordReliabilityEvent("cancelled"),g({type:"remove",id:e.id}),await d().remove(e.id),"cancelled";if(et(i)){const c=await at(e,t,i);if(c)return c}return st(e,t,i)}finally{r&&A.delete(e.idempotencyKey)}}async function ot(e,t,n){if(e.length===0)return;const r=e.filter(s=>x.has(s.actionId));if(n.skipped+=e.length-r.length,r.length>0){const s=r.map(i=>({id:i.id,update:{status:"replaying"}}));t.batchUpdateQueueItems(s),g({type:"batchUpdate",updates:s});for(const i of r)d().update(i.id,{status:"replaying"})}const a=await Promise.allSettled(r.map(s=>it(s,t)));for(const s of a){const i=s.status==="fulfilled"?s.value:"failed";i==="skipped"?n.skipped++:i==="conflicted"?n.conflicted++:i==="cancelled"?n.cancelled++:(n.attempted++,n[i]++)}}async function J(e){const t=await d().getPending(),n=Date.now(),r=t.filter(s=>s.retryCount<s.maxRetries&&(!s.nextRetryAt||s.nextRetryAt<=n)),a=_();for(const s of["high","normal","low"])await ot(r.filter(i=>(i.priority??"normal")===s),e,a);return a}async function ct(){await d().clear(),o.getState().hydrateQueue([])}function ye(){let e=o.getState().isOnline;const t=o.subscribe(()=>{const{isOnline:a}=o.getState(),s=a&&!e;e=a,s&&setTimeout(q,600)}),n=o.getState(),r=n.queue.some(a=>a.status==="pending");return n.isOnline&&r&&setTimeout(q,1200),t}async function ut(e){if(e.schemaVersion===2&&e.idempotencyKey)return e;const t={...e,schemaVersion:2,idempotencyKey:e.idempotencyKey??crypto.randomUUID()};return await(B()??ie).update(t.id,{schemaVersion:t.schemaVersion,idempotencyKey:t.idempotencyKey}).catch(()=>{}),t}var W=!1,L=null,$=null,O=null;async function ge(e={}){if(typeof window>"u"||W)return;W=!0;const t=e.swPath??"/eidos-sw.js",n=e.autoReplay??!0,r=e.skipWaiting??!0;try{const a=await se();if(a.length>0){const s=await Promise.all(a.map(ut));o.getState().hydrateQueue(s)}}catch{}try{await Re(t,{skipWaiting:r,onUpdateAvailable:e.onUpdateAvailable})}catch{}if(Ie(()=>{o.getState().isOnline&&setTimeout(q,200)}),n&&(L=ye()),$=Xe(),e.onReliabilityReport){const a=e.reliabilityReportInterval??6e4,s=e.onReliabilityReport;O=setInterval(()=>{s(o.getState().reliability)},a)}}function dt(){L?.(),L=null,$?.(),$=null,O&&clearInterval(O),O=null,W=!1}var N="@eidos:queue",lt=class{constructor(e){this.storage=e}async readAll(){try{const e=await this.storage.getItem(N);return e?JSON.parse(e):[]}catch{return[]}}async writeAll(e){await this.storage.setItem(N,JSON.stringify(e))}async add(e){const t=await this.readAll();t.push(e),await this.writeAll(t)}async getAll(){return this.readAll()}async getPending(){return(await this.readAll()).filter(e=>e.status==="pending"||e.status==="failed")}async update(e,t){const n=await this.readAll(),r=n.findIndex(a=>a.id===e);r!==-1&&(n[r]={...n[r],...t}),await this.writeAll(n)}async remove(e){const t=await this.readAll();await this.writeAll(t.filter(n=>n.id!==e))}async clear(){await this.storage.removeItem(N)}};function ft({children:e,swPath:t,autoReplay:n}){return(0,R.useEffect)(()=>{ge({swPath:t,autoReplay:n})},[]),(0,V.jsx)(V.Fragment,{children:e})}function pt(e,t){const n=Object.keys(e);if(n.length!==Object.keys(t).length)return!1;for(const r of n)if(e[r]!==t[r])return!1;return!0}function F(e,t){return pt(e,t)}function m(e,t=Object.is){return{subscribe(n){let r=e(o.getState());return n(r),o.subscribe(()=>{const a=e(o.getState());t(r,a)||(r=a,n(a))})},getState(){return e(o.getState())}}}var yt=m(e=>e),gt=m(e=>e.queue),ht=m(e=>({isOnline:e.isOnline,swStatus:e.swStatus,swError:e.swError}),F),wt=m(e=>z(e.queue),F),vt=m(e=>e.reliability,F);function mt(e){return m(t=>t.resources[e])}function St(e){return m(t=>t.queue.find(n=>n.id===e))}function he(e){let t=o.getState().queue.length;return o.subscribe(()=>{const n=o.getState().queue.length;t>0&&n===0&&e(),t=n})}function y(e){const t=e??(n=>n);return(0,R.useSyncExternalStore)(o.subscribe,()=>t(o.getState()))}function bt(){return y()}function Et(){return y(e=>e.resources)}function Rt(e){return y(t=>t.resources[e])}function At(){return y(e=>e.queue)}function It(e){return y(t=>t.queue.find(n=>n.id===e))}function kt(){return{isOnline:y(e=>e.isOnline),swStatus:y(e=>e.swStatus),swError:y(e=>e.swError)}}function _t(){const[e,t,n,r]=y(a=>{const{pending:s,failed:i,replaying:c,total:u}=z(a.queue);return`${s},${i},${c},${u}`}).split(",");return{pending:+e,failed:+t,replaying:+n,total:+r}}function Ot(){return y(e=>e.reliability)}function xt(e){const t=(0,R.useRef)(e);(0,R.useEffect)(()=>{t.current=e}),(0,R.useEffect)(()=>he(()=>t.current()),[])}var we="2.3.1";function qt(){const e=o.getState(),t=H();return{version:we,swStatus:e.swStatus,...e.swError!==void 0&&{swError:e.swError},isOnline:e.isOnline,resourceCount:Object.keys(e.resources).length,resources:Object.fromEntries(Object.entries(e.resources).map(([n,r])=>[n,{url:r.url,strategy:r.strategy.swStrategy,status:r.status,cacheHits:r.cacheHits,cacheMisses:r.cacheMisses,...r.cachedAt!==void 0&&{cachedAt:r.cachedAt}}])),queue:e.queue.map(n=>({id:n.id,actionId:n.actionId,actionName:n.actionName,status:n.status,retryCount:n.retryCount,maxRetries:n.maxRetries,idempotencyKey:n.idempotencyKey,schemaVersion:n.schemaVersion,queuedAt:n.queuedAt})),reliability:{...e.reliability},swRegistration:t?{scope:t.scope,scriptURL:(t.active??t.waiting??t.installing)?.scriptURL??"",state:t.installing?"installing":t.waiting?"waiting":t.active?"active":null}:null}}exports.AsyncStorageQueueStorage=lt;exports.EidosProvider=ft;exports.VERSION=we;exports._getQueueStorage=B;exports._resetEidos=dt;exports.action=ze;exports.cancelByIdempotencyKey=fe;exports.clearQueue=ct;exports.eidosAction=St;exports.eidosDebug=qt;exports.eidosQueue=gt;exports.eidosQueueStats=wt;exports.eidosReliabilityStats=vt;exports.eidosResource=mt;exports.eidosStatus=ht;exports.eidosStore=yt;exports.getSwRegistration=H;exports.initEidos=ge;exports.isBgSyncSupported=ke;exports.onQueueDrain=he;exports.registerPushCallbacks=_e;exports.replayQueue=q;exports.requeueItem=Ze;exports.resource=Ne;exports.resourcePattern=Me;exports.sendToWorker=I;exports.setOfflineSimulation=xe;exports.setQueryInvalidator=Pe;exports.setQueueStorage=Ye;exports.subscribeReplayOnReconnect=ye;exports.triggerSwUpdate=Qe;exports.useEidos=bt;exports.useEidosAction=It;exports.useEidosOnDrain=xt;exports.useEidosQueue=At;exports.useEidosQueueStats=_t;exports.useEidosReliabilityStats=Ot;exports.useEidosResource=Rt;exports.useEidosResources=Et;exports.useEidosStatus=kt;exports.useEidosStore=o;exports.warmCache=We;
14
14
 
15
15
  //# sourceMappingURL=eidos.cjs.map