@omnistreamai/data-core
Version:
137 lines (107 loc) • 3.62 kB
Markdown
---
name: data-operations
description: >
Perform CRUD operations on a Store. Use add, update, delete, getData, getList,
getListQuery. Understand that local getList returns T[] while remote returns
PaginatedResult. Configure where, sortBy, sortOrder, page, limit options.
type: core
library: '@omnistreamai/data-sync'
library_version: '0.4.1'
sources:
- 'omni-stream-ai/data-sync:packages/core/src/store.ts'
- 'omni-stream-ai/data-sync:packages/core/src/types.ts'
---
# Data Operations
Perform create, read, update, and delete operations on a Store.
## Setup
```typescript
import { createSyncManager } from '@omnistreamai/data-core';
import { IndexedDBAdapter } from '@omnistreamai/data-adapter-indexeddb';
import { WebDAVAdapter } from '@omnistreamai/data-adapter-webdav';
const syncManager = createSyncManager({
localAdapter: new IndexedDBAdapter({ dbName: 'app', version: 1 }),
remoteAdapter: new WebDAVAdapter(),
});
const store = syncManager.createStore<Todo>('todos', { idKey: 'id' });
syncManager.initStore();
```
## Core Patterns
### Add a record
```typescript
const todo = await store.add({
id: '1',
title: 'Learn TypeScript',
completed: false,
createdAt: Date.now(),
});
// Writes to local immediately; syncs to remote async
// Returns the added record
```
### Update a record
```typescript
await store.update('1', {
completed: true,
updatedAt: Date.now(),
});
// Updates local immediately; syncs to remote async
// Returns updated record from local
```
### Delete a record
```typescript
await store.delete('1');
// Deletes from local immediately; syncs to remote async
```
### Get a single record by ID
```typescript
const todo = await store.getData('1');
// Falls back to remote if not found locally
// Returns null if not found anywhere
```
### Get a list with filters, sorting, and pagination
```typescript
const todos = await store.getList({
source: 'remote', // 'local' | 'remote' | undefined (defaults to remote)
page: 1,
limit: 20,
where: { completed: false },
sortBy: 'createdAt',
sortOrder: 'desc',
});
// Default: remote → caches to local
// source: 'local' → local only
// source: 'remote' → remote only, no caching
```
### Get list for React Query integration
```typescript
const { queryKey, queryFn, getInitialData } = store.getListQuery({
where: { completed: false },
sortBy: 'createdAt',
sortOrder: 'desc',
});
// queryKey: ['store', 'todos', 'default', options]
// queryFn: () => store.getList(options)
// getInitialData: () => store.getList({ ...options, source: 'local' })
// Use with useQuery from React Query or similar
```
### Clear all records
```typescript
await store.clear();
// Deletes all records from both local and remote
```
## Common Mistakes
### MEDIUM Assume getList returns PaginatedResult from local adapter
Wrong:
```typescript
const result = await store.getList({ page: 1, limit: 10 });
result.data; // ❌ TypeScript error — local adapter returns T[], not PaginatedResult
result.totalCount; // ❌ TypeScript error
```
Correct:
```typescript
// store.getList always returns T[] — not PaginatedResult
const todos = await store.getList({ page: 1, limit: 10 });
// For React Query integration, use getListQuery which returns proper query shape:
const { queryKey, queryFn, getInitialData } = store.getListQuery(options);
```
Local adapter's `getList()` returns `T[]`. Remote adapter's `getList()` returns `PaginatedResult<T>`. The Store normalizes remote results to `T[]` for local caching, but does not return the full paginated shape.
Source: packages/core/src/store.ts:392-462