@sweidos/eidos 1.0.5 → 1.0.7

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/README.md CHANGED
@@ -249,7 +249,7 @@ const entry = useEidosResource('/api/products')
249
249
  // The full action queue, reactive
250
250
  const queue = useEidosQueue()
251
251
 
252
- // Full Zustand store — use sparingly
252
+ // Full store snapshot — use sparingly, prefer the narrower hooks above
253
253
  const state = useEidos()
254
254
  ```
255
255
 
@@ -268,6 +268,29 @@ setOfflineSimulation(false) // restore normal behaviour
268
268
 
269
269
  ---
270
270
 
271
+ ## Performance
272
+
273
+ Performance is a first-class concern in Eidos. Every design decision optimises for low overhead.
274
+
275
+ | Metric | Value | How |
276
+ |--------|-------|-----|
277
+ | **Bundle size** | 5.0 kB gzip | Zero runtime dependencies — not even a state library |
278
+ | **Re-renders** | Minimal | `useSyncExternalStore` with per-field selectors; components only re-render when their field changes |
279
+ | **Queue replay** | Parallel | `Promise.allSettled` — N pending actions replay concurrently, not serially |
280
+ | **IDB reads** | Index scan | `replayQueue` queries only `pending`/`failed` items via the status index — no full table scan |
281
+ | **Network timeout** | 3 s | `NetworkFirst` strategy aborts fetch after 3 s and falls back to cache — no hanging requests |
282
+ | **Pre-activation buffer** | Zero drops | Messages sent before the SW is active are buffered and flushed on activation |
283
+ | **Concurrency safety** | Lock-guarded | `_replaying` flag prevents duplicate replay passes from concurrent online events |
284
+
285
+ ### Bundle comparison
286
+
287
+ | Version | Raw | Gzip | Change |
288
+ |---------|-----|------|--------|
289
+ | 1.0.5 (with zustand) | 35.0 kB | 7.9 kB | — |
290
+ | **1.0.6** (zero deps) | **18.6 kB** | **5.0 kB** | **−47%** |
291
+
292
+ ---
293
+
271
294
  ## Architecture
272
295
 
273
296
  ```
@@ -278,7 +301,7 @@ setOfflineSimulation(false) // restore normal behaviour
278
301
  │ EIDOS_REGISTER_RESOURCE (postMessage)
279
302
  ┌────────────────▼────────────────────────────┐
280
303
  │ Runtime Layer (@sweidos/eidos) │
281
- │ Strategy derivation · Zustand store
304
+ │ Strategy derivation · reactive store
282
305
  │ SW bridge · IDB queue · exponential backoff │
283
306
  └────────────────┬────────────────────────────┘
284
307
  │ fetch intercept
@@ -329,7 +352,7 @@ eidos/
329
352
  │ │ ├── resource.ts resource() — caching + handle
330
353
  │ │ ├── action.ts action() + exponential backoff queue replay
331
354
  │ │ ├── runtime.ts initEidos + SW registration
332
- │ │ ├── store.ts Zustand store
355
+ │ │ ├── store.ts reactive store (useSyncExternalStore)
333
356
  │ │ ├── sw-bridge.ts postMessage channel
334
357
  │ │ ├── idb.ts IndexedDB CRUD wrapper
335
358
  │ │ └── react/ EidosProvider + hooks
package/dist/eidos.cjs.js CHANGED
@@ -1,400 +1,63 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const require$$0 = require("react");
3
+ const react = require("react");
4
4
  const jsxRuntime = require("react/jsx-runtime");
5
- const __vite_import_meta_env__$1 = {};
6
- const createStoreImpl = (createState) => {
7
- let state;
8
- const listeners = /* @__PURE__ */ new Set();
9
- const setState = (partial, replace) => {
10
- const nextState = typeof partial === "function" ? partial(state) : partial;
11
- if (!Object.is(nextState, state)) {
12
- const previousState = state;
13
- state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
14
- listeners.forEach((listener) => listener(state, previousState));
15
- }
16
- };
17
- const getState = () => state;
18
- const getInitialState = () => initialState;
19
- const subscribe = (listener) => {
20
- listeners.add(listener);
21
- return () => listeners.delete(listener);
22
- };
23
- const destroy = () => {
24
- if ((__vite_import_meta_env__$1 ? "production" : void 0) !== "production") {
25
- console.warn(
26
- "[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."
27
- );
28
- }
29
- listeners.clear();
30
- };
31
- const api = { setState, getState, getInitialState, subscribe, destroy };
32
- const initialState = state = createState(setState, getState, api);
33
- return api;
34
- };
35
- const createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;
36
- function getDefaultExportFromCjs(x) {
37
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
38
- }
39
- var withSelector = { exports: {} };
40
- var withSelector_production = {};
41
- var shim = { exports: {} };
42
- var useSyncExternalStoreShim_production = {};
43
- /**
44
- * @license React
45
- * use-sync-external-store-shim.production.js
46
- *
47
- * Copyright (c) Meta Platforms, Inc. and affiliates.
48
- *
49
- * This source code is licensed under the MIT license found in the
50
- * LICENSE file in the root directory of this source tree.
51
- */
52
- var hasRequiredUseSyncExternalStoreShim_production;
53
- function requireUseSyncExternalStoreShim_production() {
54
- if (hasRequiredUseSyncExternalStoreShim_production) return useSyncExternalStoreShim_production;
55
- hasRequiredUseSyncExternalStoreShim_production = 1;
56
- var React = require$$0;
57
- function is(x, y) {
58
- return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
59
- }
60
- var objectIs = "function" === typeof Object.is ? Object.is : is, useState = React.useState, useEffect = React.useEffect, useLayoutEffect = React.useLayoutEffect, useDebugValue2 = React.useDebugValue;
61
- function useSyncExternalStore$2(subscribe, getSnapshot) {
62
- var value = getSnapshot(), _useState = useState({ inst: { value, getSnapshot } }), inst = _useState[0].inst, forceUpdate = _useState[1];
63
- useLayoutEffect(
64
- function() {
65
- inst.value = value;
66
- inst.getSnapshot = getSnapshot;
67
- checkIfSnapshotChanged(inst) && forceUpdate({ inst });
68
- },
69
- [subscribe, value, getSnapshot]
70
- );
71
- useEffect(
72
- function() {
73
- checkIfSnapshotChanged(inst) && forceUpdate({ inst });
74
- return subscribe(function() {
75
- checkIfSnapshotChanged(inst) && forceUpdate({ inst });
76
- });
77
- },
78
- [subscribe]
79
- );
80
- useDebugValue2(value);
81
- return value;
82
- }
83
- function checkIfSnapshotChanged(inst) {
84
- var latestGetSnapshot = inst.getSnapshot;
85
- inst = inst.value;
86
- try {
87
- var nextValue = latestGetSnapshot();
88
- return !objectIs(inst, nextValue);
89
- } catch (error) {
90
- return true;
91
- }
92
- }
93
- function useSyncExternalStore$1(subscribe, getSnapshot) {
94
- return getSnapshot();
95
- }
96
- var shim2 = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
97
- useSyncExternalStoreShim_production.useSyncExternalStore = void 0 !== React.useSyncExternalStore ? React.useSyncExternalStore : shim2;
98
- return useSyncExternalStoreShim_production;
99
- }
100
- var useSyncExternalStoreShim_development = {};
101
- /**
102
- * @license React
103
- * use-sync-external-store-shim.development.js
104
- *
105
- * Copyright (c) Meta Platforms, Inc. and affiliates.
106
- *
107
- * This source code is licensed under the MIT license found in the
108
- * LICENSE file in the root directory of this source tree.
109
- */
110
- var hasRequiredUseSyncExternalStoreShim_development;
111
- function requireUseSyncExternalStoreShim_development() {
112
- if (hasRequiredUseSyncExternalStoreShim_development) return useSyncExternalStoreShim_development;
113
- hasRequiredUseSyncExternalStoreShim_development = 1;
114
- "production" !== process.env.NODE_ENV && function() {
115
- function is(x, y) {
116
- return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
117
- }
118
- function useSyncExternalStore$2(subscribe, getSnapshot) {
119
- didWarnOld18Alpha || void 0 === React.startTransition || (didWarnOld18Alpha = true, console.error(
120
- "You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."
121
- ));
122
- var value = getSnapshot();
123
- if (!didWarnUncachedGetSnapshot) {
124
- var cachedValue = getSnapshot();
125
- objectIs(value, cachedValue) || (console.error(
126
- "The result of getSnapshot should be cached to avoid an infinite loop"
127
- ), didWarnUncachedGetSnapshot = true);
128
- }
129
- cachedValue = useState({
130
- inst: { value, getSnapshot }
131
- });
132
- var inst = cachedValue[0].inst, forceUpdate = cachedValue[1];
133
- useLayoutEffect(
134
- function() {
135
- inst.value = value;
136
- inst.getSnapshot = getSnapshot;
137
- checkIfSnapshotChanged(inst) && forceUpdate({ inst });
138
- },
139
- [subscribe, value, getSnapshot]
140
- );
141
- useEffect(
142
- function() {
143
- checkIfSnapshotChanged(inst) && forceUpdate({ inst });
144
- return subscribe(function() {
145
- checkIfSnapshotChanged(inst) && forceUpdate({ inst });
146
- });
147
- },
148
- [subscribe]
149
- );
150
- useDebugValue2(value);
151
- return value;
152
- }
153
- function checkIfSnapshotChanged(inst) {
154
- var latestGetSnapshot = inst.getSnapshot;
155
- inst = inst.value;
156
- try {
157
- var nextValue = latestGetSnapshot();
158
- return !objectIs(inst, nextValue);
159
- } catch (error) {
160
- return true;
161
- }
162
- }
163
- function useSyncExternalStore$1(subscribe, getSnapshot) {
164
- return getSnapshot();
165
- }
166
- "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
167
- var React = require$$0, objectIs = "function" === typeof Object.is ? Object.is : is, useState = React.useState, useEffect = React.useEffect, useLayoutEffect = React.useLayoutEffect, useDebugValue2 = React.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim2 = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
168
- useSyncExternalStoreShim_development.useSyncExternalStore = void 0 !== React.useSyncExternalStore ? React.useSyncExternalStore : shim2;
169
- "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
170
- }();
171
- return useSyncExternalStoreShim_development;
172
- }
173
- var hasRequiredShim;
174
- function requireShim() {
175
- if (hasRequiredShim) return shim.exports;
176
- hasRequiredShim = 1;
177
- if (process.env.NODE_ENV === "production") {
178
- shim.exports = requireUseSyncExternalStoreShim_production();
179
- } else {
180
- shim.exports = requireUseSyncExternalStoreShim_development();
181
- }
182
- return shim.exports;
183
- }
184
- /**
185
- * @license React
186
- * use-sync-external-store-shim/with-selector.production.js
187
- *
188
- * Copyright (c) Meta Platforms, Inc. and affiliates.
189
- *
190
- * This source code is licensed under the MIT license found in the
191
- * LICENSE file in the root directory of this source tree.
192
- */
193
- var hasRequiredWithSelector_production;
194
- function requireWithSelector_production() {
195
- if (hasRequiredWithSelector_production) return withSelector_production;
196
- hasRequiredWithSelector_production = 1;
197
- var React = require$$0, shim2 = requireShim();
198
- function is(x, y) {
199
- return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
200
- }
201
- var objectIs = "function" === typeof Object.is ? Object.is : is, useSyncExternalStore = shim2.useSyncExternalStore, useRef2 = React.useRef, useEffect = React.useEffect, useMemo = React.useMemo, useDebugValue2 = React.useDebugValue;
202
- withSelector_production.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
203
- var instRef = useRef2(null);
204
- if (null === instRef.current) {
205
- var inst = { hasValue: false, value: null };
206
- instRef.current = inst;
207
- } else inst = instRef.current;
208
- instRef = useMemo(
209
- function() {
210
- function memoizedSelector(nextSnapshot) {
211
- if (!hasMemo) {
212
- hasMemo = true;
213
- memoizedSnapshot = nextSnapshot;
214
- nextSnapshot = selector(nextSnapshot);
215
- if (void 0 !== isEqual && inst.hasValue) {
216
- var currentSelection = inst.value;
217
- if (isEqual(currentSelection, nextSnapshot))
218
- return memoizedSelection = currentSelection;
219
- }
220
- return memoizedSelection = nextSnapshot;
221
- }
222
- currentSelection = memoizedSelection;
223
- if (objectIs(memoizedSnapshot, nextSnapshot)) return currentSelection;
224
- var nextSelection = selector(nextSnapshot);
225
- if (void 0 !== isEqual && isEqual(currentSelection, nextSelection))
226
- return memoizedSnapshot = nextSnapshot, currentSelection;
227
- memoizedSnapshot = nextSnapshot;
228
- return memoizedSelection = nextSelection;
229
- }
230
- var hasMemo = false, memoizedSnapshot, memoizedSelection, maybeGetServerSnapshot = void 0 === getServerSnapshot ? null : getServerSnapshot;
231
- return [
232
- function() {
233
- return memoizedSelector(getSnapshot());
234
- },
235
- null === maybeGetServerSnapshot ? void 0 : function() {
236
- return memoizedSelector(maybeGetServerSnapshot());
237
- }
238
- ];
239
- },
240
- [getSnapshot, getServerSnapshot, selector, isEqual]
241
- );
242
- var value = useSyncExternalStore(subscribe, instRef[0], instRef[1]);
243
- useEffect(
244
- function() {
245
- inst.hasValue = true;
246
- inst.value = value;
247
- },
248
- [value]
249
- );
250
- useDebugValue2(value);
251
- return value;
252
- };
253
- return withSelector_production;
254
- }
255
- var withSelector_development = {};
256
- /**
257
- * @license React
258
- * use-sync-external-store-shim/with-selector.development.js
259
- *
260
- * Copyright (c) Meta Platforms, Inc. and affiliates.
261
- *
262
- * This source code is licensed under the MIT license found in the
263
- * LICENSE file in the root directory of this source tree.
264
- */
265
- var hasRequiredWithSelector_development;
266
- function requireWithSelector_development() {
267
- if (hasRequiredWithSelector_development) return withSelector_development;
268
- hasRequiredWithSelector_development = 1;
269
- "production" !== process.env.NODE_ENV && function() {
270
- function is(x, y) {
271
- return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
272
- }
273
- "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
274
- var React = require$$0, shim2 = requireShim(), objectIs = "function" === typeof Object.is ? Object.is : is, useSyncExternalStore = shim2.useSyncExternalStore, useRef2 = React.useRef, useEffect = React.useEffect, useMemo = React.useMemo, useDebugValue2 = React.useDebugValue;
275
- withSelector_development.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
276
- var instRef = useRef2(null);
277
- if (null === instRef.current) {
278
- var inst = { hasValue: false, value: null };
279
- instRef.current = inst;
280
- } else inst = instRef.current;
281
- instRef = useMemo(
282
- function() {
283
- function memoizedSelector(nextSnapshot) {
284
- if (!hasMemo) {
285
- hasMemo = true;
286
- memoizedSnapshot = nextSnapshot;
287
- nextSnapshot = selector(nextSnapshot);
288
- if (void 0 !== isEqual && inst.hasValue) {
289
- var currentSelection = inst.value;
290
- if (isEqual(currentSelection, nextSnapshot))
291
- return memoizedSelection = currentSelection;
292
- }
293
- return memoizedSelection = nextSnapshot;
294
- }
295
- currentSelection = memoizedSelection;
296
- if (objectIs(memoizedSnapshot, nextSnapshot))
297
- return currentSelection;
298
- var nextSelection = selector(nextSnapshot);
299
- if (void 0 !== isEqual && isEqual(currentSelection, nextSelection))
300
- return memoizedSnapshot = nextSnapshot, currentSelection;
301
- memoizedSnapshot = nextSnapshot;
302
- return memoizedSelection = nextSelection;
303
- }
304
- var hasMemo = false, memoizedSnapshot, memoizedSelection, maybeGetServerSnapshot = void 0 === getServerSnapshot ? null : getServerSnapshot;
305
- return [
306
- function() {
307
- return memoizedSelector(getSnapshot());
308
- },
309
- null === maybeGetServerSnapshot ? void 0 : function() {
310
- return memoizedSelector(maybeGetServerSnapshot());
311
- }
312
- ];
313
- },
314
- [getSnapshot, getServerSnapshot, selector, isEqual]
315
- );
316
- var value = useSyncExternalStore(subscribe, instRef[0], instRef[1]);
317
- useEffect(
318
- function() {
319
- inst.hasValue = true;
320
- inst.value = value;
321
- },
322
- [value]
323
- );
324
- useDebugValue2(value);
325
- return value;
326
- };
327
- "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
328
- }();
329
- return withSelector_development;
330
- }
331
- if (process.env.NODE_ENV === "production") {
332
- withSelector.exports = requireWithSelector_production();
333
- } else {
334
- withSelector.exports = requireWithSelector_development();
335
- }
336
- var withSelectorExports = withSelector.exports;
337
- const useSyncExternalStoreExports = /* @__PURE__ */ getDefaultExportFromCjs(withSelectorExports);
338
- const __vite_import_meta_env__ = {};
339
- const { useDebugValue } = require$$0;
340
- const { useSyncExternalStoreWithSelector } = useSyncExternalStoreExports;
341
- let didWarnAboutEqualityFn = false;
342
- const identity = (arg) => arg;
343
- function useStore(api, selector = identity, equalityFn) {
344
- if ((__vite_import_meta_env__ ? "production" : void 0) !== "production" && equalityFn && !didWarnAboutEqualityFn) {
345
- console.warn(
346
- "[DEPRECATED] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`. They can be imported from 'zustand/traditional'. https://github.com/pmndrs/zustand/discussions/1937"
347
- );
348
- didWarnAboutEqualityFn = true;
349
- }
350
- const slice = useSyncExternalStoreWithSelector(
351
- api.subscribe,
352
- api.getState,
353
- api.getServerState || api.getInitialState,
354
- selector,
355
- equalityFn
356
- );
357
- useDebugValue(slice);
358
- return slice;
359
- }
360
- const createImpl = (createState) => {
361
- if ((__vite_import_meta_env__ ? "production" : void 0) !== "production" && typeof createState !== "function") {
362
- console.warn(
363
- "[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`."
364
- );
365
- }
366
- const api = typeof createState === "function" ? createStore(createState) : createState;
367
- const useBoundStore = (selector, equalityFn) => useStore(api, selector, equalityFn);
368
- Object.assign(useBoundStore, api);
369
- return useBoundStore;
370
- };
371
- const create = (createState) => createState ? createImpl(createState) : createImpl;
372
- const useEidosStore = create((set) => ({
5
+ let _state;
6
+ const _listeners = /* @__PURE__ */ new Set();
7
+ function _notify() {
8
+ _listeners.forEach((fn) => fn());
9
+ }
10
+ function _set(updater) {
11
+ _state = { ..._state, ...updater(_state) };
12
+ _notify();
13
+ }
14
+ _state = {
373
15
  isOnline: typeof navigator !== "undefined" ? navigator.onLine : true,
374
16
  swStatus: "idle",
375
17
  swError: void 0,
376
18
  resources: {},
377
19
  queue: [],
378
- setOnline: (isOnline) => set({ isOnline }),
379
- setSwStatus: (swStatus, swError) => set({ swStatus, swError }),
380
- registerResource: (url, entry) => set((s) => ({ resources: { ...s.resources, [url]: entry } })),
381
- updateResource: (url, update) => set((s) => ({
20
+ setOnline: (isOnline) => _set(() => ({ isOnline })),
21
+ setSwStatus: (swStatus, swError) => _set(() => ({ swStatus, swError })),
22
+ registerResource: (url, entry) => _set((s) => ({ resources: { ...s.resources, [url]: entry } })),
23
+ updateResource: (url, update) => _set((s) => ({
382
24
  resources: {
383
25
  ...s.resources,
384
26
  [url]: s.resources[url] ? { ...s.resources[url], ...update } : s.resources[url]
385
27
  }
386
28
  })),
387
- unregisterResource: (url) => set((s) => {
29
+ unregisterResource: (url) => _set((s) => {
388
30
  const { [url]: _removed, ...rest } = s.resources;
389
31
  return { resources: rest };
390
32
  }),
391
- addQueueItem: (item) => set((s) => ({ queue: [...s.queue, item] })),
392
- updateQueueItem: (id, update) => set((s) => ({
33
+ addQueueItem: (item) => _set((s) => ({ queue: [...s.queue, item] })),
34
+ updateQueueItem: (id, update) => _set((s) => ({
393
35
  queue: s.queue.map((item) => item.id === id ? { ...item, ...update } : item)
394
36
  })),
395
- removeQueueItem: (id) => set((s) => ({ queue: s.queue.filter((item) => item.id !== id) })),
396
- hydrateQueue: (items) => set({ queue: items })
397
- }));
37
+ removeQueueItem: (id) => _set((s) => ({ queue: s.queue.filter((item) => item.id !== id) })),
38
+ hydrateQueue: (items) => _set(() => ({ queue: items }))
39
+ };
40
+ function _getState() {
41
+ return _state;
42
+ }
43
+ function _subscribe(listener) {
44
+ _listeners.add(listener);
45
+ return () => {
46
+ _listeners.delete(listener);
47
+ };
48
+ }
49
+ function _useStore(selector) {
50
+ const fn = selector ?? ((s) => s);
51
+ return react.useSyncExternalStore(_subscribe, () => fn(_getState()));
52
+ }
53
+ _useStore.getState = _getState;
54
+ _useStore.subscribe = _subscribe;
55
+ _useStore.setState = (partial) => {
56
+ const update = typeof partial === "function" ? partial(_state) : partial;
57
+ _state = { ..._state, ...update };
58
+ _notify();
59
+ };
60
+ const useEidosStore = _useStore;
398
61
  let _registration = null;
399
62
  let _pendingMessages = [];
400
63
  async function registerServiceWorker(swPath) {
@@ -738,6 +401,40 @@ async function idbRemoveFromQueue(id) {
738
401
  tx.onerror = () => reject(tx.error);
739
402
  });
740
403
  }
404
+ async function idbGetPendingItems() {
405
+ const db = await openDB();
406
+ return new Promise((resolve, reject) => {
407
+ const tx = db.transaction(QUEUE_STORE, "readonly");
408
+ const index = tx.objectStore(QUEUE_STORE).index("status");
409
+ const results = [];
410
+ let done = 0;
411
+ function finish(err) {
412
+ if (err) {
413
+ reject(err);
414
+ return;
415
+ }
416
+ if (++done === 2) resolve(results);
417
+ }
418
+ const pendingReq = index.openCursor(IDBKeyRange.only("pending"));
419
+ pendingReq.onsuccess = (e) => {
420
+ const cursor = e.target.result;
421
+ if (cursor) {
422
+ results.push(cursor.value);
423
+ cursor.continue();
424
+ } else finish();
425
+ };
426
+ pendingReq.onerror = () => finish(pendingReq.error);
427
+ const failedReq = index.openCursor(IDBKeyRange.only("failed"));
428
+ failedReq.onsuccess = (e) => {
429
+ const cursor = e.target.result;
430
+ if (cursor) {
431
+ results.push(cursor.value);
432
+ cursor.continue();
433
+ } else finish();
434
+ };
435
+ failedReq.onerror = () => finish(failedReq.error);
436
+ });
437
+ }
741
438
  const _actionRegistry = /* @__PURE__ */ new Map();
742
439
  function uid() {
743
440
  return crypto.randomUUID();
@@ -799,10 +496,10 @@ async function replayQueue() {
799
496
  }
800
497
  }
801
498
  async function _doReplayQueue(store) {
802
- const queue = await idbGetQueue();
499
+ const candidates = await idbGetPendingItems();
803
500
  const now = Date.now();
804
- const pending = queue.filter(
805
- (item) => (item.status === "pending" || item.status === "failed") && (!item.nextRetryAt || item.nextRetryAt <= now)
501
+ const pending = candidates.filter(
502
+ (item) => !item.nextRetryAt || item.nextRetryAt <= now
806
503
  );
807
504
  await Promise.allSettled(
808
505
  pending.map(async (item) => {
@@ -860,9 +557,10 @@ async function initEidos(config = {}) {
860
557
  }
861
558
  if (autoReplay) {
862
559
  let prevIsOnline = useEidosStore.getState().isOnline;
863
- useEidosStore.subscribe((state) => {
864
- const justCameOnline = state.isOnline && !prevIsOnline;
865
- prevIsOnline = state.isOnline;
560
+ useEidosStore.subscribe(() => {
561
+ const { isOnline } = useEidosStore.getState();
562
+ const justCameOnline = isOnline && !prevIsOnline;
563
+ prevIsOnline = isOnline;
866
564
  if (justCameOnline) {
867
565
  setTimeout(replayQueue, 600);
868
566
  }
@@ -875,55 +573,11 @@ async function initEidos(config = {}) {
875
573
  }
876
574
  }
877
575
  function EidosProvider({ children, swPath, autoReplay }) {
878
- require$$0.useEffect(() => {
576
+ react.useEffect(() => {
879
577
  initEidos({ swPath, autoReplay });
880
578
  }, []);
881
579
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
882
580
  }
883
- function shallow(objA, objB) {
884
- if (Object.is(objA, objB)) {
885
- return true;
886
- }
887
- if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
888
- return false;
889
- }
890
- if (objA instanceof Map && objB instanceof Map) {
891
- if (objA.size !== objB.size) return false;
892
- for (const [key, value] of objA) {
893
- if (!Object.is(value, objB.get(key))) {
894
- return false;
895
- }
896
- }
897
- return true;
898
- }
899
- if (objA instanceof Set && objB instanceof Set) {
900
- if (objA.size !== objB.size) return false;
901
- for (const value of objA) {
902
- if (!objB.has(value)) {
903
- return false;
904
- }
905
- }
906
- return true;
907
- }
908
- const keysA = Object.keys(objA);
909
- if (keysA.length !== Object.keys(objB).length) {
910
- return false;
911
- }
912
- for (const keyA of keysA) {
913
- if (!Object.prototype.hasOwnProperty.call(objB, keyA) || !Object.is(objA[keyA], objB[keyA])) {
914
- return false;
915
- }
916
- }
917
- return true;
918
- }
919
- const { useRef } = require$$0;
920
- function useShallow(selector) {
921
- const prev = useRef();
922
- return (state) => {
923
- const next = selector(state);
924
- return shallow(prev.current, next) ? prev.current : prev.current = next;
925
- };
926
- }
927
581
  function useEidos() {
928
582
  return useEidosStore();
929
583
  }
@@ -934,15 +588,14 @@ function useEidosQueue() {
934
588
  return useEidosStore((s) => s.queue);
935
589
  }
936
590
  function useEidosStatus() {
937
- return useEidosStore(
938
- useShallow((s) => ({
939
- isOnline: s.isOnline,
940
- swStatus: s.swStatus,
941
- swError: s.swError
942
- }))
943
- );
591
+ const isOnline = useEidosStore((s) => s.isOnline);
592
+ const swStatus = useEidosStore((s) => s.swStatus);
593
+ const swError = useEidosStore((s) => s.swError);
594
+ return { isOnline, swStatus, swError };
944
595
  }
596
+ const VERSION = "1.0.7";
945
597
  exports.EidosProvider = EidosProvider;
598
+ exports.VERSION = VERSION;
946
599
  exports.action = action;
947
600
  exports.initEidos = initEidos;
948
601
  exports.replayQueue = replayQueue;