@objectstack/client-react 0.9.0 → 0.9.2

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 (3) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +158 -0
  3. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @objectstack/client-react
2
2
 
3
+ ## 0.9.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @objectstack/spec@0.9.2
9
+ - @objectstack/client@0.9.2
10
+ - @objectstack/core@0.9.2
11
+
12
+ ## 0.9.1
13
+
14
+ ### Patch Changes
15
+
16
+ - Patch release for maintenance and stability improvements. All packages updated with unified versioning.
17
+ - Updated dependencies
18
+ - @objectstack/spec@0.9.1
19
+ - @objectstack/core@0.9.1
20
+ - @objectstack/client@0.9.1
21
+
3
22
  ## 0.8.2
4
23
 
5
24
  ### Patch Changes
package/README.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  React hooks for ObjectStack Client SDK - Type-safe data fetching and mutations for React applications.
4
4
 
5
+ ## 🤖 AI Development Context
6
+
7
+ **Role**: React Bindings for Client SDK
8
+ **Usage**:
9
+ - Use `useQuery`, `useMutation` hooks.
10
+ - Similar to TanStack Query but specialized for ObjectStack.
11
+
5
12
  ## Installation
6
13
 
7
14
  ```bash
@@ -268,6 +275,157 @@ const { mutate } = useMutation<Task, Partial<Task>>('todo_task', 'create');
268
275
  // mutate expects Partial<Task>
269
276
  ```
270
277
 
278
+ ## Common Patterns
279
+
280
+ ### Master-Detail View
281
+
282
+ ```tsx
283
+ function TaskList() {
284
+ const [selectedId, setSelectedId] = useState<string | null>(null);
285
+
286
+ const { data: tasks } = useQuery('todo_task', {
287
+ select: ['id', 'subject'],
288
+ sort: ['-created_at']
289
+ });
290
+
291
+ const { data: selectedTask } = useQuery('todo_task', {
292
+ filters: ['id', '=', selectedId],
293
+ enabled: !!selectedId // Only fetch when ID is selected
294
+ });
295
+
296
+ return (
297
+ <div className="flex">
298
+ <TaskListPanel tasks={tasks?.value} onSelect={setSelectedId} />
299
+ <TaskDetail task={selectedTask?.value?.[0]} />
300
+ </div>
301
+ );
302
+ }
303
+ ```
304
+
305
+ ### Optimistic Updates
306
+
307
+ ```tsx
308
+ function TaskToggle({ taskId, completed }) {
309
+ const { mutate } = useMutation('todo_task', 'update', {
310
+ onMutate: async (variables) => {
311
+ // Optimistically update UI
312
+ return { previousValue: completed };
313
+ },
314
+ onError: (error, variables, context) => {
315
+ // Revert on error
316
+ console.error('Update failed, reverting', context.previousValue);
317
+ },
318
+ onSuccess: () => {
319
+ // Refetch to ensure data consistency
320
+ queryClient.invalidateQueries(['todo_task']);
321
+ }
322
+ });
323
+
324
+ return (
325
+ <Checkbox
326
+ checked={completed}
327
+ onChange={(e) => mutate({ id: taskId, is_completed: e.target.checked })}
328
+ />
329
+ );
330
+ }
331
+ ```
332
+
333
+ ### Dependent Queries
334
+
335
+ ```tsx
336
+ function ProjectTasks({ projectId }) {
337
+ // First, get project details
338
+ const { data: project } = useQuery('project', {
339
+ filters: ['id', '=', projectId]
340
+ });
341
+
342
+ // Then, get tasks for this project
343
+ const { data: tasks } = useQuery('todo_task', {
344
+ filters: ['project_id', '=', projectId],
345
+ enabled: !!project // Only fetch when project is loaded
346
+ });
347
+
348
+ return (
349
+ <div>
350
+ <h2>{project?.value?.[0]?.name}</h2>
351
+ <TaskList tasks={tasks?.value} />
352
+ </div>
353
+ );
354
+ }
355
+ ```
356
+
357
+ ### Search with Debounce
358
+
359
+ ```tsx
360
+ import { useDeferredValue } from 'react';
361
+
362
+ function TaskSearch() {
363
+ const [searchTerm, setSearchTerm] = useState('');
364
+ const deferredSearch = useDeferredValue(searchTerm);
365
+
366
+ const { data, isLoading } = useQuery('todo_task', {
367
+ filters: ['subject', 'contains', deferredSearch],
368
+ enabled: deferredSearch.length >= 3 // Only search with 3+ chars
369
+ });
370
+
371
+ return (
372
+ <div>
373
+ <input
374
+ type="text"
375
+ value={searchTerm}
376
+ onChange={(e) => setSearchTerm(e.target.value)}
377
+ placeholder="Search tasks..."
378
+ />
379
+ {isLoading && <Spinner />}
380
+ <TaskList tasks={data?.value} />
381
+ </div>
382
+ );
383
+ }
384
+ ```
385
+
386
+ ### Form with Validation
387
+
388
+ ```tsx
389
+ function TaskForm() {
390
+ const { mutate, isLoading, error } = useMutation('todo_task', 'create', {
391
+ onSuccess: () => {
392
+ router.push('/tasks');
393
+ }
394
+ });
395
+
396
+ const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
397
+ e.preventDefault();
398
+ const formData = new FormData(e.currentTarget);
399
+
400
+ mutate({
401
+ subject: formData.get('subject'),
402
+ priority: Number(formData.get('priority')),
403
+ due_date: formData.get('due_date')
404
+ });
405
+ };
406
+
407
+ return (
408
+ <form onSubmit={handleSubmit}>
409
+ <input name="subject" required />
410
+ <input name="priority" type="number" min="1" max="5" />
411
+ <input name="due_date" type="date" />
412
+
413
+ {error && (
414
+ <div className="error">
415
+ {error.code === 'validation_error'
416
+ ? 'Please check your input'
417
+ : error.message}
418
+ </div>
419
+ )}
420
+
421
+ <button type="submit" disabled={isLoading}>
422
+ {isLoading ? 'Creating...' : 'Create Task'}
423
+ </button>
424
+ </form>
425
+ );
426
+ }
427
+ ```
428
+
271
429
  ## License
272
430
 
273
431
  Apache-2.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@objectstack/client-react",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "description": "React hooks for ObjectStack Client SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -8,9 +8,9 @@
8
8
  "react": ">=18.0.0"
9
9
  },
10
10
  "dependencies": {
11
- "@objectstack/client": "0.9.0",
12
- "@objectstack/spec": "0.9.0",
13
- "@objectstack/core": "0.9.0"
11
+ "@objectstack/client": "0.9.2",
12
+ "@objectstack/spec": "0.9.2",
13
+ "@objectstack/core": "0.9.2"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@types/react": "^18.0.0",