mirror of
https://github.com/prdlk/dotfiles.git
synced 2026-11-05 04:08:03 +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
+173
@@ -0,0 +1,173 @@
|
||||
# setup-query-client-context: Pass QueryClient Through Router Context
|
||||
|
||||
## Priority: CRITICAL
|
||||
|
||||
## Explanation
|
||||
|
||||
Pass the QueryClient instance through TanStack Router's context system rather than using a global. This enables proper SSR with per-request clients, testability, and type-safe access in loaders. Use `@tanstack/react-router-ssr-query` for automatic SSR integration.
|
||||
|
||||
## Bad Example
|
||||
|
||||
```tsx
|
||||
// lib/query-client.ts - Global singleton
|
||||
export const queryClient = new QueryClient()
|
||||
|
||||
// routes/posts.tsx - Importing global
|
||||
import { queryClient } from '@/lib/query-client'
|
||||
|
||||
export const Route = createFileRoute('/posts')({
|
||||
loader: async () => {
|
||||
// Using global - breaks SSR, harder to test
|
||||
return queryClient.fetchQuery(postQueries.list())
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## Good Example: Modern Router Setup
|
||||
|
||||
```tsx
|
||||
// routes/__root.tsx
|
||||
import { createRootRouteWithContext } from '@tanstack/react-router'
|
||||
import { QueryClient } from '@tanstack/react-query'
|
||||
|
||||
interface RouterContext {
|
||||
queryClient: QueryClient
|
||||
}
|
||||
|
||||
export const Route = createRootRouteWithContext<RouterContext>()({
|
||||
component: RootComponent,
|
||||
})
|
||||
|
||||
// router.tsx
|
||||
import { QueryClient } from '@tanstack/react-query'
|
||||
import { createRouter } from '@tanstack/react-router'
|
||||
import { setupRouterSsrQueryIntegration } from '@tanstack/react-router-ssr-query'
|
||||
import { routeTree } from './routeTree.gen'
|
||||
|
||||
export function getRouter() {
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
refetchOnWindowFocus: false,
|
||||
staleTime: 1000 * 60 * 2, // 2 minutes
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const router = createRouter({
|
||||
routeTree,
|
||||
context: { queryClient },
|
||||
defaultPreload: 'intent',
|
||||
defaultPreloadStaleTime: 0,
|
||||
scrollRestoration: true,
|
||||
})
|
||||
|
||||
setupRouterSsrQueryIntegration({
|
||||
router,
|
||||
queryClient,
|
||||
})
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
interface Register {
|
||||
router: ReturnType<typeof getRouter>
|
||||
}
|
||||
}
|
||||
|
||||
// routes/posts.tsx - Access from context
|
||||
export const Route = createFileRoute('/posts')({
|
||||
loader: async ({ context: { queryClient } }) => {
|
||||
// Type-safe access to queryClient from context
|
||||
await queryClient.ensureQueryData(postQueries.list())
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## Good Example: Root Route with Context
|
||||
|
||||
```tsx
|
||||
// routes/__root.tsx
|
||||
import { createRootRouteWithContext, Outlet, HeadContent, Scripts } from '@tanstack/react-router'
|
||||
import { QueryClient } from '@tanstack/react-query'
|
||||
|
||||
interface RouterContext {
|
||||
queryClient: QueryClient
|
||||
user: User | null
|
||||
}
|
||||
|
||||
export const Route = createRootRouteWithContext<RouterContext>()({
|
||||
component: RootComponent,
|
||||
beforeLoad: async ({ context }) => {
|
||||
// Prefetch auth or other global data
|
||||
await context.queryClient.ensureQueryData(authQueryOptions)
|
||||
},
|
||||
})
|
||||
|
||||
function RootComponent() {
|
||||
return (
|
||||
<html>
|
||||
<head>
|
||||
<HeadContent />
|
||||
</head>
|
||||
<body>
|
||||
<Outlet />
|
||||
<Scripts />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
TanStack Start handles SSR and hydration automatically via the Vite plugin. No separate entry files needed.
|
||||
|
||||
## Good Example: Testing with Mock QueryClient
|
||||
|
||||
```tsx
|
||||
// tests/posts.test.tsx
|
||||
import { createRouter, RouterProvider } from '@tanstack/react-router'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { render } from '@testing-library/react'
|
||||
|
||||
function renderWithProviders(route: string) {
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: { retry: false },
|
||||
},
|
||||
})
|
||||
|
||||
const router = createRouter({
|
||||
routeTree,
|
||||
context: { queryClient },
|
||||
Wrap: ({ children }) => (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
{children}
|
||||
</QueryClientProvider>
|
||||
),
|
||||
})
|
||||
|
||||
return {
|
||||
...render(<RouterProvider router={router} />),
|
||||
queryClient,
|
||||
}
|
||||
}
|
||||
|
||||
test('loads posts', async () => {
|
||||
const { queryClient } = renderWithProviders('/posts')
|
||||
|
||||
// Pre-populate cache for testing
|
||||
queryClient.setQueryData(['posts'], mockPosts)
|
||||
|
||||
// ... assertions
|
||||
})
|
||||
```
|
||||
|
||||
## Context
|
||||
|
||||
- Router context flows to all loaders and beforeLoad hooks
|
||||
- Creating QueryClient per request is essential for SSR
|
||||
- Use `setupRouterSsrQueryIntegration` for automatic SSR handling
|
||||
- Access queryClient via `context` parameter in loaders
|
||||
- This pattern enables clean dependency injection for testing
|
||||
- Install: `npm install @tanstack/react-router-ssr-query`
|
||||
Reference in new issue
Block a user