diff --git a/AGENTS.md b/AGENTS.md index 6390204..87380e1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -763,6 +763,25 @@ session with **no other memory of this project**. So: returns). The relay probe still gates the **"nothing at all" card** (`relayUnreachable = !online || relay.status === 'offline'`), and both retries now call `refetchSpots()` **and** `relay.recheck()`. + - **Offline WRITE queue is now real (2026-09-29).** `lib/offlineCache` already + had a `pendingPosts` table + `useSyncPendingPosts`/`useQueuePost` + an + `OfflineIndicator` badge, but **nothing ever called `queuePost`** — offline + writes just threw. Now: **`useNostrPublish` queues on `isOffline()` (skipping + the 15s publish timeout) or when every relay fails**, storing the + **already-SIGNED event** (`queueSignedEvent`) so an interactive signer is + **never re-prompted at sync time**; `useSyncPendingPosts` publishes it + directly (`nostr.event`), **not** through `useNostrPublish` (which would + re-queue and duplicate), re-signing only legacy unsigned entries. Rules: + **supersede** — a new replaceable (0/3/10000+) or addressable (30000+) event + drops the older queued one; **TTL** — ephemeral kinds (`2259` spot status, + `24899` spot chat) are pruned after 15 min (late "I'm here" is worse than + none); **cap** 100; `getPendingPosts` returns `pending` **and** retryable + `failed` (a single failure must not strand an action) and the count includes + both; a **module-level `globalSyncing` lock** keeps ONE publisher even though + `OfflineIndicator` (which owns the sync) is mounted twice; retries every 30s + while offline→online. ⚠️ `useNostrPublish` now **resolves** (instead of + throwing) when it queues — callers show their success toast, corrected by a + global "Saved offline" toast + the badge. - **Offline map tiles (done 2026-09-28):** `lib/tileCache.ts` (Dexie `SkateSpotsTilesDB`, bounded: ≤3000 tiles, ≤500 KB each, oldest-used pruned) + `lib/cachedTileLayer.ts` (an `L.TileLayer` subclass that reads through it),