Skip to content

Commit

Permalink
feat: added catchAllHandlerKey to handler
Browse files Browse the repository at this point in the history
- can now specify a "catchall" for a handler, letting a single function attempt to handle all other values that would not get matched otherwise
  • Loading branch information
dereekb committed May 20, 2022
1 parent 9425016 commit ab93b06
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 7 deletions.
22 changes: 20 additions & 2 deletions packages/util/src/lib/service/handler.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Handler, makeHandler } from './handler';
import { catchAllHandlerKey, Handler, makeHandler } from './handler';

describe('handler()', () => {

Expand All @@ -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';
Expand All @@ -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', () => {
Expand Down
27 changes: 22 additions & 5 deletions packages/util/src/lib/service/handler.ts
Original file line number Diff line number Diff line change
@@ -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 extends PrimativeKey = string> = K | HandlerCatchAllKey;

/**
* Used to perform a task on the input value.
*
Expand All @@ -22,7 +30,7 @@ export interface HandlerSetAccessor<T, K extends PrimativeKey = string> {
* @param key
* @param handle
*/
set(key: ArrayOrValue<K>, handle: HandlerFunction<T>): void;
set(key: ArrayOrValue<HandlerKey<K>>, handle: HandlerFunction<T>): void;

}

Expand All @@ -40,7 +48,7 @@ export interface HandlerAccessor<T, K extends PrimativeKey = string> extends Han
* @param key
* @param handle
*/
bindSet(bindTo: any, key: ArrayOrValue<K>, handle: HandlerFunction<T>): void;
bindSet(bindTo: any, key: ArrayOrValue<HandlerKey<K>>, handle: HandlerFunction<T>): void;

}

Expand All @@ -49,10 +57,15 @@ export type HandlerFactory<T, K extends PrimativeKey = string> = () => Handler<T

export function handlerFactory<T, K extends PrimativeKey = string>(readKey: ReadKeyFunction<T, K>): HandlerFactory<T, K> {
return () => {
let catchAll: Maybe<HandlerFunction<T>>;
const map = new Map<K, HandlerFunction<T>>();

const set = (key: ArrayOrValue<K>, handle: HandlerFunction<T>) => {
setKeysOnMap(map, key, handle);
if (key === CATCH_ALL_HANDLE_RESULT_KEY) {
catchAll = handle;
} else {
setKeysOnMap(map, key, handle);
}
};

const bindSet = (bindTo: any, key: ArrayOrValue<K>, handle: HandlerFunction<T>) => {
Expand All @@ -62,7 +75,7 @@ export function handlerFactory<T, K extends PrimativeKey = string>(readKey: Read

const fn: Handler<T, K> = ((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<boolean> = false;

if (handler) {
Expand All @@ -83,3 +96,7 @@ export function handlerFactory<T, K extends PrimativeKey = string>(readKey: Read
export function makeHandler<T, K extends PrimativeKey = string>(readKey: ReadKeyFunction<T, K>): Handler<T, K> {
return handlerFactory(readKey)();
}

export function catchAllHandlerKey(): typeof CATCH_ALL_HANDLE_RESULT_KEY {
return CATCH_ALL_HANDLE_RESULT_KEY;
}

0 comments on commit ab93b06

Please sign in to comment.