Skip to content

Commit e604038

Browse files
committed
ref tests, add some sort of effect api
implementation is wrong, but it just to have something kinda working, suggestions and help is welcome :)
1 parent 1e1424c commit e604038

File tree

4 files changed

+187
-131
lines changed

4 files changed

+187
-131
lines changed

src/apis/effect.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { watchEffect } from './watch';
2+
3+
export function isEffect(fn: any): fn is ReactiveEffect {
4+
return fn && fn._isEffect === true;
5+
}
6+
7+
export interface ReactiveEffect<T = any> {
8+
// (...args: any[]): T;
9+
(): T;
10+
_isEffect: true;
11+
id: number;
12+
active: boolean;
13+
raw: () => T;
14+
// deps: Array<Dep>;
15+
// options: ReactiveEffectOptions;
16+
options: any;
17+
}
18+
let uid = 0;
19+
20+
export function effect<T = any>(
21+
fn: () => T,
22+
options: any = {} //ReactiveEffectOptions = EMPTY_OBJ
23+
): ReactiveEffect<T> {
24+
if (isEffect(fn)) {
25+
fn = fn.raw;
26+
}
27+
// const effect = createReactiveEffect(fn, options);
28+
// if (!options.lazy) {
29+
// effect();
30+
// }
31+
// return effect;
32+
33+
// hacky stuff
34+
const effect: ReactiveEffect = () => {
35+
return fn();
36+
};
37+
38+
watchEffect(fn, {
39+
deep: true,
40+
flush: 'sync',
41+
});
42+
43+
if (!options.lazy) {
44+
effect();
45+
}
46+
47+
effect.id = uid++;
48+
effect._isEffect = true;
49+
effect.active = true;
50+
effect.raw = fn;
51+
// effect.deps = [];
52+
effect.options = options;
53+
return effect;
54+
}

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,6 @@ export { getCurrentVM as getCurrentInstance } from './runtimeContext';
3737
export * from './apis/state';
3838
export * from './apis/lifecycle';
3939
export * from './apis/watch';
40+
export * from './apis/effect';
4041
export * from './apis/computed';
4142
export * from './apis/inject';

src/reactivity/ref.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ type RefValue<T> = T extends Ref<infer V> ? V : UnwrapRef<T>;
8282

8383
// without init value, explicit typed: a = ref<{ a: number }>()
8484
// typeof a will be Ref<{ a: number } | undefined>
85-
export function ref<T = undefined>(): Ref<T | undefined>;
85+
export function ref<T = any>(): Ref<T | undefined>;
8686
// with null as init value: a = ref<{ a: number }>(null);
8787
// typeof a will be Ref<{ a: number } | null>
8888
export function ref<T = null>(raw: null): Ref<T | null>;

test/apis/ref.spec.ts

Lines changed: 131 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import {
22
ref,
33
// effect,
4-
// reactive,
4+
reactive,
55
isRef,
6-
// toRef,
7-
// toRefs,
6+
toRef,
7+
toRefs,
88
Ref,
99
// isReactive,
1010
computed,
11+
effect,
1112
} from '../../src';
1213
// import { shallowRef, unref, customRef } from '../src/ref'
1314

@@ -19,69 +20,69 @@ describe('reactivity/ref', () => {
1920
expect(a.value).toBe(2);
2021
});
2122

22-
// it('should be reactive', () => {
23-
// const a = ref(1);
24-
// let dummy;
25-
// effect(() => {
26-
// dummy = a.value;
27-
// });
28-
// expect(dummy).toBe(1);
29-
// a.value = 2;
30-
// expect(dummy).toBe(2);
31-
// });
32-
33-
// it('should make nested properties reactive', () => {
34-
// const a = ref({
35-
// count: 1,
36-
// });
37-
// let dummy;
38-
// effect(() => {
39-
// dummy = a.value.count;
40-
// });
41-
// expect(dummy).toBe(1);
42-
// a.value.count = 2;
43-
// expect(dummy).toBe(2);
44-
// });
45-
46-
// it('should work without initial value', () => {
47-
// const a = ref();
48-
// let dummy;
49-
// effect(() => {
50-
// dummy = a.value;
51-
// });
52-
// expect(dummy).toBe(undefined);
53-
// a.value = 2;
54-
// expect(dummy).toBe(2);
55-
// });
56-
57-
// it('should work like a normal property when nested in a reactive object', () => {
58-
// const a = ref(1);
59-
// const obj = reactive({
60-
// a,
61-
// b: {
62-
// c: a,
63-
// },
64-
// });
65-
66-
// let dummy1: number;
67-
// let dummy2: number;
23+
it('should be reactive', () => {
24+
const a = ref(1);
25+
let dummy;
26+
effect(() => {
27+
dummy = a.value;
28+
});
29+
expect(dummy).toBe(1);
30+
a.value = 2;
31+
expect(dummy).toBe(2);
32+
});
6833

69-
// effect(() => {
70-
// dummy1 = obj.a;
71-
// dummy2 = obj.b.c;
72-
// });
34+
it('should make nested properties reactive', () => {
35+
const a = ref({
36+
count: 1,
37+
});
38+
let dummy;
39+
effect(() => {
40+
dummy = a.value.count;
41+
});
42+
expect(dummy).toBe(1);
43+
a.value.count = 2;
44+
expect(dummy).toBe(2);
45+
});
7346

74-
// const assertDummiesEqualTo = (val: number) =>
75-
// [dummy1, dummy2].forEach(dummy => expect(dummy).toBe(val));
47+
it('should work without initial value', () => {
48+
const a = ref();
49+
let dummy;
50+
effect(() => {
51+
dummy = a.value;
52+
});
53+
expect(dummy).toBe(undefined);
54+
a.value = 2;
55+
expect(dummy).toBe(2);
56+
});
7657

77-
// assertDummiesEqualTo(1);
78-
// a.value++;
79-
// assertDummiesEqualTo(2);
80-
// obj.a++;
81-
// assertDummiesEqualTo(3);
82-
// obj.b.c++;
83-
// assertDummiesEqualTo(4);
84-
// });
58+
it('should work like a normal property when nested in a reactive object', () => {
59+
const a = ref(1);
60+
const obj = reactive({
61+
a,
62+
b: {
63+
c: a,
64+
},
65+
});
66+
67+
let dummy1: number;
68+
let dummy2: number;
69+
70+
effect(() => {
71+
dummy1 = obj.a;
72+
dummy2 = obj.b.c;
73+
});
74+
75+
const assertDummiesEqualTo = (val: number) =>
76+
[dummy1, dummy2].forEach(dummy => expect(dummy).toBe(val));
77+
78+
assertDummiesEqualTo(1);
79+
a.value++;
80+
assertDummiesEqualTo(2);
81+
obj.a++;
82+
assertDummiesEqualTo(3);
83+
obj.b.c++;
84+
assertDummiesEqualTo(4);
85+
});
8586

8687
it('should unwrap nested ref in types', () => {
8788
const a = ref(0);
@@ -184,74 +185,74 @@ describe('reactivity/ref', () => {
184185
expect(isRef({ value: 0 })).toBe(false);
185186
});
186187

187-
// test('toRef', () => {
188-
// const a = reactive({
189-
// x: 1,
190-
// });
191-
// const x = toRef(a, 'x');
192-
// expect(isRef(x)).toBe(true);
193-
// expect(x.value).toBe(1);
194-
195-
// // source -> proxy
196-
// a.x = 2;
197-
// expect(x.value).toBe(2);
198-
199-
// // proxy -> source
200-
// x.value = 3;
201-
// expect(a.x).toBe(3);
202-
203-
// // reactivity
204-
// let dummyX;
205-
// effect(() => {
206-
// dummyX = x.value;
207-
// });
208-
// expect(dummyX).toBe(x.value);
209-
210-
// // mutating source should trigger effect using the proxy refs
211-
// a.x = 4;
212-
// expect(dummyX).toBe(4);
213-
// });
214-
215-
// test('toRefs', () => {
216-
// const a = reactive({
217-
// x: 1,
218-
// y: 2,
219-
// });
220-
221-
// const { x, y } = toRefs(a);
222-
223-
// expect(isRef(x)).toBe(true);
224-
// expect(isRef(y)).toBe(true);
225-
// expect(x.value).toBe(1);
226-
// expect(y.value).toBe(2);
227-
228-
// // source -> proxy
229-
// a.x = 2;
230-
// a.y = 3;
231-
// expect(x.value).toBe(2);
232-
// expect(y.value).toBe(3);
233-
234-
// // proxy -> source
235-
// x.value = 3;
236-
// y.value = 4;
237-
// expect(a.x).toBe(3);
238-
// expect(a.y).toBe(4);
188+
test('toRef', () => {
189+
const a = reactive({
190+
x: 1,
191+
});
192+
const x = toRef(a, 'x');
193+
expect(isRef(x)).toBe(true);
194+
expect(x.value).toBe(1);
195+
196+
// source -> proxy
197+
a.x = 2;
198+
expect(x.value).toBe(2);
199+
200+
// proxy -> source
201+
x.value = 3;
202+
expect(a.x).toBe(3);
203+
204+
// reactivity
205+
let dummyX;
206+
effect(() => {
207+
dummyX = x.value;
208+
});
209+
expect(dummyX).toBe(x.value);
210+
211+
// mutating source should trigger effect using the proxy refs
212+
a.x = 4;
213+
expect(dummyX).toBe(4);
214+
});
239215

240-
// // reactivity
241-
// let dummyX, dummyY;
242-
// effect(() => {
243-
// dummyX = x.value;
244-
// dummyY = y.value;
245-
// });
246-
// expect(dummyX).toBe(x.value);
247-
// expect(dummyY).toBe(y.value);
248-
249-
// // mutating source should trigger effect using the proxy refs
250-
// a.x = 4;
251-
// a.y = 5;
252-
// expect(dummyX).toBe(4);
253-
// expect(dummyY).toBe(5);
254-
// });
216+
test('toRefs', () => {
217+
const a = reactive({
218+
x: 1,
219+
y: 2,
220+
});
221+
222+
const { x, y } = toRefs(a);
223+
224+
expect(isRef(x)).toBe(true);
225+
expect(isRef(y)).toBe(true);
226+
expect(x.value).toBe(1);
227+
expect(y.value).toBe(2);
228+
229+
// source -> proxy
230+
a.x = 2;
231+
a.y = 3;
232+
expect(x.value).toBe(2);
233+
expect(y.value).toBe(3);
234+
235+
// proxy -> source
236+
x.value = 3;
237+
y.value = 4;
238+
expect(a.x).toBe(3);
239+
expect(a.y).toBe(4);
240+
241+
// reactivity
242+
let dummyX, dummyY;
243+
effect(() => {
244+
dummyX = x.value;
245+
dummyY = y.value;
246+
});
247+
expect(dummyX).toBe(x.value);
248+
expect(dummyY).toBe(y.value);
249+
250+
// mutating source should trigger effect using the proxy refs
251+
a.x = 4;
252+
a.y = 5;
253+
expect(dummyX).toBe(4);
254+
expect(dummyY).toBe(5);
255+
});
255256

256257
// test('customRef', () => {
257258
// let value = 1;

0 commit comments

Comments
 (0)