index.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // @flow
  2. // An event handler can take an optional event argument
  3. // and should not return a value
  4. type EventHandler = (event?: any) => void;
  5. type WildCardEventHandler = (type: string, event?: any) => void
  6. // An array of all currently registered event handlers for a type
  7. type EventHandlerList = Array<EventHandler>;
  8. type WildCardEventHandlerList = Array<WildCardEventHandler>;
  9. // A map of event types and their corresponding event handlers.
  10. type EventHandlerMap = {
  11. '*'?: WildCardEventHandlerList,
  12. [type: string]: EventHandlerList,
  13. };
  14. /** Mitt: Tiny (~200b) functional event emitter / pubsub.
  15. * @name mitt
  16. * @returns {Mitt}
  17. */
  18. export default function mitt(all: EventHandlerMap) {
  19. all = all || Object.create(null);
  20. return {
  21. /**
  22. * Register an event handler for the given type.
  23. *
  24. * @param {String} type Type of event to listen for, or `"*"` for all events
  25. * @param {Function} handler Function to call in response to given event
  26. * @memberOf mitt
  27. */
  28. on(type: string, handler: EventHandler) {
  29. (all[type] || (all[type] = [])).push(handler);
  30. },
  31. /**
  32. * Remove an event handler for the given type.
  33. *
  34. * @param {String} type Type of event to unregister `handler` from, or `"*"`
  35. * @param {Function} handler Handler function to remove
  36. * @memberOf mitt
  37. */
  38. off(type: string, handler: EventHandler) {
  39. if (all[type]) {
  40. all[type].splice(all[type].indexOf(handler) >>> 0, 1);
  41. }
  42. },
  43. /**
  44. * Invoke all handlers for the given type.
  45. * If present, `"*"` handlers are invoked after type-matched handlers.
  46. *
  47. * @param {String} type The event type to invoke
  48. * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler
  49. * @memberOf mitt
  50. */
  51. emit(type: string, evt: any) {
  52. (all[type] || []).slice().map((handler) => { handler(evt); });
  53. (all['*'] || []).slice().map((handler) => { handler(type, evt); });
  54. }
  55. };
  56. }