mitt.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /**
  2. * copy to https://github.com/developit/mitt
  3. * Expand clear method
  4. */
  5. export type EventType = string | symbol;
  6. // An event handler can take an optional event argument
  7. // and should not return a value
  8. export type Handler<T = any> = (event?: T) => void;
  9. export type WildcardHandler = (type: EventType, event?: any) => void;
  10. // An array of all currently registered event handlers for a type
  11. export type EventHandlerList = Array<Handler>;
  12. export type WildCardEventHandlerList = Array<WildcardHandler>;
  13. // A map of event types and their corresponding event handlers.
  14. export type EventHandlerMap = Map<EventType, EventHandlerList | WildCardEventHandlerList>;
  15. export interface Emitter {
  16. all: EventHandlerMap;
  17. on<T = any>(type: EventType, handler: Handler<T>): void;
  18. on(type: '*', handler: WildcardHandler): void;
  19. off<T = any>(type: EventType, handler: Handler<T>): void;
  20. off(type: '*', handler: WildcardHandler): void;
  21. emit<T = any>(type: EventType, event?: T): void;
  22. emit(type: '*', event?: any): void;
  23. clear(): void;
  24. }
  25. /**
  26. * Mitt: Tiny (~200b) functional event emitter / pubsub.
  27. * @name mitt
  28. * @returns {Mitt}
  29. */
  30. export default function mitt(all?: EventHandlerMap): Emitter {
  31. all = all || new Map();
  32. return {
  33. /**
  34. * A Map of event names to registered handler functions.
  35. */
  36. all,
  37. /**
  38. * Register an event handler for the given type.
  39. * @param {string|symbol} type Type of event to listen for, or `"*"` for all events
  40. * @param {Function} handler Function to call in response to given event
  41. * @memberOf mitt
  42. */
  43. on<T = any>(type: EventType, handler: Handler<T>) {
  44. const handlers = all?.get(type);
  45. const added = handlers && handlers.push(handler);
  46. if (!added) {
  47. all?.set(type, [handler]);
  48. }
  49. },
  50. /**
  51. * Remove an event handler for the given type.
  52. * @param {string|symbol} type Type of event to unregister `handler` from, or `"*"`
  53. * @param {Function} handler Handler function to remove
  54. * @memberOf mitt
  55. */
  56. off<T = any>(type: EventType, handler: Handler<T>) {
  57. const handlers = all?.get(type);
  58. if (handlers) {
  59. handlers.splice(handlers.indexOf(handler) >>> 0, 1);
  60. }
  61. },
  62. /**
  63. * Invoke all handlers for the given type.
  64. * If present, `"*"` handlers are invoked after type-matched handlers.
  65. *
  66. * Note: Manually firing "*" handlers is not supported.
  67. *
  68. * @param {string|symbol} type The event type to invoke
  69. * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler
  70. * @memberOf mitt
  71. */
  72. emit<T = any>(type: EventType, evt: T) {
  73. ((all?.get(type) || []) as EventHandlerList).slice().map((handler) => {
  74. handler(evt);
  75. });
  76. ((all?.get('*') || []) as WildCardEventHandlerList).slice().map((handler) => {
  77. handler(type, evt);
  78. });
  79. },
  80. /**
  81. * Clear all
  82. */
  83. clear() {
  84. this.all.clear();
  85. },
  86. };
  87. }