mirror of
https://github.com/prdlk/dotfiles.git
synced 2026-11-07 20:47:37 +00:00
shell: fish functions -> ~/.local/bin executables + bash/zsh ports; manage ~/.agents
- 16 cross-shell utilities converted to sh/bash chezmoi executables: ai c2p cp-appid extract_agents fab gdc gh-sonr-org-migrate ghg-clone ghn gho git-summary launch_omp_livediff_overlay lc-elir mdcp mdp pj (ghg-clone not named ghg: unrelated cargo binary owns that name) - cwd/history helpers stay per-shell: yy c cd clip-last + ghg/ghn/gho cd-wrappers in bash/functions/ and zsh/functions/, loaded by rc files - fish keeps only shell-state functions; converted ones now hit PATH - cp-appid ignore gating moved to .local/bin path - dot_agents/skills: 82 skills materialized from dotstate storage so dot_claude skill symlinks resolve on fresh bootstrap; dotstate profile/symlinks.json released .agents/skills .bashrc .zshrc
This commit is contained in:
1 parent
6776366ce6
commit
6406208b35
637 files changed
+100297
-497
No files matched your search
@@ -0,0 +1,102 @@
|
||||
# qk-factory-pattern: Use Query Key Factories for Complex Applications
|
||||
|
||||
## Priority: CRITICAL
|
||||
|
||||
## Explanation
|
||||
|
||||
For applications with many queries, centralize query key definitions in factory functions. This ensures consistency, enables autocomplete, prevents typos, and makes refactoring safer. Query key factories are the recommended pattern for production applications.
|
||||
|
||||
## Bad Example
|
||||
|
||||
```tsx
|
||||
// Scattered, inconsistent key definitions across files
|
||||
// file: components/TodoList.tsx
|
||||
const { data } = useQuery({
|
||||
queryKey: ['todos', 'list'],
|
||||
queryFn: fetchTodos,
|
||||
})
|
||||
|
||||
// file: components/TodoDetail.tsx
|
||||
const { data } = useQuery({
|
||||
queryKey: ['todo', id], // Inconsistent: 'todo' vs 'todos'
|
||||
queryFn: () => fetchTodo(id),
|
||||
})
|
||||
|
||||
// file: components/TodoComments.tsx
|
||||
const { data } = useQuery({
|
||||
queryKey: ['todoComments', todoId], // Different naming convention
|
||||
queryFn: () => fetchComments(todoId),
|
||||
})
|
||||
|
||||
// Invalidation is error-prone
|
||||
queryClient.invalidateQueries({ queryKey: ['todos'] }) // Misses 'todo' and 'todoComments'
|
||||
```
|
||||
|
||||
## Good Example
|
||||
|
||||
```tsx
|
||||
// file: lib/query-keys.ts
|
||||
export const todoKeys = {
|
||||
all: ['todos'] as const,
|
||||
lists: () => [...todoKeys.all, 'list'] as const,
|
||||
list: (filters: TodoFilters) => [...todoKeys.lists(), filters] as const,
|
||||
details: () => [...todoKeys.all, 'detail'] as const,
|
||||
detail: (id: number) => [...todoKeys.details(), id] as const,
|
||||
comments: (id: number) => [...todoKeys.detail(id), 'comments'] as const,
|
||||
}
|
||||
|
||||
export const userKeys = {
|
||||
all: ['users'] as const,
|
||||
detail: (id: string) => [...userKeys.all, id] as const,
|
||||
posts: (id: string) => [...userKeys.detail(id), 'posts'] as const,
|
||||
}
|
||||
|
||||
// file: components/TodoList.tsx
|
||||
import { todoKeys } from '@/lib/query-keys'
|
||||
|
||||
const { data } = useQuery({
|
||||
queryKey: todoKeys.list({ status: 'active' }),
|
||||
queryFn: () => fetchTodos({ status: 'active' }),
|
||||
})
|
||||
|
||||
// file: components/TodoDetail.tsx
|
||||
const { data } = useQuery({
|
||||
queryKey: todoKeys.detail(id),
|
||||
queryFn: () => fetchTodo(id),
|
||||
})
|
||||
|
||||
// Invalidation is type-safe and predictable
|
||||
queryClient.invalidateQueries({ queryKey: todoKeys.all }) // Invalidates everything
|
||||
queryClient.invalidateQueries({ queryKey: todoKeys.detail(5) }) // Specific todo + comments
|
||||
```
|
||||
|
||||
## Query Options Factory Pattern
|
||||
|
||||
```tsx
|
||||
// Even better: combine with queryOptions for full type safety
|
||||
import { queryOptions } from '@tanstack/react-query'
|
||||
|
||||
export const todoQueries = {
|
||||
all: () => queryOptions({
|
||||
queryKey: todoKeys.all,
|
||||
queryFn: fetchAllTodos,
|
||||
}),
|
||||
detail: (id: number) => queryOptions({
|
||||
queryKey: todoKeys.detail(id),
|
||||
queryFn: () => fetchTodo(id),
|
||||
staleTime: 5 * 60 * 1000,
|
||||
}),
|
||||
}
|
||||
|
||||
// Usage
|
||||
const { data } = useQuery(todoQueries.detail(5))
|
||||
await queryClient.prefetchQuery(todoQueries.detail(5))
|
||||
```
|
||||
|
||||
## Context
|
||||
|
||||
- Essential for applications with 10+ different query types
|
||||
- Enables IDE autocomplete and typo prevention
|
||||
- Makes invalidation patterns discoverable
|
||||
- Pairs well with `queryOptions` for full type inference
|
||||
- Consider the `@lukemorales/query-key-factory` package for standardized implementation
|
||||
Reference in new issue
Block a user