mobx 6.10.0 → 6.10.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 +14 -0
- package/dist/core/atom.d.ts +2 -1
- package/dist/core/globalstate.d.ts +5 -0
- package/dist/mobx.cjs.development.js +119 -78
- 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.esm.development.js +119 -78
- package/dist/mobx.esm.development.js.map +1 -1
- package/dist/mobx.esm.js +119 -78
- 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 +119 -78
- 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/type-utils.d.ts +7 -0
- package/package.json +1 -1
- package/src/api/extendobservable.ts +6 -9
- package/src/api/makeObservable.ts +18 -24
- package/src/api/observable.ts +10 -7
- package/src/core/atom.ts +16 -8
- package/src/core/globalstate.ts +6 -0
- package/src/core/observable.ts +6 -0
- package/src/types/legacyobservablearray.ts +17 -19
- package/src/types/observablearray.ts +12 -13
- package/src/types/observablemap.ts +13 -10
- package/src/types/observableobject.ts +6 -1
- package/src/types/observableset.ts +9 -6
- package/src/types/type-utils.ts +26 -1
|
@@ -2,3 +2,10 @@ import { IDepTreeNode } from "../internal";
|
|
|
2
2
|
export declare function getAtom(thing: any, property?: PropertyKey): IDepTreeNode;
|
|
3
3
|
export declare function getAdministration(thing: any, property?: string): any;
|
|
4
4
|
export declare function getDebugName(thing: any, property?: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Helper function for initializing observable structures, it applies:
|
|
7
|
+
* 1. allowStateChanges so we don't violate enforceActions.
|
|
8
|
+
* 2. untracked so we don't accidentaly subscribe to anything observable accessed during init in case the observable is created inside derivation.
|
|
9
|
+
* 3. batch to avoid state version updates
|
|
10
|
+
*/
|
|
11
|
+
export declare function initObservable<T>(cb: () => T): T;
|
package/package.json
CHANGED
|
@@ -2,8 +2,6 @@ import {
|
|
|
2
2
|
CreateObservableOptions,
|
|
3
3
|
isObservableMap,
|
|
4
4
|
AnnotationsMap,
|
|
5
|
-
startBatch,
|
|
6
|
-
endBatch,
|
|
7
5
|
asObservableObject,
|
|
8
6
|
isPlainObject,
|
|
9
7
|
ObservableObjectAdministration,
|
|
@@ -11,7 +9,8 @@ import {
|
|
|
11
9
|
die,
|
|
12
10
|
getOwnPropertyDescriptors,
|
|
13
11
|
$mobx,
|
|
14
|
-
ownKeys
|
|
12
|
+
ownKeys,
|
|
13
|
+
initObservable
|
|
15
14
|
} from "../internal"
|
|
16
15
|
|
|
17
16
|
export function extendObservable<A extends Object, B extends Object>(
|
|
@@ -40,9 +39,8 @@ export function extendObservable<A extends Object, B extends Object>(
|
|
|
40
39
|
// Pull descriptors first, so we don't have to deal with props added by administration ($mobx)
|
|
41
40
|
const descriptors = getOwnPropertyDescriptors(properties)
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
try {
|
|
42
|
+
initObservable(() => {
|
|
43
|
+
const adm: ObservableObjectAdministration = asObservableObject(target, options)[$mobx]
|
|
46
44
|
ownKeys(descriptors).forEach(key => {
|
|
47
45
|
adm.extend_(
|
|
48
46
|
key,
|
|
@@ -51,8 +49,7 @@ export function extendObservable<A extends Object, B extends Object>(
|
|
|
51
49
|
!annotations ? true : key in annotations ? annotations[key] : true
|
|
52
50
|
)
|
|
53
51
|
})
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
}
|
|
52
|
+
})
|
|
53
|
+
|
|
57
54
|
return target as any
|
|
58
55
|
}
|
|
@@ -2,8 +2,6 @@ import {
|
|
|
2
2
|
$mobx,
|
|
3
3
|
asObservableObject,
|
|
4
4
|
AnnotationsMap,
|
|
5
|
-
endBatch,
|
|
6
|
-
startBatch,
|
|
7
5
|
CreateObservableOptions,
|
|
8
6
|
ObservableObjectAdministration,
|
|
9
7
|
collectStoredAnnotations,
|
|
@@ -13,7 +11,8 @@ import {
|
|
|
13
11
|
ownKeys,
|
|
14
12
|
extendObservable,
|
|
15
13
|
addHiddenProp,
|
|
16
|
-
storedAnnotationsSymbol
|
|
14
|
+
storedAnnotationsSymbol,
|
|
15
|
+
initObservable
|
|
17
16
|
} from "../internal"
|
|
18
17
|
|
|
19
18
|
// Hack based on https://github.com/Microsoft/TypeScript/issues/14829#issuecomment-322267089
|
|
@@ -30,9 +29,8 @@ export function makeObservable<T extends object, AdditionalKeys extends Property
|
|
|
30
29
|
annotations?: AnnotationsMap<T, NoInfer<AdditionalKeys>>,
|
|
31
30
|
options?: MakeObservableOptions
|
|
32
31
|
): T {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
try {
|
|
32
|
+
initObservable(() => {
|
|
33
|
+
const adm: ObservableObjectAdministration = asObservableObject(target, options)[$mobx]
|
|
36
34
|
if (__DEV__ && annotations && target[storedAnnotationsSymbol]) {
|
|
37
35
|
die(
|
|
38
36
|
`makeObservable second arg must be nullish when using decorators. Mixing @decorator syntax with annotations is not supported.`
|
|
@@ -43,9 +41,7 @@ export function makeObservable<T extends object, AdditionalKeys extends Property
|
|
|
43
41
|
|
|
44
42
|
// Annotate
|
|
45
43
|
ownKeys(annotations).forEach(key => adm.make_(key, annotations![key]))
|
|
46
|
-
}
|
|
47
|
-
endBatch()
|
|
48
|
-
}
|
|
44
|
+
})
|
|
49
45
|
return target
|
|
50
46
|
}
|
|
51
47
|
|
|
@@ -72,20 +68,19 @@ export function makeAutoObservable<T extends object, AdditionalKeys extends Prop
|
|
|
72
68
|
return extendObservable(target, target, overrides, options)
|
|
73
69
|
}
|
|
74
70
|
|
|
75
|
-
|
|
71
|
+
initObservable(() => {
|
|
72
|
+
const adm: ObservableObjectAdministration = asObservableObject(target, options)[$mobx]
|
|
76
73
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
74
|
+
// Optimization: cache keys on proto
|
|
75
|
+
// Assumes makeAutoObservable can be called only once per object and can't be used in subclass
|
|
76
|
+
if (!target[keysSymbol]) {
|
|
77
|
+
const proto = Object.getPrototypeOf(target)
|
|
78
|
+
const keys = new Set([...ownKeys(target), ...ownKeys(proto)])
|
|
79
|
+
keys.delete("constructor")
|
|
80
|
+
keys.delete($mobx)
|
|
81
|
+
addHiddenProp(proto, keysSymbol, keys)
|
|
82
|
+
}
|
|
86
83
|
|
|
87
|
-
startBatch()
|
|
88
|
-
try {
|
|
89
84
|
target[keysSymbol].forEach(key =>
|
|
90
85
|
adm.make_(
|
|
91
86
|
key,
|
|
@@ -93,8 +88,7 @@ export function makeAutoObservable<T extends object, AdditionalKeys extends Prop
|
|
|
93
88
|
!overrides ? true : key in overrides ? overrides[key] : true
|
|
94
89
|
)
|
|
95
90
|
)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
}
|
|
91
|
+
})
|
|
92
|
+
|
|
99
93
|
return target
|
|
100
94
|
}
|
package/src/api/observable.ts
CHANGED
|
@@ -29,7 +29,8 @@ import {
|
|
|
29
29
|
assign,
|
|
30
30
|
isStringish,
|
|
31
31
|
createObservableAnnotation,
|
|
32
|
-
createAutoAnnotation
|
|
32
|
+
createAutoAnnotation,
|
|
33
|
+
initObservable
|
|
33
34
|
} from "../internal"
|
|
34
35
|
|
|
35
36
|
export const OBSERVABLE = "observable"
|
|
@@ -211,12 +212,14 @@ const observableFactories: IObservableFactory = {
|
|
|
211
212
|
decorators?: AnnotationsMap<T, never>,
|
|
212
213
|
options?: CreateObservableOptions
|
|
213
214
|
): T {
|
|
214
|
-
return
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
215
|
+
return initObservable(() =>
|
|
216
|
+
extendObservable(
|
|
217
|
+
globalState.useProxies === false || options?.proxy === false
|
|
218
|
+
? asObservableObject({}, options)
|
|
219
|
+
: asDynamicObservableObject({}, options),
|
|
220
|
+
props,
|
|
221
|
+
decorators
|
|
222
|
+
)
|
|
220
223
|
)
|
|
221
224
|
},
|
|
222
225
|
ref: createDecoratorAnnotation(observableRefAnnotation),
|
package/src/core/atom.ts
CHANGED
|
@@ -19,7 +19,7 @@ export const $mobx = Symbol("mobx administration")
|
|
|
19
19
|
|
|
20
20
|
export interface IAtom extends IObservable {
|
|
21
21
|
reportObserved(): boolean
|
|
22
|
-
reportChanged()
|
|
22
|
+
reportChanged(): void
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export class Atom implements IAtom {
|
|
@@ -27,6 +27,7 @@ export class Atom implements IAtom {
|
|
|
27
27
|
isBeingObserved_ = false
|
|
28
28
|
observers_ = new Set<IDerivation>()
|
|
29
29
|
|
|
30
|
+
batchId_: number
|
|
30
31
|
diffValue_ = 0
|
|
31
32
|
lastAccessedBy_ = 0
|
|
32
33
|
lowestObserverState_ = IDerivationState_.NOT_TRACKING_
|
|
@@ -34,7 +35,9 @@ export class Atom implements IAtom {
|
|
|
34
35
|
* Create a new atom. For debugging purposes it is recommended to give it a name.
|
|
35
36
|
* The onBecomeObserved and onBecomeUnobserved callbacks can be used for resource management.
|
|
36
37
|
*/
|
|
37
|
-
constructor(public name_ = __DEV__ ? "Atom@" + getNextId() : "Atom") {
|
|
38
|
+
constructor(public name_ = __DEV__ ? "Atom@" + getNextId() : "Atom") {
|
|
39
|
+
this.batchId_ = globalState.inBatch ? globalState.batchId : NaN
|
|
40
|
+
}
|
|
38
41
|
|
|
39
42
|
// onBecomeObservedListeners
|
|
40
43
|
public onBOL: Set<Lambda> | undefined
|
|
@@ -65,14 +68,19 @@ export class Atom implements IAtom {
|
|
|
65
68
|
* Invoke this method _after_ this method has changed to signal mobx that all its observers should invalidate.
|
|
66
69
|
*/
|
|
67
70
|
public reportChanged() {
|
|
71
|
+
if (!globalState.inBatch || this.batchId_ !== globalState.batchId) {
|
|
72
|
+
// We could update state version only at the end of batch,
|
|
73
|
+
// but we would still have to switch some global flag here to signal a change.
|
|
74
|
+
globalState.stateVersion =
|
|
75
|
+
globalState.stateVersion < Number.MAX_SAFE_INTEGER
|
|
76
|
+
? globalState.stateVersion + 1
|
|
77
|
+
: Number.MIN_SAFE_INTEGER
|
|
78
|
+
// Avoids the possibility of hitting the same globalState.batchId when it cycled through all integers (necessary?)
|
|
79
|
+
this.batchId_ = NaN
|
|
80
|
+
}
|
|
81
|
+
|
|
68
82
|
startBatch()
|
|
69
83
|
propagateChanged(this)
|
|
70
|
-
// We could update state version only at the end of batch,
|
|
71
|
-
// but we would still have to switch some global flag here to signal a change.
|
|
72
|
-
globalState.stateVersion =
|
|
73
|
-
globalState.stateVersion < Number.MAX_SAFE_INTEGER
|
|
74
|
-
? globalState.stateVersion + 1
|
|
75
|
-
: Number.MIN_SAFE_INTEGER
|
|
76
84
|
endBatch()
|
|
77
85
|
}
|
|
78
86
|
|
package/src/core/globalstate.ts
CHANGED
|
@@ -63,6 +63,12 @@ export class MobXGlobals {
|
|
|
63
63
|
*/
|
|
64
64
|
inBatch: number = 0
|
|
65
65
|
|
|
66
|
+
/**
|
|
67
|
+
* ID of the latest batch. Used to suppress reportChanged of newly created atoms.
|
|
68
|
+
* Note the value persists even after batch ended.
|
|
69
|
+
*/
|
|
70
|
+
batchId: number = Number.MIN_SAFE_INTEGER
|
|
71
|
+
|
|
66
72
|
/**
|
|
67
73
|
* Observables that don't have observers anymore, and are about to be
|
|
68
74
|
* suspended, unless somebody else accesses it in the same batch
|
package/src/core/observable.ts
CHANGED
|
@@ -104,6 +104,12 @@ export function queueForUnobservation(observable: IObservable) {
|
|
|
104
104
|
* Avoids unnecessary recalculations.
|
|
105
105
|
*/
|
|
106
106
|
export function startBatch() {
|
|
107
|
+
if (globalState.inBatch === 0) {
|
|
108
|
+
globalState.batchId =
|
|
109
|
+
globalState.batchId < Number.MAX_SAFE_INTEGER
|
|
110
|
+
? globalState.batchId + 1
|
|
111
|
+
: Number.MIN_SAFE_INTEGER
|
|
112
|
+
}
|
|
107
113
|
globalState.inBatch++
|
|
108
114
|
}
|
|
109
115
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getNextId,
|
|
3
3
|
addHiddenFinalProp,
|
|
4
|
-
allowStateChangesStart,
|
|
5
|
-
allowStateChangesEnd,
|
|
6
4
|
makeIterable,
|
|
7
5
|
addHiddenProp,
|
|
8
6
|
ObservableArrayAdministration,
|
|
@@ -11,7 +9,8 @@ import {
|
|
|
11
9
|
IEnhancer,
|
|
12
10
|
isObservableArray,
|
|
13
11
|
IObservableArray,
|
|
14
|
-
defineProperty
|
|
12
|
+
defineProperty,
|
|
13
|
+
initObservable
|
|
15
14
|
} from "../internal"
|
|
16
15
|
|
|
17
16
|
// Bug in safari 9.* (or iOS 9 safari mobile). See #364
|
|
@@ -61,23 +60,22 @@ class LegacyObservableArray<T> extends StubArray {
|
|
|
61
60
|
owned = false
|
|
62
61
|
) {
|
|
63
62
|
super()
|
|
63
|
+
initObservable(() => {
|
|
64
|
+
const adm = new ObservableArrayAdministration(name, enhancer, owned, true)
|
|
65
|
+
adm.proxy_ = this as any
|
|
66
|
+
addHiddenFinalProp(this, $mobx, adm)
|
|
67
|
+
|
|
68
|
+
if (initialValues && initialValues.length) {
|
|
69
|
+
// @ts-ignore
|
|
70
|
+
this.spliceWithArray(0, 0, initialValues)
|
|
71
|
+
}
|
|
64
72
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
// @ts-ignore
|
|
72
|
-
this.spliceWithArray(0, 0, initialValues)
|
|
73
|
-
allowStateChangesEnd(prev)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (safariPrototypeSetterInheritanceBug) {
|
|
77
|
-
// Seems that Safari won't use numeric prototype setter untill any * numeric property is
|
|
78
|
-
// defined on the instance. After that it works fine, even if this property is deleted.
|
|
79
|
-
Object.defineProperty(this, "0", ENTRY_0)
|
|
80
|
-
}
|
|
73
|
+
if (safariPrototypeSetterInheritanceBug) {
|
|
74
|
+
// Seems that Safari won't use numeric prototype setter untill any * numeric property is
|
|
75
|
+
// defined on the instance. After that it works fine, even if this property is deleted.
|
|
76
|
+
Object.defineProperty(this, "0", ENTRY_0)
|
|
77
|
+
}
|
|
78
|
+
})
|
|
81
79
|
}
|
|
82
80
|
|
|
83
81
|
concat(...arrays: T[][]): T[] {
|
|
@@ -22,13 +22,12 @@ import {
|
|
|
22
22
|
registerListener,
|
|
23
23
|
spyReportEnd,
|
|
24
24
|
spyReportStart,
|
|
25
|
-
allowStateChangesStart,
|
|
26
|
-
allowStateChangesEnd,
|
|
27
25
|
assertProxies,
|
|
28
26
|
reserveArrayBuffer,
|
|
29
27
|
hasProp,
|
|
30
28
|
die,
|
|
31
|
-
globalState
|
|
29
|
+
globalState,
|
|
30
|
+
initObservable
|
|
32
31
|
} from "../internal"
|
|
33
32
|
|
|
34
33
|
const SPLICE = "splice"
|
|
@@ -406,16 +405,16 @@ export function createObservableArray<T>(
|
|
|
406
405
|
owned = false
|
|
407
406
|
): IObservableArray<T> {
|
|
408
407
|
assertProxies()
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
408
|
+
return initObservable(() => {
|
|
409
|
+
const adm = new ObservableArrayAdministration(name, enhancer, owned, false)
|
|
410
|
+
addHiddenFinalProp(adm.values_, $mobx, adm)
|
|
411
|
+
const proxy = new Proxy(adm.values_, arrayTraps) as any
|
|
412
|
+
adm.proxy_ = proxy
|
|
413
|
+
if (initialValues && initialValues.length) {
|
|
414
|
+
adm.spliceWithArray_(0, 0, initialValues)
|
|
415
|
+
}
|
|
416
|
+
return proxy
|
|
417
|
+
})
|
|
419
418
|
}
|
|
420
419
|
|
|
421
420
|
// eslint-disable-next-line
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
UPDATE,
|
|
36
36
|
IAtom,
|
|
37
37
|
PureSpyEvent,
|
|
38
|
-
|
|
38
|
+
initObservable
|
|
39
39
|
} from "../internal"
|
|
40
40
|
|
|
41
41
|
export interface IKeyValueMap<V = any> {
|
|
@@ -90,11 +90,12 @@ export type IObservableMapInitialValues<K = any, V = any> =
|
|
|
90
90
|
// just extend Map? See also https://gist.github.com/nestharus/13b4d74f2ef4a2f4357dbd3fc23c1e54
|
|
91
91
|
// But: https://github.com/mobxjs/mobx/issues/1556
|
|
92
92
|
export class ObservableMap<K = any, V = any>
|
|
93
|
-
implements Map<K, V>, IInterceptable<IMapWillChange<K, V>>, IListenable
|
|
93
|
+
implements Map<K, V>, IInterceptable<IMapWillChange<K, V>>, IListenable
|
|
94
|
+
{
|
|
94
95
|
[$mobx] = ObservableMapMarker
|
|
95
|
-
data_
|
|
96
|
-
hasMap_
|
|
97
|
-
keysAtom_
|
|
96
|
+
data_!: Map<K, ObservableValue<V>>
|
|
97
|
+
hasMap_!: Map<K, ObservableValue<boolean>> // hasMap, not hashMap >-).
|
|
98
|
+
keysAtom_!: IAtom
|
|
98
99
|
interceptors_
|
|
99
100
|
changeListeners_
|
|
100
101
|
dehancer: any
|
|
@@ -107,11 +108,13 @@ export class ObservableMap<K = any, V = any>
|
|
|
107
108
|
if (!isFunction(Map)) {
|
|
108
109
|
die(18)
|
|
109
110
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
initObservable(() => {
|
|
112
|
+
this.keysAtom_ = createAtom(__DEV__ ? `${this.name_}.keys()` : "ObservableMap.keys()")
|
|
113
|
+
this.data_ = new Map()
|
|
114
|
+
this.hasMap_ = new Map()
|
|
115
|
+
if (initialData) {
|
|
116
|
+
this.merge(initialData)
|
|
117
|
+
}
|
|
115
118
|
})
|
|
116
119
|
}
|
|
117
120
|
|
|
@@ -46,7 +46,8 @@ import {
|
|
|
46
46
|
getAdministration,
|
|
47
47
|
getDebugName,
|
|
48
48
|
objectPrototype,
|
|
49
|
-
MakeResult
|
|
49
|
+
MakeResult,
|
|
50
|
+
checkIfStateModificationsAreAllowed
|
|
50
51
|
} from "../internal"
|
|
51
52
|
|
|
52
53
|
const descriptorCache = Object.create(null)
|
|
@@ -314,6 +315,7 @@ export class ObservableObjectAdministration
|
|
|
314
315
|
descriptor: PropertyDescriptor,
|
|
315
316
|
proxyTrap: boolean = false
|
|
316
317
|
): boolean | null {
|
|
318
|
+
checkIfStateModificationsAreAllowed(this.keysAtom_)
|
|
317
319
|
try {
|
|
318
320
|
startBatch()
|
|
319
321
|
|
|
@@ -368,6 +370,7 @@ export class ObservableObjectAdministration
|
|
|
368
370
|
enhancer: IEnhancer<any>,
|
|
369
371
|
proxyTrap: boolean = false
|
|
370
372
|
): boolean | null {
|
|
373
|
+
checkIfStateModificationsAreAllowed(this.keysAtom_)
|
|
371
374
|
try {
|
|
372
375
|
startBatch()
|
|
373
376
|
|
|
@@ -432,6 +435,7 @@ export class ObservableObjectAdministration
|
|
|
432
435
|
options: IComputedValueOptions<any>,
|
|
433
436
|
proxyTrap: boolean = false
|
|
434
437
|
): boolean | null {
|
|
438
|
+
checkIfStateModificationsAreAllowed(this.keysAtom_)
|
|
435
439
|
try {
|
|
436
440
|
startBatch()
|
|
437
441
|
|
|
@@ -490,6 +494,7 @@ export class ObservableObjectAdministration
|
|
|
490
494
|
* @returns {boolean|null} true on success, false on failure (proxyTrap + non-configurable), null when cancelled by interceptor
|
|
491
495
|
*/
|
|
492
496
|
delete_(key: PropertyKey, proxyTrap: boolean = false): boolean | null {
|
|
497
|
+
checkIfStateModificationsAreAllowed(this.keysAtom_)
|
|
493
498
|
// No such prop
|
|
494
499
|
if (!hasProp(this.target_, key)) {
|
|
495
500
|
return true
|
|
@@ -27,7 +27,8 @@ import {
|
|
|
27
27
|
DELETE,
|
|
28
28
|
ADD,
|
|
29
29
|
die,
|
|
30
|
-
isFunction
|
|
30
|
+
isFunction,
|
|
31
|
+
initObservable
|
|
31
32
|
} from "../internal"
|
|
32
33
|
|
|
33
34
|
const ObservableSetMarker = {}
|
|
@@ -65,7 +66,7 @@ export type ISetWillChange<T = any> =
|
|
|
65
66
|
export class ObservableSet<T = any> implements Set<T>, IInterceptable<ISetWillChange>, IListenable {
|
|
66
67
|
[$mobx] = ObservableSetMarker
|
|
67
68
|
private data_: Set<any> = new Set()
|
|
68
|
-
atom_
|
|
69
|
+
atom_!: IAtom
|
|
69
70
|
changeListeners_
|
|
70
71
|
interceptors_
|
|
71
72
|
dehancer: any
|
|
@@ -79,11 +80,13 @@ export class ObservableSet<T = any> implements Set<T>, IInterceptable<ISetWillCh
|
|
|
79
80
|
if (!isFunction(Set)) {
|
|
80
81
|
die(22)
|
|
81
82
|
}
|
|
82
|
-
this.atom_ = createAtom(this.name_)
|
|
83
83
|
this.enhancer_ = (newV, oldV) => enhancer(newV, oldV, name_)
|
|
84
|
-
|
|
85
|
-
this.
|
|
86
|
-
|
|
84
|
+
initObservable(() => {
|
|
85
|
+
this.atom_ = createAtom(this.name_)
|
|
86
|
+
if (initialData) {
|
|
87
|
+
this.replace(initialData)
|
|
88
|
+
}
|
|
89
|
+
})
|
|
87
90
|
}
|
|
88
91
|
|
|
89
92
|
private dehanceValue_<X extends T | undefined>(value: X): X {
|
package/src/types/type-utils.ts
CHANGED
|
@@ -10,7 +10,13 @@ import {
|
|
|
10
10
|
isReaction,
|
|
11
11
|
isObservableSet,
|
|
12
12
|
die,
|
|
13
|
-
isFunction
|
|
13
|
+
isFunction,
|
|
14
|
+
allowStateChangesStart,
|
|
15
|
+
untrackedStart,
|
|
16
|
+
allowStateChangesEnd,
|
|
17
|
+
untrackedEnd,
|
|
18
|
+
startBatch,
|
|
19
|
+
endBatch
|
|
14
20
|
} from "../internal"
|
|
15
21
|
|
|
16
22
|
export function getAtom(thing: any, property?: PropertyKey): IDepTreeNode {
|
|
@@ -92,3 +98,22 @@ export function getDebugName(thing: any, property?: string): string {
|
|
|
92
98
|
}
|
|
93
99
|
return named.name_
|
|
94
100
|
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Helper function for initializing observable structures, it applies:
|
|
104
|
+
* 1. allowStateChanges so we don't violate enforceActions.
|
|
105
|
+
* 2. untracked so we don't accidentaly subscribe to anything observable accessed during init in case the observable is created inside derivation.
|
|
106
|
+
* 3. batch to avoid state version updates
|
|
107
|
+
*/
|
|
108
|
+
export function initObservable<T>(cb: () => T): T {
|
|
109
|
+
const derivation = untrackedStart()
|
|
110
|
+
const allowStateChanges = allowStateChangesStart(true)
|
|
111
|
+
startBatch()
|
|
112
|
+
try {
|
|
113
|
+
return cb()
|
|
114
|
+
} finally {
|
|
115
|
+
endBatch()
|
|
116
|
+
allowStateChangesEnd(allowStateChanges)
|
|
117
|
+
untrackedEnd(derivation)
|
|
118
|
+
}
|
|
119
|
+
}
|