mobx 6.3.3 → 6.3.7

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.
@@ -48,7 +48,6 @@ export declare class ObservableMap<K = any, V = any> implements Map<K, V>, IInte
48
48
  has(key: K): boolean;
49
49
  set(key: K, value: V): this;
50
50
  delete(key: K): boolean;
51
- private updateHasMapEntry_;
52
51
  private updateValue_;
53
52
  private addValue_;
54
53
  get(key: K): V | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobx",
3
- "version": "6.3.3",
3
+ "version": "6.3.7",
4
4
  "description": "Simple, scalable state management.",
5
5
  "source": "src/mobx.ts",
6
6
  "main": "dist/index.js",
@@ -86,8 +86,8 @@ export function autorun(
86
86
  return reaction.getDisposer_()
87
87
  }
88
88
 
89
- export type IReactionOptions<T> = IAutorunOptions & {
90
- fireImmediately?: boolean
89
+ export type IReactionOptions<T, FireImmediately extends boolean> = IAutorunOptions & {
90
+ fireImmediately?: FireImmediately
91
91
  equals?: IEqualsComparer<T>
92
92
  }
93
93
 
@@ -101,10 +101,14 @@ function createSchedulerFromOptions(opts: IAutorunOptions) {
101
101
  : run
102
102
  }
103
103
 
104
- export function reaction<T>(
104
+ export function reaction<T, FireImmediately extends boolean = false>(
105
105
  expression: (r: IReactionPublic) => T,
106
- effect: (arg: T, prev: T, r: IReactionPublic) => void,
107
- opts: IReactionOptions<T> = EMPTY_OBJECT
106
+ effect: (
107
+ arg: T,
108
+ prev: FireImmediately extends true ? T | undefined : T,
109
+ r: IReactionPublic
110
+ ) => void,
111
+ opts: IReactionOptions<T, FireImmediately> = EMPTY_OBJECT
108
112
  ): IReactionDisposer {
109
113
  if (__DEV__) {
110
114
  if (!isFunction(expression) || !isFunction(effect))
@@ -122,7 +126,7 @@ export function reaction<T>(
122
126
  let firstTime = true
123
127
  let isScheduled = false
124
128
  let value: T
125
- let oldValue: T = undefined as any // only an issue with fireImmediately
129
+ let oldValue: T | undefined
126
130
 
127
131
  const equals: IEqualsComparer<T> = (opts as any).compareStructural
128
132
  ? comparer.structural
@@ -152,8 +156,11 @@ export function reaction<T>(
152
156
  oldValue = value
153
157
  value = nextValue
154
158
  })
155
- if (firstTime && opts.fireImmediately!) effectAction(value, oldValue, r)
156
- else if (!firstTime && changed) effectAction(value, oldValue, r)
159
+
160
+ // This casting is nesessary as TS cannot infer proper type in current funciton implementation
161
+ type OldValue = FireImmediately extends true ? T | undefined : T
162
+ if (firstTime && opts.fireImmediately!) effectAction(value, oldValue as OldValue, r)
163
+ else if (!firstTime && changed) effectAction(value, oldValue as OldValue, r)
157
164
  firstTime = false
158
165
  }
159
166
 
@@ -27,7 +27,7 @@ export function extendObservable<A extends Object, B extends Object>(
27
27
  if (isObservableMap(target))
28
28
  die("'extendObservable' should not be used on maps, use map.merge instead")
29
29
  if (!isPlainObject(properties))
30
- die(`'extendObservabe' only accepts plain objects as second argument`)
30
+ die(`'extendObservable' only accepts plain objects as second argument`)
31
31
  if (isObservable(properties) || isObservable(annotations))
32
32
  die(`Extending an object with another observable (object) is not supported`)
33
33
  }
@@ -24,15 +24,15 @@ export function intercept<T>(
24
24
  handler: IInterceptor<IArrayWillChange<T> | IArrayWillSplice<T>>
25
25
  ): Lambda
26
26
  export function intercept<K, V>(
27
- observableMap: ObservableMap<K, V>,
27
+ observableMap: ObservableMap<K, V> | Map<K, V>,
28
28
  handler: IInterceptor<IMapWillChange<K, V>>
29
29
  ): Lambda
30
30
  export function intercept<V>(
31
- observableMap: ObservableSet<V>,
31
+ observableSet: ObservableSet<V> | Set<V>,
32
32
  handler: IInterceptor<ISetWillChange<V>>
33
33
  ): Lambda
34
34
  export function intercept<K, V>(
35
- observableMap: ObservableMap<K, V>,
35
+ observableMap: ObservableMap<K, V> | Map<K, V>,
36
36
  property: K,
37
37
  handler: IInterceptor<IValueWillChange<V>>
38
38
  ): Lambda
@@ -40,7 +40,7 @@ export function intercept(object: object, handler: IInterceptor<IObjectWillChang
40
40
  export function intercept<T extends object, K extends keyof T>(
41
41
  object: T,
42
42
  property: K,
43
- handler: IInterceptor<IValueWillChange<any>>
43
+ handler: IInterceptor<IValueWillChange<T[K]>>
44
44
  ): Lambda
45
45
  export function intercept(thing, propOrHandler?, handler?): Lambda {
46
46
  if (isFunction(handler)) return interceptProperty(thing, propOrHandler, handler)
@@ -1,13 +1,13 @@
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 !== undefined) {
5
- if (isObservableObject(value) === false) return false
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
- return isComputedValue(value)
7
+ if (isObservableObject(value) === false) return false
8
+ if (!value[$mobx].values_.has(property)) return false
9
+ const atom = getAtom(value, property)
10
+ return isComputedValue(atom)
11
11
  }
12
12
 
13
13
  export function isComputed(value: any): boolean {
@@ -12,7 +12,8 @@ import {
12
12
  die,
13
13
  ownKeys,
14
14
  extendObservable,
15
- addHiddenProp
15
+ addHiddenProp,
16
+ storedAnnotationsSymbol
16
17
  } from "../internal"
17
18
 
18
19
  // Hack based on https://github.com/Microsoft/TypeScript/issues/14829#issuecomment-322267089
@@ -30,6 +31,11 @@ export function makeObservable<T extends object, AdditionalKeys extends Property
30
31
  const adm: ObservableObjectAdministration = asObservableObject(target, options)[$mobx]
31
32
  startBatch()
32
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
+ }
33
39
  // Default to decorators
34
40
  annotations ??= collectStoredAnnotations(target)
35
41
 
@@ -25,17 +25,18 @@ export function observe<T>(
25
25
  fireImmediately?: boolean
26
26
  ): Lambda
27
27
  export function observe<V>(
28
- observableMap: ObservableSet<V>,
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
package/src/api/when.ts CHANGED
@@ -72,7 +72,7 @@ function whenPromise(
72
72
  let disposer = _when(predicate, resolve, { ...opts, onError: reject })
73
73
  cancel = () => {
74
74
  disposer()
75
- reject("WHEN_CANCELLED")
75
+ reject(new Error("WHEN_CANCELLED"))
76
76
  }
77
77
  })
78
78
  ;(res as any).cancel = cancel
@@ -204,17 +204,6 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
204
204
  /* see #1208 */ this.dependenciesState_ === IDerivationState_.NOT_TRACKING_
205
205
  const newValue = this.computeValue_(true)
206
206
 
207
- if (__DEV__ && isSpyEnabled()) {
208
- spyReport({
209
- observableKind: "computed",
210
- debugObjectName: this.name_,
211
- object: this.scope_,
212
- type: "update",
213
- oldValue: this.value_,
214
- newValue
215
- } as IComputedDidChange)
216
- }
217
-
218
207
  const changed =
219
208
  wasSuspended ||
220
209
  isCaughtException(oldValue) ||
@@ -223,6 +212,17 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
223
212
 
224
213
  if (changed) {
225
214
  this.value_ = newValue
215
+
216
+ if (__DEV__ && isSpyEnabled()) {
217
+ spyReport({
218
+ observableKind: "computed",
219
+ debugObjectName: this.name_,
220
+ object: this.scope_,
221
+ type: "update",
222
+ oldValue,
223
+ newValue
224
+ } as IComputedDidChange)
225
+ }
226
226
  }
227
227
 
228
228
  return changed
@@ -162,6 +162,8 @@ export let globalState: MobXGlobals = (function () {
162
162
  canMergeGlobalState = false
163
163
 
164
164
  if (!canMergeGlobalState) {
165
+ // Because this is a IIFE we need to let isolateCalled a chance to change
166
+ // so we run it after the event loop completed at least 1 iteration
165
167
  setTimeout(() => {
166
168
  if (!isolateCalled) {
167
169
  die(35)
@@ -268,6 +268,6 @@ function printDepTree(tree: IDependencyTree, lines: string[], depth: number) {
268
268
  lines.push("(and many more)")
269
269
  return
270
270
  }
271
- lines.push(`${new Array(depth).join("\t")}${tree.name}`) // MWE: not the fastest, but the easiest way :)
271
+ lines.push(`${"\t".repeat(depth - 1)}${tree.name}`)
272
272
  if (tree.dependencies) tree.dependencies.forEach(child => printDepTree(child, lines, depth + 1))
273
273
  }
@@ -67,7 +67,7 @@ function assertActionDescriptor(
67
67
  if (__DEV__ && !isFunction(value)) {
68
68
  die(
69
69
  `Cannot apply '${annotationType_}' to '${adm.name_}.${key.toString()}':` +
70
- `\n'${annotationType_}' can only be used on properties with a function value.`
70
+ `\n'${annotationType_}' can only be used on properties with a function value.`
71
71
  )
72
72
  }
73
73
  }
@@ -89,7 +89,9 @@ export function createActionDescriptor(
89
89
  value: createAction(
90
90
  annotation.options_?.name ?? key.toString(),
91
91
  value,
92
- annotation.options_?.autoAction ?? false
92
+ annotation.options_?.autoAction ?? false,
93
+ // https://github.com/mobxjs/mobx/discussions/3140
94
+ annotation.options_?.bound ? (adm.proxy_ ?? adm.target_) : undefined,
93
95
  ),
94
96
  // Non-configurable for classes
95
97
  // prevents accidental field redefinition in subclass
@@ -175,7 +175,7 @@ export class ObservableArrayAdministration
175
175
  }
176
176
 
177
177
  setArrayLength_(newLength: number) {
178
- if (typeof newLength !== "number" || newLength < 0) die("Out of range: " + newLength)
178
+ if (typeof newLength !== "number" || isNaN(newLength) || newLength < 0) die("Out of range: " + newLength)
179
179
  let currentLength = this.values_.length
180
180
  if (newLength === currentLength) return
181
181
  else if (newLength > currentLength) {
@@ -178,7 +178,7 @@ export class ObservableMap<K = any, V = any>
178
178
  if (__DEV__ && notifySpy) spyReportStart(change!)
179
179
  transaction(() => {
180
180
  this.keysAtom_.reportChanged()
181
- this.updateHasMapEntry_(key, false)
181
+ this.hasMap_.get(key)?.setNewValue_(false)
182
182
  const observable = this.data_.get(key)!
183
183
  observable.setNewValue_(undefined as any)
184
184
  this.data_.delete(key)
@@ -190,13 +190,6 @@ export class ObservableMap<K = any, V = any>
190
190
  return false
191
191
  }
192
192
 
193
- private updateHasMapEntry_(key: K, value: boolean) {
194
- let entry = this.hasMap_.get(key)
195
- if (entry) {
196
- entry.setNewValue_(value)
197
- }
198
- }
199
-
200
193
  private updateValue_(key: K, newValue: V | undefined) {
201
194
  const observable = this.data_.get(key)!
202
195
  newValue = (observable as any).prepareNewValue_(newValue) as V
@@ -233,7 +226,7 @@ export class ObservableMap<K = any, V = any>
233
226
  )
234
227
  this.data_.set(key, observable)
235
228
  newValue = (observable as any).value_ // value might have been changed
236
- this.updateHasMapEntry_(key, true)
229
+ this.hasMap_.get(key)?.setNewValue_(true)
237
230
  this.keysAtom_.reportChanged()
238
231
  })
239
232
  const notifySpy = isSpyEnabled()