message-nexus 1.1.1 → 1.1.3
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 +105 -43
- package/dist/index.cjs +1 -741
- package/dist/index.d.cts +82 -23
- package/dist/index.d.ts +82 -23
- package/dist/index.js +1 -699
- package/package.json +10 -1
package/README.md
CHANGED
|
@@ -22,7 +22,8 @@ pnpm add message-nexus
|
|
|
22
22
|
- **Retry Mechanism**: Automatic retry on request failure, configurable retry counts and delays
|
|
23
23
|
- **Message Validation**: Runtime message format validation to prevent illegal messages
|
|
24
24
|
- **Monitoring Metrics**: Built-in message statistics and performance monitoring
|
|
25
|
-
- **Structured Logging**: Supports custom log handlers for easy debugging and production monitoring
|
|
25
|
+
- **Structured Logging**: Supports adjustable log levels (DEBUG, INFO, WARN, ERROR) and custom log handlers or simple loggers (like `console`) for easy debugging and production monitoring.
|
|
26
|
+
|
|
26
27
|
- **Resource Management**: All drivers support the `destroy()` method to properly clean up resources.
|
|
27
28
|
|
|
28
29
|
## Quick Start
|
|
@@ -156,19 +157,39 @@ receiverNexus.handle('SYNC_STATE', (params, context) => {
|
|
|
156
157
|
#### Constructor
|
|
157
158
|
|
|
158
159
|
```typescript
|
|
159
|
-
new MessageNexus<
|
|
160
|
+
new MessageNexus<InvokeMap, NotificationMap>(
|
|
160
161
|
driver: BaseDriver,
|
|
161
162
|
options?: MessageNexusOptions
|
|
162
163
|
)
|
|
163
164
|
```
|
|
164
165
|
|
|
166
|
+
**Generics:**
|
|
167
|
+
|
|
168
|
+
- `InvokeMap`: A record mapping method names to `{ params: any; result: any }`. Defaults to `DefaultRegistry`.
|
|
169
|
+
- `NotificationMap`: A record mapping notification method names to their parameter types. Defaults to `Record<string, any>`.
|
|
170
|
+
|
|
165
171
|
**Options:**
|
|
166
172
|
|
|
167
|
-
| Parameter
|
|
168
|
-
|
|
|
169
|
-
| instanceId
|
|
170
|
-
| timeout
|
|
171
|
-
| logger
|
|
173
|
+
| Parameter | Type | Default Value | Description |
|
|
174
|
+
| ------------- | ---------------------------- | -------------- | ------------------------------------------ |
|
|
175
|
+
| instanceId | string | auto-generated | Instance ID, used for message routing |
|
|
176
|
+
| timeout | number | 10000 | Request timeout (milliseconds) |
|
|
177
|
+
| logger | LoggerInterface \| SimpleLogger | new Logger() | Logger instance or simple logger (e.g. `console`) |
|
|
178
|
+
| loggerEnabled | boolean | false | Whether to enable logging |
|
|
179
|
+
| logLevel | LogLevel | LogLevel.INFO | Minimum log level to report |
|
|
180
|
+
|
|
181
|
+
**LogLevel:** `DEBUG`, `INFO`, `WARN`, `ERROR`
|
|
182
|
+
|
|
183
|
+
**SimpleLogger Interface:**
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
interface SimpleLogger {
|
|
187
|
+
debug(message: string, metadata?: Record<string, unknown>): void
|
|
188
|
+
info(message: string, metadata?: Record<string, unknown>): void
|
|
189
|
+
warn(message: string, metadata?: Record<string, unknown>): void
|
|
190
|
+
error(message: string, metadata?: Record<string, unknown>): void
|
|
191
|
+
}
|
|
192
|
+
```
|
|
172
193
|
|
|
173
194
|
#### Methods
|
|
174
195
|
|
|
@@ -177,15 +198,17 @@ new MessageNexus<RequestPayload, ResponsePayload>(
|
|
|
177
198
|
Send request and wait for response.
|
|
178
199
|
|
|
179
200
|
```typescript
|
|
180
|
-
nexus.invoke<
|
|
201
|
+
nexus.invoke<K extends keyof InvokeMap>(
|
|
202
|
+
methodOrOptions: K | InvokeOptions<K, InvokeMap[K]['params']>
|
|
203
|
+
): Promise<InvokeMap[K]['result']>
|
|
181
204
|
```
|
|
182
205
|
|
|
183
206
|
**Options:**
|
|
184
207
|
|
|
185
208
|
| Parameter | Type | Required | Description |
|
|
186
209
|
| ---------- | ----------------------- | -------- | ---------------------------- |
|
|
187
|
-
| method |
|
|
188
|
-
| params |
|
|
210
|
+
| method | K | Yes | Message method |
|
|
211
|
+
| params | InvokeMap[K]['params'] | No | Request data |
|
|
189
212
|
| to | string | No | Target instance ID |
|
|
190
213
|
| metadata | Record<string, unknown> | No | Metadata |
|
|
191
214
|
| timeout | number | No | Timeout (overrides global) |
|
|
@@ -214,15 +237,17 @@ const result = await nexus.invoke({
|
|
|
214
237
|
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
238
|
|
|
216
239
|
```typescript
|
|
217
|
-
nexus.notify
|
|
240
|
+
nexus.notify<K extends keyof NotificationMap>(
|
|
241
|
+
methodOrOptions: K | NotificationOptions<K, NotificationMap[K]>
|
|
242
|
+
): void
|
|
218
243
|
```
|
|
219
244
|
|
|
220
245
|
**Options:**
|
|
221
246
|
|
|
222
247
|
| Parameter | Type | Required | Description |
|
|
223
248
|
| --------- | ----------------------- | -------- | ------------------- |
|
|
224
|
-
| method |
|
|
225
|
-
| params |
|
|
249
|
+
| method | K | Yes | Notification method |
|
|
250
|
+
| params | NotificationMap[K] | No | Notification data |
|
|
226
251
|
| to | string | No | Target instance ID |
|
|
227
252
|
| metadata | Record<string, unknown> | No | Metadata |
|
|
228
253
|
|
|
@@ -245,7 +270,10 @@ nexus.notify({
|
|
|
245
270
|
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.
|
|
246
271
|
|
|
247
272
|
```typescript
|
|
248
|
-
nexus.handle<
|
|
273
|
+
nexus.handle<K extends keyof InvokeMap>(
|
|
274
|
+
method: K,
|
|
275
|
+
handler: InvokeHandler<InvokeMap[K]['params'], InvokeMap[K]['result']>
|
|
276
|
+
): () => void
|
|
249
277
|
```
|
|
250
278
|
|
|
251
279
|
**Parameters:**
|
|
@@ -279,7 +307,10 @@ unsubscribe()
|
|
|
279
307
|
Register a handler for a specific notification method (one-way messages).
|
|
280
308
|
|
|
281
309
|
```typescript
|
|
282
|
-
nexus.onNotification<
|
|
310
|
+
nexus.onNotification<K extends keyof NotificationMap>(
|
|
311
|
+
method: K,
|
|
312
|
+
handler: NotificationHandler<NotificationMap[K]>
|
|
313
|
+
): () => void
|
|
283
314
|
```
|
|
284
315
|
|
|
285
316
|
**Example:**
|
|
@@ -295,22 +326,56 @@ unsubscribe()
|
|
|
295
326
|
|
|
296
327
|
##### onError()
|
|
297
328
|
|
|
298
|
-
Register error handler.
|
|
329
|
+
Register a global error handler for background errors (e.g., driver failures, invalid incoming messages). For request-specific errors, use `try/catch` with `invoke()`.
|
|
299
330
|
|
|
300
331
|
```typescript
|
|
301
|
-
nexus.onError(handler:
|
|
332
|
+
nexus.onError(handler: (error: Error | NexusError, context?: Record<string, unknown>) => void): () => void
|
|
302
333
|
```
|
|
303
334
|
|
|
304
335
|
**Example:**
|
|
305
336
|
|
|
306
337
|
```typescript
|
|
307
338
|
nexus.onError((error, context) => {
|
|
308
|
-
|
|
339
|
+
if (error instanceof NexusError) {
|
|
340
|
+
console.error(`Bridge error [${error.code}]: ${error.message}`, error.data)
|
|
341
|
+
} else {
|
|
342
|
+
console.error('System error:', error.message)
|
|
343
|
+
}
|
|
309
344
|
// Send to error tracking service
|
|
310
345
|
Sentry.captureException(error, { extra: context })
|
|
311
346
|
})
|
|
312
347
|
```
|
|
313
348
|
|
|
349
|
+
#### Errors
|
|
350
|
+
|
|
351
|
+
MessageNexus provides a structured error system based on the JSON-RPC 2.0 specification.
|
|
352
|
+
|
|
353
|
+
##### NexusError
|
|
354
|
+
|
|
355
|
+
A custom error class that includes a numeric code and optional data.
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
class NexusError<D = any> extends Error {
|
|
359
|
+
code: number // JSON-RPC or Nexus-specific error code
|
|
360
|
+
data?: D // Optional additional error information
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
##### NexusErrorCode
|
|
365
|
+
|
|
366
|
+
Common error codes exported by the library:
|
|
367
|
+
|
|
368
|
+
| Code | Name | Description |
|
|
369
|
+
| --- | --- | --- |
|
|
370
|
+
| -32700 | `ParseError` | Invalid JSON received by the server |
|
|
371
|
+
| -32600 | `InvalidRequest` | The JSON sent is not a valid Request object |
|
|
372
|
+
| -32601 | `MethodNotFound` | The method does not exist / is not registered |
|
|
373
|
+
| -32602 | `InvalidParams` | Invalid method parameter(s) |
|
|
374
|
+
| -32603 | `InternalError` | Internal JSON-RPC error (e.g., handler threw an exception) |
|
|
375
|
+
| -32001 | `Timeout` | Request timed out |
|
|
376
|
+
| -32002 | `SendFailed` | Failed to send message via driver |
|
|
377
|
+
| -32003 | `InvalidResponse` | Received a response that doesn't match the request |
|
|
378
|
+
|
|
314
379
|
##### getMetrics()
|
|
315
380
|
|
|
316
381
|
Get monitoring metrics.
|
|
@@ -547,28 +612,33 @@ function onUserConfirm(id: string) {
|
|
|
547
612
|
|
|
548
613
|
### 1. Type Safety
|
|
549
614
|
|
|
550
|
-
MessageNexus uses TypeScript generics to provide full type inference:
|
|
615
|
+
MessageNexus uses TypeScript generics and Schema mapping to provide full type inference across method names, parameters, and results:
|
|
551
616
|
|
|
552
617
|
```typescript
|
|
553
|
-
|
|
554
|
-
|
|
618
|
+
// 1. Define your protocol schemas
|
|
619
|
+
interface MyInvokeMap {
|
|
620
|
+
'getUser': { params: { id: number }; result: { name: string; age: number } };
|
|
621
|
+
'calculate': { params: { a: number; b: number }; result: number };
|
|
555
622
|
}
|
|
556
623
|
|
|
557
|
-
interface
|
|
558
|
-
|
|
559
|
-
name: string
|
|
624
|
+
interface MyNotificationMap {
|
|
625
|
+
'onLog': { message: string; level: 'info' | 'warn' | 'error' };
|
|
560
626
|
}
|
|
561
627
|
|
|
562
|
-
|
|
628
|
+
// 2. Initialize with your schemas
|
|
629
|
+
const nexus = new MessageNexus<MyInvokeMap, MyNotificationMap>(driver)
|
|
563
630
|
|
|
564
|
-
//
|
|
565
|
-
const response = await nexus.invoke({
|
|
566
|
-
|
|
567
|
-
params: { userId: 123 }, // Type: UserRequest
|
|
568
|
-
})
|
|
631
|
+
// 3. Enjoy full type inference and autocompletion
|
|
632
|
+
const response = await nexus.invoke('getUser', { id: 123 })
|
|
633
|
+
// response Type: { name: string; age: number }
|
|
569
634
|
|
|
570
|
-
|
|
571
|
-
|
|
635
|
+
nexus.notify('onLog', { message: 'Ready', level: 'info' })
|
|
636
|
+
|
|
637
|
+
// 4. Type-safe handlers
|
|
638
|
+
nexus.handle('calculate', (params) => {
|
|
639
|
+
// params Type: { a: number; b: number }
|
|
640
|
+
return params.a + params.b // result Type must be number
|
|
641
|
+
})
|
|
572
642
|
```
|
|
573
643
|
|
|
574
644
|
### 2. Memory Safety
|
|
@@ -581,12 +651,13 @@ console.log(response.name)
|
|
|
581
651
|
- **Driver Lifecycle**: Each driver implements the `destroy()` method to correctly release resources
|
|
582
652
|
- **Emitter Isolation**: Recommended to use `createEmitter()` to create independent instances, avoiding memory leaks caused by shared singletons
|
|
583
653
|
|
|
584
|
-
### 3. Error Recovery
|
|
654
|
+
### 3. Error Recovery & Handling
|
|
585
655
|
|
|
586
656
|
- **Auto Reconnect**: WebSocket automatic reconnection mechanism with exponential backoff strategy
|
|
587
657
|
- **Request Retry**: Automatic retry on request failure, configurable retry counts and delays
|
|
588
658
|
- **Message Queue**: Offline message caching, automatically sent after connection recovery
|
|
589
|
-
- **Error
|
|
659
|
+
- **Structured Error Handling**: Dedicated `NexusError` class and standard codes (JSON-RPC 2.0 compatible) for precise diagnostic and fault recovery
|
|
660
|
+
- **Unified Error Callback**: Global `onError` listener for non-request background errors
|
|
590
661
|
|
|
591
662
|
### 4. Security Hardening
|
|
592
663
|
|
|
@@ -610,15 +681,6 @@ console.log(`Avg latency: ${metrics.averageLatency}ms`)
|
|
|
610
681
|
console.log(`Pending: ${metrics.pendingMessages}, Queued: ${metrics.queuedMessages}`)
|
|
611
682
|
```
|
|
612
683
|
|
|
613
|
-
## Testing
|
|
614
|
-
|
|
615
|
-
Run unit tests:
|
|
616
|
-
|
|
617
|
-
```bash
|
|
618
|
-
cd packages/message-nexus
|
|
619
|
-
pnpm test:run
|
|
620
|
-
```
|
|
621
|
-
|
|
622
684
|
## License
|
|
623
685
|
|
|
624
686
|
MIT
|