mobx 6.16.1 → 7.0.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.
Files changed (100) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +9 -13
  3. package/dist/api/action.d.ts +6 -4
  4. package/dist/api/annotation.d.ts +0 -1
  5. package/dist/api/computed.d.ts +4 -7
  6. package/dist/api/configure.d.ts +0 -1
  7. package/dist/api/decoratorannotation.d.ts +3 -0
  8. package/dist/api/decorators.d.ts +0 -19
  9. package/dist/api/flow.d.ts +4 -5
  10. package/dist/api/makeObservable.d.ts +2 -3
  11. package/dist/api/observable.d.ts +9 -15
  12. package/dist/core/atom.d.ts +1 -4
  13. package/dist/core/computedvalue.d.ts +5 -33
  14. package/dist/core/derivation.d.ts +1 -7
  15. package/dist/core/globalstate.d.ts +7 -2
  16. package/dist/core/observable.d.ts +9 -1
  17. package/dist/core/reaction.d.ts +1 -9
  18. package/dist/errors.d.ts +6 -4
  19. package/dist/internal.d.ts +1 -4
  20. package/dist/mobx.cjs.development.js +1704 -2484
  21. package/dist/mobx.cjs.development.js.map +1 -1
  22. package/dist/mobx.cjs.production.min.js +1 -1
  23. package/dist/mobx.cjs.production.min.js.map +1 -1
  24. package/dist/mobx.d.ts +2 -2
  25. package/dist/mobx.esm.development.js +1693 -2483
  26. package/dist/mobx.esm.development.js.map +1 -1
  27. package/dist/mobx.esm.js +1643 -2436
  28. package/dist/mobx.esm.js.map +1 -1
  29. package/dist/mobx.esm.production.min.js +1 -1
  30. package/dist/mobx.esm.production.min.js.map +1 -1
  31. package/dist/mobx.mjs +5308 -0
  32. package/dist/mobx.mjs.map +1 -0
  33. package/dist/mobx.umd.development.js +1707 -2487
  34. package/dist/mobx.umd.development.js.map +1 -1
  35. package/dist/mobx.umd.production.min.js +1 -1
  36. package/dist/mobx.umd.production.min.js.map +1 -1
  37. package/dist/types/actionannotation.d.ts +1 -0
  38. package/dist/types/computedannotation.d.ts +1 -0
  39. package/dist/types/decorator_fills.d.ts +2 -0
  40. package/dist/types/flowannotation.d.ts +1 -0
  41. package/dist/types/observableannotation.d.ts +5 -0
  42. package/dist/types/observablearray.d.ts +2 -5
  43. package/dist/types/observablemap.d.ts +1 -8
  44. package/dist/types/observableobject.d.ts +2 -13
  45. package/dist/types/observableset.d.ts +1 -3
  46. package/dist/types/observablevalue.d.ts +4 -6
  47. package/dist/types/overrideannotation.d.ts +1 -2
  48. package/dist/utils/comparer.d.ts +4 -11
  49. package/dist/utils/utils.d.ts +0 -2
  50. package/package.json +25 -15
  51. package/src/api/action.ts +27 -35
  52. package/src/api/annotation.ts +0 -1
  53. package/src/api/autorun.ts +2 -4
  54. package/src/api/computed.ts +21 -28
  55. package/src/api/configure.ts +1 -15
  56. package/src/api/decoratorannotation.ts +20 -0
  57. package/src/api/decorators.ts +1 -85
  58. package/src/api/extras.ts +1 -1
  59. package/src/api/flow.ts +26 -29
  60. package/src/api/intercept.ts +4 -3
  61. package/src/api/makeObservable.ts +45 -17
  62. package/src/api/object-api.ts +1 -1
  63. package/src/api/observable.ts +34 -67
  64. package/src/api/observe.ts +82 -3
  65. package/src/api/when.ts +4 -3
  66. package/src/core/action.ts +12 -5
  67. package/src/core/atom.ts +16 -14
  68. package/src/core/computedvalue.ts +36 -69
  69. package/src/core/derivation.ts +16 -15
  70. package/src/core/globalstate.ts +16 -13
  71. package/src/core/observable.ts +65 -73
  72. package/src/core/reaction.ts +19 -25
  73. package/src/core/spy.ts +3 -3
  74. package/src/errors.ts +23 -12
  75. package/src/internal.ts +1 -4
  76. package/src/mobx.ts +21 -10
  77. package/src/types/actionannotation.ts +5 -9
  78. package/src/types/autoannotation.ts +8 -11
  79. package/src/types/computedannotation.ts +13 -11
  80. package/src/types/decorator_fills.ts +4 -0
  81. package/src/types/dynamicobject.ts +0 -29
  82. package/src/types/flowannotation.ts +7 -4
  83. package/src/types/modifiers.ts +5 -0
  84. package/src/types/observableannotation.ts +6 -7
  85. package/src/types/observablearray.ts +8 -61
  86. package/src/types/observablemap.ts +4 -29
  87. package/src/types/observableobject.ts +5 -70
  88. package/src/types/observableset.ts +9 -52
  89. package/src/types/observablevalue.ts +7 -29
  90. package/src/types/overrideannotation.ts +7 -22
  91. package/src/types/type-utils.ts +4 -2
  92. package/src/utils/comparer.ts +4 -17
  93. package/src/utils/iterable.ts +3 -4
  94. package/src/utils/utils.ts +4 -46
  95. package/dist/api/trace.d.ts +0 -3
  96. package/dist/types/legacyobservablearray.d.ts +0 -14
  97. package/dist/utils/global.d.ts +0 -1
  98. package/src/api/trace.ts +0 -35
  99. package/src/types/legacyobservablearray.ts +0 -155
  100. package/src/utils/global.ts +0 -20
@@ -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
@@ -29,7 +26,7 @@ export interface IObservable extends IDepTreeNode {
29
26
  lowestObserverState_: IDerivationState_ // Used to avoid redundant propagations
30
27
  isPendingUnobservation: boolean // Used to push itself to global.pendingUnobservations at most once per batch.
31
28
 
32
- observers_: Set<IDerivation>
29
+ observers_: Set<IDerivation> | null
33
30
 
34
31
  onBUO(): void
35
32
  onBO(): void
@@ -39,11 +36,11 @@ export interface IObservable extends IDepTreeNode {
39
36
  }
40
37
 
41
38
  export function hasObservers(observable: IObservable): boolean {
42
- return observable.observers_ && observable.observers_.size > 0
39
+ return !!observable.observers_ && observable.observers_.size > 0
43
40
  }
44
41
 
45
42
  export function getObservers(observable: IObservable): Set<IDerivation> {
46
- return observable.observers_
43
+ return observable.observers_ ?? new Set()
47
44
  }
48
45
 
49
46
  // function invariantObservers(observable: IObservable) {
@@ -68,7 +65,7 @@ export function addObserver(observable: IObservable, node: IDerivation) {
68
65
  // invariant(observable._observers.indexOf(node) === -1, "INTERNAL ERROR add already added node");
69
66
  // invariantObservers(observable);
70
67
 
71
- observable.observers_.add(node)
68
+ ;(observable.observers_ ??= new Set()).add(node)
72
69
  if (observable.lowestObserverState_ > node.dependenciesState_) {
73
70
  observable.lowestObserverState_ = node.dependenciesState_
74
71
  }
@@ -81,8 +78,12 @@ export function removeObserver(observable: IObservable, node: IDerivation) {
81
78
  // invariant(globalState.inBatch > 0, "INTERNAL ERROR, remove should be called only inside batch");
82
79
  // invariant(observable._observers.indexOf(node) !== -1, "INTERNAL ERROR remove already removed node");
83
80
  // invariantObservers(observable);
84
- observable.observers_.delete(node)
85
- if (observable.observers_.size === 0) {
81
+ const observers = observable.observers_
82
+ if (!observers) {
83
+ return
84
+ }
85
+ observers.delete(node)
86
+ if (observers.size === 0) {
86
87
  // deleting last observer
87
88
  queueForUnobservation(observable)
88
89
  }
@@ -111,27 +112,60 @@ export function endBatch() {
111
112
  if (--globalState.inBatch === 0) {
112
113
  runReactions()
113
114
  // the batch is actually about to finish, all unobserving should happen here.
114
- const list = globalState.pendingUnobservations
115
- for (let i = 0; i < list.length; i++) {
116
- const observable = list[i]
117
- observable.isPendingUnobservation = false
118
- if (observable.observers_.size === 0) {
119
- if (observable.isBeingObserved) {
120
- // if this observable had reactive observers, trigger the hooks
121
- observable.isBeingObserved = false
122
- observable.onBUO()
123
- }
124
- if (observable instanceof ComputedValue) {
125
- // computed values are automatically teared down when the last observer leaves
126
- // this process happens recursively, this computed might be the last observabe of another, etc..
127
- observable.suspend_()
115
+ // Guard against re-entering this loop: an onBUO handler can dispose a Reaction,
116
+ // which calls startBatch/endBatch again while we're still iterating. Bail out of
117
+ // the nested call instead of recursing; the outer loop re-reads list.length on
118
+ // every iteration, so it picks up anything the nested dispose() pushes onto the
119
+ // same pendingUnobservations array.
120
+ if (!globalState.isRunningUnobservations) {
121
+ globalState.isRunningUnobservations = true
122
+ try {
123
+ const list = globalState.pendingUnobservations
124
+ for (let i = 0; i < list.length; i++) {
125
+ const observable = list[i]
126
+ observable.isPendingUnobservation = false
127
+ if (!observable.observers_ || observable.observers_.size === 0) {
128
+ if (observable.isBeingObserved) {
129
+ // if this observable had reactive observers, trigger the hooks
130
+ observable.isBeingObserved = false
131
+ observable.onBUO()
132
+ }
133
+ if (observable instanceof ComputedValue) {
134
+ // computed values are automatically teared down when the last observer leaves
135
+ // this process happens recursively, this computed might be the last observabe of another, etc..
136
+ observable.suspend_()
137
+ }
138
+ }
128
139
  }
140
+ globalState.pendingUnobservations = []
141
+ } finally {
142
+ // Always release the guard, even if an onBUO handler (user code) threw,
143
+ // otherwise every future endBatch() would see isRunningUnobservations
144
+ // stuck true and silently stop draining pendingUnobservations forever.
145
+ globalState.isRunningUnobservations = false
129
146
  }
130
147
  }
131
- globalState.pendingUnobservations = []
132
148
  }
133
149
  }
134
150
 
151
+ /**
152
+ * Marks an observable as observed, cascading into the dependencies of a ComputedValue.
153
+ * Unobservation already cascades (`suspend_` -> `clearObserving`), observation normally
154
+ * only does so by accident: a newly observed computed usually recomputes and re-reports
155
+ * its dependencies. When it serves a cached value instead nothing re-reports them, so the
156
+ * transition has to be propagated by hand. See #4547.
157
+ */
158
+ export function markObserved(observable: IObservable) {
159
+ if (observable.isBeingObserved) {
160
+ return
161
+ }
162
+ observable.isBeingObserved = true
163
+ observable.onBO()
164
+ // No queueForUnobservation here: the observer links already exist, so the regular
165
+ // suspend_ -> clearObserving -> removeObserver teardown still delivers the onBUO.
166
+ observable.observing_?.forEach(markObserved)
167
+ }
168
+
135
169
  export function reportObserved(observable: IObservable): boolean {
136
170
  checkIfStateReadsAreAllowed(observable)
137
171
 
@@ -152,7 +186,10 @@ export function reportObserved(observable: IObservable): boolean {
152
186
  }
153
187
  }
154
188
  return observable.isBeingObserved
155
- } else if (observable.observers_.size === 0 && globalState.inBatch > 0) {
189
+ } else if (
190
+ (!observable.observers_ || observable.observers_.size === 0) &&
191
+ globalState.inBatch > 0
192
+ ) {
156
193
  queueForUnobservation(observable)
157
194
  }
158
195
 
@@ -190,11 +227,8 @@ export function propagateChanged(observable: IObservable) {
190
227
  observable.lowestObserverState_ = IDerivationState_.STALE_
191
228
 
192
229
  // Ideally we use for..of here, but the downcompiled version is really slow...
193
- observable.observers_.forEach(d => {
230
+ observable.observers_?.forEach(d => {
194
231
  if (d.dependenciesState_ === IDerivationState_.UP_TO_DATE_) {
195
- if (__DEV__ && d.isTracing_ !== TraceMode.NONE) {
196
- logTraceInfo(d, observable)
197
- }
198
232
  d.onBecomeStale_()
199
233
  }
200
234
  d.dependenciesState_ = IDerivationState_.STALE_
@@ -210,12 +244,9 @@ export function propagateChangeConfirmed(observable: IObservable) {
210
244
  }
211
245
  observable.lowestObserverState_ = IDerivationState_.STALE_
212
246
 
213
- observable.observers_.forEach(d => {
247
+ observable.observers_?.forEach(d => {
214
248
  if (d.dependenciesState_ === IDerivationState_.POSSIBLY_STALE_) {
215
249
  d.dependenciesState_ = IDerivationState_.STALE_
216
- if (__DEV__ && d.isTracing_ !== TraceMode.NONE) {
217
- logTraceInfo(d, observable)
218
- }
219
250
  } else if (
220
251
  d.dependenciesState_ === IDerivationState_.UP_TO_DATE_ // this happens during computing of `d`, just keep lowestObserverState up to date.
221
252
  ) {
@@ -233,7 +264,7 @@ export function propagateMaybeChanged(observable: IObservable) {
233
264
  }
234
265
  observable.lowestObserverState_ = IDerivationState_.POSSIBLY_STALE_
235
266
 
236
- observable.observers_.forEach(d => {
267
+ observable.observers_?.forEach(d => {
237
268
  if (d.dependenciesState_ === IDerivationState_.UP_TO_DATE_) {
238
269
  d.dependenciesState_ = IDerivationState_.POSSIBLY_STALE_
239
270
  d.onBecomeStale_()
@@ -241,42 +272,3 @@ export function propagateMaybeChanged(observable: IObservable) {
241
272
  })
242
273
  // invariantLOS(observable, "maybe end");
243
274
  }
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
- }
@@ -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_, Reaction.isDisposedMask_)
78
+ return getFlag(this.flags_, ReactionFlags.isDisposed)
81
79
  }
82
80
  set isDisposed(newValue: boolean) {
83
- this.flags_ = setFlag(this.flags_, Reaction.isDisposedMask_, newValue)
81
+ this.flags_ = setFlag(this.flags_, ReactionFlags.isDisposed, newValue)
84
82
  }
85
83
 
86
84
  get isScheduled() {
87
- return getFlag(this.flags_, Reaction.isScheduledMask_)
85
+ return getFlag(this.flags_, ReactionFlags.isScheduled)
88
86
  }
89
87
  set isScheduled(newValue: boolean) {
90
- this.flags_ = setFlag(this.flags_, Reaction.isScheduledMask_, newValue)
88
+ this.flags_ = setFlag(this.flags_, ReactionFlags.isScheduled, newValue)
91
89
  }
92
90
 
93
91
  get isTrackPending() {
94
- return getFlag(this.flags_, Reaction.isTrackPendingMask_)
92
+ return getFlag(this.flags_, ReactionFlags.isTrackPending)
95
93
  }
96
94
  set isTrackPending(newValue: boolean) {
97
- this.flags_ = setFlag(this.flags_, Reaction.isTrackPendingMask_, newValue)
95
+ this.flags_ = setFlag(this.flags_, ReactionFlags.isTrackPending, newValue)
98
96
  }
99
97
 
100
98
  get isRunning() {
101
- return getFlag(this.flags_, Reaction.isRunningMask_)
99
+ return getFlag(this.flags_, ReactionFlags.isRunning)
102
100
  }
103
101
  set isRunning(newValue: boolean) {
104
- this.flags_ = setFlag(this.flags_, Reaction.isRunningMask_, newValue)
102
+ this.flags_ = setFlag(this.flags_, ReactionFlags.isRunning, newValue)
105
103
  }
106
104
 
107
105
  get diffValue(): 0 | 1 {
108
- return getFlag(this.flags_, Reaction.diffValueMask_) ? 1 : 0
106
+ return getFlag(this.flags_, ReactionFlags.diffValue) ? 1 : 0
109
107
  }
110
108
  set diffValue(newValue: 0 | 1) {
111
- this.flags_ = setFlag(this.flags_, Reaction.diffValueMask_, newValue === 1 ? true : false)
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 = { ...event, spyReportStart: true as const }
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({ ...change, type: "report-end", spyReportEnd: true })
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
- typeof error === "number"
88
- ? `[MobX] minified error nr: ${error}${
89
- args.length ? " " + args.map(String).join(",") : ""
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 * from "./utils/global"
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"
package/src/mobx.ts CHANGED
@@ -16,13 +16,14 @@
16
16
  *
17
17
  */
18
18
  import { die } from "./errors"
19
- import { getGlobal } from "./utils/global"
20
- ;["Symbol", "Map", "Set"].forEach(m => {
21
- let g = getGlobal()
22
- if (typeof g[m] === "undefined") {
23
- die(`MobX requires global '${m}' to be available or polyfilled`)
24
- }
25
- })
19
+ if (__DEV__) {
20
+ const g = globalThis as any
21
+ ;["Symbol", "Map", "Set", "Proxy"].forEach(m => {
22
+ if (typeof g[m] === "undefined") {
23
+ die(`MobX requires global '${m}' to be available or polyfilled`)
24
+ }
25
+ })
26
+ }
26
27
 
27
28
  import { spy, getDebugName, $mobx } from "./internal"
28
29
 
@@ -38,7 +39,10 @@ export {
38
39
  spy,
39
40
  IComputedValue,
40
41
  IEqualsComparer,
41
- comparer,
42
+ compareDefault,
43
+ compareIdentity,
44
+ compareStructural,
45
+ compareShallow,
42
46
  IEnhancer,
43
47
  IInterceptable,
44
48
  IInterceptor,
@@ -72,9 +76,14 @@ export {
72
76
  IObservableSetInitialValues,
73
77
  transaction,
74
78
  observable,
79
+ observableRef,
80
+ observableShallow,
81
+ observableDeep,
82
+ observableStruct,
75
83
  IObservableFactory,
76
84
  CreateObservableOptions,
77
85
  computed,
86
+ computedStruct,
78
87
  IComputedFactory,
79
88
  isObservable,
80
89
  isObservableProp,
@@ -90,6 +99,7 @@ export {
90
99
  when,
91
100
  IWhenOptions,
92
101
  action,
102
+ actionBound,
93
103
  isAction,
94
104
  runInAction,
95
105
  IActionFactory,
@@ -106,13 +116,13 @@ export {
106
116
  onBecomeObserved,
107
117
  onBecomeUnobserved,
108
118
  flow,
119
+ flowBound,
109
120
  isFlow,
110
121
  flowResult,
111
122
  CancellablePromise,
112
123
  FlowCancellationError,
113
124
  isFlowCancellationError,
114
125
  toJS,
115
- trace,
116
126
  IObserverTree,
117
127
  IDependencyTree,
118
128
  getDependencyTree,
@@ -138,6 +148,7 @@ export {
138
148
  makeObservable,
139
149
  makeAutoObservable,
140
150
  autoAction as _autoAction,
151
+ autoActionBound as _autoActionBound,
141
152
  AnnotationsMap,
142
153
  AnnotationMapEntry,
143
154
  override
@@ -145,7 +156,7 @@ export {
145
156
 
146
157
  // Devtools support
147
158
  declare const __MOBX_DEVTOOLS_GLOBAL_HOOK__: { injectMobx: (any) => void }
148
- if (typeof __MOBX_DEVTOOLS_GLOBAL_HOOK__ === "object") {
159
+ if (__DEV__ && typeof __MOBX_DEVTOOLS_GLOBAL_HOOK__ === "object") {
149
160
  // See: https://github.com/andykog/mobx-devtools/
150
161
  __MOBX_DEVTOOLS_GLOBAL_HOOK__.injectMobx({
151
162
  spy,
@@ -16,8 +16,7 @@ export function createActionAnnotation(name: string, options?: object): Annotati
16
16
  annotationType_: name,
17
17
  options_: options,
18
18
  make_,
19
- extend_,
20
- decorate_20223_
19
+ extend_
21
20
  }
22
21
  }
23
22
 
@@ -62,12 +61,12 @@ function extend_(
62
61
  return adm.defineProperty_(key, actionDescriptor, proxyTrap)
63
62
  }
64
63
 
65
- function decorate_20223_(this: Annotation, mthd, context: DecoratorContext) {
64
+ export function decorateAction20223_(annotation: Annotation, mthd, context: DecoratorContext) {
66
65
  if (__DEV__) {
67
66
  assert20223DecoratorType(context, ["method", "field"])
68
67
  }
69
68
  const { kind, name, addInitializer } = context
70
- const ann = this
69
+ const ann = annotation
71
70
 
72
71
  const _createAction = m =>
73
72
  createAction(ann.options_?.name ?? name!.toString(), m, ann.options_?.autoAction ?? false)
@@ -91,7 +90,7 @@ function decorate_20223_(this: Annotation, mthd, context: DecoratorContext) {
91
90
  mthd = _createAction(mthd)
92
91
  }
93
92
 
94
- if (this.options_?.bound) {
93
+ if (ann.options_?.bound) {
95
94
  addInitializer(function () {
96
95
  const self = this as any
97
96
  const bound = self[name].bind(self)
@@ -103,10 +102,7 @@ function decorate_20223_(this: Annotation, mthd, context: DecoratorContext) {
103
102
  return mthd
104
103
  }
105
104
 
106
- die(
107
- `Cannot apply '${ann.annotationType_}' to '${String(name)}' (kind: ${kind}):` +
108
- `\n'${ann.annotationType_}' can only be used on properties with a function value.`
109
- )
105
+ die(43, ann.annotationType_, String(name), kind)
110
106
  }
111
107
 
112
108
  function assertActionDescriptor(
@@ -1,16 +1,18 @@
1
1
  import {
2
2
  ObservableObjectAdministration,
3
3
  observable,
4
+ observableRef,
4
5
  Annotation,
5
6
  defineProperty,
6
7
  createAction,
7
8
  globalState,
8
9
  flow,
10
+ flowBound,
9
11
  computed,
10
12
  autoAction,
13
+ autoActionBound,
11
14
  isGenerator,
12
15
  MakeResult,
13
- die,
14
16
  isAction
15
17
  } from "../internal"
16
18
 
@@ -23,8 +25,7 @@ export function createAutoAnnotation(options?: object): Annotation {
23
25
  annotationType_: AUTO,
24
26
  options_: options,
25
27
  make_,
26
- extend_,
27
- decorate_20223_
28
+ extend_
28
29
  }
29
30
  }
30
31
 
@@ -63,16 +64,16 @@ function make_(
63
64
  // function on proto -> autoAction/flow
64
65
  if (source !== adm.target_ && typeof descriptor.value === "function") {
65
66
  if (isGenerator(descriptor.value)) {
66
- const flowAnnotation = this.options_?.autoBind ? flow.bound : flow
67
+ const flowAnnotation = this.options_?.autoBind ? flowBound : flow
67
68
  return flowAnnotation.make_(adm, key, descriptor, source)
68
69
  }
69
- const actionAnnotation = this.options_?.autoBind ? autoAction.bound : autoAction
70
+ const actionAnnotation = this.options_?.autoBind ? autoActionBound : autoAction
70
71
  return actionAnnotation.make_(adm, key, descriptor, source)
71
72
  }
72
73
  // other -> observable
73
74
  // Copy props from proto as well, see test:
74
75
  // "decorate should work with Object.create"
75
- let observableAnnotation = this.options_?.deep === false ? observable.ref : observable
76
+ let observableAnnotation = this.options_?.deep === false ? observableRef : observable
76
77
  // if function respect autoBind option
77
78
  if (typeof descriptor.value === "function" && this.options_?.autoBind) {
78
79
  descriptor.value = descriptor.value.bind(adm.proxy_ ?? adm.target_)
@@ -107,10 +108,6 @@ function extend_(
107
108
  if (typeof descriptor.value === "function" && this.options_?.autoBind) {
108
109
  descriptor.value = descriptor.value.bind(adm.proxy_ ?? adm.target_)
109
110
  }
110
- let observableAnnotation = this.options_?.deep === false ? observable.ref : observable
111
+ let observableAnnotation = this.options_?.deep === false ? observableRef : observable
111
112
  return observableAnnotation.extend_(adm, key, descriptor, proxyTrap)
112
113
  }
113
-
114
- function decorate_20223_(this: Annotation, desc, context: ClassGetterDecoratorContext) {
115
- die(`'${this.annotationType_}' cannot be used as a decorator`)
116
- }