Feed Types and Core Definitions
This module defines the core types and structures used to build Nostr feeds. It provides a type-safe way to define complex feed compositions using various filtering mechanisms and set operations.
Feed Types
enum FeedType {
Address = "address", // Filter by event addresses
Author = "author", // Filter by author pubkeys
CreatedAt = "created_at", // Filter by timestamp
DVM = "dvm", // Data Vending Machine based feed
Difference = "difference", // Set difference operation
ID = "id", // Filter by event IDs
Intersection = "intersection", // Set intersection operation
Global = "global", // Global feed (no filters)
Kind = "kind", // Filter by event kinds
List = "list", // List-based feed
Label = "label", // Label-based feed
WOT = "wot", // Web of Trust based feed
Relay = "relay", // Relay-specific feed
Scope = "scope", // Scoped feed (followers, network)
Search = "search", // Search-based feed
Tag = "tag", // Filter by specific tags
Union = "union" // Set union operation
}
Scope Types
enum Scope {
Followers = "followers", // People who follow the user
Follows = "follows", // People the user follows
Network = "network", // Extended network
Self = "self" // The signed in user
}
Feed Definitions
Each feed type has its own structure:
Basic Filter Feeds
type AddressFeed = [type: FeedType.Address, ...addresses: string[]]
type AuthorFeed = [type: FeedType.Author, ...pubkeys: string[]]
type IDFeed = [type: FeedType.ID, ...ids: string[]]
type KindFeed = [type: FeedType.Kind, ...kinds: number[]]
type TagFeed = [type: FeedType.Tag, key: string, ...values: string[]]
Time-based Feeds
type CreatedAtItem = {
since?: number
until?: number
relative?: string[] // For relative time references
}
type CreatedAtFeed = [type: FeedType.CreatedAt, ...items: CreatedAtItem[]]
Advanced Filter Feeds
// DVM-based feed
type DVMItem = {
kind: number
tags?: string[][]
relays?: string[]
mappings?: TagFeedMapping[]
}
type DVMFeed = [type: FeedType.DVM, ...items: DVMItem[]]
// List-based feed
type ListItem = {
addresses: string[]
mappings?: TagFeedMapping[]
}
type ListFeed = [type: FeedType.List, ...items: ListItem[]]
// Label-based feed
type LabelItem = {
relays?: string[]
authors?: string[]
[key: `#${string}`]: string[]
mappings?: TagFeedMapping[]
}
type LabelFeed = [type: FeedType.Label, ...items: LabelItem[]]
// Web of Trust feed
type WOTItem = {
min?: number
max?: number
}
type WOTFeed = [type: FeedType.WOT, ...items: WOTItem[]]
Tag Feed Mapping
TagFeedMapping
is a mechanism to convert event tags into feed definitions. It's particularly useful when working with DVMs, Lists, and Labels where you want to interpret tags in a specific way.
type TagFeedMapping = [string, Feed]
Usage
// Example mappings
const mappings: TagFeedMapping[] = [
// Convert 'p' tags into author feeds
["p", [FeedType.Author]],
// Convert 't' tags into hashtag filters
["t", [FeedType.Tag, "#t"]],
// Convert 'e' tags into event ID feeds
["e", [FeedType.ID]],
// Convert 'r' tags into relay feeds
["r", [FeedType.Relay]]
]
// Using mappings in a DVM feed
const dvmFeed: Feed = [
FeedType.DVM,
{
kind: 5300,
mappings: mappings
}
]
// Using mappings in a List feed
const listFeed: Feed = [
FeedType.List,
{
addresses: ["list_id"],
mappings: mappings
}
]
Default Mappings
The system comes with default mappings for common tags:
const defaultTagFeedMappings: TagFeedMapping[] = [
["a", [FeedType.Address]], // Address references
["e", [FeedType.ID]], // Event references
["p", [FeedType.Author]], // Person/Pubkey references
["r", [FeedType.Relay]], // Relay references
["t", [FeedType.Tag, "#t"]], // Hashtags
]
Set Operation Feeds
Union Feed
A Union feed combines multiple feeds with an OR operation. Events matching any of the constituent feeds will be included.
type UnionFeed = [type: FeedType.Union, ...feeds: Feed[]]
// Example: Events from either Alice OR Bob
const unionFeed: UnionFeed = [
FeedType.Union,
[FeedType.Author, "alice_pubkey"],
[FeedType.Author, "bob_pubkey"]
]
// Example: Events from a list OR matching a search term
const complexUnion: UnionFeed = [
FeedType.Union,
[FeedType.List, { addresses: ["trending_list"] }],
[FeedType.Search, "bitcoin"]
]
Intersection Feed
An Intersection feed combines multiple feeds with an AND operation. Only events that match all constituent feeds will be included.
type IntersectionFeed = [type: FeedType.Intersection, ...feeds: Feed[]]
// Example: Text notes (kind 1) from trusted authors
const intersectionFeed: IntersectionFeed = [
FeedType.Intersection,
[FeedType.Kind, 1],
[FeedType.WOT, { min: 0.5 }]
]
// Example: Recent posts from followed users
const timeAndScope: IntersectionFeed = [
FeedType.Intersection,
[FeedType.CreatedAt, { since: Date.now() - 86400000 }], // Last 24h
[FeedType.Scope, Scope.Follows]
]
Difference Feed
A Difference feed excludes events from the second feed from the first feed (NOT operation).
type DifferenceFeed = [type: FeedType.Difference, ...feeds: Feed[]]
// Example: Posts from everyone except blocked users
const differenceFeed: DifferenceFeed = [
FeedType.Difference,
[FeedType.Global], // All events
[FeedType.List, { addresses: ["blocked_users"] }] // Except from blocked users
]
// Example: Posts from follows except reposts
const noReposts: DifferenceFeed = [
FeedType.Difference,
[FeedType.Scope, Scope.Follows],
[FeedType.Kind, 6] // Kind 6 is repost
]
Complex Combinations
You can nest set operations to create sophisticated feed definitions:
// Posts that are either:
// - from trusted authors AND about bitcoin
// - OR from a curated list
const complexFeed: Feed = [
FeedType.Union,
[
FeedType.Intersection,
[FeedType.WOT, { min: 0.7 }],
[FeedType.Search, "bitcoin"]
],
[FeedType.List, { addresses: ["curated_content"] }]
]
// Posts that are:
// - from follows
// - AND (from the last 24h OR highly rated by DVMs)
// - AND NOT marked as sensitive content
const advancedFeed: Feed = [
FeedType.Difference,
[
FeedType.Intersection,
[FeedType.Scope, Scope.Follows],
[
FeedType.Union,
[FeedType.CreatedAt, { since: Date.now() - 86400000 }],
[FeedType.DVM, { kind: 5300, pubkey: "rating_dvm" }]
]
],
[FeedType.Label, { authors: ["content_warning_dvm"] }]
]
Feed Controller Options
The FeedOptions
interface defines the configuration required to execute a feed:
interface FeedOptions {
// The feed definition to execute
feed: Feed
// Function to request events from relays
request: (opts: RequestOpts) => Promise<void>
// Function to request events from DVMs
requestDVM: (opts: DVMOpts) => Promise<void>
// Function to get pubkeys for a given scope
getPubkeysForScope: (scope: Scope) => string[]
// Function to get pubkeys within a WOT range
getPubkeysForWOTRange: (minWOT: number, maxWOT: number) => string[]
// Event handler
onEvent?: (event: TrustedEvent) => void
// Called when feed is exhausted
onExhausted?: () => void
// Enable time-window based loading
useWindowing?: boolean
// Optional abort controller
abortController?: AbortController
}
Examples
Simple Author Feed
const authorFeed: Feed = [FeedType.Author, "pubkey1", "pubkey2"]
Time-filtered Feed
const recentFeed: Feed = [
FeedType.CreatedAt,
{
since: Date.now() - 24 * 60 * 60 * 1000, // Last 24 hours
relative: ["since"]
}
]
Complex Feed Composition
const complexFeed: Feed = [
FeedType.Intersection,
[FeedType.Kind, 1], // Text notes
[FeedType.WOT, { min: 0.5 }], // Trusted authors
[
FeedType.Union,
[FeedType.Scope, Scope.Follows], // From follows
[FeedType.List, { addresses: ["list_id"] }] // Or from list
]
]
DVM Feed with Mappings
const dvmFeed: Feed = [
FeedType.DVM,
{
kind: 5300,
mappings: [
["p", [FeedType.Author]], // Map 'p' tags to authors
["t", [FeedType.Tag, "#t"]] // Map 't' tags to hashtags
]
}
]
This core module provides the foundation for building complex, type-safe feed definitions that can be executed by the feed controller.