wip: watch

This commit is contained in:
Evan You
2019-05-29 23:44:59 +08:00
parent dde6c151e4
commit 6441db45c7
10 changed files with 196 additions and 50 deletions

View File

@@ -15,12 +15,12 @@ export function computed<T, C = null>(
let value: any = undefined
const runner = effect(() => getter.call(context, context), {
lazy: true,
// mark effect as computed so that it gets priority during trigger
computed: true,
scheduler: () => {
dirty = true
}
})
// mark effect as computed so that it gets priority during trigger
runner.computed = true
const computedValue = {
// expose effect so computed can be stopped
effect: runner,

View File

@@ -15,6 +15,7 @@ export interface ReactiveEffect {
export interface ReactiveEffectOptions {
lazy?: boolean
computed?: boolean
scheduler?: Scheduler
onTrack?: Debugger
onTrigger?: Debugger
@@ -48,6 +49,7 @@ export function createReactiveEffect(
effect.scheduler = options.scheduler
effect.onTrack = options.onTrack
effect.onTrigger = options.onTrigger
effect.computed = options.computed
effect.deps = []
return effect
}

View File

@@ -24,13 +24,13 @@ import {
DebuggerEvent
} from './effect'
import { UnwrapBindings } from './value'
import { UnwrapValues } from './value'
export { ReactiveEffect, ReactiveEffectOptions, DebuggerEvent }
export { OperationTypes } from './operations'
export { computed, ComputedValue } from './computed'
export { lock, unlock } from './lock'
export { value, isValue, Value, UnwrapBindings } from './value'
export { value, isValue, Value, UnwrapValues } from './value'
const collectionTypes: Set<any> = new Set([Set, Map, WeakMap, WeakSet])
const observableValueRE = /^\[object (?:Object|Array|Map|Set|WeakMap|WeakSet)\]$/
@@ -44,7 +44,7 @@ const canObserve = (value: any): boolean => {
)
}
type ObservableFactory = <T>(target?: T) => UnwrapBindings<T>
type ObservableFactory = <T>(target?: T) => UnwrapValues<T>
export const observable = ((target: any = {}): any => {
// if trying to observe an immutable proxy, return the immutable version.

View File

@@ -9,12 +9,34 @@ export interface Value<T> {
value: T
}
const convert = (val: any): any => (isObject(val) ? observable(val) : val)
export function value<T>(raw: T): Value<T> {
raw = convert(raw)
const v = {
get value() {
track(v, OperationTypes.GET, '')
return raw
},
set value(newVal) {
raw = convert(newVal)
trigger(v, OperationTypes.SET, '')
}
}
knownValues.add(v)
return v
}
export function isValue(v: any): v is Value<any> {
return knownValues.has(v)
}
type UnwrapValue<T, U = T> = T extends Value<infer V> ? V : T extends {} ? U : T
// A utility type that recursively unwraps value bindings nested inside an
// observable object. Unfortunately TS cannot do recursive types, but this
// should be enough for practical use cases...
export type UnwrapBindings<T> = {
export type UnwrapValues<T> = {
[key in keyof T]: UnwrapValue<
T[key],
{
@@ -64,25 +86,3 @@ export type UnwrapBindings<T> = {
}
>
}
const convert = (val: any): any => (isObject(val) ? observable(val) : val)
export function value<T>(raw: T): Value<T> {
raw = convert(raw)
const v = {
get value() {
track(v, OperationTypes.GET, '')
return raw
},
set value(newVal) {
raw = convert(newVal)
trigger(v, OperationTypes.SET, '')
}
}
knownValues.add(v)
return v
}
export function isValue(v: any): boolean {
return knownValues.has(v)
}