# Миграция с версии 0.5.x на 0.6.0

## Signals

### `Signal.create()` → `Signal.state()`

```typescript
// Было
const count = Signal.create(0);    // ❌

// Стало
const count = Signal.state(0);     // ✅
```

### `LocalSignal` → `LocalState`

```typescript
// Было
const count = new LocalSignal(0);              // ❌

// Стало
const count = LocalState.create({ key: 'count', defaultValue: 0 });   // ✅
```

## Query

Модуль Query полностью переписан в v0.6.0. Главное архитектурное изменение — переход от **standalone-функций** к **централизованному API** через `createApi()`.

### 1. Переход на `createApi`

Все ресурсы и команды теперь создаются через объект API:

```typescript
// ❌ Было (v0.5.x) — standalone функции
import { createResource, createCommand } from '@fozy-labs/rx-toolkit';

const getUsers = createResource({
    queryFn: (page: number) => fetch(`/api/users?page=${page}`).then(r => r.json()),
});

const updateUser = createCommand({
    queryFn: (data: UserUpdate) => fetch('/api/users', { method: 'PUT', body: JSON.stringify(data) }).then(r => r.json()),
    link: (link) => {
        link({ resource: getUsers, forwardArgs: () => 1 });
    },
});
```

```typescript
// ✅ Стало (v0.6.0) — централизованный API
import { createApi, reactHooksPlugin } from '@fozy-labs/rx-toolkit';

const api = createApi({
    plugins: [reactHooksPlugin()],
});

const getUsers = api.createResource({
    queryFn: (page: number) => fetch(`/api/users?page=${page}`).then(r => r.json()),
});

const updateUser = api.createCommand({
    queryFn: (data: UserUpdate) => fetch('/api/users', { method: 'PUT', body: JSON.stringify(data) }).then(r => r.json()),
    links: [
        { resource: getUsers, forwardArgs: () => 1 },
    ],
});
```

### 2. Удалённые standalone-функции

| v0.5.x | v0.6.0 |
|--------|--------|
| `createResource(options)` | `api.createResource(options)` |
| `createCommand(options)` | `api.createCommand(options)` |
| `createOperation(options)` _(deprecated)_ | `api.createCommand(options)` |
| `createResourceDuplicator(resource)` | удалён без замены |
| `resetAllQueriesCache()` | `api.resetAll()` |

### 3. React хуки

Все старые хуки удалены. Новые доступны двумя способами — как standalone-хуки или через плагин `reactHooksPlugin()`.

#### `useResourceAgent` → `useResource`

```typescript
// ❌ Было
import { useResourceAgent } from '@fozy-labs/rx-toolkit';
const query = useResourceAgent(getUsers, { page: 1 });

// ✅ Стало — standalone хук
import { useResource } from '@fozy-labs/rx-toolkit';
const query = useResource(getUsers, { page: 1 });

// ✅ Стало — через плагин (если createApi с reactHooksPlugin)
const query = getUsers.useResource({ page: 1 });
```

#### `useCommandAgent` / `useOperationAgent` → `useCommand`

```typescript
// ❌ Было
import { useCommandAgent } from '@fozy-labs/rx-toolkit';
const [trigger] = useCommandAgent(updateUser);
// или deprecated:
const [trigger] = useOperationAgent(updateUser);

// ✅ Стало — standalone хук
import { useCommand } from '@fozy-labs/rx-toolkit';
const [trigger, state] = useCommand(updateUser);

// ✅ Стало — через плагин
const [trigger, state] = updateUser.useCommand();
```

#### `useResourceRef` → `resource.getEntry()`

```typescript
// ❌ Было
const ref = useResourceRef(todoResource, args);

// ✅ Стало — прямой замены в виде хука нет
const entry = todoResource.getEntry(args, true); // true = инициировать запрос если записи нет
```

### 4. Links API

Свойство `link` (callback) переименовано в `links` (массив или callback). Колбэки `optimisticUpdate` и `update` больше **не принимают объект**, а получают аргументы напрямую:

```typescript
// ❌ Было (v0.5.x) — link (singular, callback)
const updateUser = createCommand({
    queryFn: (data) => fetch('/api/users', { method: 'PUT', body: JSON.stringify(data) }).then(r => r.json()),
    link: (link) => {
        link({
            resource: getUsers,
            forwardArgs: (cmdArgs) => cmdArgs.userId,
            optimisticUpdate: ({ draft, args }) => {
                draft.name = args.newName;
            },
            update: ({ draft, args, data }) => {
                Object.assign(draft, data);
            },
        });
    },
});

// ✅ Стало (v0.6.0) — links (plural, массив)
const updateUser = api.createCommand({
    queryFn: (data) => fetch('/api/users', { method: 'PUT', body: JSON.stringify(data) }).then(r => r.json()),
    links: [
        {
            resource: getUsers,
            forwardArgs: (cmdArgs) => cmdArgs.userId,
            optimisticUpdate: (draft, args) => {
                draft.name = args.newName;
            },
            update: (draft, args, result) => {
                Object.assign(draft, result);
            },
        },
    ],
});
```

> **Изменения:**
> - `link` → `links` (принимает массив объектов или callback)
> - `optimisticUpdate: ({ draft, args }) =>` → `optimisticUpdate: (draft, args) =>`
> - `update: ({ draft, args, data }) =>` → `update: (draft, args, result) =>` (`data` → `result`)

### 5. Machine — иммутабельные подтипы

`Machine` теперь — иммутабельное дискриминированное объединение из пяти подтипов:

```typescript
type Machine<TArgs, TData> =
    | MachinePending<TArgs, TData>      // status: 'pending'
    | MachineSuccess<TArgs, TData>      // status: 'success'
    | MachineError<TArgs, TData>        // status: 'error'
    | MachineRefreshing<TArgs, TData>   // status: 'refreshing'
    | MachineRefreshError<TArgs, TData> // status: 'refresh-error'
```

Проверка состояния:

```typescript
const machine = entry.machine$();

if (machine.state.status === 'success') {
    console.log(machine.state.data);   // типизировано как TData
}

if (machine.state.status === 'error') {
    console.log(machine.state.error);  // типизировано как Error
}
```

### 6. Новые возможности `createApi`

```typescript
const api = createApi({
    // Плагины для расширения resource/command (например, React-хуки)
    plugins: [reactHooksPlugin()],
    // Префикс ключей для изоляции нескольких API-инстансов
    keyPrefix: 'myApp',
    // Драйвер синхронизации между вкладками
    syncDriver: broadcastSyncDriver(),
    // Какие данные синхронизировать: 'none' | 'resources' | 'all'
    defaultSync: 'all',
    // Время жизни кеша ресурсов (мс), false = бессрочно
    resourceRetentionTime: 30_000,
    // Время жизни кеша команд (мс), false = бессрочно
    commandRetentionTime: 5_000,
    // SSR: время валидности снапшота (мс)
    snapshotValidTime: 60_000,
    // SSR: начальный снапшот с сервера
    initialSnapshot: getServerSnapshot(),
});

// Снапшот для SSR
const snapshot = api.getSnapshot();

// Сброс всего кеша (замена resetAllQueriesCache)
api.resetAll();
```
