mobx 6.1.8 → 6.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -5
- package/README.md +2 -1
- package/dist/api/annotation.d.ts +6 -12
- package/dist/api/flow.d.ts +1 -0
- package/dist/api/object-api.d.ts +2 -0
- package/dist/errors.d.ts +2 -0
- package/dist/internal.d.ts +1 -0
- package/dist/mobx.cjs.development.js +322 -310
- package/dist/mobx.cjs.development.js.map +1 -1
- package/dist/mobx.cjs.production.min.js +1 -1
- package/dist/mobx.cjs.production.min.js.map +1 -1
- package/dist/mobx.d.ts +1 -1
- package/dist/mobx.esm.development.js +320 -311
- package/dist/mobx.esm.development.js.map +1 -1
- package/dist/mobx.esm.js +320 -311
- package/dist/mobx.esm.js.map +1 -1
- package/dist/mobx.esm.production.min.js +1 -1
- package/dist/mobx.esm.production.min.js.map +1 -1
- package/dist/mobx.umd.development.js +322 -310
- package/dist/mobx.umd.development.js.map +1 -1
- package/dist/mobx.umd.production.min.js +1 -1
- package/dist/mobx.umd.production.min.js.map +1 -1
- package/dist/types/actionannotation.d.ts +7 -1
- package/dist/types/autoannotation.d.ts +3 -0
- package/dist/types/observableobject.d.ts +4 -7
- package/package.json +1 -1
- package/src/api/annotation.ts +13 -42
- package/src/api/flow.ts +6 -1
- package/src/api/makeObservable.ts +25 -34
- package/src/api/object-api.ts +14 -0
- package/src/api/observable.ts +3 -8
- package/src/api/tojs.ts +10 -7
- package/src/core/observable.ts +7 -6
- package/src/errors.ts +14 -1
- package/src/internal.ts +1 -0
- package/src/mobx.ts +4 -0
- package/src/types/actionannotation.ts +27 -51
- package/src/types/autoannotation.ts +107 -0
- package/src/types/computedannotation.ts +7 -37
- package/src/types/dynamicobject.ts +1 -1
- package/src/types/flowannotation.ts +31 -42
- package/src/types/modifiers.ts +13 -2
- package/src/types/observableannotation.ts +7 -34
- package/src/types/observableobject.ts +34 -63
- package/src/types/overrideannotation.ts +4 -2
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
import { Annotation } from "../internal";
|
|
1
|
+
import { ObservableObjectAdministration, Annotation } from "../internal";
|
|
2
2
|
export declare function createActionAnnotation(name: string, options?: object): Annotation;
|
|
3
|
+
export declare function createActionDescriptor(adm: ObservableObjectAdministration, annotation: Annotation, key: PropertyKey, descriptor: PropertyDescriptor, safeDescriptors?: boolean): {
|
|
4
|
+
value: Function;
|
|
5
|
+
configurable: boolean;
|
|
6
|
+
enumerable: boolean;
|
|
7
|
+
writable: boolean;
|
|
8
|
+
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { CreateObservableOptions, Annotation, ComputedValue, IAtom, IComputedValueOptions, IEnhancer, IInterceptable, IListenable, Lambda, ObservableValue } from "../internal";
|
|
2
|
-
export declare const inferredAnnotationsSymbol: unique symbol;
|
|
3
2
|
export declare type IObjectDidChange<T = any> = {
|
|
4
3
|
observableKind: "object";
|
|
5
4
|
name: PropertyKey;
|
|
@@ -31,7 +30,6 @@ export declare class ObservableObjectAdministration implements IInterceptable<IO
|
|
|
31
30
|
values_: Map<string | number | symbol, ObservableValue<any> | ComputedValue<any>>;
|
|
32
31
|
name_: string;
|
|
33
32
|
defaultAnnotation_: Annotation;
|
|
34
|
-
autoBind_: boolean;
|
|
35
33
|
keysAtom_: IAtom;
|
|
36
34
|
changeListeners_: any;
|
|
37
35
|
interceptors_: any;
|
|
@@ -39,14 +37,14 @@ export declare class ObservableObjectAdministration implements IInterceptable<IO
|
|
|
39
37
|
isPlainObject_: boolean;
|
|
40
38
|
appliedAnnotations_?: object;
|
|
41
39
|
private pendingKeys_;
|
|
42
|
-
constructor(target_: any, values_: Map<string | number | symbol, ObservableValue<any> | ComputedValue<any>>, name_: string, defaultAnnotation_?: Annotation
|
|
40
|
+
constructor(target_: any, values_: Map<string | number | symbol, ObservableValue<any> | ComputedValue<any>>, name_: string, defaultAnnotation_?: Annotation);
|
|
43
41
|
getObservablePropValue_(key: PropertyKey): any;
|
|
44
42
|
setObservablePropValue_(key: PropertyKey, newValue: any): boolean | null;
|
|
45
43
|
get_(key: PropertyKey): any;
|
|
46
44
|
/**
|
|
47
45
|
* @param {PropertyKey} key
|
|
48
46
|
* @param {any} value
|
|
49
|
-
* @param {Annotation|boolean} annotation true -
|
|
47
|
+
* @param {Annotation|boolean} annotation true - use default annotation, false - copy as is
|
|
50
48
|
* @param {boolean} proxyTrap whether it's called from proxy trap
|
|
51
49
|
* @returns {boolean|null} true on success, false on failure (proxyTrap + non-configurable), null when cancelled by interceptor
|
|
52
50
|
*/
|
|
@@ -54,18 +52,17 @@ export declare class ObservableObjectAdministration implements IInterceptable<IO
|
|
|
54
52
|
has_(key: PropertyKey): boolean;
|
|
55
53
|
/**
|
|
56
54
|
* @param {PropertyKey} key
|
|
57
|
-
* @param {Annotation|boolean} annotation true -
|
|
55
|
+
* @param {Annotation|boolean} annotation true - use default annotation, false - ignore prop
|
|
58
56
|
*/
|
|
59
57
|
make_(key: PropertyKey, annotation: Annotation | boolean): void;
|
|
60
58
|
/**
|
|
61
59
|
* @param {PropertyKey} key
|
|
62
60
|
* @param {PropertyDescriptor} descriptor
|
|
63
|
-
* @param {Annotation|boolean} annotation true -
|
|
61
|
+
* @param {Annotation|boolean} annotation true - use default annotation, false - copy as is
|
|
64
62
|
* @param {boolean} proxyTrap whether it's called from proxy trap
|
|
65
63
|
* @returns {boolean|null} true on success, false on failure (proxyTrap + non-configurable), null when cancelled by interceptor
|
|
66
64
|
*/
|
|
67
65
|
extend_(key: PropertyKey, descriptor: PropertyDescriptor, annotation: Annotation | boolean, proxyTrap?: boolean): boolean | null;
|
|
68
|
-
inferAnnotation_(key: PropertyKey): Annotation | false;
|
|
69
66
|
/**
|
|
70
67
|
* @param {PropertyKey} key
|
|
71
68
|
* @param {PropertyDescriptor} descriptor
|
package/package.json
CHANGED
package/src/api/annotation.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
computed,
|
|
9
|
-
isFlow
|
|
10
|
-
} from "../internal"
|
|
1
|
+
import { ObservableObjectAdministration, isFunction } from "../internal"
|
|
2
|
+
|
|
3
|
+
export const enum MakeResult {
|
|
4
|
+
Cancel,
|
|
5
|
+
Break,
|
|
6
|
+
Continue
|
|
7
|
+
}
|
|
11
8
|
|
|
12
9
|
export type Annotation = {
|
|
13
10
|
annotationType_: string
|
|
14
|
-
make_(
|
|
11
|
+
make_(
|
|
12
|
+
adm: ObservableObjectAdministration,
|
|
13
|
+
key: PropertyKey,
|
|
14
|
+
descriptor: PropertyDescriptor,
|
|
15
|
+
source: object
|
|
16
|
+
): MakeResult
|
|
15
17
|
extend_(
|
|
16
18
|
adm: ObservableObjectAdministration,
|
|
17
19
|
key: PropertyKey,
|
|
@@ -33,37 +35,6 @@ export type AnnotationsMap<T, AdditionalFields extends PropertyKey> = {
|
|
|
33
35
|
} &
|
|
34
36
|
Record<AdditionalFields, AnnotationMapEntry>
|
|
35
37
|
|
|
36
|
-
/**
|
|
37
|
-
* Infers the best fitting annotation from property descriptor or false if the field shoudn't be annotated
|
|
38
|
-
* - getter(+setter) -> computed
|
|
39
|
-
* - setter w/o getter -> false (ignore)
|
|
40
|
-
* - flow -> false (ignore)
|
|
41
|
-
* - generator -> flow
|
|
42
|
-
* - action -> false (ignore)
|
|
43
|
-
* - function -> action (optionally bound)
|
|
44
|
-
* - other -> defaultAnnotation
|
|
45
|
-
*/
|
|
46
|
-
export function inferAnnotationFromDescriptor(
|
|
47
|
-
desc: PropertyDescriptor,
|
|
48
|
-
defaultAnnotation: Annotation,
|
|
49
|
-
autoBind: boolean
|
|
50
|
-
): Annotation | false {
|
|
51
|
-
if (desc.get) return computed
|
|
52
|
-
if (desc.set) return false // ignore lone setter
|
|
53
|
-
// If already wrapped in action/flow, don't do that another time, but assume it is already set up properly.
|
|
54
|
-
return isFunction(desc.value)
|
|
55
|
-
? isGenerator(desc.value)
|
|
56
|
-
? isFlow(desc.value)
|
|
57
|
-
? false
|
|
58
|
-
: flow
|
|
59
|
-
: isAction(desc.value)
|
|
60
|
-
? false
|
|
61
|
-
: autoBind
|
|
62
|
-
? autoAction.bound
|
|
63
|
-
: autoAction
|
|
64
|
-
: defaultAnnotation
|
|
65
|
-
}
|
|
66
|
-
|
|
67
38
|
export function isAnnotation(thing: any) {
|
|
68
39
|
return (
|
|
69
40
|
// Can be function
|
package/src/api/flow.ts
CHANGED
|
@@ -6,7 +6,8 @@ import {
|
|
|
6
6
|
Annotation,
|
|
7
7
|
isStringish,
|
|
8
8
|
storeAnnotation,
|
|
9
|
-
createFlowAnnotation
|
|
9
|
+
createFlowAnnotation,
|
|
10
|
+
createDecoratorAnnotation
|
|
10
11
|
} from "../internal"
|
|
11
12
|
|
|
12
13
|
export const FLOW = "flow"
|
|
@@ -28,9 +29,11 @@ interface Flow extends Annotation, PropertyDecorator {
|
|
|
28
29
|
<R, Args extends any[]>(
|
|
29
30
|
generator: (...args: Args) => Generator<any, R, any> | AsyncGenerator<any, R, any>
|
|
30
31
|
): (...args: Args) => CancellablePromise<R>
|
|
32
|
+
bound: Annotation & PropertyDecorator
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
const flowAnnotation = createFlowAnnotation("flow")
|
|
36
|
+
const flowBoundAnnotation = createFlowAnnotation("flow.bound", { bound: true })
|
|
34
37
|
|
|
35
38
|
export const flow: Flow = Object.assign(
|
|
36
39
|
function flow(arg1, arg2?) {
|
|
@@ -123,6 +126,8 @@ export const flow: Flow = Object.assign(
|
|
|
123
126
|
flowAnnotation
|
|
124
127
|
)
|
|
125
128
|
|
|
129
|
+
flow.bound = createDecoratorAnnotation(flowBoundAnnotation)
|
|
130
|
+
|
|
126
131
|
function cancelPromise(promise) {
|
|
127
132
|
if (isFunction(promise.cancel)) promise.cancel()
|
|
128
133
|
}
|
|
@@ -11,9 +11,8 @@ import {
|
|
|
11
11
|
isObservableObject,
|
|
12
12
|
die,
|
|
13
13
|
ownKeys,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
extendObservable
|
|
14
|
+
extendObservable,
|
|
15
|
+
addHiddenProp
|
|
17
16
|
} from "../internal"
|
|
18
17
|
|
|
19
18
|
// Hack based on https://github.com/Microsoft/TypeScript/issues/14829#issuecomment-322267089
|
|
@@ -42,6 +41,9 @@ export function makeObservable<T extends object, AdditionalKeys extends Property
|
|
|
42
41
|
return target
|
|
43
42
|
}
|
|
44
43
|
|
|
44
|
+
// proto[keysSymbol] = new Set<PropertyKey>()
|
|
45
|
+
const keysSymbol = Symbol("mobx-keys")
|
|
46
|
+
|
|
45
47
|
export function makeAutoObservable<T extends object, AdditionalKeys extends PropertyKey = never>(
|
|
46
48
|
target: T,
|
|
47
49
|
overrides?: AnnotationsMap<T, NoInfer<AdditionalKeys>>,
|
|
@@ -54,44 +56,33 @@ export function makeAutoObservable<T extends object, AdditionalKeys extends Prop
|
|
|
54
56
|
die(`makeAutoObservable can only be used on objects not already made observable`)
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
// Optimization
|
|
58
|
-
//
|
|
59
|
+
// Optimization: avoid visiting protos
|
|
60
|
+
// Assumes that annotation.make_/.extend_ works the same for plain objects
|
|
59
61
|
if (isPlainObject(target)) {
|
|
60
62
|
return extendObservable(target, target, overrides, options)
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
const adm: ObservableObjectAdministration = asObservableObject(target, options)[$mobx]
|
|
66
|
+
|
|
67
|
+
// Optimization: cache keys on proto
|
|
68
|
+
// Assumes makeAutoObservable can be called only once per object and can't be used in subclass
|
|
69
|
+
if (!target[keysSymbol]) {
|
|
70
|
+
const proto = Object.getPrototypeOf(target)
|
|
71
|
+
const keys = new Set([...ownKeys(target), ...ownKeys(proto)])
|
|
72
|
+
keys.delete("constructor")
|
|
73
|
+
keys.delete($mobx)
|
|
74
|
+
addHiddenProp(proto, keysSymbol, keys)
|
|
75
|
+
}
|
|
76
|
+
|
|
64
77
|
startBatch()
|
|
65
78
|
try {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (annotation !== true) {
|
|
74
|
-
adm.make_(key, annotation)
|
|
75
|
-
}
|
|
76
|
-
})
|
|
77
|
-
}
|
|
78
|
-
} else {
|
|
79
|
-
const ignoreKeys = { [$mobx]: 1, [inferredAnnotationsSymbol]: 1, constructor: 1 }
|
|
80
|
-
const make = key => {
|
|
81
|
-
if (ignoreKeys[key]) return
|
|
82
|
-
ignoreKeys[key] = 1
|
|
83
|
-
adm.make_(
|
|
84
|
-
key,
|
|
85
|
-
// must pass "undefined" for { key: undefined }
|
|
86
|
-
!overrides ? true : key in overrides ? overrides[key] : true
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
let current = target
|
|
90
|
-
while (current && current !== objectPrototype) {
|
|
91
|
-
ownKeys(current).forEach(make)
|
|
92
|
-
current = Object.getPrototypeOf(current)
|
|
93
|
-
}
|
|
94
|
-
}
|
|
79
|
+
target[keysSymbol].forEach(key =>
|
|
80
|
+
adm.make_(
|
|
81
|
+
key,
|
|
82
|
+
// must pass "undefined" for { key: undefined }
|
|
83
|
+
!overrides ? true : key in overrides ? overrides[key] : true
|
|
84
|
+
)
|
|
85
|
+
)
|
|
95
86
|
} finally {
|
|
96
87
|
endBatch()
|
|
97
88
|
}
|
package/src/api/object-api.ts
CHANGED
|
@@ -158,3 +158,17 @@ export function get(obj: any, key: any): any {
|
|
|
158
158
|
}
|
|
159
159
|
die(11)
|
|
160
160
|
}
|
|
161
|
+
|
|
162
|
+
export function apiDefineProperty(obj: Object, key: PropertyKey, descriptor: PropertyDescriptor) {
|
|
163
|
+
if (isObservableObject(obj)) {
|
|
164
|
+
return ((obj as any) as IIsObservableObject)[$mobx].defineProperty_(key, descriptor)
|
|
165
|
+
}
|
|
166
|
+
die(39)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export function apiOwnKeys(obj: Object) {
|
|
170
|
+
if (isObservableObject(obj)) {
|
|
171
|
+
return ((obj as any) as IIsObservableObject)[$mobx].ownKeys_()
|
|
172
|
+
}
|
|
173
|
+
die(38)
|
|
174
|
+
}
|
package/src/api/observable.ts
CHANGED
|
@@ -28,7 +28,8 @@ import {
|
|
|
28
28
|
globalState,
|
|
29
29
|
assign,
|
|
30
30
|
isStringish,
|
|
31
|
-
createObservableAnnotation
|
|
31
|
+
createObservableAnnotation,
|
|
32
|
+
createAutoAnnotation
|
|
32
33
|
} from "../internal"
|
|
33
34
|
|
|
34
35
|
export const OBSERVABLE = "observable"
|
|
@@ -82,13 +83,7 @@ export function getEnhancerFromOptions(options: CreateObservableOptions): IEnhan
|
|
|
82
83
|
export function getAnnotationFromOptions(
|
|
83
84
|
options?: CreateObservableOptions
|
|
84
85
|
): Annotation | undefined {
|
|
85
|
-
return options
|
|
86
|
-
? options.deep === true
|
|
87
|
-
? observableAnnotation
|
|
88
|
-
: options.deep === false
|
|
89
|
-
? observableRefAnnotation
|
|
90
|
-
: options.defaultDecorator
|
|
91
|
-
: undefined
|
|
86
|
+
return options ? options.defaultDecorator ?? createAutoAnnotation(options) : undefined
|
|
92
87
|
}
|
|
93
88
|
|
|
94
89
|
export function getEnhancerFromAnnotation(annotation?: Annotation): IEnhancer<any> {
|
package/src/api/tojs.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
keys,
|
|
3
2
|
isObservable,
|
|
4
3
|
isObservableArray,
|
|
5
4
|
isObservableValue,
|
|
6
5
|
isObservableMap,
|
|
7
6
|
isObservableSet,
|
|
8
|
-
|
|
9
|
-
die
|
|
7
|
+
isComputedValue,
|
|
8
|
+
die,
|
|
9
|
+
apiOwnKeys,
|
|
10
|
+
objectPrototype
|
|
10
11
|
} from "../internal"
|
|
11
12
|
|
|
12
13
|
function cache<K, V>(map: Map<any, any>, key: K, value: V): V {
|
|
@@ -23,7 +24,8 @@ function toJSHelper(source, __alreadySeen: Map<any, any>) {
|
|
|
23
24
|
)
|
|
24
25
|
return source
|
|
25
26
|
|
|
26
|
-
if (isObservableValue(source)
|
|
27
|
+
if (isObservableValue(source) || isComputedValue(source))
|
|
28
|
+
return toJSHelper(source.get(), __alreadySeen)
|
|
27
29
|
if (__alreadySeen.has(source)) {
|
|
28
30
|
return __alreadySeen.get(source)
|
|
29
31
|
}
|
|
@@ -49,10 +51,11 @@ function toJSHelper(source, __alreadySeen: Map<any, any>) {
|
|
|
49
51
|
return res
|
|
50
52
|
} else {
|
|
51
53
|
// must be observable object
|
|
52
|
-
keys(source) // make sure keys are observed
|
|
53
54
|
const res = cache(__alreadySeen, source, {})
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
apiOwnKeys(source).forEach((key: any) => {
|
|
56
|
+
if (objectPrototype.propertyIsEnumerable.call(source, key)) {
|
|
57
|
+
res[key] = toJSHelper(source[key], __alreadySeen)
|
|
58
|
+
}
|
|
56
59
|
})
|
|
57
60
|
return res
|
|
58
61
|
}
|
package/src/core/observable.ts
CHANGED
|
@@ -206,12 +206,16 @@ export function propagateChangeConfirmed(observable: IObservable) {
|
|
|
206
206
|
observable.lowestObserverState_ = IDerivationState_.STALE_
|
|
207
207
|
|
|
208
208
|
observable.observers_.forEach(d => {
|
|
209
|
-
if (d.dependenciesState_ === IDerivationState_.POSSIBLY_STALE_)
|
|
209
|
+
if (d.dependenciesState_ === IDerivationState_.POSSIBLY_STALE_) {
|
|
210
210
|
d.dependenciesState_ = IDerivationState_.STALE_
|
|
211
|
-
|
|
211
|
+
if (__DEV__ && d.isTracing_ !== TraceMode.NONE) {
|
|
212
|
+
logTraceInfo(d, observable)
|
|
213
|
+
}
|
|
214
|
+
} else if (
|
|
212
215
|
d.dependenciesState_ === IDerivationState_.UP_TO_DATE_ // this happens during computing of `d`, just keep lowestObserverState up to date.
|
|
213
|
-
)
|
|
216
|
+
) {
|
|
214
217
|
observable.lowestObserverState_ = IDerivationState_.UP_TO_DATE_
|
|
218
|
+
}
|
|
215
219
|
})
|
|
216
220
|
// invariantLOS(observable, "confirmed end");
|
|
217
221
|
}
|
|
@@ -225,9 +229,6 @@ export function propagateMaybeChanged(observable: IObservable) {
|
|
|
225
229
|
observable.observers_.forEach(d => {
|
|
226
230
|
if (d.dependenciesState_ === IDerivationState_.UP_TO_DATE_) {
|
|
227
231
|
d.dependenciesState_ = IDerivationState_.POSSIBLY_STALE_
|
|
228
|
-
if (__DEV__ && d.isTracing_ !== TraceMode.NONE) {
|
|
229
|
-
logTraceInfo(d, observable)
|
|
230
|
-
}
|
|
231
232
|
d.onBecomeStale_()
|
|
232
233
|
}
|
|
233
234
|
})
|
package/src/errors.ts
CHANGED
|
@@ -3,6 +3,17 @@ const niceErrors = {
|
|
|
3
3
|
1(annotationType, key: PropertyKey) {
|
|
4
4
|
return `Cannot apply '${annotationType}' to '${key.toString()}': Field not found.`
|
|
5
5
|
},
|
|
6
|
+
/*
|
|
7
|
+
2(prop) {
|
|
8
|
+
return `invalid decorator for '${prop.toString()}'`
|
|
9
|
+
},
|
|
10
|
+
3(prop) {
|
|
11
|
+
return `Cannot decorate '${prop.toString()}': action can only be used on properties with a function value.`
|
|
12
|
+
},
|
|
13
|
+
4(prop) {
|
|
14
|
+
return `Cannot decorate '${prop.toString()}': computed can only be used on getter properties.`
|
|
15
|
+
},
|
|
16
|
+
*/
|
|
6
17
|
5: "'keys()' can only be used on observable objects, arrays, sets and maps",
|
|
7
18
|
6: "'values()' can only be used on observable objects, arrays, sets and maps",
|
|
8
19
|
7: "'entries()' can only be used on observable objects, arrays and maps",
|
|
@@ -59,7 +70,9 @@ const niceErrors = {
|
|
|
59
70
|
36: "isolateGlobalState should be called before MobX is running any reactions",
|
|
60
71
|
37(method) {
|
|
61
72
|
return `[mobx] \`observableArray.${method}()\` mutates the array in-place, which is not allowed inside a derivation. Use \`array.slice().${method}()\` instead`
|
|
62
|
-
}
|
|
73
|
+
},
|
|
74
|
+
38: "'ownKeys()' can only be used on observable objects",
|
|
75
|
+
39: "'defineProperty()' can only be used on observable objects"
|
|
63
76
|
} as const
|
|
64
77
|
|
|
65
78
|
const errors: typeof niceErrors = __DEV__ ? niceErrors : ({} as any)
|
package/src/internal.ts
CHANGED
|
@@ -17,6 +17,7 @@ export * from "./types/actionannotation"
|
|
|
17
17
|
export * from "./types/flowannotation"
|
|
18
18
|
export * from "./types/computedannotation"
|
|
19
19
|
export * from "./types/observableannotation"
|
|
20
|
+
export * from "./types/autoannotation"
|
|
20
21
|
export * from "./api/observable"
|
|
21
22
|
export * from "./api/computed"
|
|
22
23
|
export * from "./core/action"
|
package/src/mobx.ts
CHANGED
|
@@ -75,6 +75,7 @@ export {
|
|
|
75
75
|
IObservableFactory,
|
|
76
76
|
CreateObservableOptions,
|
|
77
77
|
computed,
|
|
78
|
+
IComputedFactory,
|
|
78
79
|
isObservable,
|
|
79
80
|
isObservableProp,
|
|
80
81
|
isComputed,
|
|
@@ -99,10 +100,13 @@ export {
|
|
|
99
100
|
remove,
|
|
100
101
|
has,
|
|
101
102
|
get,
|
|
103
|
+
apiOwnKeys as ownKeys,
|
|
104
|
+
apiDefineProperty as defineProperty,
|
|
102
105
|
configure,
|
|
103
106
|
onBecomeObserved,
|
|
104
107
|
onBecomeUnobserved,
|
|
105
108
|
flow,
|
|
109
|
+
isFlow,
|
|
106
110
|
flowResult,
|
|
107
111
|
FlowCancellationError,
|
|
108
112
|
isFlowCancellationError,
|
|
@@ -3,14 +3,11 @@ import {
|
|
|
3
3
|
createAction,
|
|
4
4
|
isAction,
|
|
5
5
|
defineProperty,
|
|
6
|
-
getDescriptor,
|
|
7
|
-
objectPrototype,
|
|
8
6
|
die,
|
|
9
7
|
isFunction,
|
|
10
8
|
Annotation,
|
|
11
|
-
recordAnnotationApplied,
|
|
12
9
|
globalState,
|
|
13
|
-
|
|
10
|
+
MakeResult
|
|
14
11
|
} from "../internal"
|
|
15
12
|
|
|
16
13
|
export function createActionAnnotation(name: string, options?: object): Annotation {
|
|
@@ -22,54 +19,33 @@ export function createActionAnnotation(name: string, options?: object): Annotati
|
|
|
22
19
|
}
|
|
23
20
|
}
|
|
24
21
|
|
|
25
|
-
function make_(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
annotated = true
|
|
43
|
-
// Don't annotate protos if bound
|
|
44
|
-
if (bound) {
|
|
45
|
-
break
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
// Prototype
|
|
49
|
-
if (source !== adm.target_) {
|
|
50
|
-
if (isAction(descriptor.value)) {
|
|
51
|
-
// A prototype could have been annotated already by other constructor,
|
|
52
|
-
// rest of the proto chain must be annotated already
|
|
53
|
-
annotated = true
|
|
54
|
-
break
|
|
55
|
-
}
|
|
56
|
-
const actionDescriptor = createActionDescriptor(adm, this, key, descriptor, false)
|
|
57
|
-
defineProperty(source, key, actionDescriptor)
|
|
58
|
-
annotated = true
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
source = Object.getPrototypeOf(source)
|
|
22
|
+
function make_(
|
|
23
|
+
adm: ObservableObjectAdministration,
|
|
24
|
+
key: PropertyKey,
|
|
25
|
+
descriptor: PropertyDescriptor,
|
|
26
|
+
source: object
|
|
27
|
+
): MakeResult {
|
|
28
|
+
// bound
|
|
29
|
+
if (this.options_?.bound) {
|
|
30
|
+
return this.extend_(adm, key, descriptor, false) === null
|
|
31
|
+
? MakeResult.Cancel
|
|
32
|
+
: MakeResult.Break
|
|
33
|
+
}
|
|
34
|
+
// own
|
|
35
|
+
if (source === adm.target_) {
|
|
36
|
+
return this.extend_(adm, key, descriptor, false) === null
|
|
37
|
+
? MakeResult.Cancel
|
|
38
|
+
: MakeResult.Continue
|
|
62
39
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
// When called from super() some props may not exist yet.
|
|
69
|
-
// However we don't have to worry about missing prop,
|
|
70
|
-
// because the decorator must have been applied to something.
|
|
71
|
-
die(1, this.annotationType_, `${adm.name_}.${key.toString()}`)
|
|
40
|
+
// prototype
|
|
41
|
+
if (isAction(descriptor.value)) {
|
|
42
|
+
// A prototype could have been annotated already by other constructor,
|
|
43
|
+
// rest of the proto chain must be annotated already
|
|
44
|
+
return MakeResult.Break
|
|
72
45
|
}
|
|
46
|
+
const actionDescriptor = createActionDescriptor(adm, this, key, descriptor, false)
|
|
47
|
+
defineProperty(source, key, actionDescriptor)
|
|
48
|
+
return MakeResult.Continue
|
|
73
49
|
}
|
|
74
50
|
|
|
75
51
|
function extend_(
|
|
@@ -96,7 +72,7 @@ function assertActionDescriptor(
|
|
|
96
72
|
}
|
|
97
73
|
}
|
|
98
74
|
|
|
99
|
-
function createActionDescriptor(
|
|
75
|
+
export function createActionDescriptor(
|
|
100
76
|
adm: ObservableObjectAdministration,
|
|
101
77
|
annotation: Annotation,
|
|
102
78
|
key: PropertyKey,
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ObservableObjectAdministration,
|
|
3
|
+
observable,
|
|
4
|
+
Annotation,
|
|
5
|
+
defineProperty,
|
|
6
|
+
createAction,
|
|
7
|
+
globalState,
|
|
8
|
+
flow,
|
|
9
|
+
computed,
|
|
10
|
+
autoAction,
|
|
11
|
+
isGenerator,
|
|
12
|
+
MakeResult
|
|
13
|
+
} from "../internal"
|
|
14
|
+
|
|
15
|
+
const AUTO = "true"
|
|
16
|
+
|
|
17
|
+
export const autoAnnotation: Annotation = createAutoAnnotation()
|
|
18
|
+
|
|
19
|
+
export function createAutoAnnotation(options?: object): Annotation {
|
|
20
|
+
return {
|
|
21
|
+
annotationType_: AUTO,
|
|
22
|
+
options_: options,
|
|
23
|
+
make_,
|
|
24
|
+
extend_
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function make_(
|
|
29
|
+
adm: ObservableObjectAdministration,
|
|
30
|
+
key: PropertyKey,
|
|
31
|
+
descriptor: PropertyDescriptor,
|
|
32
|
+
source: object
|
|
33
|
+
): MakeResult {
|
|
34
|
+
// getter -> computed
|
|
35
|
+
if (descriptor.get) {
|
|
36
|
+
return computed.make_(adm, key, descriptor, source)
|
|
37
|
+
}
|
|
38
|
+
// lone setter -> action setter
|
|
39
|
+
if (descriptor.set) {
|
|
40
|
+
// TODO make action applicable to setter and delegate to action.make_
|
|
41
|
+
const set = createAction(key.toString(), descriptor.set) as (v: any) => void
|
|
42
|
+
// own
|
|
43
|
+
if (source === adm.target_) {
|
|
44
|
+
return adm.defineProperty_(key, {
|
|
45
|
+
configurable: globalState.safeDescriptors ? adm.isPlainObject_ : true,
|
|
46
|
+
set
|
|
47
|
+
}) === null
|
|
48
|
+
? MakeResult.Cancel
|
|
49
|
+
: MakeResult.Continue
|
|
50
|
+
}
|
|
51
|
+
// proto
|
|
52
|
+
defineProperty(source, key, {
|
|
53
|
+
configurable: true,
|
|
54
|
+
set
|
|
55
|
+
})
|
|
56
|
+
return MakeResult.Continue
|
|
57
|
+
}
|
|
58
|
+
// function on proto -> autoAction/flow
|
|
59
|
+
if (source !== adm.target_ && typeof descriptor.value === "function") {
|
|
60
|
+
if (isGenerator(descriptor.value)) {
|
|
61
|
+
const flowAnnotation = this.options_?.autoBind ? flow.bound : flow
|
|
62
|
+
return flowAnnotation.make_(adm, key, descriptor, source)
|
|
63
|
+
}
|
|
64
|
+
const actionAnnotation = this.options_?.autoBind ? autoAction.bound : autoAction
|
|
65
|
+
return actionAnnotation.make_(adm, key, descriptor, source)
|
|
66
|
+
}
|
|
67
|
+
// other -> observable
|
|
68
|
+
// Copy props from proto as well, see test:
|
|
69
|
+
// "decorate should work with Object.create"
|
|
70
|
+
let observableAnnotation = this.options_?.deep === false ? observable.ref : observable
|
|
71
|
+
// if function respect autoBind option
|
|
72
|
+
if (typeof descriptor.value === "function" && this.options_?.autoBind) {
|
|
73
|
+
descriptor.value = descriptor.value.bind(adm.proxy_ ?? adm.target_)
|
|
74
|
+
}
|
|
75
|
+
return observableAnnotation.make_(adm, key, descriptor, source)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function extend_(
|
|
79
|
+
adm: ObservableObjectAdministration,
|
|
80
|
+
key: PropertyKey,
|
|
81
|
+
descriptor: PropertyDescriptor,
|
|
82
|
+
proxyTrap: boolean
|
|
83
|
+
): boolean | null {
|
|
84
|
+
// getter -> computed
|
|
85
|
+
if (descriptor.get) {
|
|
86
|
+
return computed.extend_(adm, key, descriptor, proxyTrap)
|
|
87
|
+
}
|
|
88
|
+
// lone setter -> action setter
|
|
89
|
+
if (descriptor.set) {
|
|
90
|
+
// TODO make action applicable to setter and delegate to action.extend_
|
|
91
|
+
return adm.defineProperty_(
|
|
92
|
+
key,
|
|
93
|
+
{
|
|
94
|
+
configurable: globalState.safeDescriptors ? adm.isPlainObject_ : true,
|
|
95
|
+
set: createAction(key.toString(), descriptor.set) as (v: any) => void
|
|
96
|
+
},
|
|
97
|
+
proxyTrap
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
// other -> observable
|
|
101
|
+
// if function respect autoBind option
|
|
102
|
+
if (typeof descriptor.value === "function" && this.options_?.autoBind) {
|
|
103
|
+
descriptor.value = descriptor.value.bind(adm.proxy_ ?? adm.target_)
|
|
104
|
+
}
|
|
105
|
+
let observableAnnotation = this.options_?.deep === false ? observable.ref : observable
|
|
106
|
+
return observableAnnotation.extend_(adm, key, descriptor, proxyTrap)
|
|
107
|
+
}
|