# Browser IDE SDK - API Documentation

## Overview

Browser IDE SDK — это production-ready React SDK для запуска React-проектов прямо в браузере с использованием Sandpack. SDK предоставляет полноценную IDE с редактором кода, файловым деревом, preview и терминалом.

## Архитектура

```
┌─────────────────────────────────────────────────────────────────┐
│                        BrowserIDE                                │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │                     Toolbar                               │   │
│  │  [Logo] [Code | Split | Preview] [Terminal Toggle]        │   │
│  └──────────────────────────────────────────────────────────┘   │
│  ┌─────────┬────────────────────────────────────────────────┐   │
│  │         │                                                 │   │
│  │  File   │              Main Content                       │   │
│  │  Tree   │  ┌──────────────────┬───────────────────────┐  │   │
│  │         │  │                  │                       │  │   │
│  │  📁 src │  │   Code Editor    │     Live Preview      │  │   │
│  │  📄 App │  │   (Sandpack)     │     (Sandpack)        │  │   │
│  │  📄 css │  │                  │                       │  │   │
│  │         │  │                  │                       │  │   │
│  │         │  └──────────────────┴───────────────────────┘  │   │
│  └─────────┴────────────────────────────────────────────────┘   │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │                    Terminal (xterm.js)                    │   │
│  │  $ npm install                                            │   │
│  │  ✓ Dependencies installed                                 │   │
│  └──────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘
```

## Data Flow

```
GitHub API Response
       │
       ▼
┌──────────────────┐
│ loadGitHubTree() │  ◄── Fetches & caches files
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│  SandpackFiles   │  ◄── Virtual file system
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ SandpackProvider │  ◄── State container
└────────┬─────────┘
         │
    ┌────┴────┐
    ▼         ▼
┌───────┐ ┌─────────┐
│Editor │ │ Preview │  ◄── Hot reload
└───────┘ └─────────┘
```

## Installation

```bash
npm install @codesandbox/sandpack-react @codesandbox/sandpack-themes @xterm/xterm @xterm/addon-fit
```

## Основной компонент

### `<BrowserIDE />`

Главный компонент SDK.

```tsx
import { BrowserIDE } from './browser-ide-sdk';

<BrowserIDE
  githubTree={tree}
  activeFile="/src/App.tsx"
  onActiveFileChange={(file) => setActiveFile(file)}
  startCommand="npm run dev"
  defaultViewMode="split"
  defaultTerminalOpen={false}
  theme="dark"
  height="100vh"
  onReady={() => console.log('Ready!')}
  onError={(err) => console.error(err)}
  onCommandStart={(cmd) => console.log('Running:', cmd)}
  onCommandComplete={(code) => console.log('Exit:', code)}
/>
```

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `githubTree` | `GitHubTreeNode[]` | *required* | Структура файлов из GitHub API |
| `activeFile` | `string` | *required* | Путь к активному файлу (controlled) |
| `onActiveFileChange` | `(path: string) => void` | *required* | Callback при смене файла |
| `startCommand` | `string` | `"npm run dev"` | Команда запуска после установки |
| `defaultViewMode` | `ViewMode` | `"split"` | Режим отображения по умолчанию |
| `defaultTerminalOpen` | `boolean` | `false` | Терминал открыт по умолчанию |
| `theme` | `ThemeOption` | `"dark"` | Тема оформления |
| `height` | `string` | `"100vh"` | Высота контейнера |
| `onReady` | `() => void` | - | Callback когда IDE готова |
| `onError` | `(error: Error) => void` | - | Callback при ошибке |
| `onCommandStart` | `(cmd: string) => void` | - | Callback при старте команды |
| `onCommandComplete` | `(code: number) => void` | - | Callback при завершении команды |

## Types

### `GitHubTreeNode`

Структура узла дерева файлов из GitHub API:

```typescript
interface GitHubTreeNode {
  path: string;      // Путь к файлу/папке
  mode: string;      // Git mode (040000 = dir, 100644 = file)
  type: 'blob' | 'tree';  // blob = файл, tree = папка
  sha: string;       // SHA хеш
  size?: number;     // Размер файла в байтах
  url: string;       // URL для получения содержимого
}
```

### `ViewMode`

Режимы отображения:

```typescript
type ViewMode = 'code' | 'preview' | 'split';
```

- `code` — только редактор кода
- `preview` — только превью
- `split` — редактор и превью рядом (50/50)

### `ThemeOption`

```typescript
type ThemeOption = 'dark' | 'light' | 'auto';
```

## Утилиты

### `loadGitHubTree()`

Загружает файлы из GitHub и создаёт виртуальную файловую систему:

```typescript
import { loadGitHubTree } from './browser-ide-sdk';

const { files, fileTree } = await loadGitHubTree(
  githubTree,
  (state) => {
    console.log(`Loading: ${state.progress}%`);
    if (state.currentFile) {
      console.log(`File: ${state.currentFile}`);
    }
  }
);
```

### `clearCache()`

Очищает кэш загруженных файлов:

```typescript
import { clearCache } from './browser-ide-sdk';

clearCache();
```

### `getCacheStats()`

Получает статистику кэша:

```typescript
import { getCacheStats } from './browser-ide-sdk';

const { size, entries } = getCacheStats();
console.log(`Cache: ${entries} files, ${size} bytes`);
```

## Компоненты

### `<FileTree />`

Компонент файлового дерева (используется внутри BrowserIDE):

```tsx
import { FileTree } from './browser-ide-sdk';

<FileTree
  tree={fileTree}
  activeFile="/src/App.tsx"
  onFileSelect={(path) => setActiveFile(path)}
/>
```

### `<Terminal />`

Терминал на базе xterm.js:

```tsx
import { Terminal, TerminalHandle } from './browser-ide-sdk';

const terminalRef = useRef<TerminalHandle>(null);

<Terminal
  ref={terminalRef}
  isOpen={isOpen}
  onToggle={() => setIsOpen(!isOpen)}
  theme="dark"
/>

// API терминала
terminalRef.current?.writeln('Hello!');
terminalRef.current?.writeSuccess('Done!');
terminalRef.current?.writeError('Failed!');
terminalRef.current?.writeCommand('npm install');
terminalRef.current?.clear();
```

## Примеры использования

### Базовый пример

```tsx
import { useState } from 'react';
import { BrowserIDE, GitHubTreeNode } from './browser-ide-sdk';

function App() {
  const [activeFile, setActiveFile] = useState('/src/App.tsx');

  // Получено из GitHub API
  const githubTree: GitHubTreeNode[] = [
    {
      path: 'src/App.tsx',
      type: 'blob',
      mode: '100644',
      sha: 'abc123',
      url: 'https://api.github.com/repos/...'
    }
    // ...
  ];

  return (
    <BrowserIDE
      githubTree={githubTree}
      activeFile={activeFile}
      onActiveFileChange={setActiveFile}
    />
  );
}
```

### Загрузка из GitHub API

```tsx
import { useState, useEffect } from 'react';
import { BrowserIDE, GitHubTreeNode } from './browser-ide-sdk';

function GitHubProject({ owner, repo, branch }: Props) {
  const [tree, setTree] = useState<GitHubTreeNode[]>([]);
  const [activeFile, setActiveFile] = useState('/src/App.tsx');
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function loadTree() {
      // 1. Получить SHA бранча
      const refRes = await fetch(
        `https://api.github.com/repos/${owner}/${repo}/git/ref/heads/${branch}`
      );
      const ref = await refRes.json();
      
      // 2. Получить дерево
      const treeRes = await fetch(
        `https://api.github.com/repos/${owner}/${repo}/git/trees/${ref.object.sha}?recursive=1`
      );
      const treeData = await treeRes.json();
      
      setTree(treeData.tree);
      setLoading(false);
    }
    
    loadTree();
  }, [owner, repo, branch]);

  if (loading) return <div>Loading...</div>;

  return (
    <BrowserIDE
      githubTree={tree}
      activeFile={activeFile}
      onActiveFileChange={setActiveFile}
    />
  );
}
```

### Обработка ошибок

```tsx
function App() {
  const handleError = (error: Error) => {
    // Логирование в сервис мониторинга
    console.error('IDE Error:', error);
    
    // Показать уведомление пользователю
    toast.error(`Error: ${error.message}`);
  };

  return (
    <BrowserIDE
      githubTree={tree}
      activeFile={activeFile}
      onActiveFileChange={setActiveFile}
      onError={handleError}
    />
  );
}
```

## Тестирование

### 1. Загрузка GitHub tree

```tsx
import { loadGitHubTree } from './browser-ide-sdk';

test('loads valid GitHub tree', async () => {
  const tree = [
    { path: 'src/App.tsx', type: 'blob', sha: '123', url: '...' }
  ];
  
  const result = await loadGitHubTree(tree);
  
  expect(result.files['/src/App.tsx']).toBeDefined();
  expect(result.fileTree).toHaveLength(1);
});
```

### 2. Переключение режимов

```tsx
import { render, fireEvent } from '@testing-library/react';
import { BrowserIDE } from './browser-ide-sdk';

test('switches view modes', () => {
  const { getByTitle } = render(
    <BrowserIDE
      githubTree={mockTree}
      activeFile="/src/App.tsx"
      onActiveFileChange={jest.fn()}
    />
  );
  
  fireEvent.click(getByTitle('Code Only'));
  // Assert code panel visible, preview hidden
  
  fireEvent.click(getByTitle('Preview Only'));
  // Assert preview visible, code hidden
});
```

### 3. Открытие/закрытие терминала

```tsx
test('toggles terminal', () => {
  const { getByText } = render(<BrowserIDE {...props} />);
  
  const toggleBtn = getByText('▼ Terminal');
  fireEvent.click(toggleBtn);
  
  expect(getByText('▲ Hide Terminal')).toBeInTheDocument();
});
```

### 4. Смена активного файла

```tsx
test('respects activeFile prop', () => {
  const onFileChange = jest.fn();
  
  const { rerender } = render(
    <BrowserIDE
      activeFile="/src/App.tsx"
      onActiveFileChange={onFileChange}
      {...otherProps}
    />
  );
  
  // Simulate file click
  fireEvent.click(getByText('index.tsx'));
  
  expect(onFileChange).toHaveBeenCalledWith('/src/index.tsx');
});
```

## Безопасность

1. **Sandbox Isolation** — весь код выполняется в изолированном iframe с другим origin
2. **No eval()** — код не выполняется через eval() или Function()
3. **CSP Headers** — Sandpack использует строгие Content Security Policy

## Оптимизации производительности

1. **Кэширование** — файлы кэшируются в памяти с TTL 5 минут
2. **Debounce** — изменения файлов debounce'ятся на 300ms перед rebuild
3. **React.memo** — FileTree компоненты мемоизированы
4. **Lazy Loading** — редактор загружается асинхронно
5. **Rate Limiting** — запросы к GitHub API ограничены (50ms между запросами)

