// Publisher-controlled Feed/Article storage limits (UTF-16 code units). // Display metadata is truncated at these boundaries. Identity fields are never // truncated: an overlong GUID is discarded and an overlong Article link is // rejected so distinct resources cannot collapse onto the same stored prefix. export const MAX_FEED_TITLE_SIZE = 1_000; export const MAX_FEED_DESCRIPTION_SIZE = 20_000; export const MAX_FEED_CATEGORY_SIZE = 512; export const MAX_HTTP_URL_SIZE = 8_192; export const MAX_ARTICLE_TITLE_SIZE = 2_000; export const MAX_ARTICLE_GUID_SIZE = 4_096; export const MAX_ARTICLE_LINK_SIZE = 8_192; export const MAX_ARTICLE_AUTHOR_SIZE = 2_000; export const MAX_ARTICLE_CATEGORY_SIZE = 512; export const MAX_ARTICLE_CATEGORY_COUNT = 100; // Aggregate category text, excluding JSON punctuation added at persistence. export const MAX_ARTICLE_CATEGORIES_SIZE = 10_000; // Feed-body complexity ceilings. These cap tree amplification independently of // the 10 MB response-byte limit and are checked before xml2js builds an object. export const MAX_FEED_XML_DEPTH = 256; export const MAX_FEED_XML_NODES = 50_000; // Article body limits export const MAX_CONTENT_SIZE = 100_000; // Feed summaries are useful as previews, but should not approach full-article size. export const MAX_DESCRIPTION_SIZE = 20_000; export const MAX_RESPONSE_SIZE = 10_000_000; // 10MB // Fetch defaults export const DEFAULT_TIMEOUT = 30_000; export const DEFAULT_CONCURRENCY = 5; export const DEFAULT_ARTICLE_LIMIT = 50; export const MAX_ARTICLE_LIMIT = 1000; export const MIN_CONCURRENCY = 1; export const MAX_CONCURRENCY = 20; export const RATE_LIMIT_MS = 1_000; export const MIN_TIMEOUT = 1_000; export const MAX_TIMEOUT = 600_000; export const ARCHIVE_FETCH_TIMEOUT = 5_000; // User agent export const USER_AGENT = 'BunRSS-Reader/1.0 (compatible; RSS Reader)'; // Content extraction export const CONTENT_SELECTORS = [ 'article', '[role="main"]', 'main', '.post-content', '.article-content', '.entry-content', '.content', '#content', ]; export const MIN_CONTENT_LENGTH = 200; // Display export const MAX_DISPLAY_CONTENT_LENGTH = 2000; export const MAX_TITLE_DISPLAY_LENGTH = 40; export const ARTICLE_TITLE_DISPLAY_LENGTH = 50; export const FEED_TITLE_IN_LIST_LENGTH = 20; export const FEED_TITLE_IN_STATS_LENGTH = 30; // OPML export const MAX_OPML_RECURSION_DEPTH = 50; export const MAX_OPML_OUTLINE_NODES = 10_000; // Date parsing export const MAX_RELATIVE_DAYS = 36_500; // ~100 years // Error handling export const MAX_ERROR_COUNT = 5; // Auto-deactivate feed after this many consecutive errors