npm package: @mexty/realtime
Description: React hooks for real-time collaborative features using Yjs and Hocuspocus
Author: MEXT Team
Latest version: 2.1.0

# @mexty/realtime

React hooks for real-time collaborative features using Yjs and Hocuspocus.

## Installation

```bash
npm install @mexty/realtime
```

## Usage

```tsx
import { useCollabSpace } from "@mexty/realtime";

// 🧠 Example 1: Collaborative JSON document editor
export function DocumentEditor({ blockId }: { blockId: string }) {
  const { state, update } = useCollabSpace(`block:${blockId}`, {
    document: {
      title: "Untitled",
      content: "Write something...",
    },
    game: { weights: [] },
  });

  // ✅ Partial update usage
  const handleTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    update({ document: { ...state.document, title: e.target.value } });
  };

  // ✅ Functional update usage
  const resetContent = () => {
    update((prev) => ({
      ...prev,
      document: { ...prev.document, content: "" },
    }));
  };

  return (
    <div className="p-4 border rounded space-y-3">
      <h2 className="text-lg font-bold">Collaborative Document</h2>
      <input
        type="text"
        className="border p-2 w-full"
        value={state.document.title}
        onChange={handleTitleChange}
      />
      <textarea
        className="border p-2 w-full h-32"
        value={state.document.content}
        onChange={(e) =>
          update({ document: { ...state.document, content: e.target.value } })
        }
      />
      <button
        onClick={resetContent}
        className="bg-blue-500 text-white px-3 py-1 rounded"
      >
        Reset Content
      </button>
    </div>
  );
}

// 🧩 Example 2: Multiplayer tower game state
export function TowerGame({ blockId }: { blockId: string }) {
  const { state, update } = useCollabSpace(`block:${blockId}`, {
    document: {},
    game: { weights: [] as { team: string; pos: number }[] },
  });

  // ✅ Append new weight (functional update)
  const addWeight = (team: string) => {
    update((prev) => ({
      ...prev,
      game: {
        ...prev.game,
        weights: [...prev.game.weights, { team, pos: Math.random() * 100 }],
      },
    }));
  };

  // ✅ Clear game state (partial update)
  const resetGame = () => {
    update({ game: { weights: [] } });
  };

  return (
    <div className="p-4 border rounded space-y-3">
      <h2 className="text-lg font-bold">Tower Game</h2>
      <button
        onClick={() => addWeight("blue")}
        className="bg-blue-600 text-white px-3 py-1 rounded"
      >
        Add Blue Weight
      </button>
      <button
        onClick={() => addWeight("red")}
        className="bg-red-600 text-white px-3 py-1 rounded"
      >
        Add Red Weight
      </button>
      <button
        onClick={resetGame}
        className="bg-gray-600 text-white px-3 py-1 rounded"
      >
        Reset Game
      </button>

      <pre className="bg-gray-100 p-2 text-sm rounded overflow-auto">
        {JSON.stringify(state.game, null, 2)}
      </pre>
    </div>
  );
}
```

## API

### `useCollabSpace(documentName, initialState, options?)`

#### Parameters

- `documentName: string` - Unique identifier for the collaborative document
- `initialState: T` - Initial state object for the collaborative space
- `options?: CollabSpaceOptions` - Optional configuration

#### Returns

- `state: T` - Current collaborative state
- `update: (updateFn: UpdateFunction<T>) => void` - Function to update state
- `isConnected: boolean` - WebSocket connection status
- `connectionStatus: 'connecting' | 'connected' | 'disconnected' | 'error'` - Detailed connection status
- `userId: string` - Anonymous user ID (persisted in localStorage)

#### Options

```tsx
interface CollabSpaceOptions {
  websocketUrl?: string;
  onConnect?: () => void;
  onDisconnect?: () => void;
  onError?: (error: Error) => void;
}
```

## Features

- 🔄 Real-time collaborative state synchronization
- 🆔 Anonymous user authentication with persistent IDs
- 🔗 Automatic WebSocket connection management
- 📱 React hooks for easy integration
- 🎯 TypeScript support with full type safety
- 🏗️ Built on Yjs and Hocuspocus for reliability

## License

MIT