import type { Emitter, EventType, Handler, WildcardHandler } from 'mitt' import create from 'mitt' import { useEffect, useRef } from 'react' const merge = >( ...args: Array ): T => { return Object.assign({}, ...args) } export type _Events = Record export type UseSubcribeOption = { /** * Whether the subscription is enabled. * @default true */ enabled: boolean; } export type ExtendedOn = { ( type: Key, handler: Handler, options?: UseSubcribeOption, ): void; ( type: '*', handler: WildcardHandler, option?: UseSubcribeOption, ): void; } export type UseMittReturn = { useSubcribe: ExtendedOn; emit: Emitter['emit']; } const defaultSubcribeOption: UseSubcribeOption = { enabled: true, } function useMitt( mitt?: Emitter, ): UseMittReturn { const emitterRef = useRef>() if (!emitterRef.current) emitterRef.current = mitt ?? create() if (mitt && emitterRef.current !== mitt) { emitterRef.current.off('*') emitterRef.current = mitt } const emitter = emitterRef.current const useSubcribe: ExtendedOn = ( type: string, handler: any, option?: UseSubcribeOption, ) => { const { enabled } = merge(defaultSubcribeOption, option) useEffect(() => { if (enabled) { emitter.on(type, handler) return () => emitter.off(type, handler) } }) } return { emit: emitter.emit, useSubcribe, } } export { useMitt }