@smicolon/ai-kit 0.3.2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +73 -40
  2. package/dist/index.js +312 -127
  3. package/package.json +5 -5
  4. package/.claude-plugin/marketplace.json +0 -369
  5. package/packs/architect/CHANGELOG.md +0 -17
  6. package/packs/architect/README.md +0 -58
  7. package/packs/architect/agents/system-architect.md +0 -768
  8. package/packs/architect/commands/diagram-create.md +0 -300
  9. package/packs/better-auth/.mcp.json +0 -14
  10. package/packs/better-auth/CHANGELOG.md +0 -26
  11. package/packs/better-auth/README.md +0 -125
  12. package/packs/better-auth/agents/auth-architect.md +0 -278
  13. package/packs/better-auth/commands/auth-provider-add.md +0 -265
  14. package/packs/better-auth/commands/auth-setup.md +0 -298
  15. package/packs/better-auth/skills/auth-security/SKILL.md +0 -425
  16. package/packs/better-auth/skills/better-auth-patterns/SKILL.md +0 -455
  17. package/packs/dev-loop/CHANGELOG.md +0 -69
  18. package/packs/dev-loop/README.md +0 -155
  19. package/packs/dev-loop/commands/cancel-dev.md +0 -21
  20. package/packs/dev-loop/commands/dev-loop.md +0 -72
  21. package/packs/dev-loop/commands/dev-plan.md +0 -351
  22. package/packs/dev-loop/hooks/hooks.json +0 -15
  23. package/packs/dev-loop/hooks/stop-hook.sh +0 -178
  24. package/packs/dev-loop/scripts/setup-dev-loop.sh +0 -194
  25. package/packs/dev-loop/skills/tdd-planner/SKILL.md +0 -249
  26. package/packs/dev-loop/skills/tdd-planner/references/framework-patterns.md +0 -874
  27. package/packs/dev-loop/skills/tdd-planner/references/good-example.md +0 -260
  28. package/packs/dev-loop/skills/tdd-planner/references/plan-template.md +0 -275
  29. package/packs/django/CHANGELOG.md +0 -39
  30. package/packs/django/README.md +0 -92
  31. package/packs/django/agents/django-architect.md +0 -182
  32. package/packs/django/agents/django-builder.md +0 -250
  33. package/packs/django/agents/django-feature-based.md +0 -420
  34. package/packs/django/agents/django-reviewer.md +0 -253
  35. package/packs/django/agents/django-tester.md +0 -230
  36. package/packs/django/commands/api-endpoint.md +0 -285
  37. package/packs/django/commands/model-create.md +0 -178
  38. package/packs/django/commands/test-generate.md +0 -325
  39. package/packs/django/rules/migrations.md +0 -138
  40. package/packs/django/rules/models.md +0 -167
  41. package/packs/django/rules/serializers.md +0 -126
  42. package/packs/django/rules/services.md +0 -131
  43. package/packs/django/rules/tests.md +0 -140
  44. package/packs/django/rules/views.md +0 -102
  45. package/packs/django/skills/import-convention-enforcer/SKILL.md +0 -226
  46. package/packs/django/skills/import-convention-enforcer/patterns/django-imports.md +0 -343
  47. package/packs/django/skills/migration-safety-checker/SKILL.md +0 -375
  48. package/packs/django/skills/model-entity-validator/SKILL.md +0 -298
  49. package/packs/django/skills/performance-optimizer/SKILL.md +0 -447
  50. package/packs/django/skills/red-phase-verifier/SKILL.md +0 -180
  51. package/packs/django/skills/security-first-validator/SKILL.md +0 -435
  52. package/packs/django/skills/test-coverage-advisor/SKILL.md +0 -394
  53. package/packs/django/skills/test-validity-checker/SKILL.md +0 -194
  54. package/packs/failure-log/CHANGELOG.md +0 -20
  55. package/packs/failure-log/README.md +0 -168
  56. package/packs/failure-log/commands/failure-add.md +0 -106
  57. package/packs/failure-log/commands/failure-list.md +0 -89
  58. package/packs/failure-log/hooks/hooks.json +0 -16
  59. package/packs/failure-log/hooks/scripts/inject-failures.sh +0 -64
  60. package/packs/failure-log/skills/failure-log-manager/SKILL.md +0 -164
  61. package/packs/flutter/CHANGELOG.md +0 -19
  62. package/packs/flutter/README.md +0 -170
  63. package/packs/flutter/agents/flutter-architect.md +0 -166
  64. package/packs/flutter/agents/flutter-builder.md +0 -303
  65. package/packs/flutter/agents/release-manager.md +0 -355
  66. package/packs/flutter/commands/fastlane-setup.md +0 -188
  67. package/packs/flutter/commands/flutter-build.md +0 -90
  68. package/packs/flutter/commands/flutter-deploy.md +0 -133
  69. package/packs/flutter/commands/flutter-test.md +0 -117
  70. package/packs/flutter/commands/signing-setup.md +0 -209
  71. package/packs/flutter/hooks/hooks.json +0 -17
  72. package/packs/flutter/skills/fastlane-knowledge/SKILL.md +0 -193
  73. package/packs/flutter/skills/flutter-architecture/SKILL.md +0 -127
  74. package/packs/flutter/skills/store-publishing/SKILL.md +0 -163
  75. package/packs/hono/CHANGELOG.md +0 -19
  76. package/packs/hono/README.md +0 -143
  77. package/packs/hono/agents/hono-architect.md +0 -240
  78. package/packs/hono/agents/hono-builder.md +0 -285
  79. package/packs/hono/agents/hono-reviewer.md +0 -279
  80. package/packs/hono/agents/hono-tester.md +0 -346
  81. package/packs/hono/commands/middleware-create.md +0 -223
  82. package/packs/hono/commands/project-init.md +0 -306
  83. package/packs/hono/commands/route-create.md +0 -153
  84. package/packs/hono/commands/rpc-client.md +0 -263
  85. package/packs/hono/skills/cloudflare-bindings/SKILL.md +0 -408
  86. package/packs/hono/skills/hono-patterns/SKILL.md +0 -309
  87. package/packs/hono/skills/rpc-typesafe/SKILL.md +0 -388
  88. package/packs/hono/skills/zod-validation/SKILL.md +0 -332
  89. package/packs/nestjs/CHANGELOG.md +0 -29
  90. package/packs/nestjs/README.md +0 -75
  91. package/packs/nestjs/agents/nestjs-architect.md +0 -402
  92. package/packs/nestjs/agents/nestjs-builder.md +0 -301
  93. package/packs/nestjs/agents/nestjs-tester.md +0 -437
  94. package/packs/nestjs/commands/module-create.md +0 -369
  95. package/packs/nestjs/rules/controllers.md +0 -92
  96. package/packs/nestjs/rules/dto.md +0 -124
  97. package/packs/nestjs/rules/entities.md +0 -102
  98. package/packs/nestjs/rules/services.md +0 -106
  99. package/packs/nestjs/skills/barrel-export-manager/SKILL.md +0 -389
  100. package/packs/nestjs/skills/import-convention-enforcer/SKILL.md +0 -365
  101. package/packs/nextjs/CHANGELOG.md +0 -36
  102. package/packs/nextjs/README.md +0 -76
  103. package/packs/nextjs/agents/frontend-tester.md +0 -680
  104. package/packs/nextjs/agents/frontend-visual.md +0 -820
  105. package/packs/nextjs/agents/nextjs-architect.md +0 -331
  106. package/packs/nextjs/agents/nextjs-modular.md +0 -433
  107. package/packs/nextjs/commands/component-create.md +0 -398
  108. package/packs/nextjs/rules/api-routes.md +0 -129
  109. package/packs/nextjs/rules/components.md +0 -106
  110. package/packs/nextjs/rules/hooks.md +0 -132
  111. package/packs/nextjs/skills/accessibility-validator/SKILL.md +0 -445
  112. package/packs/nextjs/skills/import-convention-enforcer/SKILL.md +0 -399
  113. package/packs/nextjs/skills/react-form-validator/SKILL.md +0 -569
  114. package/packs/nuxtjs/CHANGELOG.md +0 -30
  115. package/packs/nuxtjs/README.md +0 -56
  116. package/packs/nuxtjs/agents/frontend-tester.md +0 -680
  117. package/packs/nuxtjs/agents/frontend-visual.md +0 -820
  118. package/packs/nuxtjs/agents/nuxtjs-architect.md +0 -537
  119. package/packs/nuxtjs/commands/component-create.md +0 -223
  120. package/packs/nuxtjs/rules/components.md +0 -101
  121. package/packs/nuxtjs/rules/composables.md +0 -118
  122. package/packs/nuxtjs/rules/server-routes.md +0 -127
  123. package/packs/nuxtjs/skills/accessibility-validator/SKILL.md +0 -183
  124. package/packs/nuxtjs/skills/import-convention-enforcer/SKILL.md +0 -196
  125. package/packs/nuxtjs/skills/veevalidate-form-validator/SKILL.md +0 -190
  126. package/packs/onboard/CHANGELOG.md +0 -22
  127. package/packs/onboard/README.md +0 -103
  128. package/packs/onboard/agents/onboard-guide.md +0 -118
  129. package/packs/onboard/commands/onboard.md +0 -313
  130. package/packs/onboard/skills/onboard-context-provider/SKILL.md +0 -98
  131. package/packs/tanstack-router/CHANGELOG.md +0 -30
  132. package/packs/tanstack-router/README.md +0 -113
  133. package/packs/tanstack-router/agents/tanstack-architect.md +0 -173
  134. package/packs/tanstack-router/agents/tanstack-builder.md +0 -360
  135. package/packs/tanstack-router/agents/tanstack-tester.md +0 -454
  136. package/packs/tanstack-router/commands/form-create.md +0 -313
  137. package/packs/tanstack-router/commands/query-create.md +0 -263
  138. package/packs/tanstack-router/commands/route-create.md +0 -190
  139. package/packs/tanstack-router/commands/table-create.md +0 -413
  140. package/packs/tanstack-router/skills/ai-patterns/SKILL.md +0 -370
  141. package/packs/tanstack-router/skills/db-patterns/SKILL.md +0 -346
  142. package/packs/tanstack-router/skills/devtools-patterns/SKILL.md +0 -415
  143. package/packs/tanstack-router/skills/form-patterns/SKILL.md +0 -425
  144. package/packs/tanstack-router/skills/pacer-patterns/SKILL.md +0 -341
  145. package/packs/tanstack-router/skills/query-patterns/SKILL.md +0 -359
  146. package/packs/tanstack-router/skills/router-patterns/SKILL.md +0 -285
  147. package/packs/tanstack-router/skills/store-patterns/SKILL.md +0 -351
  148. package/packs/tanstack-router/skills/table-patterns/SKILL.md +0 -531
  149. package/packs/tanstack-router/skills/tanstack-conventions/SKILL.md +0 -428
  150. package/packs/tanstack-router/skills/virtual-patterns/SKILL.md +0 -490
  151. package/packs/worktree/CHANGELOG.md +0 -45
  152. package/packs/worktree/README.md +0 -219
  153. package/packs/worktree/commands/wt.md +0 -93
  154. package/packs/worktree/scripts/wt.sh +0 -957
  155. package/packs/worktree/skills/worktree-manager/SKILL.md +0 -113
@@ -1,370 +0,0 @@
1
- ---
2
- name: TanStack AI Patterns (Alpha)
3
- description: >-
4
- TanStack AI patterns for unified AI SDK integration. Activates when
5
- implementing AI chat, streaming responses, or AI-powered features.
6
- NOTE: Alpha library - API may change.
7
- version: 1.0.0
8
- ---
9
-
10
- # TanStack AI Patterns (Alpha)
11
-
12
- > **Alpha Library**: TanStack AI is in alpha. APIs may change between versions.
13
-
14
- TanStack AI provides a unified SDK for integrating AI capabilities into React applications.
15
-
16
- ## Core Concepts
17
-
18
- - **Providers**: Backend AI providers (OpenAI, Anthropic, etc.)
19
- - **Streams**: Real-time streaming responses
20
- - **Chat**: Conversational interfaces
21
- - **Completion**: Text completion
22
- - **Hooks**: React hooks for AI interactions
23
-
24
- ## Basic Setup
25
-
26
- ```typescript
27
- // lib/ai.ts
28
- import { createAI } from '@tanstack/ai'
29
-
30
- export const ai = createAI({
31
- provider: 'openai',
32
- apiKey: import.meta.env.VITE_OPENAI_API_KEY,
33
- // Or use server-side proxy
34
- baseUrl: '/api/ai',
35
- })
36
- ```
37
-
38
- ## Chat Interface
39
-
40
- ```typescript
41
- import { useChat } from '@tanstack/ai-react'
42
- import { ai } from '@/lib/ai'
43
-
44
- function ChatInterface() {
45
- const {
46
- messages,
47
- input,
48
- setInput,
49
- sendMessage,
50
- isLoading,
51
- error,
52
- } = useChat({
53
- ai,
54
- model: 'gpt-4',
55
- systemPrompt: 'You are a helpful assistant.',
56
- })
57
-
58
- const handleSubmit = (e: React.FormEvent) => {
59
- e.preventDefault()
60
- if (input.trim()) {
61
- sendMessage(input)
62
- setInput('')
63
- }
64
- }
65
-
66
- return (
67
- <div className="chat-container">
68
- <div className="messages">
69
- {messages.map((message) => (
70
- <div
71
- key={message.id}
72
- className={`message ${message.role}`}
73
- >
74
- {message.content}
75
- </div>
76
- ))}
77
- {isLoading && <div className="loading">Thinking...</div>}
78
- </div>
79
-
80
- <form onSubmit={handleSubmit}>
81
- <input
82
- value={input}
83
- onChange={(e) => setInput(e.target.value)}
84
- placeholder="Type a message..."
85
- disabled={isLoading}
86
- />
87
- <button type="submit" disabled={isLoading || !input.trim()}>
88
- Send
89
- </button>
90
- </form>
91
-
92
- {error && <div className="error">{error.message}</div>}
93
- </div>
94
- )
95
- }
96
- ```
97
-
98
- ## Streaming Responses
99
-
100
- ```typescript
101
- import { useCompletion } from '@tanstack/ai-react'
102
- import { ai } from '@/lib/ai'
103
-
104
- function StreamingCompletion() {
105
- const {
106
- completion,
107
- complete,
108
- isLoading,
109
- stop,
110
- } = useCompletion({
111
- ai,
112
- model: 'gpt-4',
113
- })
114
-
115
- const handleGenerate = () => {
116
- complete('Write a short story about a robot learning to paint.')
117
- }
118
-
119
- return (
120
- <div>
121
- <button onClick={handleGenerate} disabled={isLoading}>
122
- Generate Story
123
- </button>
124
- {isLoading && (
125
- <button onClick={stop}>Stop</button>
126
- )}
127
- <div className="completion">
128
- {completion}
129
- {isLoading && <span className="cursor">|</span>}
130
- </div>
131
- </div>
132
- )
133
- }
134
- ```
135
-
136
- ## Server-Side Proxy Pattern
137
-
138
- ```typescript
139
- // For security, proxy AI calls through your server
140
-
141
- // api/ai/chat.ts (server route)
142
- import { OpenAI } from 'openai'
143
-
144
- const openai = new OpenAI({
145
- apiKey: process.env.OPENAI_API_KEY,
146
- })
147
-
148
- export async function POST(request: Request) {
149
- const { messages, model } = await request.json()
150
-
151
- const stream = await openai.chat.completions.create({
152
- model,
153
- messages,
154
- stream: true,
155
- })
156
-
157
- return new Response(stream.toReadableStream(), {
158
- headers: {
159
- 'Content-Type': 'text/event-stream',
160
- 'Cache-Control': 'no-cache',
161
- 'Connection': 'keep-alive',
162
- },
163
- })
164
- }
165
-
166
- // Client setup
167
- export const ai = createAI({
168
- provider: 'openai',
169
- baseUrl: '/api/ai', // Use server proxy
170
- })
171
- ```
172
-
173
- ## Chat with Context
174
-
175
- ```typescript
176
- import { useChat } from '@tanstack/ai-react'
177
-
178
- function ContextualChat({ documentContent }: { documentContent: string }) {
179
- const chat = useChat({
180
- ai,
181
- model: 'gpt-4',
182
- systemPrompt: `You are analyzing the following document. Answer questions about it.
183
-
184
- Document:
185
- ${documentContent}`,
186
- })
187
-
188
- return <ChatUI {...chat} />
189
- }
190
- ```
191
-
192
- ## Multi-Turn Conversation
193
-
194
- ```typescript
195
- import { useChat } from '@tanstack/ai-react'
196
- import { useState } from 'react'
197
-
198
- function ConversationWithHistory() {
199
- const [conversations, setConversations] = useState<Conversation[]>([])
200
- const [activeConversation, setActiveConversation] = useState<string | null>(null)
201
-
202
- const chat = useChat({
203
- ai,
204
- model: 'gpt-4',
205
- initialMessages: activeConversation
206
- ? conversations.find(c => c.id === activeConversation)?.messages
207
- : [],
208
- onFinish: (message) => {
209
- // Save conversation
210
- if (activeConversation) {
211
- setConversations(prev =>
212
- prev.map(c =>
213
- c.id === activeConversation
214
- ? { ...c, messages: [...c.messages, message] }
215
- : c
216
- )
217
- )
218
- }
219
- },
220
- })
221
-
222
- const startNewConversation = () => {
223
- const id = crypto.randomUUID()
224
- setConversations(prev => [...prev, { id, messages: [] }])
225
- setActiveConversation(id)
226
- }
227
-
228
- return (
229
- <div className="flex">
230
- <aside>
231
- <button onClick={startNewConversation}>New Chat</button>
232
- {conversations.map(conv => (
233
- <button
234
- key={conv.id}
235
- onClick={() => setActiveConversation(conv.id)}
236
- className={activeConversation === conv.id ? 'active' : ''}
237
- >
238
- Conversation {conv.id.slice(0, 8)}
239
- </button>
240
- ))}
241
- </aside>
242
- <main>
243
- <ChatUI {...chat} />
244
- </main>
245
- </div>
246
- )
247
- }
248
- ```
249
-
250
- ## Function Calling
251
-
252
- ```typescript
253
- import { useChat } from '@tanstack/ai-react'
254
-
255
- const functions = [
256
- {
257
- name: 'get_weather',
258
- description: 'Get the current weather for a location',
259
- parameters: {
260
- type: 'object',
261
- properties: {
262
- location: { type: 'string', description: 'City name' },
263
- },
264
- required: ['location'],
265
- },
266
- },
267
- ]
268
-
269
- function ChatWithFunctions() {
270
- const chat = useChat({
271
- ai,
272
- model: 'gpt-4',
273
- functions,
274
- onFunctionCall: async (name, args) => {
275
- if (name === 'get_weather') {
276
- const weather = await fetchWeather(args.location)
277
- return JSON.stringify(weather)
278
- }
279
- return null
280
- },
281
- })
282
-
283
- return <ChatUI {...chat} />
284
- }
285
- ```
286
-
287
- ## Integration with Query
288
-
289
- ```typescript
290
- import { useQuery } from '@tanstack/react-query'
291
- import { useChat } from '@tanstack/ai-react'
292
-
293
- function AIAssistedSearch({ query }: { query: string }) {
294
- // Fetch data with Query
295
- const { data: results } = useQuery({
296
- queryKey: ['search', query],
297
- queryFn: () => searchApi.search(query),
298
- })
299
-
300
- // Use AI to summarize results
301
- const { completion, complete } = useCompletion({
302
- ai,
303
- model: 'gpt-4',
304
- })
305
-
306
- useEffect(() => {
307
- if (results?.length) {
308
- complete(`Summarize these search results:\n${JSON.stringify(results)}`)
309
- }
310
- }, [results])
311
-
312
- return (
313
- <div>
314
- <h2>AI Summary</h2>
315
- <p>{completion}</p>
316
- <h2>Results</h2>
317
- <ResultsList results={results} />
318
- </div>
319
- )
320
- }
321
- ```
322
-
323
- ## Conventions
324
-
325
- 1. **Server proxy** - Never expose API keys to client
326
- 2. **Streaming** - Use streaming for better UX
327
- 3. **Error handling** - Always handle AI errors gracefully
328
- 4. **Rate limiting** - Implement client-side throttling
329
- 5. **Token management** - Track and limit token usage
330
- 6. **Cancellation** - Allow users to stop generation
331
-
332
- ## Anti-Patterns
333
-
334
- ```typescript
335
- // ❌ WRONG: API key in client
336
- const ai = createAI({
337
- provider: 'openai',
338
- apiKey: 'sk-...', // Never do this!
339
- })
340
-
341
- // ✅ CORRECT: Use server proxy
342
- const ai = createAI({
343
- provider: 'openai',
344
- baseUrl: '/api/ai',
345
- })
346
-
347
- // ❌ WRONG: No loading state
348
- function Chat() {
349
- const { messages, sendMessage } = useChat({ ai })
350
- return <div>{messages.map(...)}</div>
351
- }
352
-
353
- // ✅ CORRECT: Show loading state
354
- function Chat() {
355
- const { messages, sendMessage, isLoading } = useChat({ ai })
356
- return (
357
- <div>
358
- {messages.map(...)}
359
- {isLoading && <Typing />}
360
- </div>
361
- )
362
- }
363
-
364
- // ❌ WRONG: No error handling
365
- const { completion } = useCompletion({ ai })
366
-
367
- // ✅ CORRECT: Handle errors
368
- const { completion, error } = useCompletion({ ai })
369
- if (error) return <ErrorMessage error={error} />
370
- ```
@@ -1,346 +0,0 @@
1
- ---
2
- name: TanStack DB Patterns (Beta)
3
- description: >-
4
- TanStack DB patterns for client-first reactive data stores. Activates when
5
- implementing offline-first apps, local-first data, or reactive client databases.
6
- NOTE: Beta library - API may change.
7
- version: 1.0.0
8
- ---
9
-
10
- # TanStack DB Patterns (Beta)
11
-
12
- > **Beta Library**: TanStack DB is in beta. APIs may change between versions.
13
-
14
- TanStack DB provides a client-first reactive data store with optional sync to remote sources.
15
-
16
- ## Core Concepts
17
-
18
- - **Collections**: Named groups of documents (like tables)
19
- - **Documents**: Individual records with unique IDs
20
- - **Queries**: Reactive queries that update when data changes
21
- - **Transactions**: Atomic operations across multiple documents
22
- - **Sync**: Optional sync to remote backends
23
-
24
- ## Basic Setup
25
-
26
- ```typescript
27
- // lib/db.ts
28
- import { createDB, createCollection } from '@tanstack/db'
29
-
30
- // Define document types
31
- interface Post {
32
- id: string
33
- title: string
34
- content: string
35
- authorId: string
36
- published: boolean
37
- createdAt: number
38
- updatedAt: number
39
- }
40
-
41
- interface User {
42
- id: string
43
- name: string
44
- email: string
45
- }
46
-
47
- // Create database
48
- export const db = createDB({
49
- collections: {
50
- posts: createCollection<Post>(),
51
- users: createCollection<User>(),
52
- },
53
- })
54
- ```
55
-
56
- ## CRUD Operations
57
-
58
- ### Create
59
- ```typescript
60
- import { db } from '@/lib/db'
61
-
62
- // Insert a single document
63
- const newPost = await db.posts.insert({
64
- id: crypto.randomUUID(),
65
- title: 'My Post',
66
- content: 'Post content...',
67
- authorId: 'user-1',
68
- published: false,
69
- createdAt: Date.now(),
70
- updatedAt: Date.now(),
71
- })
72
-
73
- // Insert multiple documents
74
- await db.posts.insertMany([
75
- { id: '1', title: 'Post 1', ... },
76
- { id: '2', title: 'Post 2', ... },
77
- ])
78
- ```
79
-
80
- ### Read
81
- ```typescript
82
- // Get by ID
83
- const post = await db.posts.get('post-id')
84
-
85
- // Query with filters
86
- const publishedPosts = await db.posts.findMany({
87
- where: { published: true },
88
- orderBy: { createdAt: 'desc' },
89
- limit: 10,
90
- })
91
-
92
- // Query with complex filters
93
- const userPosts = await db.posts.findMany({
94
- where: {
95
- authorId: 'user-1',
96
- published: true,
97
- },
98
- })
99
- ```
100
-
101
- ### Update
102
- ```typescript
103
- // Update by ID
104
- await db.posts.update('post-id', {
105
- title: 'Updated Title',
106
- updatedAt: Date.now(),
107
- })
108
-
109
- // Update with function
110
- await db.posts.update('post-id', (post) => ({
111
- ...post,
112
- viewCount: post.viewCount + 1,
113
- updatedAt: Date.now(),
114
- }))
115
-
116
- // Update many
117
- await db.posts.updateMany(
118
- { where: { authorId: 'user-1' } },
119
- { published: false }
120
- )
121
- ```
122
-
123
- ### Delete
124
- ```typescript
125
- // Delete by ID
126
- await db.posts.delete('post-id')
127
-
128
- // Delete many
129
- await db.posts.deleteMany({
130
- where: { published: false },
131
- })
132
- ```
133
-
134
- ## Reactive Queries in React
135
-
136
- ```typescript
137
- import { useQuery } from '@tanstack/db-react'
138
- import { db } from '@/lib/db'
139
-
140
- function PostList() {
141
- // Reactive query - updates when data changes
142
- const posts = useQuery(
143
- db.posts.query({
144
- where: { published: true },
145
- orderBy: { createdAt: 'desc' },
146
- })
147
- )
148
-
149
- return (
150
- <ul>
151
- {posts.map((post) => (
152
- <PostCard key={post.id} post={post} />
153
- ))}
154
- </ul>
155
- )
156
- }
157
-
158
- function PostDetail({ postId }: { postId: string }) {
159
- // Single document query
160
- const post = useQuery(db.posts.get(postId))
161
-
162
- if (!post) return <NotFound />
163
-
164
- return <article>{post.title}</article>
165
- }
166
- ```
167
-
168
- ## Transactions
169
-
170
- ```typescript
171
- import { db } from '@/lib/db'
172
-
173
- async function transferPost(postId: string, newAuthorId: string) {
174
- await db.transaction(async (tx) => {
175
- // Get current post
176
- const post = await tx.posts.get(postId)
177
- if (!post) throw new Error('Post not found')
178
-
179
- // Update post author
180
- await tx.posts.update(postId, {
181
- authorId: newAuthorId,
182
- updatedAt: Date.now(),
183
- })
184
-
185
- // Update user post counts (if tracking)
186
- await tx.users.update(post.authorId, (user) => ({
187
- ...user,
188
- postCount: user.postCount - 1,
189
- }))
190
-
191
- await tx.users.update(newAuthorId, (user) => ({
192
- ...user,
193
- postCount: user.postCount + 1,
194
- }))
195
- })
196
- }
197
- ```
198
-
199
- ## Sync with Remote Backend
200
-
201
- ```typescript
202
- // lib/db.ts
203
- import { createDB, createCollection, createSyncProvider } from '@tanstack/db'
204
-
205
- const syncProvider = createSyncProvider({
206
- // Pull changes from server
207
- pull: async (collection, lastSync) => {
208
- const response = await fetch(`/api/${collection}/sync?since=${lastSync}`)
209
- return response.json()
210
- },
211
-
212
- // Push changes to server
213
- push: async (collection, changes) => {
214
- await fetch(`/api/${collection}/sync`, {
215
- method: 'POST',
216
- body: JSON.stringify(changes),
217
- })
218
- },
219
- })
220
-
221
- export const db = createDB({
222
- collections: {
223
- posts: createCollection<Post>(),
224
- users: createCollection<User>(),
225
- },
226
- sync: syncProvider,
227
- })
228
-
229
- // Trigger sync
230
- await db.sync()
231
-
232
- // Auto-sync on interval
233
- setInterval(() => db.sync(), 30000)
234
- ```
235
-
236
- ## Offline-First Pattern
237
-
238
- ```typescript
239
- import { useQuery, useMutation } from '@tanstack/db-react'
240
- import { db } from '@/lib/db'
241
-
242
- function CreatePostForm() {
243
- const createPost = useMutation(db.posts.insert)
244
-
245
- const handleSubmit = async (data: PostInput) => {
246
- // Immediately available locally
247
- await createPost.mutate({
248
- id: crypto.randomUUID(),
249
- ...data,
250
- createdAt: Date.now(),
251
- updatedAt: Date.now(),
252
- _pending: true, // Mark as pending sync
253
- })
254
-
255
- // Sync will happen in background when online
256
- if (navigator.onLine) {
257
- db.sync()
258
- }
259
- }
260
-
261
- return <form onSubmit={handleSubmit}>{/* form fields */}</form>
262
- }
263
-
264
- // Show pending items differently
265
- function PostCard({ post }: { post: Post }) {
266
- return (
267
- <div className={post._pending ? 'opacity-50' : ''}>
268
- {post.title}
269
- {post._pending && <span>Syncing...</span>}
270
- </div>
271
- )
272
- }
273
- ```
274
-
275
- ## Integration with TanStack Query
276
-
277
- ```typescript
278
- // Hybrid approach: DB for offline, Query for server sync
279
- import { useQuery as useReactQuery } from '@tanstack/react-query'
280
- import { useQuery as useDBQuery } from '@tanstack/db-react'
281
- import { db } from '@/lib/db'
282
-
283
- function PostList() {
284
- // Local DB for immediate data
285
- const localPosts = useDBQuery(
286
- db.posts.query({ where: { published: true } })
287
- )
288
-
289
- // Server query for sync
290
- const { data: serverPosts } = useReactQuery({
291
- queryKey: ['posts', 'published'],
292
- queryFn: () => postApi.getPosts({ published: true }),
293
- onSuccess: (posts) => {
294
- // Update local DB with server data
295
- db.posts.upsertMany(posts)
296
- },
297
- })
298
-
299
- // Use local data (always available, even offline)
300
- return (
301
- <ul>
302
- {localPosts.map((post) => (
303
- <PostCard key={post.id} post={post} />
304
- ))}
305
- </ul>
306
- )
307
- }
308
- ```
309
-
310
- ## When to Use TanStack DB
311
-
312
- | Scenario | Solution |
313
- |----------|----------|
314
- | Standard server data | TanStack Query |
315
- | Offline-first app | TanStack DB |
316
- | Local-first with sync | TanStack DB + sync |
317
- | Real-time collaboration | TanStack DB + WebSocket sync |
318
- | Complex client state | TanStack DB or Store |
319
-
320
- ## Conventions
321
-
322
- 1. **Type your collections** - Always define document interfaces
323
- 2. **Use transactions** - For multi-document operations
324
- 3. **Handle offline** - Design for offline-first
325
- 4. **Sync strategy** - Define clear sync patterns
326
- 5. **Combine with Query** - Use Query for pure server data
327
-
328
- ## Anti-Patterns
329
-
330
- ```typescript
331
- // ❌ WRONG: Not using transactions for related updates
332
- await db.posts.delete(postId)
333
- await db.comments.deleteMany({ where: { postId } }) // Could fail leaving orphans
334
-
335
- // ✅ CORRECT: Use transaction
336
- await db.transaction(async (tx) => {
337
- await tx.posts.delete(postId)
338
- await tx.comments.deleteMany({ where: { postId } })
339
- })
340
-
341
- // ❌ WRONG: Using DB for pure server data without offline need
342
- const posts = useDBQuery(db.posts.query({}))
343
-
344
- // ✅ CORRECT: Use Query for server data
345
- const { data: posts } = useQuery(postsQueryOptions())
346
- ```