-import { value } from '../src/value'
-import { effect, state } from '../src/index'
+import { value, effect, state } from '../src/index'
describe('observer/value', () => {
it('should hold a value', () => {
import { OperationTypes } from './operations'
import { Dep, targetMap } from './state'
+import { EMPTY_OBJ } from '@vue/shared'
export interface ReactiveEffect {
(): any
export const ITERATE_KEY = Symbol('iterate')
-export function createReactiveEffect(
+export function effect(
+ fn: Function,
+ options: ReactiveEffectOptions = EMPTY_OBJ
+): ReactiveEffect {
+ if ((fn as ReactiveEffect).isEffect) {
+ fn = (fn as ReactiveEffect).raw
+ }
+ const effect = createReactiveEffect(fn, options)
+ if (!options.lazy) {
+ effect()
+ }
+ return effect
+}
+
+export function stop(effect: ReactiveEffect) {
+ if (effect.active) {
+ cleanup(effect)
+ if (effect.onStop) {
+ effect.onStop()
+ }
+ effect.active = false
+ }
+}
+
+function createReactiveEffect(
fn: Function,
options: ReactiveEffectOptions
): ReactiveEffect {
}
}
-export function cleanup(effect: ReactiveEffect) {
+function cleanup(effect: ReactiveEffect) {
const { deps } = effect
if (deps.length) {
for (let i = 0; i < deps.length; i++) {
-import { isObject, EMPTY_OBJ } from '@vue/shared'
-import { mutableHandlers, immutableHandlers } from './baseHandlers'
-
-import {
- mutableCollectionHandlers,
- immutableCollectionHandlers
-} from './collectionHandlers'
-
-import {
- targetMap,
- observedToRaw,
- rawToObserved,
- immutableToRaw,
- rawToImmutable,
- immutableValues,
- nonReactiveValues
+export { value, isValue, Value, UnwrapValue } from './value'
+export {
+ state,
+ isState,
+ immutableState,
+ isImmutableState,
+ toRaw,
+ markImmutable,
+ markNonReactive
} from './state'
-
-import {
- createReactiveEffect,
- cleanup,
+export { computed, ComputedValue } from './computed'
+export {
+ effect,
+ stop,
ReactiveEffect,
ReactiveEffectOptions,
DebuggerEvent
} from './effect'
-
-import { UnwrapValue } from './value'
-
-export { ReactiveEffect, ReactiveEffectOptions, DebuggerEvent }
-export { OperationTypes } from './operations'
-export { computed, ComputedValue } from './computed'
export { lock, unlock } from './lock'
-export { value, isValue, Value, UnwrapValue } from './value'
-
-const collectionTypes: Set<any> = new Set([Set, Map, WeakMap, WeakSet])
-const observableValueRE = /^\[object (?:Object|Array|Map|Set|WeakMap|WeakSet)\]$/
-
-const canObserve = (value: any): boolean => {
- return (
- !value._isVue &&
- !value._isVNode &&
- observableValueRE.test(Object.prototype.toString.call(value)) &&
- !nonReactiveValues.has(value)
- )
-}
-
-type ObservableFactory = <T>(target?: T) => UnwrapValue<T>
-
-export const state = ((target: any = {}): any => {
- // if trying to observe an immutable proxy, return the immutable version.
- if (immutableToRaw.has(target)) {
- return target
- }
- // target is explicitly marked as immutable by user
- if (immutableValues.has(target)) {
- return immutableState(target)
- }
- return createObservable(
- target,
- rawToObserved,
- observedToRaw,
- mutableHandlers,
- mutableCollectionHandlers
- )
-}) as ObservableFactory
-
-export const immutableState = ((target: any = {}): any => {
- // value is a mutable observable, retrive its original and return
- // a readonly version.
- if (observedToRaw.has(target)) {
- target = observedToRaw.get(target)
- }
- return createObservable(
- target,
- rawToImmutable,
- immutableToRaw,
- immutableHandlers,
- immutableCollectionHandlers
- )
-}) as ObservableFactory
-
-function createObservable(
- target: any,
- toProxy: WeakMap<any, any>,
- toRaw: WeakMap<any, any>,
- baseHandlers: ProxyHandler<any>,
- collectionHandlers: ProxyHandler<any>
-) {
- if (!isObject(target)) {
- if (__DEV__) {
- console.warn(`value is not observable: ${String(target)}`)
- }
- return target
- }
- // target already has corresponding Proxy
- let observed = toProxy.get(target)
- if (observed !== void 0) {
- return observed
- }
- // target is already a Proxy
- if (toRaw.has(target)) {
- return target
- }
- // only a whitelist of value types can be observed.
- if (!canObserve(target)) {
- return target
- }
- const handlers = collectionTypes.has(target.constructor)
- ? collectionHandlers
- : baseHandlers
- observed = new Proxy(target, handlers)
- toProxy.set(target, observed)
- toRaw.set(observed, target)
- if (!targetMap.has(target)) {
- targetMap.set(target, new Map())
- }
- return observed
-}
-
-export function effect(
- fn: Function,
- options: ReactiveEffectOptions = EMPTY_OBJ
-): ReactiveEffect {
- if ((fn as ReactiveEffect).isEffect) {
- fn = (fn as ReactiveEffect).raw
- }
- const effect = createReactiveEffect(fn, options)
- if (!options.lazy) {
- effect()
- }
- return effect
-}
-
-export function stop(effect: ReactiveEffect) {
- if (effect.active) {
- cleanup(effect)
- if (effect.onStop) {
- effect.onStop()
- }
- effect.active = false
- }
-}
-
-export function isState(value: any): boolean {
- return observedToRaw.has(value) || immutableToRaw.has(value)
-}
-
-export function isImmutableState(value: any): boolean {
- return immutableToRaw.has(value)
-}
-
-export function toRaw<T>(observed: T): T {
- return observedToRaw.get(observed) || immutableToRaw.get(observed) || observed
-}
-
-export function markImmutable<T>(value: T): T {
- immutableValues.add(value)
- return value
-}
-
-export function markNonReactive<T>(value: T): T {
- nonReactiveValues.add(value)
- return value
-}
+export { OperationTypes } from './operations'
+import { isObject } from '@vue/shared'
+import { mutableHandlers, immutableHandlers } from './baseHandlers'
+
+import {
+ mutableCollectionHandlers,
+ immutableCollectionHandlers
+} from './collectionHandlers'
+
+import { UnwrapValue } from './value'
import { ReactiveEffect } from './effect'
// The main WeakMap that stores {target -> key -> dep} connections.
export const targetMap: WeakMap<any, KeyToDepMap> = new WeakMap()
// WeakMaps that store {raw <-> observed} pairs.
-export const rawToObserved: WeakMap<any, any> = new WeakMap()
-export const observedToRaw: WeakMap<any, any> = new WeakMap()
-export const rawToImmutable: WeakMap<any, any> = new WeakMap()
-export const immutableToRaw: WeakMap<any, any> = new WeakMap()
+const rawToObserved: WeakMap<any, any> = new WeakMap()
+const observedToRaw: WeakMap<any, any> = new WeakMap()
+const rawToImmutable: WeakMap<any, any> = new WeakMap()
+const immutableToRaw: WeakMap<any, any> = new WeakMap()
// WeakSets for values that are marked immutable or non-reactive during
// observable creation.
-export const immutableValues: WeakSet<any> = new WeakSet()
-export const nonReactiveValues: WeakSet<any> = new WeakSet()
+const immutableValues: WeakSet<any> = new WeakSet()
+const nonReactiveValues: WeakSet<any> = new WeakSet()
+
+const collectionTypes: Set<any> = new Set([Set, Map, WeakMap, WeakSet])
+const observableValueRE = /^\[object (?:Object|Array|Map|Set|WeakMap|WeakSet)\]$/
+
+const canObserve = (value: any): boolean => {
+ return (
+ !value._isVue &&
+ !value._isVNode &&
+ observableValueRE.test(Object.prototype.toString.call(value)) &&
+ !nonReactiveValues.has(value)
+ )
+}
+
+type ObservableFactory = <T>(target?: T) => UnwrapValue<T>
+
+export const state = ((target: any = {}): any => {
+ // if trying to observe an immutable proxy, return the immutable version.
+ if (immutableToRaw.has(target)) {
+ return target
+ }
+ // target is explicitly marked as immutable by user
+ if (immutableValues.has(target)) {
+ return immutableState(target)
+ }
+ return createObservable(
+ target,
+ rawToObserved,
+ observedToRaw,
+ mutableHandlers,
+ mutableCollectionHandlers
+ )
+}) as ObservableFactory
+
+export const immutableState = ((target: any = {}): any => {
+ // value is a mutable observable, retrive its original and return
+ // a readonly version.
+ if (observedToRaw.has(target)) {
+ target = observedToRaw.get(target)
+ }
+ return createObservable(
+ target,
+ rawToImmutable,
+ immutableToRaw,
+ immutableHandlers,
+ immutableCollectionHandlers
+ )
+}) as ObservableFactory
+
+function createObservable(
+ target: any,
+ toProxy: WeakMap<any, any>,
+ toRaw: WeakMap<any, any>,
+ baseHandlers: ProxyHandler<any>,
+ collectionHandlers: ProxyHandler<any>
+) {
+ if (!isObject(target)) {
+ if (__DEV__) {
+ console.warn(`value is not observable: ${String(target)}`)
+ }
+ return target
+ }
+ // target already has corresponding Proxy
+ let observed = toProxy.get(target)
+ if (observed !== void 0) {
+ return observed
+ }
+ // target is already a Proxy
+ if (toRaw.has(target)) {
+ return target
+ }
+ // only a whitelist of value types can be observed.
+ if (!canObserve(target)) {
+ return target
+ }
+ const handlers = collectionTypes.has(target.constructor)
+ ? collectionHandlers
+ : baseHandlers
+ observed = new Proxy(target, handlers)
+ toProxy.set(target, observed)
+ toRaw.set(observed, target)
+ if (!targetMap.has(target)) {
+ targetMap.set(target, new Map())
+ }
+ return observed
+}
+
+export function isState(value: any): boolean {
+ return observedToRaw.has(value) || immutableToRaw.has(value)
+}
+
+export function isImmutableState(value: any): boolean {
+ return immutableToRaw.has(value)
+}
+
+export function toRaw<T>(observed: T): T {
+ return observedToRaw.get(observed) || immutableToRaw.get(observed) || observed
+}
+
+export function markImmutable<T>(value: T): T {
+ immutableValues.add(value)
+ return value
+}
+
+export function markNonReactive<T>(value: T): T {
+ nonReactiveValues.add(value)
+ return value
+}