Skip to content

feat(mobile): offline-first post feed with SQLite cache, background sync, and optimistic post creation#614

Open
Adeolu01 wants to merge 1 commit into
Epta-Node:mainfrom
Adeolu01:feat/mobile-offline-feed-cache
Open

feat(mobile): offline-first post feed with SQLite cache, background sync, and optimistic post creation#614
Adeolu01 wants to merge 1 commit into
Epta-Node:mainfrom
Adeolu01:feat/mobile-offline-feed-cache

Conversation

@Adeolu01

Copy link
Copy Markdown

closes #570

Summary

Implements an offline-first feed layer for the mobile app so the Feed screen
renders instantly from a local cache, posts can be created while offline and
synced when connectivity resumes, and optimistic posts that fail to confirm are
surfaced for retry or reconciled against the indexer.

The feature is fully self-contained under apps/mobile/src/; no existing
screens, hooks, or components were modified.

What's included

SQLite cache (apps/mobile/src/db/)

  • linkora.db schema with the posts, pending_posts, and feed_cursor
    tables as specified.
  • PostRepository exposing upsert, getPage(offset, limit), getPending,
    markSynced(local_id, contract_id), and markFailed(local_id, error), plus
    cursor and idempotency helpers.
  • Two interchangeable backends behind a single PostStore interface:
    SqlitePostStore (production) and MemoryPostStore (fallback for web/tests).
    expo-sqlite is loaded lazily and adapts both the modern async and the
    SDK-49 callback APIs, falling back to in-memory storage when the native
    module is unavailable.

Background sync (apps/mobile/src/sync/feedSync.ts)

  • FeedSyncService fetches new posts since feed_cursor, upserts them, and
    advances the cursor (cursor-based, never a full re-fetch). An empty response
    never resets progress.
  • Emits syncStarted, syncCompleted, and syncFailed events for the Feed
    screen; concurrent syncs are coalesced.
  • Periodic background sync registered via expo-background-fetch /
    expo-task-manager at a 15-minute interval, guarded so non-native
    environments are a no-op.

Optimistic post creation and conflict resolution

  • New posts are persisted to pending_posts immediately (for a "sending…"
    card) and submitted on chain in the background via an injected submit
    function; on success they are promoted to posts under the contract-assigned
    id, on failure marked failed for the retry UI.
  • Stale pending posts (>24h offline) are reconciled by idempotency check
    (author + content within a 24h window) so already-confirmed posts are marked
    synced without re-submitting.
  • useOfflineFeed hook composes the repository and sync service for a
    cache-first Feed screen.

Tests

Adds 23 tests covering: feed renders from cache when offline, optimistic post
appears immediately and transitions to confirmed, failed post shows retry and
re-submits, and cursor-based incremental sync. All existing mobile tests
continue to pass (17 suites, 81 tests, 16 snapshots).

Notes

Adds expo-sqlite, expo-background-fetch, and expo-task-manager (Expo SDK
49 compatible) to the mobile package, and includes src/** in the mobile
tsconfig.

@vercel

vercel Bot commented Jun 24, 2026

Copy link
Copy Markdown

@Adeolu01 is attempting to deploy a commit to the Jaja's projects Team on Vercel.

A member of the Team first needs to authorize it.

@devJaja devJaja self-requested a review June 25, 2026 05:29
@devJaja

devJaja commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Resolve the conflicts @Adeolu01

@devJaja

devJaja commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

@Adeolu01 Resolve the conflicts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(mobile): implement offline-first post feed with SQLite cache, background sync, optimistic post creation, and conflict resolution

2 participants