From 1aed0fe5d6657b06b037b28f38eeccdccac39b58 Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Thu, 14 Nov 2024 11:04:41 +0800 Subject: [PATCH] chore: use mitt hook --- web/hooks/use-mitt.ts | 74 +++++++++++++++++++++++++++++++++++++++++++ web/package.json | 1 + web/pnpm-lock.yaml | 8 +++++ 3 files changed, 83 insertions(+) create mode 100644 web/hooks/use-mitt.ts diff --git a/web/hooks/use-mitt.ts b/web/hooks/use-mitt.ts new file mode 100644 index 0000000000..b9094bc262 --- /dev/null +++ b/web/hooks/use-mitt.ts @@ -0,0 +1,74 @@ +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 } diff --git a/web/package.json b/web/package.json index 7cbe778790..22a704bdcb 100644 --- a/web/package.json +++ b/web/package.json @@ -70,6 +70,7 @@ "lodash-es": "^4.17.21", "mermaid": "10.9.3", "mime": "^4.0.4", + "mitt": "^3.0.1", "negotiator": "^0.6.3", "next": "^14.2.10", "pinyin-pro": "^3.25.0", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 5765f2589c..9426a81c49 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -151,6 +151,9 @@ importers: mime: specifier: ^4.0.4 version: 4.0.4 + mitt: + specifier: ^3.0.1 + version: 3.0.1 negotiator: specifier: ^0.6.3 version: 0.6.4 @@ -6129,6 +6132,9 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -15636,6 +15642,8 @@ snapshots: minipass@7.1.2: {} + mitt@3.0.1: {} + mkdirp@0.5.6: dependencies: minimist: 1.2.8