All files hooks.ts

62.5% Statements 10/16
50% Branches 1/2
50% Functions 4/8
71.42% Lines 10/14

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                                                                                                    2x 19x       19x   19x 19x 6x           6x                 6x   6x                   415x      
import type { BucketBy, Context, FeatureKey } from "@featurevisor/types";
 
import type { EvaluateOptions, Evaluation } from "./evaluate";
import type { Logger } from "./logger";
import type { BucketKey, BucketValue } from "./bucketer";
 
/**
 * bucketKey
 */
export interface ConfigureBucketKeyOptions {
  featureKey: FeatureKey;
  context: Context;
  bucketBy: BucketBy;
  bucketKey: string; // the initial bucket key, which can be modified by hooks
}
 
export type ConfigureBucketKey = (options: ConfigureBucketKeyOptions) => BucketKey;
 
/**
 * bucketValue
 */
export interface ConfigureBucketValueOptions {
  featureKey: FeatureKey;
  bucketKey: string;
  context: Context;
  bucketValue: number; // the initial bucket value, which can be modified by hooks
}
 
export type ConfigureBucketValue = (options: ConfigureBucketValueOptions) => BucketValue;
 
/**
 * Hooks
 */
export interface Hook {
  name: string;
 
  before?: (options: EvaluateOptions) => EvaluateOptions;
 
  bucketKey?: ConfigureBucketKey;
 
  bucketValue?: ConfigureBucketValue;
 
  after?: (evaluation: Evaluation, options: EvaluateOptions) => Evaluation;
}
 
export interface HooksManagerOptions {
  hooks?: Hook[];
  logger: Logger;
}
 
export class HooksManager {
  private hooks: Hook[] = [];
  private logger: Logger;
 
  constructor(options: HooksManagerOptions) {
    this.logger = options.logger;
 
    if (options.hooks) {
      options.hooks.forEach((hook) => {
        this.add(hook);
      });
    }
  }
 
  add(hook: Hook): (() => void) | undefined {
    Iif (this.hooks.some((existingHook) => existingHook.name === hook.name)) {
      this.logger.error(`Hook with name "${hook.name}" already exists.`, {
        name: hook.name,
        hook: hook,
      });
 
      return;
    }
 
    this.hooks.push(hook);
 
    return () => {
      this.remove(hook.name);
    };
  }
 
  remove(name: string): void {
    this.hooks = this.hooks.filter((hook) => hook.name !== name);
  }
 
  getAll(): Hook[] {
    return this.hooks;
  }
}