|
8 | 8 | * @format |
9 | 9 | */ |
10 | 10 |
|
11 | | -export interface EventSubscription { |
12 | | - remove(): void; |
13 | | -} |
14 | | - |
15 | | -export interface IEventEmitter<TEventToArgsMap: {...}> { |
16 | | - addListener<TEvent: $Keys<TEventToArgsMap>>( |
17 | | - eventType: TEvent, |
18 | | - listener: (...args: $ElementType<TEventToArgsMap, TEvent>) => mixed, |
19 | | - context?: mixed, |
20 | | - ): EventSubscription; |
21 | | - |
22 | | - emit<TEvent: $Keys<TEventToArgsMap>>( |
23 | | - eventType: TEvent, |
24 | | - ...args: $ElementType<TEventToArgsMap, TEvent> |
25 | | - ): void; |
26 | | - |
27 | | - removeAllListeners<TEvent: $Keys<TEventToArgsMap>>(eventType?: ?TEvent): void; |
28 | | - |
29 | | - listenerCount<TEvent: $Keys<TEventToArgsMap>>(eventType: TEvent): number; |
30 | | -} |
31 | | - |
32 | | -interface Registration<TArgs> { |
33 | | - +context: mixed; |
34 | | - +listener: (...args: TArgs) => mixed; |
35 | | - +remove: () => void; |
36 | | -} |
37 | | - |
38 | | -type Registry<TEventToArgsMap: {...}> = $ObjMap< |
39 | | - TEventToArgsMap, |
40 | | - <TArgs>(TArgs) => Set<Registration<TArgs>>, |
41 | | ->; |
42 | | - |
43 | | -/** |
44 | | - * EventEmitter manages listeners and publishes events to them. |
45 | | - * |
46 | | - * EventEmitter accepts a single type parameter that defines the valid events |
47 | | - * and associated listener argument(s). |
48 | | - * |
49 | | - * @example |
50 | | - * |
51 | | - * const emitter = new EventEmitter<{ |
52 | | - * success: [number, string], |
53 | | - * error: [Error], |
54 | | - * }>(); |
55 | | - * |
56 | | - * emitter.on('success', (statusCode, responseText) => {...}); |
57 | | - * emitter.emit('success', 200, '...'); |
58 | | - * |
59 | | - * emitter.on('error', error => {...}); |
60 | | - * emitter.emit('error', new Error('Resource not found')); |
61 | | - * |
62 | | - */ |
63 | | -export default class EventEmitter<TEventToArgsMap: {...}> |
64 | | - implements IEventEmitter<TEventToArgsMap> |
65 | | -{ |
66 | | - _registry: Registry<TEventToArgsMap> = {}; |
67 | | - |
68 | | - /** |
69 | | - * Registers a listener that is called when the supplied event is emitted. |
70 | | - * Returns a subscription that has a `remove` method to undo registration. |
71 | | - */ |
72 | | - addListener<TEvent: $Keys<TEventToArgsMap>>( |
73 | | - eventType: TEvent, |
74 | | - listener: (...args: $ElementType<TEventToArgsMap, TEvent>) => mixed, |
75 | | - context: mixed, |
76 | | - ): EventSubscription { |
77 | | - const registrations = allocate(this._registry, eventType); |
78 | | - const registration: Registration<$ElementType<TEventToArgsMap, TEvent>> = { |
79 | | - context, |
80 | | - listener, |
81 | | - remove(): void { |
82 | | - registrations.delete(registration); |
83 | | - }, |
84 | | - }; |
85 | | - registrations.add(registration); |
86 | | - return registration; |
87 | | - } |
88 | | - |
89 | | - /** |
90 | | - * Emits the supplied event. Additional arguments supplied to `emit` will be |
91 | | - * passed through to each of the registered listeners. |
92 | | - * |
93 | | - * If a listener modifies the listeners registered for the same event, those |
94 | | - * changes will not be reflected in the current invocation of `emit`. |
95 | | - */ |
96 | | - emit<TEvent: $Keys<TEventToArgsMap>>( |
97 | | - eventType: TEvent, |
98 | | - ...args: $ElementType<TEventToArgsMap, TEvent> |
99 | | - ): void { |
100 | | - const registrations: ?Set< |
101 | | - Registration<$ElementType<TEventToArgsMap, TEvent>>, |
102 | | - > = this._registry[eventType]; |
103 | | - if (registrations != null) { |
104 | | - for (const registration of [...registrations]) { |
105 | | - registration.listener.apply(registration.context, args); |
106 | | - } |
107 | | - } |
108 | | - } |
109 | | - |
110 | | - /** |
111 | | - * Removes all registered listeners. |
112 | | - */ |
113 | | - removeAllListeners<TEvent: $Keys<TEventToArgsMap>>( |
114 | | - eventType?: ?TEvent, |
115 | | - ): void { |
116 | | - if (eventType == null) { |
117 | | - this._registry = {}; |
118 | | - } else { |
119 | | - delete this._registry[eventType]; |
120 | | - } |
121 | | - } |
122 | | - |
123 | | - /** |
124 | | - * Returns the number of registered listeners for the supplied event. |
125 | | - */ |
126 | | - listenerCount<TEvent: $Keys<TEventToArgsMap>>(eventType: TEvent): number { |
127 | | - const registrations: ?Set<Registration<mixed>> = this._registry[eventType]; |
128 | | - return registrations == null ? 0 : registrations.size; |
129 | | - } |
130 | | -} |
131 | | - |
132 | | -function allocate< |
133 | | - TEventToArgsMap: {...}, |
134 | | - TEvent: $Keys<TEventToArgsMap>, |
135 | | - TEventArgs: $ElementType<TEventToArgsMap, TEvent>, |
136 | | ->( |
137 | | - registry: Registry<TEventToArgsMap>, |
138 | | - eventType: TEvent, |
139 | | -): Set<Registration<TEventArgs>> { |
140 | | - let registrations: ?Set<Registration<TEventArgs>> = registry[eventType]; |
141 | | - if (registrations == null) { |
142 | | - registrations = new Set(); |
143 | | - registry[eventType] = registrations; |
144 | | - } |
145 | | - return registrations; |
146 | | -} |
| 11 | +import type { |
| 12 | + EventSubscription, |
| 13 | + IEventEmitter, |
| 14 | +} from '@react-native/event-emitter'; |
| 15 | +import EventEmitter from '@react-native/event-emitter'; |
| 16 | + |
| 17 | +export type {EventSubscription, IEventEmitter}; |
| 18 | +export default EventEmitter; |
0 commit comments