import { targetMap } from '../proxy/reactive' ; const activeReactiveEffectStack = [ ] ; const EMPTY_OBJ = Object . freeze ( { } ) ; export function track ( target , key ) { const effect = activeReactiveEffectStack [ activeReactiveEffectStack . length - 1 ] ; if ( effect ) { let depsMap = targetMap . get ( target ) ; if ( depsMap === void 0 ) { targetMap . set ( target , ( depsMap = new Map ( ) ) ) ; } let dep = depsMap . get ( key ! ) ; if ( ! dep ) { depsMap . set ( key ! , ( dep = new Set ( ) ) ) ; } if ( ! dep . has ( effect ) ) { dep . add ( effect ) ; effect . deps . push ( dep ) ; } } } export function trigger ( target , key ? ) { const depsMap = targetMap . get ( target ) ; const effects = new Set ( ) ; if ( depsMap && depsMap . get ( key ) ) { depsMap . get ( key ) . forEach ( ( dep ) => { effects . add ( dep ) ; } ) ; effects . forEach ( ( e ) => e ( ) ) ; } } export function effect ( fn , options = EMPTY_OBJ ) { if ( ( fn as any ) . isEffect ) { fn = ( fn as any ) . raw ; } const effect = createReactiveEffect ( fn , options ) ; if ( ! options . lazy ) { effect ( ) ; } return effect ; } function createReactiveEffect ( fn , options ) { const effect = function effect ( ... args ) : any { return run ( effect as any , fn , args ) ; } as any ; effect . isEffect = true ; effect . active = true ; effect . raw = fn ; effect . scheduler = options . scheduler ; effect . onTrack = options . onTrack ; effect . onTrigger = options . onTrigger ; effect . onStop = options . onStop ; effect . computed = options . computed ; effect . deps = [ ] ; return effect ; } function run ( effect , fn , args ) { if ( ! effect . active ) { return fn ( ... args ) ; } if ( activeReactiveEffectStack . indexOf ( effect ) === - 1 ) { try { activeReactiveEffectStack . push ( effect ) ; return fn ( ... args ) ; } finally { activeReactiveEffectStack . pop ( ) ; } } }