@kuindji/reactive 1.0.24 → 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 +34 -11
- package/dist/action.d.ts +12 -10
- package/dist/action.js +20 -10
- package/dist/actionBus.d.ts +8 -4
- package/dist/actionBus.js +34 -2
- package/dist/actionMap.d.ts +21 -19
- package/dist/actionMap.js +10 -4
- package/dist/event.d.ts +3 -2
- package/dist/event.js +112 -58
- package/dist/eventBus.d.ts +5 -3
- package/dist/eventBus.js +88 -31
- package/dist/index.d.ts +7 -7
- package/dist/index.js +7 -7
- package/dist/lib/actionMapInternal.d.ts +8 -0
- package/dist/lib/actionMapInternal.js +8 -0
- package/dist/lib/isPromiseLike.d.ts +1 -0
- package/dist/lib/isPromiseLike.js +5 -0
- package/dist/lib/normalizeEventOptions.d.ts +13 -0
- package/dist/lib/normalizeEventOptions.js +21 -0
- package/dist/react/ErrorBoundary.d.ts +1 -1
- package/dist/react/listenerOptionsEqual.d.ts +27 -0
- package/dist/react/listenerOptionsEqual.js +121 -0
- package/dist/react/useAction.d.ts +3 -3
- package/dist/react/useAction.js +10 -7
- package/dist/react/useActionBus.d.ts +4 -4
- package/dist/react/useActionBus.js +32 -2
- package/dist/react/useActionMap.d.ts +4 -4
- package/dist/react/useActionMap.js +40 -7
- package/dist/react/useEvent.d.ts +2 -2
- package/dist/react/useEvent.js +18 -2
- package/dist/react/useEventBus.d.ts +2 -2
- package/dist/react/useEventBus.js +14 -10
- package/dist/react/useListenToAction.d.ts +1 -1
- package/dist/react/useListenToAction.js +17 -38
- package/dist/react/useListenToActionBus.d.ts +3 -3
- package/dist/react/useListenToActionBus.js +15 -9
- package/dist/react/useListenToEvent.d.ts +2 -2
- package/dist/react/useListenToEvent.js +8 -6
- package/dist/react/useListenToEventBus.d.ts +3 -3
- package/dist/react/useListenToEventBus.js +9 -7
- package/dist/react/useListenToStoreChanges.d.ts +3 -3
- package/dist/react/useListenToStoreChanges.js +9 -7
- package/dist/react/useReconciledListener.d.ts +33 -0
- package/dist/react/useReconciledListener.js +44 -0
- package/dist/react/useStore.d.ts +2 -2
- package/dist/react/useStore.js +71 -19
- package/dist/react/useStoreState.d.ts +2 -2
- package/dist/react/useStoreState.js +14 -21
- package/dist/react.d.ts +13 -13
- package/dist/react.js +13 -13
- package/dist/store.d.ts +9 -8
- package/dist/store.js +91 -24
- package/package.json +13 -3
package/dist/event.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import asyncCall from "./lib/asyncCall";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
1
|
+
import asyncCall from "./lib/asyncCall.js";
|
|
2
|
+
import isPromiseLike from "./lib/isPromiseLike.js";
|
|
3
|
+
import listenerSorter from "./lib/listenerSorter.js";
|
|
4
|
+
import tagsIntersect from "./lib/tagsIntersect.js";
|
|
5
|
+
import { TriggerReturnType } from "./lib/types.js";
|
|
5
6
|
export function createEvent(eventOptions = {}) {
|
|
6
7
|
let listeners = [];
|
|
7
8
|
const errorListeners = [];
|
|
@@ -14,10 +15,12 @@ export function createEvent(eventOptions = {}) {
|
|
|
14
15
|
let currentTagsFilter = null;
|
|
15
16
|
const options = Object.assign({ async: null, limit: null, autoTrigger: null, filter: null, filterContext: null, maxListeners: 0 }, eventOptions);
|
|
16
17
|
const addListener = (handler, listenerOptions = {}) => {
|
|
18
|
+
var _a;
|
|
17
19
|
if (!handler) {
|
|
18
20
|
return;
|
|
19
21
|
}
|
|
20
|
-
|
|
22
|
+
const listenerContext = (_a = listenerOptions.context) !== null && _a !== void 0 ? _a : null;
|
|
23
|
+
if (listeners.find((l) => l.handler === handler && l.context === listenerContext)) {
|
|
21
24
|
return;
|
|
22
25
|
}
|
|
23
26
|
if (options.maxListeners && listeners.length >= options.maxListeners) {
|
|
@@ -54,8 +57,12 @@ export function createEvent(eventOptions = {}) {
|
|
|
54
57
|
}
|
|
55
58
|
return false;
|
|
56
59
|
};
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
try {
|
|
61
|
+
_trigger(lastTrigger);
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
options.filter = prevFilter;
|
|
65
|
+
}
|
|
59
66
|
}
|
|
60
67
|
};
|
|
61
68
|
const removeListener = (handler, context, tag) => {
|
|
@@ -80,6 +87,49 @@ export function createEvent(eventOptions = {}) {
|
|
|
80
87
|
listeners.splice(inx, 1);
|
|
81
88
|
return true;
|
|
82
89
|
};
|
|
90
|
+
const updateListenerOptions = (handler, context = null, nextOptions = {}) => {
|
|
91
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
92
|
+
const listenerContext = context !== null && context !== void 0 ? context : null;
|
|
93
|
+
const listener = listeners.find((l) => l.handler === handler && l.context === listenerContext);
|
|
94
|
+
if (!listener) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
const prevAlwaysFirst = listener.alwaysFirst;
|
|
98
|
+
const prevAlwaysLast = listener.alwaysLast;
|
|
99
|
+
// Soft fields, applying the same defaults as addListener so that a
|
|
100
|
+
// removed field resets to its default rather than lingering.
|
|
101
|
+
listener.limit = (_a = nextOptions.limit) !== null && _a !== void 0 ? _a : 0;
|
|
102
|
+
listener.start = (_b = nextOptions.start) !== null && _b !== void 0 ? _b : 1;
|
|
103
|
+
listener.tags = (_c = nextOptions.tags) !== null && _c !== void 0 ? _c : [];
|
|
104
|
+
listener.extraData = (_d = nextOptions.extraData) !== null && _d !== void 0 ? _d : null;
|
|
105
|
+
listener.alwaysFirst = (_e = nextOptions.alwaysFirst) !== null && _e !== void 0 ? _e : false;
|
|
106
|
+
listener.alwaysLast = (_f = nextOptions.alwaysLast) !== null && _f !== void 0 ? _f : false;
|
|
107
|
+
let nextAsync = (_g = nextOptions.async) !== null && _g !== void 0 ? _g : null;
|
|
108
|
+
if (nextAsync === true) {
|
|
109
|
+
nextAsync = 1;
|
|
110
|
+
}
|
|
111
|
+
listener.async = nextAsync;
|
|
112
|
+
// Re-sort if ordering hints changed. Unlike addListener we do NOT
|
|
113
|
+
// rewrite each listener's index here: the existing indices hold the
|
|
114
|
+
// original insertion order, and preserving them lets sorting restore
|
|
115
|
+
// that order when alwaysFirst/alwaysLast is cleared.
|
|
116
|
+
if (listener.alwaysFirst !== prevAlwaysFirst
|
|
117
|
+
|| listener.alwaysLast !== prevAlwaysLast) {
|
|
118
|
+
if (listener.alwaysFirst === true || listener.alwaysLast === true) {
|
|
119
|
+
sortListeners = true;
|
|
120
|
+
}
|
|
121
|
+
if (sortListeners) {
|
|
122
|
+
listeners.sort((l1, l2) => listenerSorter(l1, l2));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// The core auto-remove check is a strict `called === limit`, so a
|
|
126
|
+
// listener whose `called` already exceeds the new limit would never
|
|
127
|
+
// auto-remove. Remove it immediately in that case.
|
|
128
|
+
if (listener.limit !== 0 && listener.called >= listener.limit) {
|
|
129
|
+
removeListener(listener.handler, listener.context);
|
|
130
|
+
}
|
|
131
|
+
return true;
|
|
132
|
+
};
|
|
83
133
|
const hasListener = (handler, context, tag) => {
|
|
84
134
|
if (handler) {
|
|
85
135
|
return (listeners.findIndex((l) => {
|
|
@@ -137,7 +187,7 @@ export function createEvent(eventOptions = {}) {
|
|
|
137
187
|
queued = false;
|
|
138
188
|
if (queue.length > 0) {
|
|
139
189
|
for (let i = 0, l = queue.length; i < l; i++) {
|
|
140
|
-
_trigger(queue[i][0], queue[i][1]);
|
|
190
|
+
_trigger(queue[i][0], queue[i][1], queue[i][2]);
|
|
141
191
|
}
|
|
142
192
|
queue = [];
|
|
143
193
|
}
|
|
@@ -156,7 +206,6 @@ export function createEvent(eventOptions = {}) {
|
|
|
156
206
|
triggered = 0;
|
|
157
207
|
lastTrigger = null;
|
|
158
208
|
sortListeners = false;
|
|
159
|
-
cachedPromise = null;
|
|
160
209
|
};
|
|
161
210
|
const _listenerCall = (listener, args, resolve = null) => {
|
|
162
211
|
let isAsync = listener.async;
|
|
@@ -173,26 +222,29 @@ export function createEvent(eventOptions = {}) {
|
|
|
173
222
|
const result = isAsync !== false
|
|
174
223
|
? asyncCall(listener.handler, listener.context, args, isAsync)
|
|
175
224
|
: listener.handler.bind(listener.context)(...args);
|
|
176
|
-
if (
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
resolve(result);
|
|
225
|
+
if (isPromiseLike(result)) {
|
|
226
|
+
const handledResult = Promise.resolve(result).catch((error) => {
|
|
227
|
+
for (const errorListener of errorListeners) {
|
|
228
|
+
errorListener.handler({
|
|
229
|
+
error: error instanceof Error
|
|
230
|
+
? error
|
|
231
|
+
: new Error(error),
|
|
232
|
+
args: args,
|
|
233
|
+
type: "event",
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
if (errorListeners.length === 0) {
|
|
237
|
+
throw error;
|
|
238
|
+
}
|
|
239
|
+
return undefined;
|
|
240
|
+
});
|
|
241
|
+
if (resolve !== null) {
|
|
242
|
+
void handledResult.then(resolve);
|
|
195
243
|
}
|
|
244
|
+
return handledResult;
|
|
245
|
+
}
|
|
246
|
+
if (resolve !== null) {
|
|
247
|
+
resolve(result);
|
|
196
248
|
}
|
|
197
249
|
return result;
|
|
198
250
|
}
|
|
@@ -236,8 +288,13 @@ export function createEvent(eventOptions = {}) {
|
|
|
236
288
|
return _listenerCall(listener, args);
|
|
237
289
|
};
|
|
238
290
|
const _trigger = (args, returnType = null, tags) => {
|
|
291
|
+
var _a, _b;
|
|
239
292
|
if (queued) {
|
|
240
|
-
queue.push([
|
|
293
|
+
queue.push([
|
|
294
|
+
args,
|
|
295
|
+
returnType,
|
|
296
|
+
(_b = (_a = (tags || currentTagsFilter)) === null || _a === void 0 ? void 0 : _a.slice()) !== null && _b !== void 0 ? _b : null,
|
|
297
|
+
]);
|
|
241
298
|
return;
|
|
242
299
|
}
|
|
243
300
|
if (suspended) {
|
|
@@ -303,9 +360,7 @@ export function createEvent(eventOptions = {}) {
|
|
|
303
360
|
if (isConsequent && results.length > 0) {
|
|
304
361
|
const prev = results[results.length - 1];
|
|
305
362
|
if (hasPromises) {
|
|
306
|
-
const prevPromise = prev
|
|
307
|
-
? prev
|
|
308
|
-
: Promise.resolve(prev);
|
|
363
|
+
const prevPromise = Promise.resolve(prev);
|
|
309
364
|
listenerResult = prevPromise.then(((listener, args, returnType) => (value) => {
|
|
310
365
|
return _listenerCallWPrev(listener, args, value, returnType);
|
|
311
366
|
})(listener, args, returnType));
|
|
@@ -342,7 +397,7 @@ export function createEvent(eventOptions = {}) {
|
|
|
342
397
|
}
|
|
343
398
|
case TriggerReturnType.FIRST_NON_EMPTY: {
|
|
344
399
|
if (!hasPromises
|
|
345
|
-
&& !(listenerResult
|
|
400
|
+
&& !isPromiseLike(listenerResult)
|
|
346
401
|
&& listenerResult !== null
|
|
347
402
|
&& listenerResult !== undefined) {
|
|
348
403
|
return listenerResult;
|
|
@@ -351,7 +406,7 @@ export function createEvent(eventOptions = {}) {
|
|
|
351
406
|
}
|
|
352
407
|
}
|
|
353
408
|
}
|
|
354
|
-
if (!hasPromises && listenerResult
|
|
409
|
+
if (!hasPromises && isPromiseLike(listenerResult)) {
|
|
355
410
|
hasPromises = true;
|
|
356
411
|
}
|
|
357
412
|
results.push(listenerResult);
|
|
@@ -405,33 +460,31 @@ export function createEvent(eventOptions = {}) {
|
|
|
405
460
|
_trigger(args);
|
|
406
461
|
};
|
|
407
462
|
const withTags = (tags, callback) => {
|
|
463
|
+
const prevTagsFilter = currentTagsFilter;
|
|
408
464
|
currentTagsFilter = tags;
|
|
409
465
|
try {
|
|
410
466
|
return callback();
|
|
411
467
|
}
|
|
412
468
|
finally {
|
|
413
|
-
currentTagsFilter =
|
|
469
|
+
currentTagsFilter = prevTagsFilter;
|
|
414
470
|
}
|
|
415
471
|
};
|
|
416
|
-
let cachedPromise = null;
|
|
417
472
|
const promise = (options) => {
|
|
418
|
-
return
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
resolve(args);
|
|
423
|
-
cachedPromise = null;
|
|
424
|
-
});
|
|
425
|
-
addListener(l, options);
|
|
473
|
+
return new Promise((resolve) => {
|
|
474
|
+
options = Object.assign(Object.assign({}, (options || {})), { limit: 1 });
|
|
475
|
+
const l = ((...args) => {
|
|
476
|
+
resolve(args);
|
|
426
477
|
});
|
|
478
|
+
addListener(l, options);
|
|
479
|
+
});
|
|
427
480
|
};
|
|
428
481
|
const first = (...args) => {
|
|
429
482
|
return _trigger(args, TriggerReturnType.FIRST);
|
|
430
483
|
};
|
|
431
484
|
const resolveFirst = (...args) => {
|
|
432
485
|
const response = _trigger(args, TriggerReturnType.FIRST);
|
|
433
|
-
if (response
|
|
434
|
-
return response;
|
|
486
|
+
if (isPromiseLike(response)) {
|
|
487
|
+
return Promise.resolve(response);
|
|
435
488
|
}
|
|
436
489
|
return Promise.resolve(response);
|
|
437
490
|
};
|
|
@@ -440,8 +493,8 @@ export function createEvent(eventOptions = {}) {
|
|
|
440
493
|
};
|
|
441
494
|
const resolveAll = (...args) => {
|
|
442
495
|
const response = _trigger(args, TriggerReturnType.ALL);
|
|
443
|
-
if (response
|
|
444
|
-
return response;
|
|
496
|
+
if (isPromiseLike(response)) {
|
|
497
|
+
return Promise.resolve(response);
|
|
445
498
|
}
|
|
446
499
|
return Promise.resolve(response);
|
|
447
500
|
};
|
|
@@ -450,8 +503,8 @@ export function createEvent(eventOptions = {}) {
|
|
|
450
503
|
};
|
|
451
504
|
const resolveLast = (...args) => {
|
|
452
505
|
const response = _trigger(args, TriggerReturnType.LAST);
|
|
453
|
-
if (response
|
|
454
|
-
return response;
|
|
506
|
+
if (isPromiseLike(response)) {
|
|
507
|
+
return Promise.resolve(response);
|
|
455
508
|
}
|
|
456
509
|
return Promise.resolve(response);
|
|
457
510
|
};
|
|
@@ -460,8 +513,8 @@ export function createEvent(eventOptions = {}) {
|
|
|
460
513
|
};
|
|
461
514
|
const resolveMerge = (...args) => {
|
|
462
515
|
const response = _trigger(args, TriggerReturnType.MERGE);
|
|
463
|
-
if (response
|
|
464
|
-
return response;
|
|
516
|
+
if (isPromiseLike(response)) {
|
|
517
|
+
return Promise.resolve(response);
|
|
465
518
|
}
|
|
466
519
|
return Promise.resolve(response);
|
|
467
520
|
};
|
|
@@ -470,8 +523,8 @@ export function createEvent(eventOptions = {}) {
|
|
|
470
523
|
};
|
|
471
524
|
const resolveConcat = (...args) => {
|
|
472
525
|
const response = _trigger(args, TriggerReturnType.CONCAT);
|
|
473
|
-
if (response
|
|
474
|
-
return response;
|
|
526
|
+
if (isPromiseLike(response)) {
|
|
527
|
+
return Promise.resolve(response);
|
|
475
528
|
}
|
|
476
529
|
return Promise.resolve(response);
|
|
477
530
|
};
|
|
@@ -480,8 +533,8 @@ export function createEvent(eventOptions = {}) {
|
|
|
480
533
|
};
|
|
481
534
|
const resolveFirstNonEmpty = (...args) => {
|
|
482
535
|
const response = _trigger(args, TriggerReturnType.FIRST_NON_EMPTY);
|
|
483
|
-
if (response
|
|
484
|
-
return response;
|
|
536
|
+
if (isPromiseLike(response)) {
|
|
537
|
+
return Promise.resolve(response);
|
|
485
538
|
}
|
|
486
539
|
return Promise.resolve(response);
|
|
487
540
|
};
|
|
@@ -496,8 +549,8 @@ export function createEvent(eventOptions = {}) {
|
|
|
496
549
|
};
|
|
497
550
|
const resolvePipe = (...args) => {
|
|
498
551
|
const response = _trigger(args, TriggerReturnType.PIPE);
|
|
499
|
-
if (response
|
|
500
|
-
return response;
|
|
552
|
+
if (isPromiseLike(response)) {
|
|
553
|
+
return Promise.resolve(response);
|
|
501
554
|
}
|
|
502
555
|
return Promise.resolve(response);
|
|
503
556
|
};
|
|
@@ -513,6 +566,7 @@ export function createEvent(eventOptions = {}) {
|
|
|
513
566
|
/** @alias addListener */
|
|
514
567
|
subscribe: addListener,
|
|
515
568
|
removeListener,
|
|
569
|
+
updateListenerOptions,
|
|
516
570
|
/** @alias removeListener */
|
|
517
571
|
un: removeListener,
|
|
518
572
|
/** @alias removeListener */
|
package/dist/eventBus.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createEvent } from "./event";
|
|
2
|
-
import type { EventDefinitionHelper, EventOptions, ListenerOptions } from "./event";
|
|
3
|
-
import { ApiType, BaseHandler, ErrorListenerSignature, KeyOf, MapKey, ProxyType, TriggerReturnType } from "./lib/types";
|
|
1
|
+
import { createEvent } from "./event.js";
|
|
2
|
+
import type { EventDefinitionHelper, EventOptions, ListenerOptions } from "./event.js";
|
|
3
|
+
import { ApiType, BaseHandler, ErrorListenerSignature, KeyOf, MapKey, ProxyType, TriggerReturnType } from "./lib/types.js";
|
|
4
4
|
type InterceptorFunction = (name: MapKey, args: any[], tags: string[] | null, returnType: TriggerReturnType | null) => boolean;
|
|
5
5
|
type RelaySource = {
|
|
6
6
|
on: (name: any, fn: (...args: any[]) => any, options?: ListenerOptions) => void;
|
|
@@ -59,6 +59,7 @@ export declare function createEventBus<EventsMap extends BaseEventMap = DefaultE
|
|
|
59
59
|
readonly remove: <K extends KeyOf<GetEventsMap<EventsMap>>, H extends GetEventsMap<EventsMap>[K]["signature"]>(name: K, handler: H, context?: object | null, tag?: string | null) => void;
|
|
60
60
|
/** @alias removeListener */
|
|
61
61
|
readonly unsubscribe: <K extends KeyOf<GetEventsMap<EventsMap>>, H extends GetEventsMap<EventsMap>[K]["signature"]>(name: K, handler: H, context?: object | null, tag?: string | null) => void;
|
|
62
|
+
readonly updateListenerOptions: <K extends KeyOf<GetEventsMap<EventsMap>>, H extends GetEventsMap<EventsMap>[K]["signature"]>(name: K, handler: H, context?: object | null, nextOptions?: ListenerOptions) => boolean;
|
|
62
63
|
readonly trigger: <K extends KeyOf<GetEventsMap<EventsMap>>, A extends GetEventsMap<EventsMap>[K]["arguments"]>(name: K, ...args: A) => void;
|
|
63
64
|
/** @alias trigger */
|
|
64
65
|
readonly emit: <K extends KeyOf<GetEventsMap<EventsMap>>, A extends GetEventsMap<EventsMap>[K]["arguments"]>(name: K, ...args: A) => void;
|
|
@@ -66,6 +67,7 @@ export declare function createEventBus<EventsMap extends BaseEventMap = DefaultE
|
|
|
66
67
|
readonly dispatch: <K extends KeyOf<GetEventsMap<EventsMap>>, A extends GetEventsMap<EventsMap>[K]["arguments"]>(name: K, ...args: A) => void;
|
|
67
68
|
readonly get: <K extends KeyOf<GetEventsMap<EventsMap>>>(name: K) => GetEventTypesMap<EventsMap>[K];
|
|
68
69
|
readonly add: (name: MapKey, options?: EventOptions<BaseHandler>) => void;
|
|
70
|
+
readonly setOptions: (options?: EventBusOptions<BaseEventMap>) => void;
|
|
69
71
|
readonly first: <K extends KeyOf<GetEventsMap<EventsMap>>, A extends GetEventsMap<EventsMap>[K]["arguments"]>(name: K, ...args: A) => ReturnType<GetEventTypesMap<EventsMap>[K]["first"]>;
|
|
70
72
|
readonly resolveFirst: <K extends KeyOf<GetEventsMap<EventsMap>>, A extends GetEventsMap<EventsMap>[K]["arguments"]>(name: K, ...args: A) => ReturnType<GetEventTypesMap<EventsMap>[K]["resolveFirst"]>;
|
|
71
73
|
readonly all: <K extends KeyOf<GetEventsMap<EventsMap>>, A extends GetEventsMap<EventsMap>[K]["arguments"]>(name: K, ...args: A) => ReturnType<GetEventTypesMap<EventsMap>[K]["all"]>;
|
package/dist/eventBus.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { createEvent } from "./event";
|
|
2
|
-
import
|
|
1
|
+
import { createEvent } from "./event.js";
|
|
2
|
+
import isPromiseLike from "./lib/isPromiseLike.js";
|
|
3
|
+
import { normalizeEventOptions } from "./lib/normalizeEventOptions.js";
|
|
4
|
+
import { ProxyType, TriggerReturnType, } from "./lib/types.js";
|
|
3
5
|
function proxyReturnTypeToTriggerReturnType(proxyType) {
|
|
4
6
|
switch (proxyType) {
|
|
5
7
|
case ProxyType.TRIGGER:
|
|
@@ -71,6 +73,7 @@ function proxyReturnTypeToTriggerReturnType(proxyType) {
|
|
|
71
73
|
}
|
|
72
74
|
export function createEventBus(eventBusOptions) {
|
|
73
75
|
const events = new Map();
|
|
76
|
+
let currentEventBusOptions = eventBusOptions;
|
|
74
77
|
let currentTagsFilter = null;
|
|
75
78
|
let interceptor = null;
|
|
76
79
|
const proxyListeners = [];
|
|
@@ -135,10 +138,31 @@ export function createEventBus(eventBusOptions) {
|
|
|
135
138
|
const _getOrAddEvent = (name) => {
|
|
136
139
|
var _a;
|
|
137
140
|
if (!events.has(name)) {
|
|
138
|
-
events.set(name, createEvent((_a =
|
|
141
|
+
events.set(name, createEvent((_a = currentEventBusOptions === null || currentEventBusOptions === void 0 ? void 0 : currentEventBusOptions.eventOptions) === null || _a === void 0 ? void 0 : _a[name]));
|
|
139
142
|
}
|
|
140
143
|
return events.get(name);
|
|
141
144
|
};
|
|
145
|
+
// Parameter is intentionally map-independent (like `add`) so that the
|
|
146
|
+
// method type is identical across instantiations and a typed bus stays
|
|
147
|
+
// assignable to BaseEventBus (which the React listener hooks rely on).
|
|
148
|
+
const setOptions = (options) => {
|
|
149
|
+
currentEventBusOptions = options;
|
|
150
|
+
const eventOptions = options === null || options === void 0 ? void 0 : options.eventOptions;
|
|
151
|
+
if (!eventOptions) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
// Apply present entries to already-created events. Removed entries are
|
|
155
|
+
// intentionally left as-is (the bus can change an event's options but
|
|
156
|
+
// does not un-set them).
|
|
157
|
+
Object.keys(eventOptions).forEach((name) => {
|
|
158
|
+
const e = events.get(name);
|
|
159
|
+
if (e) {
|
|
160
|
+
// Normalize so fields removed from a present entry reset to
|
|
161
|
+
// their defaults (event.setOptions merges, it does not reset).
|
|
162
|
+
e.setOptions(normalizeEventOptions(eventOptions[name]));
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
};
|
|
142
166
|
const intercept = (fn) => {
|
|
143
167
|
interceptor = fn;
|
|
144
168
|
};
|
|
@@ -168,7 +192,7 @@ export function createEventBus(eventBusOptions) {
|
|
|
168
192
|
resolve,
|
|
169
193
|
localEventNamePrefix: null,
|
|
170
194
|
});
|
|
171
|
-
evs.eventSource.on(name, listener.listener, evs.eventSource
|
|
195
|
+
evs.eventSource.on(name, listener.listener, evs.eventSource);
|
|
172
196
|
evs.subscribed.push(name);
|
|
173
197
|
}
|
|
174
198
|
});
|
|
@@ -192,23 +216,28 @@ export function createEventBus(eventBusOptions) {
|
|
|
192
216
|
const isEmpty = !e.hasListener();
|
|
193
217
|
eventSources.forEach((evs) => {
|
|
194
218
|
const inx = evs.subscribed.indexOf(name);
|
|
195
|
-
if (inx !== -1) {
|
|
219
|
+
if (inx !== -1 && isEmpty) {
|
|
196
220
|
evs.subscribed.splice(inx, 1);
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
evs.eventSource.un(name, listener.listener, evs.eventSource, tag);
|
|
207
|
-
}
|
|
221
|
+
const { returnType, resolve } = proxyReturnTypeToTriggerReturnType(evs.eventSource.proxyType || ProxyType.TRIGGER);
|
|
222
|
+
const listener = _getProxyListener({
|
|
223
|
+
localEventName: null,
|
|
224
|
+
remoteEventName: name,
|
|
225
|
+
returnType,
|
|
226
|
+
resolve,
|
|
227
|
+
localEventNamePrefix: null,
|
|
228
|
+
});
|
|
229
|
+
evs.eventSource.un(name, listener.listener, evs.eventSource, tag);
|
|
208
230
|
}
|
|
209
231
|
});
|
|
210
232
|
}
|
|
211
233
|
};
|
|
234
|
+
const updateListenerOptions = (name, handler, context, nextOptions) => {
|
|
235
|
+
const e = events.get(name);
|
|
236
|
+
if (!e) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
return e.updateListenerOptions(handler, context !== null && context !== void 0 ? context : null, nextOptions);
|
|
240
|
+
};
|
|
212
241
|
const _trigger = (name, args, returnType, resolve) => {
|
|
213
242
|
if (name === "*") {
|
|
214
243
|
return;
|
|
@@ -220,6 +249,20 @@ export function createEventBus(eventBusOptions) {
|
|
|
220
249
|
}
|
|
221
250
|
}
|
|
222
251
|
const e = _getOrAddEvent(name);
|
|
252
|
+
const handleError = (error) => {
|
|
253
|
+
errorEvent.trigger({
|
|
254
|
+
name,
|
|
255
|
+
error: error instanceof Error
|
|
256
|
+
? error
|
|
257
|
+
: new Error(String(error)),
|
|
258
|
+
args,
|
|
259
|
+
type: "event",
|
|
260
|
+
});
|
|
261
|
+
if (errorEvent.hasListener()) {
|
|
262
|
+
return undefined;
|
|
263
|
+
}
|
|
264
|
+
throw error;
|
|
265
|
+
};
|
|
223
266
|
const runner = () => {
|
|
224
267
|
let result;
|
|
225
268
|
switch (returnType) {
|
|
@@ -276,21 +319,13 @@ export function createEventBus(eventBusOptions) {
|
|
|
276
319
|
result = runner();
|
|
277
320
|
}
|
|
278
321
|
asterisk.trigger(name, args, currentTagsFilter);
|
|
322
|
+
if (isPromiseLike(result)) {
|
|
323
|
+
return Promise.resolve(result).catch(handleError);
|
|
324
|
+
}
|
|
279
325
|
return result;
|
|
280
326
|
}
|
|
281
327
|
catch (error) {
|
|
282
|
-
|
|
283
|
-
name,
|
|
284
|
-
error: error instanceof Error
|
|
285
|
-
? error
|
|
286
|
-
: new Error(String(error)),
|
|
287
|
-
args,
|
|
288
|
-
type: "event",
|
|
289
|
-
});
|
|
290
|
-
if (errorEvent.hasListener()) {
|
|
291
|
-
return undefined;
|
|
292
|
-
}
|
|
293
|
-
throw error;
|
|
328
|
+
return handleError(error);
|
|
294
329
|
}
|
|
295
330
|
};
|
|
296
331
|
const trigger = (name, ...args) => {
|
|
@@ -348,17 +383,18 @@ export function createEventBus(eventBusOptions) {
|
|
|
348
383
|
return _trigger(name, args, TriggerReturnType.RAW, false);
|
|
349
384
|
};
|
|
350
385
|
const withTags = (tags, callback) => {
|
|
386
|
+
const prevTagsFilter = currentTagsFilter;
|
|
351
387
|
currentTagsFilter = tags;
|
|
352
388
|
try {
|
|
353
389
|
return callback();
|
|
354
390
|
}
|
|
355
391
|
finally {
|
|
356
|
-
currentTagsFilter =
|
|
392
|
+
currentTagsFilter = prevTagsFilter;
|
|
357
393
|
}
|
|
358
394
|
};
|
|
359
395
|
const reset = () => {
|
|
360
396
|
if (eventSources.length > 0) {
|
|
361
|
-
eventSources.forEach((evs) => {
|
|
397
|
+
eventSources.slice().forEach((evs) => {
|
|
362
398
|
removeEventSource(evs.eventSource);
|
|
363
399
|
});
|
|
364
400
|
}
|
|
@@ -417,9 +453,28 @@ export function createEventBus(eventBusOptions) {
|
|
|
417
453
|
if (eventSources.find((evs) => evs.eventSource.name === eventSource.name)) {
|
|
418
454
|
return;
|
|
419
455
|
}
|
|
420
|
-
|
|
456
|
+
const eventSourceData = {
|
|
421
457
|
eventSource,
|
|
422
458
|
subscribed: [],
|
|
459
|
+
};
|
|
460
|
+
eventSources.push(eventSourceData);
|
|
461
|
+
events.forEach((event, name) => {
|
|
462
|
+
if (!event.hasListener()
|
|
463
|
+
|| eventSource.accepts === false
|
|
464
|
+
|| (typeof eventSource.accepts === "function"
|
|
465
|
+
&& !eventSource.accepts(name))) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
const { returnType, resolve } = proxyReturnTypeToTriggerReturnType(eventSource.proxyType || ProxyType.TRIGGER);
|
|
469
|
+
const listener = _getProxyListener({
|
|
470
|
+
localEventName: null,
|
|
471
|
+
remoteEventName: name,
|
|
472
|
+
returnType,
|
|
473
|
+
resolve,
|
|
474
|
+
localEventNamePrefix: null,
|
|
475
|
+
});
|
|
476
|
+
eventSource.on(name, listener.listener, eventSource);
|
|
477
|
+
eventSourceData.subscribed.push(name);
|
|
423
478
|
});
|
|
424
479
|
};
|
|
425
480
|
const removeEventSource = (eventSource) => {
|
|
@@ -462,6 +517,7 @@ export function createEventBus(eventBusOptions) {
|
|
|
462
517
|
remove: un,
|
|
463
518
|
/** @alias removeListener */
|
|
464
519
|
unsubscribe: un,
|
|
520
|
+
updateListenerOptions,
|
|
465
521
|
trigger,
|
|
466
522
|
/** @alias trigger */
|
|
467
523
|
emit: trigger,
|
|
@@ -469,6 +525,7 @@ export function createEventBus(eventBusOptions) {
|
|
|
469
525
|
dispatch: trigger,
|
|
470
526
|
get,
|
|
471
527
|
add,
|
|
528
|
+
setOptions,
|
|
472
529
|
first,
|
|
473
530
|
resolveFirst,
|
|
474
531
|
all,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from "./action";
|
|
2
|
-
export * from "./actionBus";
|
|
3
|
-
export * from "./actionMap";
|
|
4
|
-
export * from "./event";
|
|
5
|
-
export * from "./eventBus";
|
|
6
|
-
export * from "./lib/types";
|
|
7
|
-
export * from "./store";
|
|
1
|
+
export * from "./action.js";
|
|
2
|
+
export * from "./actionBus.js";
|
|
3
|
+
export * from "./actionMap.js";
|
|
4
|
+
export * from "./event.js";
|
|
5
|
+
export * from "./eventBus.js";
|
|
6
|
+
export * from "./lib/types.js";
|
|
7
|
+
export * from "./store.js";
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from "./action";
|
|
2
|
-
export * from "./actionBus";
|
|
3
|
-
export * from "./actionMap";
|
|
4
|
-
export * from "./event";
|
|
5
|
-
export * from "./eventBus";
|
|
6
|
-
export * from "./lib/types";
|
|
7
|
-
export * from "./store";
|
|
1
|
+
export * from "./action.js";
|
|
2
|
+
export * from "./actionBus.js";
|
|
3
|
+
export * from "./actionMap.js";
|
|
4
|
+
export * from "./event.js";
|
|
5
|
+
export * from "./eventBus.js";
|
|
6
|
+
export * from "./lib/types.js";
|
|
7
|
+
export * from "./store.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal-only symbol used to expose an in-place setter for an action map's
|
|
3
|
+
* forwarded error listeners. Lives under src/lib (which is not re-exported by
|
|
4
|
+
* the package root in index.ts) so it does not become part of the public API
|
|
5
|
+
* surface. Imported by createActionMap (to attach the setter) and by
|
|
6
|
+
* useActionMap (to call it during reconciliation).
|
|
7
|
+
*/
|
|
8
|
+
export declare const ActionMapSetErrorListeners: unique symbol;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal-only symbol used to expose an in-place setter for an action map's
|
|
3
|
+
* forwarded error listeners. Lives under src/lib (which is not re-exported by
|
|
4
|
+
* the package root in index.ts) so it does not become part of the public API
|
|
5
|
+
* surface. Imported by createActionMap (to attach the setter) and by
|
|
6
|
+
* useActionMap (to call it during reconciliation).
|
|
7
|
+
*/
|
|
8
|
+
export const ActionMapSetErrorListeners = Symbol("actionMapSetErrorListeners");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function isPromiseLike<T = unknown>(value: unknown): value is PromiseLike<T>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { EventOptions } from "../event.js";
|
|
2
|
+
import type { BaseHandler } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Produces a complete {@link EventOptions} object with every field set to the
|
|
5
|
+
* provided value or its createEvent default. Used by the reconciliation paths
|
|
6
|
+
* (useEvent and eventBus.setOptions) so that applying options via the
|
|
7
|
+
* merge-based event.setOptions also resets fields that were removed across
|
|
8
|
+
* renders, instead of leaving stale values from a previous render.
|
|
9
|
+
*
|
|
10
|
+
* Internal-only: this module lives under src/lib (not re-exported by the
|
|
11
|
+
* package root) and is not part of the public API surface.
|
|
12
|
+
*/
|
|
13
|
+
export declare function normalizeEventOptions(options?: EventOptions<BaseHandler> | null): EventOptions<BaseHandler>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Produces a complete {@link EventOptions} object with every field set to the
|
|
3
|
+
* provided value or its createEvent default. Used by the reconciliation paths
|
|
4
|
+
* (useEvent and eventBus.setOptions) so that applying options via the
|
|
5
|
+
* merge-based event.setOptions also resets fields that were removed across
|
|
6
|
+
* renders, instead of leaving stale values from a previous render.
|
|
7
|
+
*
|
|
8
|
+
* Internal-only: this module lives under src/lib (not re-exported by the
|
|
9
|
+
* package root) and is not part of the public API surface.
|
|
10
|
+
*/
|
|
11
|
+
export function normalizeEventOptions(options) {
|
|
12
|
+
var _a, _b, _c, _d, _e, _f;
|
|
13
|
+
return {
|
|
14
|
+
async: (_a = options === null || options === void 0 ? void 0 : options.async) !== null && _a !== void 0 ? _a : null,
|
|
15
|
+
limit: (_b = options === null || options === void 0 ? void 0 : options.limit) !== null && _b !== void 0 ? _b : null,
|
|
16
|
+
autoTrigger: (_c = options === null || options === void 0 ? void 0 : options.autoTrigger) !== null && _c !== void 0 ? _c : null,
|
|
17
|
+
filter: (_d = options === null || options === void 0 ? void 0 : options.filter) !== null && _d !== void 0 ? _d : null,
|
|
18
|
+
filterContext: (_e = options === null || options === void 0 ? void 0 : options.filterContext) !== null && _e !== void 0 ? _e : null,
|
|
19
|
+
maxListeners: (_f = options === null || options === void 0 ? void 0 : options.maxListeners) !== null && _f !== void 0 ? _f : 0,
|
|
20
|
+
};
|
|
21
|
+
}
|