# Subscription System The subscription system extends Nostr's base subscription model with intelligent caching, repository integration, and configurable behaviors. ## Key Concepts - **Local Repository**: Events are automatically cached and tracked - **Cache Intelligence**: Smart decisions about when to use cached data - **Relay Integration**: Works with the router for optimal relay selection - **Configurable Behavior**: Control caching and timeouts ## Configuration Options ```typescript type SubscribeRequest = { // Required filters: Filter[] // What to query // Behavior Control closeOnEose?: boolean // Auto-close and use cache timeout?: number // Max time to wait authTimeout?: number // Time for auth negotiation requestDelay?: number // Delay between batched requests // Optional relays?: string[] // Specific relays to query // Event Handlers onEvent?: (event: TrustedEvent) => void onEose?: (url: string) => void onComplete?: () => void } ``` ## Cache Behavior Control The `closeOnEose` parameter is crucial for controlling caching behavior: ```typescript // WITH closeOnEose: true (default for load()) // - Checks cache first // - Returns cached results if complete // - Closes after EOSE // - Good for: Known events, historical data const loadKnownEvent = async (id: string) => { const events = await load({ filters: [{ids: [id]}], closeOnEose: true }) return events[0] } // WITH closeOnEose: false // - Always queries relays // - Stays open for updates // - Ignores cache completeness // - Good for: Replaceable events, live data const watchProfile = (pubkey: string) => { return subscribe({ filters: [{ kinds: [PROFILE], authors: [pubkey] }], closeOnEose: false // Force relay query }) } ``` ## Common Usage Patterns ### One-time Queries ```typescript // Load specific event const event = await load({ filters: [{ids: [eventId]}] // closeOnEose: true by default }) // Load latest profile const profile = await load({ filters: [{ kinds: [PROFILE], authors: [pubkey], limit: 1 }], closeOnEose: false // Get latest from network }) ``` ### Live Subscriptions ```typescript // Watch for updates const sub = subscribe({ filters: [{ kinds: [NOTE], since: now() // Only new events }], closeOnEose: false, // Stay open }) sub.on('event', (url, event) => { // Handle live events }) ``` ### Smart Caching ```typescript // Profile loader with refresh control const loadProfile = async (pubkey: string, options = {}) => { const { forceRefresh = false, // Skip cache timeout = 3000, // Max wait time relays = [] // Optional relay override } = options // Get optimal relays if not specified const targetRelays = relays.length > 0 ? relays : ctx.app.router.ForPubkey(pubkey).getUrls() return new Promise((resolve) => { const sub = subscribe({ filters: [{ kinds: [PROFILE], authors: [pubkey], limit: 1 }], relays: targetRelays, closeOnEose: !forceRefresh, // Control cache behavior timeout, onEvent: (url, event) => { resolve(event) sub.close() }, onComplete: () => resolve(null) }) }) } ``` ## Repository Integration All events from subscriptions are automatically: - Saved to the repository - Tracked to their source relay - Checked against deletion status The repository serves as an intelligent cache layer, making subsequent queries for the same data faster.