events-ex 2.3.0 → 2.4.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/.babelrc +1 -1
- package/CHANGELOG.md +25 -0
- package/README.cn.md +114 -3
- package/README.md +106 -5
- package/coverage/all-off.js.html +133 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +572 -0
- package/coverage/consts.js.html +154 -0
- package/coverage/default-methods.js.html +2068 -0
- package/coverage/event-emitter.js.html +121 -0
- package/coverage/event.js.html +286 -0
- package/coverage/eventable.js.html +355 -0
- package/coverage/favicon.png +0 -0
- package/coverage/has-listeners.js.html +166 -0
- package/coverage/index.html +281 -0
- package/coverage/lcov-report/all-off.js.html +133 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/consts.js.html +154 -0
- package/coverage/lcov-report/default-methods.js.html +2068 -0
- package/coverage/lcov-report/event-emitter.js.html +121 -0
- package/coverage/lcov-report/event.js.html +286 -0
- package/coverage/lcov-report/eventable.js.html +355 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/has-listeners.js.html +166 -0
- package/coverage/lcov-report/index.html +281 -0
- package/coverage/lcov-report/once-promise.js.html +325 -0
- package/coverage/lcov-report/pipe-async.js.html +385 -0
- package/coverage/lcov-report/pipe.js.html +244 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/unify.js.html +259 -0
- package/coverage/lcov-report/wrap-event-emitter.js.html +223 -0
- package/coverage/lcov.info +1201 -0
- package/coverage/once-promise.js.html +325 -0
- package/coverage/pipe-async.js.html +385 -0
- package/coverage/pipe.js.html +244 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/coverage/unify.js.html +259 -0
- package/coverage/wrap-event-emitter.js.html +223 -0
- package/docs/README.md +106 -5
- package/docs/all-off/functions/allOff.md +1 -1
- package/docs/consts/README.md +4 -0
- package/docs/consts/functions/createAbortError.md +18 -0
- package/docs/consts/variables/RegExpEventSymbol.md +1 -1
- package/docs/consts/variables/states.md +2 -2
- package/docs/default-methods/functions/getEventableMethods.md +34 -18
- package/docs/event/classes/Event.md +23 -13
- package/docs/event-emitter/classes/EventEmitter-1.md +2 -2
- package/docs/event-emitter/classes/EventEmitter.md +28 -28
- package/docs/eventable/functions/eventable.md +1 -1
- package/docs/has-listeners/functions/hasListeners.md +2 -2
- package/docs/index/README.md +12 -0
- package/docs/modules.md +1 -0
- package/docs/once-promise/README.md +17 -0
- package/docs/once-promise/functions/oncePromise.md +60 -0
- package/docs/pipe/functions/pipe.md +3 -3
- package/docs/pipe-async/functions/pipeAsync.md +3 -3
- package/docs/unify/functions/unify.md +1 -1
- package/docs/util/array-remove/functions/remove.md +1 -1
- package/docs/util/object-for-each/functions/forEach.md +1 -1
- package/docs/util/string-pad/functions/pad.md +1 -1
- package/docs/util/to-int/functions/toInt.md +1 -1
- package/docs/util/valid-callable/functions/validCallable.md +1 -1
- package/docs/util/valid-object/functions/validObject.md +1 -1
- package/docs/wrap-event-emitter/functions/wrapEventEmitter.md +3 -3
- package/docs/wrap-event-emitter/variables/methods.md +1 -1
- package/lib/all-off.mjs +16 -0
- package/lib/consts.d.ts +7 -1
- package/lib/consts.js +17 -2
- package/lib/consts.mjs +23 -0
- package/lib/default-methods.d.ts +12 -4
- package/lib/default-methods.js +174 -22
- package/lib/default-methods.mjs +661 -0
- package/lib/event-emitter.mjs +12 -0
- package/lib/event.d.ts +10 -4
- package/lib/event.js +6 -0
- package/lib/event.mjs +67 -0
- package/lib/eventable.d.ts +1 -1
- package/lib/eventable.mjs +90 -0
- package/lib/has-listeners.d.ts +1 -1
- package/lib/has-listeners.mjs +27 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +12 -0
- package/lib/index.mjs +16 -0
- package/lib/once-promise.d.ts +23 -0
- package/lib/once-promise.js +82 -0
- package/lib/once-promise.mjs +80 -0
- package/lib/pipe-async.d.ts +4 -2
- package/lib/pipe-async.js +16 -3
- package/lib/pipe-async.mjs +100 -0
- package/lib/pipe.d.ts +1 -1
- package/lib/pipe.mjs +53 -0
- package/lib/unify.js +1 -1
- package/lib/unify.mjs +58 -0
- package/lib/util/array-remove.mjs +16 -0
- package/lib/util/object-for-each.mjs +20 -0
- package/lib/util/promise-any.mjs +45 -0
- package/lib/util/string-pad.mjs +19 -0
- package/lib/util/to-int.mjs +9 -0
- package/lib/util/valid-callable.mjs +6 -0
- package/lib/util/valid-object.mjs +8 -0
- package/lib/wrap-event-emitter.d.ts +1 -1
- package/lib/wrap-event-emitter.mjs +46 -0
- package/package.json +29 -20
- package/scripts/copy-to-mjs.mjs +79 -0
- package/src/consts.js +10 -0
- package/src/default-methods.js +169 -24
- package/src/event.js +6 -0
- package/src/index.js +1 -0
- package/src/once-promise.js +80 -0
- package/src/pipe-async.js +16 -3
- package/src/unify.js +1 -1
- package/tsconfig.json +2 -1
- package/vitest.config.js +61 -0
- package/.mocharc.yml +0 -3
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for wrap-event-emitter.js</title>
|
|
7
|
+
<meta charset="utf-8" />
|
|
8
|
+
<link rel="stylesheet" href="prettify.css" />
|
|
9
|
+
<link rel="stylesheet" href="base.css" />
|
|
10
|
+
<link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
|
|
11
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
12
|
+
<style type='text/css'>
|
|
13
|
+
.coverage-summary .sorter {
|
|
14
|
+
background-image: url(sort-arrow-sprite.png);
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<div class='wrapper'>
|
|
21
|
+
<div class='pad1'>
|
|
22
|
+
<h1><a href="index.html">All files</a> wrap-event-emitter.js</h1>
|
|
23
|
+
<div class='clearfix'>
|
|
24
|
+
|
|
25
|
+
<div class='fl pad1y space-right2'>
|
|
26
|
+
<span class="strong">100% </span>
|
|
27
|
+
<span class="quiet">Statements</span>
|
|
28
|
+
<span class='fraction'>13/13</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">100% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>6/6</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">100% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>2/2</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<div class='fl pad1y space-right2'>
|
|
47
|
+
<span class="strong">100% </span>
|
|
48
|
+
<span class="quiet">Lines</span>
|
|
49
|
+
<span class='fraction'>13/13</span>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
<p class="quiet">
|
|
55
|
+
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
56
|
+
</p>
|
|
57
|
+
<template id="filterTemplate">
|
|
58
|
+
<div class="quiet">
|
|
59
|
+
Filter:
|
|
60
|
+
<input type="search" id="fileSearch">
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
</div>
|
|
64
|
+
<div class='status-line high'></div>
|
|
65
|
+
<pre><table class="coverage">
|
|
66
|
+
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
67
|
+
<a name='L2'></a><a href='#L2'>2</a>
|
|
68
|
+
<a name='L3'></a><a href='#L3'>3</a>
|
|
69
|
+
<a name='L4'></a><a href='#L4'>4</a>
|
|
70
|
+
<a name='L5'></a><a href='#L5'>5</a>
|
|
71
|
+
<a name='L6'></a><a href='#L6'>6</a>
|
|
72
|
+
<a name='L7'></a><a href='#L7'>7</a>
|
|
73
|
+
<a name='L8'></a><a href='#L8'>8</a>
|
|
74
|
+
<a name='L9'></a><a href='#L9'>9</a>
|
|
75
|
+
<a name='L10'></a><a href='#L10'>10</a>
|
|
76
|
+
<a name='L11'></a><a href='#L11'>11</a>
|
|
77
|
+
<a name='L12'></a><a href='#L12'>12</a>
|
|
78
|
+
<a name='L13'></a><a href='#L13'>13</a>
|
|
79
|
+
<a name='L14'></a><a href='#L14'>14</a>
|
|
80
|
+
<a name='L15'></a><a href='#L15'>15</a>
|
|
81
|
+
<a name='L16'></a><a href='#L16'>16</a>
|
|
82
|
+
<a name='L17'></a><a href='#L17'>17</a>
|
|
83
|
+
<a name='L18'></a><a href='#L18'>18</a>
|
|
84
|
+
<a name='L19'></a><a href='#L19'>19</a>
|
|
85
|
+
<a name='L20'></a><a href='#L20'>20</a>
|
|
86
|
+
<a name='L21'></a><a href='#L21'>21</a>
|
|
87
|
+
<a name='L22'></a><a href='#L22'>22</a>
|
|
88
|
+
<a name='L23'></a><a href='#L23'>23</a>
|
|
89
|
+
<a name='L24'></a><a href='#L24'>24</a>
|
|
90
|
+
<a name='L25'></a><a href='#L25'>25</a>
|
|
91
|
+
<a name='L26'></a><a href='#L26'>26</a>
|
|
92
|
+
<a name='L27'></a><a href='#L27'>27</a>
|
|
93
|
+
<a name='L28'></a><a href='#L28'>28</a>
|
|
94
|
+
<a name='L29'></a><a href='#L29'>29</a>
|
|
95
|
+
<a name='L30'></a><a href='#L30'>30</a>
|
|
96
|
+
<a name='L31'></a><a href='#L31'>31</a>
|
|
97
|
+
<a name='L32'></a><a href='#L32'>32</a>
|
|
98
|
+
<a name='L33'></a><a href='#L33'>33</a>
|
|
99
|
+
<a name='L34'></a><a href='#L34'>34</a>
|
|
100
|
+
<a name='L35'></a><a href='#L35'>35</a>
|
|
101
|
+
<a name='L36'></a><a href='#L36'>36</a>
|
|
102
|
+
<a name='L37'></a><a href='#L37'>37</a>
|
|
103
|
+
<a name='L38'></a><a href='#L38'>38</a>
|
|
104
|
+
<a name='L39'></a><a href='#L39'>39</a>
|
|
105
|
+
<a name='L40'></a><a href='#L40'>40</a>
|
|
106
|
+
<a name='L41'></a><a href='#L41'>41</a>
|
|
107
|
+
<a name='L42'></a><a href='#L42'>42</a>
|
|
108
|
+
<a name='L43'></a><a href='#L43'>43</a>
|
|
109
|
+
<a name='L44'></a><a href='#L44'>44</a>
|
|
110
|
+
<a name='L45'></a><a href='#L45'>45</a>
|
|
111
|
+
<a name='L46'></a><a href='#L46'>46</a>
|
|
112
|
+
<a name='L47'></a><a href='#L47'>47</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
113
|
+
<span class="cline-any cline-neutral"> </span>
|
|
114
|
+
<span class="cline-any cline-neutral"> </span>
|
|
115
|
+
<span class="cline-any cline-yes">33x</span>
|
|
116
|
+
<span class="cline-any cline-yes">33x</span>
|
|
117
|
+
<span class="cline-any cline-neutral"> </span>
|
|
118
|
+
<span class="cline-any cline-yes">33x</span>
|
|
119
|
+
<span class="cline-any cline-neutral"> </span>
|
|
120
|
+
<span class="cline-any cline-neutral"> </span>
|
|
121
|
+
<span class="cline-any cline-neutral"> </span>
|
|
122
|
+
<span class="cline-any cline-neutral"> </span>
|
|
123
|
+
<span class="cline-any cline-yes">33x</span>
|
|
124
|
+
<span class="cline-any cline-neutral"> </span>
|
|
125
|
+
<span class="cline-any cline-neutral"> </span>
|
|
126
|
+
<span class="cline-any cline-neutral"> </span>
|
|
127
|
+
<span class="cline-any cline-neutral"> </span>
|
|
128
|
+
<span class="cline-any cline-neutral"> </span>
|
|
129
|
+
<span class="cline-any cline-neutral"> </span>
|
|
130
|
+
<span class="cline-any cline-neutral"> </span>
|
|
131
|
+
<span class="cline-any cline-neutral"> </span>
|
|
132
|
+
<span class="cline-any cline-neutral"> </span>
|
|
133
|
+
<span class="cline-any cline-neutral"> </span>
|
|
134
|
+
<span class="cline-any cline-neutral"> </span>
|
|
135
|
+
<span class="cline-any cline-yes">33x</span>
|
|
136
|
+
<span class="cline-any cline-yes">33x</span>
|
|
137
|
+
<span class="cline-any cline-yes">396x</span>
|
|
138
|
+
<span class="cline-any cline-neutral"> </span>
|
|
139
|
+
<span class="cline-any cline-neutral"> </span>
|
|
140
|
+
<span class="cline-any cline-yes">33x</span>
|
|
141
|
+
<span class="cline-any cline-neutral"> </span>
|
|
142
|
+
<span class="cline-any cline-neutral"> </span>
|
|
143
|
+
<span class="cline-any cline-neutral"> </span>
|
|
144
|
+
<span class="cline-any cline-neutral"> </span>
|
|
145
|
+
<span class="cline-any cline-neutral"> </span>
|
|
146
|
+
<span class="cline-any cline-neutral"> </span>
|
|
147
|
+
<span class="cline-any cline-neutral"> </span>
|
|
148
|
+
<span class="cline-any cline-neutral"> </span>
|
|
149
|
+
<span class="cline-any cline-yes">192x</span>
|
|
150
|
+
<span class="cline-any cline-yes">192x</span>
|
|
151
|
+
<span class="cline-any cline-yes">192x</span>
|
|
152
|
+
<span class="cline-any cline-yes">2x</span>
|
|
153
|
+
<span class="cline-any cline-neutral"> </span>
|
|
154
|
+
<span class="cline-any cline-yes">192x</span>
|
|
155
|
+
<span class="cline-any cline-neutral"> </span>
|
|
156
|
+
<span class="cline-any cline-neutral"> </span>
|
|
157
|
+
<span class="cline-any cline-neutral"> </span>
|
|
158
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import {defineProperty} from 'util-ex'
|
|
159
|
+
import eventable from './eventable'
|
|
160
|
+
|
|
161
|
+
const create = Object.create;
|
|
162
|
+
const defineProperties = Object.defineProperties;
|
|
163
|
+
|
|
164
|
+
export const methods = eventable().methods;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Minimal set of core methods to be injected into an existing object.
|
|
168
|
+
*/
|
|
169
|
+
const descriptors = {
|
|
170
|
+
on: { value: methods.on },
|
|
171
|
+
once: { value: methods.once },
|
|
172
|
+
off: { value: methods.off },
|
|
173
|
+
emit: { value: methods.emit },
|
|
174
|
+
emitAsync: { value: methods.emitAsync },
|
|
175
|
+
setEmitterOptions: { value: methods.setEmitterOptions },
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Full set of all available methods from eventable for standalone instances.
|
|
180
|
+
*/
|
|
181
|
+
const fullDescriptors = {};
|
|
182
|
+
Object.keys(methods).forEach(key => {
|
|
183
|
+
fullDescriptors[key] = { value: methods[key] };
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const base = defineProperties({}, fullDescriptors);
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Create or inject the eventable instance into the object
|
|
190
|
+
* @param {Object} [o] the optional instance to eventable
|
|
191
|
+
* @param {Object} [options] optional configuration for the emitter
|
|
192
|
+
* @returns o or new Event instance
|
|
193
|
+
*/
|
|
194
|
+
export function wrapEventEmitter(o, options) {
|
|
195
|
+
const result = o == null ? create(base) : defineProperties(Object(o), descriptors)
|
|
196
|
+
defineProperty(result, '_events', {})
|
|
197
|
+
if (options && options.emitterOptions) {
|
|
198
|
+
result.setEmitterOptions(options.emitterOptions)
|
|
199
|
+
}
|
|
200
|
+
return result
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
export default wrapEventEmitter
|
|
204
|
+
</pre></td></tr></table></pre>
|
|
205
|
+
|
|
206
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
207
|
+
</div><!-- /wrapper -->
|
|
208
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
209
|
+
Code coverage generated by
|
|
210
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
211
|
+
at 2026-07-07T07:31:06.609Z
|
|
212
|
+
</div>
|
|
213
|
+
<script src="prettify.js"></script>
|
|
214
|
+
<script>
|
|
215
|
+
window.onload = function () {
|
|
216
|
+
prettyPrint();
|
|
217
|
+
};
|
|
218
|
+
</script>
|
|
219
|
+
<script src="sorter.js"></script>
|
|
220
|
+
<script src="block-navigation.js"></script>
|
|
221
|
+
</body>
|
|
222
|
+
</html>
|
|
223
|
+
|
package/docs/README.md
CHANGED
|
@@ -18,8 +18,9 @@ Browser-friendly enhanced event emitter [ability][Ability] and class. It's modif
|
|
|
18
18
|
* **Configurable Concurrency**: Choose between **Serial** (default) and **Parallel** execution for async listeners.
|
|
19
19
|
* **Result Aggregation**: Strategies to gather return values: `last` (default), `first` (first success), and `collect` (all results).
|
|
20
20
|
* **Fluent API Proxies**: Use `.parallel()` and `.configure()` for transient, side-effect-free execution context.
|
|
21
|
+
* **AbortSignal Support**: Cancel async event emissions via `configure({ signal })` or `oncePromise` with an `AbortSignal`.
|
|
21
22
|
* **Architecture**: Rewritten core for improved performance and flexibility while maintaining broad compatibility.
|
|
22
|
-
* **Event Utilities**: Built-in support for `pipe`, `pipeAsync`, `unify`, `allOff`, and `hasListeners`.
|
|
23
|
+
* **Event Utilities**: Built-in support for `pipe`, `pipeAsync`, `oncePromise`, `unify`, `allOff`, and `hasListeners`.
|
|
23
24
|
|
|
24
25
|
### Differences
|
|
25
26
|
|
|
@@ -28,6 +29,7 @@ Browser-friendly enhanced event emitter [ability][Ability] and class. It's modif
|
|
|
28
29
|
+ the `event object` as listener's "this" object:
|
|
29
30
|
* `result`: If set, the result is returned to the `Event Emitter`.
|
|
30
31
|
* `stopped`: If set to `true`, it prevents the remaining listeners from being executed.
|
|
32
|
+
* `aborted`: (Async only) `true` if the emission was cancelled by an `AbortSignal`.
|
|
31
33
|
* `target`: The `Event Emitter` object, which was originally the `this` object.
|
|
32
34
|
* `type`: triggered event type(name).
|
|
33
35
|
* `resolved`: (Async only) Indicates if a successful result has been found in `first` mode.
|
|
@@ -43,7 +45,7 @@ Browser-friendly enhanced event emitter [ability][Ability] and class. It's modif
|
|
|
43
45
|
* `collect`: Returns an array of all results in registration order.
|
|
44
46
|
* **Fluent Configuration**: Use `.parallel()` or `.configure({...})` for one-time customized async emits.
|
|
45
47
|
* **Listener APIs**: `on/once(event: string|RegExp, listener, index?: number|'first'|'last')`
|
|
46
|
-
* 📌 **Index Parameter** (Optional): Insertion position in the listener array.
|
|
48
|
+
* 📌 **Index Parameter** (Optional): Insertion position in the listener array.
|
|
47
49
|
* `'first'` (`-Infinity`): Stays in the **Head** zone. The first listener added as `'first'` is placed at the very front.
|
|
48
50
|
* `'last'` (`Infinity`): Stays in the **Tail** zone. The first listener added as `'last'` will always remain at the absolute end.
|
|
49
51
|
* `number`: Relative index within the **Body** zone.
|
|
@@ -63,7 +65,7 @@ Browser-friendly enhanced event emitter [ability][Ability] and class. It's modif
|
|
|
63
65
|
* `pipeAsync(source, target, options)`: Async forwarding with configurable concurrency and aggregation.
|
|
64
66
|
* `unify(emitter1, emitter2)`: Bi-directional synchronization.
|
|
65
67
|
|
|
66
|
-
Note:
|
|
68
|
+
Note: A listener's throw error does not break the notification flow—caught errors are collected and then re-emitted as an `'error'` event after all listeners run. **Exception**: If the error is thrown inside an `'error'` event listener itself, it propagates directly as a thrown exception (sync) or a rejected promise (async), preventing infinite recursion / stack overflow. This applies to both `emit()` and `emitAsync()`.
|
|
67
69
|
|
|
68
70
|
### Installation
|
|
69
71
|
|
|
@@ -174,6 +176,44 @@ const allResults = await ee.parallel('collect').emitAsync('task');
|
|
|
174
176
|
const firstResult = await ee.parallel('first').emitAsync('task');
|
|
175
177
|
```
|
|
176
178
|
|
|
179
|
+
#### AbortSignal Support (Async Only)
|
|
180
|
+
|
|
181
|
+
Cancel async event emissions using the standard `AbortSignal` via `configure({ signal })` or `oncePromise` options.
|
|
182
|
+
|
|
183
|
+
```js
|
|
184
|
+
const emitter = new EventEmitter();
|
|
185
|
+
const controller = new AbortController();
|
|
186
|
+
|
|
187
|
+
emitter.on('task', async () => {
|
|
188
|
+
await sleep(500);
|
|
189
|
+
return 'done';
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// emitAsync: pass signal via configure
|
|
193
|
+
setTimeout(() => controller.abort(), 200); // cancel after 200ms
|
|
194
|
+
try {
|
|
195
|
+
await emitter.configure({ signal: controller.signal }).emitAsync('task');
|
|
196
|
+
} catch (err) {
|
|
197
|
+
console.log(err.name); // 'AbortError'
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// oncePromise: pass signal directly via options
|
|
201
|
+
const c2 = new AbortController();
|
|
202
|
+
setTimeout(() => c2.abort(), 100);
|
|
203
|
+
try {
|
|
204
|
+
await oncePromise(emitter, 'ready', { signal: c2.signal });
|
|
205
|
+
} catch (err) {
|
|
206
|
+
console.log(err.name); // 'AbortError'
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Behavior**:
|
|
211
|
+
|
|
212
|
+
- **Serial mode**: Checks `signal.aborted` before each listener, throws `AbortError` immediately when triggered. When `raiseError` is explicitly set (`true`/`false`/`null`), uses `Promise.race` to interrupt an actively running listener as well.
|
|
213
|
+
- **Parallel mode**: Races listener execution against the signal via `Promise.race`. Throws `AbortError` when the signal wins.
|
|
214
|
+
- **pipeAsync**: In serial mode, checks the source's signal before forwarding to each pipe target; skips remaining targets if aborted.
|
|
215
|
+
- `Event` objects have an `aborted` field (independent of `stopped`) to track cancellation state.
|
|
216
|
+
|
|
177
217
|
### Advanced Features
|
|
178
218
|
|
|
179
219
|
#### Async Concurrency Engine (For `emitAsync` Only)
|
|
@@ -185,6 +225,11 @@ const firstResult = await ee.parallel('first').emitAsync('task');
|
|
|
185
225
|
| **`resultMode`** | `'last'` | **(Default)** Returns the result of the last listener (or last to finish). |
|
|
186
226
|
| | `'first'` | Returns the first **non-undefined** and **successful** result. Skips errors. |
|
|
187
227
|
| | `'collect'` | Returns an array of all results in registration order. |
|
|
228
|
+
| **`signal`** | `AbortSignal` | An `AbortSignal` from an `AbortController` to cancel async event emission. Only passed via `configure()`, not stored on the instance. |
|
|
229
|
+
| **`raiseError`** | `true` | Throws all listener errors immediately. Parallel mode aggregates multiple errors into an `AggregateError`. |
|
|
230
|
+
| | `false` | Silently swallows listener errors. Used with `signal` to interrupt an executing listener in serial mode (added `Promise.race`). |
|
|
231
|
+
| | `null` | **(Default for sync `emit`)** For `'error'` events only: throws if there are no error listeners (Node.js default behavior). |
|
|
232
|
+
| | `undefined` | **(Default)** Same as `false` for `emitAsync`. Keeps existing behavior unchanged. |
|
|
188
233
|
|
|
189
234
|
#### Proxy Isolation (Fluent API)
|
|
190
235
|
|
|
@@ -252,11 +297,67 @@ hasListeners(emitter, 'foo'); // true
|
|
|
252
297
|
Creates an asynchronous pipeline.
|
|
253
298
|
|
|
254
299
|
- `options.asyncMode`: Propagation mode (`'serial' | 'parallel'`).
|
|
255
|
-
- `options.resultMode`: Aggregation strategy.
|
|
300
|
+
- `options.resultMode`: Aggregation strategy (`'last'` default | `'first'` | `'collect'`).
|
|
301
|
+
|
|
302
|
+
#### oncePromise(emitter, type[, options]) _(events-ex/once-promise)_
|
|
303
|
+
|
|
304
|
+
Returns a `Promise` that resolves with the **Event object** when the specified event is emitted on the given emitter.
|
|
305
|
+
If an `error` event is emitted (and the waiting event is not `error`), the promise rejects.
|
|
306
|
+
If the provided `AbortSignal` is aborted, the promise rejects with an `AbortError`.
|
|
307
|
+
|
|
308
|
+
- `emitter` _(EventEmitter)_: The event emitter to listen on.
|
|
309
|
+
- `type` _(string | RegExp)_: The event type to wait for. Supports regex for matching multiple events.
|
|
310
|
+
- `options` _(Object)_: Optional configuration.
|
|
311
|
+
- `signal` _(AbortSignal)_: An AbortSignal to cancel the wait.
|
|
312
|
+
- `raiseError` _(boolean|null)_: Controls behavior when an `'error'` event is emitted on the emitter.
|
|
313
|
+
- `true` / `undefined` **(default)**: The promise rejects with the error.
|
|
314
|
+
- `false`: The promise resolves with the error object instead of rejecting.
|
|
315
|
+
- Returns: `Promise<Event>` — resolves with the Event object, which provides `type`, `target`, etc.
|
|
316
|
+
|
|
317
|
+
> Note: The resolved Event object's `result` field may not be the final value if other listeners have not yet run. For the definitive emit return value, use `emit()` or `emitAsync()` directly.
|
|
318
|
+
|
|
319
|
+
```js
|
|
320
|
+
import {oncePromise, EventEmitter} from 'events-ex';
|
|
321
|
+
|
|
322
|
+
const ee = new EventEmitter();
|
|
323
|
+
|
|
324
|
+
// Wait for a data event
|
|
325
|
+
setTimeout(() => ee.emit('data', { id: 1 }), 100);
|
|
326
|
+
const evt = await oncePromise(ee, 'data');
|
|
327
|
+
console.log(evt.type); // 'data'
|
|
328
|
+
console.log(evt.target); // the emitter
|
|
329
|
+
|
|
330
|
+
// Wait for a regex-matched event – evt.type reveals the actual event
|
|
331
|
+
setTimeout(() => ee.emit('user.login', { name: 'Alice' }), 100);
|
|
332
|
+
const evt2 = await oncePromise(ee, /^user\./);
|
|
333
|
+
console.log(evt2.type); // 'user.login' (not the regex)
|
|
334
|
+
|
|
335
|
+
// Error handling: rejects on error (unless waiting for 'error')
|
|
336
|
+
try {
|
|
337
|
+
await oncePromise(ee, 'data');
|
|
338
|
+
} catch (err) {
|
|
339
|
+
console.error('Error occurred:', err);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Waiting for 'error' event resolves normally
|
|
343
|
+
ee.emit('error', new Error('expected'));
|
|
344
|
+
await oncePromise(ee, 'error'); // resolves, not rejects
|
|
345
|
+
|
|
346
|
+
// Use AbortSignal for timeout cancellation
|
|
347
|
+
const controller = new AbortController();
|
|
348
|
+
setTimeout(() => controller.abort(), 5000);
|
|
349
|
+
try {
|
|
350
|
+
const evt = await oncePromise(ee, 'response', { signal: controller.signal });
|
|
351
|
+
} catch (err) {
|
|
352
|
+
if (err.name === 'AbortError') {
|
|
353
|
+
console.log('timed out or cancelled');
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
```
|
|
256
357
|
|
|
257
358
|
#### setEmitterOptions(options)
|
|
258
359
|
|
|
259
|
-
Configures instance-wide defaults for `asyncMode`, `resultMode`, and `
|
|
360
|
+
Configures instance-wide defaults for `asyncMode`, `resultMode`, `maxListeners`, and `raiseError`.
|
|
260
361
|
|
|
261
362
|
[event-emitter]: https://github.com/medikoo/event-emitter
|
|
262
363
|
[Ability]: https://github.com/snowyu/custom-ability.js
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
> **allOff**(`emitter`, `type?`): [`EventEmitter`](../../event-emitter/classes/EventEmitter.md)
|
|
10
10
|
|
|
11
|
-
Defined in: [src/all-off.js:12](https://github.com/snowyu/events-ex.js/blob/
|
|
11
|
+
Defined in: [src/all-off.js:12](https://github.com/snowyu/events-ex.js/blob/1738d9bce8d1eae4826213336afe3c0c8e5fa482/src/all-off.js#L12)
|
|
12
12
|
|
|
13
13
|
Removes all listeners for a specific event or all events from an event emitter.
|
|
14
14
|
|
package/docs/consts/README.md
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[**events-ex**](../../README.md)
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
[events-ex](../../modules.md) / [consts](../README.md) / createAbortError
|
|
6
|
+
|
|
7
|
+
# Function: createAbortError()
|
|
8
|
+
|
|
9
|
+
> **createAbortError**(): `Error`
|
|
10
|
+
|
|
11
|
+
Defined in: [src/consts.js:21](https://github.com/snowyu/events-ex.js/blob/1738d9bce8d1eae4826213336afe3c0c8e5fa482/src/consts.js#L21)
|
|
12
|
+
|
|
13
|
+
Creates an AbortError with name 'AbortError'.
|
|
14
|
+
Ensures a fresh Error instance each call for proper stack traces.
|
|
15
|
+
|
|
16
|
+
## Returns
|
|
17
|
+
|
|
18
|
+
`Error`
|
|
@@ -8,4 +8,4 @@
|
|
|
8
8
|
|
|
9
9
|
> `const` **RegExpEventSymbol**: `symbol` \| `"@@RegExpEvent"`
|
|
10
10
|
|
|
11
|
-
Defined in: [src/consts.js:
|
|
11
|
+
Defined in: [src/consts.js:14](https://github.com/snowyu/events-ex.js/blob/1738d9bce8d1eae4826213336afe3c0c8e5fa482/src/consts.js#L14)
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
> `const` **states**: `object`
|
|
10
10
|
|
|
11
|
-
Defined in: [src/consts.js:6](https://github.com/snowyu/events-ex.js/blob/
|
|
11
|
+
Defined in: [src/consts.js:6](https://github.com/snowyu/events-ex.js/blob/1738d9bce8d1eae4826213336afe3c0c8e5fa482/src/consts.js#L6)
|
|
12
12
|
|
|
13
13
|
## Type Declaration
|
|
14
14
|
|
|
@@ -18,7 +18,7 @@ Defined in: [src/consts.js:6](https://github.com/snowyu/events-ex.js/blob/53cfb5
|
|
|
18
18
|
|
|
19
19
|
### CONTINUE
|
|
20
20
|
|
|
21
|
-
> **CONTINUE**: `
|
|
21
|
+
> **CONTINUE**: `undefined`
|
|
22
22
|
|
|
23
23
|
### DONE
|
|
24
24
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
> **getEventableMethods**(`aClass`): `object`
|
|
10
10
|
|
|
11
|
-
Defined in: [src/default-methods.js:15](https://github.com/snowyu/events-ex.js/blob/
|
|
11
|
+
Defined in: [src/default-methods.js:15](https://github.com/snowyu/events-ex.js/blob/1738d9bce8d1eae4826213336afe3c0c8e5fa482/src/default-methods.js#L15)
|
|
12
12
|
|
|
13
13
|
## Parameters
|
|
14
14
|
|
|
@@ -36,12 +36,28 @@ Configuration options for event emission.
|
|
|
36
36
|
|
|
37
37
|
The mode of asynchronous emission ('serial' or 'parallel').
|
|
38
38
|
|
|
39
|
+
###### raiseError?
|
|
40
|
+
|
|
41
|
+
`boolean` \| `null`
|
|
42
|
+
|
|
43
|
+
Controls error handling behavior:
|
|
44
|
+
- `true`: Always throw listener errors immediately.
|
|
45
|
+
- `false`: Silently swallow listener errors.
|
|
46
|
+
- `null`: Throw only for 'error' events with no error listeners (Node.js default).
|
|
47
|
+
- `undefined` (default): Same as `false` for emitAsync.
|
|
48
|
+
|
|
39
49
|
###### resultMode?
|
|
40
50
|
|
|
41
51
|
`string`
|
|
42
52
|
|
|
43
53
|
The strategy for handling multiple return values ('last', 'first', 'collect').
|
|
44
54
|
|
|
55
|
+
###### signal?
|
|
56
|
+
|
|
57
|
+
`any`
|
|
58
|
+
|
|
59
|
+
An AbortSignal to cancel async event emission.
|
|
60
|
+
|
|
45
61
|
#### Returns
|
|
46
62
|
|
|
47
63
|
[`EventEmitter`](../../event-emitter/classes/EventEmitter.md)
|
|
@@ -130,9 +146,9 @@ Removes a listener function from the specified event type.
|
|
|
130
146
|
|
|
131
147
|
##### type
|
|
132
148
|
|
|
133
|
-
|
|
149
|
+
`string` \| `RegExp`
|
|
134
150
|
|
|
135
|
-
|
|
151
|
+
The event type to remove the listener from.
|
|
136
152
|
|
|
137
153
|
##### listener
|
|
138
154
|
|
|
@@ -160,9 +176,9 @@ Adds a listener function to the specified event type.
|
|
|
160
176
|
|
|
161
177
|
##### type
|
|
162
178
|
|
|
163
|
-
|
|
179
|
+
`string` \| `RegExp`
|
|
164
180
|
|
|
165
|
-
|
|
181
|
+
The event type to listen for.
|
|
166
182
|
|
|
167
183
|
##### listener
|
|
168
184
|
|
|
@@ -172,14 +188,14 @@ The listener function to be called when the event is emitted.
|
|
|
172
188
|
|
|
173
189
|
##### index?
|
|
174
190
|
|
|
175
|
-
|
|
191
|
+
`number` \| `"first"` \| `"last"`
|
|
192
|
+
|
|
193
|
+
The index at which to insert the listener.
|
|
176
194
|
- 'first' or -Infinity: Adds to the "Head" zone. The first listener added as 'first' is placed at the very front.
|
|
177
195
|
- 'last' or Infinity: Adds to the "Tail" zone. The first listener added as 'last' will always be the very last one to execute.
|
|
178
196
|
- number: Inserts at the specified index within the "Body" (normal) zone.
|
|
179
197
|
If not specified, the listener is added to the end of the "Body" zone.
|
|
180
198
|
|
|
181
|
-
`number` | `"first"` | `"last"`
|
|
182
|
-
|
|
183
199
|
#### Returns
|
|
184
200
|
|
|
185
201
|
[`EventEmitter`](../../event-emitter/classes/EventEmitter.md)
|
|
@@ -200,9 +216,9 @@ Adds a one-time listener function to the specified event type.
|
|
|
200
216
|
|
|
201
217
|
##### type
|
|
202
218
|
|
|
203
|
-
|
|
219
|
+
`string` \| `RegExp`
|
|
204
220
|
|
|
205
|
-
|
|
221
|
+
The event type to listen for.
|
|
206
222
|
|
|
207
223
|
##### listener
|
|
208
224
|
|
|
@@ -212,14 +228,14 @@ The listener function to be called once when the event is emitted.
|
|
|
212
228
|
|
|
213
229
|
##### index?
|
|
214
230
|
|
|
231
|
+
`number` \| `"first"` \| `"last"`
|
|
232
|
+
|
|
215
233
|
The index at which to insert the listener.
|
|
216
234
|
- 'first' or -Infinity: Adds to the "Head" zone. The first listener added as 'first' is placed at the very front.
|
|
217
235
|
- 'last' or Infinity: Adds to the "Tail" zone. The first listener added as 'last' will always be the very last one to execute.
|
|
218
236
|
- number: Inserts at the specified index within the "Body" (normal) zone.
|
|
219
237
|
If not specified, the listener is added to the end of the "Body" zone.
|
|
220
238
|
|
|
221
|
-
`number` | `"first"` | `"last"`
|
|
222
|
-
|
|
223
239
|
#### Returns
|
|
224
240
|
|
|
225
241
|
[`EventEmitter`](../../event-emitter/classes/EventEmitter.md)
|
|
@@ -260,9 +276,9 @@ Removes all listener functions from the specified event type.
|
|
|
260
276
|
|
|
261
277
|
##### type
|
|
262
278
|
|
|
263
|
-
|
|
279
|
+
`string` \| `RegExp`
|
|
264
280
|
|
|
265
|
-
|
|
281
|
+
The event type to remove the listener from.
|
|
266
282
|
|
|
267
283
|
#### Returns
|
|
268
284
|
|
|
@@ -284,9 +300,9 @@ Sets the configuration options for the EventEmitter instance.
|
|
|
284
300
|
|
|
285
301
|
##### options
|
|
286
302
|
|
|
287
|
-
`
|
|
303
|
+
`Object`
|
|
288
304
|
|
|
289
|
-
Configuration options for the emitter (e.g., asyncMode, resultMode, maxListeners).
|
|
305
|
+
Configuration options for the emitter (e.g., asyncMode, resultMode, maxListeners, raiseError).
|
|
290
306
|
|
|
291
307
|
#### Returns
|
|
292
308
|
|
|
@@ -296,7 +312,7 @@ The EventEmitter instance for chaining.
|
|
|
296
312
|
|
|
297
313
|
### setMaxListeners()
|
|
298
314
|
|
|
299
|
-
> **setMaxListeners**(`n`): \{ configure(options: \{ asyncMode?: string; resultMode?: string; \}): EventEmitter; parallel(resultMode?: string
|
|
315
|
+
> **setMaxListeners**(`n`): \{ configure(options: \{ asyncMode?: string \| undefined; resultMode?: string \| undefined; signal?: any; raiseError?: boolean \| null \| undefined; \}): EventEmitter; parallel(resultMode?: string \| undefined): EventEmitter; ... 9 more ...; removeAllListeners(type: string \| RegExp): EventEmitter; \}
|
|
300
316
|
|
|
301
317
|
#### Parameters
|
|
302
318
|
|
|
@@ -306,4 +322,4 @@ The EventEmitter instance for chaining.
|
|
|
306
322
|
|
|
307
323
|
#### Returns
|
|
308
324
|
|
|
309
|
-
\{ configure(options: \{ asyncMode?: string; resultMode?: string; \}): EventEmitter; parallel(resultMode?: string
|
|
325
|
+
\{ configure(options: \{ asyncMode?: string \| undefined; resultMode?: string \| undefined; signal?: any; raiseError?: boolean \| null \| undefined; \}): EventEmitter; parallel(resultMode?: string \| undefined): EventEmitter; ... 9 more ...; removeAllListeners(type: string \| RegExp): EventEmitter; \}
|