@actdim/msgmesh 1.3.2 → 1.3.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 +74 -68
- package/package.json +1 -1
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,11 +45,15 @@ 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
|
-
```
|
|
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
|
+
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.
|
|
55
|
+
|
|
56
|
+
See [`provide()` -> `Cancellation Handling`](#cancellation-handling) and [`request()` -> `Cancellation`](#cancellation).
|
|
51
57
|
|
|
52
58
|
## Installation
|
|
53
59
|
|
|
@@ -193,19 +199,19 @@ Use generic `MsgStruct<...>` to define bus structures: it extends your declared
|
|
|
193
199
|
import { MsgStruct } from '@actdim/msgmesh';
|
|
194
200
|
|
|
195
201
|
export type MyBusStruct = MsgStruct<{
|
|
196
|
-
'
|
|
202
|
+
'TEST.COMPUTE_SUM': {
|
|
197
203
|
in: { a: number; b: number };
|
|
198
204
|
out: number;
|
|
199
205
|
};
|
|
200
|
-
'
|
|
206
|
+
'TEST.DO_SOME_WORK': {
|
|
201
207
|
in: string;
|
|
202
208
|
out: void;
|
|
203
209
|
};
|
|
204
|
-
'
|
|
210
|
+
'TEST.TEST_TASK_WITH_REPEAT': {
|
|
205
211
|
in: string;
|
|
206
212
|
out: void;
|
|
207
213
|
};
|
|
208
|
-
'
|
|
214
|
+
'TEST.MULTIPLEXER': {
|
|
209
215
|
in1: string;
|
|
210
216
|
in2: number;
|
|
211
217
|
out: number;
|
|
@@ -274,7 +280,7 @@ type MyMsgChannels<TChannel extends keyof MyBusStruct | Array<keyof MyBusStruct>
|
|
|
274
280
|
// Helper types are necessary for IntelliSense with dynamic types
|
|
275
281
|
// All API checks are enforced at compile time - you cannot violate defined contracts
|
|
276
282
|
type Behavior = {
|
|
277
|
-
messages: MyMsgChannels<'
|
|
283
|
+
messages: MyMsgChannels<'TEST.COMPUTE_SUM' | 'TEST.DO_SOME_WORK'>;
|
|
278
284
|
};
|
|
279
285
|
```
|
|
280
286
|
|
|
@@ -297,7 +303,7 @@ You can configure channels with various options:
|
|
|
297
303
|
import { MsgBusConfig } from '@actdim/msgmesh';
|
|
298
304
|
|
|
299
305
|
const config: MsgBusConfig<MyBusStruct> = {
|
|
300
|
-
'
|
|
306
|
+
'TEST.COMPUTE_SUM': {
|
|
301
307
|
replayBufferSize: 10, // Number of messages to buffer for replay
|
|
302
308
|
replayWindowTime: 5000, // Time window for replay (ms)
|
|
303
309
|
delay: 100, // Delay before processing (ms)
|
|
@@ -321,33 +327,33 @@ Send a message to the bus for a specific channel and group (default is `in`). Th
|
|
|
321
327
|
```typescript
|
|
322
328
|
// Basic send
|
|
323
329
|
await msgBus.send({
|
|
324
|
-
channel: '
|
|
330
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
325
331
|
payload: { a: 10, b: 20 }, // Typed and validated
|
|
326
332
|
});
|
|
327
333
|
|
|
328
334
|
// With group specification
|
|
329
335
|
await msgBus.send({
|
|
330
|
-
channel: '
|
|
336
|
+
channel: 'TEST.MULTIPLEXER',
|
|
331
337
|
group: 'in1',
|
|
332
338
|
payload: 'hello', // Typed as string for 'in1' group
|
|
333
339
|
});
|
|
334
340
|
|
|
335
341
|
await msgBus.send({
|
|
336
|
-
channel: '
|
|
342
|
+
channel: 'TEST.MULTIPLEXER',
|
|
337
343
|
group: 'in2',
|
|
338
344
|
payload: 42, // Typed as number for 'in2' group
|
|
339
345
|
});
|
|
340
346
|
|
|
341
347
|
// With topic
|
|
342
348
|
await msgBus.send({
|
|
343
|
-
channel: '
|
|
349
|
+
channel: 'TEST.DO_SOME_WORK',
|
|
344
350
|
topic: 'priority-high',
|
|
345
351
|
payload: 'urgent task',
|
|
346
352
|
});
|
|
347
353
|
|
|
348
354
|
// With custom headers
|
|
349
355
|
await msgBus.send({
|
|
350
|
-
channel: '
|
|
356
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
351
357
|
payload: { a: 5, b: 15 },
|
|
352
358
|
headers: {
|
|
353
359
|
correlationId: 'task-123',
|
|
@@ -365,7 +371,7 @@ Subscribe to messages on a specific channel and group with optional topic filter
|
|
|
365
371
|
```typescript
|
|
366
372
|
// Basic subscription
|
|
367
373
|
msgBus.on({
|
|
368
|
-
channel: '
|
|
374
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
369
375
|
callback: (msg) => {
|
|
370
376
|
// msg.payload is typed as { a: number; b: number }
|
|
371
377
|
console.log('Received:', msg.payload);
|
|
@@ -374,7 +380,7 @@ msgBus.on({
|
|
|
374
380
|
|
|
375
381
|
// Subscribe to specific group
|
|
376
382
|
msgBus.on({
|
|
377
|
-
channel: '
|
|
383
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
378
384
|
group: 'out', // Listen for responses
|
|
379
385
|
callback: (msg) => {
|
|
380
386
|
// msg.payload is typed as number
|
|
@@ -384,7 +390,7 @@ msgBus.on({
|
|
|
384
390
|
|
|
385
391
|
// With topic filtering (regex pattern)
|
|
386
392
|
msgBus.on({
|
|
387
|
-
channel: '
|
|
393
|
+
channel: 'TEST.DO_SOME_WORK',
|
|
388
394
|
topic: '/^task-.*/', // Match topics starting with "task-"
|
|
389
395
|
callback: (msg) => {
|
|
390
396
|
console.log('Task message:', msg.payload);
|
|
@@ -393,7 +399,7 @@ msgBus.on({
|
|
|
393
399
|
|
|
394
400
|
// With options
|
|
395
401
|
msgBus.on({
|
|
396
|
-
channel: '
|
|
402
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
397
403
|
callback: (msg) => {
|
|
398
404
|
console.log('Message:', msg.payload);
|
|
399
405
|
},
|
|
@@ -415,7 +421,7 @@ msgBus.on({
|
|
|
415
421
|
|
|
416
422
|
```typescript
|
|
417
423
|
msgBus.on({
|
|
418
|
-
channel: '
|
|
424
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
419
425
|
callback: (msg) => {
|
|
420
426
|
console.log(msg.payload);
|
|
421
427
|
},
|
|
@@ -433,7 +439,7 @@ Use `AbortSignal` for controlled unsubscription. This allows combining abort sig
|
|
|
433
439
|
const abortController = new AbortController();
|
|
434
440
|
|
|
435
441
|
msgBus.on({
|
|
436
|
-
channel: "
|
|
442
|
+
channel: "TEST.COMPUTE_SUM",
|
|
437
443
|
callback: (msg) => {
|
|
438
444
|
console.log(msg.payload);
|
|
439
445
|
},
|
|
@@ -455,7 +461,7 @@ const combinedSignal = AbortSignal.any([
|
|
|
455
461
|
]);
|
|
456
462
|
|
|
457
463
|
msgBus.on({
|
|
458
|
-
channel: "
|
|
464
|
+
channel: "TEST.COMPUTE_SUM",
|
|
459
465
|
options: {
|
|
460
466
|
abortSignal: combinedSignal
|
|
461
467
|
},
|
|
@@ -472,7 +478,7 @@ function MyComponent() {
|
|
|
472
478
|
const controller = new AbortController();
|
|
473
479
|
|
|
474
480
|
msgBus.on({
|
|
475
|
-
channel: "
|
|
481
|
+
channel: "TEST.EVENTS",
|
|
476
482
|
callback: handleEvent,
|
|
477
483
|
options: {
|
|
478
484
|
abortSignal: controller.signal
|
|
@@ -496,14 +502,14 @@ Subscribe and await the first (next) message on a specific channel and group, si
|
|
|
496
502
|
```typescript
|
|
497
503
|
// Wait for one message
|
|
498
504
|
const msg = await msgBus.once({
|
|
499
|
-
channel: '
|
|
505
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
500
506
|
});
|
|
501
507
|
|
|
502
508
|
console.log('Received:', msg.payload); // Typed as { a: number; b: number }
|
|
503
509
|
|
|
504
510
|
// With group specification
|
|
505
511
|
const response = await msgBus.once({
|
|
506
|
-
channel: '
|
|
512
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
507
513
|
group: 'out',
|
|
508
514
|
});
|
|
509
515
|
|
|
@@ -511,7 +517,7 @@ console.log('Result:', response.payload); // Typed as number
|
|
|
511
517
|
|
|
512
518
|
// With topic filtering
|
|
513
519
|
const taskMsg = await msgBus.once({
|
|
514
|
-
channel: '
|
|
520
|
+
channel: 'TEST.DO_SOME_WORK',
|
|
515
521
|
topic: '/^priority-.*/', // Match topics starting with "priority-"
|
|
516
522
|
});
|
|
517
523
|
```
|
|
@@ -523,7 +529,7 @@ Configure timeout duration via the `timeout` option. The `abortSignal` option al
|
|
|
523
529
|
```typescript
|
|
524
530
|
try {
|
|
525
531
|
const msg = await msgBus.once({
|
|
526
|
-
channel: '
|
|
532
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
527
533
|
options: {
|
|
528
534
|
timeout: 5000, // 5 second timeout
|
|
529
535
|
},
|
|
@@ -539,7 +545,7 @@ try {
|
|
|
539
545
|
const abortController = new AbortController();
|
|
540
546
|
|
|
541
547
|
const messagePromise = msgBus.once({
|
|
542
|
-
channel: '
|
|
548
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
543
549
|
options: {
|
|
544
550
|
timeout: 10000,
|
|
545
551
|
abortSignal: abortController.signal,
|
|
@@ -565,7 +571,7 @@ Create an async iterable iterator for consuming messages as a stream.
|
|
|
565
571
|
```typescript
|
|
566
572
|
// Basic streaming
|
|
567
573
|
const messageStream = msgBus.stream({
|
|
568
|
-
channel: '
|
|
574
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
569
575
|
});
|
|
570
576
|
|
|
571
577
|
for await (const msg of messageStream) {
|
|
@@ -575,7 +581,7 @@ for await (const msg of messageStream) {
|
|
|
575
581
|
|
|
576
582
|
// With topic filtering
|
|
577
583
|
const taskStream = msgBus.stream({
|
|
578
|
-
channel: '
|
|
584
|
+
channel: 'TEST.DO_SOME_WORK',
|
|
579
585
|
topic: '/^task-.*/',
|
|
580
586
|
});
|
|
581
587
|
|
|
@@ -593,7 +599,7 @@ For a hard time limit on the stream's total duration, use `AbortSignal.timeout()
|
|
|
593
599
|
```typescript
|
|
594
600
|
// Inactivity timeout: end stream if no messages for 5s
|
|
595
601
|
const stream1 = msgBus.stream({
|
|
596
|
-
channel: '
|
|
602
|
+
channel: 'TEST.EVENTS',
|
|
597
603
|
options: {
|
|
598
604
|
timeout: 5000,
|
|
599
605
|
},
|
|
@@ -601,7 +607,7 @@ const stream1 = msgBus.stream({
|
|
|
601
607
|
|
|
602
608
|
// Total duration limit: end stream after 60s regardless of activity
|
|
603
609
|
const stream2 = msgBus.stream({
|
|
604
|
-
channel: '
|
|
610
|
+
channel: 'TEST.EVENTS',
|
|
605
611
|
options: {
|
|
606
612
|
abortSignal: AbortSignal.timeout(60000),
|
|
607
613
|
},
|
|
@@ -609,7 +615,7 @@ const stream2 = msgBus.stream({
|
|
|
609
615
|
|
|
610
616
|
// Both: inactivity 5s + hard limit 60s
|
|
611
617
|
const stream3 = msgBus.stream({
|
|
612
|
-
channel: '
|
|
618
|
+
channel: 'TEST.EVENTS',
|
|
613
619
|
options: {
|
|
614
620
|
timeout: 5000,
|
|
615
621
|
abortSignal: AbortSignal.timeout(60000),
|
|
@@ -626,7 +632,7 @@ The callback can be asynchronous and its result is automatically used to form th
|
|
|
626
632
|
```typescript
|
|
627
633
|
// Simple provider
|
|
628
634
|
msgBus.provide({
|
|
629
|
-
channel: '
|
|
635
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
630
636
|
callback: (msg) => {
|
|
631
637
|
// msg.payload is typed as { a: number; b: number }
|
|
632
638
|
// Return type is inferred as number (from 'out' type)
|
|
@@ -636,7 +642,7 @@ msgBus.provide({
|
|
|
636
642
|
|
|
637
643
|
// Async provider
|
|
638
644
|
msgBus.provide({
|
|
639
|
-
channel: '
|
|
645
|
+
channel: 'TEST.DO_SOME_WORK',
|
|
640
646
|
callback: async (msg) => {
|
|
641
647
|
// msg.payload is typed as string
|
|
642
648
|
await performWork(msg.payload);
|
|
@@ -646,7 +652,7 @@ msgBus.provide({
|
|
|
646
652
|
|
|
647
653
|
// With topic filtering
|
|
648
654
|
msgBus.provide({
|
|
649
|
-
channel: '
|
|
655
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
650
656
|
topic: '/^calc-.*/',
|
|
651
657
|
callback: (msg) => {
|
|
652
658
|
return msg.payload.a + msg.payload.b;
|
|
@@ -655,7 +661,7 @@ msgBus.provide({
|
|
|
655
661
|
|
|
656
662
|
// With options
|
|
657
663
|
msgBus.provide({
|
|
658
|
-
channel: '
|
|
664
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
659
665
|
callback: (msg) => {
|
|
660
666
|
return msg.payload.a + msg.payload.b;
|
|
661
667
|
},
|
|
@@ -674,7 +680,7 @@ For providers that don't need cancellation support, simply check that `headers.s
|
|
|
674
680
|
|
|
675
681
|
```typescript
|
|
676
682
|
msgBus.provide({
|
|
677
|
-
channel: '
|
|
683
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
678
684
|
callback: (msg, headers) => {
|
|
679
685
|
if (headers.status !== 'ok') return;
|
|
680
686
|
return msg.payload.a + msg.payload.b;
|
|
@@ -688,7 +694,7 @@ For providers with long-running or cancelable operations (e.g. `fetch`), track a
|
|
|
688
694
|
const activeRequests = new Map<string, AbortController>();
|
|
689
695
|
|
|
690
696
|
msgBus.provide({
|
|
691
|
-
channel: '
|
|
697
|
+
channel: 'API.FETCH_DATA',
|
|
692
698
|
callback: async (msg, headers) => {
|
|
693
699
|
const { requestId } = headers;
|
|
694
700
|
|
|
@@ -722,7 +728,7 @@ Send a message and automatically await a response from a handler (registered via
|
|
|
722
728
|
```typescript
|
|
723
729
|
// Basic request
|
|
724
730
|
const response = await msgBus.request({
|
|
725
|
-
channel: '
|
|
731
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
726
732
|
payload: { a: 10, b: 20 },
|
|
727
733
|
});
|
|
728
734
|
|
|
@@ -730,13 +736,13 @@ console.log('Result:', response.payload); // Typed as number
|
|
|
730
736
|
|
|
731
737
|
// With group overloading (using different input groups)
|
|
732
738
|
const response1 = await msgBus.request({
|
|
733
|
-
channel: '
|
|
739
|
+
channel: 'TEST.MULTIPLEXER',
|
|
734
740
|
group: 'in1',
|
|
735
741
|
payload: 'hello',
|
|
736
742
|
});
|
|
737
743
|
|
|
738
744
|
const response2 = await msgBus.request({
|
|
739
|
-
channel: '
|
|
745
|
+
channel: 'TEST.MULTIPLEXER',
|
|
740
746
|
group: 'in2',
|
|
741
747
|
payload: 42,
|
|
742
748
|
});
|
|
@@ -746,7 +752,7 @@ const response2 = await msgBus.request({
|
|
|
746
752
|
// With timeout
|
|
747
753
|
try {
|
|
748
754
|
const response = await msgBus.request({
|
|
749
|
-
channel: '
|
|
755
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
750
756
|
payload: { a: 5, b: 15 },
|
|
751
757
|
options: {
|
|
752
758
|
timeout: 5000, // Overall timeout
|
|
@@ -760,7 +766,7 @@ try {
|
|
|
760
766
|
|
|
761
767
|
// With separate send and response timeouts
|
|
762
768
|
const response = await msgBus.request({
|
|
763
|
-
channel: '
|
|
769
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
764
770
|
payload: { a: 5, b: 15 },
|
|
765
771
|
options: {
|
|
766
772
|
sendTimeout: 1000, // Timeout for sending the message
|
|
@@ -770,7 +776,7 @@ const response = await msgBus.request({
|
|
|
770
776
|
|
|
771
777
|
// With headers for correlation
|
|
772
778
|
const response = await msgBus.request({
|
|
773
|
-
channel: '
|
|
779
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
774
780
|
payload: { a: 5, b: 15 },
|
|
775
781
|
headers: {
|
|
776
782
|
sourceId: 'component-123',
|
|
@@ -803,7 +809,7 @@ On the provider side, the cancel message is delivered to the callback so it can
|
|
|
803
809
|
const abortController = new AbortController();
|
|
804
810
|
|
|
805
811
|
const responsePromise = msgBus.request({
|
|
806
|
-
channel: '
|
|
812
|
+
channel: 'API.FETCH_DATA',
|
|
807
813
|
payload: { url: 'https://api.example.com/data' },
|
|
808
814
|
options: {
|
|
809
815
|
abortSignal: abortController.signal,
|
|
@@ -829,7 +835,7 @@ Configure channels to buffer and replay messages for late subscribers.
|
|
|
829
835
|
|
|
830
836
|
```typescript
|
|
831
837
|
const msgBus = createMsgBus<MyBusStruct>({
|
|
832
|
-
'
|
|
838
|
+
'TEST.EVENTS': {
|
|
833
839
|
replayBufferSize: 50, // Keep last 50 messages
|
|
834
840
|
replayWindowTime: 60000, // Keep messages for 60 seconds
|
|
835
841
|
},
|
|
@@ -838,14 +844,14 @@ const msgBus = createMsgBus<MyBusStruct>({
|
|
|
838
844
|
// Send messages
|
|
839
845
|
for (let i = 0; i < 100; i++) {
|
|
840
846
|
await msgBus.send({
|
|
841
|
-
channel: '
|
|
847
|
+
channel: 'TEST.EVENTS',
|
|
842
848
|
payload: `Message ${i}`,
|
|
843
849
|
});
|
|
844
850
|
}
|
|
845
851
|
|
|
846
852
|
// Late subscriber receives last 50 messages
|
|
847
853
|
msgBus.on({
|
|
848
|
-
channel: '
|
|
854
|
+
channel: 'TEST.EVENTS',
|
|
849
855
|
callback: (msg) => {
|
|
850
856
|
console.log('Replayed:', msg.payload);
|
|
851
857
|
},
|
|
@@ -859,7 +865,7 @@ Control message processing rate at both channel and subscription levels.
|
|
|
859
865
|
```typescript
|
|
860
866
|
// Channel-level throttling
|
|
861
867
|
const msgBus = createMsgBus<MyBusStruct>({
|
|
862
|
-
'
|
|
868
|
+
'TEST.UPDATES': {
|
|
863
869
|
throttle: {
|
|
864
870
|
duration: 1000,
|
|
865
871
|
leading: true,
|
|
@@ -870,7 +876,7 @@ const msgBus = createMsgBus<MyBusStruct>({
|
|
|
870
876
|
|
|
871
877
|
// Subscription-level debouncing
|
|
872
878
|
msgBus.on({
|
|
873
|
-
channel: '
|
|
879
|
+
channel: 'TEST.UPDATES',
|
|
874
880
|
callback: (msg) => {
|
|
875
881
|
updateUI(msg.payload);
|
|
876
882
|
},
|
|
@@ -887,7 +893,7 @@ The bus includes built-in error handling and a reserved error channel.
|
|
|
887
893
|
```typescript
|
|
888
894
|
// Subscribe to errors for a specific channel
|
|
889
895
|
msgBus.on({
|
|
890
|
-
channel: '
|
|
896
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
891
897
|
group: 'error',
|
|
892
898
|
callback: (msg) => {
|
|
893
899
|
console.error('Error in ComputeSum:', msg.payload.error);
|
|
@@ -904,7 +910,7 @@ msgBus.on({
|
|
|
904
910
|
|
|
905
911
|
// Errors in providers are automatically caught and routed
|
|
906
912
|
msgBus.provide({
|
|
907
|
-
channel: '
|
|
913
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
908
914
|
callback: (msg) => {
|
|
909
915
|
if (msg.payload.a < 0) {
|
|
910
916
|
throw new Error('Negative numbers not allowed');
|
|
@@ -946,7 +952,7 @@ type MyHeaders = MsgHeaders & {
|
|
|
946
952
|
const msgBus = createMsgBus<MyBusStruct, MyHeaders>();
|
|
947
953
|
|
|
948
954
|
await msgBus.send({
|
|
949
|
-
channel: '
|
|
955
|
+
channel: 'TEST.COMPUTE_SUM',
|
|
950
956
|
payload: { a: 10, b: 20 },
|
|
951
957
|
headers: {
|
|
952
958
|
userId: 'user-123',
|
|
@@ -1119,7 +1125,7 @@ The message bus serves as a solid foundation for the @actdim/dynstruct architect
|
|
|
1119
1125
|
|
|
1120
1126
|
## Further Reading
|
|
1121
1127
|
|
|
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/)
|
|
1128
|
+
- [GitHub Repository](https://github.com/actdim/msgmesh)
|
|
1129
|
+
- [@actdim/dynstruct Documentation](https://github.com/actdim/dynstruct)
|
|
1130
|
+
- [Type Safety Best Practices](https://www.typescriptlang.org/docs/handbook/2/types-from-types.html)
|
|
1131
|
+
- [Message-Oriented Middleware Patterns](https://www.enterpriseintegrationpatterns.com/)
|