Version v2.1.0 Size 2.2 KB gzip Dependencies Zero dependencies
Why Sourcerer?
Lists often combine pagination, search, request cancellation, and render state. Sourcerer gives local arrays and remote loaders one snapshot contract while leaving caching, retries, and transport policy to your application.
ts
import { createPageSource } from '@vielzeug/sourcerer';
type User = { id: number; name: string };
// Before: query changes can mix old items with new loading and page state.
let items: User[] = [];
let page = 1;
let isLoading = false;
// After: one source publishes internally consistent loaded state.
const source = createPageSource<User>({
autoStart: false,
load: async () => ({ data: [{ id: 1, name: 'Ada' }], total: 1 }),
});
source.subscribe((snapshot) => console.log(snapshot.data));
source.dispose();| Feature | Sourcerer | Manual list state | Courier query cache |
|---|---|---|---|
| Bundle size | 2.2 KB | Application-defined | 4.9 KB |
| Zero runtime dependencies | |||
| Local and remote collections | Application-defined | ||
| Cursor and infinite pagination | Application-defined | ||
| Latest-request cancellation | Application-defined | Transport-level |
Use Sourcerer when one UI collection needs local or remote pagination with an explicit, framework-independent snapshot contract.
Consider Courier alone when you only need cached HTTP queries and pagination state belongs elsewhere.
Installation
sh
pnpm add @vielzeug/sourcerersh
npm install @vielzeug/sourcerersh
yarn add @vielzeug/sourcererQuick Start
Create a page source, load it, then dispose it with its owner.
ts
import { createPageSource } from '@vielzeug/sourcerer';
type User = { id: number; name: string };
const source = createPageSource<User>({
autoStart: false,
load: async ({ query }) => {
const users = [
{ id: 1, name: 'Ada' },
{ id: 2, name: 'Grace' },
{ id: 3, name: 'Linus' },
];
const start = (query.page - 1) * query.pageSize;
return { data: users.slice(start, start + query.pageSize), total: users.length };
},
});
try {
await source.reload();
console.log(source.snapshot.data);
} catch (error) {
console.error(error);
} finally {
source.dispose();
}Features
createLocalSource()— synchronous search and numbered pagination over an arraycreatePageSource()— numbered remote pages with latest-request cancellationcreateCursorSource()— sequential opaque-cursor navigationcreateInfiniteSource()— append-only page loadingSourceSnapshot— loadedquery,data, andpaginationplus optionalpendingQuery