@zudojs/messaging 1.2.0 → 1.2.2
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
|
@@ -117,6 +117,33 @@ that ignores its signal. `handlerResults` still lists every handler that
|
|
|
117
117
|
finished. Before 1.2.0 an abort during the last handler was reported as
|
|
118
118
|
`success: true`.
|
|
119
119
|
|
|
120
|
+
The error's `cause` is the signal's `reason`, so the reason you aborted with
|
|
121
|
+
survives the dispatch:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
const controller = new AbortController();
|
|
125
|
+
bus.on("report", () => {
|
|
126
|
+
controller.abort(new Error("user navigated away"));
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const result = await bus.send(
|
|
130
|
+
{ type: "report", payload: {} },
|
|
131
|
+
{ signal: controller.signal },
|
|
132
|
+
);
|
|
133
|
+
result.error; // MessageDispatchAbortedError
|
|
134
|
+
result.error?.cause; // Error: user navigated away
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
A signal that is already aborted when the dispatch starts rejects the call
|
|
138
|
+
with the same error and the same `cause`. `controller.abort()` without an
|
|
139
|
+
argument gives the platform's default `AbortError` `DOMException` as the
|
|
140
|
+
cause. Before 1.2.2 `cause` was always `undefined`.
|
|
141
|
+
|
|
142
|
+
Cancellation uses only `AbortSignal` and `setTimeout`, so it works in
|
|
143
|
+
browsers and other non-Node runtimes. 1.2.0 scheduled the abort with Node's
|
|
144
|
+
`setImmediate`, and aborting a dispatch in a browser threw
|
|
145
|
+
`ReferenceError: setImmediate is not defined`; later releases do not.
|
|
146
|
+
|
|
120
147
|
## Timeouts
|
|
121
148
|
|
|
122
149
|
`timeout` is honoured by the dispatcher itself, so it applies whether you hold
|
|
@@ -20,7 +20,8 @@ export interface AbortRejection {
|
|
|
20
20
|
* The error a dispatch fails with once `signal` has aborted.
|
|
21
21
|
*
|
|
22
22
|
* A timeout aborts with its own {@link MessageTimeoutError}, which is kept;
|
|
23
|
-
* any other abort is reported as {@link MessageDispatchAbortedError}
|
|
23
|
+
* any other abort is reported as {@link MessageDispatchAbortedError}, whose
|
|
24
|
+
* `cause` is the signal's `reason`.
|
|
24
25
|
*/
|
|
25
26
|
export declare function abortErrorFor(signal: AbortSignal, message: Message): Error;
|
|
26
27
|
/** Throws the dispatch's abort error when `signal` has aborted. */
|
|
@@ -33,6 +34,11 @@ export declare function assertDispatchNotAborted(signal: AbortSignal, message: M
|
|
|
33
34
|
* The rejection waits one macrotask. A handler that aborts and then returns
|
|
34
35
|
* synchronously has its result recorded first, so `handlerResults` still
|
|
35
36
|
* lists every handler that finished.
|
|
37
|
+
*
|
|
38
|
+
* The macrotask is a `setTimeout(…, 0)`, not `setImmediate`: the package is
|
|
39
|
+
* not Node-only, and browsers have no `setImmediate`, so an abort there
|
|
40
|
+
* threw a `ReferenceError`. A microtask would not do — the dispatch records
|
|
41
|
+
* a handler's result several promise hops after the handler returns.
|
|
36
42
|
*/
|
|
37
43
|
export declare function abortRejection(signal: AbortSignal, message: Message): AbortRejection;
|
|
38
44
|
//# sourceMappingURL=dispatcher.abort.d.ts.map
|
|
@@ -13,7 +13,8 @@ import { MessageDispatchAbortedError, MessageTimeoutError, } from "@zudojs/error
|
|
|
13
13
|
* The error a dispatch fails with once `signal` has aborted.
|
|
14
14
|
*
|
|
15
15
|
* A timeout aborts with its own {@link MessageTimeoutError}, which is kept;
|
|
16
|
-
* any other abort is reported as {@link MessageDispatchAbortedError}
|
|
16
|
+
* any other abort is reported as {@link MessageDispatchAbortedError}, whose
|
|
17
|
+
* `cause` is the signal's `reason`.
|
|
17
18
|
*/
|
|
18
19
|
export function abortErrorFor(signal, message) {
|
|
19
20
|
if (signal.reason instanceof MessageTimeoutError)
|
|
@@ -21,6 +22,7 @@ export function abortErrorFor(signal, message) {
|
|
|
21
22
|
return new MessageDispatchAbortedError(undefined, {
|
|
22
23
|
messageType: message.type,
|
|
23
24
|
messageId: message.id,
|
|
25
|
+
cause: signal.reason,
|
|
24
26
|
});
|
|
25
27
|
}
|
|
26
28
|
/** Throws the dispatch's abort error when `signal` has aborted. */
|
|
@@ -36,13 +38,18 @@ export function assertDispatchNotAborted(signal, message) {
|
|
|
36
38
|
* The rejection waits one macrotask. A handler that aborts and then returns
|
|
37
39
|
* synchronously has its result recorded first, so `handlerResults` still
|
|
38
40
|
* lists every handler that finished.
|
|
41
|
+
*
|
|
42
|
+
* The macrotask is a `setTimeout(…, 0)`, not `setImmediate`: the package is
|
|
43
|
+
* not Node-only, and browsers have no `setImmediate`, so an abort there
|
|
44
|
+
* threw a `ReferenceError`. A microtask would not do — the dispatch records
|
|
45
|
+
* a handler's result several promise hops after the handler returns.
|
|
39
46
|
*/
|
|
40
47
|
export function abortRejection(signal, message) {
|
|
41
48
|
let pending;
|
|
42
49
|
let onAbort;
|
|
43
50
|
const promise = new Promise((_resolve, reject) => {
|
|
44
51
|
onAbort = () => {
|
|
45
|
-
pending =
|
|
52
|
+
pending = setTimeout(() => reject(abortErrorFor(signal, message)), 0);
|
|
46
53
|
};
|
|
47
54
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
48
55
|
});
|
|
@@ -55,7 +62,7 @@ export function abortRejection(signal, message) {
|
|
|
55
62
|
if (onAbort)
|
|
56
63
|
signal.removeEventListener("abort", onAbort);
|
|
57
64
|
if (pending !== undefined)
|
|
58
|
-
|
|
65
|
+
clearTimeout(pending);
|
|
59
66
|
},
|
|
60
67
|
};
|
|
61
68
|
}
|
|
@@ -155,8 +155,11 @@ export class DefaultDispatcher {
|
|
|
155
155
|
* timeout can abort the work without the caller losing its own cancellation.
|
|
156
156
|
*/
|
|
157
157
|
resolveSignal(signal, controller) {
|
|
158
|
-
if (signal?.aborted)
|
|
159
|
-
throw new MessageDispatchAbortedError(
|
|
158
|
+
if (signal?.aborted) {
|
|
159
|
+
throw new MessageDispatchAbortedError(undefined, {
|
|
160
|
+
cause: signal.reason,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
160
163
|
if (!signal) {
|
|
161
164
|
return { signal: controller.signal, release: () => { } };
|
|
162
165
|
}
|
|
@@ -176,6 +179,7 @@ export class DefaultDispatcher {
|
|
|
176
179
|
throw new MessageDispatchAbortedError(undefined, {
|
|
177
180
|
messageType: message.type,
|
|
178
181
|
messageId: message.id,
|
|
182
|
+
cause: context.signal.reason,
|
|
179
183
|
});
|
|
180
184
|
}
|
|
181
185
|
const start = performance.now();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zudojs/messaging",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
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,9 +19,9 @@
|
|
|
19
19
|
"!dist/.tsbuildinfo"
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@zudojs/constants": "1.1.
|
|
23
|
-
"@zudojs/errors": "1.3.
|
|
24
|
-
"@zudojs/middleware": "1.1.
|
|
22
|
+
"@zudojs/constants": "1.1.3",
|
|
23
|
+
"@zudojs/errors": "1.3.1",
|
|
24
|
+
"@zudojs/middleware": "1.1.1"
|
|
25
25
|
},
|
|
26
26
|
"engines": {
|
|
27
27
|
"node": ">=24.0.0"
|