mobx 6.15.4 → 6.16.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # mobx
2
2
 
3
+ ## 6.16.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`7fd93348e81f484c4ec2dcca8cde5fa6ed7412fe`](https://github.com/mobxjs/mobx/commit/7fd93348e81f484c4ec2dcca8cde5fa6ed7412fe) [#4661](https://github.com/mobxjs/mobx/pull/4661) Thanks [@js2me](https://github.com/js2me)! - Fix Stage 3 `@computed` overrides that delegate to a same-named parent getter via `super`.
8
+
9
+ - [`02afa5b6c33441737df81d344161a03bb9aea0c8`](https://github.com/mobxjs/mobx/commit/02afa5b6c33441737df81d344161a03bb9aea0c8) [#4666](https://github.com/mobxjs/mobx/pull/4666) Thanks [@kubk](https://github.com/kubk)! - Remove outdated Flow typechecker support artifacts from the package.
10
+
11
+ ## 6.16.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [`6b3fb0ee725c0521bbaf7ba901a30261472a0e71`](https://github.com/mobxjs/mobx/commit/6b3fb0ee725c0521bbaf7ba901a30261472a0e71) [#4639](https://github.com/mobxjs/mobx/pull/4639) Thanks [@ashishkr96](https://github.com/ashishkr96)! - feat(mobx): make the 2022.3 `@computed` decorator lazy. `ComputedValue` is now created on first read of the decorated getter rather than eagerly during instance construction, avoiding wasted allocations for getters that are never used. On a 50k-instance × 10-getter class with one read per instance this cuts construction heap by ~50% and construction time by ~25%; the steady-state read path is unchanged. Closes #4616.
16
+
17
+ - [`f0c68749428fd4d3bba48e9685e44fd1ddbbee76`](https://github.com/mobxjs/mobx/commit/f0c68749428fd4d3bba48e9685e44fd1ddbbee76) [#4658](https://github.com/mobxjs/mobx/pull/4658) Thanks [@ashishkr96](https://github.com/ashishkr96)! - feat(mobx): make the 2022.3 `@observable accessor` decorator lazy. `ObservableValue` is now created on first read/write/observe of the decorated accessor rather than eagerly during instance construction, avoiding wasted allocations for fields that are never touched. On a 50k-instance × 10-field class with sparse access (1 of 10 fields read per instance), this cuts construction heap by ~82% and construction time by ~86% versus the eager path. Follow-up to #4639.
18
+
19
+ ### Patch Changes
20
+
21
+ - [`7eb54418b16fb9b415c04c5b8e05779790dd74ed`](https://github.com/mobxjs/mobx/commit/7eb54418b16fb9b415c04c5b8e05779790dd74ed) [#4659](https://github.com/mobxjs/mobx/pull/4659) Thanks [@kubk](https://github.com/kubk)! - Fix regression from #4639 where isComputedProp returned false for lazy @computed properties before first read
22
+
23
+ - [`c22b4b705447a4ccdce93473255f4beb170613f3`](https://github.com/mobxjs/mobx/commit/c22b4b705447a4ccdce93473255f4beb170613f3) [#4657](https://github.com/mobxjs/mobx/pull/4657) Thanks [@kubk](https://github.com/kubk)! - Add `getOrInsert` and `getOrInsertComputed` to `ObservableMap` for compatibility with ESNext `Map` typings.
24
+
3
25
  ## 6.15.4
4
26
 
5
27
  ### Patch Changes
@@ -945,17 +945,44 @@ function decorate_20223_$3(get, context) {
945
945
  var ann = this;
946
946
  var key = context.name,
947
947
  addInitializer = context.addInitializer;
948
- addInitializer(function () {
949
- var adm = asObservableObject(this)[$mobx];
948
+ var computedValues;
949
+ // Defer ComputedValue creation until first access — avoids allocating
950
+ // ComputedValues for getters that are never read on a given instance.
951
+ // The factory is materialised by ObservableObjectAdministration on demand.
952
+ function createComputedValue(target, adm) {
950
953
  var options = _extends({}, ann.options_, {
951
954
  get: get,
952
- context: this
955
+ context: target
953
956
  });
954
957
  options.name || (options.name = adm.name_ + "." + key.toString() );
955
- adm.values_.set(key, new ComputedValue(options));
958
+ return new ComputedValue(options);
959
+ }
960
+ addInitializer(function () {
961
+ var _adm$lazyComputedKeys;
962
+ var adm = asObservableObject(this)[$mobx];
963
+ var target = this;
964
+ var observable = adm.values_.get(key);
965
+ if (observable instanceof ComputedValue && observable.derivation !== get) {
966
+ adm.values_["delete"](key);
967
+ }
968
+ ((_adm$lazyComputedKeys = adm.lazyComputedKeys_) != null ? _adm$lazyComputedKeys : adm.lazyComputedKeys_ = new Map()).set(key, function () {
969
+ return createComputedValue(target, adm);
970
+ });
956
971
  });
957
972
  return function () {
958
- return this[$mobx].getObservablePropValue_(key);
973
+ var adm = this[$mobx];
974
+ var observable = adm.values_.get(key);
975
+ if (observable instanceof ComputedValue && observable.derivation !== get) {
976
+ var _computedValues;
977
+ var computed = (_computedValues = computedValues) == null ? void 0 : _computedValues.get(this);
978
+ if (!computed) {
979
+ var _computedValues2;
980
+ computed = createComputedValue(this, adm);
981
+ ((_computedValues2 = computedValues) != null ? _computedValues2 : computedValues = new WeakMap()).set(this, computed);
982
+ }
983
+ return computed.get();
984
+ }
985
+ return adm.getObservablePropValue_(key);
959
986
  };
960
987
  }
961
988
  function assertComputedDescriptor(adm, _ref, key, _ref2) {
@@ -993,44 +1020,37 @@ function decorate_20223_$4(desc, context) {
993
1020
  var ann = this;
994
1021
  var kind = context.kind,
995
1022
  name = context.name;
996
- // The laziness here is not ideal... It's a workaround to how 2022.3 Decorators are implemented:
997
- // `addInitializer` callbacks are executed _before_ any accessors are defined (instead of the ideal-for-us right after each).
998
- // This means that, if we were to do our stuff in an `addInitializer`, we'd attempt to read a private slot
999
- // before it has been initialized. The runtime doesn't like that and throws a `Cannot read private member
1000
- // from an object whose class did not declare it` error.
1001
- // TODO: it seems that this will not be required anymore in the final version of the spec
1002
- // See TODO: link
1003
- var initializedObjects = new WeakSet();
1004
- function initializeObservable(target, value) {
1005
- var _ann$options_$enhance, _ann$options_;
1023
+ if (kind !== "accessor") {
1024
+ return;
1025
+ }
1026
+ // Defer ObservableValue construction until first access. The factory is
1027
+ // materialised by ObservableObjectAdministration on demand, so unused
1028
+ // fields on wide classes never pay the per-instance allocation cost.
1029
+ function registerLazy(target, value) {
1030
+ var _adm$lazyObservableKe;
1006
1031
  var adm = asObservableObject(target)[$mobx];
1007
- var observable = new ObservableValue(value, (_ann$options_$enhance = (_ann$options_ = ann.options_) == null ? void 0 : _ann$options_.enhancer) != null ? _ann$options_$enhance : deepEnhancer, adm.name_ + "." + name.toString() , false);
1008
- adm.values_.set(name, observable);
1009
- initializedObjects.add(target);
1010
- }
1011
- if (kind == "accessor") {
1012
- return {
1013
- get: function get() {
1014
- if (!initializedObjects.has(this)) {
1015
- initializeObservable(this, desc.get.call(this));
1016
- }
1017
- return this[$mobx].getObservablePropValue_(name);
1018
- },
1019
- set: function set(value) {
1020
- if (!initializedObjects.has(this)) {
1021
- initializeObservable(this, value);
1022
- }
1023
- return this[$mobx].setObservablePropValue_(name, value);
1024
- },
1025
- init: function init(value) {
1026
- if (!initializedObjects.has(this)) {
1027
- initializeObservable(this, value);
1028
- }
1029
- return value;
1030
- }
1031
- };
1032
+ ((_adm$lazyObservableKe = adm.lazyObservableKeys_) != null ? _adm$lazyObservableKe : adm.lazyObservableKeys_ = new Map()).set(name, function () {
1033
+ var _ann$options_$enhance, _ann$options_;
1034
+ return new ObservableValue(value, (_ann$options_$enhance = (_ann$options_ = ann.options_) == null ? void 0 : _ann$options_.enhancer) != null ? _ann$options_$enhance : deepEnhancer, adm.name_ + "." + name.toString() , false);
1035
+ });
1036
+ return adm;
1032
1037
  }
1033
- return;
1038
+ return {
1039
+ get: function get() {
1040
+ var _this$$mobx;
1041
+ var adm = (_this$$mobx = this[$mobx]) != null ? _this$$mobx : registerLazy(this, desc.get.call(this));
1042
+ return adm.getObservablePropValue_(name);
1043
+ },
1044
+ set: function set(value) {
1045
+ var _this$$mobx2;
1046
+ var adm = (_this$$mobx2 = this[$mobx]) != null ? _this$$mobx2 : registerLazy(this, value);
1047
+ return adm.setObservablePropValue_(name, value);
1048
+ },
1049
+ init: function init(value) {
1050
+ registerLazy(this, value);
1051
+ return value;
1052
+ }
1053
+ };
1034
1054
  }
1035
1055
  function assertObservableDescriptor(adm, _ref, key, descriptor) {
1036
1056
  var annotationType_ = _ref.annotationType_;
@@ -3218,13 +3238,18 @@ function interceptProperty(thing, property, handler) {
3218
3238
  }
3219
3239
 
3220
3240
  function _isComputed(value, property) {
3241
+ var _adm$lazyComputedKeys;
3221
3242
  if (property === undefined) {
3222
3243
  return isComputedValue(value);
3223
3244
  }
3224
3245
  if (isObservableObject(value) === false) {
3225
3246
  return false;
3226
3247
  }
3227
- if (!value[$mobx].values_.has(property)) {
3248
+ var adm = value[$mobx];
3249
+ if ((_adm$lazyComputedKeys = adm.lazyComputedKeys_) != null && _adm$lazyComputedKeys.has(property)) {
3250
+ return true;
3251
+ }
3252
+ if (!adm.values_.has(property)) {
3228
3253
  return false;
3229
3254
  }
3230
3255
  var atom = getAtom(value, property);
@@ -3252,7 +3277,9 @@ function _isObservable(value, property) {
3252
3277
  return die("isObservable(object, propertyName) is not supported for arrays and maps. Use map.has or array.length instead.");
3253
3278
  }
3254
3279
  if (isObservableObject(value)) {
3255
- return value[$mobx].values_.has(property);
3280
+ var _adm$lazyComputedKeys, _adm$lazyObservableKe;
3281
+ var adm = value[$mobx];
3282
+ return adm.values_.has(property) || !!((_adm$lazyComputedKeys = adm.lazyComputedKeys_) != null && _adm$lazyComputedKeys.has(property)) || !!((_adm$lazyObservableKe = adm.lazyObservableKeys_) != null && _adm$lazyObservableKe.has(property));
3256
3283
  }
3257
3284
  return false;
3258
3285
  }
@@ -4450,6 +4477,18 @@ var ObservableMap = /*#__PURE__*/function () {
4450
4477
  }
4451
4478
  return this.dehanceValue_(undefined);
4452
4479
  };
4480
+ _proto.getOrInsert = function getOrInsert(key, value) {
4481
+ if (!this.has(key)) {
4482
+ this.set(key, value);
4483
+ }
4484
+ return this.get(key);
4485
+ };
4486
+ _proto.getOrInsertComputed = function getOrInsertComputed(key, callback) {
4487
+ if (!this.has(key)) {
4488
+ this.set(key, callback(key));
4489
+ }
4490
+ return this.get(key);
4491
+ };
4453
4492
  _proto.dehanceValue_ = function dehanceValue_(value) {
4454
4493
  if (this.dehancer !== undefined) {
4455
4494
  return this.dehancer(value);
@@ -4983,6 +5022,8 @@ var ObservableObjectAdministration = /*#__PURE__*/function () {
4983
5022
  this.isPlainObject_ = void 0;
4984
5023
  this.appliedAnnotations_ = void 0;
4985
5024
  this.pendingKeys_ = void 0;
5025
+ this.lazyComputedKeys_ = void 0;
5026
+ this.lazyObservableKeys_ = void 0;
4986
5027
  this.target_ = target_;
4987
5028
  this.values_ = values_;
4988
5029
  this.name_ = name_;
@@ -5000,10 +5041,42 @@ var ObservableObjectAdministration = /*#__PURE__*/function () {
5000
5041
  }
5001
5042
  var _proto = ObservableObjectAdministration.prototype;
5002
5043
  _proto.getObservablePropValue_ = function getObservablePropValue_(key) {
5003
- return this.values_.get(key).get();
5044
+ var _ref, _this$values_$get;
5045
+ // Hot path: single map lookup. Lazy entries (rare) take the materialise branch.
5046
+ var observable = (_ref = (_this$values_$get = this.values_.get(key)) != null ? _this$values_$get : this.materializeLazyComputed_(key)) != null ? _ref : this.materializeLazyObservable_(key);
5047
+ return observable.get();
5048
+ };
5049
+ _proto.materializeLazyComputed_ = function materializeLazyComputed_(key) {
5050
+ var _this$lazyComputedKey;
5051
+ var factory = (_this$lazyComputedKey = this.lazyComputedKeys_) == null ? void 0 : _this$lazyComputedKey.get(key);
5052
+ if (!factory) {
5053
+ return undefined;
5054
+ }
5055
+ this.lazyComputedKeys_["delete"](key);
5056
+ if (this.lazyComputedKeys_.size === 0) {
5057
+ this.lazyComputedKeys_ = undefined;
5058
+ }
5059
+ var computed = factory();
5060
+ this.values_.set(key, computed);
5061
+ return computed;
5062
+ };
5063
+ _proto.materializeLazyObservable_ = function materializeLazyObservable_(key) {
5064
+ var _this$lazyObservableK;
5065
+ var factory = (_this$lazyObservableK = this.lazyObservableKeys_) == null ? void 0 : _this$lazyObservableK.get(key);
5066
+ if (!factory) {
5067
+ return undefined;
5068
+ }
5069
+ this.lazyObservableKeys_["delete"](key);
5070
+ if (this.lazyObservableKeys_.size === 0) {
5071
+ this.lazyObservableKeys_ = undefined;
5072
+ }
5073
+ var observable = factory();
5074
+ this.values_.set(key, observable);
5075
+ return observable;
5004
5076
  };
5005
5077
  _proto.setObservablePropValue_ = function setObservablePropValue_(key, newValue) {
5006
- var observable = this.values_.get(key);
5078
+ var _ref2, _this$values_$get2;
5079
+ var observable = (_ref2 = (_this$values_$get2 = this.values_.get(key)) != null ? _this$values_$get2 : this.materializeLazyComputed_(key)) != null ? _ref2 : this.materializeLazyObservable_(key);
5007
5080
  if (observable instanceof ComputedValue) {
5008
5081
  observable.set(newValue);
5009
5082
  return true;
@@ -5724,10 +5797,12 @@ function getAtom(thing, property) {
5724
5797
  return observable;
5725
5798
  }
5726
5799
  if (isObservableObject(thing)) {
5800
+ var _ref, _adm$values_$get;
5727
5801
  if (!property) {
5728
5802
  return die(26);
5729
5803
  }
5730
- var _observable = thing[$mobx].values_.get(property);
5804
+ var adm = thing[$mobx];
5805
+ var _observable = (_ref = (_adm$values_$get = adm.values_.get(property)) != null ? _adm$values_$get : adm.materializeLazyComputed_(property)) != null ? _ref : adm.materializeLazyObservable_(property);
5731
5806
  if (!_observable) {
5732
5807
  die(27, property, getDebugName(thing));
5733
5808
  }