|
|
@@ -1,15 +1,16 @@
|
|
|
import { effect } from './index'
|
|
|
import { ReactiveEffect, activeReactiveEffectStack } from './effect'
|
|
|
+import { knownValues } from './value'
|
|
|
|
|
|
-export interface ComputedGetter<T = any> {
|
|
|
- (): T
|
|
|
- effect: ReactiveEffect
|
|
|
+export interface ComputedValue<T> {
|
|
|
+ readonly value: T
|
|
|
+ readonly effect: ReactiveEffect
|
|
|
}
|
|
|
|
|
|
export function computed<T, C = null>(
|
|
|
getter: (this: C, ctx: C) => T,
|
|
|
context?: C
|
|
|
-): ComputedGetter<T> {
|
|
|
+): ComputedValue<T> {
|
|
|
let dirty: boolean = true
|
|
|
let value: any = undefined
|
|
|
const runner = effect(() => getter.call(context, context), {
|
|
|
@@ -18,22 +19,25 @@ export function computed<T, C = null>(
|
|
|
dirty = true
|
|
|
}
|
|
|
})
|
|
|
- const computedGetter = (() => {
|
|
|
- if (dirty) {
|
|
|
- value = runner()
|
|
|
- dirty = false
|
|
|
- }
|
|
|
- // When computed effects are accessed in a parent effect, the parent
|
|
|
- // should track all the dependencies the computed property has tracked.
|
|
|
- // This should also apply for chained computed properties.
|
|
|
- trackChildRun(runner)
|
|
|
- return value
|
|
|
- }) as ComputedGetter
|
|
|
- // expose effect so computed can be stopped
|
|
|
- computedGetter.effect = runner
|
|
|
// mark effect as computed so that it gets priority during trigger
|
|
|
runner.computed = true
|
|
|
- return computedGetter
|
|
|
+ const computedValue = {
|
|
|
+ // expose effect so computed can be stopped
|
|
|
+ effect: runner,
|
|
|
+ get value() {
|
|
|
+ if (dirty) {
|
|
|
+ value = runner()
|
|
|
+ dirty = false
|
|
|
+ }
|
|
|
+ // When computed effects are accessed in a parent effect, the parent
|
|
|
+ // should track all the dependencies the computed property has tracked.
|
|
|
+ // This should also apply for chained computed properties.
|
|
|
+ trackChildRun(runner)
|
|
|
+ return value
|
|
|
+ }
|
|
|
+ }
|
|
|
+ knownValues.add(computedValue)
|
|
|
+ return computedValue
|
|
|
}
|
|
|
|
|
|
function trackChildRun(childRunner: ReactiveEffect) {
|