UNPKG

2 kBPlain TextView Raw
1import {
2 ComputedValue,
3 IComputedValueOptions,
4 Annotation,
5 storeAnnotation,
6 createDecoratorAnnotation,
7 isStringish,
8 isPlainObject,
9 isFunction,
10 die,
11 IComputedValue,
12 createComputedAnnotation,
13 comparer
14} from "../internal"
15
16export const COMPUTED = "computed"
17export const COMPUTED_STRUCT = "computed.struct"
18
19export interface IComputedFactory extends Annotation, PropertyDecorator {
20 // @computed(opts)
21 <T>(options: IComputedValueOptions<T>): Annotation & PropertyDecorator
22 // computed(fn, opts)
23 <T>(func: () => T, options?: IComputedValueOptions<T>): IComputedValue<T>
24
25 struct: Annotation & PropertyDecorator
26}
27
28const computedAnnotation = createComputedAnnotation(COMPUTED)
29const computedStructAnnotation = createComputedAnnotation(COMPUTED_STRUCT, {
30 equals: comparer.structural
31})
32
33/**
34 * Decorator for class properties: @computed get value() { return expr; }.
35 * For legacy purposes also invokable as ES5 observable created: `computed(() => expr)`;
36 */
37export const computed: IComputedFactory = function computed(arg1, arg2) {
38 if (isStringish(arg2)) {
39 // @computed
40 return storeAnnotation(arg1, arg2, computedAnnotation)
41 }
42 if (isPlainObject(arg1)) {
43 // @computed({ options })
44 return createDecoratorAnnotation(createComputedAnnotation(COMPUTED, arg1))
45 }
46
47 // computed(expr, options?)
48 if (__DEV__) {
49 if (!isFunction(arg1)) die("First argument to `computed` should be an expression.")
50 if (isFunction(arg2))
51 die(
52 "A setter as second argument is no longer supported, use `{ set: fn }` option instead"
53 )
54 }
55 const opts: IComputedValueOptions<any> = isPlainObject(arg2) ? arg2 : {}
56 opts.get = arg1
57 opts.name ||= arg1.name || "" /* for generated name */
58
59 return new ComputedValue(opts)
60} as any
61
62Object.assign(computed, computedAnnotation)
63
64computed.struct = createDecoratorAnnotation(computedStructAnnotation)
65
\No newline at end of file