Queries
Type-safe TanStack Query abstraction for server state management.
The @teardown/queries package provides a lightweight wrapper around TanStack Query (React Query) that simplifies creating type-safe, composable data fetching patterns. It abstracts key generation, provides utility methods for cache management, and enforces consistent patterns across the codebase.
Features
- Type-safe query keys - Automatic key generation with resource/sub-resource hierarchies
- Composable QueryClient - Organize domain-specific queries in classes
- Cache utilities - Built-in fetch, prefetch, set, get, and refresh methods
- Full query support - Standard queries, infinite queries, and mutations
- Configurable defaults - Set staleTime and gcTime per resource domain
Installation
bun add @teardown/queriesQuick Start
import { QueryClient } from "@teardown/queries";
import { useQuery, useMutation } from "@tanstack/react-query";
// 1. Create a domain-specific query client
class ProjectsClient extends QueryClient<"projects"> {
constructor(tanstackClient: TanstackQueryClient) {
super(tanstackClient, "projects", {
staleTime: 5 * 60 * 1000, // 5 minutes
});
}
// 2. Define queries as methods
getProjects(userId: string) {
return this.query({
key: ["list", userId],
fn: async () => {
const response = await fetch(`/api/projects?userId=${userId}`);
return response.json();
},
});
}
// 3. Define mutations
createProject() {
return this.mutation({
key: ["create"],
fn: async (data: { name: string }) => {
const response = await fetch("/api/projects", {
method: "POST",
body: JSON.stringify(data),
});
return response.json();
},
onSuccess: () => {
this.refresh("list"); // Invalidate list queries
},
});
}
}
// 4. Use in components
function ProjectsList({ userId }) {
const projectsClient = useProjectsClient();
const { data, isLoading } = useQuery(projectsClient.getProjects(userId));
const { mutate } = useMutation(projectsClient.createProject());
return (
<div>
{data?.map(project => <div key={project.id}>{project.name}</div>)}
<button onClick={() => mutate({ name: "New Project" })}>Create</button>
</div>
);
}Query Key Structure
All queries use a consistent key format for predictable cache management:
// Query keys
["@teardown", resource, "query", subResource, ...args]
// Example: ["@teardown", "projects", "query", "list", "user-123"]
// Mutation keys
["@teardown", resource, "mutation", mutationKey, ...args]
// Example: ["@teardown", "projects", "mutation", "create"]Documentation
- Core Concepts - QueryClient architecture and type system
- Queries - Standard and infinite queries
- Mutations - Mutations and cache invalidation
- Best Practices - Patterns and SDK integration
- API Reference - Complete type exports