mobx 6.15.3 → 6.16.0

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,25 @@
1
1
  # mobx
2
2
 
3
+ ## 6.16.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`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.
8
+
9
+ - [`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.
10
+
11
+ ### Patch Changes
12
+
13
+ - [`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
14
+
15
+ - [`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.
16
+
17
+ ## 6.15.4
18
+
19
+ ### Patch Changes
20
+
21
+ - [`105c985c71308e439bfeed118fb1ba1eac06824e`](https://github.com/mobxjs/mobx/commit/105c985c71308e439bfeed118fb1ba1eac06824e) [#4650](https://github.com/mobxjs/mobx/pull/4650) Thanks [@kubk](https://github.com/kubk)! - Avoid Rolldown invalid PURE annotation warnings from Babel-generated optional chaining output.
22
+
3
23
  ## 6.15.3
4
24
 
5
25
  ### Patch Changes
@@ -945,14 +945,21 @@ function decorate_20223_$3(get, context) {
945
945
  var ann = this;
946
946
  var key = context.name,
947
947
  addInitializer = context.addInitializer;
948
+ // Defer ComputedValue creation until first access — avoids allocating
949
+ // ComputedValues for getters that are never read on a given instance.
950
+ // The factory is materialised by ObservableObjectAdministration on demand.
948
951
  addInitializer(function () {
952
+ var _adm$lazyComputedKeys;
949
953
  var adm = asObservableObject(this)[$mobx];
950
- var options = _extends({}, ann.options_, {
951
- get: get,
952
- context: this
954
+ var target = this;
955
+ ((_adm$lazyComputedKeys = adm.lazyComputedKeys_) != null ? _adm$lazyComputedKeys : adm.lazyComputedKeys_ = new Map()).set(key, function () {
956
+ var options = _extends({}, ann.options_, {
957
+ get: get,
958
+ context: target
959
+ });
960
+ options.name || (options.name = adm.name_ + "." + key.toString() );
961
+ return new ComputedValue(options);
953
962
  });
954
- options.name || (options.name = adm.name_ + "." + key.toString() );
955
- adm.values_.set(key, new ComputedValue(options));
956
963
  });
957
964
  return function () {
958
965
  return this[$mobx].getObservablePropValue_(key);
@@ -993,44 +1000,37 @@ function decorate_20223_$4(desc, context) {
993
1000
  var ann = this;
994
1001
  var kind = context.kind,
995
1002
  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_;
1003
+ if (kind !== "accessor") {
1004
+ return;
1005
+ }
1006
+ // Defer ObservableValue construction until first access. The factory is
1007
+ // materialised by ObservableObjectAdministration on demand, so unused
1008
+ // fields on wide classes never pay the per-instance allocation cost.
1009
+ function registerLazy(target, value) {
1010
+ var _adm$lazyObservableKe;
1006
1011
  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
- };
1012
+ ((_adm$lazyObservableKe = adm.lazyObservableKeys_) != null ? _adm$lazyObservableKe : adm.lazyObservableKeys_ = new Map()).set(name, function () {
1013
+ var _ann$options_$enhance, _ann$options_;
1014
+ 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);
1015
+ });
1016
+ return adm;
1032
1017
  }
1033
- return;
1018
+ return {
1019
+ get: function get() {
1020
+ var _this$$mobx;
1021
+ var adm = (_this$$mobx = this[$mobx]) != null ? _this$$mobx : registerLazy(this, desc.get.call(this));
1022
+ return adm.getObservablePropValue_(name);
1023
+ },
1024
+ set: function set(value) {
1025
+ var _this$$mobx2;
1026
+ var adm = (_this$$mobx2 = this[$mobx]) != null ? _this$$mobx2 : registerLazy(this, value);
1027
+ return adm.setObservablePropValue_(name, value);
1028
+ },
1029
+ init: function init(value) {
1030
+ registerLazy(this, value);
1031
+ return value;
1032
+ }
1033
+ };
1034
1034
  }
1035
1035
  function assertObservableDescriptor(adm, _ref, key, descriptor) {
1036
1036
  var annotationType_ = _ref.annotationType_;
@@ -3218,13 +3218,18 @@ function interceptProperty(thing, property, handler) {
3218
3218
  }
3219
3219
 
3220
3220
  function _isComputed(value, property) {
3221
+ var _adm$lazyComputedKeys;
3221
3222
  if (property === undefined) {
3222
3223
  return isComputedValue(value);
3223
3224
  }
3224
3225
  if (isObservableObject(value) === false) {
3225
3226
  return false;
3226
3227
  }
3227
- if (!value[$mobx].values_.has(property)) {
3228
+ var adm = value[$mobx];
3229
+ if ((_adm$lazyComputedKeys = adm.lazyComputedKeys_) != null && _adm$lazyComputedKeys.has(property)) {
3230
+ return true;
3231
+ }
3232
+ if (!adm.values_.has(property)) {
3228
3233
  return false;
3229
3234
  }
3230
3235
  var atom = getAtom(value, property);
@@ -3252,7 +3257,9 @@ function _isObservable(value, property) {
3252
3257
  return die("isObservable(object, propertyName) is not supported for arrays and maps. Use map.has or array.length instead.");
3253
3258
  }
3254
3259
  if (isObservableObject(value)) {
3255
- return value[$mobx].values_.has(property);
3260
+ var _adm$lazyComputedKeys, _adm$lazyObservableKe;
3261
+ var adm = value[$mobx];
3262
+ return adm.values_.has(property) || !!((_adm$lazyComputedKeys = adm.lazyComputedKeys_) != null && _adm$lazyComputedKeys.has(property)) || !!((_adm$lazyObservableKe = adm.lazyObservableKeys_) != null && _adm$lazyObservableKe.has(property));
3256
3263
  }
3257
3264
  return false;
3258
3265
  }
@@ -4450,6 +4457,18 @@ var ObservableMap = /*#__PURE__*/function () {
4450
4457
  }
4451
4458
  return this.dehanceValue_(undefined);
4452
4459
  };
4460
+ _proto.getOrInsert = function getOrInsert(key, value) {
4461
+ if (!this.has(key)) {
4462
+ this.set(key, value);
4463
+ }
4464
+ return this.get(key);
4465
+ };
4466
+ _proto.getOrInsertComputed = function getOrInsertComputed(key, callback) {
4467
+ if (!this.has(key)) {
4468
+ this.set(key, callback(key));
4469
+ }
4470
+ return this.get(key);
4471
+ };
4453
4472
  _proto.dehanceValue_ = function dehanceValue_(value) {
4454
4473
  if (this.dehancer !== undefined) {
4455
4474
  return this.dehancer(value);
@@ -4983,6 +5002,8 @@ var ObservableObjectAdministration = /*#__PURE__*/function () {
4983
5002
  this.isPlainObject_ = void 0;
4984
5003
  this.appliedAnnotations_ = void 0;
4985
5004
  this.pendingKeys_ = void 0;
5005
+ this.lazyComputedKeys_ = void 0;
5006
+ this.lazyObservableKeys_ = void 0;
4986
5007
  this.target_ = target_;
4987
5008
  this.values_ = values_;
4988
5009
  this.name_ = name_;
@@ -5000,10 +5021,42 @@ var ObservableObjectAdministration = /*#__PURE__*/function () {
5000
5021
  }
5001
5022
  var _proto = ObservableObjectAdministration.prototype;
5002
5023
  _proto.getObservablePropValue_ = function getObservablePropValue_(key) {
5003
- return this.values_.get(key).get();
5024
+ var _ref, _this$values_$get;
5025
+ // Hot path: single map lookup. Lazy entries (rare) take the materialise branch.
5026
+ var observable = (_ref = (_this$values_$get = this.values_.get(key)) != null ? _this$values_$get : this.materializeLazyComputed_(key)) != null ? _ref : this.materializeLazyObservable_(key);
5027
+ return observable.get();
5028
+ };
5029
+ _proto.materializeLazyComputed_ = function materializeLazyComputed_(key) {
5030
+ var _this$lazyComputedKey;
5031
+ var factory = (_this$lazyComputedKey = this.lazyComputedKeys_) == null ? void 0 : _this$lazyComputedKey.get(key);
5032
+ if (!factory) {
5033
+ return undefined;
5034
+ }
5035
+ this.lazyComputedKeys_["delete"](key);
5036
+ if (this.lazyComputedKeys_.size === 0) {
5037
+ this.lazyComputedKeys_ = undefined;
5038
+ }
5039
+ var computed = factory();
5040
+ this.values_.set(key, computed);
5041
+ return computed;
5042
+ };
5043
+ _proto.materializeLazyObservable_ = function materializeLazyObservable_(key) {
5044
+ var _this$lazyObservableK;
5045
+ var factory = (_this$lazyObservableK = this.lazyObservableKeys_) == null ? void 0 : _this$lazyObservableK.get(key);
5046
+ if (!factory) {
5047
+ return undefined;
5048
+ }
5049
+ this.lazyObservableKeys_["delete"](key);
5050
+ if (this.lazyObservableKeys_.size === 0) {
5051
+ this.lazyObservableKeys_ = undefined;
5052
+ }
5053
+ var observable = factory();
5054
+ this.values_.set(key, observable);
5055
+ return observable;
5004
5056
  };
5005
5057
  _proto.setObservablePropValue_ = function setObservablePropValue_(key, newValue) {
5006
- var observable = this.values_.get(key);
5058
+ var _ref2, _this$values_$get2;
5059
+ var observable = (_ref2 = (_this$values_$get2 = this.values_.get(key)) != null ? _this$values_$get2 : this.materializeLazyComputed_(key)) != null ? _ref2 : this.materializeLazyObservable_(key);
5007
5060
  if (observable instanceof ComputedValue) {
5008
5061
  observable.set(newValue);
5009
5062
  return true;
@@ -5724,10 +5777,12 @@ function getAtom(thing, property) {
5724
5777
  return observable;
5725
5778
  }
5726
5779
  if (isObservableObject(thing)) {
5780
+ var _ref, _adm$values_$get;
5727
5781
  if (!property) {
5728
5782
  return die(26);
5729
5783
  }
5730
- var _observable = thing[$mobx].values_.get(property);
5784
+ var adm = thing[$mobx];
5785
+ var _observable = (_ref = (_adm$values_$get = adm.values_.get(property)) != null ? _adm$values_$get : adm.materializeLazyComputed_(property)) != null ? _ref : adm.materializeLazyObservable_(property);
5731
5786
  if (!_observable) {
5732
5787
  die(27, property, getDebugName(thing));
5733
5788
  }
@@ -5948,9 +6003,10 @@ function unwrap(a) {
5948
6003
  return a;
5949
6004
  }
5950
6005
 
5951
- var _getGlobal$Iterator;
6006
+ var _global$Iterator;
5952
6007
  // safely get iterator prototype if available
5953
- var maybeIteratorPrototype = ((_getGlobal$Iterator = /*#__PURE__*/getGlobal().Iterator) == null ? void 0 : _getGlobal$Iterator.prototype) || {};
6008
+ var global$1 = /*#__PURE__*/getGlobal();
6009
+ var maybeIteratorPrototype = ((_global$Iterator = global$1.Iterator) == null ? void 0 : _global$Iterator.prototype) || {};
5954
6010
  function makeIterable(iterator) {
5955
6011
  iterator[Symbol.iterator] = getSelf;
5956
6012
  return Object.assign(Object.create(maybeIteratorPrototype), iterator);