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

<Meta title='@dxtmisha/vi/figma/Classes/FigmaPostAbstract - Lớp cơ sở cho nhắn tin'/>

# Lớp FigmaPostAbstract

Lớp trừu tượng cơ sở để quản lý việc nhắn tin giữa plugin Figma (backend) và UI (frontend). Nó cung cấp một nền tảng có cấu trúc cho giao tiếp hai chiều với tính năng xác minh tích hợp và quản lý nhiều trình lắng nghe.

## Các tính năng chính

- **Hỗ trợ hai chiều** — Nền tảng cho cả `FigmaPluginMessenger` và `FigmaUiMessenger`.
- **Xác minh tin nhắn** — Sử dụng `FigmaPostCode` để đảm bảo rằng tin nhắn bắt nguồn từ cùng một phiên bản plugin.
- **Trình lắng nghe đa điểm** — Hỗ trợ nhiều callback cho một loại tin nhắn duy nhất.
- **Chuỗi phương thức (Chaining)** — Các phương thức như `make` và `add` trả về `this`, cho phép khởi tạo ngắn gọn hơn.

## Các phương thức công khai

### `make`

Khởi tạo trình lắng nghe tin nhắn. Phương thức này đảm bảo rằng việc thiết lập cụ thể cho môi trường (`prepare`) được thực hiện đúng một lần, bất kể `make` được gọi bao nhiêu lần.

**Trả về:** `this`

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

### `add`

Đăng ký một hàm callback để thực thi khi nhận được tin nhắn thuộc một loại cụ thể.

**Tham số:**
- `type: string` — Mã định danh duy nhất cho loại tin nhắn.
- `callback: UiFigmaMessengerCallback<Message>` — Hàm sẽ gọi khi nhận được tin nhắn. Nhận dữ liệu tin nhắn làm đối số đầu tiên.
- `once: boolean = false` — Nếu được đặt thành `true`, callback sẽ tự động bị xóa sau khi được gọi một lần.

**Trả về:** `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`

Xóa một hàm callback đã đăng ký trước đó cho một loại tin nhắn cụ thể.

**Tham số:**
- `type: string` — Mã định danh duy nhất cho loại tin nhắn.
- `callback: UiFigmaMessengerCallback<Message>` — Hàm sẽ bị xóa khỏi các trình lắng nghe.

**Trả về:** `this`

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

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

## Cấu trúc dữ liệu

### `UiFigmaMessengerData`

Cấu trúc của đối tượng dữ liệu được truyền qua đường truyền tin nhắn:

- `code: string` — Mã xác minh từ `FigmaPostCode`.
- `type: string` — Mã định danh của tin nhắn.
- `message: Message` — Dữ liệu payload thực tế.

## Mở rộng lớp

`FigmaPostAbstract` là một lớp trừu tượng và đóng vai trò là nền tảng để tạo các messenger tùy chỉnh. Để sử dụng nó, bạn phải tạo một lớp con và thực hiện hai phương thức bắt buộc:

### `post`

Một phương thức trừu tượng để thực hiện logic gửi tin nhắn đến phía bên kia. Trong lớp dẫn xuất, phương thức này sẽ đóng gói lệnh gọi gửi theo hệ thống cụ thể (ví dụ: `postMessage`).

**Tham số:**
- `type: string` — Mã định danh duy nhất cho loại tin nhắn.
- `message: Message` — Dữ liệu tin nhắn sẽ được gửi.

```typescript
post<Message>(type: string, message?: Message): void {
  // Thực hiện gửi theo hệ thống
}
```

### `prepare`

Một phương thức được bảo vệ trừu tượng để thiết lập trình lắng nghe sự kiện đến của hệ thống. Phương thức này được gọi tự động một lần khi `make()` được thực thi. Trong quá trình thực hiện, `this.onMessage(data)` phải được gọi bất cứ khi nào nhận được dữ liệu.

```typescript
protected prepare(): void {
  // Thiết lập đăng ký các sự kiện hệ thống
}
```

## Cách sử dụng

Sau khi đã triển khai lớp tùy chỉnh của mình, hãy làm việc với nó như sau:

1. **Khởi tạo**: Gọi phương thức `make()` để bắt đầu trình lắng nghe (kích hoạt triển khai `prepare` của bạn).
2. **Đăng ký**: Sử dụng phương thức `add(type, callback)` để xử lý dữ liệu đến.
3. **Gửi**: Sử dụng phương thức `post(type, data)`.

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

messenger.add('my-event', (data) => {
  console.log('Nhận được tin nhắn:', data);
});

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