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

<Meta title='@dxtmisha/en/figma/Classes/FigmaPostAbstract - Base Messaging Class'/>

# FigmaPostAbstract Class

Base abstract class for managing messaging between the Figma plugin (backend) and the UI (frontend). It provides a structured foundation for bidirectional communication with built-in verification and multiple listener management.

## Key Features

- **Bidirectional Support** — Foundation for both `FigmaPluginMessenger` and `FigmaUiMessenger`.
- **Message Verification** — Uses `FigmaPostCode` to ensure that messages originated from the same plugin instance.
- **Multicast Listeners** — Supports multiple callbacks for a single message type.
- **Method Chaining** — Methods like `make` and `add` return `this`, allowing for a more concise initialization.

## Public Methods

### `make`

Initializes the message listener. This method ensures that the environment-specific setup (`prepare`) is executed exactly once, regardless of how many times `make` is called.

**Returns:** `this`

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

### `add`

Registers a callback function to be executed when a message of a specific type is received.

**Parameters:**
- `type: string` — The unique identifier for the message type.
- `callback: UiFigmaMessengerCallback<Message>` — The function to call when the message is received. Receives the message data as its first argument.
- `once: boolean = false` — If set to `true`, the callback will be automatically removed after being called once.

**Returns:** `this`

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

### `remove`

Removes a previously registered callback function for a specific message type.

**Parameters:**
- `type: string` — The unique identifier for the message type.
- `callback: UiFigmaMessengerCallback<Message>` — The function to be removed from the listeners.

**Returns:** `this`

```javascript
const onUpdate = (data) => console.log('Selection:', data.count)

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

## Data Structures

### `UiFigmaMessengerData`

The structure of the data object passed through the messaging pipeline:

- `code: string` — The verification code from `FigmaPostCode`.
- `type: string` — The identifier of the message.
- `message: Message` — The actual payload data.

## Extending the Class

`FigmaPostAbstract` is an abstract class that serves as a foundation for creating custom messengers. To use it, you must create a subclass and implement two required methods:

### `post`

An abstract method for implementing the logic to send messages to the other side. In a derived class, this method should encapsulate the system-specific send call (e.g., `postMessage`).

**Parameters:**
- `type: string` — The unique identifier for the message type.
- `message: Message` — The message data to be sent.

```typescript
post<Message>(type: string, message?: Message): void {
  // Implementation of system sending
}
```

### `prepare`

An abstract protected method for setting up the system's incoming event listener. This method is called automatically once when `make()` is executed. Within the implementation, `this.onMessage(data)` must be called whenever data is received.

```typescript
protected prepare(): void {
  // Setup subscription to system events
}
```

## Usage

Once you have implemented your custom class, work with it as follows:

1. **Initialization**: Call the `make()` method to start the listener (triggers your `prepare` implementation).
2. **Subscribing**: Use the `add(type, callback)` method to handle incoming data.
3. **Sending**: Use the `post(type, data)` method.

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

messenger.add('my-event', (data) => {
  console.log('Message received:', data);
});

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