123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- const Pre = '__pre__'
- const Last = '__last__'
- export type AsyncHandler<T = unknown> = (event: T) => any
- export type AsyncEvents = Record<string, unknown>
- export type AsyncFlush = { pre?: boolean; last?: boolean }
- export type AsyncBus<T extends AsyncEvents> = {
- on<Key extends keyof T>(type: Key, handler: AsyncHandler<T[Key]>, flush?: AsyncFlush): void
- off<Key extends keyof T>(type: Key, handler?: AsyncHandler<T[Key]>, flush?: AsyncFlush): void
- emit<Key extends keyof T>(type: Key, args?: T[Key]): Promise<any>
- }
- export const asyncBusFactory = <T extends AsyncEvents>() => {
- const store = {} as { [key in keyof T]: Array<AsyncHandler> }
- const allKey = (type: keyof T): Array<keyof T> => [Pre + type.toString(), type, Last + type.toString()]
- const getKey = (type: keyof T, flush?: AsyncFlush): keyof T => {
- const keys = allKey(type)
- return flush ? (flush.pre ? keys[0] : flush.last ? keys[2] : keys[0]) : keys[0]
- }
- const bus: AsyncBus<T> = {
- on: (type, handler, flush) => {
- const key = getKey(type, flush)
- if (!store[key]) {
- store[key] = []
- }
- if (!store[key].includes(handler as any)) {
- store[key].push(handler as any)
- }
- },
- 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]) {
- console.log(fn)
- await fn(args)
- }
- }
- }
- },
- }
- return bus
- }
|