mobx 6.16.1 → 7.0.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 +72 -0
- package/README.md +9 -13
- package/dist/api/action.d.ts +6 -4
- package/dist/api/annotation.d.ts +0 -1
- package/dist/api/computed.d.ts +4 -7
- package/dist/api/configure.d.ts +0 -1
- package/dist/api/decoratorannotation.d.ts +3 -0
- package/dist/api/decorators.d.ts +0 -19
- package/dist/api/flow.d.ts +4 -5
- package/dist/api/makeObservable.d.ts +2 -3
- package/dist/api/observable.d.ts +9 -15
- package/dist/core/atom.d.ts +0 -3
- package/dist/core/computedvalue.d.ts +4 -32
- package/dist/core/derivation.d.ts +1 -7
- package/dist/core/globalstate.d.ts +0 -2
- package/dist/core/reaction.d.ts +1 -9
- package/dist/errors.d.ts +6 -4
- package/dist/internal.d.ts +1 -4
- package/dist/mobx.cjs.development.js +1630 -2447
- 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 +2 -2
- package/dist/mobx.esm.development.js +1619 -2446
- package/dist/mobx.esm.development.js.map +1 -1
- package/dist/mobx.esm.js +1567 -2397
- 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.mjs +5271 -0
- package/dist/mobx.mjs.map +1 -0
- package/dist/mobx.umd.development.js +1633 -2450
- 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 +1 -0
- package/dist/types/computedannotation.d.ts +1 -0
- package/dist/types/decorator_fills.d.ts +2 -0
- package/dist/types/flowannotation.d.ts +1 -0
- package/dist/types/observableannotation.d.ts +5 -0
- package/dist/types/observablearray.d.ts +2 -5
- package/dist/types/observablemap.d.ts +1 -8
- package/dist/types/observableobject.d.ts +2 -13
- package/dist/types/observableset.d.ts +1 -3
- package/dist/types/observablevalue.d.ts +4 -6
- package/dist/types/overrideannotation.d.ts +1 -2
- package/dist/utils/comparer.d.ts +4 -11
- package/dist/utils/utils.d.ts +0 -2
- package/package.json +25 -15
- package/src/api/action.ts +27 -35
- package/src/api/annotation.ts +0 -1
- package/src/api/autorun.ts +2 -4
- package/src/api/computed.ts +21 -28
- package/src/api/configure.ts +1 -15
- package/src/api/decoratorannotation.ts +20 -0
- package/src/api/decorators.ts +1 -85
- package/src/api/extras.ts +1 -1
- package/src/api/flow.ts +26 -29
- package/src/api/intercept.ts +4 -3
- package/src/api/makeObservable.ts +45 -17
- package/src/api/object-api.ts +1 -1
- package/src/api/observable.ts +34 -67
- package/src/api/observe.ts +82 -3
- package/src/api/when.ts +4 -3
- package/src/core/action.ts +12 -5
- package/src/core/atom.ts +14 -13
- package/src/core/computedvalue.ts +27 -67
- package/src/core/derivation.ts +15 -14
- package/src/core/globalstate.ts +8 -13
- package/src/core/observable.ts +0 -48
- package/src/core/reaction.ts +19 -25
- package/src/core/spy.ts +3 -3
- package/src/errors.ts +23 -12
- package/src/internal.ts +1 -4
- package/src/mobx.ts +21 -10
- package/src/types/actionannotation.ts +5 -9
- package/src/types/autoannotation.ts +8 -11
- package/src/types/computedannotation.ts +13 -11
- package/src/types/decorator_fills.ts +4 -0
- package/src/types/dynamicobject.ts +0 -29
- package/src/types/flowannotation.ts +7 -4
- package/src/types/observableannotation.ts +6 -7
- package/src/types/observablearray.ts +8 -61
- package/src/types/observablemap.ts +4 -29
- package/src/types/observableobject.ts +5 -70
- package/src/types/observableset.ts +5 -28
- package/src/types/observablevalue.ts +7 -29
- package/src/types/overrideannotation.ts +7 -22
- package/src/types/type-utils.ts +4 -2
- package/src/utils/comparer.ts +4 -17
- package/src/utils/iterable.ts +3 -4
- package/src/utils/utils.ts +4 -46
- package/dist/api/trace.d.ts +0 -3
- package/dist/types/legacyobservablearray.d.ts +0 -14
- package/dist/utils/global.d.ts +0 -1
- package/src/api/trace.ts +0 -35
- package/src/types/legacyobservablearray.ts +0 -155
- package/src/utils/global.ts +0 -20
|
@@ -5,10 +5,8 @@ import {
|
|
|
5
5
|
IEqualsComparer,
|
|
6
6
|
IObservable,
|
|
7
7
|
Lambda,
|
|
8
|
-
TraceMode,
|
|
9
|
-
autorun,
|
|
10
8
|
clearObserving,
|
|
11
|
-
|
|
9
|
+
compareDefault,
|
|
12
10
|
createAction,
|
|
13
11
|
createInstanceofPredicate,
|
|
14
12
|
endBatch,
|
|
@@ -24,9 +22,6 @@ import {
|
|
|
24
22
|
startBatch,
|
|
25
23
|
toPrimitive,
|
|
26
24
|
trackDerivedFunction,
|
|
27
|
-
untrackedEnd,
|
|
28
|
-
untrackedStart,
|
|
29
|
-
UPDATE,
|
|
30
25
|
die,
|
|
31
26
|
allowStateChangesStart,
|
|
32
27
|
allowStateChangesEnd
|
|
@@ -77,6 +72,14 @@ export type IComputedDidChange<T = any> = {
|
|
|
77
72
|
*
|
|
78
73
|
* If at any point it's outside batch and it isn't observed: reset everything and go to 1.
|
|
79
74
|
*/
|
|
75
|
+
const enum ComputedValueFlags {
|
|
76
|
+
isComputing = 0b00001,
|
|
77
|
+
isRunningSetter = 0b00010,
|
|
78
|
+
isBeingObserved = 0b00100,
|
|
79
|
+
isPendingUnobservation = 0b01000,
|
|
80
|
+
diffValue = 0b10000
|
|
81
|
+
}
|
|
82
|
+
|
|
80
83
|
export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDerivation {
|
|
81
84
|
dependenciesState_ = IDerivationState_.NOT_TRACKING_
|
|
82
85
|
observing_: IObservable[] = [] // nodes we are looking at. Our value depends on these nodes
|
|
@@ -90,16 +93,10 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
|
|
|
90
93
|
name_: string
|
|
91
94
|
triggeredBy_?: string
|
|
92
95
|
|
|
93
|
-
private static readonly isComputingMask_ = 0b00001
|
|
94
|
-
private static readonly isRunningSetterMask_ = 0b00010
|
|
95
|
-
private static readonly isBeingObservedMask_ = 0b00100
|
|
96
|
-
private static readonly isPendingUnobservationMask_ = 0b01000
|
|
97
|
-
private static readonly diffValueMask_ = 0b10000
|
|
98
96
|
private flags_ = 0b00000
|
|
99
97
|
|
|
100
98
|
derivation: () => T // N.B: unminified as it is used by MST
|
|
101
99
|
setter_?: (value: T) => void
|
|
102
|
-
isTracing_: TraceMode = TraceMode.NONE
|
|
103
100
|
scope_: Object | undefined
|
|
104
101
|
private equals_: IEqualsComparer<any>
|
|
105
102
|
private requiresReaction_: boolean | undefined
|
|
@@ -110,11 +107,9 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
|
|
|
110
107
|
*
|
|
111
108
|
* The `name` property is for debug purposes only.
|
|
112
109
|
*
|
|
113
|
-
* The `equals` property specifies the comparer function
|
|
114
|
-
* value differs from the previous value.
|
|
115
|
-
*
|
|
116
|
-
* Structural comparison can be convenient if you always produce a new aggregated object and
|
|
117
|
-
* don't want to notify observers if it is structurally the same.
|
|
110
|
+
* The `equals` property specifies the comparer function used to determine if a newly produced
|
|
111
|
+
* value differs from the previous value. Structural comparison can be convenient if you always
|
|
112
|
+
* produce a new aggregated object and don't want to notify observers if it is structurally the same.
|
|
118
113
|
* This is useful for working with vectors, mouse coordinates etc.
|
|
119
114
|
*/
|
|
120
115
|
constructor(options: IComputedValueOptions<T>) {
|
|
@@ -129,11 +124,7 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
|
|
|
129
124
|
options.set
|
|
130
125
|
) as any
|
|
131
126
|
}
|
|
132
|
-
this.equals_ =
|
|
133
|
-
options.equals ||
|
|
134
|
-
((options as any).compareStructural || (options as any).struct
|
|
135
|
-
? comparer.structural
|
|
136
|
-
: comparer.default)
|
|
127
|
+
this.equals_ = options.equals || compareDefault
|
|
137
128
|
this.scope_ = options.context
|
|
138
129
|
this.requiresReaction_ = options.requiresReaction
|
|
139
130
|
this.keepAlive_ = !!options.keepAlive
|
|
@@ -160,40 +151,40 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
|
|
|
160
151
|
|
|
161
152
|
// to check for cycles
|
|
162
153
|
private get isComputing(): boolean {
|
|
163
|
-
return getFlag(this.flags_,
|
|
154
|
+
return getFlag(this.flags_, ComputedValueFlags.isComputing)
|
|
164
155
|
}
|
|
165
156
|
private set isComputing(newValue: boolean) {
|
|
166
|
-
this.flags_ = setFlag(this.flags_,
|
|
157
|
+
this.flags_ = setFlag(this.flags_, ComputedValueFlags.isComputing, newValue)
|
|
167
158
|
}
|
|
168
159
|
|
|
169
160
|
private get isRunningSetter(): boolean {
|
|
170
|
-
return getFlag(this.flags_,
|
|
161
|
+
return getFlag(this.flags_, ComputedValueFlags.isRunningSetter)
|
|
171
162
|
}
|
|
172
163
|
private set isRunningSetter(newValue: boolean) {
|
|
173
|
-
this.flags_ = setFlag(this.flags_,
|
|
164
|
+
this.flags_ = setFlag(this.flags_, ComputedValueFlags.isRunningSetter, newValue)
|
|
174
165
|
}
|
|
175
166
|
|
|
176
167
|
get isBeingObserved(): boolean {
|
|
177
|
-
return getFlag(this.flags_,
|
|
168
|
+
return getFlag(this.flags_, ComputedValueFlags.isBeingObserved)
|
|
178
169
|
}
|
|
179
170
|
set isBeingObserved(newValue: boolean) {
|
|
180
|
-
this.flags_ = setFlag(this.flags_,
|
|
171
|
+
this.flags_ = setFlag(this.flags_, ComputedValueFlags.isBeingObserved, newValue)
|
|
181
172
|
}
|
|
182
173
|
|
|
183
174
|
get isPendingUnobservation(): boolean {
|
|
184
|
-
return getFlag(this.flags_,
|
|
175
|
+
return getFlag(this.flags_, ComputedValueFlags.isPendingUnobservation)
|
|
185
176
|
}
|
|
186
177
|
set isPendingUnobservation(newValue: boolean) {
|
|
187
|
-
this.flags_ = setFlag(this.flags_,
|
|
178
|
+
this.flags_ = setFlag(this.flags_, ComputedValueFlags.isPendingUnobservation, newValue)
|
|
188
179
|
}
|
|
189
180
|
|
|
190
181
|
get diffValue(): 0 | 1 {
|
|
191
|
-
return getFlag(this.flags_,
|
|
182
|
+
return getFlag(this.flags_, ComputedValueFlags.diffValue) ? 1 : 0
|
|
192
183
|
}
|
|
193
184
|
set diffValue(newValue: 0 | 1) {
|
|
194
185
|
this.flags_ = setFlag(
|
|
195
186
|
this.flags_,
|
|
196
|
-
|
|
187
|
+
ComputedValueFlags.diffValue,
|
|
197
188
|
newValue === 1 ? true : false
|
|
198
189
|
)
|
|
199
190
|
}
|
|
@@ -289,7 +280,7 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
|
|
|
289
280
|
computeValue_(track: boolean) {
|
|
290
281
|
this.isComputing = true
|
|
291
282
|
// don't allow state changes during computation
|
|
292
|
-
const prev = allowStateChangesStart(false)
|
|
283
|
+
const prev = __DEV__ ? allowStateChangesStart(false) : false
|
|
293
284
|
let res: T | CaughtException
|
|
294
285
|
if (track) {
|
|
295
286
|
res = trackDerivedFunction(this, this.derivation, this.scope_)
|
|
@@ -304,7 +295,9 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
|
|
|
304
295
|
}
|
|
305
296
|
}
|
|
306
297
|
}
|
|
307
|
-
|
|
298
|
+
if (__DEV__) {
|
|
299
|
+
allowStateChangesEnd(prev)
|
|
300
|
+
}
|
|
308
301
|
this.isComputing = false
|
|
309
302
|
return res
|
|
310
303
|
}
|
|
@@ -313,46 +306,13 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
|
|
|
313
306
|
if (!this.keepAlive_) {
|
|
314
307
|
clearObserving(this)
|
|
315
308
|
this.value_ = undefined // don't hold on to computed value!
|
|
316
|
-
if (__DEV__ && this.isTracing_ !== TraceMode.NONE) {
|
|
317
|
-
console.log(
|
|
318
|
-
`[mobx.trace] Computed value '${this.name_}' was suspended and it will recompute on the next access.`
|
|
319
|
-
)
|
|
320
|
-
}
|
|
321
309
|
}
|
|
322
310
|
}
|
|
323
311
|
|
|
324
|
-
observe_(listener: (change: IComputedDidChange<T>) => void, fireImmediately?: boolean): Lambda {
|
|
325
|
-
let firstTime = true
|
|
326
|
-
let prevValue: T | undefined = undefined
|
|
327
|
-
return autorun(() => {
|
|
328
|
-
// TODO: why is this in a different place than the spyReport() function? in all other observables it's called in the same place
|
|
329
|
-
let newValue = this.get()
|
|
330
|
-
if (!firstTime || fireImmediately) {
|
|
331
|
-
const prevU = untrackedStart()
|
|
332
|
-
listener({
|
|
333
|
-
observableKind: "computed",
|
|
334
|
-
debugObjectName: this.name_,
|
|
335
|
-
type: UPDATE,
|
|
336
|
-
object: this,
|
|
337
|
-
newValue,
|
|
338
|
-
oldValue: prevValue
|
|
339
|
-
})
|
|
340
|
-
untrackedEnd(prevU)
|
|
341
|
-
}
|
|
342
|
-
firstTime = false
|
|
343
|
-
prevValue = newValue
|
|
344
|
-
})
|
|
345
|
-
}
|
|
346
|
-
|
|
347
312
|
warnAboutUntrackedRead_() {
|
|
348
313
|
if (!__DEV__) {
|
|
349
314
|
return
|
|
350
315
|
}
|
|
351
|
-
if (this.isTracing_ !== TraceMode.NONE) {
|
|
352
|
-
console.log(
|
|
353
|
-
`[mobx.trace] Computed value '${this.name_}' is being read outside a reactive context. Doing a full recompute.`
|
|
354
|
-
)
|
|
355
|
-
}
|
|
356
316
|
if (
|
|
357
317
|
typeof this.requiresReaction_ === "boolean"
|
|
358
318
|
? this.requiresReaction_
|
package/src/core/derivation.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
removeObserver
|
|
9
9
|
} from "../internal"
|
|
10
10
|
|
|
11
|
-
export enum IDerivationState_ {
|
|
11
|
+
export const enum IDerivationState_ {
|
|
12
12
|
// before being run or (outside batch and not being observed)
|
|
13
13
|
// at this point derivation is not holding any data about dependency tree
|
|
14
14
|
NOT_TRACKING_ = -1,
|
|
@@ -28,12 +28,6 @@ export enum IDerivationState_ {
|
|
|
28
28
|
STALE_ = 2
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export enum TraceMode {
|
|
32
|
-
NONE,
|
|
33
|
-
LOG,
|
|
34
|
-
BREAK
|
|
35
|
-
}
|
|
36
|
-
|
|
37
31
|
/**
|
|
38
32
|
* A derivation is everything that can be derived from the state (all the atoms) in a pure manner.
|
|
39
33
|
* See https://medium.com/@mweststrate/becoming-fully-reactive-an-in-depth-explanation-of-mobservable-55995262a254#.xvbh6qd74
|
|
@@ -52,7 +46,6 @@ export interface IDerivation extends IDepTreeNode {
|
|
|
52
46
|
*/
|
|
53
47
|
unboundDepsCount_: number
|
|
54
48
|
onBecomeStale_(): void
|
|
55
|
-
isTracing_: TraceMode
|
|
56
49
|
|
|
57
50
|
/**
|
|
58
51
|
* warn if the derivation has no dependencies after creation/update
|
|
@@ -90,7 +83,7 @@ export function shouldCompute(derivation: IDerivation): boolean {
|
|
|
90
83
|
return true
|
|
91
84
|
case IDerivationState_.POSSIBLY_STALE_: {
|
|
92
85
|
// state propagation can occur outside of action/reactive context #2195
|
|
93
|
-
const prevAllowStateReads = allowStateReadsStart(true)
|
|
86
|
+
const prevAllowStateReads = __DEV__ ? allowStateReadsStart(true) : true
|
|
94
87
|
const prevUntracked = untrackedStart() // no need for those computeds to be reported, they will be picked up in trackDerivedFunction.
|
|
95
88
|
const obs = derivation.observing_,
|
|
96
89
|
l = obs.length
|
|
@@ -105,7 +98,9 @@ export function shouldCompute(derivation: IDerivation): boolean {
|
|
|
105
98
|
} catch (e) {
|
|
106
99
|
// we are not interested in the value *or* exception at this moment, but if there is one, notify all
|
|
107
100
|
untrackedEnd(prevUntracked)
|
|
108
|
-
|
|
101
|
+
if (__DEV__) {
|
|
102
|
+
allowStateReadsEnd(prevAllowStateReads)
|
|
103
|
+
}
|
|
109
104
|
return true
|
|
110
105
|
}
|
|
111
106
|
}
|
|
@@ -114,14 +109,18 @@ export function shouldCompute(derivation: IDerivation): boolean {
|
|
|
114
109
|
// invariantShouldCompute(derivation)
|
|
115
110
|
if ((derivation.dependenciesState_ as any) === IDerivationState_.STALE_) {
|
|
116
111
|
untrackedEnd(prevUntracked)
|
|
117
|
-
|
|
112
|
+
if (__DEV__) {
|
|
113
|
+
allowStateReadsEnd(prevAllowStateReads)
|
|
114
|
+
}
|
|
118
115
|
return true
|
|
119
116
|
}
|
|
120
117
|
}
|
|
121
118
|
}
|
|
122
119
|
changeDependenciesStateTo0(derivation)
|
|
123
120
|
untrackedEnd(prevUntracked)
|
|
124
|
-
|
|
121
|
+
if (__DEV__) {
|
|
122
|
+
allowStateReadsEnd(prevAllowStateReads)
|
|
123
|
+
}
|
|
125
124
|
return false
|
|
126
125
|
}
|
|
127
126
|
}
|
|
@@ -165,7 +164,7 @@ export function checkIfStateReadsAreAllowed(observable: IObservable) {
|
|
|
165
164
|
* as observer of any of the accessed observables.
|
|
166
165
|
*/
|
|
167
166
|
export function trackDerivedFunction<T>(derivation: IDerivation, f: () => T, context: any) {
|
|
168
|
-
const prevAllowStateReads = allowStateReadsStart(true)
|
|
167
|
+
const prevAllowStateReads = __DEV__ ? allowStateReadsStart(true) : true
|
|
169
168
|
changeDependenciesStateTo0(derivation)
|
|
170
169
|
// Preallocate array; will be trimmed by bindDependencies.
|
|
171
170
|
derivation.newObserving_ = new Array(
|
|
@@ -193,7 +192,9 @@ export function trackDerivedFunction<T>(derivation: IDerivation, f: () => T, con
|
|
|
193
192
|
bindDependencies(derivation)
|
|
194
193
|
|
|
195
194
|
warnAboutDerivationWithoutDependencies(derivation)
|
|
196
|
-
|
|
195
|
+
if (__DEV__) {
|
|
196
|
+
allowStateReadsEnd(prevAllowStateReads)
|
|
197
|
+
}
|
|
197
198
|
return result
|
|
198
199
|
}
|
|
199
200
|
|
package/src/core/globalstate.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { IDerivation, IObservable, Reaction, die
|
|
1
|
+
import { IDerivation, IObservable, Reaction, die } from "../internal"
|
|
2
2
|
import { ComputedValue } from "./computedvalue"
|
|
3
3
|
|
|
4
|
+
const MOBX_GLOBALS_VERSION = 7
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
* These values will persist if global state is reset
|
|
6
8
|
*/
|
|
@@ -14,8 +16,7 @@ const persistentKeys: (keyof MobXGlobals)[] = [
|
|
|
14
16
|
"allowStateReads",
|
|
15
17
|
"disableErrorBoundaries",
|
|
16
18
|
"runId",
|
|
17
|
-
"UNCHANGED"
|
|
18
|
-
"useProxies"
|
|
19
|
+
"UNCHANGED"
|
|
19
20
|
]
|
|
20
21
|
|
|
21
22
|
export type IUNCHANGED = {}
|
|
@@ -29,7 +30,7 @@ export class MobXGlobals {
|
|
|
29
30
|
* N.B: this version is unrelated to the package version of MobX, and is only the version of the
|
|
30
31
|
* internal state storage of MobX, and can be the same across many different package versions
|
|
31
32
|
*/
|
|
32
|
-
version =
|
|
33
|
+
version = MOBX_GLOBALS_VERSION
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* globally unique token to signal unchanged
|
|
@@ -138,12 +139,6 @@ export class MobXGlobals {
|
|
|
138
139
|
*/
|
|
139
140
|
suppressReactionErrors = false
|
|
140
141
|
|
|
141
|
-
useProxies = true
|
|
142
|
-
/*
|
|
143
|
-
* print warnings about code that would fail if proxies weren't available
|
|
144
|
-
*/
|
|
145
|
-
verifyProxies = false
|
|
146
|
-
|
|
147
142
|
/**
|
|
148
143
|
* False forces all object's descriptors to
|
|
149
144
|
* writable: true
|
|
@@ -156,11 +151,11 @@ let canMergeGlobalState = true
|
|
|
156
151
|
let isolateCalled = false
|
|
157
152
|
|
|
158
153
|
export let globalState: MobXGlobals = (function () {
|
|
159
|
-
let global =
|
|
154
|
+
let global = globalThis as any
|
|
160
155
|
if (global.__mobxInstanceCount > 0 && !global.__mobxGlobals) {
|
|
161
156
|
canMergeGlobalState = false
|
|
162
157
|
}
|
|
163
|
-
if (global.__mobxGlobals && global.__mobxGlobals.version !==
|
|
158
|
+
if (global.__mobxGlobals && global.__mobxGlobals.version !== MOBX_GLOBALS_VERSION) {
|
|
164
159
|
canMergeGlobalState = false
|
|
165
160
|
}
|
|
166
161
|
|
|
@@ -195,7 +190,7 @@ export function isolateGlobalState() {
|
|
|
195
190
|
}
|
|
196
191
|
isolateCalled = true
|
|
197
192
|
if (canMergeGlobalState) {
|
|
198
|
-
let global =
|
|
193
|
+
let global = globalThis as any
|
|
199
194
|
if (--global.__mobxInstanceCount === 0) {
|
|
200
195
|
global.__mobxGlobals = undefined
|
|
201
196
|
}
|
package/src/core/observable.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Lambda,
|
|
3
3
|
ComputedValue,
|
|
4
|
-
IDependencyTree,
|
|
5
4
|
IDerivation,
|
|
6
5
|
IDerivationState_,
|
|
7
|
-
TraceMode,
|
|
8
|
-
getDependencyTree,
|
|
9
6
|
globalState,
|
|
10
7
|
runReactions,
|
|
11
8
|
checkIfStateReadsAreAllowed
|
|
@@ -192,9 +189,6 @@ export function propagateChanged(observable: IObservable) {
|
|
|
192
189
|
// Ideally we use for..of here, but the downcompiled version is really slow...
|
|
193
190
|
observable.observers_.forEach(d => {
|
|
194
191
|
if (d.dependenciesState_ === IDerivationState_.UP_TO_DATE_) {
|
|
195
|
-
if (__DEV__ && d.isTracing_ !== TraceMode.NONE) {
|
|
196
|
-
logTraceInfo(d, observable)
|
|
197
|
-
}
|
|
198
192
|
d.onBecomeStale_()
|
|
199
193
|
}
|
|
200
194
|
d.dependenciesState_ = IDerivationState_.STALE_
|
|
@@ -213,9 +207,6 @@ export function propagateChangeConfirmed(observable: IObservable) {
|
|
|
213
207
|
observable.observers_.forEach(d => {
|
|
214
208
|
if (d.dependenciesState_ === IDerivationState_.POSSIBLY_STALE_) {
|
|
215
209
|
d.dependenciesState_ = IDerivationState_.STALE_
|
|
216
|
-
if (__DEV__ && d.isTracing_ !== TraceMode.NONE) {
|
|
217
|
-
logTraceInfo(d, observable)
|
|
218
|
-
}
|
|
219
210
|
} else if (
|
|
220
211
|
d.dependenciesState_ === IDerivationState_.UP_TO_DATE_ // this happens during computing of `d`, just keep lowestObserverState up to date.
|
|
221
212
|
) {
|
|
@@ -241,42 +232,3 @@ export function propagateMaybeChanged(observable: IObservable) {
|
|
|
241
232
|
})
|
|
242
233
|
// invariantLOS(observable, "maybe end");
|
|
243
234
|
}
|
|
244
|
-
|
|
245
|
-
function logTraceInfo(derivation: IDerivation, observable: IObservable) {
|
|
246
|
-
console.log(
|
|
247
|
-
`[mobx.trace] '${derivation.name_}' is invalidated due to a change in: '${observable.name_}'`
|
|
248
|
-
)
|
|
249
|
-
if (derivation.isTracing_ === TraceMode.BREAK) {
|
|
250
|
-
const lines = []
|
|
251
|
-
printDepTree(getDependencyTree(derivation), lines, 1)
|
|
252
|
-
|
|
253
|
-
// prettier-ignore
|
|
254
|
-
new Function(
|
|
255
|
-
`debugger;
|
|
256
|
-
/*
|
|
257
|
-
Tracing '${derivation.name_}'
|
|
258
|
-
|
|
259
|
-
You are entering this break point because derivation '${derivation.name_}' is being traced and '${observable.name_}' is now forcing it to update.
|
|
260
|
-
Just follow the stacktrace you should now see in the devtools to see precisely what piece of your code is causing this update
|
|
261
|
-
The stackframe you are looking for is at least ~6-8 stack-frames up.
|
|
262
|
-
|
|
263
|
-
${derivation instanceof ComputedValue ? derivation.derivation.toString().replace(/[*]\//g, "/") : ""}
|
|
264
|
-
|
|
265
|
-
The dependencies for this derivation are:
|
|
266
|
-
|
|
267
|
-
${lines.join("\n")}
|
|
268
|
-
*/
|
|
269
|
-
`)()
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
function printDepTree(tree: IDependencyTree, lines: string[], depth: number) {
|
|
274
|
-
if (lines.length >= 1000) {
|
|
275
|
-
lines.push("(and many more)")
|
|
276
|
-
return
|
|
277
|
-
}
|
|
278
|
-
lines.push(`${"\t".repeat(depth - 1)}${tree.name}`)
|
|
279
|
-
if (tree.dependencies) {
|
|
280
|
-
tree.dependencies.forEach(child => printDepTree(child, lines, depth + 1))
|
|
281
|
-
}
|
|
282
|
-
}
|
package/src/core/reaction.ts
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
IDerivationState_,
|
|
5
5
|
IObservable,
|
|
6
6
|
Lambda,
|
|
7
|
-
TraceMode,
|
|
8
7
|
clearObserving,
|
|
9
8
|
createInstanceofPredicate,
|
|
10
9
|
endBatch,
|
|
@@ -17,7 +16,6 @@ import {
|
|
|
17
16
|
spyReportEnd,
|
|
18
17
|
spyReportStart,
|
|
19
18
|
startBatch,
|
|
20
|
-
trace,
|
|
21
19
|
trackDerivedFunction,
|
|
22
20
|
GenericAbortSignal
|
|
23
21
|
} from "../internal"
|
|
@@ -45,7 +43,6 @@ import { getFlag, setFlag } from "../utils/utils"
|
|
|
45
43
|
|
|
46
44
|
export interface IReactionPublic {
|
|
47
45
|
dispose(): void
|
|
48
|
-
trace(enterBreakPoint?: boolean): void
|
|
49
46
|
}
|
|
50
47
|
|
|
51
48
|
export interface IReactionDisposer {
|
|
@@ -53,6 +50,14 @@ export interface IReactionDisposer {
|
|
|
53
50
|
[$mobx]: Reaction
|
|
54
51
|
}
|
|
55
52
|
|
|
53
|
+
const enum ReactionFlags {
|
|
54
|
+
isDisposed = 0b00001,
|
|
55
|
+
isScheduled = 0b00010,
|
|
56
|
+
isTrackPending = 0b00100,
|
|
57
|
+
isRunning = 0b01000,
|
|
58
|
+
diffValue = 0b10000
|
|
59
|
+
}
|
|
60
|
+
|
|
56
61
|
export class Reaction implements IDerivation, IReactionPublic {
|
|
57
62
|
observing_: IObservable[] = [] // nodes we are looking at. Our value depends on these nodes
|
|
58
63
|
newObserving_: IObservable[] = []
|
|
@@ -60,15 +65,8 @@ export class Reaction implements IDerivation, IReactionPublic {
|
|
|
60
65
|
runId_ = 0
|
|
61
66
|
unboundDepsCount_ = 0
|
|
62
67
|
|
|
63
|
-
private static readonly isDisposedMask_ = 0b00001
|
|
64
|
-
private static readonly isScheduledMask_ = 0b00010
|
|
65
|
-
private static readonly isTrackPendingMask_ = 0b00100
|
|
66
|
-
private static readonly isRunningMask_ = 0b01000
|
|
67
|
-
private static readonly diffValueMask_ = 0b10000
|
|
68
68
|
private flags_ = 0b00000
|
|
69
69
|
|
|
70
|
-
isTracing_: TraceMode = TraceMode.NONE
|
|
71
|
-
|
|
72
70
|
constructor(
|
|
73
71
|
public name_: string = __DEV__ ? "Reaction@" + getNextId() : "Reaction",
|
|
74
72
|
private onInvalidate_: () => void,
|
|
@@ -77,38 +75,38 @@ export class Reaction implements IDerivation, IReactionPublic {
|
|
|
77
75
|
) {}
|
|
78
76
|
|
|
79
77
|
get isDisposed() {
|
|
80
|
-
return getFlag(this.flags_,
|
|
78
|
+
return getFlag(this.flags_, ReactionFlags.isDisposed)
|
|
81
79
|
}
|
|
82
80
|
set isDisposed(newValue: boolean) {
|
|
83
|
-
this.flags_ = setFlag(this.flags_,
|
|
81
|
+
this.flags_ = setFlag(this.flags_, ReactionFlags.isDisposed, newValue)
|
|
84
82
|
}
|
|
85
83
|
|
|
86
84
|
get isScheduled() {
|
|
87
|
-
return getFlag(this.flags_,
|
|
85
|
+
return getFlag(this.flags_, ReactionFlags.isScheduled)
|
|
88
86
|
}
|
|
89
87
|
set isScheduled(newValue: boolean) {
|
|
90
|
-
this.flags_ = setFlag(this.flags_,
|
|
88
|
+
this.flags_ = setFlag(this.flags_, ReactionFlags.isScheduled, newValue)
|
|
91
89
|
}
|
|
92
90
|
|
|
93
91
|
get isTrackPending() {
|
|
94
|
-
return getFlag(this.flags_,
|
|
92
|
+
return getFlag(this.flags_, ReactionFlags.isTrackPending)
|
|
95
93
|
}
|
|
96
94
|
set isTrackPending(newValue: boolean) {
|
|
97
|
-
this.flags_ = setFlag(this.flags_,
|
|
95
|
+
this.flags_ = setFlag(this.flags_, ReactionFlags.isTrackPending, newValue)
|
|
98
96
|
}
|
|
99
97
|
|
|
100
98
|
get isRunning() {
|
|
101
|
-
return getFlag(this.flags_,
|
|
99
|
+
return getFlag(this.flags_, ReactionFlags.isRunning)
|
|
102
100
|
}
|
|
103
101
|
set isRunning(newValue: boolean) {
|
|
104
|
-
this.flags_ = setFlag(this.flags_,
|
|
102
|
+
this.flags_ = setFlag(this.flags_, ReactionFlags.isRunning, newValue)
|
|
105
103
|
}
|
|
106
104
|
|
|
107
105
|
get diffValue(): 0 | 1 {
|
|
108
|
-
return getFlag(this.flags_,
|
|
106
|
+
return getFlag(this.flags_, ReactionFlags.diffValue) ? 1 : 0
|
|
109
107
|
}
|
|
110
108
|
set diffValue(newValue: 0 | 1) {
|
|
111
|
-
this.flags_ = setFlag(this.flags_,
|
|
109
|
+
this.flags_ = setFlag(this.flags_, ReactionFlags.diffValue, newValue === 1 ? true : false)
|
|
112
110
|
}
|
|
113
111
|
|
|
114
112
|
onBecomeStale_() {
|
|
@@ -159,7 +157,7 @@ export class Reaction implements IDerivation, IReactionPublic {
|
|
|
159
157
|
// console.warn("Reaction already disposed") // Note: Not a warning / error in mobx 4 either
|
|
160
158
|
}
|
|
161
159
|
startBatch()
|
|
162
|
-
const notify = isSpyEnabled()
|
|
160
|
+
const notify = __DEV__ && isSpyEnabled()
|
|
163
161
|
let startTime
|
|
164
162
|
if (__DEV__ && notify) {
|
|
165
163
|
startTime = Date.now()
|
|
@@ -250,10 +248,6 @@ export class Reaction implements IDerivation, IReactionPublic {
|
|
|
250
248
|
toString() {
|
|
251
249
|
return `Reaction[${this.name_}]`
|
|
252
250
|
}
|
|
253
|
-
|
|
254
|
-
trace(enterBreakPoint: boolean = false) {
|
|
255
|
-
trace(this, enterBreakPoint)
|
|
256
|
-
}
|
|
257
251
|
}
|
|
258
252
|
|
|
259
253
|
export function onReactionError(handler: (error: any, derivation: IDerivation) => void): Lambda {
|
package/src/core/spy.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { IComputedDidChange } from "./computedvalue"
|
|
|
2
2
|
import { IValueDidChange, IBoxDidChange } from "./../types/observablevalue"
|
|
3
3
|
import { IObjectDidChange } from "./../types/observableobject"
|
|
4
4
|
import { IArrayDidChange } from "./../types/observablearray"
|
|
5
|
-
import { Lambda, globalState, once, ISetDidChange, IMapDidChange } from "../internal"
|
|
5
|
+
import { Lambda, globalState, once, ISetDidChange, IMapDidChange, assign } from "../internal"
|
|
6
6
|
|
|
7
7
|
export function isSpyEnabled() {
|
|
8
8
|
return __DEV__ && !!globalState.spyListeners.length
|
|
@@ -41,7 +41,7 @@ export function spyReportStart(event: PureSpyEvent) {
|
|
|
41
41
|
if (!__DEV__) {
|
|
42
42
|
return
|
|
43
43
|
}
|
|
44
|
-
const change = {
|
|
44
|
+
const change = assign({}, event, { spyReportStart: true as const })
|
|
45
45
|
spyReport(change)
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -52,7 +52,7 @@ export function spyReportEnd(change?: { time?: number }) {
|
|
|
52
52
|
return
|
|
53
53
|
}
|
|
54
54
|
if (change) {
|
|
55
|
-
spyReport({
|
|
55
|
+
spyReport(assign({}, change, { type: "report-end" as const, spyReportEnd: true as const }))
|
|
56
56
|
} else {
|
|
57
57
|
spyReport(END_EVENT)
|
|
58
58
|
}
|
package/src/errors.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const niceErrors = {
|
|
1
|
+
export const niceErrors = {
|
|
2
2
|
0: `Invalid value for configuration 'enforceActions', expected 'never', 'always' or 'observed'`,
|
|
3
3
|
1(annotationType, key: PropertyKey) {
|
|
4
4
|
return `Cannot apply '${annotationType}' to '${key.toString()}': Field not found.`
|
|
@@ -26,10 +26,6 @@ const niceErrors = {
|
|
|
26
26
|
14: "Intercept handlers should return nothing or a change object",
|
|
27
27
|
15: `Observable arrays cannot be frozen. If you're passing observables to 3rd party component/function that calls Object.freeze, pass copy instead: toJS(observable)`,
|
|
28
28
|
16: `Modification exception: the internal structure of an observable array was changed.`,
|
|
29
|
-
17(index, length) {
|
|
30
|
-
return `[mobx.array] Index out of bounds, ${index} is larger than ${length}`
|
|
31
|
-
},
|
|
32
|
-
18: "mobx.map requires Map polyfill for the current browser. Check babel-polyfill or core-js/es6/map.js",
|
|
33
29
|
19(other) {
|
|
34
30
|
return "Cannot initialize from classes that inherit from Map: " + other.constructor.name
|
|
35
31
|
},
|
|
@@ -39,7 +35,6 @@ const niceErrors = {
|
|
|
39
35
|
21(dataStructure) {
|
|
40
36
|
return `Cannot convert to map from '${dataStructure}'`
|
|
41
37
|
},
|
|
42
|
-
22: "mobx.set requires Set polyfill for the current browser. Check babel-polyfill or core-js/es6/set.js",
|
|
43
38
|
23: "It is not possible to get index atoms from arrays",
|
|
44
39
|
24(thing) {
|
|
45
40
|
return "Cannot obtain administration from " + thing
|
|
@@ -72,7 +67,25 @@ const niceErrors = {
|
|
|
72
67
|
return `[mobx] \`observableArray.${method}()\` mutates the array in-place, which is not allowed inside a derivation. Use \`array.slice().${method}()\` instead`
|
|
73
68
|
},
|
|
74
69
|
38: "'ownKeys()' can only be used on observable objects",
|
|
75
|
-
39: "'defineProperty()' can only be used on observable objects"
|
|
70
|
+
39: "'defineProperty()' can only be used on observable objects",
|
|
71
|
+
40(length) {
|
|
72
|
+
return "Out of range: " + length
|
|
73
|
+
},
|
|
74
|
+
41(other) {
|
|
75
|
+
return "Cannot initialize set from " + other
|
|
76
|
+
},
|
|
77
|
+
42(key) {
|
|
78
|
+
return `Invalid index: '${key}'`
|
|
79
|
+
},
|
|
80
|
+
43(annotationType, name, kind) {
|
|
81
|
+
return (
|
|
82
|
+
`Cannot apply '${annotationType}' to '${name}' (kind: ${kind}):` +
|
|
83
|
+
`\n'${annotationType}' can only be used on properties with a function value.`
|
|
84
|
+
)
|
|
85
|
+
},
|
|
86
|
+
44(annotationType) {
|
|
87
|
+
return `'${annotationType}' can only be used with 'makeObservable'`
|
|
88
|
+
}
|
|
76
89
|
} as const
|
|
77
90
|
|
|
78
91
|
const errors: typeof niceErrors = __DEV__ ? niceErrors : ({} as any)
|
|
@@ -84,10 +97,8 @@ export function die(error: string | keyof typeof errors, ...args: any[]): never
|
|
|
84
97
|
throw new Error(`[MobX] ${e}`)
|
|
85
98
|
}
|
|
86
99
|
throw new Error(
|
|
87
|
-
|
|
88
|
-
?
|
|
89
|
-
|
|
90
|
-
}. Find the full error at: https://github.com/mobxjs/mobx/blob/main/packages/mobx/src/errors.ts`
|
|
91
|
-
: `[MobX] ${error}`
|
|
100
|
+
`[MobX] minified error nr: ${error}${
|
|
101
|
+
args.length ? " " + args.map(String).join(",") : ""
|
|
102
|
+
}. See mobx.js.org/errors`
|
|
92
103
|
)
|
|
93
104
|
}
|
package/src/internal.ts
CHANGED
|
@@ -5,8 +5,7 @@ it will cause undefined errors (for example because super classes or local varia
|
|
|
5
5
|
With this file that will still happen,
|
|
6
6
|
but at least in this file we can magically reorder the imports with trial and error until the build succeeds again.
|
|
7
7
|
*/
|
|
8
|
-
export
|
|
9
|
-
export * from "./errors"
|
|
8
|
+
export { die } from "./errors"
|
|
10
9
|
export * from "./utils/utils"
|
|
11
10
|
export * from "./api/decorators"
|
|
12
11
|
export * from "./core/atom"
|
|
@@ -43,7 +42,6 @@ export * from "./api/isobservable"
|
|
|
43
42
|
export * from "./api/object-api"
|
|
44
43
|
export * from "./api/observe"
|
|
45
44
|
export * from "./api/tojs"
|
|
46
|
-
export * from "./api/trace"
|
|
47
45
|
export * from "./api/transaction"
|
|
48
46
|
export * from "./api/when"
|
|
49
47
|
export * from "./types/dynamicobject"
|
|
@@ -54,7 +52,6 @@ export * from "./types/observablearray"
|
|
|
54
52
|
export * from "./types/observablemap"
|
|
55
53
|
export * from "./types/observableset"
|
|
56
54
|
export * from "./types/observableobject"
|
|
57
|
-
export * from "./types/legacyobservablearray"
|
|
58
55
|
export * from "./types/type-utils"
|
|
59
56
|
export * from "./utils/eq"
|
|
60
57
|
export * from "./utils/iterable"
|