All files action-handler.ts

100% Statements 63/63
100% Branches 16/16
100% Functions 13/13
100% Lines 63/63

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107                                                            1x 294x 294x 294x 294x 294x 294x 294x 294x 294x   294x 294x 294x 294x 294x 294x 192x 192x   192x 192x 294x 294x 294x 294x   294x 13x 13x   294x 362x 362x   294x 166x 166x   294x 542x 542x   294x 129x 129x   294x 6x 6x   294x 6x 6x   294x 2x 2x   294x 12x 12x   294x 70x 70x 70x 70x 70x 294x   1x 273x 273x 273x 273x  
import { ActionMap, ActionMapBasic, ActionMapInternal } from './action-map';
import { ActionCreator } from './action';
 
export type ActionHandlerCallback<AM extends ActionMapBasic = ActionMapBasic, Inject = any> = (
  this: IActionHandler<Inject>,
  actionMap: AM,
  inject: Inject
) => any;
 
export interface ActionHandlerConfiguration<AM extends ActionMapBasic = ActionMapBasic, Inject = any> {
  inputs: readonly ActionCreator[];
  outputs?: readonly ActionCreator[];
  run: ActionHandlerCallback<AM, Inject>;
  name?: string;
  inject?: Inject;
}
 
export interface IActionHandler<Inject = any> {
  getName: () => string;
  getInputs: () => readonly ActionCreator[];
  getInputSet: () => ReadonlySet<ActionCreator>;
  getOutputs: () => readonly ActionCreator[] | undefined;
  getOutputSet: () => ReadonlySet<ActionCreator> | undefined;
  getInputsAndOutputs: () => readonly ActionCreator[];
  getInputsAndOutputsSet: () => ReadonlySet<ActionCreator>;
  inject: (inject: Inject) => void;
  getInjected: () => Inject;
  invoke: (actionMap: ActionMapInternal) => any;
}
 
export class ActionHandler<AM extends ActionMapBasic = ActionMapBasic, Inject = any> implements IActionHandler<Inject> {
  protected _inputs: readonly ActionCreator[];
  protected _inputSet: ReadonlySet<ActionCreator>;
  protected _outputs?: readonly ActionCreator[];
  protected _outputSet?: ReadonlySet<ActionCreator>;
  protected _inputsAndOutputs: readonly ActionCreator[];
  protected _inputsAndOutputsSet: ReadonlySet<ActionCreator>;
  protected _name: string;
  protected _injected: Inject;
  protected _callback: ActionHandlerCallback<AM, Inject>;
 
  constructor(config: ActionHandlerConfiguration<AM, Inject>) {
    this._callback = config.run;
    this._inputSet = new Set(config.inputs);
    this._inputs = [...this._inputSet];
    this._inputsAndOutputs = [...this._inputs];
    if (config.outputs && config.outputs.length) {
      this._outputSet = new Set(config.outputs);
      this._outputs = [...this._outputSet];
      // @ts-expect-error - _inputsAndOutputs is readonly and must be because it is exposed as a public method
      this._inputsAndOutputs.push(...this._outputs);
    }
    this._inputsAndOutputsSet = new Set(this._inputsAndOutputs);
    this._injected = config.inject!;
    this._name = config.name ?? 'ActionHandler(Unnamed)';
  }
 
  getName() {
    return this._name;
  }
 
  getInputs() {
    return this._inputs;
  }
 
  getInputSet() {
    return this._inputSet;
  }
 
  getOutputs() {
    return this._outputs;
  }
 
  getOutputSet() {
    return this._outputSet;
  }
 
  getInputsAndOutputs() {
    return this._inputsAndOutputs;
  }
 
  getInputsAndOutputsSet() {
    return this._inputsAndOutputsSet;
  }
 
  inject(inject: Inject) {
    this._injected = inject;
  }
 
  getInjected() {
    return this._injected;
  }
 
  invoke(actionMap: ActionMapInternal) {
    actionMap._setIsHandlerExecuted(true);
    const result = this._callback(actionMap as unknown as AM, this._injected);
    actionMap._setIsHandlerExecuted(false);
    return result;
  }
}
 
export function createHandler<AM extends ActionMapBasic = ActionMapBasic, Inject = any>(
  config: ActionHandlerConfiguration<AM, Inject>
): ActionHandler<AM, Inject> {
  return new ActionHandler(config);
}