@@ -16,6 +16,8 @@ npm install @object-ui/data-objectstack @objectstack/client
1616
1717## Usage
1818
19+ ### Basic Setup
20+
1921``` typescript
2022import { createObjectStackAdapter } from ' @object-ui/data-objectstack' ;
2123import { SchemaRenderer } from ' @object-ui/react' ;
@@ -37,9 +39,235 @@ function App() {
3739}
3840```
3941
42+ ### Advanced Configuration
43+
44+ ``` typescript
45+ const dataSource = createObjectStackAdapter ({
46+ baseUrl: ' https://api.example.com' ,
47+ token: ' your-api-token' ,
48+ // Configure metadata cache
49+ cache: {
50+ maxSize: 100 , // Maximum number of cached schemas (default: 100)
51+ ttl: 5 * 60 * 1000 // Time to live in ms (default: 5 minutes)
52+ }
53+ });
54+ ```
55+
4056## Features
4157
4258- ✅ ** CRUD Operations** : Implements ` find ` , ` findOne ` , ` create ` , ` update ` , ` delete ` .
59+ - ✅ ** Metadata Caching** : Automatic LRU caching of schema metadata with TTL expiration.
4360- ✅ ** Metadata Fetching** : Implements ` getObjectSchema ` to power auto-generated forms and grids.
4461- ✅ ** Query Translation** : Converts Object UI's OData-like query parameters to ObjectStack's native query format.
45- - ✅ ** Bulk Operations** : Supports batch create/update/delete.
62+ - ✅ ** Bulk Operations** : Supports optimized batch create/update/delete with detailed error reporting.
63+ - ✅ ** Error Handling** : Comprehensive error hierarchy with unique error codes and debugging details.
64+
65+ ## Metadata Caching
66+
67+ The adapter includes built-in metadata caching to improve performance when fetching schemas:
68+
69+ ``` typescript
70+ // Get cache statistics
71+ const stats = dataSource .getCacheStats ();
72+ console .log (` Cache hit rate: ${stats .hitRate * 100 }% ` );
73+ console .log (` Cache size: ${stats .size }/${stats .maxSize } ` );
74+
75+ // Manually invalidate cache entries
76+ dataSource .invalidateCache (' users' ); // Invalidate specific schema
77+ dataSource .invalidateCache (); // Invalidate all cached schemas
78+
79+ // Clear cache and statistics
80+ dataSource .clearCache ();
81+ ```
82+
83+ ### Cache Configuration
84+
85+ - ** LRU Eviction** : Automatically evicts least recently used entries when cache is full
86+ - ** TTL Expiration** : Entries expire after the configured time-to-live from creation (default: 5 minutes)
87+ - Note: TTL is fixed from creation time, not sliding based on access
88+ - ** Memory Limits** : Configurable maximum cache size (default: 100 entries)
89+ - ** Concurrent Access** : Handles async operations safely. Note that concurrent requests for the same uncached key may result in multiple fetcher calls.
90+
91+ ## Error Handling
92+
93+ The adapter provides a comprehensive error hierarchy for better error handling:
94+
95+ ### Error Types
96+
97+ ``` typescript
98+ import {
99+ ObjectStackError , // Base error class
100+ MetadataNotFoundError , // Schema/metadata not found (404)
101+ BulkOperationError , // Bulk operation failures with partial results
102+ ConnectionError , // Network/connection errors (503/504)
103+ AuthenticationError , // Authentication failures (401/403)
104+ ValidationError , // Data validation errors (400)
105+ } from ' @object-ui/data-objectstack' ;
106+ ```
107+
108+ ### Error Handling Example
109+
110+ ``` typescript
111+ try {
112+ const schema = await dataSource .getObjectSchema (' users' );
113+ } catch (error ) {
114+ if (error instanceof MetadataNotFoundError ) {
115+ console .error (` Schema not found: ${error .details .objectName } ` );
116+ } else if (error instanceof ConnectionError ) {
117+ console .error (` Connection failed to: ${error .url } ` );
118+ } else if (error instanceof AuthenticationError ) {
119+ console .error (' Authentication required' );
120+ }
121+
122+ // All errors have consistent structure
123+ console .error ({
124+ code: error .code ,
125+ message: error .message ,
126+ statusCode: error .statusCode ,
127+ details: error .details
128+ });
129+ }
130+ ```
131+
132+ ### Bulk Operation Errors
133+
134+ Bulk operations provide detailed error reporting with partial success information:
135+
136+ ``` typescript
137+ try {
138+ await dataSource .bulk (' users' , ' update' , records );
139+ } catch (error ) {
140+ if (error instanceof BulkOperationError ) {
141+ const summary = error .getSummary ();
142+ console .log (` ${summary .successful } succeeded, ${summary .failed } failed ` );
143+ console .log (` Failure rate: ${summary .failureRate * 100 }% ` );
144+
145+ // Inspect individual failures
146+ summary .errors .forEach (({ index , error }) => {
147+ console .error (` Record ${index } failed: ` , error );
148+ });
149+ }
150+ }
151+ ```
152+
153+ ### Error Codes
154+
155+ All errors include unique error codes for programmatic handling:
156+
157+ - ` METADATA_NOT_FOUND ` - Schema/metadata not found
158+ - ` BULK_OPERATION_ERROR ` - Bulk operation failure
159+ - ` CONNECTION_ERROR ` - Connection/network error
160+ - ` AUTHENTICATION_ERROR ` - Authentication failure
161+ - ` VALIDATION_ERROR ` - Data validation error
162+ - ` UNSUPPORTED_OPERATION ` - Unsupported operation
163+ - ` NOT_FOUND ` - Resource not found
164+ - ` UNKNOWN_ERROR ` - Unknown error
165+
166+ ## Batch Operations
167+
168+ The adapter supports optimized batch operations with automatic fallback:
169+
170+ ``` typescript
171+ // Batch create
172+ const newUsers = await dataSource .bulk (' users' , ' create' , [
173+ { name: ' Alice' , email: ' alice@example.com' },
174+ { name: ' Bob' , email: ' bob@example.com' },
175+ ]);
176+
177+ // Batch update (uses updateMany if available, falls back to individual updates)
178+ const updated = await dataSource .bulk (' users' , ' update' , [
179+ { id: ' 1' , name: ' Alice Smith' },
180+ { id: ' 2' , name: ' Bob Jones' },
181+ ]);
182+
183+ // Batch delete
184+ await dataSource .bulk (' users' , ' delete' , [
185+ { id: ' 1' },
186+ { id: ' 2' },
187+ ]);
188+ ```
189+
190+ ### Performance Optimizations
191+
192+ - Automatically uses ` createMany ` , ` updateMany ` , ` deleteMany ` when available
193+ - Falls back to individual operations with detailed error tracking
194+ - Provides partial success reporting for resilient error handling
195+ - Atomic operations where supported by the backend
196+
197+ ## API Reference
198+
199+ ### ObjectStackAdapter
200+
201+ #### Constructor
202+
203+ ``` typescript
204+ new ObjectStackAdapter (config : {
205+ baseUrl: string ;
206+ token ?: string ;
207+ fetch ?: (input : RequestInfo | URL , init ? : RequestInit ) => Promise < Response > ;
208+ cache ?: {
209+ maxSize?: number ;
210+ ttl ?: number ;
211+ };
212+ })
213+ ```
214+
215+ #### Methods
216+
217+ - ` connect() ` - Establish connection to ObjectStack server
218+ - ` find(resource, params?) ` - Query multiple records
219+ - ` findOne(resource, id, params?) ` - Get a single record by ID
220+ - ` create(resource, data) ` - Create a new record
221+ - ` update(resource, id, data) ` - Update an existing record
222+ - ` delete(resource, id) ` - Delete a record
223+ - ` bulk(resource, operation, data) ` - Batch operations (create/update/delete)
224+ - ` getObjectSchema(objectName) ` - Get schema metadata (cached)
225+ - ` getCacheStats() ` - Get cache statistics
226+ - ` invalidateCache(key?) ` - Invalidate cache entries
227+ - ` clearCache() ` - Clear all cache entries
228+ - ` getClient() ` - Access underlying ObjectStack client
229+
230+ ## Best Practices
231+
232+ 1 . ** Enable Caching** : Use default cache settings for optimal performance
233+ 2 . ** Handle Errors** : Use typed error handling for better user experience
234+ 3 . ** Batch Operations** : Use bulk methods for large datasets
235+ 4 . ** Monitor Cache** : Check cache hit rates in production
236+ 5 . ** Invalidate Wisely** : Clear cache after schema changes
237+
238+ ## Troubleshooting
239+
240+ ### Common Issues
241+
242+ #### Schema Not Found
243+
244+ ``` typescript
245+ // Error: MetadataNotFoundError
246+ // Solution: Verify object name and ensure schema exists on server
247+ const schema = await dataSource .getObjectSchema (' correct_object_name' );
248+ ```
249+
250+ #### Connection Errors
251+
252+ ``` typescript
253+ // Error: ConnectionError
254+ // Solution: Check baseUrl and network connectivity
255+ const dataSource = createObjectStackAdapter ({
256+ baseUrl: ' https://correct-url.example.com' ,
257+ token: ' valid-token'
258+ });
259+ ```
260+
261+ #### Cache Issues
262+
263+ ``` typescript
264+ // Clear cache if stale data is being returned
265+ dataSource .clearCache ();
266+
267+ // Or invalidate specific entries
268+ dataSource .invalidateCache (' users' );
269+ ```
270+
271+ ## License
272+
273+ MIT
0 commit comments