# Миграция с версии 0.10.x на 0.11.0

## Query

Релиз унифицирует словарь запуска у ресурсов и команд: `trigger` перестаёт означать три разных контракта.

| Уровень | Было (0.10.x) | Стало (0.11.0) |
|---|---|---|
| `Command` (ядро) | `trigger(args, key?)` → сырой `Promise<TData>` | `execute(args, key?)` — тот же контракт; `trigger` **deprecated** |
| `CommandAgent` / `useCommand` | `trigger(args)` → конверт `TTriggerPromise` | без изменений |
| `Resource` | `trigger(args, doForce?)` → `void` | **deprecated** → `prefetch(args)` / `prefetch(args, { force: true })` |

### `Command.trigger` → `Command.execute`

Чистое переименование, контракт идентичен (сырой промис, реджектится, `mapError`). Старое имя работает с пометкой `@deprecated` и будет удалено в одном из следующих релизов:

```typescript
// Было
await addTodoCommand.trigger({ text: 'Задача' }, 'my-key');

// Стало
await addTodoCommand.execute({ text: 'Задача' }, 'my-key');
```

### `Resource.trigger` → `prefetch`

Императивный API ресурса (`ensure` / `fetch` / `prefetch`) стабилизирован — с него снят `@experimental`. `Resource.trigger` объявлен `@deprecated`; замена:

```typescript
// Было
usersResource.trigger({ page: 1 });          // запустить, если ещё нет
usersResource.trigger({ page: 1 }, true);    // форс-перезапрос

// Стало
void usersResource.prefetch({ page: 1 });
void usersResource.prefetch({ page: 1 }, { force: true });
```

Общее сохраняется: запись создаётся синхронно, промис (`Promise<void>`) никогда не реджектится. Но замена **не тождественна** — различия сосредоточены на записи в состоянии `error`:

- `prefetch(args)` (без `force`) **ретраит упавшую запись** (он делегирует в `ensure`), тогда как старый `trigger(args)` был на ней no-op. Код, который «замолкал» после ошибки (например, периодический прогрев), после механической замены начнёт повторять запрос при каждом вызове. Если это нежелательно — проверяйте состояние перед вызовом: `if (!resource.getState(args).isError) void resource.prefetch(args)`.
- `prefetch({ force: true })` на упавшей записи тоже делает `retry`. Старый `trigger(args, true)` на ней фактически был no-op: его force-путь шёл через `refresh()`, который невалиден из состояния `error` и лишь писал предупреждение в консоль. То есть ретрай упавшей записи — **новое** поведение force-пути, а не замена одного перезапуска другим.
- `prefetch` касается retention-таймера записи, а `trigger` — нет. Каждый вызов `prefetch` (включая cache-hit) удерживает подписку на запись до резолва и затем **перезапускает отсчёт `retentionTime` заново**. Следствие для периодического прогрева ненаблюдаемой записи: с интервалом меньше `retentionTime` запись теперь живёт бесконечно и — без `force` — никогда не перезапрашивается, тогда как старый `trigger` давал ей истечь и пересоздавал со свежим запросом примерно раз в retention-окно. Для такого паттерна используйте `{ force: true }` либо интервал больше `retentionTime`.

### Что не изменилось

- Агентский / хуковый `trigger` — по-прежнему возвращает конверт `TTriggerPromise` (не реджектится, `.unwrap()` даёт сырой промис). Типы `TTriggerResult` / `TTriggerPromise` и хелпер `wrapTrigger` на месте.
- Реактивное состояние (`TCommandAgentState`: `status`, `data`, `error`, `isLoading`, `isSuccess`, `isError`, `retry`) — код, читающий состояние из `useCommand` / `state$`, менять не нужно.
- Ретраи и request id — `retry()` и стабильность ключа идемпотентности работают как раньше.
- `ensure` / `fetch` — сигнатуры и семантика прежние (изменился только статус стабильности).
- `mapError` — все реджекты мутаций и поле `error` конверта по-прежнему нормализованы.

Подробнее — в [API агента команды](../query/api/command-agent.md#результат-trigger) и [API ресурса](../query/api/resource.md#ensure--fetch--prefetch).
