@sentinel-it/meowmeow-sdk 0.1.0-rc.7f74b8d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +287 -0
- package/dist/index.d.ts +612 -0
- package/dist/meowmeow-sdk.esm.js +13528 -0
- package/dist/meowmeow-sdk.esm.js.map +1 -0
- package/dist/meowmeow-sdk.js +738 -0
- package/dist/meowmeow-sdk.js.map +1 -0
- package/package.json +105 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,612 @@
|
|
|
1
|
+
export declare type ClientErrorCode = 'WS_ERROR' | 'WS_MESSAGE_ERROR' | 'TOKEN_REFRESH_FAILED' | 'JOIN_ROOM_FAILED';
|
|
2
|
+
|
|
3
|
+
/** `MeowMeowClient` 可監聽的事件與其 payload 型別對應表 */
|
|
4
|
+
export declare interface ClientEventMap {
|
|
5
|
+
/** WebSocket 連線建立,伺服器已確認身份 */
|
|
6
|
+
connected: {
|
|
7
|
+
user: User;
|
|
8
|
+
};
|
|
9
|
+
/** 連線中斷;`willReconnect` 為 true 時 SDK 會自動重連 */
|
|
10
|
+
disconnected: {
|
|
11
|
+
reason: DisconnectReason;
|
|
12
|
+
willReconnect: boolean;
|
|
13
|
+
};
|
|
14
|
+
/** 目前所在的聊天室已不可用,已退回 lobby,WS 連線保留 */
|
|
15
|
+
room_unavailable: {
|
|
16
|
+
roomId: string;
|
|
17
|
+
};
|
|
18
|
+
/** 正在嘗試重新連線,`attempt` 為目前第幾次嘗試 */
|
|
19
|
+
reconnecting: {
|
|
20
|
+
attempt: number;
|
|
21
|
+
};
|
|
22
|
+
/** 重連成功 */
|
|
23
|
+
reconnected: void;
|
|
24
|
+
/** 目前使用者被禁言,`until` 為禁言到期時間(ISO 8601),永久禁言為 null */
|
|
25
|
+
muted: {
|
|
26
|
+
until: string | null;
|
|
27
|
+
};
|
|
28
|
+
/** 目前使用者的禁言已解除 */
|
|
29
|
+
unmuted: void;
|
|
30
|
+
/** 目前使用者被封禁,`until` 為解封時間(ISO 8601),永久封禁為 null */
|
|
31
|
+
banned: {
|
|
32
|
+
until: string | null;
|
|
33
|
+
};
|
|
34
|
+
/** 目前使用者的封禁已解除 */
|
|
35
|
+
unbanned: void;
|
|
36
|
+
/** SDK 內部錯誤,`code` 為錯誤代碼 */
|
|
37
|
+
error: {
|
|
38
|
+
code: ClientErrorCode;
|
|
39
|
+
message: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
declare interface ConnectionApi {
|
|
44
|
+
connect(): Promise<void>;
|
|
45
|
+
disconnect(reason?: DisconnectReason): void;
|
|
46
|
+
joinRoom(roomId: string): Promise<WsRequestMap['join_room']['res'] & {
|
|
47
|
+
seq: number;
|
|
48
|
+
}>;
|
|
49
|
+
leaveRoom(roomId: string): Promise<void>;
|
|
50
|
+
sendMessage(roomId: string, payload: SendMessagePayload): Promise<void>;
|
|
51
|
+
getMessages(roomId: string, options?: GetMessagesOptions): Promise<MessagesResult>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** WebSocket 連線狀態 */
|
|
55
|
+
export declare type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
|
|
56
|
+
|
|
57
|
+
/** 連線斷開原因 */
|
|
58
|
+
export declare type DisconnectReason = 'room_unavailable' | 'connection_replaced' | 'ping_timeout' | 'connected_timeout' | 'room_joined_timeout' | 'token_refresh_failed' | 'fetch_ticket_failed' | 'reconnect_failed' | 'connection_failed' | 'user_banned' | (string & {});
|
|
59
|
+
|
|
60
|
+
/** 型別安全的事件發送器,`MeowMeowClient` 與 `Room` 皆繼承此類別。 */
|
|
61
|
+
declare class EventEmitter<TEventMap extends object = Record<string, unknown>> {
|
|
62
|
+
private _listeners;
|
|
63
|
+
/**
|
|
64
|
+
* 註冊事件監聽器。
|
|
65
|
+
* @param event 事件名稱
|
|
66
|
+
* @param handler 事件處理函式
|
|
67
|
+
*/
|
|
68
|
+
on<E extends keyof TEventMap>(event: E, handler: (payload: TEventMap[E]) => void): void;
|
|
69
|
+
/**
|
|
70
|
+
* 移除已註冊的事件監聽器。
|
|
71
|
+
* @param event 事件名稱
|
|
72
|
+
* @param handler 要移除的處理函式(需與 `on` 傳入的參考相同)
|
|
73
|
+
*/
|
|
74
|
+
off<E extends keyof TEventMap>(event: E, handler: (payload: TEventMap[E]) => void): void;
|
|
75
|
+
protected emit<E extends keyof TEventMap>(event: E, ...args: TEventMap[E] extends void ? [] : [payload: TEventMap[E]]): void;
|
|
76
|
+
/** 移除所有事件的所有監聽器。 */
|
|
77
|
+
removeAllListeners(): void;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** 取得歷史訊息的查詢選項 */
|
|
81
|
+
declare interface GetMessagesOptions {
|
|
82
|
+
/** 單次最多取幾筆 */
|
|
83
|
+
limit: number;
|
|
84
|
+
/** 取在此訊息 ID 之前的訊息(用於分頁) */
|
|
85
|
+
before?: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
declare type JoinFailReason = 'skipped' | 'timeout' | 'disconnected' | 'disposed' | 'room_unavailable' | WsErrorCode;
|
|
89
|
+
|
|
90
|
+
declare type JoinResult = {
|
|
91
|
+
ok: true;
|
|
92
|
+
room: Room;
|
|
93
|
+
} | {
|
|
94
|
+
ok: false;
|
|
95
|
+
reason: JoinFailReason;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
declare type LeaveFailReason = 'skipped' | 'disconnected' | 'disposed' | WsErrorCode;
|
|
99
|
+
|
|
100
|
+
declare type LeaveResult = {
|
|
101
|
+
ok: true;
|
|
102
|
+
} | {
|
|
103
|
+
ok: false;
|
|
104
|
+
reason: LeaveFailReason;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* MeowMeow 聊天室 UI Widget。
|
|
109
|
+
* 掛載後在頁面上顯示完整的聊天室介面(預覽泡泡 + 聊天室視窗)。
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* const chat = new MeowMeow({ token: '...', room: 'room-1', locale: 'zh' })
|
|
114
|
+
* await chat.mount()
|
|
115
|
+
* chat.show()
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
export declare class MeowMeow extends EventEmitter {
|
|
119
|
+
private readonly options;
|
|
120
|
+
private vueApp;
|
|
121
|
+
private hostElement;
|
|
122
|
+
private meowmeowStore;
|
|
123
|
+
private uiStore;
|
|
124
|
+
constructor(options: MeowMeowOptions);
|
|
125
|
+
/** 顯示 MeowMeow */
|
|
126
|
+
show(): void;
|
|
127
|
+
/** 加入聊天室 */
|
|
128
|
+
join(roomId: string): Promise<void>;
|
|
129
|
+
/** 隱藏 MeowMeow */
|
|
130
|
+
hide(): void;
|
|
131
|
+
/**
|
|
132
|
+
* 動態設定語系
|
|
133
|
+
* @param locale en-US 英語 ( 預設 )
|
|
134
|
+
* @param locale zh-Hant 繁體中文
|
|
135
|
+
* @param locale zh-Hans 簡體中文
|
|
136
|
+
* @param locale vi-VN 越南語
|
|
137
|
+
* @param locale th-TH 泰語
|
|
138
|
+
* @param locale id-ID 印尼語
|
|
139
|
+
* @param locale pt-BR 葡萄牙語 ( 巴西 )
|
|
140
|
+
* @param locale my-MM 緬甸語
|
|
141
|
+
* @param locale hi-IN 印地語
|
|
142
|
+
* @param locale ru-RU 俄語
|
|
143
|
+
* @param locale ko-KR 韓國語
|
|
144
|
+
* @param locale ms-MY 馬來語
|
|
145
|
+
* @param locale fil-PH 菲律賓語
|
|
146
|
+
*/
|
|
147
|
+
setLocale(locale?: string): void;
|
|
148
|
+
/**
|
|
149
|
+
* 動態設定主題
|
|
150
|
+
* @param theme p1 ( 預設 )
|
|
151
|
+
* @param theme p2
|
|
152
|
+
*/
|
|
153
|
+
setTheme(theme?: Theme): void;
|
|
154
|
+
/**
|
|
155
|
+
* 建立 Shadow DOM、初始化 Vue 應用並掛載到 `document.body`。
|
|
156
|
+
* 掛載後聊天室預設為隱藏,需呼叫 {@link show} 顯示。
|
|
157
|
+
*/
|
|
158
|
+
mount(): Promise<void>;
|
|
159
|
+
/** 卸載 Vue 應用、移除 DOM 元素並釋放所有資源。 */
|
|
160
|
+
unmount(): void;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* MeowMeow SDK 的核心 Client,負責管理 WebSocket 連線與聊天室生命週期。
|
|
165
|
+
*
|
|
166
|
+
* @remarks
|
|
167
|
+
* 可透過 `on(event, handler)` 監聽以下事件:
|
|
168
|
+
*
|
|
169
|
+
* | 事件 | Payload | 說明 |
|
|
170
|
+
* |------|---------|------|
|
|
171
|
+
* | `connected` | `{ user }` | 連線建立並通過身份驗證 |
|
|
172
|
+
* | `disconnected` | `{ reason, willReconnect }` | 連線中斷 |
|
|
173
|
+
* | `reconnecting` | `{ attempt }` | 正在嘗試重連 |
|
|
174
|
+
* | `reconnected` | — | 重連成功 |
|
|
175
|
+
* | `banned` | `{ until }` | 被封禁 |
|
|
176
|
+
* | `unbanned` | — | 封禁解除 |
|
|
177
|
+
* | `error` | `{ code, message }` | SDK 內部錯誤 |
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```ts
|
|
181
|
+
* const client = new MeowMeowClient({ token: '...' })
|
|
182
|
+
* const result = await client.join('room-1')
|
|
183
|
+
* if (result.ok) result.room.on('message', msg => console.log(msg))
|
|
184
|
+
* client.on('disconnected', ({ reason }) => console.warn('disconnected:', reason))
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
export declare class MeowMeowClient extends EventEmitter<ClientEventMap> {
|
|
188
|
+
private readonly connectionApi;
|
|
189
|
+
private _currentRoomId;
|
|
190
|
+
private currentRoom;
|
|
191
|
+
private _pendingJoinSettle;
|
|
192
|
+
private _pendingJoinTimer;
|
|
193
|
+
private _preJoinBuffer;
|
|
194
|
+
private _pendingLeaveSettle;
|
|
195
|
+
private _nextOp;
|
|
196
|
+
private _connectionStatus;
|
|
197
|
+
private _currentUser;
|
|
198
|
+
private _isMuted;
|
|
199
|
+
private _mutedUntil;
|
|
200
|
+
private _isBanned;
|
|
201
|
+
private _retryAfterSeconds;
|
|
202
|
+
private readonly _userStateFilter;
|
|
203
|
+
/** 目前的連線狀態 */
|
|
204
|
+
get connectionStatus(): ConnectionStatus;
|
|
205
|
+
/** 目前登入的使用者,連線前為 null */
|
|
206
|
+
get currentUser(): User | null;
|
|
207
|
+
/** 目前使用者是否被禁言 */
|
|
208
|
+
get isMuted(): boolean;
|
|
209
|
+
/** 禁言到期時間(ISO 8601),未被禁言時為 null */
|
|
210
|
+
get mutedUntil(): string | null;
|
|
211
|
+
/** 目前使用者是否被封禁 */
|
|
212
|
+
get isBanned(): boolean;
|
|
213
|
+
/** 發送過於頻繁時需等待的秒數(0 表示無需等待) */
|
|
214
|
+
get retryAfterSeconds(): number;
|
|
215
|
+
/** 目前所在的聊天室 ID,未入桌時為 null */
|
|
216
|
+
get currentRoomId(): string | null;
|
|
217
|
+
constructor(options: MeowMeowClientOptions);
|
|
218
|
+
/**
|
|
219
|
+
* 建立連線並加入聊天室,回傳 {@link JoinResult},不拋出例外。
|
|
220
|
+
*
|
|
221
|
+
* 狀態機行為:
|
|
222
|
+
* - joining / leaving → 排隊(最後一次生效),被覆蓋的 `{ ok: false, reason: 'skipped' }`
|
|
223
|
+
* - room 同桌 → 立即 `{ ok: true, room }`
|
|
224
|
+
* - room 不同桌 / lobby → 直接開始 join(server 支援 switch)
|
|
225
|
+
*/
|
|
226
|
+
join(roomId: string): Promise<JoinResult>;
|
|
227
|
+
/**
|
|
228
|
+
* 離開聊天室(ws 連線保留),回傳 {@link LeaveResult},不拋出例外。
|
|
229
|
+
*
|
|
230
|
+
* 狀態機行為:
|
|
231
|
+
* - joining / leaving → 排隊(最後一次生效),被覆蓋的 `{ ok: false, reason: 'skipped' }`
|
|
232
|
+
* - lobby → 立即 `{ ok: true }`
|
|
233
|
+
* - room → 開始 leave
|
|
234
|
+
*/
|
|
235
|
+
leaveRoom(): Promise<LeaveResult>;
|
|
236
|
+
private disconnect;
|
|
237
|
+
/** 斷開連線並移除所有事件監聽器,釋放資源。頁面卸載時應呼叫此方法。 */
|
|
238
|
+
dispose(): void;
|
|
239
|
+
/* Excluded from this release type: onConnected */
|
|
240
|
+
/* Excluded from this release type: onDisconnected */
|
|
241
|
+
/* Excluded from this release type: onReconnecting */
|
|
242
|
+
/* Excluded from this release type: onReconnected */
|
|
243
|
+
private onRoomJoined;
|
|
244
|
+
/* Excluded from this release type: onRoomUpdated */
|
|
245
|
+
/* Excluded from this release type: onRoomUnavailable */
|
|
246
|
+
/* Excluded from this release type: onMessage */
|
|
247
|
+
/* Excluded from this release type: onPresence */
|
|
248
|
+
/* Excluded from this release type: onMuted */
|
|
249
|
+
/* Excluded from this release type: onUnmuted */
|
|
250
|
+
/* Excluded from this release type: onBanned */
|
|
251
|
+
/* Excluded from this release type: onUnbanned */
|
|
252
|
+
/* Excluded from this release type: onWarned */
|
|
253
|
+
/* Excluded from this release type: onError */
|
|
254
|
+
private _startJoin;
|
|
255
|
+
private _startLeave;
|
|
256
|
+
private _doLeaveRoom;
|
|
257
|
+
private _queueJoin;
|
|
258
|
+
private _queueLeave;
|
|
259
|
+
private _runNextOp;
|
|
260
|
+
private _doJoinRoom;
|
|
261
|
+
private _toJoinFailReason;
|
|
262
|
+
private _toLeaveFailReason;
|
|
263
|
+
private _settleAll;
|
|
264
|
+
private _startJoinTimer;
|
|
265
|
+
private _clearPendingJoin;
|
|
266
|
+
private _clearPendingLeave;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/** MeowMeowClient 建構所需的設定選項 */
|
|
270
|
+
export declare interface MeowMeowClientOptions {
|
|
271
|
+
/** 用於驗證身份的 JWT token */
|
|
272
|
+
token: string;
|
|
273
|
+
/**
|
|
274
|
+
* Token 過期時的刷新回調,應回傳新的有效 token。
|
|
275
|
+
* 若未提供,token 過期後連線將直接斷開。
|
|
276
|
+
*/
|
|
277
|
+
onTokenRefresh?: () => Promise<string>;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export declare interface MeowMeowOptions {
|
|
281
|
+
token: string;
|
|
282
|
+
locale?: string;
|
|
283
|
+
theme?: Theme;
|
|
284
|
+
title?: string | Record<string, string>;
|
|
285
|
+
onTokenRefresh?: () => Promise<string>;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/** 聊天室訊息 */
|
|
289
|
+
export declare type Message = (MessageBase & {
|
|
290
|
+
type: 'text' | 'system';
|
|
291
|
+
content: string;
|
|
292
|
+
}) | (MessageBase & {
|
|
293
|
+
type: 'sticker';
|
|
294
|
+
content: {
|
|
295
|
+
packId: string;
|
|
296
|
+
stickerId: string;
|
|
297
|
+
url: string;
|
|
298
|
+
};
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
declare type MessageBase = {
|
|
302
|
+
/** 訊息唯一識別碼 */
|
|
303
|
+
id: string;
|
|
304
|
+
/** 訊息的序號(用於排序) */
|
|
305
|
+
seq: number;
|
|
306
|
+
/** 同一 seq 下的子序號 */
|
|
307
|
+
subSeq: number;
|
|
308
|
+
/** 發送者的使用者 ID */
|
|
309
|
+
userId: string;
|
|
310
|
+
/** 發送者的顯示名稱 */
|
|
311
|
+
userName: string;
|
|
312
|
+
/** 發送者的頭像 URL,無頭像時為 null */
|
|
313
|
+
avatar: string | null;
|
|
314
|
+
/** 訊息建立時間(ISO 8601 格式) */
|
|
315
|
+
createdAt: string;
|
|
316
|
+
/** 傳送失敗時的錯誤代碼 */
|
|
317
|
+
errorCode?: WsErrorCode;
|
|
318
|
+
/** 客戶端本地參考 ID,用於對應樂觀更新 */
|
|
319
|
+
clientRef?: string | null;
|
|
320
|
+
/** 是否為尚未確認的樂觀更新訊息 */
|
|
321
|
+
pending?: boolean;
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
declare type MessageSender = {
|
|
325
|
+
id: string;
|
|
326
|
+
name: string;
|
|
327
|
+
avatar?: string | null;
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
/** `getMessages` / `loadMoreMessages` 的回傳結果 */
|
|
331
|
+
declare interface MessagesResult {
|
|
332
|
+
/** 取得的訊息列表(依序號排序) */
|
|
333
|
+
messages: Message[];
|
|
334
|
+
/** 是否還有更早的訊息可以載入 */
|
|
335
|
+
hasMore: boolean;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/** server push event → handler 收到的完整資料型別對應表(outer envelope 欄位已攤平) */
|
|
339
|
+
declare interface PushEventMap {
|
|
340
|
+
connected: {
|
|
341
|
+
seq: number;
|
|
342
|
+
user: User & {
|
|
343
|
+
status: 'normal' | 'muted' | 'banned';
|
|
344
|
+
};
|
|
345
|
+
};
|
|
346
|
+
room_updated: {
|
|
347
|
+
seq: number;
|
|
348
|
+
roomId: string;
|
|
349
|
+
cooldownSeconds: number;
|
|
350
|
+
};
|
|
351
|
+
presence: {
|
|
352
|
+
seq: number;
|
|
353
|
+
roomId: string;
|
|
354
|
+
type: 'join' | 'leave';
|
|
355
|
+
user: User;
|
|
356
|
+
onlineCount: number;
|
|
357
|
+
};
|
|
358
|
+
muted: {
|
|
359
|
+
seq: number;
|
|
360
|
+
roomId?: string;
|
|
361
|
+
until: string | null;
|
|
362
|
+
};
|
|
363
|
+
unmuted: {
|
|
364
|
+
seq: number;
|
|
365
|
+
roomId?: string;
|
|
366
|
+
};
|
|
367
|
+
banned: {
|
|
368
|
+
seq: number;
|
|
369
|
+
roomId?: string;
|
|
370
|
+
until: string | null;
|
|
371
|
+
};
|
|
372
|
+
unbanned: {
|
|
373
|
+
seq: number;
|
|
374
|
+
roomId?: string;
|
|
375
|
+
};
|
|
376
|
+
warned: {
|
|
377
|
+
seq: number;
|
|
378
|
+
roomId: string;
|
|
379
|
+
reason?: string;
|
|
380
|
+
};
|
|
381
|
+
room_unavailable: {
|
|
382
|
+
seq: number;
|
|
383
|
+
roomId: string;
|
|
384
|
+
};
|
|
385
|
+
connection_replaced: {
|
|
386
|
+
seq: number;
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
declare type RawMessagePayload = {
|
|
391
|
+
id: string;
|
|
392
|
+
type: 'text' | 'system';
|
|
393
|
+
sender: MessageSender;
|
|
394
|
+
body: {
|
|
395
|
+
content: string;
|
|
396
|
+
};
|
|
397
|
+
createdAt: string;
|
|
398
|
+
clientRef?: string | null;
|
|
399
|
+
} | {
|
|
400
|
+
id: string;
|
|
401
|
+
type: 'sticker';
|
|
402
|
+
sender: MessageSender;
|
|
403
|
+
body: {
|
|
404
|
+
packId: string;
|
|
405
|
+
stickerId: string;
|
|
406
|
+
url: string;
|
|
407
|
+
};
|
|
408
|
+
createdAt: string;
|
|
409
|
+
clientRef?: string | null;
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* 代表一個已加入的聊天室,提供發送訊息、載入歷史紀錄與監聽即時事件的能力。
|
|
414
|
+
* 由 {@link MeowMeowClient.join} 回傳,不應自行建構。
|
|
415
|
+
*
|
|
416
|
+
* @remarks
|
|
417
|
+
* 可透過 `on(event, handler)` 監聽以下事件:
|
|
418
|
+
*
|
|
419
|
+
* | 事件 | Payload | 說明 |
|
|
420
|
+
* |------|---------|------|
|
|
421
|
+
* | `message` | {@link Message} | 收到新訊息(含 pending 樂觀更新) |
|
|
422
|
+
* | `presence` | `{ type, user, onlineCount }` | 使用者加入或離開 |
|
|
423
|
+
* | `muted` | `{ until }` | 被禁言 |
|
|
424
|
+
* | `unmuted` | — | 禁言解除 |
|
|
425
|
+
* | `room_updated` | `{ cooldownSeconds }` | 聊天室設定更新 |
|
|
426
|
+
*/
|
|
427
|
+
export declare class Room extends EventEmitter<RoomEventMap> {
|
|
428
|
+
/** 聊天室唯一識別碼 */
|
|
429
|
+
readonly id: string;
|
|
430
|
+
/** 聊天室顯示名稱 */
|
|
431
|
+
readonly name: string;
|
|
432
|
+
private readonly connectionApi;
|
|
433
|
+
private readonly client;
|
|
434
|
+
private _cooldownSeconds;
|
|
435
|
+
private _greetingMessage;
|
|
436
|
+
private _stickerPacks;
|
|
437
|
+
private _messages;
|
|
438
|
+
private _hasMore;
|
|
439
|
+
private _isDisposed;
|
|
440
|
+
/** 發送訊息冷卻秒數(0 表示無限制) */
|
|
441
|
+
get cooldownSeconds(): number;
|
|
442
|
+
/** 加入房間時的歡迎訊息,無則為 null */
|
|
443
|
+
get greetingMessage(): string | null;
|
|
444
|
+
/** 此聊天室可用的貼圖包列表 */
|
|
445
|
+
get stickerPacks(): StickerPack[];
|
|
446
|
+
/** 目前已載入的訊息列表(依序號排序) */
|
|
447
|
+
get messages(): Message[];
|
|
448
|
+
/** 是否還有更早的歷史訊息可以載入 */
|
|
449
|
+
get hasMore(): boolean;
|
|
450
|
+
/** 此 Room 是否已失效(換房間或斷線後) */
|
|
451
|
+
get isDisposed(): boolean;
|
|
452
|
+
/* Excluded from this release type: __constructor */
|
|
453
|
+
/**
|
|
454
|
+
* 發送文字訊息。採樂觀更新,訊息會立即出現在 `messages` 並觸發 `message` 事件;
|
|
455
|
+
* 若伺服器回傳錯誤,該訊息的 `errorCode` 會被設定且 `pending` 設為 false。
|
|
456
|
+
* @param content 訊息文字內容
|
|
457
|
+
* @param sender 發送者資訊
|
|
458
|
+
*/
|
|
459
|
+
send(content: string): Promise<void>;
|
|
460
|
+
/**
|
|
461
|
+
* 發送貼圖訊息,行為同 {@link send}(樂觀更新)。
|
|
462
|
+
* @param options 貼圖包 ID 與貼圖代碼
|
|
463
|
+
* @param sender 發送者資訊
|
|
464
|
+
*/
|
|
465
|
+
sendSticker(options: {
|
|
466
|
+
packId: string;
|
|
467
|
+
stickerId: string;
|
|
468
|
+
}): Promise<void>;
|
|
469
|
+
/* Excluded from this release type: dispose */
|
|
470
|
+
/* Excluded from this release type: _setCooldownSeconds */
|
|
471
|
+
/* Excluded from this release type: _setGreetingMessage */
|
|
472
|
+
/* Excluded from this release type: _setStickerPacks */
|
|
473
|
+
/* Excluded from this release type: _initMessages */
|
|
474
|
+
/* Excluded from this release type: _handleMessage */
|
|
475
|
+
/* Excluded from this release type: _handleRoomUpdated */
|
|
476
|
+
/* Excluded from this release type: _handlePresence */
|
|
477
|
+
/* Excluded from this release type: _handleWarned */
|
|
478
|
+
/* Excluded from this release type: reload */
|
|
479
|
+
/* Excluded from this release type: reset */
|
|
480
|
+
private _createPendingMessage;
|
|
481
|
+
private _markFailed;
|
|
482
|
+
private _insertMessage;
|
|
483
|
+
private _mergeSorted;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/** `Room` 可監聽的事件與其 payload 型別對應表 */
|
|
487
|
+
export declare interface RoomEventMap {
|
|
488
|
+
/** 收到新訊息(含樂觀更新的 pending 訊息與伺服器確認後的最終訊息) */
|
|
489
|
+
message: Message;
|
|
490
|
+
/** 使用者加入或離開聊天室 */
|
|
491
|
+
presence: {
|
|
492
|
+
type: 'join' | 'leave';
|
|
493
|
+
user: User;
|
|
494
|
+
onlineCount: number;
|
|
495
|
+
};
|
|
496
|
+
/** 聊天室設定更新(目前僅有冷卻秒數) */
|
|
497
|
+
room_updated: {
|
|
498
|
+
cooldownSeconds: number;
|
|
499
|
+
};
|
|
500
|
+
/** 訊息重新載入完成(初次加入或重連後) */
|
|
501
|
+
messages_reloaded: void;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
declare type SendMessagePayload = {
|
|
505
|
+
type: 'text';
|
|
506
|
+
body: {
|
|
507
|
+
content: string;
|
|
508
|
+
};
|
|
509
|
+
clientRef: string;
|
|
510
|
+
} | {
|
|
511
|
+
type: 'sticker';
|
|
512
|
+
body: {
|
|
513
|
+
packId: string;
|
|
514
|
+
stickerId: string;
|
|
515
|
+
};
|
|
516
|
+
clientRef: string;
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
/** 貼圖包資訊 */
|
|
520
|
+
export declare interface StickerPack {
|
|
521
|
+
/** 貼圖包唯一識別碼 */
|
|
522
|
+
id: string;
|
|
523
|
+
/** 貼圖包圖示 URL */
|
|
524
|
+
iconUrl: string;
|
|
525
|
+
/** 貼圖包名稱 */
|
|
526
|
+
name: string;
|
|
527
|
+
/** 包含的貼圖列表 */
|
|
528
|
+
stickers: Array<{
|
|
529
|
+
id: string;
|
|
530
|
+
url: string;
|
|
531
|
+
}>;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
declare type Theme = typeof THEMES[number];
|
|
535
|
+
|
|
536
|
+
declare const THEMES: readonly ["p1", "p2"];
|
|
537
|
+
|
|
538
|
+
/** 使用者資訊 */
|
|
539
|
+
export declare interface User {
|
|
540
|
+
/** 使用者唯一識別碼 */
|
|
541
|
+
id: string;
|
|
542
|
+
/** 使用者顯示名稱 */
|
|
543
|
+
name: string;
|
|
544
|
+
/** 頭像 URL,無頭像時為 null */
|
|
545
|
+
avatar: string | null;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
export declare type WsErrorCode = 'BAD_REQUEST' | 'TOKEN_INVALID' | 'FORBIDDEN' | 'USER_MUTED' | 'USER_BANNED' | 'ROOM_NOT_FOUND' | 'CHAT_MESSAGE_STORE_UNAVAILABLE' | 'CHAT_MESSAGE_BLOCKED' | 'INTERNAL_SERVER_ERROR' | 'INVALID_TYPE' | 'INVALID_MESSAGE_TYPE' | 'MISSING_REF' | 'STICKER_NOT_AVAILABLE';
|
|
549
|
+
|
|
550
|
+
/** Client → Server request/response 型別對應表 */
|
|
551
|
+
declare interface WsRequestMap {
|
|
552
|
+
ping: {
|
|
553
|
+
req: {
|
|
554
|
+
type: 'request';
|
|
555
|
+
action: 'ping';
|
|
556
|
+
};
|
|
557
|
+
res: undefined;
|
|
558
|
+
};
|
|
559
|
+
join_room: {
|
|
560
|
+
req: {
|
|
561
|
+
type: 'request';
|
|
562
|
+
action: 'join_room';
|
|
563
|
+
roomId: string;
|
|
564
|
+
};
|
|
565
|
+
res: {
|
|
566
|
+
seq: number;
|
|
567
|
+
onlineCount: number;
|
|
568
|
+
latestMessageId: string;
|
|
569
|
+
greetingMessage?: string;
|
|
570
|
+
cooldownSeconds: number;
|
|
571
|
+
retryAfterSeconds: number;
|
|
572
|
+
stickerPacks: StickerPack[];
|
|
573
|
+
};
|
|
574
|
+
};
|
|
575
|
+
leave_room: {
|
|
576
|
+
req: {
|
|
577
|
+
type: 'request';
|
|
578
|
+
action: 'leave_room';
|
|
579
|
+
roomId: string;
|
|
580
|
+
};
|
|
581
|
+
res: {
|
|
582
|
+
left: boolean;
|
|
583
|
+
roomId: string;
|
|
584
|
+
};
|
|
585
|
+
};
|
|
586
|
+
get_messages: {
|
|
587
|
+
req: {
|
|
588
|
+
type: 'request';
|
|
589
|
+
action: 'get_messages';
|
|
590
|
+
roomId: string;
|
|
591
|
+
payload: {
|
|
592
|
+
limit: number;
|
|
593
|
+
before?: string;
|
|
594
|
+
};
|
|
595
|
+
};
|
|
596
|
+
res: {
|
|
597
|
+
messages: RawMessagePayload[];
|
|
598
|
+
hasMore: boolean;
|
|
599
|
+
};
|
|
600
|
+
};
|
|
601
|
+
send_message: {
|
|
602
|
+
req: {
|
|
603
|
+
type: 'request';
|
|
604
|
+
action: 'send_message';
|
|
605
|
+
roomId: string;
|
|
606
|
+
payload: SendMessagePayload;
|
|
607
|
+
};
|
|
608
|
+
res: undefined;
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
export { }
|