import { Config } from "./define" ; import { compute } from "./compute" ; const DERIVE_FUNCTION_KEY = "derived" ; interface DerivedFunction < Base , Output > { ( result , values , invocations , path , override , computedKeys ) : Output ; __cooky_cutter : typeof DERIVE_FUNCTION_KEY ; } param fn param dependentKeys function derive < Base extends object , Output > ( fn , ... dependentKeys ) { const derivedFunction = function ( result , values , invocations , path , override , computedKeys ) { const input = dependentKeys . reduce < Partial < Base > > ( ( input , key ) => { if ( ! result . hasOwnProperty ( key ) ) { if ( path . indexOf ( key ) > - 1 ) { throw `${ key } cannot circularly derive itself. Check along this path: ${ path . join ( "->" ) }->${ key }` ; } compute ( key , values , result , invocations , [ ... path , key ] , override , computedKeys ) ; } input [ key ] = result [ key ] ; return input ; } , { } as Partial < Base > ) ; return fn ( input ) ; } ; derivedFunction . __cooky_cutter = DERIVE_FUNCTION_KEY as typeof DERIVE_FUNCTION_KEY ; return derivedFunction ; } export { derive , DerivedFunction , DERIVE_FUNCTION_KEY } ;