All files / src compute.ts

100% Statements 28/28
100% Branches 8/8
100% Functions 2/2
100% Lines 28/28

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 422x   2x           2x 127x   127x 287x 287x   283x   283x 287x   127x 224x 224x   224x 99x 139x 139x 99x   224x 224x 224x 224x 224x 224x 224x 127x   127x 127x  
import { ReadableImpl } from "./readable";
import { type ReadableLike, type Config, type Get, type OwnedReadable } from "./typings";
import { getReadable } from "./utils";
 
export interface ComputeFn<TValue = any> {
  (get: Get): TValue;
}
 
export const compute = <TValue>(fn: ComputeFn<TValue>, config?: Config<TValue>): OwnedReadable<TValue> => {
  let running: boolean | undefined;
 
  const get: Get = ($?: ReadableLike): unknown => {
    const readable = getReadable($);
    if (!readable) return $;
 
    self.addDep_(readable as ReadableImpl);
 
    return readable.get();
  };
 
  const self = new ReadableImpl(self => {
    const isFirst = !running;
    running = true;
 
    if (isFirst && self.deps_?.size) {
      for (const dep of self.deps_.keys()) {
        self.removeDep_(dep);
      }
    }
 
    try {
      return fn(get);
    } finally {
      if (isFirst) {
        running = false;
      }
    }
  }, config);
 
  return self;
};