Feed
The feed system provides a powerful way to compose and load complex Nostr
queries. It supports user scopes, web of trust filtering, DVM integration, and thread construction.
Controller
The controller.load()
function is the main interface for fetching events from a feed. It handles all the complexity of relay selection, subscription management, and event filtering.
typescript
import {createFeedController} from '@welshman/app'
import {scopeFeed, wotFeed} from '@welshman/feeds'
const controller = createFeedController({
// Define what to load
feed: scopeFeed("follows"),
// Optional configurations
closeOnEose: true, // Close after getting all events
onEvent: event => {}, // Handle events as they arrive
onEose: url => {}, // Handle EOSE from each relay
onComplete: () => {}, // Called when all relays complete
})
// Load first 20 events
const events = await controller.load(20)
// Load next 20 events
const moreEvents = await controller.load(20)
The controller maintains its state between loads, so subsequent calls will:
- Continue from last position
- Use appropriate time windows
- Skip already seen events
- Maintain relay connections
Paginated Feed
typescript
import {intersectionFeed, scopeFeed, wotFeed} from '@welshman/feeds'
const HomeFeed = {
let events = []
let loading = false
let controller
onMount(() => {
// Create feed for home timeline
controller = createFeedController({
feed: intersectionFeed(
// Content from follows
scopeFeed("follows"),
// Filtered by web of trust
wotFeed({min: 0.1})
),
// Handle events as they arrive
onEvent: event => {
events = [...events, event]
},
// Track loading state
onComplete: () => {
loading = false
}
})
// Initial load
loadMore()
})
const loadMore = async () => {
if (loading) return
loading = true
// Load next batch
await controller.load(20)
}
}
Key points about controller.load()
:
- Takes a limit parameter for batch size
- Returns a promise of loaded events
- Can be called repeatedly for pagination
- Handles subscription lifecycle
- Manages relay connections
- Deduplicates events
The controller is stateful and maintains:
- Current time window
- Seen events
- Active subscriptions
- Relay connections
This makes it ideal for implementing infinite scroll feeds, thread loading, and other paginated content scenarios.