-import { computed, reactive, effect, stop } from '../src'
+import { computed, reactive, effect, stop, ref } from '../src'
describe('reactivity/computed', () => {
it('should return updated value', () => {
})
it('should support setter', () => {
- // TODO
+ const n = ref(1)
+ const plusOne = computed({
+ get: () => n.value + 1,
+ set: val => {
+ n.value = val - 1
+ }
+ })
+
+ expect(plusOne.value).toBe(2)
+ n.value++
+ expect(plusOne.value).toBe(3)
+
+ plusOne.value = 0
+ expect(n.value).toBe(-1)
+ })
+
+ it('should trigger effect w/ setter', () => {
+ const n = ref(1)
+ const plusOne = computed({
+ get: () => n.value + 1,
+ set: val => {
+ n.value = val - 1
+ }
+ })
+
+ let dummy
+ effect(() => {
+ dummy = n.value
+ })
+ expect(dummy).toBe(1)
+
+ plusOne.value = 0
+ expect(dummy).toBe(-1)
})
})
})
it('should not allow mutation', () => {
- const observed = immutable({ foo: 1, bar: { baz: 2 } })
+ const observed: any = immutable({ foo: 1, bar: { baz: 2 } })
observed.foo = 2
expect(observed.foo).toBe(1)
expect(warn).toHaveBeenCalledTimes(1)
})
it('should not trigger effects when locked', () => {
- const observed = immutable({ a: 1 })
+ const observed: any = immutable({ a: 1 })
let dummy
effect(() => {
dummy = observed.a
})
it('should trigger effects when unlocked', () => {
- const observed = immutable({ a: 1 })
+ const observed: any = immutable({ a: 1 })
let dummy
effect(() => {
dummy = observed.a
})
it('should allow mutation when unlocked', () => {
- const observed: any[] = immutable([{ foo: 1, bar: { baz: 2 } }])
+ const observed: any = immutable([{ foo: 1, bar: { baz: 2 } }])
unlock()
observed[1] = 2
observed.push(3)
})
it('should not trigger effects when locked', () => {
- const observed = immutable([{ a: 1 }])
+ const observed: any = immutable([{ a: 1 }])
let dummy
effect(() => {
dummy = observed[0].a
})
it('should trigger effects when unlocked', () => {
- const observed = immutable([{ a: 1 }])
+ const observed: any = immutable([{ a: 1 }])
let dummy
effect(() => {
dummy = observed[0].a
const key1 = {}
const key2 = {}
const original = new Collection([[key1, {}], [key2, {}]])
- const observed = immutable(original)
+ const observed: any = immutable(original)
for (const [key, value] of observed) {
expect(isImmutable(key)).toBe(true)
expect(isImmutable(value)).toBe(true)
if (Collection === Set) {
test('should retrive immutable values on iteration', () => {
const original = new Collection([{}, {}])
- const observed = immutable(original)
+ const observed: any = immutable(original)
for (const value of observed) {
expect(isImmutable(value)).toBe(true)
}
expect(dummy).toBe(2)
})
- it('should work like a normal property when nested in an observable', () => {
+ it('should work like a normal property when nested in a reactive object', () => {
const a = ref(1)
const obj = reactive({
a,
import { effect, ReactiveEffect, activeReactiveEffectStack } from './effect'
-import { UnwrapNestedRefs, knownRefs } from './ref'
+import { UnwrapNestedRefs, knownRefs, Ref } from './ref'
import { isFunction } from '@vue/shared'
export interface ComputedRef<T> {
set: (v: T) => void
}
+export function computed<T>(getter: () => T): ComputedRef<T>
+export function computed<T>(options: ComputedOptions<T>): Ref<T>
export function computed<T>(
getterOrOptions: (() => T) | ComputedOptions<T>
-): ComputedRef<T> {
+): Ref<T> {
const isReadonly = isFunction(getterOrOptions)
const getter = isReadonly
? (getterOrOptions as (() => T))
immutableCollectionHandlers
} from './collectionHandlers'
-import { UnwrapRef } from './ref'
+import { UnwrapNestedRefs } from './ref'
import { ReactiveEffect } from './effect'
// The main WeakMap that stores {target -> key -> dep} connections.
)
}
-type ObservableFactory = <T>(target?: T) => UnwrapRef<T>
-
-export const reactive = ((target: unknown): any => {
+export function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
+export function reactive(target: object) {
// if trying to observe an immutable proxy, return the immutable version.
if (immutableToRaw.has(target)) {
return target
mutableHandlers,
mutableCollectionHandlers
)
-}) as ObservableFactory
+}
-export const immutable = ((target: unknown): any => {
+export function immutable<T extends object>(
+ target: T
+): Readonly<UnwrapNestedRefs<T>>
+export function immutable(target: object) {
// value is a mutable observable, retrive its original and return
// a readonly version.
if (observedToRaw.has(target)) {
immutableHandlers,
immutableCollectionHandlers
)
-}) as ObservableFactory
+}
function createReactiveObject(
target: any,
} from '@vue/reactivity'
import {
+ Ref,
computed as _computed,
ComputedRef,
ComputedOptions,
}
}
-export function computed<T>(
- getterOrOptions: (() => T) | ComputedOptions<T>
-): ComputedRef<T> {
+export function computed<T>(getter: () => T): ComputedRef<T>
+export function computed<T>(options: ComputedOptions<T>): Ref<T>
+export function computed<T>(getterOrOptions: any) {
const c = _computed(getterOrOptions)
recordEffect(c.effect)
return c