# Core Concepts

Understanding the foundational concepts behind @networkoptix/crdt-sync.

## Table of Contents

- [What are CRDTs?](#what-are-crdts)
- [Why Yjs?](#why-yjs)
- [MobX Reactivity](#mobx-reactivity)
- [Network Synchronization](#network-synchronization)
- [Leader-Follower Pattern](#leader-follower-pattern)
- [Data Models](#data-models)

## What are CRDTs?

**CRDT** stands for **Conflict-free Replicated Data Type**.

### The Problem

Traditional sync approaches fail with concurrent edits:

```
User A: counter = 5 → counter = 6
User B: counter = 5 → counter = 7

❌ Conflict! Which value wins? 6 or 7?
```

### The CRDT Solution

CRDTs are mathematical data structures that **automatically merge** concurrent changes without conflicts:

```
User A: counter = 5 → +1 → counter = 6
User B: counter = 5 → +2 → counter = 7

✅ CRDT merges operations: 5 + 1 + 2 = 8
```

### Key Properties

1. **Commutative** - Order doesn't matter: `A + B = B + A`
2. **Associative** - Grouping doesn't matter: `(A + B) + C = A + (B + C)`
3. **Idempotent** - Applying twice = applying once

### Real-World Analogy

Think of Google Docs:
- Multiple people edit simultaneously
- No "merge conflicts" like Git
- Everyone eventually sees the same result
- That's CRDTs in action!

## Why Yjs?

[Yjs](https://github.com/yjs/yjs) is a high-performance CRDT implementation.

### Advantages

- **Efficient** - Binary encoding, delta sync, minimal bandwidth
- **Fast** - Optimized algorithms for large documents
- **Proven** - Used in production by many collaborative apps
- **Flexible** - Supports text, arrays, maps, and custom types

### Data Structures

```typescript
import * as Y from 'yjs';

const ydoc = new Y.Doc();

// Y.Map - Key-value store (like JavaScript Object)
const ymap = ydoc.getMap('settings');
ymap.set('theme', 'dark');

// Y.Array - Ordered list
const yarray = ydoc.getArray('todos');
yarray.push([{ title: 'Buy milk', done: false }]);

// Y.Text - Collaborative text editing
const ytext = ydoc.getText('document');
ytext.insert(0, 'Hello, world!');
```

### Sync Protocol

Yjs uses a binary sync protocol:

```
Client A          Network          Client B
   |                                   |
   |--- State Vector --------------->  |
   |<-- Missing Updates --------------|
   |--- Acknowledgment ------------->  |
```

This library wraps Yjs to handle this automatically!

## MobX Reactivity

[MobX](https://mobx.js.org/) provides reactive state management.

### Observable State

```typescript
import { observable, autorun } from 'mobx';

class Counter {
  @observable count = 0;

  increment() {
    this.count++; // Triggers reactions automatically
  }
}

const counter = new Counter();

// Automatically re-runs when count changes
autorun(() => {
  console.log(`Count: ${counter.count}`);
});

counter.increment(); // Logs: "Count: 1"
```

### Integration with Yjs

Our library bridges Yjs (CRDT) ↔ MobX (Reactivity):

```
Yjs Document (CRDT)     ←→     MobX Observable (Reactive)
        ↓                               ↓
  Network Sync                     UI Updates
```

When Yjs receives updates → MobX observables update → UI re-renders automatically!

## Network Synchronization

### Connection Types

The library supports multiple network protocols:

#### 1. WebRTC (Peer-to-Peer)

**Default**: Direct browser-to-browser connections

```
Browser A  ←──WebRTC──→  Browser B
     ↓                       ↓
Browser C  ←──WebRTC──→  Browser D
```

**Advantages**:
- ✅ Low latency (direct P2P)
- ✅ Reduced server load
- ✅ Scalable (mesh network)

**Limitations**:
- ⚠️ Requires signaling server for initial handshake
- ⚠️ May need TURN server for NAT traversal
- ⚠️ Connection limit (~20-35 peers)

#### 2. WebSocket (Server-Based)

**Fallback**: Central server relays updates

```
Browser A  ──→  WebSocket Server  ←──  Browser B
Browser C  ──→  WebSocket Server  ←──  Browser D
```

**Advantages**:
- ✅ Works in restrictive networks
- ✅ Server can persist data
- ✅ Reliable message delivery

**Limitations**:
- ⚠️ Server becomes bottleneck
- ⚠️ Higher latency than WebRTC
- ⚠️ Requires server infrastructure

#### 3. BroadcastChannel (Local Tabs)

**Optimization**: Same-browser tabs sync locally

```
Browser (Tab 1)  ←──BroadcastChannel──→  Browser (Tab 2)
```

**Advantages**:
- ✅ Zero network latency
- ✅ No bandwidth usage
- ✅ Works offline
- ✅ Battery efficient

**Usage**: Automatic when multiple tabs open

### Automatic Connection Management

```typescript
const model = new MyModel({
  provider: {
    webrtc: { enabled: true },    // Try WebRTC first
    websocket: { enabled: true }  // Fallback to WebSocket
  }
});

// Library automatically:
// 1. Tries WebRTC
// 2. Falls back to WebSocket if WebRTC fails
// 3. Uses BroadcastChannel for same-browser tabs
```

## Leader-Follower Pattern

### The Problem

Without coordination, every browser tab makes external connections:

```
❌ Inefficient:
Tab 1 ──WebRTC──→ Network
Tab 2 ──WebRTC──→ Network  (Duplicate connections!)
Tab 3 ──WebRTC──→ Network  (Wasting resources!)
```

### The Solution

**One leader tab** per browser manages external connections:

```
✅ Efficient:
Tab 1 (Leader) ──WebRTC──→ Network
  ↓
Tab 2 (Follower) ←─BroadcastChannel
  ↓
Tab 3 (Follower) ←─BroadcastChannel
```

### Leader Election

Automatic via `broadcast-channel` library:

```typescript
// Internally, the library:
import { createLeaderElection } from 'broadcast-channel';

const elector = createLeaderElection(channel);
await elector.awaitLeadership(); // Becomes leader

// When leader tab closes:
// → New election automatically
// → New leader elected in ~500ms
// → Seamless transition!
```

### Benefits

- ✅ Reduced browser resource usage
- ✅ No duplicate network connections
- ✅ Faster local sync via BroadcastChannel
- ✅ Automatic failover when leader closes

## Data Models

### Singleton Model

**Use Case**: Single shared value

```typescript
import { createSingletonModel } from '@networkoptix/crdt-sync/core';

// Settings, preferences, shared state
const SettingsModel = createSingletonModel<Settings>(
  { room: 'app-settings' },
  { theme: 'dark', fontSize: 14 }
);

const model = new SettingsModel();
model.setValue({ theme: 'light', fontSize: 16 });
const current = model.getValue();
```

### Collection Model (Map)

**Use Case**: Collection of items with unique IDs

```typescript
import { createMapModel } from '@networkoptix/crdt-sync/core';

interface Todo {
  id: string;
  title: string;
  completed: boolean;
}

const TodosModel = createMapModel<Todo>({ room: 'todos' });

const model = new TodosModel();
model.create({ title: 'Buy milk', completed: false });
model.update(todoId, { completed: true });
model.delete(todoId);
const allTodos = model.all;
```

### List Model (Array)

**Use Case**: Ordered list of items

```typescript
import { createListModel } from '@networkoptix/crdt-sync/core';

const ItemsModel = createListModel<string>({ room: 'items' });

const model = new ItemsModel();
model.add('First');
model.add('Second');
model.insertAt(1, 'Between');
model.removeAt(0);
```

### Model Lifecycle

```
Create → Connect → Sync → Update → Disconnect → Destroy
```

```typescript
const model = new MyModel();  // Create
model.connect();              // Connect to network
// ... sync happens automatically ...
model.setValue(newValue);     // Update (triggers sync)
model.disconnect();           // Disconnect from network
model.destroy();              // Clean up resources
```

## Putting It All Together

### Data Flow

```
User Action (increment)
        ↓
MobX @modelAction
        ↓
Yjs Transaction (CRDT operation)
        ↓
Provider (WebRTC/WebSocket/BroadcastChannel)
        ↓
Network (sync to peers)
        ↓
Remote Yjs Apply (CRDT merge)
        ↓
Remote MobX Update
        ↓
Remote UI Re-render
```

### Example: Counter Increment Flow

```typescript
// User clicks "Increment" button
onClick={() => setCount(count + 1)}

// React hook calls model
model.setValue(count + 1)

// Model updates Yjs (CRDT)
this.ymap.set('value', count + 1)

// Yjs generates update
const update = Y.encodeStateAsUpdate(ydoc)

// Provider broadcasts to network
webrtcProvider.broadcast(update)

// Remote peer receives
remotePeer.applyUpdate(update)

// Remote MobX observable updates
@observable value = count + 1

// Remote UI re-renders automatically
// (via autorun in React hook)
```

## Next Steps

- **[Quick Start](./quick-start.md)** - Build your first app
- **[Installation Guide](./installation.md)** - Installation and setup
- **[Troubleshooting](../troubleshooting/common-issues.md)** - Common issues and solutions

## Further Reading

- [Yjs Documentation](https://docs.yjs.dev/)
- [MobX Documentation](https://mobx.js.org/)
- [CRDT Research Papers](https://crdt.tech/)
- [WebRTC Fundamentals](https://webrtc.org/getting-started/overview)
