mobx 6.13.0 → 6.13.1

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.
@@ -44,3 +44,5 @@ export declare function hasProp(target: Object, prop: PropertyKey): boolean;
44
44
  export declare const getOwnPropertyDescriptors: <T>(o: T) => { [P in keyof T]: TypedPropertyDescriptor<T[P]>; } & {
45
45
  [x: string]: PropertyDescriptor;
46
46
  };
47
+ export declare function getFlag(flags: number, mask: number): boolean;
48
+ export declare function setFlag(flags: number, mask: number, newValue: boolean): number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobx",
3
- "version": "6.13.0",
3
+ "version": "6.13.1",
4
4
  "description": "Simple, scalable state management.",
5
5
  "source": "src/mobx.ts",
6
6
  "main": "dist/index.js",
@@ -75,7 +75,7 @@ export function autorun(
75
75
  isScheduled = true
76
76
  scheduler(() => {
77
77
  isScheduled = false
78
- if (!reaction.isDisposed_) {
78
+ if (!reaction.isDisposed) {
79
79
  reaction.track(reactionRunner)
80
80
  }
81
81
  })
@@ -90,7 +90,7 @@ export function autorun(
90
90
  view(reaction)
91
91
  }
92
92
 
93
- if(!opts?.signal?.aborted) {
93
+ if (!opts?.signal?.aborted) {
94
94
  reaction.schedule_()
95
95
  }
96
96
  return reaction.getDisposer_(opts?.signal)
@@ -160,7 +160,7 @@ export function reaction<T, FireImmediately extends boolean = false>(
160
160
 
161
161
  function reactionRunner() {
162
162
  isScheduled = false
163
- if (r.isDisposed_) {
163
+ if (r.isDisposed) {
164
164
  return
165
165
  }
166
166
  let changed: boolean = false
@@ -181,7 +181,7 @@ export function reaction<T, FireImmediately extends boolean = false>(
181
181
  firstTime = false
182
182
  }
183
183
 
184
- if(!opts?.signal?.aborted) {
184
+ if (!opts?.signal?.aborted) {
185
185
  r.schedule_()
186
186
  }
187
187
  return r.getDisposer_(opts?.signal)
package/src/api/when.ts CHANGED
@@ -38,7 +38,7 @@ function _when(predicate: () => boolean, effect: Lambda, opts: IWhenOptions): IR
38
38
  if (typeof opts.timeout === "number") {
39
39
  const error = new Error("WHEN_TIMEOUT")
40
40
  timeoutHandle = setTimeout(() => {
41
- if (!disposer[$mobx].isDisposed_) {
41
+ if (!disposer[$mobx].isDisposed) {
42
42
  disposer()
43
43
  if (opts.onError) {
44
44
  opts.onError(error)
package/src/core/atom.ts CHANGED
@@ -14,6 +14,8 @@ import {
14
14
  Lambda
15
15
  } from "../internal"
16
16
 
17
+ import { getFlag, setFlag } from "../utils/utils"
18
+
17
19
  export const $mobx = Symbol("mobx administration")
18
20
 
19
21
  export interface IAtom extends IObservable {
@@ -22,11 +24,13 @@ export interface IAtom extends IObservable {
22
24
  }
23
25
 
24
26
  export class Atom implements IAtom {
25
- isPendingUnobservation = false // for effective unobserving. BaseAtom has true, for extra optimization, so its onBecomeUnobserved never gets called, because it's not needed
26
- isBeingObserved = false
27
+ private static readonly isBeingObservedMask_ = 0b001
28
+ private static readonly isPendingUnobservationMask_ = 0b010
29
+ private static readonly diffValueMask_ = 0b100
30
+ private flags_ = 0b000
31
+
27
32
  observers_ = new Set<IDerivation>()
28
33
 
29
- diffValue_ = 0
30
34
  lastAccessedBy_ = 0
31
35
  lowestObserverState_ = IDerivationState_.NOT_TRACKING_
32
36
  /**
@@ -35,6 +39,28 @@ export class Atom implements IAtom {
35
39
  */
36
40
  constructor(public name_ = __DEV__ ? "Atom@" + getNextId() : "Atom") {}
37
41
 
42
+ // for effective unobserving. BaseAtom has true, for extra optimization, so its onBecomeUnobserved never gets called, because it's not needed
43
+ get isBeingObserved(): boolean {
44
+ return getFlag(this.flags_, Atom.isBeingObservedMask_)
45
+ }
46
+ set isBeingObserved(newValue: boolean) {
47
+ this.flags_ = setFlag(this.flags_, Atom.isBeingObservedMask_, newValue)
48
+ }
49
+
50
+ get isPendingUnobservation(): boolean {
51
+ return getFlag(this.flags_, Atom.isPendingUnobservationMask_)
52
+ }
53
+ set isPendingUnobservation(newValue: boolean) {
54
+ this.flags_ = setFlag(this.flags_, Atom.isPendingUnobservationMask_, newValue)
55
+ }
56
+
57
+ get diffValue(): 0 | 1 {
58
+ return getFlag(this.flags_, Atom.diffValueMask_) ? 1 : 0
59
+ }
60
+ set diffValue(newValue: 0 | 1) {
61
+ this.flags_ = setFlag(this.flags_, Atom.diffValueMask_, newValue === 1 ? true : false)
62
+ }
63
+
38
64
  // onBecomeObservedListeners
39
65
  public onBOL: Set<Lambda> | undefined
40
66
  // onBecomeUnobservedListeners
@@ -32,6 +32,8 @@ import {
32
32
  allowStateChangesEnd
33
33
  } from "../internal"
34
34
 
35
+ import { getFlag, setFlag } from "../utils/utils"
36
+
35
37
  export interface IComputedValue<T> {
36
38
  get(): T
37
39
  set(value: T): void
@@ -56,18 +58,6 @@ export type IComputedDidChange<T = any> = {
56
58
  oldValue: T | undefined
57
59
  }
58
60
 
59
- function getFlag(flags: number, mask: number) {
60
- return !!(flags & mask)
61
- }
62
- function setFlag(flags: number, mask: number, newValue: boolean): number {
63
- if (newValue) {
64
- flags |= mask
65
- } else {
66
- flags &= ~mask
67
- }
68
- return flags
69
- }
70
-
71
61
  /**
72
62
  * A node in the state dependency root that observes other nodes, and can be observed itself.
73
63
  *
@@ -92,7 +82,6 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
92
82
  observing_: IObservable[] = [] // nodes we are looking at. Our value depends on these nodes
93
83
  newObserving_ = null // during tracking it's an array with new observed observers
94
84
  observers_ = new Set<IDerivation>()
95
- diffValue_ = 0
96
85
  runId_ = 0
97
86
  lastAccessedBy_ = 0
98
87
  lowestObserverState_ = IDerivationState_.UP_TO_DATE_
@@ -101,11 +90,12 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
101
90
  name_: string
102
91
  triggeredBy_?: string
103
92
 
104
- private static readonly isComputingMask_ = 0b0001
105
- private static readonly isRunningSetterMask_ = 0b0010
106
- private static readonly isBeingObservedMask_ = 0b0100
107
- private static readonly isPendingUnobservationMask_ = 0b1000
108
- private flags_ = 0b0000
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
+ private flags_ = 0b00000
109
99
 
110
100
  derivation: () => T // N.B: unminified as it is used by MST
111
101
  setter_?: (value: T) => void
@@ -197,6 +187,17 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
197
187
  this.flags_ = setFlag(this.flags_, ComputedValue.isPendingUnobservationMask_, newValue)
198
188
  }
199
189
 
190
+ get diffValue(): 0 | 1 {
191
+ return getFlag(this.flags_, ComputedValue.diffValueMask_) ? 1 : 0
192
+ }
193
+ set diffValue(newValue: 0 | 1) {
194
+ this.flags_ = setFlag(
195
+ this.flags_,
196
+ ComputedValue.diffValueMask_,
197
+ newValue === 1 ? true : false
198
+ )
199
+ }
200
+
200
201
  /**
201
202
  * Returns the current value of this computed value.
202
203
  * Will evaluate its computation first if needed.
@@ -235,8 +235,8 @@ function bindDependencies(derivation: IDerivation) {
235
235
  l = derivation.unboundDepsCount_
236
236
  for (let i = 0; i < l; i++) {
237
237
  const dep = observing[i]
238
- if (dep.diffValue_ === 0) {
239
- dep.diffValue_ = 1
238
+ if (dep.diffValue === 0) {
239
+ dep.diffValue = 1
240
240
  if (i0 !== i) {
241
241
  observing[i0] = dep
242
242
  }
@@ -259,10 +259,10 @@ function bindDependencies(derivation: IDerivation) {
259
259
  l = prevObserving.length
260
260
  while (l--) {
261
261
  const dep = prevObserving[l]
262
- if (dep.diffValue_ === 0) {
262
+ if (dep.diffValue === 0) {
263
263
  removeObserver(dep, derivation)
264
264
  }
265
- dep.diffValue_ = 0
265
+ dep.diffValue = 0
266
266
  }
267
267
 
268
268
  // Go through all new observables and check diffValue: (now it should be unique)
@@ -270,8 +270,8 @@ function bindDependencies(derivation: IDerivation) {
270
270
  // 1: it wasn't observed, let's observe it. set back to 0
271
271
  while (i0--) {
272
272
  const dep = observing[i0]
273
- if (dep.diffValue_ === 1) {
274
- dep.diffValue_ = 0
273
+ if (dep.diffValue === 1) {
274
+ dep.diffValue = 0
275
275
  addObserver(dep, derivation)
276
276
  }
277
277
  }
@@ -17,7 +17,7 @@ export interface IDepTreeNode {
17
17
  }
18
18
 
19
19
  export interface IObservable extends IDepTreeNode {
20
- diffValue_: number
20
+ diffValue: number
21
21
  /**
22
22
  * Id of the derivation *run* that last accessed this observable.
23
23
  * If this id equals the *run* id of the current derivation,
@@ -22,6 +22,8 @@ import {
22
22
  GenericAbortSignal
23
23
  } from "../internal"
24
24
 
25
+ import { getFlag, setFlag } from "../utils/utils"
26
+
25
27
  /**
26
28
  * Reactions are a special kind of derivations. Several things distinguishes them from normal reactive computations
27
29
  *
@@ -55,13 +57,16 @@ export class Reaction implements IDerivation, IReactionPublic {
55
57
  observing_: IObservable[] = [] // nodes we are looking at. Our value depends on these nodes
56
58
  newObserving_: IObservable[] = []
57
59
  dependenciesState_ = IDerivationState_.NOT_TRACKING_
58
- diffValue_ = 0
59
60
  runId_ = 0
60
61
  unboundDepsCount_ = 0
61
- isDisposed_ = false
62
- isScheduled_ = false
63
- isTrackPending_ = false
64
- isRunning_ = false
62
+
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
+ private flags_ = 0b00000
69
+
65
70
  isTracing_: TraceMode = TraceMode.NONE
66
71
 
67
72
  constructor(
@@ -71,37 +76,68 @@ export class Reaction implements IDerivation, IReactionPublic {
71
76
  public requiresObservable_?
72
77
  ) {}
73
78
 
79
+ get isDisposed() {
80
+ return getFlag(this.flags_, Reaction.isDisposedMask_)
81
+ }
82
+ set isDisposed(newValue: boolean) {
83
+ this.flags_ = setFlag(this.flags_, Reaction.isDisposedMask_, newValue)
84
+ }
85
+
86
+ get isScheduled() {
87
+ return getFlag(this.flags_, Reaction.isScheduledMask_)
88
+ }
89
+ set isScheduled(newValue: boolean) {
90
+ this.flags_ = setFlag(this.flags_, Reaction.isScheduledMask_, newValue)
91
+ }
92
+
93
+ get isTrackPending() {
94
+ return getFlag(this.flags_, Reaction.isTrackPendingMask_)
95
+ }
96
+ set isTrackPending(newValue: boolean) {
97
+ this.flags_ = setFlag(this.flags_, Reaction.isTrackPendingMask_, newValue)
98
+ }
99
+
100
+ get isRunning() {
101
+ return getFlag(this.flags_, Reaction.isRunningMask_)
102
+ }
103
+ set isRunning(newValue: boolean) {
104
+ this.flags_ = setFlag(this.flags_, Reaction.isRunningMask_, newValue)
105
+ }
106
+
107
+ get diffValue(): 0 | 1 {
108
+ return getFlag(this.flags_, Reaction.diffValueMask_) ? 1 : 0
109
+ }
110
+ set diffValue(newValue: 0 | 1) {
111
+ this.flags_ = setFlag(this.flags_, Reaction.diffValueMask_, newValue === 1 ? true : false)
112
+ }
113
+
74
114
  onBecomeStale_() {
75
115
  this.schedule_()
76
116
  }
77
117
 
78
118
  schedule_() {
79
- if (!this.isScheduled_) {
80
- this.isScheduled_ = true
119
+ if (!this.isScheduled) {
120
+ this.isScheduled = true
81
121
  globalState.pendingReactions.push(this)
82
122
  runReactions()
83
123
  }
84
124
  }
85
125
 
86
- isScheduled() {
87
- return this.isScheduled_
88
- }
89
-
90
126
  /**
91
127
  * internal, use schedule() if you intend to kick off a reaction
92
128
  */
93
129
  runReaction_() {
94
- if (!this.isDisposed_) {
130
+ if (!this.isDisposed) {
95
131
  startBatch()
96
- this.isScheduled_ = false
132
+ this.isScheduled = false
97
133
  const prev = globalState.trackingContext
98
134
  globalState.trackingContext = this
99
135
  if (shouldCompute(this)) {
100
- this.isTrackPending_ = true
136
+ this.isTrackPending = true
101
137
 
102
138
  try {
103
139
  this.onInvalidate_()
104
- if (__DEV__ && this.isTrackPending_ && isSpyEnabled()) {
140
+ if (__DEV__ && this.isTrackPending && isSpyEnabled()) {
105
141
  // onInvalidate didn't trigger track right away..
106
142
  spyReport({
107
143
  name: this.name_,
@@ -118,7 +154,7 @@ export class Reaction implements IDerivation, IReactionPublic {
118
154
  }
119
155
 
120
156
  track(fn: () => void) {
121
- if (this.isDisposed_) {
157
+ if (this.isDisposed) {
122
158
  return
123
159
  // console.warn("Reaction already disposed") // Note: Not a warning / error in mobx 4 either
124
160
  }
@@ -132,14 +168,14 @@ export class Reaction implements IDerivation, IReactionPublic {
132
168
  type: "reaction"
133
169
  })
134
170
  }
135
- this.isRunning_ = true
171
+ this.isRunning = true
136
172
  const prevReaction = globalState.trackingContext // reactions could create reactions...
137
173
  globalState.trackingContext = this
138
174
  const result = trackDerivedFunction(this, fn, undefined)
139
175
  globalState.trackingContext = prevReaction
140
- this.isRunning_ = false
141
- this.isTrackPending_ = false
142
- if (this.isDisposed_) {
176
+ this.isRunning = false
177
+ this.isTrackPending = false
178
+ if (this.isDisposed) {
143
179
  // disposed during last run. Clean up everything that was bound after the dispose call.
144
180
  clearObserving(this)
145
181
  }
@@ -185,9 +221,9 @@ export class Reaction implements IDerivation, IReactionPublic {
185
221
  }
186
222
 
187
223
  dispose() {
188
- if (!this.isDisposed_) {
189
- this.isDisposed_ = true
190
- if (!this.isRunning_) {
224
+ if (!this.isDisposed) {
225
+ this.isDisposed = true
226
+ if (!this.isRunning) {
191
227
  // if disposed while running, clean up later. Maybe not optimal, but rare case
192
228
  startBatch()
193
229
  clearObserving(this)
@@ -212,3 +212,16 @@ export const getOwnPropertyDescriptors =
212
212
  })
213
213
  return res
214
214
  }
215
+
216
+ export function getFlag(flags: number, mask: number) {
217
+ return !!(flags & mask)
218
+ }
219
+
220
+ export function setFlag(flags: number, mask: number, newValue: boolean): number {
221
+ if (newValue) {
222
+ flags |= mask
223
+ } else {
224
+ flags &= ~mask
225
+ }
226
+ return flags
227
+ }