Feed Utilities
The utils module provides helper functions for creating, type-checking, and manipulating feed definitions. It includes factory functions, type guards, feed transformation utilities, and feed traversal tools.
Feed Factory Functions
Create strongly-typed feed definitions:
typescript
// Basic Feeds
const authors = makeAuthorFeed("pubkey1", "pubkey2")
const kinds = makeKindFeed(1, 6)
const search = makeSearchFeed("bitcoin", "nostr")
const global = makeGlobalFeed()
// Time-based Feeds
const recent = makeCreatedAtFeed({
since: Date.now() - 86400000,
relative: ["since"]
})
// Advanced Feeds
const dvm = makeDVMFeed({
kind: 5300,
mappings: [["p", [FeedType.Author]]]
})
const list = makeListFeed({
addresses: ["list_id"],
mappings: [["t", [FeedType.Tag, "#t"]]]
})
// Set Operations
const union = makeUnionFeed(authors, kinds)
const intersection = makeIntersectionFeed(authors, recent)
const difference = makeDifferenceFeed(global, authors)
Type Guards
Check feed types safely:
typescript
const feed: Feed = makeDVMFeed({ kind: 5300 })
if (isDVMFeed(feed)) {
// feed is now typed as DVMFeed
const [kind] = feed.slice(1)
}
if (hasSubFeeds(feed)) {
// feed is now typed as UnionFeed | IntersectionFeed | DifferenceFeed
const subFeeds = getFeedArgs(feed)
}
Feed Transformations
Tag to Feed Conversion
typescript
// Default tag mappings
const defaultTagFeedMappings: TagFeedMapping[] = [
["a", [FeedType.Address]], // address tags
["e", [FeedType.ID]], // event references
["p", [FeedType.Author]], // people/pubkeys
["r", [FeedType.Relay]], // relay URLs
["t", [FeedType.Tag, "#t"]], // hashtags
]
// Convert event tags to feeds
const tags = [["p", "pubkey1"], ["t", "bitcoin"]]
const feeds = feedsFromTags(tags)
// => [[FeedType.Author, "pubkey1"], [FeedType.Tag, "#t", "bitcoin"]]
// Convert tags to a single intersection feed
const feed = feedFromTags(tags)
// => [FeedType.Intersection, [FeedType.Author, "pubkey1"], [FeedType.Tag, "#t", "bitcoin"]]
Filter to Feed Conversion
typescript
// Convert a single filter to feeds
const filter = {
kinds: [1],
authors: ["pubkey1"],
"#t": ["bitcoin"],
since: 1234567890
}
const feeds = feedsFromFilter(filter)
// => [
// [FeedType.CreatedAt, { since: 1234567890 }],
// [FeedType.Kind, 1],
// [FeedType.Author, "pubkey1"],
// [FeedType.Tag, "#t", "bitcoin"]
// ]
// Convert a filter to an intersection feed
const feed = feedFromFilter(filter)
// Convert multiple filters to a union feed
const feeds = feedFromFilters([filter1, filter2])
Feed Traversal
Walk through a feed tree and visit each node:
typescript
const feed = makeIntersectionFeed(
makeAuthorFeed("pubkey1"),
makeUnionFeed(
makeKindFeed(1),
makeTagFeed("#t", "bitcoin")
)
)
walkFeed(feed, (node) => {
console.log(`Visiting feed of type: ${node[0]}`)
})
Type Extraction
Get typed arguments from feeds:
typescript
function getFeedArgs(feed: IntersectionFeed): Feed[]
function getFeedArgs(feed: AuthorFeed): string[]
function getFeedArgs(feed: CreatedAtFeed): CreatedAtItem[]
function getFeedArgs(feed: WOTFeed): WOTItem[]
// ... and so on for each feed type
const feed = makeAuthorFeed("pubkey1", "pubkey2")
const pubkeys = getFeedArgs(feed) // => ["pubkey1", "pubkey2"]
Best Practices
Use factory functions instead of raw arrays:
typescript// Good const feed = makeAuthorFeed("pubkey1") // Avoid const feed = [FeedType.Author, "pubkey1"]
Use type guards for safe type narrowing:
typescriptif (isAuthorFeed(feed)) { const pubkeys = getFeedArgs(feed) // Properly typed }
Use feed transformations for dynamic feed creation:
typescript// Convert event tags to feeds const feeds = feedsFromTags(event.tags) // Convert filters to feeds const feed = feedFromFilter(filter)
Use feed traversal for analysis or transformation:
typescriptconst kinds = new Set<number>() walkFeed(feed, (node) => { if (isKindFeed(node)) { getFeedArgs(node).forEach(k => kinds.add(k)) } })