Skip to content

Commit 1f4697c

Browse files
Add RSS and Atom feed collections to TanStack DB
Co-authored-by: sam.willis <[email protected]>
1 parent e6d6960 commit 1f4697c

File tree

2 files changed

+84
-2
lines changed

2 files changed

+84
-2
lines changed

.changeset/add-rss-atom-collection.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
"@tanstack/rss-db-collection": patch
3+
---
4+
5+
Add RSS and Atom feed collections for TanStack DB
6+
7+
Introduces `@tanstack/rss-db-collection` package with:
8+
9+
- `rssCollectionOptions()` for RSS 2.0 feeds
10+
- `atomCollectionOptions()` for Atom 1.0 feeds
11+
- Automatic polling with configurable intervals
12+
- Built-in deduplication based on feed item IDs
13+
- Custom transform functions for data normalization
14+
- Full TypeScript support with proper type inference
15+
- Error recovery and robust feed parsing
16+
- HTTP configuration options for headers and timeouts
17+
18+
Both collection types provide seamless integration with TanStack DB's live queries and optimistic mutations, allowing you to sync RSS/Atom feed data and query it alongside other collection types.

docs/overview.md

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,9 @@ There are a number of built-in collection types:
154154
1. [`QueryCollection`](#querycollection) to load data into collections using [TanStack Query](https://tanstack.com/query)
155155
2. [`ElectricCollection`](#electriccollection) to sync data into collections using [ElectricSQL](https://electric-sql.com)
156156
3. [`TrailBaseCollection`](#trailbasecollection) to sync data into collections using [TrailBase](https://trailbase.io)
157-
4. [`LocalStorageCollection`](#localstoragecollection) for small amounts of local-only state that syncs across browser tabs
158-
5. [`LocalOnlyCollection`](#localonlycollection) for in-memory client data or UI state
157+
4. [`RSSCollection` and `AtomCollection`](#rsscollection-and-atomcollection) to sync data from RSS and Atom feeds with automatic polling
158+
5. [`LocalStorageCollection`](#localstoragecollection) for small amounts of local-only state that syncs across browser tabs
159+
6. [`LocalOnlyCollection`](#localonlycollection) for in-memory client data or UI state
159160

160161
You can also use:
161162

@@ -297,6 +298,69 @@ This collection requires the following TrailBase-specific options:
297298

298299
A new collections doesn't start syncing until you call `collection.preload()` or you query it.
299300

301+
#### `RSSCollection` and `AtomCollection`
302+
303+
RSS and Atom feeds are widely used syndication formats for publishing frequently updated content like blogs, news, and podcasts. TanStack DB provides dedicated collection types for both RSS 2.0 and Atom 1.0 feeds with automatic polling, deduplication, and type safety.
304+
305+
Use `rssCollectionOptions` for RSS feeds or `atomCollectionOptions` for Atom feeds to sync feed data into collections:
306+
307+
```ts
308+
import { createCollection } from "@tanstack/react-db"
309+
import { rssCollectionOptions, atomCollectionOptions } from "@tanstack/rss-db-collection"
310+
311+
// RSS Collection
312+
export const blogFeed = createCollection(
313+
rssCollectionOptions({
314+
id: "blog-posts",
315+
feedUrl: "https://blog.example.com/rss.xml",
316+
pollingInterval: 5 * 60 * 1000, // Poll every 5 minutes
317+
getKey: (item) => item.guid || item.link,
318+
transform: (item) => ({
319+
id: item.guid || item.link || '',
320+
title: item.title || '',
321+
description: item.description || '',
322+
link: item.link || '',
323+
publishedAt: new Date(item.pubDate || Date.now()),
324+
author: item.author
325+
}),
326+
schema: blogPostSchema,
327+
})
328+
)
329+
330+
// Atom Collection
331+
export const newsFeed = createCollection(
332+
atomCollectionOptions({
333+
id: "news-items",
334+
feedUrl: "https://news.example.com/atom.xml",
335+
pollingInterval: 10 * 60 * 1000, // Poll every 10 minutes
336+
getKey: (item) => item.id,
337+
transform: (item) => ({
338+
id: item.id || '',
339+
title: typeof item.title === 'string' ? item.title : item.title?.$text || '',
340+
description: typeof item.summary === 'string' ? item.summary : item.summary?.$text || '',
341+
link: typeof item.link === 'string' ? item.link : item.link?.href || '',
342+
publishedAt: new Date(item.published || item.updated || Date.now()),
343+
author: typeof item.author === 'object' ? item.author?.name : item.author
344+
}),
345+
schema: newsItemSchema,
346+
})
347+
)
348+
```
349+
350+
Both collection types require:
351+
352+
- `feedUrl` — the RSS or Atom feed URL to fetch from
353+
- `getKey` — identifies the unique ID for feed items
354+
- `pollingInterval` — how frequently to check for new items (default: 5 minutes)
355+
356+
Optional configuration includes:
357+
358+
- `transform` — custom function to normalize feed items to your desired format
359+
- `httpOptions` — custom headers, timeout, and user agent settings
360+
- `startPolling` — whether to begin polling immediately (default: true)
361+
- `maxSeenItems` — maximum items to track for deduplication (default: 1000)
362+
363+
RSS and Atom collections automatically handle feed parsing, deduplication of items, and provide built-in error recovery. The collections will continue polling even after network failures or parsing errors.
300364

301365
#### `LocalStorageCollection`
302366

0 commit comments

Comments
 (0)