Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
1234567891011121314151617181920212223242526import { createServer } from 'node:http';import { requesterDid } from './auth.js';export function createFeedServer({ ranker, config, logger = console }) { return createServer((req, res) => { const url = new URL(req.url, `http://${req.headers.host ?? 'localhost'}`); if (url.pathname === '/health') return json(res, 200, { ok: true }); if (url.pathname !== '/xrpc/app.bsky.feed.getFeedSkeleton') return json(res, 404, xrpcError('NotFound', 'Unknown XRPC method')); if (req.method !== 'GET') return json(res, 405, xrpcError('MethodNotAllowed', 'GET required')); if (url.searchParams.get('feed') !== config.feedUri) return json(res, 400, xrpcError('UnknownFeed', 'This generator does not serve that feed URI')); const did = requesterDid(req, config); if (!did) return json(res, 401, xrpcError('AuthRequired', 'A validated requester DID is required')); const requested = Number.parseInt(url.searchParams.get('limit') ?? '30', 10); const limit = Math.max(1, Math.min(Number.isFinite(requested) ? requested : 30, config.pageMax)); const result = ranker.recommend(did); const offset = decodeCursor(url.searchParams.get('cursor'), did); const page = result.candidates.slice(offset, offset + limit); const next = offset + page.length < result.candidates.length ? encodeCursor(offset + page.length, did) : undefined; logger.info?.(`feed request ${did}: ${page.length}/${result.candidates.length}`); return json(res, 200, { feed: page.map((x) => ({ post: x.postUri })), ...(next ? { cursor: next } : {}) }); });}function encodeCursor(offset, did) { return Buffer.from(JSON.stringify({ offset, did })).toString('base64url'); }function decodeCursor(cursor, did) { try { const x = JSON.parse(Buffer.from(cursor, 'base64url').toString()); return x.did === did && Number.isInteger(x.offset) && x.offset >= 0 ? x.offset : 0; } catch { return 0; } }function xrpcError(error, message) { return { error, message }; }function json(res, status, data) { res.writeHead(status, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' }); res.end(JSON.stringify(data)); }