import {Meta} from '@storybook/addon-docs/blocks'

<Meta title='@dxtmisha/ru/figma/Classes/FigmaPostAbstract - Базовый класс сообщений'/>

# Класс FigmaPostAbstract

Базовый абстрактный класс для управления обменом сообщениями между плагином Figma (backend) и UI (frontend). Обеспечивает структурированную основу для двусторонней связи со встроенной проверкой и управлением несколькими слушателями.

## Ключевые особенности

- **Двусторонняя поддержка** — База как для `FigmaPluginMessenger`, так и для `FigmaUiMessenger`.
- **Проверка сообщений** — Использует `FigmaPostCode`, чтобы гарантировать, что сообщения исходят из того же экземпляра плагина.
- **Множественные слушатели** — Поддерживает несколько колбэков для одного типа сообщения.
- **Цепочка вызовов** — Методы, такие как `make` и `add`, возвращают `this`, что позволяет писать более лаконичный код.

## Публичные методы

### `make`

Инициализирует слушатель сообщений. Этот метод гарантирует, что специфичная для среды настройка (`prepare`) будет выполнена ровно один раз, независимо от того, сколько раз вызывается `make`.

**Возвращает:** `this`

```javascript
const messenger = new FigmaPluginMessenger().make()
```

### `add`

Регистрирует функцию обратного вызова (колбэк), которая будет выполнена при получении сообщения определенного типа.

**Параметры:**
- `type: string` — Уникальный идентификатор типа сообщения.
- `callback: UiFigmaMessengerCallback<Message>` — Функция, вызываемая при получении сообщения. Получает данные сообщения в качестве первого аргумента.
- `once: boolean = false` — Если установлено значение `true`, колбэк будет автоматически удален после одного вызова.

**Возвращает:** `this`

```javascript
messenger
  .add('update-selection', (data) => console.log('Выбор:', data.count))
  .add('init', (data) => console.log('Init:', data), true)
  .add('close', () => figma.closePlugin())
```

### `remove`

Удаляет ранее зарегистрированную функцию обратного вызова для определенного типа сообщения.

**Параметры:**
- `type: string` — Уникальный идентификатор типа сообщения.
- `callback: UiFigmaMessengerCallback<Message>` — Функция, которая будет удалена из слушателей.

**Возвращает:** `this`

```javascript
const onUpdate = (data) => console.log('Выбор:', data.count)

messenger
  .add('update-selection', onUpdate)
  .remove('update-selection', onUpdate)
```

## Расширение класса

`FigmaPostAbstract` является абстрактным классом и служит основой для создания собственных мессенджеров. Для его использования необходимо создать производный класс и реализовать два обязательных метода:

### `post`

Абстрактный метод для реализации логики отправки сообщений на другую сторону. В производном классе этот метод должен инкапсулировать системный вызов отправки (например, `postMessage`).

**Параметры:**
- `type: string` — Уникальный идентификатор типа сообщения.
- `message: Message` — Данные сообщения для отправки.

```typescript
post<Message>(type: string, message?: Message): void {
  // Реализация системной отправки
}
```

### `prepare`

Абстрактный защищенный метод для настройки системного слушателя входящих событий. Метод вызывается автоматически один раз при вызове `make()`. Внутри реализации при получении данных необходимо вызвать `this.onMessage(data)`.

```typescript
protected prepare(): void {
  // Настройка подписки на системные события
}
```

## Использование

После реализации собственного класса, работа с ним строится следующим образом:

1. **Создание экземпляра и инициализация**: Вызовите метод `make()` для запуска слушателя (вызывает ваш `prepare`).
2. **Подписка на сообщения**: Используйте метод `add(type, callback)` для обработки входящих данных.
3. **Отправка сообщений**: Используйте метод `post(type, data)`.

```typescript
const messenger = new MyMessenger().make();

messenger.add('my-event', (data) => {
  console.log('Получено сообщение:', data);
});

messenger.post('my-event', { hello: 'world' });
```

## Структуры данных

### `UiFigmaMessengerData`

Структура объекта данных, передаваемого через систему сообщений:

- `code: string` — Код проверки из `FigmaPostCode`.
- `type: string` — Идентификатор сообщения.
- `message: Message` — Сами полезные данные сообщения.
