Skip to content

feat: offline-first capabilities — transaction queue, SW caching, background sync (#483) - #617

Merged
Topmatrixmor2014 merged 3 commits into
FinChippay:mainfrom
ZuLu0890:feat/offline-first-483-v2
Sep 4, 2026
Merged

feat: offline-first capabilities — transaction queue, SW caching, background sync (#483)#617
Topmatrixmor2014 merged 3 commits into
FinChippay:mainfrom
ZuLu0890:feat/offline-first-483-v2

Conversation

@ZuLu0890

Copy link
Copy Markdown
Contributor

Summary

Implements Issue #483 — Offline-First Capabilities Enhancement: offline transaction queuing with IndexedDB persistence, strategic service-worker caching, an offline transaction composer, background sync, and connectivity-aware UI.

What was built — mapped to the acceptance criteria

  • Transactions composed offline are queued in IndexedDB and survive page reloads
    frontend/lib/offlineQueue.ts is rewritten around a generic, fully-typed IndexedDB-backed queue. Entry shape is { id, type, payload, createdAt, status: 'pending' | 'processing' | 'failed', retryCount }, with the API enqueue(type, payload), dequeue(), peek(), remove(id), getAll(), getFailed(). Persistence across reloads is covered by unit tests that reset the module and re-read from IndexedDB.

  • Service worker caches static assets and serves them offline
    frontend/public/sw.js uses a cache-first strategy for static assets (app shell: JS/CSS/images/fonts) with cache versioning (CACHE_VERSION) and cleanup of stale caches on activate.

  • API responses (balance, transactions) are cached and served offline
    Network-first with cache fallback for balance and transactions API responses; stale-while-revalidate for price feeds.

  • Background sync automatically processes the queue when online
    A sync event listener on the process-transaction-queue tag drains the queue in FIFO order. registerQueueSync() registers the tag, and useNetworkStatus re-registers sync and triggers processing on reconnection (with a main-thread fallback for browsers without the Background Sync API).

  • Failed transactions show in queue with retry status
    Max 3 retries per entry with exponential backoff (backoffDelayMs). getFailed() plus per-item status in the composer surface failures and retry state.

  • OfflineBanner shows pending queue count
    getQueueCount() is unified to include the new generic queue, so the existing OfflineBanner (which already consumed getQueueCount()) reflects pending generic entries with no props-contract change.

  • e2e tests cover the offline → online transition
    frontend/e2e/offline.spec.ts extended with an offline → compose → queue → online → auto-submit flow.

  • Tests
    frontend/__tests__/offlineQueue.test.ts extended to 31 tests covering enqueue/dequeue ordering, retry + backoff, persistence across simulated reloads, malformed legacy entries, and failure states. All 31 pass locally.

⚠️ "All existing tests pass" — see CI notes below; the repo baseline has pre-existing test/type-check failures unrelated to this change.

Files changed

File Change
frontend/lib/offlineQueue.ts Generic IndexedDB queue + retry/backoff + sync; legacy XDR API retained for back-compat
frontend/public/sw.js Cache strategies, versioning + cleanup, /offline fallback, process-transaction-queue sync drain
frontend/components/OfflineTransactionComposer.tsx New — offline send form with local address validation, queue status, retry/remove
frontend/components/TransactionList.tsx Queued-item badge (no props change)
frontend/hooks/useNetworkStatus.ts Queue count + reconnection processing + auto-submit toast
frontend/pages/offline.tsx New — offline fallback page
frontend/__tests__/offlineQueue.test.ts Extended to 31 tests
frontend/e2e/offline.spec.ts Offline → compose → queue → online → auto-submit
frontend/jest.config.ts Correct @stellar/stellar-sdk mapping to its v16 CJS entry (lib/cjs/index.js)

Scope exclusions

Per the issue's Out of Scope: no offline transaction signing (requires Freighter) and no offline contract interactions. Legacy signed-XDR queue behavior (submit-payments) is preserved unchanged.

How to test (manual)

  1. npm run dev and open the app.
  2. DevTools → Network → set throttling to Offline.
  3. Compose a transaction in the offline composer — it validates locally, enqueues, and shows a live pending count with per-item status.
  4. Reload the page — the queued entry survives (IndexedDB persistence).
  5. Restore connectivity — background sync / the reconnection handler auto-submits the queue and shows a confirmation toast.

Screenshots / GIF

CI notes (pre-existing, unrelated to #483)

The following checks fail on the current main baseline (verified locally) and are not introduced by this PR:

  • npm run type-check — 223 pre-existing TS errors across many files (stale APIs, renamed exports, type drift).
  • npm test — ~29 pre-existing failing suites: @stellar/stellar-sdk v16 depends on ESM-only @noble/* packages that Jest (CommonJS) can't parse, plus stale test mocks/fixtures. (This PR includes the correct lib/cjs/index.js mapping fix; the remaining @noble ESM transform requires a separate babel/jest config change.)
  • npm run build-storybook — Storybook's Next.js plugin can't find next/dist/build/webpack/plugins/define-env-plugin.js (Next 16 incompatibility).

What passes: npm run lint (0 errors), npm run i18n:check, npm run build, and the 31 new/extended offlineQueue unit tests.

Closes #483

The moduleNameMapper pointed at lib/index.js, which no longer exists in
@stellar/stellar-sdk v16 (entries now live under lib/cjs and lib/esm).
Point it at lib/cjs/index.js so Jest can resolve the SDK.
@github-actions github-actions Bot added the needs-review PR ready for Greptile AI code review label Aug 19, 2026
@Topmatrixmor2014
Topmatrixmor2014 merged commit a40f1ed into FinChippay:main Sep 4, 2026
23 checks passed
@grantfox-oss grantfox-oss Bot mentioned this pull request Sep 4, 2026
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-review PR ready for Greptile AI code review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Offline-First Capabilities Enhancement

2 participants