aisdk5-news-package
v1.0.0
Published
A comprehensive RSS news aggregation package for chat applications
Maintainers
Readme
@aisdk5/news-package
A comprehensive RSS news aggregation package for chat applications built with React, Next.js, and TypeScript.
✨ Features
- 📰 RSS Feed Aggregation - Fetch and parse RSS feeds from multiple sources
- 🔍 Full-text Search - Search articles by title, description, and content
- 📱 Responsive Design - Mobile-first responsive layout
- 🎨 Multiple Layouts - Google News, Magazine, and Grid layouts
- 💾 Article Saving - Save articles for later reading
- 🤖 AI Integration - Built-in AI discussion prompts
- 🔄 Background Jobs - Automated RSS feed fetching
- 📊 Admin Panel - Manage RSS feeds and monitor performance
- 🎯 Smart Filtering - Category-based filtering and sorting
- ♿ Accessibility - ARIA-compliant components
- 🌙 Dark Mode - Full dark mode support
🚀 Quick Start
Installation
# Install the package
pnpm add @aisdk5/news-package
# Install peer dependencies
pnpm add react next @radix-ui/react-dialog @radix-ui/react-tabs tailwindcss lucide-reactLocal Development Setup
For local development or testing before npm publication:
# Option 1: Use setup script (Unix/Mac)
cd packages/news-package
./scripts/setup-local.sh
# Option 2: Manual setup
pnpm install
pnpm build
pnpm link --global
# In your project
cd /path/to/your-project
pnpm link --global @aisdk5/news-packageWorkspace Setup
If using pnpm workspaces, add to your root package.json:
{
"packages": ["packages/*", "apps/*"]
}Then reference as:
{
"dependencies": {
"@aisdk5/news-package": "workspace:*"
}
}Basic Usage
import { NewsPage, DatabaseService } from '@aisdk5/news-package';
export default function NewsRoute() {
return (
<NewsPage
onLoadArticles={async (filters) => {
// Your implementation
return { articles: [], total: 0, hasMore: false };
}}
onSaveArticle={async (articleId) => {
// Your implementation
}}
onDiscussArticle={(article) => {
// Integrate with your AI chat
}}
/>
);
}📦 What's Included
Components
NewsPage- Complete news reading experienceArticleList- List of articles with infinite scrollArticleCard- Individual article displayCategoryFilter- Category filtering interfaceSearchInterface- Search input with suggestions
Services
RSSFetcherService- RSS feed fetching and parsingBackgroundJobService- Automated feed processingDatabaseService- Database abstraction layer
Hooks
useNewsSearch- Search state managementuseCategoryFilter- Category selectionuseArticleViewer- Article modal state
Database
- PostgreSQL schema and migrations
- Drizzle ORM integration
- Full-text search indexes
🏗️ Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Components │───▶│ Services │───▶│ Database │
│ │ │ │ │ │
│ • NewsPage │ │ • RSSFetcher │ │ • Articles │
│ • ArticleList │ │ • BackgroundJob │ │ • RSS Feeds │
│ • CategoryFilter│ │ • Database │ │ • Saved Items │
└─────────────────┘ └─────────────────┘ └─────────────────┘🔧 Configuration
Environment Variables
DATABASE_URL=postgresql://user:password@localhost:5432/db
RSS_FETCH_TIMEOUT=10000
RSS_MAX_RETRIES=3Custom Configuration
import { defaultConfig } from '@aisdk5/news-package';
const config = {
...defaultConfig,
rss: {
fetchTimeout: 15000,
maxRetries: 5,
batchSize: 3,
},
ui: {
defaultLayout: 'magazine',
enableSaveArticles: true,
enableAIDiscussion: true,
},
};💾 Database Setup
1. Run Migration
-- Run the provided migration script
\i database/migration.sql2. Create Database Adapter
import { DatabaseAdapter } from '@aisdk5/news-package';
class MyDatabaseAdapter implements DatabaseAdapter {
// Implement required methods
async getArticles(filters) { /* ... */ }
async createArticles(articles) { /* ... */ }
// ... other methods
}3. Initialize Services
const databaseService = new DatabaseService(new MyDatabaseAdapter());🔄 Background Jobs
Set up automated RSS feed processing:
import { BackgroundJobService } from '@aisdk5/news-package';
const jobService = new BackgroundJobService({
onStoreArticles: async (articles) => {
return databaseService.createArticles(articles);
},
onGetFeeds: async () => {
return databaseService.getRSSFeeds(true);
},
onUpdateFeedStatus: async (feedId, success, errorCount) => {
await databaseService.updateFeedLastFetched(feedId, success, errorCount);
},
});
// Process feeds every 30 minutes
setInterval(() => {
jobService.processRSSFeeds();
}, 30 * 60 * 1000);🎨 Styling
The package uses Tailwind CSS. Add to your configuration:
// tailwind.config.js
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx}',
'./node_modules/@aisdk5/news-package/**/*.{js,ts,jsx,tsx}',
],
};📡 API Integration
Copy API route templates to your project:
cp -r node_modules/@aisdk5/news-package/api-templates/* app/api/Customize the routes for your authentication and database setup.
🤖 AI Integration
Article Discussion
import { generateArticleDiscussionPrompt } from '@aisdk5/news-package';
function handleDiscussArticle(article) {
const prompt = generateArticleDiscussionPrompt(article, 'summary');
// Send to your AI chat system
startChatWithPrompt(prompt);
}Custom AI Tools
import { createArticleContext } from '@aisdk5/news-package';
const articleTool = {
name: 'analyzeArticle',
execute: async ({ articleId }) => {
const article = await databaseService.getArticleById(articleId);
const context = createArticleContext(article);
return analyzeArticleContent(context);
},
};📱 Layout Variants
Google News Style
<NewsPage layout="google-news" />Magazine Style
<NewsPage layout="magazine" />Grid Layout
<NewsPage layout="grid" />🔍 Search & Filtering
Full-text Search
const articles = await databaseService.searchArticles('artificial intelligence', {
categories: ['technology'],
dateRange: 'week',
});Category Filtering
<CategoryFilter
categories={categories}
selectedCategories={selected}
onCategoryChange={handleChange}
variant="pills" // or "buttons" or "compact"
/>⚡ Performance
Caching
// Implement caching for better performance
const cache = new Map();
async function getCachedArticles(filters) {
const key = JSON.stringify(filters);
if (cache.has(key)) return cache.get(key);
const result = await databaseService.getArticles(filters);
cache.set(key, result);
return result;
}Database Optimization
-- Key indexes for performance
CREATE INDEX idx_articles_category_published
ON news_articles (category, published_at DESC);
CREATE INDEX idx_articles_fulltext
ON news_articles USING GIN (to_tsvector('english', title || ' ' || description));🧪 Testing
import { RSSFetcherService } from '@aisdk5/news-package';
// Test RSS feed validity
const fetcher = new RSSFetcherService();
const isValid = await fetcher.validateFeedUrl('https://example.com/rss');
// Test feed parsing
const result = await fetcher.testFeed('https://techcrunch.com/feed/');
console.log(`Found ${result.articleCount} articles`);🔧 Troubleshooting
Common Issues
RSS feeds not loading
- Check URL accessibility
- Verify CORS settings
- Test feed validity
Database connection errors
- Check DATABASE_URL
- Verify permissions
- Run migrations
Authentication issues
- Check session handling
- Verify API route protection
- Update user foreign keys
Debug Mode
const fetcher = new RSSFetcherService({
debug: process.env.NODE_ENV === 'development'
});📚 Documentation
- Integration Guide - Complete setup guide
- API Reference - API route documentation
- Database Schema - Database structure
- Examples - Implementation examples
🤝 Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
📄 License
MIT License - see LICENSE for details.
🆘 Support
- GitHub Issues: Report bugs and request features
- Documentation: Check the integration guide
- Examples: See the examples directory
🔗 Related Packages
@aisdk5/chat-package- Chat interface components@aisdk5/ai-tools- AI integration utilities@aisdk5/ui-components- Shared UI components
Made with ❤️ for the developer community
