-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcomputed.ts
70 lines (56 loc) · 2.34 KB
/
computed.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { ClassInfo } from '../info';
import { dataDescriptor, deferredDefineProperty, log } from '../utils';
/**
* Property decorator.
* Computed values are computed each time the store state is changed.
*/
export function computed(target: any, propertyKey: string | symbol): void {
const descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
if (typeof descriptor.get !== 'function')
throw new Error(`Failed to decorate '${propertyKey}'. The 'computed' decorator should only be used on getters.`);
if (descriptor.set)
throw new Error(`Failed to decorate '${propertyKey}'. Decorated property should not have a setter.`);
// store getter for later
const info = ClassInfo.getOrInitInfo(target);
info.computedGetters[propertyKey] = descriptor.get;
// and replace it with a simple data descriptor
return deferredDefineProperty(target, propertyKey, dataDescriptor);
}
export class Computed {
public static readonly placeholder = '<computed>';
/**
* Returns a shallow clone of 'state' with it's computed props replaced with
* Computed.placeholder.
*/
public static removeComputedProps(state: any, obj: any): any {
const info = ClassInfo.getInfo(obj);
if (!info)
return state;
const newState = Object.assign({}, state);
for (let propKey of Object.keys(info.computedGetters)) {
newState[propKey] = Computed.placeholder;
}
return newState;
}
/**
* Replace each computed property of 'obj' with it's current computed value.
*/
public static computeProps(obj: any): void {
// obj may be a component or any other object
const info = ClassInfo.getInfo(obj);
if (!info)
return;
for (let propKey of Object.keys(info.computedGetters)) {
// get old value
var getter = info.computedGetters[propKey];
log.verbose(`[computeProps] computing new value of '${propKey}'`);
var newValue = getter.call(obj);
// update if necessary
var oldValue = obj[propKey];
if (newValue !== oldValue) {
log.verbose(`[computeProps] updating the state of '${propKey}'. New value: '${newValue}', Old value: '${oldValue}'.`);
obj[propKey] = newValue;
}
}
}
}