import { Feed } from 'feed' import { JSDOM } from 'jsdom' import { Readability } from '@mozilla/readability' const PORT = process.env.BEACON_PORT || 3700 export async function pageToRSS(page, sourceUrl) { const [html, title, url] = await Promise.all([ page.content(), page.title(), Promise.resolve(page.url()), ]) const dom = new JSDOM(html, { url }) const doc = dom.window.document const feed = new Feed({ title: title || sourceUrl, id: url, link: url, feedLinks: { rss: `http://localhost:${PORT}/feed?url=${encodeURIComponent(sourceUrl)}`, }, generator: 'beacon', updated: new Date(), }) // Try Readability — works for article pages const reader = new Readability(doc.cloneNode(true)) const article = reader.parse() if (article && article.length > 500) { feed.addItem({ title: article.title || title, id: url, link: url, description: article.excerpt, content: article.content, date: article.publishedTime ? new Date(article.publishedTime) : new Date(), author: article.byline ? [{ name: article.byline }] : [], }) } else { // Link-list page (HN, Reddit, news front pages) — harvest significant links const seen = new Set() const links = [...doc.querySelectorAll('a[href]')] .filter(a => { const text = a.textContent.trim() const href = a.href if (!href || !text || text.length < 12) return false if (href.startsWith('#') || href.startsWith('javascript:')) return false if (seen.has(href)) return false seen.add(href) return true }) .slice(0, 40) for (const link of links) { feed.addItem({ title: link.textContent.trim(), id: link.href, link: link.href, description: link.title || link.textContent.trim(), date: new Date(), }) } } return feed.rss2() }