All files observable-crate.ts

100% Statements 53/53
87.5% Branches 7/8
100% Functions 5/5
100% Lines 53/53

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 541x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 8x 8x 8x 8x 45x 45x 8x 8x 8x 1x 1x 8x 8x 8x 8x 8x 2x 2x 8x 3x 3x 3x 3x 3x 3x 3x 8x 8x  
/**
 * Copyright (c) OpenLens Authors. All rights reserved.
 * Licensed under MIT License. See LICENSE in root directory for more information.
 */
 
import { observable, runInAction } from "mobx";
import { getOrInsertMap } from "./collection-functions";
import { noop } from "./noop";
 
export interface ObservableCrate<T> {
  get(): T;
  set(value: T): void;
}
 
export interface ObservableCrateFactory {
  <T>(initialValue: T, transitionHandlers?: ObservableCrateTransitionHandlers<T>): ObservableCrate<T>;
}
 
export interface ObservableCrateTransitionHandler<T> {
  from: T;
  to: T;
  onTransition: () => void;
}
export type ObservableCrateTransitionHandlers<T> = ObservableCrateTransitionHandler<T>[];
 
function convertToHandlersMap<T>(handlers: ObservableCrateTransitionHandlers<T>): Map<T, Map<T, () => void>> {
  const res: ReturnType<typeof convertToHandlersMap<T>> = new Map();
 
  for (const { from, to, onTransition } of handlers) {
    getOrInsertMap(res, from).set(to, onTransition);
  }
 
  return res;
}
 
export const observableCrate = ((initialValue, transitionHandlers = []) => {
  const crate = observable.box(initialValue);
  const handlers = convertToHandlersMap(transitionHandlers);
 
  return {
    get() {
      return crate.get();
    },
    set(value) {
      const onTransition = handlers.get(crate.get())?.get(value) ?? noop;
 
      runInAction(() => {
        crate.set(value);
        onTransition();
      });
    },
  };
}) as ObservableCrateFactory;