core api
These cards keep one idea per surface so the mental model stays lightweight.
Register a GET endpoint as offline-capable and let Eidos pick the cache strategy.
offline: true to enable fetch interception and cache persistence.strategy only when you want to force a specific cache policy.maxAge when the data should refresh after a short TTL.const products = resource('/api/products', { offline: true,})
const data = await products.json<Product[]>()Wrap async mutations so offline writes are persisted and replayed later.
reliability: "neverLose" when dropping a write would be painful.name so replay can find them after refresh.maxRetries when you need a shorter or longer retry window.onOptimistic updates the UI instantly; onRollback reverts if the action permanently fails.const createOrder = action( async (payload: OrderPayload) => { const res = await fetch('/api/orders', { method: 'POST', body: JSON.stringify(payload), }) return res.json() }, { reliability: 'neverLose', name: 'createOrder', onOptimistic: (payload) => addOptimisticOrder(payload), onRollback: (payload) => removeOptimisticOrder(payload), },)Register the SW and hydrate the runtime once near the root of the app.
swPath if the worker lives somewhere other than /eidos-sw.js.autoReplay on unless you want full manual control of queue replay.<EidosProvider swPath="/eidos-sw.js" autoReplay> <App /></EidosProvider>Trigger queue replay yourself when you want a manual recovery action.
const result = await replayQueue()// { attempted, succeeded, failed, retrying, skipped }Decide what happens when a queued write replays against state that has since changed.
serverWins drops the queued item; clientWins keeps retrying.merge / custom call resolve(ctx) with the error, args, and attempt count.{ resolved: args } to rewrite the queued write and retry, or 'skip' to drop it.action(reserveStock, { reliability: 'neverLose', name: 'reserveStock', conflict: { strategy: 'custom', resolve: ({ error, args }) => { if (error instanceof StockConflictError) { const [payload] = args return { resolved: [{ ...payload, quantity: error.available }] } } return 'skip' }, },})