@zudojs/messaging 1.0.1 → 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 +6 -0
- package/dist/dispatcher/dispatcherCore.js +12 -3
- package/dist/dispatcher/dispatcherType.type.d.ts +14 -0
- package/dist/messageHandler/messageHandlerType.type.d.ts +7 -2
- package/dist/messageHandler/messageHandlerType.type.js +1 -1
- package/dist/messageMiddleware/messageMiddlewarePipeline.js +4 -28
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
In-process message bus infrastructure with handlers, middleware, and publish/subscribe patterns.
|
|
4
4
|
|
|
5
|
+
<!-- zudo-docs:start -->
|
|
6
|
+
|
|
7
|
+
**Documentation:** [zudojs.oyinlola.site/docs/packages-messaging](https://zudojs.oyinlola.site/docs/packages-messaging) · **For AI agents:** [Markdown version](https://zudojs.oyinlola.site/docs/packages-messaging.md), [llms.txt](https://zudojs.oyinlola.site/llms.txt)
|
|
8
|
+
|
|
9
|
+
<!-- zudo-docs:end -->
|
|
10
|
+
|
|
5
11
|
## Installation
|
|
6
12
|
|
|
7
13
|
```bash
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* @module dispatcher/dispatcherCore
|
|
5
5
|
*/
|
|
6
6
|
import { createMessageContext } from "../messageContext/messageContextType.type.js";
|
|
7
|
+
import { resolveMessageHandler } from "../messageHandler/messageHandlerType.type.js";
|
|
7
8
|
import { HandlerRegistryStore } from "../handlerRegistry/handlerRegistryStore.js";
|
|
8
9
|
import { runMessagePipeline } from "../messageMiddleware/messageMiddlewarePipeline.js";
|
|
9
10
|
import { MessageDispatchAbortedError, MessageHandlerError, MessageMiddlewareError, MessageTimeoutError, MessageBusDisposedError, } from "@zudojs/errors";
|
|
@@ -80,7 +81,11 @@ export class DefaultDispatcher {
|
|
|
80
81
|
value: pipelineResult.result,
|
|
81
82
|
message,
|
|
82
83
|
context,
|
|
83
|
-
|
|
84
|
+
// A copy, not the live array: on a timeout the dispatch settles
|
|
85
|
+
// while a handler is still running, and that handler later pushed
|
|
86
|
+
// a `success: true` record into the result the caller was already
|
|
87
|
+
// holding for a dispatch that had failed.
|
|
88
|
+
handlerResults: [...handlerResults],
|
|
84
89
|
middlewareResult: pipelineResult,
|
|
85
90
|
duration: performance.now() - dispatchStart,
|
|
86
91
|
};
|
|
@@ -91,7 +96,7 @@ export class DefaultDispatcher {
|
|
|
91
96
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
92
97
|
message,
|
|
93
98
|
context,
|
|
94
|
-
handlerResults,
|
|
99
|
+
handlerResults: [...handlerResults],
|
|
95
100
|
duration: performance.now() - dispatchStart,
|
|
96
101
|
};
|
|
97
102
|
}
|
|
@@ -190,7 +195,11 @@ export class DefaultDispatcher {
|
|
|
190
195
|
}
|
|
191
196
|
async executeHandler(handler, message, context) {
|
|
192
197
|
try {
|
|
193
|
-
|
|
198
|
+
// Handlers may be a plain function or an object with a `handle`
|
|
199
|
+
// method. Calling `handler.handler(...)` directly made the object
|
|
200
|
+
// form crash on every dispatch, so it goes through the same
|
|
201
|
+
// normaliser the public type advertises.
|
|
202
|
+
return await resolveMessageHandler(handler.handler)(message, context);
|
|
194
203
|
}
|
|
195
204
|
catch (error) {
|
|
196
205
|
throw new MessageHandlerError(`Handler "${handler.id}" failed: ${error instanceof Error ? error.message : String(error)}`, {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type { Message } from "../message/messageType.type.js";
|
|
10
10
|
import type { MessageContext, MessageContextOptions } from "../messageContext/messageContextType.type.js";
|
|
11
11
|
import type { MessageMiddlewareLike, MessageMiddlewareOptions, MessageMiddlewarePipelineResult } from "../messageMiddleware/messageMiddlewareType.type.js";
|
|
12
|
+
import type { HandlerRegistryStore } from "../handlerRegistry/handlerRegistryStore.js";
|
|
12
13
|
/**
|
|
13
14
|
* Result of dispatching a message.
|
|
14
15
|
*/
|
|
@@ -90,5 +91,18 @@ export interface Dispatcher {
|
|
|
90
91
|
* @returns Whether a registration was removed.
|
|
91
92
|
*/
|
|
92
93
|
removeMiddleware(middlewareId: string): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* The ids of every registered global middleware, in the order they run.
|
|
96
|
+
*/
|
|
97
|
+
listMiddleware(): readonly string[];
|
|
98
|
+
/**
|
|
99
|
+
* The handler registry this dispatcher resolves handlers from.
|
|
100
|
+
*/
|
|
101
|
+
getRegistry(): HandlerRegistryStore;
|
|
102
|
+
/**
|
|
103
|
+
* Releases the dispatcher: drops all middleware and rejects any further
|
|
104
|
+
* dispatch with `MessageBusDisposedError`.
|
|
105
|
+
*/
|
|
106
|
+
dispose(): void;
|
|
93
107
|
}
|
|
94
108
|
//# sourceMappingURL=dispatcherType.type.d.ts.map
|
|
@@ -35,8 +35,13 @@ export interface NamedMessageHandler<TMessage extends Message = Message, TResult
|
|
|
35
35
|
readonly id: string;
|
|
36
36
|
/** Human-readable name for debugging. */
|
|
37
37
|
readonly name: string;
|
|
38
|
-
/**
|
|
39
|
-
|
|
38
|
+
/**
|
|
39
|
+
* The handler itself: a function, or an object with a `handle` method.
|
|
40
|
+
*
|
|
41
|
+
* The dispatcher normalises both forms through
|
|
42
|
+
* {@link resolveMessageHandler} before invoking them.
|
|
43
|
+
*/
|
|
44
|
+
readonly handler: MessageHandlerLike<TMessage, TResult>;
|
|
40
45
|
/** Message types this handler processes. */
|
|
41
46
|
readonly messageTypes: readonly string[];
|
|
42
47
|
/** Execution priority (lower = earlier). Default: 100. */
|
|
@@ -3,32 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module messageMiddleware/messageMiddlewarePipeline
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
* Compose an array of middleware into a single function.
|
|
8
|
-
*
|
|
9
|
-
* The returned function executes middleware in order.
|
|
10
|
-
* If no middleware is provided, the handler is called directly.
|
|
11
|
-
*/
|
|
12
|
-
function compose(middlewareList, handler) {
|
|
13
|
-
if (middlewareList.length === 0) {
|
|
14
|
-
return handler;
|
|
15
|
-
}
|
|
16
|
-
return async (context) => {
|
|
17
|
-
let index = -1;
|
|
18
|
-
async function dispatch(i) {
|
|
19
|
-
if (i <= index) {
|
|
20
|
-
throw new Error("next() called multiple times");
|
|
21
|
-
}
|
|
22
|
-
index = i;
|
|
23
|
-
if (i < middlewareList.length) {
|
|
24
|
-
const mw = middlewareList[i];
|
|
25
|
-
return mw(context, () => dispatch(i + 1));
|
|
26
|
-
}
|
|
27
|
-
return handler(context);
|
|
28
|
-
}
|
|
29
|
-
return dispatch(0);
|
|
30
|
-
};
|
|
31
|
-
}
|
|
6
|
+
import { compose } from "@zudojs/middleware";
|
|
32
7
|
/**
|
|
33
8
|
* Resolves a MessageMiddlewareLike to a plain MessageMiddleware function.
|
|
34
9
|
*/
|
|
@@ -36,7 +11,7 @@ function resolveMiddlewareLike(mw) {
|
|
|
36
11
|
if (typeof mw === "function") {
|
|
37
12
|
return mw;
|
|
38
13
|
}
|
|
39
|
-
return mw.handle;
|
|
14
|
+
return mw.handle.bind(mw);
|
|
40
15
|
}
|
|
41
16
|
/**
|
|
42
17
|
* Runs a handler through a middleware pipeline and returns the
|
|
@@ -78,7 +53,8 @@ export async function runMessagePipeline(middlewareList, handler, message, optio
|
|
|
78
53
|
};
|
|
79
54
|
});
|
|
80
55
|
const pipelineStart = performance.now();
|
|
81
|
-
|
|
56
|
+
// Unbounded depth: the list length is fixed by the registered middleware.
|
|
57
|
+
const composed = compose(resolvedMiddleware, async (ctx) => handler(message, ctx), { maxDepth: Number.POSITIVE_INFINITY });
|
|
82
58
|
const context = {
|
|
83
59
|
message,
|
|
84
60
|
context: options.context ?? {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zudojs/messaging",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "In-process message bus infrastructure with handlers, middleware, and publish/subscribe patterns.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
"!dist/.tsbuildinfo"
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@zudojs/
|
|
23
|
-
"@zudojs/
|
|
22
|
+
"@zudojs/constants": "1.1.1",
|
|
23
|
+
"@zudojs/errors": "1.2.0",
|
|
24
|
+
"@zudojs/middleware": "1.0.3"
|
|
24
25
|
},
|
|
25
26
|
"engines": {
|
|
26
27
|
"node": ">=24.0.0"
|