/* IMPORT */ import get from '~/methods/get'; import isObservableBoolean from '~/methods/is_observable_boolean'; import isObservableFrozen from '~/methods/is_observable_frozen'; import isUntracked from '~/methods/is_untracked'; import memo from '~/methods/memo'; import resolve from '~/methods/resolve'; import warmup from '~/methods/warmup'; import {frozen} from '~/objects/callable'; import {is, isFunction} from '~/utils'; import type {ObservableReadonly, FunctionMaybe, Resolved} from '~/types'; /* HELPERS */ const match = ( condition: T, values: ([T, R] | [R])[], fallback?: F ): R | F | undefined => { for ( let i = 0, l = values.length; i < l; i++ ) { const value = values[i]; if ( value.length === 1 ) return value[0]; if ( is ( value[0], condition ) ) return value[1]; } return fallback; }; /* MAIN */ function _switch ( when: FunctionMaybe, values: [...[T, R][], [R]], fallback?: undefined ): ObservableReadonly>; function _switch ( when: FunctionMaybe, values: [...[T, R][], [R]], fallback: F ): ObservableReadonly>; function _switch ( when: FunctionMaybe, values: [T, R][], fallback?: undefined ): ObservableReadonly>; function _switch ( when: FunctionMaybe, values: [T, R][], fallback: F ): ObservableReadonly>; function _switch ( when: FunctionMaybe, values: ([T, R] | [R])[], fallback?: F ): ObservableReadonly> { const isDynamic = isFunction ( when ) && !isObservableFrozen ( when ) && !isUntracked ( when ); if ( isDynamic ) { if ( isObservableBoolean ( when ) ) { return memo ( () => resolve ( match ( when (), values, fallback ) ) ); } const value = warmup ( memo ( () => match ( when (), values, fallback ) ) ); if ( isObservableFrozen ( value ) ) { return frozen ( resolve ( value () ) ); } else { return memo ( () => resolve ( get ( value ) ) ); } } else { const value = match ( get ( when ), values, fallback ); return frozen ( resolve ( value ) ); } } /* EXPORT */ export default _switch;