diff --git a/packages/util/src/lib/service/handler.spec.ts b/packages/util/src/lib/service/handler.spec.ts index 381f6b1ca..c16fabe74 100644 --- a/packages/util/src/lib/service/handler.spec.ts +++ b/packages/util/src/lib/service/handler.spec.ts @@ -1,4 +1,4 @@ -import { Handler, makeHandler } from './handler'; +import { catchAllHandlerKey, Handler, makeHandler } from './handler'; describe('handler()', () => { @@ -21,7 +21,6 @@ describe('handler()', () => { describe('set', () => { it('should set the function on the handler for that key', () => { - let wasUsed = false; const key = '1'; @@ -40,6 +39,25 @@ describe('handler()', () => { expect(wasUsed).toBe(true); }); + it('should set the catch all when using the catchall key', () => { + let wasUsed = false; + + const otherValue = 10000; + + const fn = (x: number) => { + wasUsed = true; + expect(x).toBe(otherValue); + return true; // result + }; + + handler.set(catchAllHandlerKey(), fn); + expect(wasUsed).toBe(false); + + const result = handler(otherValue); + expect(result).toBe(true); + expect(wasUsed).toBe(true); + }); + }); describe('bindSet', () => { diff --git a/packages/util/src/lib/service/handler.ts b/packages/util/src/lib/service/handler.ts index 185a7f003..dfafd7f13 100644 --- a/packages/util/src/lib/service/handler.ts +++ b/packages/util/src/lib/service/handler.ts @@ -1,12 +1,20 @@ import { PrimativeKey, ReadKeyFunction } from './../key'; import { ArrayOrValue } from './../array/array'; -import { PromiseOrValue, setKeysOnMap } from '@dereekb/util'; +import { Maybe, PromiseOrValue, setKeysOnMap } from '@dereekb/util'; + +/** + * Key used to signify + */ +export const CATCH_ALL_HANDLE_RESULT_KEY = '__CATCH_ALL_HANDLE_RESULT_KEY__'; /** * Whether or not the input value was handled. */ export type HandleResult = boolean; +export type HandlerCatchAllKey = typeof CATCH_ALL_HANDLE_RESULT_KEY; +export type HandlerKey = K | HandlerCatchAllKey; + /** * Used to perform a task on the input value. * @@ -22,7 +30,7 @@ export interface HandlerSetAccessor { * @param key * @param handle */ - set(key: ArrayOrValue, handle: HandlerFunction): void; + set(key: ArrayOrValue>, handle: HandlerFunction): void; } @@ -40,7 +48,7 @@ export interface HandlerAccessor extends Han * @param key * @param handle */ - bindSet(bindTo: any, key: ArrayOrValue, handle: HandlerFunction): void; + bindSet(bindTo: any, key: ArrayOrValue>, handle: HandlerFunction): void; } @@ -49,10 +57,15 @@ export type HandlerFactory = () => Handler(readKey: ReadKeyFunction): HandlerFactory { return () => { + let catchAll: Maybe>; const map = new Map>(); const set = (key: ArrayOrValue, handle: HandlerFunction) => { - setKeysOnMap(map, key, handle); + if (key === CATCH_ALL_HANDLE_RESULT_KEY) { + catchAll = handle; + } else { + setKeysOnMap(map, key, handle); + } }; const bindSet = (bindTo: any, key: ArrayOrValue, handle: HandlerFunction) => { @@ -62,7 +75,7 @@ export function handlerFactory(readKey: Read const fn: Handler = ((value: T) => { const key = readKey(value); - const handler = (key != null) ? map.get(key) : undefined; + const handler = ((key != null) ? map.get(key) : undefined) ?? catchAll; let handled: PromiseOrValue = false; if (handler) { @@ -83,3 +96,7 @@ export function handlerFactory(readKey: Read export function makeHandler(readKey: ReadKeyFunction): Handler { return handlerFactory(readKey)(); } + +export function catchAllHandlerKey(): typeof CATCH_ALL_HANDLE_RESULT_KEY { + return CATCH_ALL_HANDLE_RESULT_KEY; +}