import { track, trigger } from './effect'
import { LOCKED } from './lock'
import { isObject } from '@vue/shared'
+import { isValue } from './value'
const hasOwnProperty = Object.prototype.hasOwnProperty
if (typeof key === 'symbol' && builtInSymbols.has(key)) {
return res
}
+ if (isValue(res)) {
+ return res.value
+ }
track(target, OperationTypes.GET, key)
return isObject(res)
? isImmutable
value = unwrap(value)
const hadKey = hasOwnProperty.call(target, key)
const oldValue = target[key]
+ if (isValue(oldValue)) {
+ oldValue.value = value
+ return true
+ }
const result = Reflect.set(target, key, value, receiver)
// don't trigger if target is something up in the prototype chain of original
if (target === unwrap(receiver)) {
import { OperationTypes } from './operations'
-import { Dep, KeyToDepMap, targetMap } from './state'
+import { Dep, targetMap } from './state'
export interface ReactiveEffect {
(): any
if (type === OperationTypes.ITERATE) {
key = ITERATE_KEY
}
- // keyMap must exist because only an observed target can call this function
- const depsMap = targetMap.get(target) as KeyToDepMap
+ let depsMap = targetMap.get(target)
+ if (depsMap === void 0) {
+ targetMap.set(target, (depsMap = new Map()))
+ }
let dep = depsMap.get(key as string | symbol)
if (!dep) {
depsMap.set(key as string | symbol, (dep = new Set()))
key?: string | symbol,
extraInfo?: any
) {
- const depsMap = targetMap.get(target) as KeyToDepMap
+ const depsMap = targetMap.get(target)
+ if (depsMap === void 0) {
+ // never been tracked
+ return
+ }
const effects = new Set()
const computedRunners = new Set()
if (type === OperationTypes.CLEAR) {
export { OperationTypes } from './operations'
export { computed, ComputedGetter } from './computed'
export { lock, unlock } from './lock'
+export { value, isValue } from './value'
const collectionTypes: Set<any> = new Set([Set, Map, WeakMap, WeakSet])
const observableValueRE = /^\[object (?:Object|Array|Map|Set|WeakMap|WeakSet)\]$/
--- /dev/null
+import { track, trigger } from './effect'
+import { OperationTypes } from './operations'
+
+const knownValues = new WeakSet()
+
+export interface Value<T> {
+ value: T
+}
+
+export function value<T>(raw: T): Value<T> {
+ const v = {
+ get value() {
+ track(v, OperationTypes.GET, '')
+ return raw
+ },
+ set value(newVal) {
+ raw = newVal
+ trigger(v, OperationTypes.SET, '')
+ }
+ }
+ knownValues.add(v)
+ return v
+}
+
+export function isValue(v: any): boolean {
+ return knownValues.has(v)
+}
import { ComponentInstance } from './component'
-import { isObservable, unwrap } from '@vue/observer'
-
-// TODO use proper implementation
-function isValue(binding: any) {
- return isObservable(binding) && unwrap(binding).hasOwnProperty('value')
-}
export const RenderProxyHandlers = {
get(target: ComponentInstance, key: string) {
const { state, props } = target
if (state.hasOwnProperty(key)) {
- const value = state[key]
- return isValue(value) ? value.value : value
+ return state[key]
} else if (props.hasOwnProperty(key)) {
return props[key]
} else {
set(target: ComponentInstance, key: string, value: any): boolean {
const { state } = target
if (state.hasOwnProperty(key)) {
- const binding = state[key]
- if (isValue(binding)) {
- binding.value = value
- } else {
- state[key] = value
- }
+ state[key] = value
return true
} else {
if (__DEV__) {
} else {
if (__DEV__ && !isFunction(type) && !isObject(type)) {
// TODO warn invalid node type
+ debugger
}
processComponent(n1, n2, container, anchor)
}