# MemoryStack - React Native SDK

Official React Native SDK for [MemoryStack](https://memorystack.app) - The memory layer for AI applications.

[![npm](https://img.shields.io/npm/v/@memorystack/react-native-sdk)](https://www.npmjs.com/package/@memorystack/react-native-sdk)
[![Website](https://img.shields.io/badge/Website-memorystack.app-purple)](https://memorystack.app)
[![Documentation](https://img.shields.io/badge/Docs-memorystack.app%2Fdocs-blue)](https://memorystack.app/docs)

## What is MemoryStack?

MemoryStack is a **semantic memory layer** that gives your AI applications persistent, searchable memory. Instead of losing context between conversations, your AI can:

- **Remember** user preferences, facts, and conversation history
- **Search** through memories using natural language
- **Learn** from past interactions to provide personalized responses
- **Scale** from personal assistants to multi-tenant B2B applications

Think of it as a brain for your AI - it stores information intelligently and retrieves it when needed.

## Why React Native SDK?

- 📱 **React Native Optimized** - Uses native `fetch`, minimal bundle size
- 🔌 **Offline-First** - Queue operations when offline, auto-sync when back online
- ⚛️ **React Hooks** - `useMemories`, `useSearch`, `useMemory`, and more
- 🎯 **TypeScript** - Full type safety with IntelliSense
- 📦 **Expo Compatible** - Works with Expo and bare React Native

## Installation

```bash
npm install @memorystack/react-native-sdk
```

## Quick Start

```tsx
import { MemoryStackClient } from '@memorystack/react-native-sdk';

const client = new MemoryStackClient({
  apiKey: 'your-api-key',
});

// Store a memory
await client.add('User prefers dark mode');

// Search memories
const results = await client.search('user preferences');
console.log(results.results);
```

That's it! Two methods - `add()` and `search()` - handle 90% of use cases.

## Core API

### `add()` - Store Memories

The `add()` method accepts either a simple string or an array of messages:

```typescript
// Simple text
await client.add('User likes React Native');

// With user ID (for B2B apps)
await client.add('User prefers morning meetings', { userId: 'user_123' });

// Conversation format
await client.add([
  { role: 'user', content: 'What is my favorite color?' },
  { role: 'assistant', content: 'Based on our conversations, you prefer blue!' }
]);

// With metadata
await client.add('Important project deadline is Friday', {
  userId: 'user_123',
  metadata: { category: 'work', priority: 'high' }
});
```

### `search()` - Find Memories

The `search()` method finds relevant memories using semantic search:

```typescript
// Simple search
const results = await client.search('user preferences');

// With user ID filter
const results = await client.search('favorite color', { userId: 'user_123' });

// Limit results
const results = await client.search('meetings', { limit: 5 });
```

## Common Use Cases

### AI Chatbot with Memory

```tsx
import { MemoryStackClient } from '@memorystack/react-native-sdk';

const memory = new MemoryStackClient({ apiKey: 'your-api-key' });

async function chat(userId: string, message: string) {
  // Get relevant context from memory
  const context = await memory.search(message, { userId, limit: 5 });
  
  // Build prompt with memory context
  const systemPrompt = `You are a helpful assistant. Here's what you remember about this user:
${context.results.map(m => `- ${m.content}`).join('\n')}`;

  // Generate response with your LLM (OpenAI, Anthropic, etc.)
  const response = await yourLLM.chat({
    systemPrompt,
    message,
  });

  // Save conversation to memory
  await memory.add([
    { role: 'user', content: message },
    { role: 'assistant', content: response }
  ], { userId });

  return response;
}
```

### Personal Assistant App

```typescript
// Store preferences
await client.add('I wake up at 6am every day');
await client.add('I prefer coffee over tea');
await client.add('My favorite restaurant is Olive Garden');

// Later, retrieve relevant info
const results = await client.search('morning routine');
// Returns: "I wake up at 6am every day"

const results = await client.search('food preferences');
// Returns: "My favorite restaurant is Olive Garden", "I prefer coffee over tea"
```

### Multi-Tenant B2B App

```typescript
// Each user has isolated memories
await client.add('Prefers dark mode', { userId: 'alice_123' });
await client.add('Prefers light mode', { userId: 'bob_456' });

// Search only returns that user's memories
const alicePrefs = await client.search('theme preference', { userId: 'alice_123' });
// Returns: "Prefers dark mode"
```

## React Hooks (Recommended for React Native)

### Setup Provider

```tsx
// App.tsx
import React from 'react';
import { MemoryStackProvider } from '@memorystack/react-native-sdk';

function App() {
  return (
    <MemoryStackProvider
      config={{
        apiKey: 'your-api-key',
        enableOffline: true,
      }}
    >
      <YourApp />
    </MemoryStackProvider>
  );
}
```

### Using Hooks

```tsx
import { useMemories, useSearch, useAddMemory, useIsOnline } from '@memorystack/react-native-sdk';

function MemoriesScreen() {
  const isOnline = useIsOnline();
  const { memories, isLoading, refetch, loadMore } = useMemories();
  const { results, search } = useSearch({ debounceMs: 300 });
  const { add, isAdding } = useAddMemory();

  return (
    <View>
      <Text>{isOnline ? '🟢 Online' : '🔴 Offline'}</Text>
      
      <TextInput
        placeholder="Search memories..."
        onChangeText={search}
      />
      
      <Button
        title={isAdding ? 'Adding...' : 'Add Memory'}
        onPress={() => add('New memory content')}
      />
      
      <FlatList
        data={results.length > 0 ? results : memories}
        renderItem={({ item }) => (
          <Text>{item.content}</Text>
        )}
        keyExtractor={(item) => item.id}
        refreshing={isLoading}
        onRefresh={refetch}
      />
    </View>
  );
}
```

## Additional Methods

While `add()` and `search()` cover most needs, the SDK also provides:

```typescript
// List all memories with pagination
const memories = await client.listMemories({ limit: 50 });

// Get a single memory
const memory = await client.getMemory('memory-id');

// Get usage statistics
const stats = await client.getStats();
console.log(`Total memories: ${stats.totals.total_memories}`);

// Update a memory
await client.updateMemory('memory-id', { content: 'Updated content' });

// Delete a memory
await client.deleteMemory('memory-id');
```

## Offline Support

For mobile apps, offline support is crucial. The SDK can queue operations when offline:

```typescript
import AsyncStorage from '@react-native-async-storage/async-storage';
import NetInfo from '@react-native-community/netinfo';

// Install optional dependencies
// npm install @react-native-async-storage/async-storage @react-native-community/netinfo

// Configure provider with offline support
<MemoryStackProvider
  config={{
    apiKey: 'your-api-key',
    enableOffline: true,
  }}
  storage={AsyncStorage}
  netInfo={NetInfo}
>
  <YourApp />
</MemoryStackProvider>

// Operations will automatically queue when offline
// and sync when the device comes back online
```

## Error Handling

```typescript
import { 
  MemoryStackError, 
  AuthenticationError, 
  RateLimitError,
  ValidationError 
} from '@memorystack/react-native-sdk';

try {
  await client.add('Hello world');
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof RateLimitError) {
    console.error('Rate limit exceeded, retry later');
  } else if (error instanceof ValidationError) {
    console.error('Invalid input:', error.message);
  }
}
```

## Configuration Options

```typescript
const client = new MemoryStackClient({
  apiKey: process.env.MEMORYSTACK_API_KEY!,
  
  // Optional settings
  baseUrl: 'https://www.memorystack.app',  // Custom API URL
  timeout: 30000,                           // Request timeout (ms)
  enableLogging: true,                      // Enable debug logging
  enableOffline: true,                      // Enable offline queue
  
  // Retry configuration
  retryConfig: {
    maxRetries: 3,
    retryDelay: 1000,
  }
});
```

## Platform Support

| Platform | Supported |
|----------|-----------|
| iOS | ✅ |
| Android | ✅ |
| Expo | ✅ |
| React Native Web | ✅ |

## Links

- 🌐 **Website**: https://memorystack.app
- 📚 **Documentation**: https://memorystack.app/docs
- 🚀 **Quick Start**: https://memorystack.app/docs/quickstart
- 💰 **Pricing**: https://memorystack.app/pricing
- 📧 **Support**: support@memorystack.app

## License

MIT
