mirror of
https://github.com/prdlk/dotfiles.git
synced 2026-11-08 04:57:36 +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,206 @@
|
||||
# ssr-dehydrate-hydrate: Configure SSR Query Integration
|
||||
|
||||
## Priority: CRITICAL
|
||||
|
||||
## Explanation
|
||||
|
||||
Use `@tanstack/react-router-ssr-query` to automatically handle SSR dehydration/hydration between TanStack Router and TanStack Query. This package automates cache transfer, streaming, and redirect handling.
|
||||
|
||||
## Bad Example
|
||||
|
||||
```tsx
|
||||
// Manual dehydration - verbose and error-prone
|
||||
import { dehydrate, hydrate } from '@tanstack/react-query'
|
||||
|
||||
const router = createRouter({
|
||||
routeTree,
|
||||
context: { queryClient },
|
||||
|
||||
// Manual approach - lots of boilerplate
|
||||
dehydrate: () => ({
|
||||
queryClientState: dehydrate(queryClient),
|
||||
}),
|
||||
|
||||
hydrate: (dehydrated) => {
|
||||
hydrate(queryClient, dehydrated.queryClientState)
|
||||
},
|
||||
|
||||
Wrap: ({ children }) => (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
{children}
|
||||
</QueryClientProvider>
|
||||
),
|
||||
})
|
||||
```
|
||||
|
||||
## Good Example: Modern SSR Integration
|
||||
|
||||
```tsx
|
||||
// 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, // Let Query manage cache freshness
|
||||
scrollRestoration: true,
|
||||
defaultStructuralSharing: true,
|
||||
})
|
||||
|
||||
// Automatic SSR dehydration/hydration
|
||||
setupRouterSsrQueryIntegration({
|
||||
router,
|
||||
queryClient,
|
||||
handleRedirects: true, // Intercept redirects from queries/mutations
|
||||
wrapQueryClient: true, // Auto-wrap with QueryClientProvider
|
||||
})
|
||||
|
||||
return router
|
||||
}
|
||||
```
|
||||
|
||||
## Good Example: With Error and NotFound Components
|
||||
|
||||
```tsx
|
||||
import { DefaultCatchBoundary } from '@/components/DefaultCatchBoundary'
|
||||
import { DefaultNotFound } from '@/components/DefaultNotFound'
|
||||
|
||||
export function getRouter() {
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
refetchOnWindowFocus: false,
|
||||
staleTime: 1000 * 60 * 2,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const router = createRouter({
|
||||
routeTree,
|
||||
context: { queryClient, user: null },
|
||||
defaultPreload: 'intent',
|
||||
defaultPreloadStaleTime: 0,
|
||||
defaultErrorComponent: DefaultCatchBoundary,
|
||||
defaultNotFoundComponent: DefaultNotFound,
|
||||
scrollRestoration: true,
|
||||
defaultStructuralSharing: true,
|
||||
})
|
||||
|
||||
setupRouterSsrQueryIntegration({
|
||||
router,
|
||||
queryClient,
|
||||
handleRedirects: true,
|
||||
wrapQueryClient: true,
|
||||
})
|
||||
|
||||
return router
|
||||
}
|
||||
```
|
||||
|
||||
## Good Example: Custom QueryClientProvider
|
||||
|
||||
```tsx
|
||||
// If you need custom provider setup (e.g., for DevTools)
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
|
||||
|
||||
export function getRouter() {
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
const router = createRouter({
|
||||
routeTree,
|
||||
context: { queryClient },
|
||||
defaultPreload: 'intent',
|
||||
defaultPreloadStaleTime: 0,
|
||||
scrollRestoration: true,
|
||||
})
|
||||
|
||||
setupRouterSsrQueryIntegration({
|
||||
router,
|
||||
queryClient,
|
||||
handleRedirects: true,
|
||||
wrapQueryClient: false, // We'll provide our own
|
||||
})
|
||||
|
||||
// Custom wrapper with DevTools
|
||||
router.options.Wrap = ({ children }) => (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
{children}
|
||||
{process.env.NODE_ENV === 'development' && (
|
||||
<ReactQueryDevtools initialIsOpen={false} />
|
||||
)}
|
||||
</QueryClientProvider>
|
||||
)
|
||||
|
||||
return router
|
||||
}
|
||||
```
|
||||
|
||||
## Good Example: Vite Configuration
|
||||
|
||||
```ts
|
||||
// vite.config.ts
|
||||
import { tanstackStart } from "@tanstack/start/plugin/vite"
|
||||
import { defineConfig } from "vite"
|
||||
import react from "@vitejs/plugin-react"
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
tanstackStart(), // Handles SSR entry points automatically
|
||||
react(),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
TanStack Start handles client hydration and SSR automatically via the Vite plugin. No separate `client.tsx` or `ssr.tsx` files are needed.
|
||||
|
||||
## setupRouterSsrQueryIntegration Options
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
|--------|------|---------|-------------|
|
||||
| `router` | Router | Required | Your router instance |
|
||||
| `queryClient` | QueryClient | Required | Your QueryClient instance |
|
||||
| `handleRedirects` | boolean | `true` | Intercept and handle redirects from queries/mutations |
|
||||
| `wrapQueryClient` | boolean | `true` | Wrap router with QueryClientProvider automatically |
|
||||
|
||||
## SSR Data Flow
|
||||
|
||||
```
|
||||
Server:
|
||||
1. Request received
|
||||
2. getRouter() creates fresh QueryClient + Router
|
||||
3. setupRouterSsrQueryIntegration connects them
|
||||
4. Router matches routes, runs loaders
|
||||
5. Loaders call ensureQueryData → data cached
|
||||
6. Integration auto-dehydrates QueryClient state
|
||||
7. HTML + serialized state streamed to client
|
||||
|
||||
Client:
|
||||
1. HTML rendered (React hydrates)
|
||||
2. getRouter() creates fresh QueryClient + Router
|
||||
3. Integration auto-hydrates state from server
|
||||
4. useSuspenseQuery finds data in cache - no refetch!
|
||||
5. App is interactive with data already loaded
|
||||
```
|
||||
|
||||
## Context
|
||||
|
||||
- Install: `npm install @tanstack/react-router-ssr-query`
|
||||
- Creates fresh QueryClient per request (required for SSR)
|
||||
- Handles streaming of queries that resolve during render
|
||||
- Set `defaultPreloadStaleTime: 0` to let Query manage freshness
|
||||
- Each SSR request needs its own router instance via `getRouter()`
|
||||
- The integration handles all dehydration/hydration automatically
|
||||
Reference in new issue
Block a user