mobx 6.2.0 → 6.3.3
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 +44 -5
- package/README.md +4 -4
- package/dist/api/autorun.d.ts +3 -3
- 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/mobx.cjs.development.js +94 -33
- 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 +93 -34
- package/dist/mobx.esm.development.js.map +1 -1
- package/dist/mobx.esm.js +93 -34
- 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 +94 -33
- 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/package.json +1 -1
- package/src/api/autorun.ts +5 -5
- package/src/api/flow.ts +6 -1
- package/src/api/object-api.ts +14 -0
- package/src/api/observable.ts +4 -4
- package/src/api/tojs.ts +5 -4
- package/src/api/when.ts +1 -1
- package/src/core/computedvalue.ts +8 -6
- package/src/core/derivation.ts +4 -2
- package/src/errors.ts +14 -1
- package/src/mobx.ts +3 -1
- package/src/types/autoannotation.ts +2 -1
- package/src/types/dynamicobject.ts +1 -1
- package/src/types/flowannotation.ts +12 -3
- package/src/utils/comparer.ts +5 -1
package/package.json
CHANGED
package/src/api/autorun.ts
CHANGED
|
@@ -86,14 +86,14 @@ export function autorun(
|
|
|
86
86
|
return reaction.getDisposer_()
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
export type IReactionOptions = IAutorunOptions & {
|
|
89
|
+
export type IReactionOptions<T> = IAutorunOptions & {
|
|
90
90
|
fireImmediately?: boolean
|
|
91
|
-
equals?: IEqualsComparer<
|
|
91
|
+
equals?: IEqualsComparer<T>
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
const run = (f: Lambda) => f()
|
|
95
95
|
|
|
96
|
-
function createSchedulerFromOptions(opts:
|
|
96
|
+
function createSchedulerFromOptions(opts: IAutorunOptions) {
|
|
97
97
|
return opts.scheduler
|
|
98
98
|
? opts.scheduler
|
|
99
99
|
: opts.delay
|
|
@@ -104,7 +104,7 @@ function createSchedulerFromOptions(opts: IReactionOptions) {
|
|
|
104
104
|
export function reaction<T>(
|
|
105
105
|
expression: (r: IReactionPublic) => T,
|
|
106
106
|
effect: (arg: T, prev: T, r: IReactionPublic) => void,
|
|
107
|
-
opts: IReactionOptions = EMPTY_OBJECT
|
|
107
|
+
opts: IReactionOptions<T> = EMPTY_OBJECT
|
|
108
108
|
): IReactionDisposer {
|
|
109
109
|
if (__DEV__) {
|
|
110
110
|
if (!isFunction(expression) || !isFunction(effect))
|
|
@@ -124,7 +124,7 @@ export function reaction<T>(
|
|
|
124
124
|
let value: T
|
|
125
125
|
let oldValue: T = undefined as any // only an issue with fireImmediately
|
|
126
126
|
|
|
127
|
-
const equals = (opts as any).compareStructural
|
|
127
|
+
const equals: IEqualsComparer<T> = (opts as any).compareStructural
|
|
128
128
|
? comparer.structural
|
|
129
129
|
: opts.equals || comparer.default
|
|
130
130
|
|
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
|
}
|
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
|
@@ -60,14 +60,14 @@ export function asCreateObservableOptions(thing: any): CreateObservableOptions {
|
|
|
60
60
|
return thing || defaultCreateObservableOptions
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
const observableAnnotation = createObservableAnnotation(
|
|
64
|
-
const observableRefAnnotation = createObservableAnnotation(
|
|
63
|
+
const observableAnnotation = createObservableAnnotation(OBSERVABLE)
|
|
64
|
+
const observableRefAnnotation = createObservableAnnotation(OBSERVABLE_REF, {
|
|
65
65
|
enhancer: referenceEnhancer
|
|
66
66
|
})
|
|
67
|
-
const observableShallowAnnotation = createObservableAnnotation(
|
|
67
|
+
const observableShallowAnnotation = createObservableAnnotation(OBSERVABLE_SHALLOW, {
|
|
68
68
|
enhancer: shallowEnhancer
|
|
69
69
|
})
|
|
70
|
-
const observableStructAnnotation = createObservableAnnotation(
|
|
70
|
+
const observableStructAnnotation = createObservableAnnotation(OBSERVABLE_STRUCT, {
|
|
71
71
|
enhancer: refStructEnhancer
|
|
72
72
|
})
|
|
73
73
|
const observableDecoratorAnnotation = createDecoratorAnnotation(observableAnnotation)
|
package/src/api/tojs.ts
CHANGED
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
isObservableValue,
|
|
5
5
|
isObservableMap,
|
|
6
6
|
isObservableSet,
|
|
7
|
+
isComputedValue,
|
|
7
8
|
die,
|
|
8
|
-
|
|
9
|
-
$mobx,
|
|
9
|
+
apiOwnKeys,
|
|
10
10
|
objectPrototype
|
|
11
11
|
} from "../internal"
|
|
12
12
|
|
|
@@ -24,7 +24,8 @@ function toJSHelper(source, __alreadySeen: Map<any, any>) {
|
|
|
24
24
|
)
|
|
25
25
|
return source
|
|
26
26
|
|
|
27
|
-
if (isObservableValue(source)
|
|
27
|
+
if (isObservableValue(source) || isComputedValue(source))
|
|
28
|
+
return toJSHelper(source.get(), __alreadySeen)
|
|
28
29
|
if (__alreadySeen.has(source)) {
|
|
29
30
|
return __alreadySeen.get(source)
|
|
30
31
|
}
|
|
@@ -51,7 +52,7 @@ function toJSHelper(source, __alreadySeen: Map<any, any>) {
|
|
|
51
52
|
} else {
|
|
52
53
|
// must be observable object
|
|
53
54
|
const res = cache(__alreadySeen, source, {})
|
|
54
|
-
|
|
55
|
+
apiOwnKeys(source).forEach((key: any) => {
|
|
55
56
|
if (objectPrototype.propertyIsEnumerable.call(source, key)) {
|
|
56
57
|
res[key] = toJSHelper(source[key], __alreadySeen)
|
|
57
58
|
}
|
package/src/api/when.ts
CHANGED
|
@@ -33,10 +33,10 @@ export function when(predicate: any, arg1?: any, arg2?: any): any {
|
|
|
33
33
|
function _when(predicate: () => boolean, effect: Lambda, opts: IWhenOptions): IReactionDisposer {
|
|
34
34
|
let timeoutHandle: any
|
|
35
35
|
if (typeof opts.timeout === "number") {
|
|
36
|
+
const error = new Error("WHEN_TIMEOUT")
|
|
36
37
|
timeoutHandle = setTimeout(() => {
|
|
37
38
|
if (!disposer[$mobx].isDisposed_) {
|
|
38
39
|
disposer()
|
|
39
|
-
const error = new Error("WHEN_TIMEOUT")
|
|
40
40
|
if (opts.onError) opts.onError(error)
|
|
41
41
|
else throw error
|
|
42
42
|
}
|
|
@@ -255,6 +255,11 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
|
|
|
255
255
|
if (!this.keepAlive_) {
|
|
256
256
|
clearObserving(this)
|
|
257
257
|
this.value_ = undefined // don't hold on to computed value!
|
|
258
|
+
if (__DEV__ && this.isTracing_ !== TraceMode.NONE) {
|
|
259
|
+
console.log(
|
|
260
|
+
`[mobx.trace] Computed value '${this.name_}' was suspended and it will recompute on the next access.`
|
|
261
|
+
)
|
|
262
|
+
}
|
|
258
263
|
}
|
|
259
264
|
}
|
|
260
265
|
|
|
@@ -283,17 +288,14 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
|
|
|
283
288
|
|
|
284
289
|
warnAboutUntrackedRead_() {
|
|
285
290
|
if (!__DEV__) return
|
|
286
|
-
if (this.requiresReaction_ === true) {
|
|
287
|
-
die(`[mobx] Computed value ${this.name_} is read outside a reactive context`)
|
|
288
|
-
}
|
|
289
291
|
if (this.isTracing_ !== TraceMode.NONE) {
|
|
290
292
|
console.log(
|
|
291
|
-
`[mobx.trace] '${this.name_}' is being read outside a reactive context. Doing a full recompute
|
|
293
|
+
`[mobx.trace] Computed value '${this.name_}' is being read outside a reactive context. Doing a full recompute.`
|
|
292
294
|
)
|
|
293
295
|
}
|
|
294
|
-
if (globalState.computedRequiresReaction) {
|
|
296
|
+
if (globalState.computedRequiresReaction || this.requiresReaction_) {
|
|
295
297
|
console.warn(
|
|
296
|
-
`[mobx] Computed value ${this.name_} is being read outside a reactive context. Doing a full recompute
|
|
298
|
+
`[mobx] Computed value '${this.name_}' is being read outside a reactive context. Doing a full recompute.`
|
|
297
299
|
)
|
|
298
300
|
}
|
|
299
301
|
}
|
package/src/core/derivation.ts
CHANGED
|
@@ -149,7 +149,9 @@ export function checkIfStateModificationsAreAllowed(atom: IAtom) {
|
|
|
149
149
|
|
|
150
150
|
export function checkIfStateReadsAreAllowed(observable: IObservable) {
|
|
151
151
|
if (__DEV__ && !globalState.allowStateReads && globalState.observableRequiresReaction) {
|
|
152
|
-
console.warn(
|
|
152
|
+
console.warn(
|
|
153
|
+
`[mobx] Observable '${observable.name_}' being read outside a reactive context.`
|
|
154
|
+
)
|
|
153
155
|
}
|
|
154
156
|
}
|
|
155
157
|
|
|
@@ -195,7 +197,7 @@ function warnAboutDerivationWithoutDependencies(derivation: IDerivation) {
|
|
|
195
197
|
|
|
196
198
|
if (globalState.reactionRequiresObservable || derivation.requiresObservable_) {
|
|
197
199
|
console.warn(
|
|
198
|
-
`[mobx] Derivation ${derivation.name_} is created/updated without reading any observable value
|
|
200
|
+
`[mobx] Derivation '${derivation.name_}' is created/updated without reading any observable value.`
|
|
199
201
|
)
|
|
200
202
|
}
|
|
201
203
|
}
|
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/mobx.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { die } from "./errors"
|
|
19
19
|
import { getGlobal } from "./utils/global"
|
|
20
|
-
;["Symbol", "Map", "Set"
|
|
20
|
+
;["Symbol", "Map", "Set"].forEach(m => {
|
|
21
21
|
let g = getGlobal()
|
|
22
22
|
if (typeof g[m] === "undefined") {
|
|
23
23
|
die(`MobX requires global '${m}' to be available or polyfilled`)
|
|
@@ -100,6 +100,8 @@ export {
|
|
|
100
100
|
remove,
|
|
101
101
|
has,
|
|
102
102
|
get,
|
|
103
|
+
apiOwnKeys as ownKeys,
|
|
104
|
+
apiDefineProperty as defineProperty,
|
|
103
105
|
configure,
|
|
104
106
|
onBecomeObserved,
|
|
105
107
|
onBecomeUnobserved,
|
|
@@ -58,7 +58,8 @@ function make_(
|
|
|
58
58
|
// function on proto -> autoAction/flow
|
|
59
59
|
if (source !== adm.target_ && typeof descriptor.value === "function") {
|
|
60
60
|
if (isGenerator(descriptor.value)) {
|
|
61
|
-
|
|
61
|
+
const flowAnnotation = this.options_?.autoBind ? flow.bound : flow
|
|
62
|
+
return flowAnnotation.make_(adm, key, descriptor, source)
|
|
62
63
|
}
|
|
63
64
|
const actionAnnotation = this.options_?.autoBind ? autoAction.bound : autoAction
|
|
64
65
|
return actionAnnotation.make_(adm, key, descriptor, source)
|
|
@@ -64,7 +64,7 @@ const objectProxyTraps: ProxyHandler<any> = {
|
|
|
64
64
|
ownKeys(target: IIsObservableObject): PropertyKey[] {
|
|
65
65
|
if (__DEV__ && globalState.trackingDerivation)
|
|
66
66
|
warnAboutProxyRequirement(
|
|
67
|
-
"iterate keys to detect added / removed properties. Use
|
|
67
|
+
"iterate keys to detect added / removed properties. Use 'keys' from 'mobx' instead."
|
|
68
68
|
)
|
|
69
69
|
return getAdm(target).ownKeys_()
|
|
70
70
|
},
|
|
@@ -32,12 +32,16 @@ function make_(
|
|
|
32
32
|
: MakeResult.Continue
|
|
33
33
|
}
|
|
34
34
|
// prototype
|
|
35
|
+
// bound - must annotate protos to support super.flow()
|
|
36
|
+
if (this.options_?.bound && !isFlow(adm.target_[key])) {
|
|
37
|
+
if (this.extend_(adm, key, descriptor, false) === null) return MakeResult.Cancel
|
|
38
|
+
}
|
|
35
39
|
if (isFlow(descriptor.value)) {
|
|
36
40
|
// A prototype could have been annotated already by other constructor,
|
|
37
41
|
// rest of the proto chain must be annotated already
|
|
38
42
|
return MakeResult.Break
|
|
39
43
|
}
|
|
40
|
-
const flowDescriptor = createFlowDescriptor(adm, this, key, descriptor, false)
|
|
44
|
+
const flowDescriptor = createFlowDescriptor(adm, this, key, descriptor, false, false)
|
|
41
45
|
defineProperty(source, key, flowDescriptor)
|
|
42
46
|
return MakeResult.Continue
|
|
43
47
|
}
|
|
@@ -48,7 +52,7 @@ function extend_(
|
|
|
48
52
|
descriptor: PropertyDescriptor,
|
|
49
53
|
proxyTrap: boolean
|
|
50
54
|
): boolean | null {
|
|
51
|
-
const flowDescriptor = createFlowDescriptor(adm, this, key, descriptor)
|
|
55
|
+
const flowDescriptor = createFlowDescriptor(adm, this, key, descriptor, this.options_?.bound)
|
|
52
56
|
return adm.defineProperty_(key, flowDescriptor, proxyTrap)
|
|
53
57
|
}
|
|
54
58
|
|
|
@@ -71,12 +75,17 @@ function createFlowDescriptor(
|
|
|
71
75
|
annotation: Annotation,
|
|
72
76
|
key: PropertyKey,
|
|
73
77
|
descriptor: PropertyDescriptor,
|
|
78
|
+
bound: boolean,
|
|
74
79
|
// provides ability to disable safeDescriptors for prototypes
|
|
75
80
|
safeDescriptors: boolean = globalState.safeDescriptors
|
|
76
81
|
): PropertyDescriptor {
|
|
77
82
|
assertFlowDescriptor(adm, annotation, key, descriptor)
|
|
83
|
+
let { value } = descriptor
|
|
84
|
+
if (bound) {
|
|
85
|
+
value = value.bind(adm.proxy_ ?? adm.target_)
|
|
86
|
+
}
|
|
78
87
|
return {
|
|
79
|
-
value: flow(
|
|
88
|
+
value: flow(value),
|
|
80
89
|
// Non-configurable for classes
|
|
81
90
|
// prevents accidental field redefinition in subclass
|
|
82
91
|
configurable: safeDescriptors ? adm.isPlainObject_ : true,
|
package/src/utils/comparer.ts
CHANGED
|
@@ -17,7 +17,11 @@ function shallowComparer(a: any, b: any): boolean {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function defaultComparer(a: any, b: any): boolean {
|
|
20
|
-
return Object.is(a, b)
|
|
20
|
+
if (Object.is) return Object.is(a, b)
|
|
21
|
+
|
|
22
|
+
return a === b
|
|
23
|
+
? a !== 0 || 1 / a === 1 / b
|
|
24
|
+
: a !== a && b !== b
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
export const comparer = {
|