All files question.ts

100% Statements 31/31
100% Branches 11/11
100% Functions 6/6
100% Lines 31/31

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                        1x 10x 10x   10x 16x 1x 1x 15x 15x 16x   10x 4x 1x 1x 3x 3x 4x   10x 1x 1x 1x 1x 1x 1x   10x 11x 14x 14x 11x 11x 10x  
export type AnswerCallback<Result, Arguments extends any[] = []> = (result: Result, ...args: Arguments) => Result;
 
export interface IQuestionAsker<Result = any, Arguments extends any[] = []> {
  ask(result: Result, ...args: Arguments): Result;
}
 
export interface IQuestion<Result = any, Arguments extends any[] = []> extends IQuestionAsker<Result, Arguments> {
  addAnswer(callback: AnswerCallback<Result, Arguments>): void;
  removeAnswer(callback: AnswerCallback<Result, Arguments>): void;
  addOneTimeAnswer(callback: AnswerCallback<Result, Arguments>): void;
}
 
export class Question<Result = any, Arguments extends any[] = []> implements IQuestion<Result, Arguments> {
  protected _callbacks: AnswerCallback<Result, Arguments>[] = [];
  protected _callbacksSet: Set<AnswerCallback<Result, Arguments>> = new Set();
 
  addAnswer(callback: AnswerCallback<Result, Arguments>) {
    if (this._callbacksSet.has(callback)) {
      return;
    }
    this._callbacksSet.add(callback);
    this._callbacks.push(callback);
  }
 
  removeAnswer(callback: AnswerCallback<Result, Arguments>) {
    if (!this._callbacksSet.has(callback)) {
      return;
    }
    this._callbacksSet.delete(callback);
    this._callbacks = [...this._callbacksSet];
  }
 
  addOneTimeAnswer(callback: AnswerCallback<Result, Arguments>) {
    const onceCallback: AnswerCallback<Result, Arguments> = (...args) => {
      this.removeAnswer(onceCallback);
      return callback(...args);
    };
    this.addAnswer(onceCallback);
  }
 
  ask(result: Result, ...args: Arguments): Result {
    for (const callback of this._callbacks) {
      result = callback(result, ...args);
    }
    return result;
  }
}