@actdim/msgmesh 1.3.2 → 1.3.4
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 +79 -75
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -21,15 +21,17 @@
|
|
|
21
21
|
- [Global vs Local Usage](#global-vs-local-usage)
|
|
22
22
|
- [Creating a Message Bus](#creating-a-message-bus)
|
|
23
23
|
- [Type Utilities](#type-utilities)
|
|
24
|
-
- [API Reference](#api-reference)
|
|
25
|
-
- [Configuration](#configuration)
|
|
26
|
-
- [`send()`](#sending-messages-send)
|
|
27
|
-
- [`on()`](#subscribing-to-messages-on)
|
|
28
|
-
- [`once()`](#awaiting-a-single-message-once)
|
|
29
|
-
- [`stream()`](#streaming-messages-stream)
|
|
30
|
-
- [`provide()`](#providing-response-handlers-provide)
|
|
31
|
-
|
|
32
|
-
- [
|
|
24
|
+
- [API Reference](#api-reference)
|
|
25
|
+
- [Configuration](#configuration)
|
|
26
|
+
- [`send()`](#sending-messages-send)
|
|
27
|
+
- [`on()`](#subscribing-to-messages-on)
|
|
28
|
+
- [`once()`](#awaiting-a-single-message-once)
|
|
29
|
+
- [`stream()`](#streaming-messages-stream)
|
|
30
|
+
- [`provide()`](#providing-response-handlers-provide)
|
|
31
|
+
- [Provider-Side Cancellation](#cancellation-handling)
|
|
32
|
+
- [`request()`](#request-response-pattern-request)
|
|
33
|
+
- [Request Cancellation](#cancellation)
|
|
34
|
+
- [Advanced Features](#advanced-features)
|
|
33
35
|
- [Message Replay](#message-replay)
|
|
34
36
|
- [Throttling and Debouncing](#throttling-and-debouncing)
|
|
35
37
|
- [Error Handling](#error-handling)
|
|
@@ -43,13 +45,13 @@ Try @actdim/msgmesh instantly in your browser without any installation:
|
|
|
43
45
|
|
|
44
46
|
[](https://stackblitz.com/~/github.com/actdim/msgmesh)
|
|
45
47
|
|
|
46
|
-
Once the project loads, run the tests to see the message bus in action:
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
pnpm run test
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Installation
|
|
48
|
+
Once the project loads, run the tests to see the message bus in action:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pnpm run test
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
53
55
|
|
|
54
56
|
```bash
|
|
55
57
|
npm install @actdim/msgmesh
|
|
@@ -193,19 +195,19 @@ Use generic `MsgStruct<...>` to define bus structures: it extends your declared
|
|
|
193
195
|
import { MsgStruct } from '@actdim/msgmesh';
|
|
194
196
|
|
|
195
197
|
export type MyBusStruct = MsgStruct<{
|
|
196
|
-
'
|
|
198
|
+
'TEST.COMPUTE_SUM': {
|
|
197
199
|
in: { a: number; b: number };
|
|
198
200
|
out: number;
|
|
199
201
|
};
|
|
200
|
-
'
|
|
202
|
+
'TEST.DO_SOME_WORK': {
|
|
201
203
|
in: string;
|
|
202
204
|
out: void;
|
|
203
205
|
};
|
|
204
|
-
'
|
|
206
|
+
'TEST.TEST_TASK_WITH_REPEAT': {
|
|
205
207
|
in: string;
|
|
206
208
|
out: void;
|
|
207
209
|
};
|
|
208
|
-
'
|
|
210
|
+
'TEST.MULTIPLEXER': {
|
|
209
211
|
in1: string;
|
|
210
212
|
in2: number;
|
|
211
213
|
out: number;
|
|
@@ -274,7 +276,7 @@ type MyMsgChannels<TChannel extends keyof MyBusStruct | Array<keyof MyBusStruct>
|
|
|
274
276
|
// Helper types are necessary for IntelliSense with dynamic types
|
|
275
277
|
// All API checks are enforced at compile time - you cannot violate defined contracts
|
|
276
278
|
type Behavior = {
|
|
277
|
-
messages: MyMsgChannels<'
|
|
279
|
+
messages: MyMsgChannels<'TEST.COMPUTE_SUM' | 'TEST.DO_SOME_WORK'>;
|
|
278
280
|
};
|
|
279
281
|
```
|
|
280
282
|
|
|
@@ -297,7 +299,7 @@ You can configure channels with various options:
|
|
|
297
299
|
import { MsgBusConfig } from '@actdim/msgmesh';
|
|
298
300
|
|
|
299
301
|
const config: MsgBusConfig<MyBusStruct> = {
|
|
300
|
-
'
|
|
302
|
+
'TEST.COMPUTE_SUM': {
|
|
301
303
|
replayBufferSize: 10, // Number of messages to buffer for replay
|
|
302
304
|
replayWindowTime: 5000, // Time window for replay (ms)
|
|
303
305
|
delay: 100, // Delay before processing (ms)
|
|
@@ -321,33 +323,33 @@ Send a message to the bus for a specific channel and group (default is `in`). Th
|
|
|
321
323
|
```typescript
|
|
322
324
|
// Basic send
|
|
323
325
|
await msgBus.send({
|
|
324
|
-
channel: '
|
|
326
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
325
327
|
payload: { a: 10, b: 20 }, // Typed and validated
|
|
326
328
|
});
|
|
327
329
|
|
|
328
330
|
// With group specification
|
|
329
331
|
await msgBus.send({
|
|
330
|
-
channel: '
|
|
332
|
+
channel: 'TEST.MULTIPLEXER',
|
|
331
333
|
group: 'in1',
|
|
332
334
|
payload: 'hello', // Typed as string for 'in1' group
|
|
333
335
|
});
|
|
334
336
|
|
|
335
337
|
await msgBus.send({
|
|
336
|
-
channel: '
|
|
338
|
+
channel: 'TEST.MULTIPLEXER',
|
|
337
339
|
group: 'in2',
|
|
338
340
|
payload: 42, // Typed as number for 'in2' group
|
|
339
341
|
});
|
|
340
342
|
|
|
341
343
|
// With topic
|
|
342
344
|
await msgBus.send({
|
|
343
|
-
channel: '
|
|
345
|
+
channel: 'TEST.DO_SOME_WORK',
|
|
344
346
|
topic: 'priority-high',
|
|
345
347
|
payload: 'urgent task',
|
|
346
348
|
});
|
|
347
349
|
|
|
348
350
|
// With custom headers
|
|
349
351
|
await msgBus.send({
|
|
350
|
-
channel: '
|
|
352
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
351
353
|
payload: { a: 5, b: 15 },
|
|
352
354
|
headers: {
|
|
353
355
|
correlationId: 'task-123',
|
|
@@ -365,7 +367,7 @@ Subscribe to messages on a specific channel and group with optional topic filter
|
|
|
365
367
|
```typescript
|
|
366
368
|
// Basic subscription
|
|
367
369
|
msgBus.on({
|
|
368
|
-
channel: '
|
|
370
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
369
371
|
callback: (msg) => {
|
|
370
372
|
// msg.payload is typed as { a: number; b: number }
|
|
371
373
|
console.log('Received:', msg.payload);
|
|
@@ -374,7 +376,7 @@ msgBus.on({
|
|
|
374
376
|
|
|
375
377
|
// Subscribe to specific group
|
|
376
378
|
msgBus.on({
|
|
377
|
-
channel: '
|
|
379
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
378
380
|
group: 'out', // Listen for responses
|
|
379
381
|
callback: (msg) => {
|
|
380
382
|
// msg.payload is typed as number
|
|
@@ -384,7 +386,7 @@ msgBus.on({
|
|
|
384
386
|
|
|
385
387
|
// With topic filtering (regex pattern)
|
|
386
388
|
msgBus.on({
|
|
387
|
-
channel: '
|
|
389
|
+
channel: 'TEST.DO_SOME_WORK',
|
|
388
390
|
topic: '/^task-.*/', // Match topics starting with "task-"
|
|
389
391
|
callback: (msg) => {
|
|
390
392
|
console.log('Task message:', msg.payload);
|
|
@@ -393,7 +395,7 @@ msgBus.on({
|
|
|
393
395
|
|
|
394
396
|
// With options
|
|
395
397
|
msgBus.on({
|
|
396
|
-
channel: '
|
|
398
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
397
399
|
callback: (msg) => {
|
|
398
400
|
console.log('Message:', msg.payload);
|
|
399
401
|
},
|
|
@@ -415,7 +417,7 @@ msgBus.on({
|
|
|
415
417
|
|
|
416
418
|
```typescript
|
|
417
419
|
msgBus.on({
|
|
418
|
-
channel: '
|
|
420
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
419
421
|
callback: (msg) => {
|
|
420
422
|
console.log(msg.payload);
|
|
421
423
|
},
|
|
@@ -433,7 +435,7 @@ Use `AbortSignal` for controlled unsubscription. This allows combining abort sig
|
|
|
433
435
|
const abortController = new AbortController();
|
|
434
436
|
|
|
435
437
|
msgBus.on({
|
|
436
|
-
channel: "
|
|
438
|
+
channel: "TEST.COMPUTE_SUM",
|
|
437
439
|
callback: (msg) => {
|
|
438
440
|
console.log(msg.payload);
|
|
439
441
|
},
|
|
@@ -455,7 +457,7 @@ const combinedSignal = AbortSignal.any([
|
|
|
455
457
|
]);
|
|
456
458
|
|
|
457
459
|
msgBus.on({
|
|
458
|
-
channel: "
|
|
460
|
+
channel: "TEST.COMPUTE_SUM",
|
|
459
461
|
options: {
|
|
460
462
|
abortSignal: combinedSignal
|
|
461
463
|
},
|
|
@@ -472,7 +474,7 @@ function MyComponent() {
|
|
|
472
474
|
const controller = new AbortController();
|
|
473
475
|
|
|
474
476
|
msgBus.on({
|
|
475
|
-
channel: "
|
|
477
|
+
channel: "TEST.EVENTS",
|
|
476
478
|
callback: handleEvent,
|
|
477
479
|
options: {
|
|
478
480
|
abortSignal: controller.signal
|
|
@@ -496,14 +498,14 @@ Subscribe and await the first (next) message on a specific channel and group, si
|
|
|
496
498
|
```typescript
|
|
497
499
|
// Wait for one message
|
|
498
500
|
const msg = await msgBus.once({
|
|
499
|
-
channel: '
|
|
501
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
500
502
|
});
|
|
501
503
|
|
|
502
504
|
console.log('Received:', msg.payload); // Typed as { a: number; b: number }
|
|
503
505
|
|
|
504
506
|
// With group specification
|
|
505
507
|
const response = await msgBus.once({
|
|
506
|
-
channel: '
|
|
508
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
507
509
|
group: 'out',
|
|
508
510
|
});
|
|
509
511
|
|
|
@@ -511,7 +513,7 @@ console.log('Result:', response.payload); // Typed as number
|
|
|
511
513
|
|
|
512
514
|
// With topic filtering
|
|
513
515
|
const taskMsg = await msgBus.once({
|
|
514
|
-
channel: '
|
|
516
|
+
channel: 'TEST.DO_SOME_WORK',
|
|
515
517
|
topic: '/^priority-.*/', // Match topics starting with "priority-"
|
|
516
518
|
});
|
|
517
519
|
```
|
|
@@ -523,7 +525,7 @@ Configure timeout duration via the `timeout` option. The `abortSignal` option al
|
|
|
523
525
|
```typescript
|
|
524
526
|
try {
|
|
525
527
|
const msg = await msgBus.once({
|
|
526
|
-
channel: '
|
|
528
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
527
529
|
options: {
|
|
528
530
|
timeout: 5000, // 5 second timeout
|
|
529
531
|
},
|
|
@@ -539,7 +541,7 @@ try {
|
|
|
539
541
|
const abortController = new AbortController();
|
|
540
542
|
|
|
541
543
|
const messagePromise = msgBus.once({
|
|
542
|
-
channel: '
|
|
544
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
543
545
|
options: {
|
|
544
546
|
timeout: 10000,
|
|
545
547
|
abortSignal: abortController.signal,
|
|
@@ -565,7 +567,7 @@ Create an async iterable iterator for consuming messages as a stream.
|
|
|
565
567
|
```typescript
|
|
566
568
|
// Basic streaming
|
|
567
569
|
const messageStream = msgBus.stream({
|
|
568
|
-
channel: '
|
|
570
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
569
571
|
});
|
|
570
572
|
|
|
571
573
|
for await (const msg of messageStream) {
|
|
@@ -575,7 +577,7 @@ for await (const msg of messageStream) {
|
|
|
575
577
|
|
|
576
578
|
// With topic filtering
|
|
577
579
|
const taskStream = msgBus.stream({
|
|
578
|
-
channel: '
|
|
580
|
+
channel: 'TEST.DO_SOME_WORK',
|
|
579
581
|
topic: '/^task-.*/',
|
|
580
582
|
});
|
|
581
583
|
|
|
@@ -593,7 +595,7 @@ For a hard time limit on the stream's total duration, use `AbortSignal.timeout()
|
|
|
593
595
|
```typescript
|
|
594
596
|
// Inactivity timeout: end stream if no messages for 5s
|
|
595
597
|
const stream1 = msgBus.stream({
|
|
596
|
-
channel: '
|
|
598
|
+
channel: 'TEST.EVENTS',
|
|
597
599
|
options: {
|
|
598
600
|
timeout: 5000,
|
|
599
601
|
},
|
|
@@ -601,7 +603,7 @@ const stream1 = msgBus.stream({
|
|
|
601
603
|
|
|
602
604
|
// Total duration limit: end stream after 60s regardless of activity
|
|
603
605
|
const stream2 = msgBus.stream({
|
|
604
|
-
channel: '
|
|
606
|
+
channel: 'TEST.EVENTS',
|
|
605
607
|
options: {
|
|
606
608
|
abortSignal: AbortSignal.timeout(60000),
|
|
607
609
|
},
|
|
@@ -609,7 +611,7 @@ const stream2 = msgBus.stream({
|
|
|
609
611
|
|
|
610
612
|
// Both: inactivity 5s + hard limit 60s
|
|
611
613
|
const stream3 = msgBus.stream({
|
|
612
|
-
channel: '
|
|
614
|
+
channel: 'TEST.EVENTS',
|
|
613
615
|
options: {
|
|
614
616
|
timeout: 5000,
|
|
615
617
|
abortSignal: AbortSignal.timeout(60000),
|
|
@@ -626,7 +628,7 @@ The callback can be asynchronous and its result is automatically used to form th
|
|
|
626
628
|
```typescript
|
|
627
629
|
// Simple provider
|
|
628
630
|
msgBus.provide({
|
|
629
|
-
channel: '
|
|
631
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
630
632
|
callback: (msg) => {
|
|
631
633
|
// msg.payload is typed as { a: number; b: number }
|
|
632
634
|
// Return type is inferred as number (from 'out' type)
|
|
@@ -636,7 +638,7 @@ msgBus.provide({
|
|
|
636
638
|
|
|
637
639
|
// Async provider
|
|
638
640
|
msgBus.provide({
|
|
639
|
-
channel: '
|
|
641
|
+
channel: 'TEST.DO_SOME_WORK',
|
|
640
642
|
callback: async (msg) => {
|
|
641
643
|
// msg.payload is typed as string
|
|
642
644
|
await performWork(msg.payload);
|
|
@@ -646,7 +648,7 @@ msgBus.provide({
|
|
|
646
648
|
|
|
647
649
|
// With topic filtering
|
|
648
650
|
msgBus.provide({
|
|
649
|
-
channel: '
|
|
651
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
650
652
|
topic: '/^calc-.*/',
|
|
651
653
|
callback: (msg) => {
|
|
652
654
|
return msg.payload.a + msg.payload.b;
|
|
@@ -655,7 +657,7 @@ msgBus.provide({
|
|
|
655
657
|
|
|
656
658
|
// With options
|
|
657
659
|
msgBus.provide({
|
|
658
|
-
channel: '
|
|
660
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
659
661
|
callback: (msg) => {
|
|
660
662
|
return msg.payload.a + msg.payload.b;
|
|
661
663
|
},
|
|
@@ -674,7 +676,7 @@ For providers that don't need cancellation support, simply check that `headers.s
|
|
|
674
676
|
|
|
675
677
|
```typescript
|
|
676
678
|
msgBus.provide({
|
|
677
|
-
channel: '
|
|
679
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
678
680
|
callback: (msg, headers) => {
|
|
679
681
|
if (headers.status !== 'ok') return;
|
|
680
682
|
return msg.payload.a + msg.payload.b;
|
|
@@ -688,7 +690,7 @@ For providers with long-running or cancelable operations (e.g. `fetch`), track a
|
|
|
688
690
|
const activeRequests = new Map<string, AbortController>();
|
|
689
691
|
|
|
690
692
|
msgBus.provide({
|
|
691
|
-
channel: '
|
|
693
|
+
channel: 'API.FETCH_DATA',
|
|
692
694
|
callback: async (msg, headers) => {
|
|
693
695
|
const { requestId } = headers;
|
|
694
696
|
|
|
@@ -722,7 +724,7 @@ Send a message and automatically await a response from a handler (registered via
|
|
|
722
724
|
```typescript
|
|
723
725
|
// Basic request
|
|
724
726
|
const response = await msgBus.request({
|
|
725
|
-
channel: '
|
|
727
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
726
728
|
payload: { a: 10, b: 20 },
|
|
727
729
|
});
|
|
728
730
|
|
|
@@ -730,13 +732,13 @@ console.log('Result:', response.payload); // Typed as number
|
|
|
730
732
|
|
|
731
733
|
// With group overloading (using different input groups)
|
|
732
734
|
const response1 = await msgBus.request({
|
|
733
|
-
channel: '
|
|
735
|
+
channel: 'TEST.MULTIPLEXER',
|
|
734
736
|
group: 'in1',
|
|
735
737
|
payload: 'hello',
|
|
736
738
|
});
|
|
737
739
|
|
|
738
740
|
const response2 = await msgBus.request({
|
|
739
|
-
channel: '
|
|
741
|
+
channel: 'TEST.MULTIPLEXER',
|
|
740
742
|
group: 'in2',
|
|
741
743
|
payload: 42,
|
|
742
744
|
});
|
|
@@ -746,7 +748,7 @@ const response2 = await msgBus.request({
|
|
|
746
748
|
// With timeout
|
|
747
749
|
try {
|
|
748
750
|
const response = await msgBus.request({
|
|
749
|
-
channel: '
|
|
751
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
750
752
|
payload: { a: 5, b: 15 },
|
|
751
753
|
options: {
|
|
752
754
|
timeout: 5000, // Overall timeout
|
|
@@ -760,7 +762,7 @@ try {
|
|
|
760
762
|
|
|
761
763
|
// With separate send and response timeouts
|
|
762
764
|
const response = await msgBus.request({
|
|
763
|
-
channel: '
|
|
765
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
764
766
|
payload: { a: 5, b: 15 },
|
|
765
767
|
options: {
|
|
766
768
|
sendTimeout: 1000, // Timeout for sending the message
|
|
@@ -770,7 +772,7 @@ const response = await msgBus.request({
|
|
|
770
772
|
|
|
771
773
|
// With headers for correlation
|
|
772
774
|
const response = await msgBus.request({
|
|
773
|
-
channel: '
|
|
775
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
774
776
|
payload: { a: 5, b: 15 },
|
|
775
777
|
headers: {
|
|
776
778
|
sourceId: 'component-123',
|
|
@@ -793,17 +795,19 @@ console.log(response.headers.correlationId); // Preserved correlation ID
|
|
|
793
795
|
|
|
794
796
|
4. **Cancellation**: Cancel in-flight requests with `AbortSignal` (see below).
|
|
795
797
|
|
|
796
|
-
#### Cancellation
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
798
|
+
#### Cancellation
|
|
799
|
+
|
|
800
|
+
Request cancellation is cooperative: when `request()` is aborted, the provider callback receives a cancel message (`headers.status === 'canceled'`) so it can stop in-flight work and clean up resources.
|
|
801
|
+
|
|
802
|
+
Cancel an in-flight request by passing an `AbortSignal` via `options.abortSignal`. When aborted, the bus sends a cancel message to the provider and rejects the returned Promise with an `OperationCanceledError`.
|
|
803
|
+
|
|
804
|
+
See [`provide()` -> `Cancellation Handling`](#cancellation-handling) for provider-side handling details.
|
|
801
805
|
|
|
802
806
|
```typescript
|
|
803
807
|
const abortController = new AbortController();
|
|
804
808
|
|
|
805
809
|
const responsePromise = msgBus.request({
|
|
806
|
-
channel: '
|
|
810
|
+
channel: 'API.FETCH_DATA',
|
|
807
811
|
payload: { url: 'https://api.example.com/data' },
|
|
808
812
|
options: {
|
|
809
813
|
abortSignal: abortController.signal,
|
|
@@ -829,7 +833,7 @@ Configure channels to buffer and replay messages for late subscribers.
|
|
|
829
833
|
|
|
830
834
|
```typescript
|
|
831
835
|
const msgBus = createMsgBus<MyBusStruct>({
|
|
832
|
-
'
|
|
836
|
+
'TEST.EVENTS': {
|
|
833
837
|
replayBufferSize: 50, // Keep last 50 messages
|
|
834
838
|
replayWindowTime: 60000, // Keep messages for 60 seconds
|
|
835
839
|
},
|
|
@@ -838,14 +842,14 @@ const msgBus = createMsgBus<MyBusStruct>({
|
|
|
838
842
|
// Send messages
|
|
839
843
|
for (let i = 0; i < 100; i++) {
|
|
840
844
|
await msgBus.send({
|
|
841
|
-
channel: '
|
|
845
|
+
channel: 'TEST.EVENTS',
|
|
842
846
|
payload: `Message ${i}`,
|
|
843
847
|
});
|
|
844
848
|
}
|
|
845
849
|
|
|
846
850
|
// Late subscriber receives last 50 messages
|
|
847
851
|
msgBus.on({
|
|
848
|
-
channel: '
|
|
852
|
+
channel: 'TEST.EVENTS',
|
|
849
853
|
callback: (msg) => {
|
|
850
854
|
console.log('Replayed:', msg.payload);
|
|
851
855
|
},
|
|
@@ -859,7 +863,7 @@ Control message processing rate at both channel and subscription levels.
|
|
|
859
863
|
```typescript
|
|
860
864
|
// Channel-level throttling
|
|
861
865
|
const msgBus = createMsgBus<MyBusStruct>({
|
|
862
|
-
'
|
|
866
|
+
'TEST.UPDATES': {
|
|
863
867
|
throttle: {
|
|
864
868
|
duration: 1000,
|
|
865
869
|
leading: true,
|
|
@@ -870,7 +874,7 @@ const msgBus = createMsgBus<MyBusStruct>({
|
|
|
870
874
|
|
|
871
875
|
// Subscription-level debouncing
|
|
872
876
|
msgBus.on({
|
|
873
|
-
channel: '
|
|
877
|
+
channel: 'TEST.UPDATES',
|
|
874
878
|
callback: (msg) => {
|
|
875
879
|
updateUI(msg.payload);
|
|
876
880
|
},
|
|
@@ -887,7 +891,7 @@ The bus includes built-in error handling and a reserved error channel.
|
|
|
887
891
|
```typescript
|
|
888
892
|
// Subscribe to errors for a specific channel
|
|
889
893
|
msgBus.on({
|
|
890
|
-
channel: '
|
|
894
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
891
895
|
group: 'error',
|
|
892
896
|
callback: (msg) => {
|
|
893
897
|
console.error('Error in ComputeSum:', msg.payload.error);
|
|
@@ -904,7 +908,7 @@ msgBus.on({
|
|
|
904
908
|
|
|
905
909
|
// Errors in providers are automatically caught and routed
|
|
906
910
|
msgBus.provide({
|
|
907
|
-
channel: '
|
|
911
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
908
912
|
callback: (msg) => {
|
|
909
913
|
if (msg.payload.a < 0) {
|
|
910
914
|
throw new Error('Negative numbers not allowed');
|
|
@@ -946,7 +950,7 @@ type MyHeaders = MsgHeaders & {
|
|
|
946
950
|
const msgBus = createMsgBus<MyBusStruct, MyHeaders>();
|
|
947
951
|
|
|
948
952
|
await msgBus.send({
|
|
949
|
-
channel: '
|
|
953
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
950
954
|
payload: { a: 10, b: 20 },
|
|
951
955
|
headers: {
|
|
952
956
|
userId: 'user-123',
|
|
@@ -1119,7 +1123,7 @@ The message bus serves as a solid foundation for the @actdim/dynstruct architect
|
|
|
1119
1123
|
|
|
1120
1124
|
## Further Reading
|
|
1121
1125
|
|
|
1122
|
-
- [GitHub Repository](https://github.com/actdim/msgmesh)
|
|
1123
|
-
- [@actdim/dynstruct Documentation](https://github.com/actdim/dynstruct)
|
|
1124
|
-
- [Type Safety Best Practices](https://www.typescriptlang.org/docs/handbook/2/types-from-types.html)
|
|
1125
|
-
- [Message-Oriented Middleware Patterns](https://www.enterpriseintegrationpatterns.com/)
|
|
1126
|
+
- [GitHub Repository](https://github.com/actdim/msgmesh)
|
|
1127
|
+
- [@actdim/dynstruct Documentation](https://github.com/actdim/dynstruct)
|
|
1128
|
+
- [Type Safety Best Practices](https://www.typescriptlang.org/docs/handbook/2/types-from-types.html)
|
|
1129
|
+
- [Message-Oriented Middleware Patterns](https://www.enterpriseintegrationpatterns.com/)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actdim/msgmesh",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "A type-safe, modular message mesh for scalable async communication in TypeScript",
|
|
5
5
|
"author": "Pavel Borodaev",
|
|
6
6
|
"license": "Proprietary",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
|
-
"@actdim/utico": "^1.1.
|
|
72
|
+
"@actdim/utico": "^1.1.5",
|
|
73
73
|
"rxjs": "^7.8.2",
|
|
74
74
|
"uuid": "^13.0.0"
|
|
75
75
|
},
|