diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 97dd6fb62..83c8ccbef 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -200,21 +200,40 @@ ObjectStack is organized as a **monorepo** with distinct package layers: #### `@objectstack/client` **Location**: `packages/client/` -**Role**: Client SDK - -- Client-side API wrapper -- Request/response handling -- Type-safe API calls +**Role**: Official TypeScript Client SDK for ObjectStack Protocol + +**Features**: +- **Auto-Discovery**: Connects to ObjectStack server and auto-configures API endpoints +- **Typed Metadata**: Retrieve Object and View definitions with full TypeScript support +- **Metadata Caching**: ETag-based conditional requests for efficient metadata caching +- **Data Operations**: + - Advanced queries with filtering, sorting, and field selection + - CRUD operations (create, read, update, delete) + - Batch operations with transaction support (batch create/update/upsert/delete) + - Query builder with type-safe filters +- **View Storage**: Save, load, share, and manage custom UI view configurations +- **Error Handling**: Standardized error codes with retry guidance +- **HTTP Caching**: ETag support for optimized metadata requests + +**API Surface**: +- `client.connect()`: Initialize client with server discovery +- `client.meta.*`: Metadata operations (getObject, getCached, getView) +- `client.data.*`: Data operations (find, get, query, create, batch, update, delete) +- `client.views.*`: View storage operations (create, get, list, update, delete, share) **Dependencies**: `@objectstack/core`, `@objectstack/spec` #### `@objectstack/client-react` **Location**: `packages/client-react/` -**Role**: React Hooks - -- React hooks for ObjectStack -- State management integration -- React Query / SWR patterns +**Role**: React Hooks for ObjectStack Client SDK + +**Features**: +- **Data Hooks**: `useQuery`, `useMutation`, `usePagination`, `useInfiniteQuery` +- **Metadata Hooks**: `useObject`, `useView`, `useFields`, `useMetadata` +- **Context Management**: `ObjectStackProvider`, `useClient` +- **Type Safety**: Full TypeScript generics support for type-safe data +- **Auto-refetch**: Automatic data refetching and caching +- **Loading States**: Built-in loading and error state management **Dependencies**: `@objectstack/client`, `@objectstack/core`, `@objectstack/spec` **Peer Dependencies**: `react` diff --git a/PROTOCOL-QUICK-REFERENCE.md b/PROTOCOL-QUICK-REFERENCE.md index 8bf85de25..c433f3562 100644 --- a/PROTOCOL-QUICK-REFERENCE.md +++ b/PROTOCOL-QUICK-REFERENCE.md @@ -7,6 +7,40 @@ - **Find by Category**: Browse protocols by domain (Data, UI, System, etc.) - **Find by Example**: Every protocol links to practical examples - **Find by Feature**: Use the index to jump to specific features +- **Client SDKs**: See [Client SDK](#client-sdk) section for TypeScript and React integration + +--- + +## 🔌 Client SDK + +Access ObjectStack from your applications using the official client libraries: + +| SDK | Description | Documentation | Status | +|-----|-------------|---------------|--------| +| **@objectstack/client** | Official TypeScript client with metadata caching, batch operations, and view storage | [Client SDK Docs](./content/docs/references/client-sdk/) | ✅ | +| **@objectstack/client-react** | React hooks for data fetching, mutations, pagination, and infinite scrolling | [React Hooks Docs](./content/docs/references/client-sdk/react-hooks.mdx) | ✅ | + +**Quick Start:** +```typescript +import { ObjectStackClient } from '@objectstack/client'; + +const client = new ObjectStackClient({ baseUrl: 'http://localhost:3004' }); +await client.connect(); + +// Query data with filtering and sorting +const tasks = await client.data.find('todo_task', { + filters: ['status', '=', 'active'], + sort: ['-priority'], + top: 10 +}); + +// Batch operations with transaction support +await client.data.batch('todo_task', { + operation: 'update', + records: [/* ... */], + options: { atomic: true } +}); +``` --- diff --git a/README.md b/README.md index bd8b3e4d5..25f04a58e 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,49 @@ ObjectStack is a metadata-driven platform built on three foundational protocols: ## 🚀 Quick Start +### For Application Developers (Using the Client SDK) + +If you want to build applications using ObjectStack: + +```bash +# Install the client SDK +pnpm add @objectstack/client + +# For React applications +pnpm add @objectstack/client-react +``` + +```typescript +import { ObjectStackClient } from '@objectstack/client'; + +// Connect to your ObjectStack server +const client = new ObjectStackClient({ + baseUrl: 'http://localhost:3004' +}); + +await client.connect(); + +// Query data +const tasks = await client.data.find('todo_task', { + select: ['subject', 'priority'], + filters: ['status', '=', 'active'], + sort: ['-priority'], + top: 10 +}); + +// Create data +await client.data.create('todo_task', { + subject: 'New Task', + priority: 1 +}); +``` + +📖 **[View Client SDK Documentation](./content/docs/references/client-sdk/)** - Complete SDK reference with React hooks + +### For Protocol Developers (Contributing to ObjectStack) + +If you want to contribute to the ObjectStack protocol or build plugins: + ```bash # 1. Install dependencies pnpm install diff --git a/content/docs/references/client-sdk/index.mdx b/content/docs/references/client-sdk/index.mdx index 201c8a97b..8ac754930 100644 --- a/content/docs/references/client-sdk/index.mdx +++ b/content/docs/references/client-sdk/index.mdx @@ -11,7 +11,11 @@ The `@objectstack/client` is the official TypeScript client for ObjectStack. It - **Auto-Discovery**: Connects to your ObjectStack server and automatically configures API endpoints. - **Typed Metadata**: Retrieve Object and View definitions with full type support. -- **Unified Data Access**: Simple and Advanced CRUD operations for any object in your schema. +- **Metadata Caching**: ETag-based conditional requests for efficient metadata caching. +- **Unified Data Access**: Simple CRUD operations for any object in your schema. +- **Batch Operations**: Efficient bulk create/update/delete with transaction support. +- **View Storage**: Save, load, and share custom UI view configurations. +- **Standardized Errors**: Machine-readable error codes with retry guidance. ## Installation @@ -52,8 +56,48 @@ async function main() { priority: 1 }); - // 6. Batch Operations - await client.data.deleteMany('todo_task', ['id1', 'id2']); + // 6. Batch Operations (New!) + const batchResult = await client.data.batch('todo_task', { + operation: 'update', + records: [ + { id: '1', data: { status: 'active' } }, + { id: '2', data: { status: 'active' } } + ], + options: { + atomic: true, // Rollback on any failure + returnRecords: true // Include full records in response + } + }); + console.log(`Updated ${batchResult.succeeded} records`); + + // 7. Metadata Caching (New!) + const cachedObject = await client.meta.getCached('todo_task', { + ifNoneMatch: '"686897696a7c876b7e"' // ETag from previous request + }); + if (cachedObject.notModified) { + console.log('Using cached metadata'); + } + + // 8. View Storage (New!) + const view = await client.views.create({ + name: 'active_tasks', + label: 'Active Tasks', + object: 'todo_task', + type: 'list', + visibility: 'public', + query: { + object: 'todo_task', + where: { status: 'active' }, + orderBy: [{ field: 'priority', order: 'desc' }], + limit: 50 + }, + layout: { + columns: [ + { field: 'subject', label: 'Task', width: 200 }, + { field: 'priority', label: 'Priority', width: 100 } + ] + } + }); } ``` @@ -72,18 +116,29 @@ Initializes the client by fetching the system discovery manifest from `/api/v1`. ### `client.meta` - `getObject(name: string)`: Get object schema. +- `getCached(name: string, options?)`: Get object schema with ETag-based caching. - `getView(name: string)`: Get view configuration (e.g. for automatic UI generation). ### `client.data` -- `find(object, options)`: Advanced query. +- `find(object, options)`: Advanced query with filtering, sorting, selection. - `get(object, id)`: Get single record by ID. - `query(object, ast)`: Execute complex query using full AST (support for Joins, Aggregations). - `create(object, data)`: Create record. -- `createMany(object, data[])`: Batch create. +- `batch(object, request)`: **Recommended** - Execute batch operations (create/update/upsert/delete) with full control. +- `createMany(object, data[])`: Batch create records (convenience method). - `update(object, id, data)`: Update record. -- `updateMany(object, ids[], data)`: Batch update. +- `updateMany(object, records[], options?)`: Batch update records (convenience method). - `delete(object, id)`: Delete record. -- `deleteMany(object, ids[])`: Batch delete. +- `deleteMany(object, ids[], options?)`: Batch delete records (convenience method). + +### `client.views` (New!) +- `create(request)`: Create a new saved view. +- `get(id)`: Get a saved view by ID. +- `list(request?)`: List saved views with optional filters. +- `update(request)`: Update an existing view. +- `delete(id)`: Delete a saved view. +- `share(id, userIds[])`: Share a view with users/teams. +- `setDefault(id, object)`: Set a view as default for an object. ### Query Options (`QueryOptions`) The `find` method accepts an options object to control the query: @@ -95,3 +150,42 @@ The `find` method accepts an options object to control the query: | `sort` | `string` or `string[]` | Sort order | `['-created_at']` | | `top` | `number` | Limit records | `20` | | `skip` | `number` | Offset (Pagination) | `0` | + +### Batch Options +Batch operations support the following options: +- `atomic`: If true, rollback entire batch on any failure (default: true). +- `returnRecords`: If true, return full record data in response (default: false). +- `continueOnError`: If true (and atomic=false), continue processing remaining records after errors. +- `validateOnly`: If true, validate records without persisting changes (dry-run mode). + +### Error Handling +The client provides standardized error handling with machine-readable error codes: + +```typescript +try { + await client.data.create('todo_task', { subject: '' }); +} catch (error) { + console.error('Error code:', error.code); // e.g., 'validation_error' + console.error('Category:', error.category); // e.g., 'validation' + console.error('HTTP status:', error.httpStatus); // e.g., 400 + console.error('Retryable:', error.retryable); // e.g., false + console.error('Details:', error.details); // Additional error info +} +``` + +Common error codes: +- `validation_error`: Input validation failed +- `unauthenticated`: Authentication required +- `permission_denied`: Insufficient permissions +- `resource_not_found`: Resource does not exist +- `rate_limit_exceeded`: Too many requests + +## React Hooks + +For React applications, use `@objectstack/client-react` which provides hooks for data fetching and mutations: + +```bash +pnpm add @objectstack/client-react +``` + +See the [React Hooks documentation](./react-hooks) for detailed usage.