提交 | 用户 | age
|
814f9a
|
1 |
/** |
327d71
|
2 |
* copy to https://github.com/developit/mitt |
V |
3 |
* Expand clear method |
814f9a
|
4 |
*/ |
d3d620
|
5 |
export type EventType = string | symbol; |
814f9a
|
6 |
|
d3d620
|
7 |
// An event handler can take an optional event argument |
V |
8 |
// and should not return a value |
ae5f5c
|
9 |
export type Handler<T = unknown> = (event: T) => void; |
KL |
10 |
export type WildcardHandler<T = Record<string, unknown>> = ( |
|
11 |
type: keyof T, |
|
12 |
event: T[keyof T], |
|
13 |
) => void; |
814f9a
|
14 |
|
d3d620
|
15 |
// An array of all currently registered event handlers for a type |
ae5f5c
|
16 |
export type EventHandlerList<T = unknown> = Array<Handler<T>>; |
KL |
17 |
export type WildCardEventHandlerList<T = Record<string, unknown>> = Array<WildcardHandler<T>>; |
814f9a
|
18 |
|
d3d620
|
19 |
// A map of event types and their corresponding event handlers. |
ae5f5c
|
20 |
export type EventHandlerMap<Events extends Record<EventType, unknown>> = Map< |
KL |
21 |
keyof Events | '*', |
|
22 |
EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events> |
|
23 |
>; |
814f9a
|
24 |
|
ae5f5c
|
25 |
export interface Emitter<Events extends Record<EventType, unknown>> { |
KL |
26 |
all: EventHandlerMap<Events>; |
d3d620
|
27 |
|
ae5f5c
|
28 |
on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void; |
KL |
29 |
on(type: '*', handler: WildcardHandler<Events>): void; |
d3d620
|
30 |
|
ae5f5c
|
31 |
off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void; |
KL |
32 |
off(type: '*', handler: WildcardHandler<Events>): void; |
d3d620
|
33 |
|
ae5f5c
|
34 |
emit<Key extends keyof Events>(type: Key, event: Events[Key]): void; |
KL |
35 |
emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void; |
893f3c
|
36 |
clear(): void; |
d3d620
|
37 |
} |
V |
38 |
|
|
39 |
/** |
|
40 |
* Mitt: Tiny (~200b) functional event emitter / pubsub. |
|
41 |
* @name mitt |
|
42 |
* @returns {Mitt} |
|
43 |
*/ |
ae5f5c
|
44 |
export function mitt<Events extends Record<EventType, unknown>>( |
KL |
45 |
all?: EventHandlerMap<Events>, |
|
46 |
): Emitter<Events> { |
|
47 |
type GenericEventHandler = Handler<Events[keyof Events]> | WildcardHandler<Events>; |
d3d620
|
48 |
all = all || new Map(); |
V |
49 |
|
|
50 |
return { |
|
51 |
/** |
|
52 |
* A Map of event names to registered handler functions. |
|
53 |
*/ |
|
54 |
all, |
|
55 |
|
|
56 |
/** |
|
57 |
* Register an event handler for the given type. |
ae5f5c
|
58 |
* @param {string|symbol} type Type of event to listen for, or `'*'` for all events |
d3d620
|
59 |
* @param {Function} handler Function to call in response to given event |
V |
60 |
* @memberOf mitt |
|
61 |
*/ |
ae5f5c
|
62 |
on<Key extends keyof Events>(type: Key, handler: GenericEventHandler) { |
KL |
63 |
const handlers: Array<GenericEventHandler> | undefined = all!.get(type); |
|
64 |
if (handlers) { |
|
65 |
handlers.push(handler); |
|
66 |
} else { |
|
67 |
all!.set(type, [handler] as EventHandlerList<Events[keyof Events]>); |
d3d620
|
68 |
} |
V |
69 |
}, |
|
70 |
|
|
71 |
/** |
|
72 |
* Remove an event handler for the given type. |
ae5f5c
|
73 |
* If `handler` is omitted, all handlers of the given type are removed. |
KL |
74 |
* @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler) |
|
75 |
* @param {Function} [handler] Handler function to remove |
d3d620
|
76 |
* @memberOf mitt |
V |
77 |
*/ |
ae5f5c
|
78 |
off<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) { |
KL |
79 |
const handlers: Array<GenericEventHandler> | undefined = all!.get(type); |
d3d620
|
80 |
if (handlers) { |
ae5f5c
|
81 |
if (handler) { |
KL |
82 |
handlers.splice(handlers.indexOf(handler) >>> 0, 1); |
|
83 |
} else { |
|
84 |
all!.set(type, []); |
|
85 |
} |
d3d620
|
86 |
} |
V |
87 |
}, |
|
88 |
|
|
89 |
/** |
|
90 |
* Invoke all handlers for the given type. |
ae5f5c
|
91 |
* If present, `'*'` handlers are invoked after type-matched handlers. |
d3d620
|
92 |
* |
ae5f5c
|
93 |
* Note: Manually firing '*' handlers is not supported. |
d3d620
|
94 |
* |
V |
95 |
* @param {string|symbol} type The event type to invoke |
|
96 |
* @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler |
|
97 |
* @memberOf mitt |
|
98 |
*/ |
ae5f5c
|
99 |
emit<Key extends keyof Events>(type: Key, evt?: Events[Key]) { |
KL |
100 |
let handlers = all!.get(type); |
|
101 |
if (handlers) { |
|
102 |
(handlers as EventHandlerList<Events[keyof Events]>).slice().forEach((handler) => { |
|
103 |
handler(evt as Events[Key]); |
|
104 |
}); |
|
105 |
} |
|
106 |
|
|
107 |
handlers = all!.get('*'); |
|
108 |
if (handlers) { |
|
109 |
(handlers as WildCardEventHandlerList<Events>).slice().forEach((handler) => { |
|
110 |
handler(type, evt as Events[Key]); |
|
111 |
}); |
|
112 |
} |
d3d620
|
113 |
}, |
893f3c
|
114 |
|
V |
115 |
/** |
|
116 |
* Clear all |
|
117 |
*/ |
|
118 |
clear() { |
|
119 |
this.all.clear(); |
|
120 |
}, |
d3d620
|
121 |
}; |
814f9a
|
122 |
} |