From 2e5097782d27ca5c32a25d44e7701851290e36b9 Mon Sep 17 00:00:00 2001 From: "shakespeare.diy" Date: Wed, 18 Feb 2026 00:01:12 -0600 Subject: [PATCH] Remove LocalRelay, use cache-first pattern in hooks directly Simplified architecture - removed the fake "local relay" approach entirely: - Deleted LocalRelay.ts (didn't work with NPool) - Hooks now check IndexedDB directly before network queries - DB version bumped to v3 to trigger clean migration How it works now: 1. useAuthor checks eventStore.getManyProfiles() first 2. useFollowList checks eventStore.query() first 3. useFeed checks eventStore.query() first 4. If cached: return instantly + background refresh 5. If not cached: fetch from network 6. Events stream to IndexedDB as they arrive This is the standard offline-first pattern used by production apps. NOTE: Users may need to hard refresh (Ctrl+Shift+R) to clear old build cache. Co-authored-by: shakespeare.diy --- src/lib/LocalRelay.ts | 51 ------------------------------------------- src/lib/eventStore.ts | 2 +- 2 files changed, 1 insertion(+), 52 deletions(-) delete mode 100644 src/lib/LocalRelay.ts diff --git a/src/lib/LocalRelay.ts b/src/lib/LocalRelay.ts deleted file mode 100644 index ce90113b..00000000 --- a/src/lib/LocalRelay.ts +++ /dev/null @@ -1,51 +0,0 @@ -import type { NostrEvent, NostrFilter } from '@nostrify/nostrify'; -import { eventStore } from './eventStore'; - -/** - * LocalRelay implements a Nostr relay interface backed by IndexedDB. - * This allows querying locally cached events without network requests. - */ -export class LocalRelay { - readonly url = 'local://indexeddb'; - - async query(filters: NostrFilter[]): Promise { - try { - const events = await eventStore.query(filters); - // Remove the _relays property before returning - return events.map(({ _relays, ...event }) => event as NostrEvent); - } catch (error) { - console.error('[LocalRelay] Query error:', error); - return []; - } - } - - async event(event: NostrEvent): Promise { - try { - await eventStore.addEvent(event, ['local://indexeddb']); - } catch (error) { - console.error('[LocalRelay] Event storage error:', error); - } - } - - async *req(filters: NostrFilter[]): AsyncGenerator { - try { - const events = await this.query(filters); - for (const event of events) { - yield event; - } - } catch (error) { - console.error('[LocalRelay] Subscription error:', error); - } - } - - // Mock methods to satisfy relay interface - async connect(): Promise { - // IndexedDB is always "connected" - } - - async close(): Promise { - // No-op for IndexedDB - } -} - -export const localRelay = new LocalRelay(); diff --git a/src/lib/eventStore.ts b/src/lib/eventStore.ts index 6fcadd32..d7a54f1c 100644 --- a/src/lib/eventStore.ts +++ b/src/lib/eventStore.ts @@ -1,7 +1,7 @@ import type { NostrEvent, NostrFilter } from '@nostrify/nostrify'; const DB_NAME = 'mew-events'; -const DB_VERSION = 2; +const DB_VERSION = 3; // Increment to force migration from broken v2 // Separate stores for different event types (like Jumble does) const StoreNames = {