message-nexus 1.0.0 → 1.1.0

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/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # message-nexus
2
2
 
3
- 一个统一、类型安全、支持多种传输协议的跨上下文消息通信库。
3
+ A unified, type-safe cross-context message communication library supporting multiple transport protocols.
4
4
 
5
- ## 安装
5
+ ## Installation
6
6
 
7
7
  ```bash
8
8
  npm install message-nexus
@@ -10,170 +10,198 @@ npm install message-nexus
10
10
  pnpm add message-nexus
11
11
  ```
12
12
 
13
- ## 特性
13
+ ## Features
14
14
 
15
- - **统一接口**: 支持 Mitt(进程内)、PostMessageiframe/window 间)、BroadcastChannel(跨标签页)、WebSocket(网络通信)
16
- - **类型安全**: 完整的 TypeScript 支持,泛型类型推断
17
- - **请求-响应模式**: Promise 风格的异步通信,内置超时保护
18
- - **自动重连**: WebSocket 自动重连机制,支持指数退避
19
- - **消息队列**: 离线消息缓存,连接恢复后自动发送
20
- - **重试机制**: 请求失败自动重试,可配置重试次数和延迟
21
- - **消息验证**: 运行时消息格式验证,防止非法消息
22
- - **监控指标**: 内置消息统计和性能监控
23
- - **结构化日志**: 支持自定义日志处理器,便于调试和生产监控
24
- - **资源管理**: 所有 Driver 支持 `destroy()` 方法,正确清理资源
15
+ - **Unified Interface**: Supports Mitt (in-process), PostMessage (iframe/window), BroadcastChannel (cross-tab), and WebSocket (network communication)
16
+ - **JSON-RPC 2.0 Compliance**: Strict adherence to the JSON-RPC 2.0 specification for standardized communication
17
+ - **Envelope Pattern**: Extensible message envelope containing routing information (from, to) and metadata
18
+ - **Type Safety**: Full TypeScript support with generic type inference
19
+ - **Request-Response Pattern**: Promise-style asynchronous communication with built-in timeout protection
20
+ - **Auto Reconnect**: WebSocket automatic reconnection mechanism with exponential backoff support
21
+ - **Message Queue**: Offline message caching, automatically sent after connection recovery
22
+ - **Retry Mechanism**: Automatic retry on request failure, configurable retry counts and delays
23
+ - **Message Validation**: Runtime message format validation to prevent illegal messages
24
+ - **Monitoring Metrics**: Built-in message statistics and performance monitoring
25
+ - **Structured Logging**: Supports custom log handlers for easy debugging and production monitoring
26
+ - **Resource Management**: All drivers support the `destroy()` method to properly clean up resources.
25
27
 
26
- ## 快速开始
28
+ ## Quick Start
27
29
 
28
- ### 1. 进程内通信(Mitt
30
+ ### 1. In-Process Communication (Mitt)
29
31
 
30
32
  ```typescript
31
- import mitt from 'mitt'
32
- import { MittDriver, MessageBridge } from 'message-nexus'
33
+ import MessageNexus, { MittDriver, createEmitter } from 'message-nexus'
34
+
35
+ // Shared emitter
36
+ const emitter = createEmitter()
33
37
 
34
- const emitter = mitt()
35
38
  const driver = new MittDriver(emitter)
36
- const bridge = new MessageBridge(driver)
39
+ const nexus = new MessageNexus(driver)
37
40
 
38
- // 发送请求
39
- const response = await bridge.request('GET_DATA', { id: 123 })
41
+ // Send request
42
+ const response = await nexus.invoke('GET_DATA', { id: 123 })
40
43
  console.log(response)
41
44
 
42
- // 监听命令
43
- const unsubscribe = bridge.onCommand((data) => {
44
- if (data.type === 'GET_DATA') {
45
- bridge.reply(data.id, { name: 'test', value: 42 })
46
- }
45
+ // Send one-way notification
46
+ nexus.notify('UPDATE_STATUS', { status: 'active' })
47
+
48
+ // Listen for commands
49
+ const receiverDriver = new MittDriver(emitter)
50
+ const receiverNexus = new MessageNexus(receiverDriver)
51
+ const unsubscribe = receiverNexus.handle('GET_DATA', (params, context) => {
52
+ return { name: 'test', value: 42 }
53
+ })
54
+
55
+ // Listen for notifications
56
+ const unsubscribeNotify = receiverNexus.onNotification('UPDATE_STATUS', (params, context) => {
57
+ console.log('Notification received:', params)
47
58
  })
48
59
  ```
49
60
 
50
- ### 2. iframe/Window 通信(PostMessage
61
+ ### 2. iframe/Window Communication (PostMessage)
51
62
 
52
63
  ```typescript
53
- import { PostMessageDriver, MessageBridge } from 'message-nexus'
64
+ import MessageNexus, { PostMessageDriver } from 'message-nexus'
54
65
 
55
- // 发送方
66
+ // Sender
56
67
  const driver = new PostMessageDriver(window.parent, 'https://example.com')
57
- const bridge = new MessageBridge(driver)
68
+ const nexus = new MessageNexus(driver)
58
69
 
59
- const response = await bridge.request('PING')
70
+ const response = await nexus.invoke('PING')
60
71
  console.log('Pong:', response)
61
72
 
62
- // 接收方
73
+ // Receiver
63
74
  const iframeDriver = new PostMessageDriver(iframe.contentWindow, 'https://example.com')
64
- const iframeBridge = new MessageBridge(iframeDriver)
75
+ const iframeNexus = new MessageNexus(iframeDriver)
65
76
 
66
- iframeBridge.onCommand((data) => {
67
- if (data.type === 'PING') {
68
- bridge.reply(data.id, { time: Date.now() })
69
- }
77
+ iframeNexus.handle('PING', (params, context) => {
78
+ return { time: Date.now() }
70
79
  })
71
80
  ```
72
81
 
73
- ### 3. 跨标签页通信(BroadcastChannel
82
+ ### 3. Cross-Tab Communication (BroadcastChannel)
74
83
 
75
84
  ```typescript
76
- import { BroadcastDriver, MessageBridge } from 'message-nexus'
85
+ import MessageNexus, { BroadcastDriver } from 'message-nexus'
77
86
 
78
- // 创建 BroadcastDriver,指定频道名称
87
+ // Create BroadcastDriver, specifying the channel name
79
88
  const driver = new BroadcastDriver({ channel: 'my-app-channel' })
80
- const bridge = new MessageBridge(driver)
89
+ const nexus = new MessageNexus(driver)
81
90
 
82
- // 监听命令
83
- bridge.onCommand((data) => {
84
- console.log('Received:', data.type, data.payload)
85
- bridge.reply(data.id, { result: 'success' })
91
+ // Listen for commands
92
+ nexus.handle('SYNC_STATE', (params, context) => {
93
+ console.log('Received:', params)
94
+ return { result: 'success' }
86
95
  })
87
96
 
88
- // 发送请求(会在所有同频道的标签页中广播)
89
- const response = await bridge.request({
90
- type: 'SYNC_STATE',
91
- payload: { state: '...' },
97
+ // Send request (will be broadcast to all tabs on the same channel)
98
+ const response = await nexus.invoke({
99
+ method: 'SYNC_STATE',
100
+ params: { state: '...' },
92
101
  })
93
102
 
94
- // 清理资源
95
- bridge.destroy()
103
+ // Receiver
104
+ const receiverDriver = new BroadcastDriver({ channel: 'my-app-channel' })
105
+ const receiverNexus = new MessageNexus(receiverDriver)
106
+ receiverNexus.handle('SYNC_STATE', (params, context) => {
107
+ console.log('Received:', params)
108
+ return { result: 'success' }
109
+ })
96
110
  ```
97
111
 
98
- ### 4. WebSocket 通信
112
+ ### 4. WebSocket Communication
99
113
 
100
114
  ```typescript
101
- import { WebSocketDriver, MessageBridge } from 'message-nexus'
115
+ import MessageNexus, { WebSocketDriver } from 'message-nexus'
102
116
 
103
- // 自动重连配置
117
+ // Automatic reconnection configuration
104
118
  const driver = new WebSocketDriver({
105
119
  url: 'wss://api.example.com/ws',
106
120
  reconnect: {
107
- maxRetries: 5, // 最大重试次数
108
- retryInterval: 3000, // 重试间隔(毫秒)
121
+ maxRetries: 5, // Maximum retry count
122
+ retryInterval: 3000, // Retry interval (milliseconds)
109
123
  },
110
124
  })
111
125
 
112
- const bridge = new MessageBridge(driver)
126
+ const nexus = new MessageNexus(driver)
113
127
 
114
- // 发送请求
115
- const response = await bridge.request({
116
- type: 'GET_USER',
117
- payload: { userId: 123 },
128
+ // Send request
129
+ const response = await nexus.invoke({
130
+ method: 'GET_USER',
131
+ params: { userId: 123 },
118
132
  timeout: 5000,
119
- retryCount: 3, // 失败重试 3
120
- retryDelay: 1000, // 重试延迟
133
+ retryCount: 3, // Retry 3 times on failure
134
+ retryDelay: 1000, // Retry delay
135
+ })
136
+
137
+ // Receiver
138
+ const receiverDriver = new WebSocketDriver({
139
+ url: 'wss://api.example.com/ws',
140
+ reconnect: {
141
+ maxRetries: 5, // Maximum retry count
142
+ retryInterval: 3000, // Retry interval (milliseconds)
143
+ },
144
+ })
145
+ const receiverNexus = new MessageNexus(receiverDriver)
146
+ receiverNexus.handle('SYNC_STATE', (params, context) => {
147
+ console.log('Received:', params)
148
+ return { result: 'success' }
121
149
  })
122
150
  ```
123
151
 
124
- ## API 文档
152
+ ## API Documentation
125
153
 
126
- ### MessageBridge
154
+ ### MessageNexus
127
155
 
128
- #### 构造函数
156
+ #### Constructor
129
157
 
130
158
  ```typescript
131
- new MessageBridge<RequestPayload, ResponsePayload>(
159
+ new MessageNexus<RequestPayload, ResponsePayload>(
132
160
  driver: BaseDriver,
133
- options?: MessageBridgeOptions
161
+ options?: MessageNexusOptions
134
162
  )
135
163
  ```
136
164
 
137
165
  **Options:**
138
166
 
139
- | 参数 | 类型 | 默认值 | 说明 |
140
- | ---------- | ------ | -------------- | --------------------- |
141
- | instanceId | string | auto-generated | 实例 ID,用于消息路由 |
142
- | timeout | number | 10000 | 请求超时时间(毫秒) |
143
- | logger | Logger | new Logger() | 日志实例 |
167
+ | Parameter | Type | Default Value | Description |
168
+ | ---------- | ------ | -------------- | ------------------------------------- |
169
+ | instanceId | string | auto-generated | Instance ID, used for message routing |
170
+ | timeout | number | 10000 | Request timeout (milliseconds) |
171
+ | logger | Logger | new Logger() | Logger instance |
144
172
 
145
- #### 方法
173
+ #### Methods
146
174
 
147
- ##### request()
175
+ ##### invoke()
148
176
 
149
- 发送请求并等待响应。
177
+ Send request and wait for response.
150
178
 
151
179
  ```typescript
152
- bridge.request(typeOrOptions: string | RequestOptions): Promise<ResponsePayload>
180
+ nexus.invoke<T>(methodOrOptions: string | InvokeOptions): Promise<T>
153
181
  ```
154
182
 
155
183
  **Options:**
156
184
 
157
- | 参数 | 类型 | 必填 | 说明 |
158
- | ---------- | ----------------------- | ---- | -------------------- |
159
- | type | string | | 消息类型 |
160
- | payload | unknown | | 请求数据 |
161
- | to | string | | 目标实例 ID |
162
- | metadata | Record<string, unknown> | | 元数据 |
163
- | timeout | number | | 超时时间(覆盖全局) |
164
- | retryCount | number | | 失败重试次数 |
165
- | retryDelay | number | | 重试延迟(毫秒) |
185
+ | Parameter | Type | Required | Description |
186
+ | ---------- | ----------------------- | -------- | ---------------------------- |
187
+ | method | string | Yes | Message method |
188
+ | params | unknown | No | Request data |
189
+ | to | string | No | Target instance ID |
190
+ | metadata | Record<string, unknown> | No | Metadata |
191
+ | timeout | number | No | Timeout (overrides global) |
192
+ | retryCount | number | No | Number of retries on failure |
193
+ | retryDelay | number | No | Retry delay (milliseconds) |
166
194
 
167
- **示例:**
195
+ **Example:**
168
196
 
169
197
  ```typescript
170
- // 简单请求
171
- const result = await bridge.request('FETCH_DATA')
198
+ // Simple request
199
+ const result = await nexus.invoke('FETCH_DATA')
172
200
 
173
- // 完整配置
174
- const result = await bridge.request({
175
- type: 'FETCH_DATA',
176
- payload: { id: 123 },
201
+ // Full configuration
202
+ const result = await nexus.invoke({
203
+ method: 'FETCH_DATA',
204
+ params: { id: 123 },
177
205
  to: 'target-instance',
178
206
  timeout: 5000,
179
207
  retryCount: 3,
@@ -181,90 +209,134 @@ const result = await bridge.request({
181
209
  })
182
210
  ```
183
211
 
184
- ##### onCommand()
212
+ ##### notify()
213
+
214
+ Send a one-way notification (Fire-and-Forget). Does not wait for a response and does not generate an ID. Complies with JSON-RPC 2.0 Notification specification.
215
+
216
+ ```typescript
217
+ nexus.notify(methodOrOptions: string | Omit<InvokeOptions, 'timeout' | 'retryCount' | 'retryDelay'>): void
218
+ ```
219
+
220
+ **Options:**
221
+
222
+ | Parameter | Type | Required | Description |
223
+ | --------- | ----------------------- | -------- | ------------------- |
224
+ | method | string | Yes | Notification method |
225
+ | params | unknown | No | Notification data |
226
+ | to | string | No | Target instance ID |
227
+ | metadata | Record<string, unknown> | No | Metadata |
185
228
 
186
- 注册消息处理器。
229
+ **Example:**
187
230
 
188
231
  ```typescript
189
- bridge.onCommand(handler: (data: CommandMessage) => void): () => void
232
+ // Simple notification
233
+ nexus.notify('HEARTBEAT')
234
+
235
+ // Full configuration
236
+ nexus.notify({
237
+ method: 'UPDATE_STATE',
238
+ params: { state: 'ready' },
239
+ to: 'target-instance',
240
+ })
190
241
  ```
191
242
 
192
- **返回值:** 取消监听的函数
243
+ ##### handle()
193
244
 
194
- **示例:**
245
+ Register a request handler for a specific method. The return value (or resolved value of a returned Promise) is automatically sent back as the response.
195
246
 
196
247
  ```typescript
197
- const unsubscribe = bridge.onCommand((data) => {
198
- console.log('Received:', data.type, data.payload)
248
+ nexus.handle<Params, Result>(method: string, handler: InvokeHandler<Params, Result>): () => void
249
+ ```
199
250
 
200
- if (data.type === 'ECHO') {
201
- bridge.reply(data.id, { echoed: data.payload })
202
- }
251
+ **Parameters:**
252
+
253
+ - `method`: The method name to handle.
254
+ - `handler`: A function that receives `(params, context)` and returns a result or a Promise.
255
+
256
+ **InvokeContext:**
257
+
258
+ | Property | Type | Description |
259
+ | ----------- | ------------------------- | ----------------------------------------------- |
260
+ | `messageId` | `string` | Unique identifier for the request (JSON-RPC ID) |
261
+ | `from` | `string` | Instance ID of the sender |
262
+ | `to` | `string` | Instance ID of the receiver (your instance ID) |
263
+ | `metadata` | `Record<string, unknown>` | Custom metadata sent with the envelope |
264
+
265
+ **Example:**
266
+
267
+ ```typescript
268
+ const unsubscribe = nexus.handle('ECHO', (params, context) => {
269
+ console.log(`Received ECHO from ${context.from}`)
270
+ return { echoed: params }
203
271
  })
204
272
 
205
- // 取消监听
273
+ // Unsubscribe
206
274
  unsubscribe()
207
275
  ```
208
276
 
209
- ##### reply()
277
+ ##### onNotification()
210
278
 
211
- 回复传入消息。
279
+ Register a handler for a specific notification method (one-way messages).
212
280
 
213
281
  ```typescript
214
- bridge.reply(messageId: string, payload: unknown, error?: unknown)
282
+ nexus.onNotification<Params>(method: string, handler: NotificationHandler<Params>): () => void
215
283
  ```
216
284
 
217
- **示例:**
285
+ **Example:**
218
286
 
219
287
  ```typescript
220
- bridge.reply('message-id-123', { success: true })
221
- bridge.reply('message-id-456', null, new Error('Invalid request'))
288
+ const unsubscribe = nexus.onNotification('HEARTBEAT', (params, context) => {
289
+ console.log(`Heartbeat from ${context.from}`)
290
+ })
291
+
292
+ // Unsubscribe
293
+ unsubscribe()
222
294
  ```
223
295
 
224
296
  ##### onError()
225
297
 
226
- 注册错误处理器。
298
+ Register error handler.
227
299
 
228
300
  ```typescript
229
- bridge.onError(handler: ErrorHandler): () => void
301
+ nexus.onError(handler: ErrorHandler): () => void
230
302
  ```
231
303
 
232
- **示例:**
304
+ **Example:**
233
305
 
234
306
  ```typescript
235
- bridge.onError((error, context) => {
307
+ nexus.onError((error, context) => {
236
308
  console.error('Bridge error:', error.message, context)
237
- // 发送到错误追踪服务
309
+ // Send to error tracking service
238
310
  Sentry.captureException(error, { extra: context })
239
311
  })
240
312
  ```
241
313
 
242
314
  ##### getMetrics()
243
315
 
244
- 获取监控指标。
316
+ Get monitoring metrics.
245
317
 
246
318
  ```typescript
247
- bridge.getMetrics(): Metrics
319
+ nexus.getMetrics(): Metrics
248
320
  ```
249
321
 
250
- **返回值:**
322
+ **Return Value:**
251
323
 
252
324
  ```typescript
253
325
  {
254
- messagesSent: number // 发送消息数
255
- messagesReceived: number // 接收消息数
256
- messagesFailed: number // 失败消息数
257
- pendingMessages: number // 待处理消息数
258
- queuedMessages: number // 队列消息数
259
- totalLatency: number // 总延迟(毫秒)
260
- averageLatency: number // 平均延迟(毫秒)
326
+ messagesSent: number // Messages sent
327
+ messagesReceived: number // Messages received
328
+ messagesFailed: number // Messages failed
329
+ pendingMessages: number // Pending messages
330
+ queuedMessages: number // Queued messages
331
+ totalLatency: number // Total latency (milliseconds)
332
+ averageLatency: number // Average latency (milliseconds)
261
333
  }
262
334
  ```
263
335
 
264
- **示例:**
336
+ **Example:**
265
337
 
266
338
  ```typescript
267
- const metrics = bridge.getMetrics()
339
+ const metrics = nexus.getMetrics()
268
340
  console.log(`Avg latency: ${metrics.averageLatency}ms`)
269
341
  console.log(
270
342
  `Success rate: ${((metrics.messagesReceived / metrics.messagesSent) * 100).toFixed(2)}%`,
@@ -273,42 +345,42 @@ console.log(
273
345
 
274
346
  ##### onMetrics()
275
347
 
276
- 注册指标变更回调。
348
+ Register metrics change callback.
277
349
 
278
350
  ```typescript
279
- bridge.onMetrics(callback: MetricsCallback): () => void
351
+ nexus.onMetrics(callback: MetricsCallback): () => void
280
352
  ```
281
353
 
282
- **示例:**
354
+ **Example:**
283
355
 
284
356
  ```typescript
285
- const unsubscribe = bridge.onMetrics((metrics) => {
286
- // 发送到监控系统
357
+ const unsubscribe = nexus.onMetrics((metrics) => {
358
+ // Send to monitoring system
287
359
  metricsService.report(metrics)
288
360
  })
289
361
  ```
290
362
 
291
363
  ##### flushQueue()
292
364
 
293
- 刷新消息队列,发送所有缓存的消息。
365
+ Flush the message queue, sending all cached messages.
294
366
 
295
367
  ```typescript
296
- bridge.flushQueue()
368
+ nexus.flushQueue()
297
369
  ```
298
370
 
299
371
  ##### destroy()
300
372
 
301
- 销毁实例,清理资源。
373
+ Destroy the instance and clean up resources.
302
374
 
303
375
  ```typescript
304
- bridge.destroy()
376
+ nexus.destroy()
305
377
  ```
306
378
 
307
- **注意**: `destroy()` 方法会自动调用驱动的 `destroy()` 方法来清理事件监听器等资源。建议在组件卸载时调用此方法以避免内存泄漏。
379
+ **Note**: The `destroy()` method automatically calls the driver's `destroy()` method to clean up resources like event listeners. It is recommended to call this method when the component is unmounted to avoid memory leaks.
308
380
 
309
381
  ### WebSocketDriver
310
382
 
311
- #### 构造函数
383
+ #### Constructor
312
384
 
313
385
  ```typescript
314
386
  new WebSocketDriver(options: WebSocketDriverOptions)
@@ -316,20 +388,20 @@ new WebSocketDriver(options: WebSocketDriverOptions)
316
388
 
317
389
  **Options:**
318
390
 
319
- | 参数 | 类型 | 默认值 | 说明 |
320
- | --------- | --------------------------- | ------------ | ------------- |
321
- | url | string | 必填 | WebSocket URL |
322
- | reconnect | boolean \| ReconnectOptions | true | 是否自动重连 |
323
- | logger | Logger | new Logger() | 日志实例 |
391
+ | Parameter | Type | Default Value | Description |
392
+ | --------- | --------------------------- | ------------- | ---------------------------------- |
393
+ | url | string | Required | WebSocket URL |
394
+ | reconnect | boolean \| ReconnectOptions | true | Whether to automatically reconnect |
395
+ | logger | Logger | new Logger() | Logger instance |
324
396
 
325
397
  **ReconnectOptions:**
326
398
 
327
- | 参数 | 类型 | 默认值 | 说明 |
328
- | ------------- | ------ | -------- | ---------------- |
329
- | maxRetries | number | Infinity | 最大重试次数 |
330
- | retryInterval | number | 5000 | 重试间隔(毫秒) |
399
+ | Parameter | Type | Default Value | Description |
400
+ | ------------- | ------ | ------------- | ----------------------------- |
401
+ | maxRetries | number | Infinity | Maximum retry count |
402
+ | retryInterval | number | 5000 | Retry interval (milliseconds) |
331
403
 
332
- **示例:**
404
+ **Example:**
333
405
 
334
406
  ```typescript
335
407
  const driver = new WebSocketDriver({
@@ -341,11 +413,11 @@ const driver = new WebSocketDriver({
341
413
  })
342
414
  ```
343
415
 
344
- #### 方法
416
+ #### Methods
345
417
 
346
418
  ##### close()
347
419
 
348
- 关闭连接并停止重连。
420
+ Close connection and stop reconnection.
349
421
 
350
422
  ```typescript
351
423
  driver.close()
@@ -353,20 +425,20 @@ driver.close()
353
425
 
354
426
  ### PostMessageDriver
355
427
 
356
- #### 构造函数
428
+ #### Constructor
357
429
 
358
430
  ```typescript
359
431
  new PostMessageDriver(targetWindow: Window, targetOrigin: string)
360
432
  ```
361
433
 
362
- **参数:**
434
+ **Parameters:**
363
435
 
364
- | 参数 | 类型 | 必填 | 说明 |
365
- | ------------ | ------ | ---- | ------------------------------------- |
366
- | targetWindow | Window | | 目标窗口对象 |
367
- | targetOrigin | string | | 目标源地址(安全要求,不能使用 '\*' |
436
+ | Parameter | Type | Required | Description |
437
+ | ------------ | ------ | -------- | ----------------------------------------------------------------- |
438
+ | targetWindow | Window | Yes | Target window object |
439
+ | targetOrigin | string | Yes | Target origin address (security requirement, '\*' cannot be used) |
368
440
 
369
- **示例:**
441
+ **Example:**
370
442
 
371
443
  ```typescript
372
444
  const driver = new PostMessageDriver(window.parent, 'https://app.example.com')
@@ -374,27 +446,27 @@ const driver = new PostMessageDriver(window.parent, 'https://app.example.com')
374
446
 
375
447
  ### MittDriver
376
448
 
377
- #### 构造函数
449
+ #### Constructor
378
450
 
379
451
  ```typescript
380
452
  new MittDriver(emitter: Emitter<Record<string, Message>>)
381
453
  ```
382
454
 
383
- **示例:**
455
+ **Example:**
384
456
 
385
457
  ```typescript
386
458
  import { createEmitter, MittDriver } from 'message-nexus'
387
459
 
388
- // 使用工厂函数创建独立的 emitter 实例
460
+ // Use the factory function to create an independent emitter instance
389
461
  const emitter = createEmitter()
390
462
  const driver = new MittDriver(emitter)
391
463
  ```
392
464
 
393
- **注意**: 推荐使用 `createEmitter()` 工厂函数创建独立的 emitter 实例。
465
+ **Note**: It is recommended to use the `createEmitter()` factory function to create an independent emitter instance.
394
466
 
395
467
  ### BroadcastDriver
396
468
 
397
- #### 构造函数
469
+ #### Constructor
398
470
 
399
471
  ```typescript
400
472
  new BroadcastDriver(options: BroadcastDriverOptions)
@@ -402,83 +474,80 @@ new BroadcastDriver(options: BroadcastDriverOptions)
402
474
 
403
475
  **BroadcastDriverOptions:**
404
476
 
405
- | 参数 | 类型 | 默认值 | 说明 |
406
- | ------- | ------ | ------ | ------------ |
407
- | channel | string | 必填 | 广播频道名称 |
477
+ | Parameter | Type | Default Value | Description |
478
+ | --------- | ------ | ------------- | ---------------------- |
479
+ | channel | string | Required | Broadcast channel name |
408
480
 
409
- **示例:**
481
+ **Example:**
410
482
 
411
483
  ```typescript
412
- import { BroadcastDriver, MessageBridge } from 'message-nexus'
484
+ import { BroadcastDriver, MessageNexus } from 'message-nexus'
413
485
 
414
486
  const driver = new BroadcastDriver({ channel: 'my-app-channel' })
415
- const bridge = new MessageBridge(driver)
487
+ const nexus = new MessageNexus(driver)
416
488
 
417
- // 监听来自其他标签页的消息
418
- bridge.onCommand((data) => {
419
- console.log('Received from another tab:', data)
420
- bridge.reply(data.id, { received: true })
489
+ // Listen for messages from other tabs
490
+ nexus.handle('SOME_METHOD', (params, context) => {
491
+ console.log('Received from another tab:', params)
492
+ return { received: true }
421
493
  })
422
494
 
423
- // 清理资源
424
- bridge.destroy()
495
+ // Clean up resources
496
+ nexus.destroy()
425
497
  ```
426
498
 
427
- **特性:**
428
-
429
- - 同一源下的多个标签页可以通过相同频道名进行通信
430
- - 自动添加协议标识符,过滤非 MessageBridge 消息
431
- - 支持动态切换频道
499
+ **Features:**
432
500
 
433
- ## Logger 日志
501
+ - Multiple tabs under the same origin can communicate via the same channel name
502
+ - Automatically adds a protocol identifier to filter non-MessageNexus messages
503
+ - Supports dynamic channel switching
434
504
 
435
- ### 基本使用
505
+ ## Advanced Usage / Techniques
436
506
 
437
- ```typescript
438
- import { Logger, createConsoleHandler, LogLevel } from 'message-nexus/utils/logger'
507
+ ### Asynchronous Handlers
439
508
 
440
- const logger = new Logger('MyApp', LogLevel.DEBUG)
441
- logger.addHandler(createConsoleHandler())
442
-
443
- logger.debug('Debug message', { data: 123 })
444
- logger.info('Info message')
445
- logger.warn('Warning message')
446
- logger.error('Error message', { error: new Error('test') })
447
- ```
448
-
449
- ### 自定义日志处理器
509
+ Handlers registered via `handle()` can be `async` functions or return a `Promise`. MessageNexus will wait for the Promise to resolve before sending the response back to the caller.
450
510
 
451
511
  ```typescript
452
- const apiHandler = (entry) => {
453
- fetch('/api/logs', {
454
- method: 'POST',
455
- body: JSON.stringify(entry),
456
- })
457
- }
458
-
459
- logger.addHandler(apiHandler)
512
+ nexus.handle('FETCH_REMOTE', async (params) => {
513
+ const data = await fetch(`https://api.example.com/items/${params.id}`)
514
+ return await data.json()
515
+ })
460
516
  ```
461
517
 
462
- ### 设置日志级别
518
+ ### Suspending Responses (Manual Reply Simulation)
519
+
520
+ In some cases, you may need to wait for a user action (like clicking a button in the UI) before replying to a request. You can achieve this by returning a Promise and storing its `resolve` function.
463
521
 
464
522
  ```typescript
465
- logger.setMinLevel(LogLevel.WARN) // 只输出 WARN ERROR
466
- ```
523
+ const pendingResolvers = new Map<string, (value: any) => void>()
467
524
 
468
- ### Bridge 中使用
525
+ nexus.handle('user.confirm', (params, context) => {
526
+ return new Promise((resolve) => {
527
+ // Store the resolve function indexed by messageId
528
+ const id = context.messageId!
529
+ pendingResolvers.set(id, resolve)
469
530
 
470
- ```typescript
471
- import { Logger } from 'message-nexus/utils/logger'
531
+ // Trigger some UI to show a confirmation dialog
532
+ showDialog(params.message)
533
+ })
534
+ })
472
535
 
473
- const logger = new Logger('MyBridge')
474
- const bridge = new MessageBridge(driver, { logger })
536
+ // Later, when the user clicks "Confirm"
537
+ function onUserConfirm(id: string) {
538
+ const resolve = pendingResolvers.get(id)
539
+ if (resolve) {
540
+ resolve({ confirmed: true })
541
+ pendingResolvers.delete(id)
542
+ }
543
+ }
475
544
  ```
476
545
 
477
- ## 设计亮点
546
+ ## Design Highlights
478
547
 
479
- ### 1. 类型安全
548
+ ### 1. Type Safety
480
549
 
481
- MessageBridge 使用 TypeScript 泛型提供完整的类型推断:
550
+ MessageNexus uses TypeScript generics to provide full type inference:
482
551
 
483
552
  ```typescript
484
553
  interface UserRequest {
@@ -490,47 +559,48 @@ interface UserResponse {
490
559
  name: string
491
560
  }
492
561
 
493
- const bridge = new MessageBridge<UserRequest, UserResponse>(driver)
562
+ const nexus = new MessageNexus<UserRequest, UserResponse>(driver)
494
563
 
495
- // 完整的类型推断
496
- const response = await bridge.request({
497
- type: 'GET_USER',
498
- payload: { userId: 123 }, // 类型: UserRequest
564
+ // Full type inference
565
+ const response = await nexus.invoke({
566
+ method: 'GET_USER',
567
+ params: { userId: 123 }, // Type: UserRequest
499
568
  })
500
569
 
501
- // response 类型: UserResponse
570
+ // response Type: UserResponse
502
571
  console.log(response.name)
503
572
  ```
504
573
 
505
- ### 2. 内存安全
574
+ ### 2. Memory Safety
506
575
 
507
- - **自动清理**: 定期清理过期的消息记录
508
- - **手动清理**: `reply()` 后立即删除记录
509
- - **资源释放**: `destroy()` 方法清理所有定时器和事件监听器
510
- - **队列限制**: 消息队列有最大大小限制,防止无限增长
511
- - **Driver 生命周期**: 每个 Driver 实现 `destroy()` 方法,正确释放资源
512
- - **Emitter 隔离**: 推荐使用 `createEmitter()` 创建独立实例,避免共享单例导致的内存泄漏
576
+ - **Auto Cleanup**: Regularly clean up expired message records
577
+ - **Manual Cleanup**: Internal request records are deleted immediately after the response is received or timed out
578
+ - **Auto-Reply**: Handlers automatically send responses when the return value is resolved, ensuring no orphaned requests
579
+ - **Resource Release**: The `destroy()` method cleans up all timers and event listeners
580
+ - **Queue Limits**: The message queue has a maximum size limit to prevent infinite growth
581
+ - **Driver Lifecycle**: Each driver implements the `destroy()` method to correctly release resources
582
+ - **Emitter Isolation**: Recommended to use `createEmitter()` to create independent instances, avoiding memory leaks caused by shared singletons
513
583
 
514
- ### 3. 错误恢复
584
+ ### 3. Error Recovery
515
585
 
516
- - **自动重连**: WebSocket 断线自动重连,指数退避策略
517
- - **请求重试**: 失败请求自动重试,可配置次数和延迟
518
- - **消息队列**: 离线消息缓存,连接恢复后自动发送
519
- - **错误回调**: 统一的错误处理机制
586
+ - **Auto Reconnect**: WebSocket automatic reconnection mechanism with exponential backoff strategy
587
+ - **Request Retry**: Automatic retry on request failure, configurable retry counts and delays
588
+ - **Message Queue**: Offline message caching, automatically sent after connection recovery
589
+ - **Error Callback**: Unified error handling mechanism
520
590
 
521
- ### 4. 安全加固
591
+ ### 4. Security Hardening
522
592
 
523
- - **PostMessage**: 禁止使用 `'*'` 作为 targetOrigin,必须明确指定源地址
524
- - **BroadcastChannel**: 使用协议标识符 `__messageBridge` 区分 MessageBridge 消息和用户自定义消息
525
- - **消息验证**: 运行时验证消息格式,防止非法消息导致崩溃
526
- - **来源过滤**: 自动过滤非目标消息
593
+ - **PostMessage**: Prohibit using `'*'` as targetOrigin; the origin address must be explicitly specified
594
+ - **BroadcastChannel**: Use the protocol identifier `__messageBridge` to distinguish MessageNexus messages from user-defined messages
595
+ - **Message Validation**: Runtime validation of message format to prevent crashes from illegal messages
596
+ - **Source Filtering**: Automatically filters non-target messages
527
597
 
528
- ### 5. 可观测性
598
+ ### 5. Observability
529
599
 
530
- 内置监控指标,便于生产环境监控:
600
+ Built-in monitoring metrics for easy production environment monitoring:
531
601
 
532
602
  ```typescript
533
- const metrics = bridge.getMetrics()
603
+ const metrics = nexus.getMetrics()
534
604
 
535
605
  console.log(`Messages: ${metrics.messagesSent} sent, ${metrics.messagesReceived} received`)
536
606
  console.log(
@@ -540,34 +610,15 @@ console.log(`Avg latency: ${metrics.averageLatency}ms`)
540
610
  console.log(`Pending: ${metrics.pendingMessages}, Queued: ${metrics.queuedMessages}`)
541
611
  ```
542
612
 
543
- ### 6. 结构化日志
544
-
545
- 统一的日志接口,支持多种输出方式:
546
-
547
- ```typescript
548
- // 控制台输出
549
- logger.addHandler(createConsoleHandler())
550
-
551
- // 发送到 API
552
- logger.addHandler((entry) => {
553
- fetch('/api/logs', { body: JSON.stringify(entry) })
554
- })
555
-
556
- // 发送到 ELK
557
- logger.addHandler((entry) => {
558
- elk.send(entry)
559
- })
560
- ```
561
-
562
- ## 测试
613
+ ## Testing
563
614
 
564
- 运行单元测试:
615
+ Run unit tests:
565
616
 
566
617
  ```bash
567
618
  cd packages/message-nexus
568
619
  pnpm test:run
569
620
  ```
570
621
 
571
- ## 许可证
622
+ ## License
572
623
 
573
624
  MIT