@sweidos/eidos 1.0.30 → 1.0.32

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/idb.js CHANGED
@@ -1,87 +1,80 @@
1
- const w = "eidos";
1
+ const p = "eidos";
2
2
  const o = "action-queue";
3
- let m = null;
4
- function d() {
5
- return m ? Promise.resolve(m) : new Promise((r, s) => {
6
- const t = indexedDB.open(w, 1);
7
- t.onupgradeneeded = (n) => {
8
- const e = n.target.result;
3
+ let b = null;
4
+ function a() {
5
+ return b ? Promise.resolve(b) : new Promise((s, n) => {
6
+ const t = indexedDB.open(p, 1);
7
+ t.onupgradeneeded = (r) => {
8
+ const e = r.target.result;
9
9
  if (!e.objectStoreNames.contains(o)) {
10
10
  const c = e.createObjectStore(o, { keyPath: "id" });
11
11
  c.createIndex("status", "status", { unique: !1 }), c.createIndex("actionId", "actionId", { unique: !1 });
12
12
  }
13
13
  }, t.onsuccess = () => {
14
- m = t.result, r(t.result);
15
- }, t.onerror = () => s(t.error);
14
+ b = t.result, s(t.result);
15
+ }, t.onerror = () => n(t.error);
16
16
  });
17
17
  }
18
- async function p(r) {
19
- const s = await d();
20
- return new Promise((t, n) => {
21
- const e = s.transaction(o, "readwrite");
22
- e.objectStore(o).add(r), e.oncomplete = () => t(), e.onerror = () => n(e.error);
18
+ async function x(s) {
19
+ const n = await a();
20
+ return new Promise((t, r) => {
21
+ const e = n.transaction(o, "readwrite");
22
+ e.objectStore(o).add(s), e.oncomplete = () => t(), e.onerror = () => r(e.error);
23
23
  });
24
24
  }
25
- async function x() {
26
- const r = await d();
27
- return new Promise((s, t) => {
28
- const e = r.transaction(o, "readonly").objectStore(o).getAll();
29
- e.onsuccess = () => s(e.result), e.onerror = () => t(e.error);
25
+ async function y() {
26
+ const s = await a();
27
+ return new Promise((n, t) => {
28
+ const e = s.transaction(o, "readonly").objectStore(o).getAll();
29
+ e.onsuccess = () => n(e.result), e.onerror = () => t(e.error);
30
30
  });
31
31
  }
32
- async function y(r, s) {
33
- const t = await d();
34
- return new Promise((n, e) => {
35
- const c = t.transaction(o, "readwrite"), l = c.objectStore(o), i = l.get(r);
36
- i.onsuccess = () => {
37
- i.result && l.put({ ...i.result, ...s });
38
- }, c.oncomplete = () => n(), c.onerror = () => e(c.error);
32
+ async function P(s, n) {
33
+ const t = await a();
34
+ return new Promise((r, e) => {
35
+ const c = t.transaction(o, "readwrite"), i = c.objectStore(o), u = i.get(s);
36
+ u.onsuccess = () => {
37
+ u.result && i.put({ ...u.result, ...n });
38
+ }, c.oncomplete = () => r(), c.onerror = () => e(c.error);
39
39
  });
40
40
  }
41
- async function g(r) {
42
- const s = await d();
43
- return new Promise((t, n) => {
44
- const e = s.transaction(o, "readwrite");
45
- e.objectStore(o).delete(r), e.oncomplete = () => t(), e.onerror = () => n(e.error);
41
+ async function S(s) {
42
+ const n = await a();
43
+ return new Promise((t, r) => {
44
+ const e = n.transaction(o, "readwrite");
45
+ e.objectStore(o).delete(s), e.oncomplete = () => t(), e.onerror = () => r(e.error);
46
46
  });
47
47
  }
48
- async function S() {
49
- const r = await d();
50
- return new Promise((s, t) => {
51
- const e = r.transaction(o, "readonly").objectStore(o).index("status"), c = [];
52
- let l = 0;
53
- function i(u) {
54
- if (u) {
55
- t(u);
56
- return;
57
- }
58
- ++l === 2 && s(c);
59
- }
60
- const b = e.openCursor(IDBKeyRange.only("pending"));
61
- b.onsuccess = (u) => {
62
- const a = u.target.result;
63
- a ? (c.push(a.value), a.continue()) : i();
64
- }, b.onerror = () => i(b.error);
65
- const f = e.openCursor(IDBKeyRange.only("failed"));
66
- f.onsuccess = (u) => {
67
- const a = u.target.result;
68
- a ? (c.push(a.value), a.continue()) : i();
69
- }, f.onerror = () => i(f.error);
70
- });
48
+ async function g() {
49
+ const s = await a();
50
+ function n(e) {
51
+ return new Promise((c, i) => {
52
+ const w = s.transaction(o, "readonly").objectStore(o).index("status"), m = [], d = w.openCursor(IDBKeyRange.only(e));
53
+ d.onsuccess = (f) => {
54
+ const l = f.target.result;
55
+ l ? (m.push(l.value), l.continue()) : c(m);
56
+ }, d.onerror = () => i(d.error);
57
+ });
58
+ }
59
+ const [t, r] = await Promise.all([
60
+ n("pending"),
61
+ n("failed")
62
+ ]);
63
+ return [...t, ...r];
71
64
  }
72
65
  async function I() {
73
- const r = await d();
74
- return new Promise((s, t) => {
75
- const n = r.transaction(o, "readwrite");
76
- n.objectStore(o).clear(), n.oncomplete = () => s(), n.onerror = () => t(n.error);
66
+ const s = await a();
67
+ return new Promise((n, t) => {
68
+ const r = s.transaction(o, "readwrite");
69
+ r.objectStore(o).clear(), r.oncomplete = () => n(), r.onerror = () => t(r.error);
77
70
  });
78
71
  }
79
72
  export {
80
- p as idbAddToQueue,
73
+ x as idbAddToQueue,
81
74
  I as idbClearQueue,
82
- S as idbGetPendingItems,
83
- x as idbGetQueue,
84
- g as idbRemoveFromQueue,
85
- y as idbUpdateQueueItem
75
+ g as idbGetPendingItems,
76
+ y as idbGetQueue,
77
+ S as idbRemoveFromQueue,
78
+ P as idbUpdateQueueItem
86
79
  };
87
80
  //# sourceMappingURL=idb.js.map
package/dist/idb.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"idb.js","sources":["../src/idb.ts"],"sourcesContent":["import type { ActionQueueItem } from './types'\n\nconst DB_NAME = 'eidos'\nconst DB_VERSION = 1\nconst QUEUE_STORE = 'action-queue'\n\nlet _db: IDBDatabase | null = null\n\nfunction openDB(): Promise<IDBDatabase> {\n if (_db) return Promise.resolve(_db)\n\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(DB_NAME, DB_VERSION)\n\n req.onupgradeneeded = (event) => {\n const db = (event.target as IDBOpenDBRequest).result\n if (!db.objectStoreNames.contains(QUEUE_STORE)) {\n const store = db.createObjectStore(QUEUE_STORE, { keyPath: 'id' })\n store.createIndex('status', 'status', { unique: false })\n store.createIndex('actionId', 'actionId', { unique: false })\n }\n }\n\n req.onsuccess = () => {\n _db = req.result\n resolve(req.result)\n }\n\n req.onerror = () => reject(req.error)\n })\n}\n\nexport async function idbAddToQueue(item: ActionQueueItem): Promise<void> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(QUEUE_STORE, 'readwrite')\n tx.objectStore(QUEUE_STORE).add(item)\n tx.oncomplete = () => resolve()\n tx.onerror = () => reject(tx.error)\n })\n}\n\nexport async function idbGetQueue(): Promise<ActionQueueItem[]> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(QUEUE_STORE, 'readonly')\n const req = tx.objectStore(QUEUE_STORE).getAll()\n req.onsuccess = () => resolve(req.result as ActionQueueItem[])\n req.onerror = () => reject(req.error)\n })\n}\n\nexport async function idbUpdateQueueItem(\n id: string,\n update: Partial<ActionQueueItem>,\n): Promise<void> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(QUEUE_STORE, 'readwrite')\n const store = tx.objectStore(QUEUE_STORE)\n const get = store.get(id)\n get.onsuccess = () => {\n if (get.result) {\n store.put({ ...get.result, ...update })\n } else if (import.meta.env.DEV) {\n console.warn(`[eidos] idbUpdateQueueItem: item \"${id}\" not found — store/IDB may have diverged`)\n }\n }\n tx.oncomplete = () => resolve()\n tx.onerror = () => reject(tx.error)\n })\n}\n\nexport async function idbRemoveFromQueue(id: string): Promise<void> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(QUEUE_STORE, 'readwrite')\n tx.objectStore(QUEUE_STORE).delete(id)\n tx.oncomplete = () => resolve()\n tx.onerror = () => reject(tx.error)\n })\n}\n\n// Uses the status index to fetch only pending/failed items — avoids a full\n// table scan when the queue has many succeeded/replaying entries.\nexport async function idbGetPendingItems(): Promise<ActionQueueItem[]> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(QUEUE_STORE, 'readonly')\n const index = tx.objectStore(QUEUE_STORE).index('status')\n const results: ActionQueueItem[] = []\n\n let done = 0\n function finish(err?: DOMException | null) {\n if (err) { reject(err); return }\n if (++done === 2) resolve(results)\n }\n\n const pendingReq = index.openCursor(IDBKeyRange.only('pending'))\n pendingReq.onsuccess = (e) => {\n const cursor = (e.target as IDBRequest<IDBCursorWithValue>).result\n if (cursor) { results.push(cursor.value as ActionQueueItem); cursor.continue() }\n else finish()\n }\n pendingReq.onerror = () => finish(pendingReq.error)\n\n const failedReq = index.openCursor(IDBKeyRange.only('failed'))\n failedReq.onsuccess = (e) => {\n const cursor = (e.target as IDBRequest<IDBCursorWithValue>).result\n if (cursor) { results.push(cursor.value as ActionQueueItem); cursor.continue() }\n else finish()\n }\n failedReq.onerror = () => finish(failedReq.error)\n })\n}\n\nexport async function idbClearQueue(): Promise<void> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(QUEUE_STORE, 'readwrite')\n tx.objectStore(QUEUE_STORE).clear()\n tx.oncomplete = () => resolve()\n tx.onerror = () => reject(tx.error)\n })\n}\n"],"names":["DB_NAME","QUEUE_STORE","_db","openDB","resolve","reject","req","event","db","store","idbAddToQueue","item","tx","idbGetQueue","idbUpdateQueueItem","id","update","get","idbRemoveFromQueue","idbGetPendingItems","index","results","done","finish","err","pendingReq","e","cursor","failedReq","idbClearQueue"],"mappings":"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"}
1
+ {"version":3,"file":"idb.js","sources":["../src/idb.ts"],"sourcesContent":["import type { ActionQueueItem } from './types'\nimport type { QueueStorage } from './queue-storage'\n\nconst DB_NAME = 'eidos'\nconst DB_VERSION = 1\nconst QUEUE_STORE = 'action-queue'\n\nlet _db: IDBDatabase | null = null\n\nfunction openDB(): Promise<IDBDatabase> {\n if (_db) return Promise.resolve(_db)\n\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(DB_NAME, DB_VERSION)\n\n req.onupgradeneeded = (event) => {\n const db = (event.target as IDBOpenDBRequest).result\n if (!db.objectStoreNames.contains(QUEUE_STORE)) {\n const store = db.createObjectStore(QUEUE_STORE, { keyPath: 'id' })\n store.createIndex('status', 'status', { unique: false })\n store.createIndex('actionId', 'actionId', { unique: false })\n }\n }\n\n req.onsuccess = () => {\n _db = req.result\n resolve(req.result)\n }\n\n req.onerror = () => reject(req.error)\n })\n}\n\nexport async function idbAddToQueue(item: ActionQueueItem): Promise<void> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(QUEUE_STORE, 'readwrite')\n tx.objectStore(QUEUE_STORE).add(item)\n tx.oncomplete = () => resolve()\n tx.onerror = () => reject(tx.error)\n })\n}\n\nexport async function idbGetQueue(): Promise<ActionQueueItem[]> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(QUEUE_STORE, 'readonly')\n const req = tx.objectStore(QUEUE_STORE).getAll()\n req.onsuccess = () => resolve(req.result as ActionQueueItem[])\n req.onerror = () => reject(req.error)\n })\n}\n\nexport async function idbUpdateQueueItem(\n id: string,\n update: Partial<ActionQueueItem>,\n): Promise<void> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(QUEUE_STORE, 'readwrite')\n const store = tx.objectStore(QUEUE_STORE)\n const get = store.get(id)\n get.onsuccess = () => {\n if (get.result) {\n store.put({ ...get.result, ...update })\n } else if (import.meta.env.DEV) {\n console.warn(`[eidos] idbUpdateQueueItem: item \"${id}\" not found — store/IDB may have diverged`)\n }\n }\n tx.oncomplete = () => resolve()\n tx.onerror = () => reject(tx.error)\n })\n}\n\nexport async function idbRemoveFromQueue(id: string): Promise<void> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(QUEUE_STORE, 'readwrite')\n tx.objectStore(QUEUE_STORE).delete(id)\n tx.oncomplete = () => resolve()\n tx.onerror = () => reject(tx.error)\n })\n}\n\n// Uses the status index to fetch only pending/failed items — avoids a full\n// table scan when the queue has many succeeded/replaying entries.\nexport async function idbGetPendingItems(): Promise<ActionQueueItem[]> {\n const db = await openDB()\n\n function cursorToArray(status: string): Promise<ActionQueueItem[]> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(QUEUE_STORE, 'readonly')\n const index = tx.objectStore(QUEUE_STORE).index('status')\n const items: ActionQueueItem[] = []\n const req = index.openCursor(IDBKeyRange.only(status))\n req.onsuccess = (e) => {\n const cursor = (e.target as IDBRequest<IDBCursorWithValue>).result\n if (cursor) { items.push(cursor.value as ActionQueueItem); cursor.continue() }\n else resolve(items)\n }\n req.onerror = () => reject(req.error)\n })\n }\n\n const [pending, failed] = await Promise.all([\n cursorToArray('pending'),\n cursorToArray('failed'),\n ])\n return [...pending, ...failed]\n}\n\nexport async function idbClearQueue(): Promise<void> {\n const db = await openDB()\n return new Promise((resolve, reject) => {\n const tx = db.transaction(QUEUE_STORE, 'readwrite')\n tx.objectStore(QUEUE_STORE).clear()\n tx.oncomplete = () => resolve()\n tx.onerror = () => reject(tx.error)\n })\n}\n\n/** IndexedDB-backed QueueStorage implementation (default for browser environments). */\nexport const idbQueueStorage: QueueStorage = {\n add: idbAddToQueue,\n getAll: idbGetQueue,\n getPending: idbGetPendingItems,\n update: idbUpdateQueueItem,\n remove: idbRemoveFromQueue,\n clear: idbClearQueue,\n}\n"],"names":["DB_NAME","QUEUE_STORE","_db","openDB","resolve","reject","req","event","db","store","idbAddToQueue","item","tx","idbGetQueue","idbUpdateQueueItem","id","update","get","idbRemoveFromQueue","idbGetPendingItems","cursorToArray","status","index","items","e","cursor","pending","failed","idbClearQueue"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -75,9 +75,34 @@ export declare interface ActionQueueItem {
75
75
  nextRetryAt?: number;
76
76
  }
77
77
 
78
+ /** Minimal subset of @react-native-async-storage/async-storage (or any compatible key-value store). */
79
+ export declare interface AsyncStorageLike {
80
+ getItem(key: string): Promise<string | null>;
81
+ setItem(key: string, value: string): Promise<void>;
82
+ removeItem(key: string): Promise<void>;
83
+ }
84
+
85
+ /**
86
+ * QueueStorage implementation backed by any AsyncStorage-compatible API.
87
+ * Pass the AsyncStorage singleton from @react-native-async-storage/async-storage
88
+ * (or MMKV, SQLite, or any store that satisfies AsyncStorageLike).
89
+ */
90
+ export declare class AsyncStorageQueueStorage implements QueueStorage {
91
+ private readonly storage;
92
+ constructor(storage: AsyncStorageLike);
93
+ private readAll;
94
+ private writeAll;
95
+ add(item: ActionQueueItem): Promise<void>;
96
+ getAll(): Promise<ActionQueueItem[]>;
97
+ getPending(): Promise<ActionQueueItem[]>;
98
+ update(id: string, patch: Partial<ActionQueueItem>): Promise<void>;
99
+ remove(id: string): Promise<void>;
100
+ clear(): Promise<void>;
101
+ }
102
+
78
103
  export declare type CacheStrategy = 'cache-first' | 'stale-while-revalidate' | 'network-first';
79
104
 
80
- /** Remove all items from the action queue (IDB + in-memory store). */
105
+ /** Remove all items from the action queue (storage + in-memory store). */
81
106
  export declare function clearQueue(): Promise<void>;
82
107
 
83
108
  /**
@@ -191,6 +216,8 @@ export declare interface GeneratedStrategy {
191
216
  equivalentCode: string;
192
217
  }
193
218
 
219
+ export declare function _getQueueStorage(): QueueStorage | null;
220
+
194
221
  declare function _getState(): EidosStore;
195
222
 
196
223
  export declare function initEidos(config?: EidosConfig): Promise<void>;
@@ -207,6 +234,15 @@ export declare interface QueuedResult {
207
234
  readonly message: string;
208
235
  }
209
236
 
237
+ export declare interface QueueStorage {
238
+ add(item: ActionQueueItem): Promise<void>;
239
+ getAll(): Promise<ActionQueueItem[]>;
240
+ getPending(): Promise<ActionQueueItem[]>;
241
+ update(id: string, patch: Partial<ActionQueueItem>): Promise<void>;
242
+ remove(id: string): Promise<void>;
243
+ clear(): Promise<void>;
244
+ }
245
+
210
246
  export declare function replayQueue(): Promise<ReplayResult>;
211
247
 
212
248
  /** Summary returned by replayQueue(). */
@@ -273,6 +309,9 @@ export declare function setOfflineSimulation(enabled: boolean): void;
273
309
 
274
310
  /* Excluded from this release type: setQueryInvalidator */
275
311
 
312
+ /** Override the default IndexedDB queue with a custom storage backend (e.g. AsyncStorage for React Native). */
313
+ export declare function setQueueStorage(s: QueueStorage): void;
314
+
276
315
  declare function _subscribe(listener: Listener): () => void;
277
316
 
278
317
  /** Full Eidos store — prefer the narrower hooks below for performance. */
@@ -333,7 +372,7 @@ export declare const useEidosStore: {
333
372
  setState: (partial: Partial<EidosStore> | ((s: EidosStore) => Partial<EidosStore>)) => void;
334
373
  };
335
374
 
336
- export declare const VERSION = "1.0.30";
375
+ export declare const VERSION = "1.0.31";
337
376
 
338
377
  /**
339
378
  * Bulk-prefetch an array of resource handles concurrently, warming the cache
package/dist/index.js CHANGED
@@ -1,39 +1,44 @@
1
- import { resource as s, setQueryInvalidator as r, warmCache as i } from "./resource.js";
2
- import { action as t, clearQueue as d, replayQueue as a } from "./action.js";
3
- import { _resetEidos as p, initEidos as f } from "./runtime.js";
4
- import { EidosProvider as c } from "./react/Provider.js";
5
- import { useEidos as S, useEidosAction as x, useEidosOnDrain as Q, useEidosQueue as l, useEidosQueueStats as R, useEidosResource as y, useEidosResources as O, useEidosStatus as v } from "./react/hooks.js";
6
- import { VERSION as I } from "./version.js";
7
- import { isBgSyncSupported as h, setOfflineSimulation as w } from "./sw-bridge.js";
8
- import { useEidosStore as C } from "./store.js";
9
- import { eidosAction as N, eidosQueue as P, eidosQueueStats as V, eidosResource as _, eidosStatus as b, eidosStore as j } from "./stores.js";
1
+ import { resource as r, setQueryInvalidator as s, warmCache as t } from "./resource.js";
2
+ import { action as i, clearQueue as d, replayQueue as a } from "./action.js";
3
+ import { _resetEidos as S, initEidos as f } from "./runtime.js";
4
+ import { _getQueueStorage as E, setQueueStorage as c } from "./queue-storage.js";
5
+ import { AsyncStorageQueueStorage as x } from "./async-storage-adapter.js";
6
+ import { EidosProvider as g } from "./react/Provider.js";
7
+ import { useEidos as y, useEidosAction as R, useEidosOnDrain as A, useEidosQueue as O, useEidosQueueStats as v, useEidosResource as I, useEidosResources as _, useEidosStatus as h } from "./react/hooks.js";
8
+ import { VERSION as B } from "./version.js";
9
+ import { isBgSyncSupported as D, setOfflineSimulation as N } from "./sw-bridge.js";
10
+ import { useEidosStore as V } from "./store.js";
11
+ import { eidosAction as j, eidosQueue as k, eidosQueueStats as q, eidosResource as z, eidosStatus as F, eidosStore as G } from "./stores.js";
10
12
  export {
11
- c as EidosProvider,
12
- I as VERSION,
13
- p as _resetEidos,
14
- t as action,
13
+ x as AsyncStorageQueueStorage,
14
+ g as EidosProvider,
15
+ B as VERSION,
16
+ E as _getQueueStorage,
17
+ S as _resetEidos,
18
+ i as action,
15
19
  d as clearQueue,
16
- N as eidosAction,
17
- P as eidosQueue,
18
- V as eidosQueueStats,
19
- _ as eidosResource,
20
- b as eidosStatus,
21
- j as eidosStore,
20
+ j as eidosAction,
21
+ k as eidosQueue,
22
+ q as eidosQueueStats,
23
+ z as eidosResource,
24
+ F as eidosStatus,
25
+ G as eidosStore,
22
26
  f as initEidos,
23
- h as isBgSyncSupported,
27
+ D as isBgSyncSupported,
24
28
  a as replayQueue,
25
- s as resource,
26
- w as setOfflineSimulation,
27
- r as setQueryInvalidator,
28
- S as useEidos,
29
- x as useEidosAction,
30
- Q as useEidosOnDrain,
31
- l as useEidosQueue,
32
- R as useEidosQueueStats,
33
- y as useEidosResource,
34
- O as useEidosResources,
35
- v as useEidosStatus,
36
- C as useEidosStore,
37
- i as warmCache
29
+ r as resource,
30
+ N as setOfflineSimulation,
31
+ s as setQueryInvalidator,
32
+ c as setQueueStorage,
33
+ y as useEidos,
34
+ R as useEidosAction,
35
+ A as useEidosOnDrain,
36
+ O as useEidosQueue,
37
+ v as useEidosQueueStats,
38
+ I as useEidosResource,
39
+ _ as useEidosResources,
40
+ h as useEidosStatus,
41
+ V as useEidosStore,
42
+ t as warmCache
38
43
  };
39
44
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
@@ -0,0 +1,12 @@
1
+ let e = null;
2
+ function u(t) {
3
+ e = t;
4
+ }
5
+ function n() {
6
+ return e;
7
+ }
8
+ export {
9
+ n as _getQueueStorage,
10
+ u as setQueueStorage
11
+ };
12
+ //# sourceMappingURL=queue-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-storage.js","sources":["../src/queue-storage.ts"],"sourcesContent":["import type { ActionQueueItem } from './types'\n\nexport interface QueueStorage {\n add(item: ActionQueueItem): Promise<void>\n getAll(): Promise<ActionQueueItem[]>\n getPending(): Promise<ActionQueueItem[]>\n update(id: string, patch: Partial<ActionQueueItem>): Promise<void>\n remove(id: string): Promise<void>\n clear(): Promise<void>\n}\n\nlet _storage: QueueStorage | null = null\n\n/** Override the default IndexedDB queue with a custom storage backend (e.g. AsyncStorage for React Native). */\nexport function setQueueStorage(s: QueueStorage): void {\n _storage = s\n}\n\nexport function _getQueueStorage(): QueueStorage | null {\n return _storage\n}\n"],"names":["_storage","setQueueStorage","s","_getQueueStorage"],"mappings":"AAWA,IAAIA,IAAgC;AAG7B,SAASC,EAAgBC,GAAuB;AACrD,EAAAF,IAAWE;AACb;AAEO,SAASC,IAAwC;AACtD,SAAOH;AACT;"}
@@ -0,0 +1,23 @@
1
+ import { default as React } from 'react';
2
+
3
+ export interface EidosProviderRNProps {
4
+ children: React.ReactNode;
5
+ /**
6
+ * Current network connectivity state.
7
+ * Pass the value from `useNetInfo()` (@react-native-community/netinfo).
8
+ * Defaults to `true` if omitted.
9
+ *
10
+ * @example
11
+ * const netInfo = useNetInfo()
12
+ * <EidosProviderRN isConnected={netInfo.isConnected ?? true}>
13
+ */
14
+ isConnected?: boolean;
15
+ }
16
+ /**
17
+ * Connectivity bridge for React Native.
18
+ * Syncs the network state into the Eidos store so `initEidosRN`'s autoReplay
19
+ * subscription fires when the device comes back online.
20
+ *
21
+ * Render this near the root of your app, after calling `initEidosRN()`.
22
+ */
23
+ export declare function EidosProviderRN({ children, isConnected }: EidosProviderRNProps): React.JSX.Element;
@@ -0,0 +1,8 @@
1
+ export { EidosProviderRN } from './react/ProviderRN';
2
+ export type { EidosProviderRNProps } from './react/ProviderRN';
3
+ export { initEidosRN, _resetEidosRN } from './runtime-rn';
4
+ export type { EidosRNConfig } from './runtime-rn';
5
+ export { setQueueStorage } from './index.ts';
6
+ export type { QueueStorage } from './index.ts';
7
+ export { AsyncStorageQueueStorage } from './index.ts';
8
+ export type { AsyncStorageLike } from './index.ts';
@@ -0,0 +1,59 @@
1
+ import { jsx, Fragment } from "react/jsx-runtime";
2
+ import { useRef, useEffect } from "react";
3
+ import { useEidosStore, AsyncStorageQueueStorage, setQueueStorage, replayQueue } from "@sweidos/eidos";
4
+ import { AsyncStorageQueueStorage as AsyncStorageQueueStorage2, setQueueStorage as setQueueStorage2 } from "@sweidos/eidos";
5
+ function EidosProviderRN({ children, isConnected }) {
6
+ const prevRef = useRef(void 0);
7
+ useEffect(() => {
8
+ const online = isConnected !== false;
9
+ if (online !== prevRef.current) {
10
+ prevRef.current = online;
11
+ useEidosStore.getState().setOnline(online);
12
+ }
13
+ }, [isConnected]);
14
+ return /* @__PURE__ */ jsx(Fragment, { children });
15
+ }
16
+ let _initialized = false;
17
+ let _unsubscribe = null;
18
+ async function initEidosRN(config) {
19
+ if (_initialized) return;
20
+ _initialized = true;
21
+ const { storage, autoReplay = true } = config;
22
+ const queueStorage = new AsyncStorageQueueStorage(storage);
23
+ setQueueStorage(queueStorage);
24
+ try {
25
+ const persisted = await queueStorage.getAll();
26
+ if (persisted.length > 0) {
27
+ useEidosStore.getState().hydrateQueue(persisted);
28
+ }
29
+ } catch {
30
+ }
31
+ if (autoReplay) {
32
+ let prevIsOnline = useEidosStore.getState().isOnline;
33
+ _unsubscribe = useEidosStore.subscribe(() => {
34
+ const { isOnline } = useEidosStore.getState();
35
+ const justCameOnline = isOnline && !prevIsOnline;
36
+ prevIsOnline = isOnline;
37
+ if (justCameOnline) {
38
+ setTimeout(replayQueue, 600);
39
+ }
40
+ });
41
+ const store = useEidosStore.getState();
42
+ const hasPending = store.queue.some((q) => q.status === "pending" || q.status === "failed");
43
+ if (store.isOnline && hasPending) {
44
+ setTimeout(replayQueue, 1200);
45
+ }
46
+ }
47
+ }
48
+ function _resetEidosRN() {
49
+ _unsubscribe == null ? void 0 : _unsubscribe();
50
+ _unsubscribe = null;
51
+ _initialized = false;
52
+ }
53
+ export {
54
+ AsyncStorageQueueStorage2 as AsyncStorageQueueStorage,
55
+ EidosProviderRN,
56
+ _resetEidosRN,
57
+ initEidosRN,
58
+ setQueueStorage2 as setQueueStorage
59
+ };
package/dist/resource.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import { useEidosStore as h } from "./store.js";
2
2
  import { sendToWorker as g } from "./sw-bridge.js";
3
- const p = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map();
3
+ const p = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map();
4
4
  let m = null;
5
- function N(e) {
5
+ function q(e) {
6
6
  m = e;
7
7
  }
8
8
  function l(e) {
9
9
  return e.includes("*") || /:[^/]+/.test(e);
10
10
  }
11
- function k(e) {
11
+ function E(e) {
12
12
  return "^" + e.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, ".+").replace(/\*/g, "[^/]+").replace(/:[^/]+/g, "[^/]+") + "$";
13
13
  }
14
14
  function w(e, a) {
@@ -16,10 +16,10 @@ function w(e, a) {
16
16
  `[eidos] resource('${e}') is a URL pattern — ${a}() is not supported on pattern handles. The SW intercepts matching requests automatically; call fetch(specificUrl) directly in your app code.`
17
17
  );
18
18
  }
19
- function q(e, a) {
19
+ function A(e, a) {
20
20
  if (p.has(e))
21
21
  return p.get(e);
22
- const s = E(e, a), t = l(e) ? k(e) : void 0, o = {
22
+ const s = S(e, a), t = l(e) ? E(e) : void 0, o = {
23
23
  url: e,
24
24
  config: a,
25
25
  strategy: s,
@@ -40,10 +40,10 @@ function q(e, a) {
40
40
  strategy: s,
41
41
  fetch: async () => {
42
42
  if (l(e)) throw w(e, "fetch");
43
- const r = y.get(e);
43
+ const r = v.get(e);
44
44
  if (r) return r.then((n) => n.clone());
45
- const i = S(e, a, s);
46
- return y.set(e, i), i.finally(() => y.delete(e)).catch(() => {
45
+ const i = k(e, a, s);
46
+ return v.set(e, i), i.finally(() => v.delete(e)).catch(() => {
47
47
  }), i.then((n) => n.clone());
48
48
  },
49
49
  json: async () => {
@@ -68,8 +68,8 @@ function q(e, a) {
68
68
  const i = await r.keys(), n = t ? new RegExp(t) : null, u = e.startsWith("http");
69
69
  await Promise.all(
70
70
  i.filter((f) => {
71
- const d = f.url, v = new URL(d).pathname;
72
- return n ? n.test(u ? d : v) : u ? d === e : d === e || v === e;
71
+ const d = f.url, y = new URL(d).pathname;
72
+ return n ? n.test(u ? d : y) : u ? d === e : d === e || y === e;
73
73
  }).map((f) => r.delete(f))
74
74
  );
75
75
  }
@@ -87,7 +87,7 @@ function q(e, a) {
87
87
  };
88
88
  return p.set(e, c), c;
89
89
  }
90
- async function S(e, a, s) {
90
+ async function k(e, a, s) {
91
91
  const t = h.getState();
92
92
  t.updateResource(e, { status: "fetching", fetchedAt: Date.now() });
93
93
  const o = await caches.open(s.cacheName).catch(() => null);
@@ -136,13 +136,16 @@ async function S(e, a, s) {
136
136
  throw t.updateResource(e, { status: "error" }), c;
137
137
  }
138
138
  }
139
- function E(e, a) {
139
+ function S(e, a) {
140
140
  const s = a.strategy;
141
141
  return a.offline ? R(s ?? "stale-while-revalidate", e, a.cacheName) : R(s ?? "network-first", e, a.cacheName);
142
142
  }
143
- const x = {
143
+ const b = {
144
+ "stale-while-revalidate": "StaleWhileRevalidate",
145
+ "cache-first": "CacheFirst",
146
+ "network-first": "NetworkFirst"
147
+ }, x = {
144
148
  "stale-while-revalidate": {
145
- name: "StaleWhileRevalidate",
146
149
  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.",
147
150
  behavior: [
148
151
  "Cache hit → return immediately, kick off background revalidation",
@@ -157,7 +160,6 @@ new StaleWhileRevalidate({
157
160
  })`
158
161
  },
159
162
  "cache-first": {
160
- name: "CacheFirst",
161
163
  reasoning: "cache-first maximises speed and offline availability. Network is consulted only on cache miss. Best for static or infrequently-updated data.",
162
164
  behavior: [
163
165
  "Cache hit → return immediately, no network request made",
@@ -172,7 +174,6 @@ new CacheFirst({
172
174
  })`
173
175
  },
174
176
  "network-first": {
175
- name: "NetworkFirst",
176
177
  reasoning: "network-first prioritises fresh data. Cache acts as a safety net when offline. Best for frequently-updated resources where stale data causes problems.",
177
178
  behavior: [
178
179
  "Always try network first",
@@ -188,13 +189,19 @@ new NetworkFirst({
188
189
  }
189
190
  };
190
191
  function R(e, a, s) {
192
+ const t = x[e];
191
193
  return {
192
- ...x[e],
194
+ name: b[e],
193
195
  swStrategy: e,
194
- cacheName: s ?? "eidos-resources-v1"
196
+ cacheName: s ?? "eidos-resources-v1",
197
+ // reasoning + behavior are rendered by the playground UI from live ResourceEntry objects —
198
+ // keep them in all builds. equivalentCode is a static code block only used in DEV tools.
199
+ reasoning: t.reasoning,
200
+ behavior: t.behavior,
201
+ equivalentCode: ""
195
202
  };
196
203
  }
197
- async function A(e) {
204
+ async function _(e) {
198
205
  const a = await Promise.allSettled(e.map((t) => t.prefetch())), s = a.filter((t) => t.status === "rejected").map((t) => t.reason);
199
206
  return {
200
207
  warmed: a.filter((t) => t.status === "fulfilled").length,
@@ -203,8 +210,8 @@ async function A(e) {
203
210
  };
204
211
  }
205
212
  export {
206
- q as resource,
207
- N as setQueryInvalidator,
208
- A as warmCache
213
+ A as resource,
214
+ q as setQueryInvalidator,
215
+ _ as warmCache
209
216
  };
210
217
  //# sourceMappingURL=resource.js.map