Skip to content

feat(pwa): installable offline PWA with cached feed and consented updates - #562

Merged
james2177 merged 4 commits into
stellar-vortex-protocol:mainfrom
josunday002:drips/500-501-503
Sep 30, 2026
Merged

james2177 merged 4 commits into
stellar-vortex-protocol:mainfrom
josunday002:drips/500-501-503

Conversation

@josunday002

Copy link
Copy Markdown

Summary

feat(pwa): installable offline PWA with cached feed and consented updates

What was solved

#500 — [High] Deliver an installable, offline-capable PWA with a service worker, maskable icons and shortcuts

Deliver a production-ready, installable offline-capable PWA: add a service worker with a strict allowlist of cacheable public GET requests (stale-while-revalidate), network-first HTML, precached app shell, cache versioning/cleanup and size/expiry limits; expand manifest.ts with PNG + maskable icons, shortcuts, screenshots, categories, id, scope and localised names; add an offline fallback page and wire it into ConnectivityBanner with an 'offline — last updated X' state that blocks (never queues) submissions; and add a user-consented 'New version available — Reload' update flow with skipWaiting gated behind consent, SW registered only in production with worker-src 'self' CSP.

Addressed:

  • Changed: src/app/manifest.ts, src/components/ConnectivityBanner.tsx, next.config.mjs
  • Service worker with precache of app shell + static assets, stale-while-revalidate for read-only public API GETs, network-first for HTML, cache versioning and cleanup, and size/expiry limits
  • Strict allowlist of cacheable request patterns (public GETs only); never cache POST/signing or authenticated/user-specific data; cache keys include API origin
  • Manifest: PNG icons (192/512 + maskable), shortcuts (Swap, Explore, My Intents), screenshots, categories, id, scope, localised names; passes Lighthouse PWA installability checks

#501 — [High] Optimize rendering and hydration: Server Components for static shells, streaming with Suspense and reduced client boundaries

Restructure the app so static shells (Nav, Footer, headings/copy, layout) render as Server Components while interactive wallet widgets remain client islands; add server-side data prefetch with SWR fallback, Suspense boundaries with skeletons, and per-route loading.tsx/error.tsx for analytics/governance/contributors; document the pattern in docs/performance.md and docs/architecture.md; verify hydration cleanliness via a Playwright console-error assertion.

Addressed:

  • Changed: src/app/analytics/page.tsx, src/app/governance/page.tsx, src/app/contributors/page.tsx
  • Audit client boundaries and document them in a table in docs/performance.md
  • Move Nav (where possible), Footer, headings/copy and static layout to Server Components; keep wallet/interactive widgets as client islands
  • Server-side fetch (with revalidate) for public read endpoints on Explore/Analytics/Governance initial payloads, hydrated into SWR via fallback (no double fetch, no waterfalls)

#503 — [High] Profile and eliminate re-render storms from WebSocket streams with batching, transitions and render-count tests

Eliminate WebSocket-driven re-render storms by batching message ingestion per animation frame (with timer fallback for background tabs), memoising row components with stable props, using startTransition/useDeferredValue for heavy views, and adding a React Profiler-based render-count test harness plus a dev-only perf overlay. Scope is limited to the live-intent hooks, realtime batcher utility, ActivityFeed/Explore/My Intents/Analytics views, and new test helpers; worker-based analytics is explicitly out of scope.

Addressed:

  • Changed: src/hooks/useLiveIntents.ts, src/hooks/useIntentFeed.ts, src/hooks/useMyLiveIntents.ts
  • Batch WebSocket message ingestion within a frame using requestAnimationFrame/microtask with a max-latency fallback so bursts commit once per frame
  • Provide a testable createBatcher(flush, {maxLatencyMs}) utility in the realtime layer, unit-tested with fake timers
  • Handle background tabs where rAF is paused by falling back to timers with visibility handling, preserving ordering across batches and bounding queue memory

Changes

  • src/app/manifest.ts (modify)
  • src/app/analytics/page.tsx (modify)
  • next.config.mjs (modify)
  • src/components/ConnectivityBanner.tsx (modify)
  • src/app/governance/page.tsx (modify)
  • src/app/contributors/page.tsx (modify)
  • src/hooks/useMyLiveIntents.ts (modify)
  • src/hooks/useLiveIntents.ts (modify)
  • src/hooks/useIntentFeed.ts (modify)

Approach

  1. [High] Deliver an installable, offline-capable PWA with a service worker, maskable icons and shortcuts #500 — [High] Deliver an installable, offline-capable PWA with a service worker, maskable icons and shortcuts (Changed: src/app/manifest.ts, src/components/ConnectivityBanner.tsx, next.config.mjs)
  2. [High] Optimize rendering and hydration: Server Components for static shells, streaming with Suspense and reduced client boundaries #501 — [High] Optimize rendering and hydration: Server Components for static shells, streaming with Suspense and reduced client boundaries (Changed: src/app/analytics/page.tsx, src/app/governance/page.tsx, src/app/contributors/page.tsx)
  3. [High] Profile and eliminate re-render storms from WebSocket streams with batching, transitions and render-count tests #503 — [High] Profile and eliminate re-render storms from WebSocket streams with batching, transitions and render-count tests (Changed: src/hooks/useLiveIntents.ts, src/hooks/useIntentFeed.ts, src/hooks/useMyLiveIntents.ts)

Issues

Closes #500
Closes #501
Closes #503

@drips-wave

drips-wave Bot commented Sep 29, 2026

Copy link
Copy Markdown

@josunday002 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

# Conflicts:
#	next.config.mjs
#	src/app/contributors/page.tsx
#	src/components/ConnectivityBanner.tsx
#	src/hooks/useIntentFeed.ts
#	src/hooks/useLiveIntents.ts
#	src/hooks/useMyLiveIntents.ts
@james2177
james2177 merged commit 5dd2e59 into stellar-vortex-protocol:main Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment