repos / starfx

supercharged async flow control library.
git clone https://github.com/neurosnap/starfx.git

Eric Bower · 23 Feb 24

matcher.ts

 1import type { AnyAction } from "./types.ts";
 2
 3type ActionType = string;
 4type GuardPredicate<G extends T, T = unknown> = (arg: T) => arg is G;
 5type Predicate<Guard extends AnyAction = AnyAction> = (
 6  action: Guard,
 7) => boolean;
 8type StringableActionCreator<A extends AnyAction = AnyAction> = {
 9  (...args: unknown[]): A;
10  toString(): string;
11};
12type SubPattern<Guard extends AnyAction = AnyAction> =
13  | Predicate<Guard>
14  | StringableActionCreator
15  | ActionType;
16export type Pattern = SubPattern | SubPattern[];
17type ActionSubPattern<Guard extends AnyAction = AnyAction> =
18  | GuardPredicate<Guard, AnyAction>
19  | StringableActionCreator<Guard>
20  | Predicate<Guard>
21  | ActionType;
22export type ActionPattern<Guard extends AnyAction = AnyAction> =
23  | ActionSubPattern<Guard>
24  | ActionSubPattern<Guard>[];
25
26export function matcher(pattern: ActionPattern): Predicate {
27  if (pattern === "*") {
28    return function (input) {
29      return !!input;
30    };
31  }
32
33  if (typeof pattern === "string") {
34    return function (input) {
35      return pattern === input.type;
36    };
37  }
38
39  if (Array.isArray(pattern)) {
40    return function (input) {
41      return pattern.some((p) => matcher(p)(input));
42    };
43  }
44
45  if (typeof pattern === "function" && Object.hasOwn(pattern, "toString")) {
46    return function (input) {
47      return pattern.toString() === input.type;
48    };
49  }
50
51  if (typeof pattern === "function") {
52    return function (input) {
53      return pattern(input) as boolean;
54    };
55  }
56
57  throw new Error("invalid pattern");
58}