/ lib / enhancers.js
enhancers.js
 1  import {
 2    enhanceStrategyBuilderWithDebugLogging as logStrategy,
 3    enhanceStrategyBuilderWithEmittedLogging as logEmitted,
 4  } from '@bablr/strategy_enhancer-debug-log';
 5  import { enhanceProductionWithDebugLogging as createProductionLogger } from '@bablr/language_enhancer-debug-log';
 6  import { mapProductions } from './grammar.js';
 7  
 8  export const memoize = (original) => {
 9    const cache = new WeakMap();
10    const memoized = (...args) => {
11      if (args.length > 1) throw new Error('A memoized function accepts only one argument');
12      const arg = args[0];
13  
14      if (cache.has(arg)) {
15        return cache.get(arg);
16      } else {
17        return original(arg);
18      }
19    };
20    return memoized;
21  };
22  
23  const identity = (x) => x;
24  
25  export const compose = (functions) => {
26    let first = true;
27    let f = identity;
28    for (const g of functions) {
29      if (first) {
30        f = g;
31      } else {
32        const f_ = f;
33        f = (x) => f_(g(x));
34      }
35      first = false;
36    }
37  
38    return f;
39  };
40  
41  export const debugEnhancers = {
42    // bablr: (strategy) => logStrategy(strategy, '<<< '),
43    createBablrStrategy: (strategy) => (matcher, props) =>
44      logStrategy(strategy(matcher, props), '    >>> '),
45    bablrProduction: createProductionLogger('>>> '),
46  };
47  
48  export const stateEnhancer = (hooks, grammar) => {
49    let state;
50    return mapProductions((production) => {
51      return function* (props) {
52        let prevState = props.state;
53  
54        if (!state) {
55          hooks.buildState?.(props.state);
56        } else if (props.state !== state) {
57          hooks.branchState?.(state, props.state);
58        }
59  
60        state = props.state;
61  
62        try {
63          yield* production(props);
64  
65          hooks.acceptState?.(props.state, state);
66        } catch (e) {
67          hooks.rejectState?.(props.state);
68        }
69  
70        state = prevState;
71      };
72    }, grammar);
73  };