npm package: @nosql-ai/react
Description: Official React SDK for NoSQL with hooks, real-time subscriptions, and offline-first capabilities
Author: NoSQL Team
Latest version: 1.0.0

# NoSQL React SDK

Official React SDK for [NoSQL](https://nosql-docs-prod.finhub.workers.dev) with hooks, real-time subscriptions, and offline-first capabilities.

## Features

- 🎣 **React Hooks**: `useDocument`, `useVectorSearch`, `useSubscription`
- 🔄 **Real-time Updates**: WebSocket subscriptions with automatic reconnection
- 📴 **Offline-First**: IndexedDB caching for offline support
- ⚡ **Optimistic Updates**: Instant UI updates with background sync
- 🔌 **Auto-Connect**: Automatic online/offline detection
- 📦 **TypeScript**: Full type safety
- 🎯 **Context Provider**: Global client configuration

## Installation

```bash
npm install @nosql/react @nosql/sdk
# or
yarn add @nosql/react @nosql/sdk
```

## Quick Start

### 1. Setup Provider

Wrap your app with `NoSQLProvider`:

```tsx
import { NoSQLClient } from '@nosql/sdk';
import { NoSQLProvider } from '@nosql/react';

const client = new NoSQLClient({
  endpoint: 'https://nosql-db-prod.finhub.workers.dev',
  apiKey: 'your-api-key'
});

function App() {
  return (
    <NoSQLProvider client={client}>
      <YourApp />
    </NoSQLProvider>
  );
}
```

### 2. Use Hooks in Components

```tsx
import { useDocument } from '@nosql/react';

function UserProfile({ userId }: { userId: string }) {
  const { data, loading, error, update } = useDocument({
    database: 'mydb',
    collection: 'users',
    id: userId,
    subscribe: true // Enable real-time updates
  });

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h1>{data.name}</h1>
      <button onClick={() => update({ lastSeen: Date.now() })}>
        Update Last Seen
      </button>
    </div>
  );
}
```

## Hooks

### useDocument

Fetch, update, and subscribe to document changes:

```tsx
const { data, loading, error, insert, update, remove, refetch } = useDocument({
  database: 'mydb',
  collection: 'users',
  id: 'user-123', // Optional: for single document
  query: { filter: { age: { $gte: 18 } } }, // Optional: for multiple documents
  subscribe: true, // Enable real-time updates
  cacheKey: 'users-query' // Custom cache key
});

// Insert new document
await insert({ name: 'John', age: 30 });

// Update existing document
await update({ age: 31 });

// Delete document
await remove();

// Manually refetch
await refetch();
```

### useVectorSearch

Perform AI-powered similarity search:

```tsx
const { results, loading, error, search, generateEmbedding } = useVectorSearch({
  database: 'mydb',
  collection: 'embeddings',
  query: {
    vector: [0.1, 0.2, 0.3],
    topK: 10,
    metric: 'cosine',
    filter: { category: 'ai' }
  },
  autoSearch: true, // Automatically search on mount
  cacheResults: true // Cache results for offline access
});

// Search with different query
await search({
  vector: [0.2, 0.3, 0.4],
  topK: 5
});

// Generate embedding from text
const embedding = await generateEmbedding('machine learning');
```

### useSubscription

Subscribe to real-time data updates:

```tsx
const { data, connected, error, messages } = useSubscription({
  channel: 'documents:mydb:users',
  filter: { age: { $gte: 18 } },
  enabled: true // Toggle subscription on/off
});

// Latest message
console.log('Latest update:', data);

// All messages received
console.log('All updates:', messages);

// Connection status
console.log('Connected:', connected);
```

### useOfflineCache

Manage offline data caching:

```tsx
const { cachedData, setCachedData, clearCache, clearAllCache } = useOfflineCache('my-cache-key');

// Save to cache
await setCachedData({ foo: 'bar' });

// Read from cache (automatic on mount)
console.log(cachedData);

// Clear specific cache
await clearCache();

// Clear all caches
await clearAllCache();
```

## Real-World Examples

### User List with Real-time Updates

```tsx
function UserList() {
  const { data: users, loading } = useDocument({
    database: 'mydb',
    collection: 'users',
    query: {
      filter: { active: true },
      sort: { createdAt: -1 },
      limit: 50
    },
    subscribe: true // Live updates as users are added/modified
  });

  if (loading) return <Spinner />;

  return (
    <ul>
      {users?.map(user => (
        <li key={user._id}>{user.name}</li>
      ))}
    </ul>
  );
}
```

### AI-Powered Search

```tsx
function SemanticSearch() {
  const [searchText, setSearchText] = useState('');
  const { search, generateEmbedding, results, loading } = useVectorSearch({
    database: 'mydb',
    collection: 'documents',
    query: { vector: [], topK: 10 },
    autoSearch: false
  });

  const handleSearch = async () => {
    const embedding = await generateEmbedding(searchText);
    await search({ vector: embedding, topK: 10 });
  };

  return (
    <div>
      <input
        value={searchText}
        onChange={(e) => setSearchText(e.target.value)}
        onKeyPress={(e) => e.key === 'Enter' && handleSearch()}
      />
      {loading ? (
        <Spinner />
      ) : (
        <ul>
          {results.map(result => (
            <li key={result.id}>
              {result.metadata?.title} (Score: {result.score})
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}
```

### Live Chat with Real-time Messages

```tsx
function ChatRoom({ roomId }: { roomId: string }) {
  const { messages } = useSubscription({
    channel: `chat:${roomId}`,
    enabled: true
  });

  const { insert } = useDocument({
    database: 'chat',
    collection: 'messages'
  });

  const sendMessage = async (text: string) => {
    await insert({
      roomId,
      text,
      userId: currentUser.id,
      timestamp: Date.now()
    });
  };

  return (
    <div>
      <div className="messages">
        {messages.map((msg, i) => (
          <div key={i}>{msg.text}</div>
        ))}
      </div>
      <MessageInput onSend={sendMessage} />
    </div>
  );
}
```

### Offline-First Todo App

```tsx
function TodoList() {
  const { data: todos, loading, insert, update } = useDocument({
    database: 'todos',
    collection: 'items',
    query: { filter: { completed: false } },
    subscribe: true
  });

  // Works offline! Changes sync when back online
  const addTodo = async (text: string) => {
    await insert({
      text,
      completed: false,
      createdAt: Date.now()
    });
  };

  const toggleTodo = async (id: string, completed: boolean) => {
    await update({ _id: id, completed: !completed });
  };

  return (
    <div>
      {!navigator.onLine && <div className="offline-badge">Offline Mode</div>}
      <ul>
        {todos?.map(todo => (
          <li key={todo._id}>
            <input
              type="checkbox"
              checked={todo.completed}
              onChange={() => toggleTodo(todo._id, todo.completed)}
            />
            {todo.text}
          </li>
        ))}
      </ul>
    </div>
  );
}
```

## Offline Support

The SDK automatically handles offline scenarios:

- **Automatic Caching**: All queries are cached in IndexedDB
- **Offline Reads**: Cached data served when offline
- **Online/Offline Detection**: Automatic network status monitoring
- **Background Sync**: Changes sync when connection restored
- **Optimistic Updates**: UI updates immediately, syncs in background

## TypeScript Support

Full TypeScript support with type inference:

```tsx
import type { Document } from '@nosql/sdk';

interface User extends Document {
  name: string;
  email: string;
  age: number;
}

const { data } = useDocument<User>({
  database: 'mydb',
  collection: 'users',
  id: 'user-123'
});

// data is typed as User!
console.log(data?.name.toUpperCase());
```

## Best Practices

1. **Use Context Provider**: Always wrap your app with `NoSQLProvider`
2. **Enable Subscriptions**: Use `subscribe: true` for live data
3. **Cache Strategically**: Use meaningful `cacheKey` values
4. **Handle Loading States**: Always check `loading` before rendering
5. **Optimize Queries**: Use filters and limits to reduce data transfer
6. **Test Offline**: Test your app with network disabled

## Requirements

- React 18+ or React 19+
- @nosql/sdk ^1.0.0
- Modern browser with IndexedDB support

## Documentation

Visit https://nosql-docs-prod.finhub.workers.dev for complete documentation.

## License

MIT © NoSQL Team