mobx 6.9.1 → 6.10.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 (42) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/api/autorun.d.ts +2 -1
  3. package/dist/api/makeObservable.d.ts +3 -2
  4. package/dist/api/when.d.ts +1 -8
  5. package/dist/core/atom.d.ts +2 -1
  6. package/dist/core/globalstate.d.ts +5 -0
  7. package/dist/core/reaction.d.ts +2 -2
  8. package/dist/internal.d.ts +1 -0
  9. package/dist/mobx.cjs.development.js +137 -85
  10. package/dist/mobx.cjs.development.js.map +1 -1
  11. package/dist/mobx.cjs.production.min.js +1 -1
  12. package/dist/mobx.cjs.production.min.js.map +1 -1
  13. package/dist/mobx.esm.development.js +137 -85
  14. package/dist/mobx.esm.development.js.map +1 -1
  15. package/dist/mobx.esm.js +137 -85
  16. package/dist/mobx.esm.js.map +1 -1
  17. package/dist/mobx.esm.production.min.js +1 -1
  18. package/dist/mobx.esm.production.min.js.map +1 -1
  19. package/dist/mobx.umd.development.js +137 -85
  20. package/dist/mobx.umd.development.js.map +1 -1
  21. package/dist/mobx.umd.production.min.js +1 -1
  22. package/dist/mobx.umd.production.min.js.map +1 -1
  23. package/dist/types/generic-abort-signal.d.ts +6 -0
  24. package/dist/types/type-utils.d.ts +7 -0
  25. package/package.json +1 -1
  26. package/src/api/autorun.ts +11 -5
  27. package/src/api/extendobservable.ts +6 -9
  28. package/src/api/makeObservable.ts +22 -26
  29. package/src/api/observable.ts +10 -7
  30. package/src/api/when.ts +2 -9
  31. package/src/core/atom.ts +12 -2
  32. package/src/core/globalstate.ts +6 -0
  33. package/src/core/observable.ts +6 -0
  34. package/src/core/reaction.ts +10 -5
  35. package/src/internal.ts +1 -0
  36. package/src/types/generic-abort-signal.ts +7 -0
  37. package/src/types/legacyobservablearray.ts +17 -19
  38. package/src/types/observablearray.ts +12 -13
  39. package/src/types/observablemap.ts +13 -10
  40. package/src/types/observableobject.ts +6 -1
  41. package/src/types/observableset.ts +9 -6
  42. package/src/types/type-utils.ts +26 -1
@@ -428,12 +428,14 @@
428
428
  this.isPendingUnobservation_ = false;
429
429
  this.isBeingObserved_ = false;
430
430
  this.observers_ = new Set();
431
+ this.batchId_ = void 0;
431
432
  this.diffValue_ = 0;
432
433
  this.lastAccessedBy_ = 0;
433
434
  this.lowestObserverState_ = IDerivationState_.NOT_TRACKING_;
434
435
  this.onBOL = void 0;
435
436
  this.onBUOL = void 0;
436
437
  this.name_ = name_;
438
+ this.batchId_ = globalState.inBatch ? globalState.batchId : NaN;
437
439
  }
438
440
  // onBecomeObservedListeners
439
441
  var _proto = Atom.prototype;
@@ -462,6 +464,12 @@
462
464
  * Invoke this method _after_ this method has changed to signal mobx that all its observers should invalidate.
463
465
  */;
464
466
  _proto.reportChanged = function reportChanged() {
467
+ if (globalState.inBatch && this.batchId_ === globalState.batchId) {
468
+ // Called from the same batch this atom was created in.
469
+ return;
470
+ }
471
+ // Avoids the possibility of hitting the same globalState.batchId when it cycled through all integers (necessary?)
472
+ this.batchId_ = NaN;
465
473
  startBatch();
466
474
  propagateChanged(this);
467
475
  // We could update state version only at the end of batch,
@@ -995,7 +1003,9 @@
995
1003
  return new ObservableSet(initialValues, getEnhancerFromOptions(o), o.name);
996
1004
  },
997
1005
  object: function object(props, decorators, options) {
998
- return extendObservable(globalState.useProxies === false || (options == null ? void 0 : options.proxy) === false ? asObservableObject({}, options) : asDynamicObservableObject({}, options), props, decorators);
1006
+ return initObservable(function () {
1007
+ return extendObservable(globalState.useProxies === false || (options == null ? void 0 : options.proxy) === false ? asObservableObject({}, options) : asDynamicObservableObject({}, options), props, decorators);
1008
+ });
999
1009
  },
1000
1010
  ref: /*#__PURE__*/createDecoratorAnnotation(observableRefAnnotation),
1001
1011
  shallow: /*#__PURE__*/createDecoratorAnnotation(observableShallowAnnotation),
@@ -1817,6 +1827,7 @@
1817
1827
  this.runId = 0;
1818
1828
  this.mobxGuid = 0;
1819
1829
  this.inBatch = 0;
1830
+ this.batchId = Number.MIN_SAFE_INTEGER;
1820
1831
  this.pendingUnobservations = [];
1821
1832
  this.pendingReactions = [];
1822
1833
  this.isRunningReactions = false;
@@ -1956,6 +1967,9 @@
1956
1967
  * Avoids unnecessary recalculations.
1957
1968
  */
1958
1969
  function startBatch() {
1970
+ if (globalState.inBatch === 0) {
1971
+ globalState.batchId = globalState.batchId < Number.MAX_SAFE_INTEGER ? globalState.batchId + 1 : Number.MIN_SAFE_INTEGER;
1972
+ }
1959
1973
  globalState.inBatch++;
1960
1974
  }
1961
1975
  function endBatch() {
@@ -2248,10 +2262,15 @@
2248
2262
  }
2249
2263
  }
2250
2264
  };
2251
- _proto.getDisposer_ = function getDisposer_() {
2252
- var r = this.dispose.bind(this);
2253
- r[$mobx] = this;
2254
- return r;
2265
+ _proto.getDisposer_ = function getDisposer_(abortSignal) {
2266
+ var _this2 = this;
2267
+ var dispose = function dispose() {
2268
+ _this2.dispose();
2269
+ abortSignal == null ? void 0 : abortSignal.removeEventListener == null ? void 0 : abortSignal.removeEventListener("abort", dispose);
2270
+ };
2271
+ abortSignal == null ? void 0 : abortSignal.addEventListener == null ? void 0 : abortSignal.addEventListener("abort", dispose);
2272
+ dispose[$mobx] = this;
2273
+ return dispose;
2255
2274
  };
2256
2275
  _proto.toString = function toString() {
2257
2276
  return "Reaction[" + this.name_ + "]";
@@ -2425,7 +2444,7 @@
2425
2444
  * @returns disposer function, which can be used to stop the view from being updated in the future.
2426
2445
  */
2427
2446
  function autorun(view, opts) {
2428
- var _opts$name, _opts;
2447
+ var _opts$name, _opts, _opts2, _opts2$signal, _opts3;
2429
2448
  if (opts === void 0) {
2430
2449
  opts = EMPTY_OBJECT;
2431
2450
  }
@@ -2464,8 +2483,10 @@
2464
2483
  function reactionRunner() {
2465
2484
  view(reaction);
2466
2485
  }
2467
- reaction.schedule_();
2468
- return reaction.getDisposer_();
2486
+ if (!((_opts2 = opts) != null && (_opts2$signal = _opts2.signal) != null && _opts2$signal.aborted)) {
2487
+ reaction.schedule_();
2488
+ }
2489
+ return reaction.getDisposer_((_opts3 = opts) == null ? void 0 : _opts3.signal);
2469
2490
  }
2470
2491
  var run = function run(f) {
2471
2492
  return f();
@@ -2476,7 +2497,7 @@
2476
2497
  } : run;
2477
2498
  }
2478
2499
  function reaction(expression, effect, opts) {
2479
- var _opts$name2;
2500
+ var _opts$name2, _opts4, _opts4$signal, _opts5;
2480
2501
  if (opts === void 0) {
2481
2502
  opts = EMPTY_OBJECT;
2482
2503
  }
@@ -2526,8 +2547,10 @@
2526
2547
  }
2527
2548
  firstTime = false;
2528
2549
  }
2529
- r.schedule_();
2530
- return r.getDisposer_();
2550
+ if (!((_opts4 = opts) != null && (_opts4$signal = _opts4.signal) != null && _opts4$signal.aborted)) {
2551
+ r.schedule_();
2552
+ }
2553
+ return r.getDisposer_((_opts5 = opts) == null ? void 0 : _opts5.signal);
2531
2554
  }
2532
2555
  function wrapErrorHandler(errorHandler, baseFn) {
2533
2556
  return function () {
@@ -2622,17 +2645,14 @@
2622
2645
  }
2623
2646
  // Pull descriptors first, so we don't have to deal with props added by administration ($mobx)
2624
2647
  var descriptors = getOwnPropertyDescriptors(properties);
2625
- var adm = asObservableObject(target, options)[$mobx];
2626
- startBatch();
2627
- try {
2648
+ initObservable(function () {
2649
+ var adm = asObservableObject(target, options)[$mobx];
2628
2650
  ownKeys(descriptors).forEach(function (key) {
2629
2651
  adm.extend_(key, descriptors[key],
2630
2652
  // must pass "undefined" for { key: undefined }
2631
2653
  !annotations ? true : key in annotations ? annotations[key] : true);
2632
2654
  });
2633
- } finally {
2634
- endBatch();
2635
- }
2655
+ });
2636
2656
  return target;
2637
2657
  }
2638
2658
 
@@ -3318,10 +3338,9 @@
3318
3338
  }
3319
3339
 
3320
3340
  function makeObservable(target, annotations, options) {
3321
- var adm = asObservableObject(target, options)[$mobx];
3322
- startBatch();
3323
- try {
3341
+ initObservable(function () {
3324
3342
  var _annotations;
3343
+ var adm = asObservableObject(target, options)[$mobx];
3325
3344
  if ("development" !== "production" && annotations && target[storedAnnotationsSymbol]) {
3326
3345
  die("makeObservable second arg must be nullish when using decorators. Mixing @decorator syntax with annotations is not supported.");
3327
3346
  }
@@ -3331,9 +3350,7 @@
3331
3350
  ownKeys(annotations).forEach(function (key) {
3332
3351
  return adm.make_(key, annotations[key]);
3333
3352
  });
3334
- } finally {
3335
- endBatch();
3336
- }
3353
+ });
3337
3354
  return target;
3338
3355
  }
3339
3356
  // proto[keysSymbol] = new Set<PropertyKey>()
@@ -3352,26 +3369,23 @@
3352
3369
  if (isPlainObject(target)) {
3353
3370
  return extendObservable(target, target, overrides, options);
3354
3371
  }
3355
- var adm = asObservableObject(target, options)[$mobx];
3356
- // Optimization: cache keys on proto
3357
- // Assumes makeAutoObservable can be called only once per object and can't be used in subclass
3358
- if (!target[keysSymbol]) {
3359
- var proto = Object.getPrototypeOf(target);
3360
- var keys = new Set([].concat(ownKeys(target), ownKeys(proto)));
3361
- keys["delete"]("constructor");
3362
- keys["delete"]($mobx);
3363
- addHiddenProp(proto, keysSymbol, keys);
3364
- }
3365
- startBatch();
3366
- try {
3372
+ initObservable(function () {
3373
+ var adm = asObservableObject(target, options)[$mobx];
3374
+ // Optimization: cache keys on proto
3375
+ // Assumes makeAutoObservable can be called only once per object and can't be used in subclass
3376
+ if (!target[keysSymbol]) {
3377
+ var proto = Object.getPrototypeOf(target);
3378
+ var keys = new Set([].concat(ownKeys(target), ownKeys(proto)));
3379
+ keys["delete"]("constructor");
3380
+ keys["delete"]($mobx);
3381
+ addHiddenProp(proto, keysSymbol, keys);
3382
+ }
3367
3383
  target[keysSymbol].forEach(function (key) {
3368
3384
  return adm.make_(key,
3369
3385
  // must pass "undefined" for { key: undefined }
3370
3386
  !overrides ? true : key in overrides ? overrides[key] : true);
3371
3387
  });
3372
- } finally {
3373
- endBatch();
3374
- }
3388
+ });
3375
3389
  return target;
3376
3390
  }
3377
3391
 
@@ -3679,16 +3693,16 @@
3679
3693
  owned = false;
3680
3694
  }
3681
3695
  assertProxies();
3682
- var adm = new ObservableArrayAdministration(name, enhancer, owned, false);
3683
- addHiddenFinalProp(adm.values_, $mobx, adm);
3684
- var proxy = new Proxy(adm.values_, arrayTraps);
3685
- adm.proxy_ = proxy;
3686
- if (initialValues && initialValues.length) {
3687
- var prev = allowStateChangesStart(true);
3688
- adm.spliceWithArray_(0, 0, initialValues);
3689
- allowStateChangesEnd(prev);
3690
- }
3691
- return proxy;
3696
+ return initObservable(function () {
3697
+ var adm = new ObservableArrayAdministration(name, enhancer, owned, false);
3698
+ addHiddenFinalProp(adm.values_, $mobx, adm);
3699
+ var proxy = new Proxy(adm.values_, arrayTraps);
3700
+ adm.proxy_ = proxy;
3701
+ if (initialValues && initialValues.length) {
3702
+ adm.spliceWithArray_(0, 0, initialValues);
3703
+ }
3704
+ return proxy;
3705
+ });
3692
3706
  }
3693
3707
  // eslint-disable-next-line
3694
3708
  var arrayExtensions = {
@@ -3884,11 +3898,13 @@
3884
3898
  if (!isFunction(Map)) {
3885
3899
  die(18);
3886
3900
  }
3887
- this.keysAtom_ = createAtom( this.name_ + ".keys()" );
3888
- this.data_ = new Map();
3889
- this.hasMap_ = new Map();
3890
- allowStateChanges(true, function () {
3891
- _this.merge(initialData);
3901
+ initObservable(function () {
3902
+ _this.keysAtom_ = createAtom("development" !== "production" ? _this.name_ + ".keys()" : "ObservableMap.keys()");
3903
+ _this.data_ = new Map();
3904
+ _this.hasMap_ = new Map();
3905
+ if (initialData) {
3906
+ _this.merge(initialData);
3907
+ }
3892
3908
  });
3893
3909
  }
3894
3910
  var _proto = ObservableMap.prototype;
@@ -4272,6 +4288,7 @@
4272
4288
  _Symbol$toStringTag$1 = Symbol.toStringTag;
4273
4289
  var ObservableSet = /*#__PURE__*/function () {
4274
4290
  function ObservableSet(initialData, enhancer, name_) {
4291
+ var _this = this;
4275
4292
  if (enhancer === void 0) {
4276
4293
  enhancer = deepEnhancer;
4277
4294
  }
@@ -4290,13 +4307,15 @@
4290
4307
  if (!isFunction(Set)) {
4291
4308
  die(22);
4292
4309
  }
4293
- this.atom_ = createAtom(this.name_);
4294
4310
  this.enhancer_ = function (newV, oldV) {
4295
4311
  return enhancer(newV, oldV, name_);
4296
4312
  };
4297
- if (initialData) {
4298
- this.replace(initialData);
4299
- }
4313
+ initObservable(function () {
4314
+ _this.atom_ = createAtom(_this.name_);
4315
+ if (initialData) {
4316
+ _this.replace(initialData);
4317
+ }
4318
+ });
4300
4319
  }
4301
4320
  var _proto = ObservableSet.prototype;
4302
4321
  _proto.dehanceValue_ = function dehanceValue_(value) {
@@ -4306,12 +4325,12 @@
4306
4325
  return value;
4307
4326
  };
4308
4327
  _proto.clear = function clear() {
4309
- var _this = this;
4328
+ var _this2 = this;
4310
4329
  transaction(function () {
4311
4330
  untracked(function () {
4312
- for (var _iterator = _createForOfIteratorHelperLoose(_this.data_.values()), _step; !(_step = _iterator()).done;) {
4331
+ for (var _iterator = _createForOfIteratorHelperLoose(_this2.data_.values()), _step; !(_step = _iterator()).done;) {
4313
4332
  var value = _step.value;
4314
- _this["delete"](value);
4333
+ _this2["delete"](value);
4315
4334
  }
4316
4335
  });
4317
4336
  });
@@ -4323,7 +4342,7 @@
4323
4342
  }
4324
4343
  };
4325
4344
  _proto.add = function add(value) {
4326
- var _this2 = this;
4345
+ var _this3 = this;
4327
4346
  checkIfStateModificationsAreAllowed(this.atom_);
4328
4347
  if (hasInterceptors(this)) {
4329
4348
  var change = interceptChange(this, {
@@ -4340,8 +4359,8 @@
4340
4359
 
4341
4360
  if (!this.has(value)) {
4342
4361
  transaction(function () {
4343
- _this2.data_.add(_this2.enhancer_(value, undefined));
4344
- _this2.atom_.reportChanged();
4362
+ _this3.data_.add(_this3.enhancer_(value, undefined));
4363
+ _this3.atom_.reportChanged();
4345
4364
  });
4346
4365
  var notifySpy = isSpyEnabled();
4347
4366
  var notify = hasListeners(this);
@@ -4365,7 +4384,7 @@
4365
4384
  return this;
4366
4385
  };
4367
4386
  _proto["delete"] = function _delete(value) {
4368
- var _this3 = this;
4387
+ var _this4 = this;
4369
4388
  if (hasInterceptors(this)) {
4370
4389
  var change = interceptChange(this, {
4371
4390
  type: DELETE,
@@ -4390,8 +4409,8 @@
4390
4409
  spyReportStart(_change2);
4391
4410
  }
4392
4411
  transaction(function () {
4393
- _this3.atom_.reportChanged();
4394
- _this3.data_["delete"](value);
4412
+ _this4.atom_.reportChanged();
4413
+ _this4.data_["delete"](value);
4395
4414
  });
4396
4415
  if (notify) {
4397
4416
  notifyListeners(this, _change2);
@@ -4444,20 +4463,20 @@
4444
4463
  });
4445
4464
  };
4446
4465
  _proto.replace = function replace(other) {
4447
- var _this4 = this;
4466
+ var _this5 = this;
4448
4467
  if (isObservableSet(other)) {
4449
4468
  other = new Set(other);
4450
4469
  }
4451
4470
  transaction(function () {
4452
4471
  if (Array.isArray(other)) {
4453
- _this4.clear();
4472
+ _this5.clear();
4454
4473
  other.forEach(function (value) {
4455
- return _this4.add(value);
4474
+ return _this5.add(value);
4456
4475
  });
4457
4476
  } else if (isES6Set(other)) {
4458
- _this4.clear();
4477
+ _this5.clear();
4459
4478
  other.forEach(function (value) {
4460
- return _this4.add(value);
4479
+ return _this5.add(value);
4461
4480
  });
4462
4481
  } else if (other !== null && other !== undefined) {
4463
4482
  die("Cannot initialize set from " + other);
@@ -4721,6 +4740,7 @@
4721
4740
  if (proxyTrap === void 0) {
4722
4741
  proxyTrap = false;
4723
4742
  }
4743
+ checkIfStateModificationsAreAllowed(this.keysAtom_);
4724
4744
  try {
4725
4745
  startBatch();
4726
4746
  // Delete
@@ -4768,6 +4788,7 @@
4768
4788
  if (proxyTrap === void 0) {
4769
4789
  proxyTrap = false;
4770
4790
  }
4791
+ checkIfStateModificationsAreAllowed(this.keysAtom_);
4771
4792
  try {
4772
4793
  startBatch();
4773
4794
  // Delete
@@ -4819,6 +4840,7 @@
4819
4840
  if (proxyTrap === void 0) {
4820
4841
  proxyTrap = false;
4821
4842
  }
4843
+ checkIfStateModificationsAreAllowed(this.keysAtom_);
4822
4844
  try {
4823
4845
  startBatch();
4824
4846
  // Delete
@@ -4874,6 +4896,7 @@
4874
4896
  if (proxyTrap === void 0) {
4875
4897
  proxyTrap = false;
4876
4898
  }
4899
+ checkIfStateModificationsAreAllowed(this.keysAtom_);
4877
4900
  // No such prop
4878
4901
  if (!hasProp(this.target_, key)) {
4879
4902
  return true;
@@ -5103,6 +5126,17 @@
5103
5126
 
5104
5127
  // Bug in safari 9.* (or iOS 9 safari mobile). See #364
5105
5128
  var ENTRY_0 = /*#__PURE__*/createArrayEntryDescriptor(0);
5129
+ var safariPrototypeSetterInheritanceBug = /*#__PURE__*/function () {
5130
+ var v = false;
5131
+ var p = {};
5132
+ Object.defineProperty(p, "0", {
5133
+ set: function set() {
5134
+ v = true;
5135
+ }
5136
+ });
5137
+ /*#__PURE__*/Object.create(p)["0"] = 1;
5138
+ return v === false;
5139
+ }();
5106
5140
  /**
5107
5141
  * This array buffer contains two lists of properties, so that all arrays
5108
5142
  * can recycle their property definitions, which significantly improves performance of creating
@@ -5135,20 +5169,20 @@
5135
5169
  owned = false;
5136
5170
  }
5137
5171
  _this = _StubArray.call(this) || this;
5138
- var adm = new ObservableArrayAdministration(name, enhancer, owned, true);
5139
- adm.proxy_ = _assertThisInitialized(_this);
5140
- addHiddenFinalProp(_assertThisInitialized(_this), $mobx, adm);
5141
- if (initialValues && initialValues.length) {
5142
- var prev = allowStateChangesStart(true);
5143
- // @ts-ignore
5144
- _this.spliceWithArray(0, 0, initialValues);
5145
- allowStateChangesEnd(prev);
5146
- }
5147
- {
5148
- // Seems that Safari won't use numeric prototype setter untill any * numeric property is
5149
- // defined on the instance. After that it works fine, even if this property is deleted.
5150
- Object.defineProperty(_assertThisInitialized(_this), "0", ENTRY_0);
5151
- }
5172
+ initObservable(function () {
5173
+ var adm = new ObservableArrayAdministration(name, enhancer, owned, true);
5174
+ adm.proxy_ = _assertThisInitialized(_this);
5175
+ addHiddenFinalProp(_assertThisInitialized(_this), $mobx, adm);
5176
+ if (initialValues && initialValues.length) {
5177
+ // @ts-ignore
5178
+ _this.spliceWithArray(0, 0, initialValues);
5179
+ }
5180
+ if (safariPrototypeSetterInheritanceBug) {
5181
+ // Seems that Safari won't use numeric prototype setter untill any * numeric property is
5182
+ // defined on the instance. After that it works fine, even if this property is deleted.
5183
+ Object.defineProperty(_assertThisInitialized(_this), "0", ENTRY_0);
5184
+ }
5185
+ });
5152
5186
  return _this;
5153
5187
  }
5154
5188
  var _proto = LegacyObservableArray.prototype;
@@ -5303,6 +5337,24 @@
5303
5337
  }
5304
5338
  return named.name_;
5305
5339
  }
5340
+ /**
5341
+ * Helper function for initializing observable structures, it applies:
5342
+ * 1. allowStateChanges so we don't violate enforceActions.
5343
+ * 2. untracked so we don't accidentaly subscribe to anything observable accessed during init in case the observable is created inside derivation.
5344
+ * 3. batch to avoid state version updates
5345
+ */
5346
+ function initObservable(cb) {
5347
+ var derivation = untrackedStart();
5348
+ var allowStateChanges = allowStateChangesStart(true);
5349
+ startBatch();
5350
+ try {
5351
+ return cb();
5352
+ } finally {
5353
+ endBatch();
5354
+ allowStateChangesEnd(allowStateChanges);
5355
+ untrackedEnd(derivation);
5356
+ }
5357
+ }
5306
5358
 
5307
5359
  var toString = objectPrototype.toString;
5308
5360
  function deepEqual(a, b, depth) {