Server state for Angular, built on signals. Queries, mutations, infinite scroll, caching and SSR hydration — with no observer layer underneath, because the cache entry is a signal.
📖 Docs and interactive playground →
npm i @ali7040/ng-signal-queryMutation concurrency strategies. Overlapping mutate() calls resolve the way
you choose, with semantics borrowed from the RxJS flattening operators:
// Double-click proof. No disabled flag, no debounce.
const submit = createMutation({
mutationFn: (order: Order) => api.place(order),
concurrencyStrategy: 'exhaust',
});| Strategy | RxJS | Behaviour |
|---|---|---|
merge |
mergeMap |
Every call runs, in parallel (default) |
concat |
concatMap |
Queued, and kept in order |
switch |
switchMap |
Latest wins, earlier discarded |
exhaust |
exhaustMap |
First wins, the rest ignored |
See them run on a live timeline →
Request cancellation. Every fetcher receives an AbortSignal, and superseded
requests are actually aborted:
const users = createQuery({
key: ['users'],
fetcher: ({ signal }) => fetch('/api/users', { signal }).then(r => r.json()),
});Queries sharing a key also share a single in-flight request.
TanStack Query is the reference implementation for this problem and, for most
teams, still the right answer. The
comparison table is
honest about both directions — including enabled, select, placeholderData,
persistence and offline support, which it has and this does not yet.
Issues and pull requests are welcome — several are tagged
good first issue.
See the contributing guide.
projects/signal-query/ the published library
projects/signal-query/examples/ runnable examples
src/ demo application shell
Common commands:
npm start # serve the demo app
npm run build:lib # build the publishable library
npm test # run the test suiteThe website lives in a separate repository: ng-signal-query-site.
MIT — see LICENSE.