mobx 6.1.8 → 6.9.0
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 +224 -7
- package/README.md +54 -52
- package/dist/api/annotation.d.ts +6 -12
- package/dist/api/autorun.d.ts +4 -4
- package/dist/api/flow.d.ts +1 -0
- package/dist/api/intercept.d.ts +5 -5
- package/dist/api/object-api.d.ts +2 -0
- package/dist/api/observable.d.ts +5 -1
- package/dist/api/observe.d.ts +4 -4
- package/dist/api/tojs.d.ts +4 -1
- package/dist/api/when.d.ts +8 -0
- package/dist/core/atom.d.ts +1 -1
- package/dist/core/computedvalue.d.ts +0 -1
- package/dist/core/globalstate.d.ts +4 -0
- package/dist/core/reaction.d.ts +2 -2
- package/dist/errors.d.ts +4 -2
- package/dist/internal.d.ts +1 -0
- package/dist/mobx.cjs.development.js +1477 -1719
- 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 +1475 -1720
- package/dist/mobx.esm.development.js.map +1 -1
- package/dist/mobx.esm.js +1492 -1726
- 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 +1477 -1719
- 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/observablemap.d.ts +5 -4
- package/dist/types/observableobject.d.ts +6 -9
- package/dist/types/observableset.d.ts +4 -4
- package/dist/types/observablevalue.d.ts +3 -5
- package/dist/utils/utils.d.ts +4 -4
- package/package.json +1 -1
- package/src/api/action.ts +8 -3
- package/src/api/annotation.ts +14 -44
- package/src/api/autorun.ts +38 -17
- package/src/api/computed.ts +5 -2
- package/src/api/configure.ts +6 -2
- package/src/api/decorators.ts +1 -1
- package/src/api/extendobservable.ts +12 -6
- package/src/api/extras.ts +4 -2
- package/src/api/flow.ts +17 -5
- package/src/api/intercept-read.ts +4 -2
- package/src/api/intercept.ts +10 -7
- package/src/api/iscomputed.ts +14 -8
- package/src/api/isobservable.ts +10 -4
- package/src/api/makeObservable.ts +35 -36
- package/src/api/object-api.ts +42 -14
- package/src/api/observable.ts +39 -25
- package/src/api/observe.ts +9 -6
- package/src/api/tojs.ts +20 -10
- package/src/api/trace.ts +6 -2
- package/src/api/when.ts +34 -9
- package/src/core/action.ts +11 -5
- package/src/core/atom.ts +9 -2
- package/src/core/computedvalue.ts +48 -27
- package/src/core/derivation.ts +34 -12
- package/src/core/globalstate.ts +25 -7
- package/src/core/observable.ts +23 -13
- package/src/core/reaction.ts +16 -7
- package/src/core/spy.ts +20 -7
- package/src/errors.ts +16 -3
- package/src/internal.ts +1 -0
- package/src/mobx.ts +6 -2
- package/src/types/actionannotation.ts +30 -52
- package/src/types/autoannotation.ts +107 -0
- package/src/types/computedannotation.ts +7 -37
- package/src/types/dynamicobject.ts +12 -6
- package/src/types/flowannotation.ts +40 -41
- package/src/types/intercept-utils.ts +9 -3
- package/src/types/legacyobservablearray.ts +26 -3
- package/src/types/listen-utils.ts +6 -2
- package/src/types/modifiers.ts +52 -16
- package/src/types/observableannotation.ts +7 -34
- package/src/types/observablearray.ts +106 -45
- package/src/types/observablemap.ts +71 -35
- package/src/types/observableobject.ts +88 -82
- package/src/types/observableset.ts +32 -13
- package/src/types/observablevalue.ts +16 -10
- package/src/types/overrideannotation.ts +4 -2
- package/src/types/type-utils.ts +34 -12
- package/src/utils/comparer.ts +5 -1
- package/src/utils/eq.ts +45 -15
- package/src/utils/utils.ts +39 -16
package/src/api/iscomputed.ts
CHANGED
|
@@ -1,25 +1,31 @@
|
|
|
1
1
|
import { $mobx, getAtom, isComputedValue, isObservableObject, die, isStringish } from "../internal"
|
|
2
2
|
|
|
3
3
|
export function _isComputed(value, property?: PropertyKey): boolean {
|
|
4
|
-
if (property
|
|
5
|
-
|
|
6
|
-
if (!value[$mobx].values_.has(property)) return false
|
|
7
|
-
const atom = getAtom(value, property)
|
|
8
|
-
return isComputedValue(atom)
|
|
4
|
+
if (property === undefined) {
|
|
5
|
+
return isComputedValue(value)
|
|
9
6
|
}
|
|
10
|
-
|
|
7
|
+
if (isObservableObject(value) === false) {
|
|
8
|
+
return false
|
|
9
|
+
}
|
|
10
|
+
if (!value[$mobx].values_.has(property)) {
|
|
11
|
+
return false
|
|
12
|
+
}
|
|
13
|
+
const atom = getAtom(value, property)
|
|
14
|
+
return isComputedValue(atom)
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
export function isComputed(value: any): boolean {
|
|
14
|
-
if (__DEV__ && arguments.length > 1)
|
|
18
|
+
if (__DEV__ && arguments.length > 1) {
|
|
15
19
|
return die(
|
|
16
20
|
`isComputed expects only 1 argument. Use isComputedProp to inspect the observability of a property`
|
|
17
21
|
)
|
|
22
|
+
}
|
|
18
23
|
return _isComputed(value)
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
export function isComputedProp(value: any, propName: PropertyKey): boolean {
|
|
22
|
-
if (__DEV__ && !isStringish(propName))
|
|
27
|
+
if (__DEV__ && !isStringish(propName)) {
|
|
23
28
|
return die(`isComputed expected a property name as second argument`)
|
|
29
|
+
}
|
|
24
30
|
return _isComputed(value, propName)
|
|
25
31
|
}
|
package/src/api/isobservable.ts
CHANGED
|
@@ -11,12 +11,15 @@ import {
|
|
|
11
11
|
} from "../internal"
|
|
12
12
|
|
|
13
13
|
function _isObservable(value, property?: PropertyKey): boolean {
|
|
14
|
-
if (!value)
|
|
14
|
+
if (!value) {
|
|
15
|
+
return false
|
|
16
|
+
}
|
|
15
17
|
if (property !== undefined) {
|
|
16
|
-
if (__DEV__ && (isObservableMap(value) || isObservableArray(value)))
|
|
18
|
+
if (__DEV__ && (isObservableMap(value) || isObservableArray(value))) {
|
|
17
19
|
return die(
|
|
18
20
|
"isObservable(object, propertyName) is not supported for arrays and maps. Use map.has or array.length instead."
|
|
19
21
|
)
|
|
22
|
+
}
|
|
20
23
|
if (isObservableObject(value)) {
|
|
21
24
|
return value[$mobx].values_.has(property)
|
|
22
25
|
}
|
|
@@ -33,14 +36,17 @@ function _isObservable(value, property?: PropertyKey): boolean {
|
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
export function isObservable(value: any): boolean {
|
|
36
|
-
if (__DEV__ && arguments.length !== 1)
|
|
39
|
+
if (__DEV__ && arguments.length !== 1) {
|
|
37
40
|
die(
|
|
38
41
|
`isObservable expects only 1 argument. Use isObservableProp to inspect the observability of a property`
|
|
39
42
|
)
|
|
43
|
+
}
|
|
40
44
|
return _isObservable(value)
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
export function isObservableProp(value: any, propName: PropertyKey): boolean {
|
|
44
|
-
if (__DEV__ && !isStringish(propName))
|
|
48
|
+
if (__DEV__ && !isStringish(propName)) {
|
|
49
|
+
return die(`expected a property name as second argument`)
|
|
50
|
+
}
|
|
45
51
|
return _isObservable(value, propName)
|
|
46
52
|
}
|
|
@@ -11,9 +11,9 @@ import {
|
|
|
11
11
|
isObservableObject,
|
|
12
12
|
die,
|
|
13
13
|
ownKeys,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
extendObservable,
|
|
15
|
+
addHiddenProp,
|
|
16
|
+
storedAnnotationsSymbol
|
|
17
17
|
} from "../internal"
|
|
18
18
|
|
|
19
19
|
// Hack based on https://github.com/Microsoft/TypeScript/issues/14829#issuecomment-322267089
|
|
@@ -31,6 +31,11 @@ export function makeObservable<T extends object, AdditionalKeys extends Property
|
|
|
31
31
|
const adm: ObservableObjectAdministration = asObservableObject(target, options)[$mobx]
|
|
32
32
|
startBatch()
|
|
33
33
|
try {
|
|
34
|
+
if (__DEV__ && annotations && target[storedAnnotationsSymbol]) {
|
|
35
|
+
die(
|
|
36
|
+
`makeObservable second arg must be nullish when using decorators. Mixing @decorator syntax with annotations is not supported.`
|
|
37
|
+
)
|
|
38
|
+
}
|
|
34
39
|
// Default to decorators
|
|
35
40
|
annotations ??= collectStoredAnnotations(target)
|
|
36
41
|
|
|
@@ -42,56 +47,50 @@ export function makeObservable<T extends object, AdditionalKeys extends Property
|
|
|
42
47
|
return target
|
|
43
48
|
}
|
|
44
49
|
|
|
50
|
+
// proto[keysSymbol] = new Set<PropertyKey>()
|
|
51
|
+
const keysSymbol = Symbol("mobx-keys")
|
|
52
|
+
|
|
45
53
|
export function makeAutoObservable<T extends object, AdditionalKeys extends PropertyKey = never>(
|
|
46
54
|
target: T,
|
|
47
55
|
overrides?: AnnotationsMap<T, NoInfer<AdditionalKeys>>,
|
|
48
56
|
options?: CreateObservableOptions
|
|
49
57
|
): T {
|
|
50
58
|
if (__DEV__) {
|
|
51
|
-
if (!isPlainObject(target) && !isPlainObject(Object.getPrototypeOf(target)))
|
|
59
|
+
if (!isPlainObject(target) && !isPlainObject(Object.getPrototypeOf(target))) {
|
|
52
60
|
die(`'makeAutoObservable' can only be used for classes that don't have a superclass`)
|
|
53
|
-
|
|
61
|
+
}
|
|
62
|
+
if (isObservableObject(target)) {
|
|
54
63
|
die(`makeAutoObservable can only be used on objects not already made observable`)
|
|
64
|
+
}
|
|
55
65
|
}
|
|
56
66
|
|
|
57
|
-
// Optimization
|
|
58
|
-
//
|
|
67
|
+
// Optimization: avoid visiting protos
|
|
68
|
+
// Assumes that annotation.make_/.extend_ works the same for plain objects
|
|
59
69
|
if (isPlainObject(target)) {
|
|
60
70
|
return extendObservable(target, target, overrides, options)
|
|
61
71
|
}
|
|
62
72
|
|
|
63
73
|
const adm: ObservableObjectAdministration = asObservableObject(target, options)[$mobx]
|
|
74
|
+
|
|
75
|
+
// Optimization: cache keys on proto
|
|
76
|
+
// Assumes makeAutoObservable can be called only once per object and can't be used in subclass
|
|
77
|
+
if (!target[keysSymbol]) {
|
|
78
|
+
const proto = Object.getPrototypeOf(target)
|
|
79
|
+
const keys = new Set([...ownKeys(target), ...ownKeys(proto)])
|
|
80
|
+
keys.delete("constructor")
|
|
81
|
+
keys.delete($mobx)
|
|
82
|
+
addHiddenProp(proto, keysSymbol, keys)
|
|
83
|
+
}
|
|
84
|
+
|
|
64
85
|
startBatch()
|
|
65
86
|
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
|
-
}
|
|
87
|
+
target[keysSymbol].forEach(key =>
|
|
88
|
+
adm.make_(
|
|
89
|
+
key,
|
|
90
|
+
// must pass "undefined" for { key: undefined }
|
|
91
|
+
!overrides ? true : key in overrides ? overrides[key] : true
|
|
92
|
+
)
|
|
93
|
+
)
|
|
95
94
|
} finally {
|
|
96
95
|
endBatch()
|
|
97
96
|
}
|
package/src/api/object-api.ts
CHANGED
|
@@ -20,9 +20,9 @@ export function keys<T>(set: ObservableSet<T>): ReadonlyArray<T>
|
|
|
20
20
|
export function keys<T extends Object>(obj: T): ReadonlyArray<PropertyKey>
|
|
21
21
|
export function keys(obj: any): any {
|
|
22
22
|
if (isObservableObject(obj)) {
|
|
23
|
-
return (
|
|
24
|
-
$mobx
|
|
25
|
-
|
|
23
|
+
return (
|
|
24
|
+
(obj as any as IIsObservableObject)[$mobx] as ObservableObjectAdministration
|
|
25
|
+
).keys_()
|
|
26
26
|
}
|
|
27
27
|
if (isObservableMap(obj) || isObservableSet(obj)) {
|
|
28
28
|
return Array.from(obj.keys())
|
|
@@ -86,26 +86,36 @@ export function set(obj: any, key: any, value?: any): void {
|
|
|
86
86
|
startBatch()
|
|
87
87
|
const values = key
|
|
88
88
|
try {
|
|
89
|
-
for (let key in values)
|
|
89
|
+
for (let key in values) {
|
|
90
|
+
set(obj, key, values[key])
|
|
91
|
+
}
|
|
90
92
|
} finally {
|
|
91
93
|
endBatch()
|
|
92
94
|
}
|
|
93
95
|
return
|
|
94
96
|
}
|
|
95
97
|
if (isObservableObject(obj)) {
|
|
96
|
-
;(
|
|
98
|
+
;(obj as any as IIsObservableObject)[$mobx].set_(key, value)
|
|
97
99
|
} else if (isObservableMap(obj)) {
|
|
98
100
|
obj.set(key, value)
|
|
99
101
|
} else if (isObservableSet(obj)) {
|
|
100
102
|
obj.add(key)
|
|
101
103
|
} else if (isObservableArray(obj)) {
|
|
102
|
-
if (typeof key !== "number")
|
|
103
|
-
|
|
104
|
+
if (typeof key !== "number") {
|
|
105
|
+
key = parseInt(key, 10)
|
|
106
|
+
}
|
|
107
|
+
if (key < 0) {
|
|
108
|
+
die(`Invalid index: '${key}'`)
|
|
109
|
+
}
|
|
104
110
|
startBatch()
|
|
105
|
-
if (key >= obj.length)
|
|
111
|
+
if (key >= obj.length) {
|
|
112
|
+
obj.length = key + 1
|
|
113
|
+
}
|
|
106
114
|
obj[key] = value
|
|
107
115
|
endBatch()
|
|
108
|
-
} else
|
|
116
|
+
} else {
|
|
117
|
+
die(8)
|
|
118
|
+
}
|
|
109
119
|
}
|
|
110
120
|
|
|
111
121
|
export function remove<K, V>(obj: ObservableMap<K, V>, key: K)
|
|
@@ -114,13 +124,15 @@ export function remove<T>(obj: IObservableArray<T>, index: number)
|
|
|
114
124
|
export function remove<T extends Object>(obj: T, key: string)
|
|
115
125
|
export function remove(obj: any, key: any): void {
|
|
116
126
|
if (isObservableObject(obj)) {
|
|
117
|
-
;(
|
|
127
|
+
;(obj as any as IIsObservableObject)[$mobx].delete_(key)
|
|
118
128
|
} else if (isObservableMap(obj)) {
|
|
119
129
|
obj.delete(key)
|
|
120
130
|
} else if (isObservableSet(obj)) {
|
|
121
131
|
obj.delete(key)
|
|
122
132
|
} else if (isObservableArray(obj)) {
|
|
123
|
-
if (typeof key !== "number")
|
|
133
|
+
if (typeof key !== "number") {
|
|
134
|
+
key = parseInt(key, 10)
|
|
135
|
+
}
|
|
124
136
|
obj.splice(key, 1)
|
|
125
137
|
} else {
|
|
126
138
|
die(9)
|
|
@@ -133,7 +145,7 @@ export function has<T>(obj: IObservableArray<T>, index: number): boolean
|
|
|
133
145
|
export function has<T extends Object>(obj: T, key: string): boolean
|
|
134
146
|
export function has(obj: any, key: any): boolean {
|
|
135
147
|
if (isObservableObject(obj)) {
|
|
136
|
-
return (
|
|
148
|
+
return (obj as any as IIsObservableObject)[$mobx].has_(key)
|
|
137
149
|
} else if (isObservableMap(obj)) {
|
|
138
150
|
return obj.has(key)
|
|
139
151
|
} else if (isObservableSet(obj)) {
|
|
@@ -148,9 +160,11 @@ export function get<K, V>(obj: ObservableMap<K, V>, key: K): V | undefined
|
|
|
148
160
|
export function get<T>(obj: IObservableArray<T>, index: number): T | undefined
|
|
149
161
|
export function get<T extends Object>(obj: T, key: string): any
|
|
150
162
|
export function get(obj: any, key: any): any {
|
|
151
|
-
if (!has(obj, key))
|
|
163
|
+
if (!has(obj, key)) {
|
|
164
|
+
return undefined
|
|
165
|
+
}
|
|
152
166
|
if (isObservableObject(obj)) {
|
|
153
|
-
return (
|
|
167
|
+
return (obj as any as IIsObservableObject)[$mobx].get_(key)
|
|
154
168
|
} else if (isObservableMap(obj)) {
|
|
155
169
|
return obj.get(key)
|
|
156
170
|
} else if (isObservableArray(obj)) {
|
|
@@ -158,3 +172,17 @@ export function get(obj: any, key: any): any {
|
|
|
158
172
|
}
|
|
159
173
|
die(11)
|
|
160
174
|
}
|
|
175
|
+
|
|
176
|
+
export function apiDefineProperty(obj: Object, key: PropertyKey, descriptor: PropertyDescriptor) {
|
|
177
|
+
if (isObservableObject(obj)) {
|
|
178
|
+
return (obj as any as IIsObservableObject)[$mobx].defineProperty_(key, descriptor)
|
|
179
|
+
}
|
|
180
|
+
die(39)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export function apiOwnKeys(obj: Object) {
|
|
184
|
+
if (isObservableObject(obj)) {
|
|
185
|
+
return (obj as any as IIsObservableObject)[$mobx].ownKeys_()
|
|
186
|
+
}
|
|
187
|
+
die(38)
|
|
188
|
+
}
|
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"
|
|
@@ -59,14 +60,14 @@ export function asCreateObservableOptions(thing: any): CreateObservableOptions {
|
|
|
59
60
|
return thing || defaultCreateObservableOptions
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
const observableAnnotation = createObservableAnnotation(
|
|
63
|
-
const observableRefAnnotation = createObservableAnnotation(
|
|
63
|
+
const observableAnnotation = createObservableAnnotation(OBSERVABLE)
|
|
64
|
+
const observableRefAnnotation = createObservableAnnotation(OBSERVABLE_REF, {
|
|
64
65
|
enhancer: referenceEnhancer
|
|
65
66
|
})
|
|
66
|
-
const observableShallowAnnotation = createObservableAnnotation(
|
|
67
|
+
const observableShallowAnnotation = createObservableAnnotation(OBSERVABLE_SHALLOW, {
|
|
67
68
|
enhancer: shallowEnhancer
|
|
68
69
|
})
|
|
69
|
-
const observableStructAnnotation = createObservableAnnotation(
|
|
70
|
+
const observableStructAnnotation = createObservableAnnotation(OBSERVABLE_STRUCT, {
|
|
70
71
|
enhancer: refStructEnhancer
|
|
71
72
|
})
|
|
72
73
|
const observableDecoratorAnnotation = createDecoratorAnnotation(observableAnnotation)
|
|
@@ -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> {
|
|
@@ -107,27 +102,44 @@ function createObservable(v: any, arg2?: any, arg3?: any) {
|
|
|
107
102
|
}
|
|
108
103
|
|
|
109
104
|
// already observable - ignore
|
|
110
|
-
if (isObservable(v))
|
|
105
|
+
if (isObservable(v)) {
|
|
106
|
+
return v
|
|
107
|
+
}
|
|
111
108
|
|
|
112
109
|
// plain object
|
|
113
|
-
if (isPlainObject(v))
|
|
110
|
+
if (isPlainObject(v)) {
|
|
111
|
+
return observable.object(v, arg2, arg3)
|
|
112
|
+
}
|
|
114
113
|
|
|
115
114
|
// Array
|
|
116
|
-
if (Array.isArray(v))
|
|
115
|
+
if (Array.isArray(v)) {
|
|
116
|
+
return observable.array(v, arg2)
|
|
117
|
+
}
|
|
117
118
|
|
|
118
119
|
// Map
|
|
119
|
-
if (isES6Map(v))
|
|
120
|
+
if (isES6Map(v)) {
|
|
121
|
+
return observable.map(v, arg2)
|
|
122
|
+
}
|
|
120
123
|
|
|
121
124
|
// Set
|
|
122
|
-
if (isES6Set(v))
|
|
125
|
+
if (isES6Set(v)) {
|
|
126
|
+
return observable.set(v, arg2)
|
|
127
|
+
}
|
|
123
128
|
|
|
124
129
|
// other object - ignore
|
|
125
|
-
if (typeof v === "object" && v !== null)
|
|
130
|
+
if (typeof v === "object" && v !== null) {
|
|
131
|
+
return v
|
|
132
|
+
}
|
|
126
133
|
|
|
127
134
|
// anything else
|
|
128
135
|
return observable.box(v, arg2)
|
|
129
136
|
}
|
|
130
|
-
|
|
137
|
+
assign(createObservable, observableDecoratorAnnotation)
|
|
138
|
+
|
|
139
|
+
export interface IObservableValueFactory {
|
|
140
|
+
<T>(value: T, options?: CreateObservableOptions): IObservableValue<T>
|
|
141
|
+
<T>(value?: T, options?: CreateObservableOptions): IObservableValue<T | undefined>
|
|
142
|
+
}
|
|
131
143
|
|
|
132
144
|
export interface IObservableFactory extends Annotation, PropertyDecorator {
|
|
133
145
|
<T = any>(value: T[], options?: CreateObservableOptions): IObservableArray<T>
|
|
@@ -139,7 +151,7 @@ export interface IObservableFactory extends Annotation, PropertyDecorator {
|
|
|
139
151
|
options?: CreateObservableOptions
|
|
140
152
|
): T
|
|
141
153
|
|
|
142
|
-
box:
|
|
154
|
+
box: IObservableValueFactory
|
|
143
155
|
array: <T = any>(initialValues?: T[], options?: CreateObservableOptions) => IObservableArray<T>
|
|
144
156
|
set: <T = any>(
|
|
145
157
|
initialValues?: IObservableSetInitialValues<T>,
|
|
@@ -168,15 +180,17 @@ export interface IObservableFactory extends Annotation, PropertyDecorator {
|
|
|
168
180
|
}
|
|
169
181
|
|
|
170
182
|
const observableFactories: IObservableFactory = {
|
|
171
|
-
box<T = any>(value
|
|
183
|
+
box<T = any>(value: T, options?: CreateObservableOptions): IObservableValue<T> {
|
|
172
184
|
const o = asCreateObservableOptions(options)
|
|
173
185
|
return new ObservableValue(value, getEnhancerFromOptions(o), o.name, true, o.equals)
|
|
174
186
|
},
|
|
175
187
|
array<T = any>(initialValues?: T[], options?: CreateObservableOptions): IObservableArray<T> {
|
|
176
188
|
const o = asCreateObservableOptions(options)
|
|
177
|
-
return (
|
|
178
|
-
|
|
179
|
-
|
|
189
|
+
return (
|
|
190
|
+
globalState.useProxies === false || o.proxy === false
|
|
191
|
+
? createLegacyArray
|
|
192
|
+
: createObservableArray
|
|
193
|
+
)(initialValues, getEnhancerFromOptions(o), o.name)
|
|
180
194
|
},
|
|
181
195
|
map<K = any, V = any>(
|
|
182
196
|
initialValues?: IObservableMapInitialValues<K, V>,
|
|
@@ -192,7 +206,7 @@ const observableFactories: IObservableFactory = {
|
|
|
192
206
|
const o = asCreateObservableOptions(options)
|
|
193
207
|
return new ObservableSet<T>(initialValues, getEnhancerFromOptions(o), o.name)
|
|
194
208
|
},
|
|
195
|
-
object<T = any>(
|
|
209
|
+
object<T extends object = any>(
|
|
196
210
|
props: T,
|
|
197
211
|
decorators?: AnnotationsMap<T, never>,
|
|
198
212
|
options?: CreateObservableOptions
|
package/src/api/observe.ts
CHANGED
|
@@ -20,22 +20,23 @@ export function observe<T>(
|
|
|
20
20
|
fireImmediately?: boolean
|
|
21
21
|
): Lambda
|
|
22
22
|
export function observe<T>(
|
|
23
|
-
observableArray: IObservableArray<T>,
|
|
23
|
+
observableArray: IObservableArray<T> | Array<T>,
|
|
24
24
|
listener: (change: IArrayDidChange<T>) => void,
|
|
25
25
|
fireImmediately?: boolean
|
|
26
26
|
): Lambda
|
|
27
27
|
export function observe<V>(
|
|
28
|
-
|
|
28
|
+
// ObservableSet/ObservableMap are required despite they implement Set/Map: https://github.com/mobxjs/mobx/pull/3180#discussion_r746542929
|
|
29
|
+
observableSet: ObservableSet<V> | Set<V>,
|
|
29
30
|
listener: (change: ISetDidChange<V>) => void,
|
|
30
31
|
fireImmediately?: boolean
|
|
31
32
|
): Lambda
|
|
32
33
|
export function observe<K, V>(
|
|
33
|
-
observableMap: ObservableMap<K, V>,
|
|
34
|
+
observableMap: ObservableMap<K, V> | Map<K, V>,
|
|
34
35
|
listener: (change: IMapDidChange<K, V>) => void,
|
|
35
36
|
fireImmediately?: boolean
|
|
36
37
|
): Lambda
|
|
37
38
|
export function observe<K, V>(
|
|
38
|
-
observableMap: ObservableMap<K, V>,
|
|
39
|
+
observableMap: ObservableMap<K, V> | Map<K, V>,
|
|
39
40
|
property: K,
|
|
40
41
|
listener: (change: IValueDidChange<V>) => void,
|
|
41
42
|
fireImmediately?: boolean
|
|
@@ -52,9 +53,11 @@ export function observe<T, K extends keyof T>(
|
|
|
52
53
|
fireImmediately?: boolean
|
|
53
54
|
): Lambda
|
|
54
55
|
export function observe(thing, propOrCb?, cbOrFire?, fireImmediately?): Lambda {
|
|
55
|
-
if (isFunction(cbOrFire))
|
|
56
|
+
if (isFunction(cbOrFire)) {
|
|
56
57
|
return observeObservableProperty(thing, propOrCb, cbOrFire, fireImmediately)
|
|
57
|
-
else
|
|
58
|
+
} else {
|
|
59
|
+
return observeObservable(thing, propOrCb, cbOrFire)
|
|
60
|
+
}
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
function observeObservable(thing, listener, fireImmediately: boolean) {
|
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 {
|
|
@@ -20,10 +21,13 @@ function toJSHelper(source, __alreadySeen: Map<any, any>) {
|
|
|
20
21
|
typeof source !== "object" ||
|
|
21
22
|
source instanceof Date ||
|
|
22
23
|
!isObservable(source)
|
|
23
|
-
)
|
|
24
|
+
) {
|
|
24
25
|
return source
|
|
26
|
+
}
|
|
25
27
|
|
|
26
|
-
if (isObservableValue(source)
|
|
28
|
+
if (isObservableValue(source) || isComputedValue(source)) {
|
|
29
|
+
return toJSHelper(source.get(), __alreadySeen)
|
|
30
|
+
}
|
|
27
31
|
if (__alreadySeen.has(source)) {
|
|
28
32
|
return __alreadySeen.get(source)
|
|
29
33
|
}
|
|
@@ -49,19 +53,25 @@ function toJSHelper(source, __alreadySeen: Map<any, any>) {
|
|
|
49
53
|
return res
|
|
50
54
|
} else {
|
|
51
55
|
// must be observable object
|
|
52
|
-
keys(source) // make sure keys are observed
|
|
53
56
|
const res = cache(__alreadySeen, source, {})
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
apiOwnKeys(source).forEach((key: any) => {
|
|
58
|
+
if (objectPrototype.propertyIsEnumerable.call(source, key)) {
|
|
59
|
+
res[key] = toJSHelper(source[key], __alreadySeen)
|
|
60
|
+
}
|
|
56
61
|
})
|
|
57
62
|
return res
|
|
58
63
|
}
|
|
59
64
|
}
|
|
60
65
|
|
|
61
66
|
/**
|
|
62
|
-
*
|
|
67
|
+
* Recursively converts an observable to it's non-observable native counterpart.
|
|
68
|
+
* It does NOT recurse into non-observables, these are left as they are, even if they contain observables.
|
|
69
|
+
* Computed and other non-enumerable properties are completely ignored.
|
|
70
|
+
* Complex scenarios require custom solution, eg implementing `toJSON` or using `serializr` lib.
|
|
63
71
|
*/
|
|
64
72
|
export function toJS<T>(source: T, options?: any): T {
|
|
65
|
-
if (__DEV__ && options)
|
|
73
|
+
if (__DEV__ && options) {
|
|
74
|
+
die("toJS no longer supports options")
|
|
75
|
+
}
|
|
66
76
|
return toJSHelper(source, new Map())
|
|
67
77
|
}
|
package/src/api/trace.ts
CHANGED
|
@@ -4,9 +4,13 @@ export function trace(thing?: any, prop?: string, enterBreakPoint?: boolean): vo
|
|
|
4
4
|
export function trace(thing?: any, enterBreakPoint?: boolean): void
|
|
5
5
|
export function trace(enterBreakPoint?: boolean): void
|
|
6
6
|
export function trace(...args: any[]): void {
|
|
7
|
-
if (!__DEV__)
|
|
7
|
+
if (!__DEV__) {
|
|
8
|
+
die(`trace() is not available in production builds`)
|
|
9
|
+
}
|
|
8
10
|
let enterBreakPoint = false
|
|
9
|
-
if (typeof args[args.length - 1] === "boolean")
|
|
11
|
+
if (typeof args[args.length - 1] === "boolean") {
|
|
12
|
+
enterBreakPoint = args.pop()
|
|
13
|
+
}
|
|
10
14
|
const derivation = getAtomFromArgs(args)
|
|
11
15
|
if (!derivation) {
|
|
12
16
|
return die(
|
package/src/api/when.ts
CHANGED
|
@@ -9,10 +9,19 @@ import {
|
|
|
9
9
|
allowStateChanges
|
|
10
10
|
} from "../internal"
|
|
11
11
|
|
|
12
|
+
// https://github.com/mobxjs/mobx/issues/3582
|
|
13
|
+
interface GenericAbortSignal {
|
|
14
|
+
readonly aborted: boolean
|
|
15
|
+
onabort?: ((...args: any) => any) | null
|
|
16
|
+
addEventListener?: (...args: any) => any
|
|
17
|
+
removeEventListener?: (...args: any) => any
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
export interface IWhenOptions {
|
|
13
21
|
name?: string
|
|
14
22
|
timeout?: number
|
|
15
23
|
onError?: (error: any) => void
|
|
24
|
+
signal?: GenericAbortSignal
|
|
16
25
|
}
|
|
17
26
|
|
|
18
27
|
export function when(
|
|
@@ -25,20 +34,24 @@ export function when(
|
|
|
25
34
|
opts?: IWhenOptions
|
|
26
35
|
): IReactionDisposer
|
|
27
36
|
export function when(predicate: any, arg1?: any, arg2?: any): any {
|
|
28
|
-
if (arguments.length === 1 || (arg1 && typeof arg1 === "object"))
|
|
37
|
+
if (arguments.length === 1 || (arg1 && typeof arg1 === "object")) {
|
|
29
38
|
return whenPromise(predicate, arg1)
|
|
39
|
+
}
|
|
30
40
|
return _when(predicate, arg1, arg2 || {})
|
|
31
41
|
}
|
|
32
42
|
|
|
33
43
|
function _when(predicate: () => boolean, effect: Lambda, opts: IWhenOptions): IReactionDisposer {
|
|
34
44
|
let timeoutHandle: any
|
|
35
45
|
if (typeof opts.timeout === "number") {
|
|
46
|
+
const error = new Error("WHEN_TIMEOUT")
|
|
36
47
|
timeoutHandle = setTimeout(() => {
|
|
37
48
|
if (!disposer[$mobx].isDisposed_) {
|
|
38
49
|
disposer()
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
else
|
|
50
|
+
if (opts.onError) {
|
|
51
|
+
opts.onError(error)
|
|
52
|
+
} else {
|
|
53
|
+
throw error
|
|
54
|
+
}
|
|
42
55
|
}
|
|
43
56
|
}, opts.timeout)
|
|
44
57
|
}
|
|
@@ -54,7 +67,9 @@ function _when(predicate: () => boolean, effect: Lambda, opts: IWhenOptions): IR
|
|
|
54
67
|
let cond = allowStateChanges(false, predicate)
|
|
55
68
|
if (cond) {
|
|
56
69
|
r.dispose()
|
|
57
|
-
if (timeoutHandle)
|
|
70
|
+
if (timeoutHandle) {
|
|
71
|
+
clearTimeout(timeoutHandle)
|
|
72
|
+
}
|
|
58
73
|
effectAction()
|
|
59
74
|
}
|
|
60
75
|
}, opts)
|
|
@@ -65,16 +80,26 @@ function whenPromise(
|
|
|
65
80
|
predicate: () => boolean,
|
|
66
81
|
opts?: IWhenOptions
|
|
67
82
|
): Promise<void> & { cancel(): void } {
|
|
68
|
-
if (__DEV__ && opts && opts.onError)
|
|
83
|
+
if (__DEV__ && opts && opts.onError) {
|
|
69
84
|
return die(`the options 'onError' and 'promise' cannot be combined`)
|
|
85
|
+
}
|
|
86
|
+
if (opts?.signal?.aborted) {
|
|
87
|
+
return Object.assign(Promise.reject(new Error("WHEN_ABORTED")), { cancel: () => null })
|
|
88
|
+
}
|
|
70
89
|
let cancel
|
|
90
|
+
let abort
|
|
71
91
|
const res = new Promise((resolve, reject) => {
|
|
72
|
-
let disposer = _when(predicate, resolve, { ...opts, onError: reject })
|
|
92
|
+
let disposer = _when(predicate, resolve as Lambda, { ...opts, onError: reject })
|
|
73
93
|
cancel = () => {
|
|
74
94
|
disposer()
|
|
75
|
-
reject("WHEN_CANCELLED")
|
|
95
|
+
reject(new Error("WHEN_CANCELLED"))
|
|
96
|
+
}
|
|
97
|
+
abort = () => {
|
|
98
|
+
disposer()
|
|
99
|
+
reject(new Error("WHEN_ABORTED"))
|
|
76
100
|
}
|
|
77
|
-
|
|
101
|
+
opts?.signal?.addEventListener?.("abort", abort)
|
|
102
|
+
}).finally(() => opts?.signal?.removeEventListener?.("abort", abort))
|
|
78
103
|
;(res as any).cancel = cancel
|
|
79
104
|
return res as any
|
|
80
105
|
}
|