12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- const Pre = '__pre__'
- const Last = '__last__'
- export type Handler<T = unknown> = (event: T) => any
- export type Events = Record<string, unknown>
- export type Flush = { pre?: boolean; last?: boolean }
- export type Bus<T extends Events> = {
- on<Key extends keyof T>(
- type: Key,
- handler: Handler<T[Key]>,
- flush?: Flush
- ): void
- off<Key extends keyof T>(
- type: Key,
- handler?: Handler<T[Key]>,
- flush?: Flush
- ): void
- emit<Key extends keyof T>(type: Key, args?: T[Key]): Promise<any>
- }
- export const useAsyncBus = <T extends Events>() => {
- const store = {} as { [key in keyof T]: Array<Handler> }
- const allKey = (type): Array<keyof T> => [Pre + type, type, Last + type]
- const getKey = (type, flush: Flush): keyof T => {
- const keys = allKey(type)
- return flush
- ? flush.pre
- ? keys[0]
- : flush.last
- ? keys[2]
- : keys[0]
- : keys[0]
- }
- const bus: Bus<T> = {
- on: (type, handler, flush) => {
- const key = getKey(type, flush)
- if (!store[key]) {
- store[key] = []
- }
- if (!store[key].includes(handler)) {
- store[key].push(handler)
- }
- },
- off: (type, handler, flush) => {
- const keys = flush ? [getKey(type, flush)] : allKey(type)
- for (const key of keys) {
- if (handler) {
- if (store[key]) {
- store[key] = store[key].filter(h => h !== handler)
- }
- } else if (store[key]) {
- delete store[key]
- }
- }
- },
- emit: async (type, args) => {
- const keys = allKey(type)
- for (const key of keys) {
- if (store[key]) {
- for (const fn of store[key]) {
- await fn(args)
- }
- }
- }
- }
- }
- return bus
- }
|