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 <assistant@shakespeare.diy>
This commit is contained in:
shakespeare.diy
2026-02-18 00:01:12 -06:00
parent c019a65a2e
commit 2e5097782d
2 changed files with 1 additions and 52 deletions
-51
View File
@@ -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<NostrEvent[]> {
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<void> {
try {
await eventStore.addEvent(event, ['local://indexeddb']);
} catch (error) {
console.error('[LocalRelay] Event storage error:', error);
}
}
async *req(filters: NostrFilter[]): AsyncGenerator<NostrEvent> {
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<void> {
// IndexedDB is always "connected"
}
async close(): Promise<void> {
// No-op for IndexedDB
}
}
export const localRelay = new LocalRelay();
+1 -1
View File
@@ -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 = {