mobx 7.0.5 → 7.0.6

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,17 @@
1
1
  # mobx
2
2
 
3
+ ## 7.0.6
4
+
5
+ ### Patch Changes
6
+
7
+ - [`4b1c8d3ea2b3de1a2ae852fd5631e33d28a82b15`](https://github.com/mobxjs/mobx/commit/4b1c8d3ea2b3de1a2ae852fd5631e33d28a82b15) [#4721](https://github.com/mobxjs/mobx/pull/4721) Thanks [@giaBaoJS](https://github.com/giaBaoJS)! - fix: assigning `length` on an observable array now respects `intercept`. A cancelled or modified splice used to be overridden by a direct write to the backing array, which truncated it without notifying observers and made the next mutation throw "Modification exception". A non-integer `length` now throws "Out of range" before touching the array.
8
+
9
+ - [`60be47cab0926d12f22449ec6c809fb5ec6601c4`](https://github.com/mobxjs/mobx/commit/60be47cab0926d12f22449ec6c809fb5ec6601c4) [#4716](https://github.com/mobxjs/mobx/pull/4716) Thanks [@AcEKaycgR](https://github.com/AcEKaycgR)! - fix: `observable.box(array)` no longer warns under `observableRequiresReaction` when a spy is active. The `create` spy event now reports `newValue` as the value itself rather than a string, matching the declared `IBoxDidChange` type. Previously the constructor stringified the value, and stringifying an observable array reads its `length`, which counted as an observable read outside a reactive context. Spy listeners that relied on `newValue` being a string for `create` events will now receive the raw value.
10
+
11
+ - [`3551aeb051ff922717b03c4fbc04a6b98f7f3b3e`](https://github.com/mobxjs/mobx/commit/3551aeb051ff922717b03c4fbc04a6b98f7f3b3e) [#4717](https://github.com/mobxjs/mobx/pull/4717) Thanks [@breken-ai](https://github.com/breken-ai)! - Remove the `signal` abort listener when a reaction disposes itself (`r.dispose()` or a resolved `when`), so long-lived `AbortSignal`s no longer accumulate listeners that keep disposed reactions in memory
12
+
13
+ - [`7e4e27dbfbf0b56770a11e9cba913e5d49c0c6f8`](https://github.com/mobxjs/mobx/commit/7e4e27dbfbf0b56770a11e9cba913e5d49c0c6f8) [#4718](https://github.com/mobxjs/mobx/pull/4718) Thanks [@breken-ai](https://github.com/breken-ai)! - `observe`/`spy` `add` events of an observable Set now report the value that was actually stored (e.g. the observable copy of a plain object), matching ObservableMap and observable arrays, so `set.has(change.newValue)` holds
14
+
3
15
  ## 7.0.5
4
16
 
5
17
  ### Patch Changes
@@ -35,6 +35,7 @@ export declare class Reaction implements IDerivation, IReactionPublic {
35
35
  runId_: number;
36
36
  unboundDepsCount_: number;
37
37
  private flags_;
38
+ private removeAbortListener_;
38
39
  constructor(name_: string | undefined, onInvalidate_: () => void, errorHandler_?: ((error: any, derivation: IDerivation) => void) | undefined, requiresObservable_?: any);
39
40
  get isDisposed(): boolean;
40
41
  set isDisposed(newValue: boolean);
@@ -1195,14 +1195,13 @@ class ObservableValue extends Atom {
1195
1195
  this.equals_ = equals_;
1196
1196
  this.value_ = enhancer_(value, undefined, name_);
1197
1197
  if (notifySpy && isSpyEnabled()) {
1198
- var _this$value_;
1199
1198
  // only notify spy if this is a stand-alone observable
1200
1199
  spyReport({
1201
1200
  type: CREATE,
1202
1201
  object: this,
1203
1202
  observableKind: "value",
1204
1203
  debugObjectName: this.name_,
1205
- newValue: "" + ((_this$value_ = this.value_) == null ? void 0 : _this$value_.toString())
1204
+ newValue: this.value_
1206
1205
  });
1207
1206
  }
1208
1207
  }
@@ -2165,6 +2164,7 @@ class Reaction {
2165
2164
  this.runId_ = 0;
2166
2165
  this.unboundDepsCount_ = 0;
2167
2166
  this.flags_ = 0b00000;
2167
+ this.removeAbortListener_ = undefined;
2168
2168
  this.name_ = name_;
2169
2169
  this.onInvalidate_ = onInvalidate_;
2170
2170
  this.errorHandler_ = errorHandler_;
@@ -2301,7 +2301,10 @@ class Reaction {
2301
2301
  }
2302
2302
  dispose() {
2303
2303
  if (!this.isDisposed) {
2304
+ var _this$removeAbortList;
2304
2305
  this.isDisposed = true;
2306
+ // also covers self-disposal (`r.dispose()`, `when`), which bypasses the disposer
2307
+ (_this$removeAbortList = this.removeAbortListener_) == null || _this$removeAbortList.call(this);
2305
2308
  if (!this.isRunning) {
2306
2309
  // if disposed while running, clean up later. Maybe not optimal, but rare case
2307
2310
  startBatch();
@@ -2311,11 +2314,11 @@ class Reaction {
2311
2314
  }
2312
2315
  }
2313
2316
  getDisposer_(abortSignal) {
2314
- const dispose = () => {
2315
- this.dispose();
2316
- abortSignal == null || abortSignal.removeEventListener == null || abortSignal.removeEventListener("abort", dispose);
2317
- };
2318
- abortSignal == null || abortSignal.addEventListener == null || abortSignal.addEventListener("abort", dispose);
2317
+ const dispose = () => this.dispose();
2318
+ if (abortSignal != null && abortSignal.addEventListener && !this.isDisposed) {
2319
+ abortSignal.addEventListener("abort", dispose);
2320
+ this.removeAbortListener_ = () => abortSignal.removeEventListener == null ? void 0 : abortSignal.removeEventListener("abort", dispose);
2321
+ }
2319
2322
  dispose[$mobx] = this;
2320
2323
  if ("dispose" in Symbol && typeof Symbol.dispose === "symbol") {
2321
2324
  dispose[Symbol.dispose] = dispose;
@@ -3472,8 +3475,7 @@ const arrayTraps = {
3472
3475
  const adm = target[$mobx];
3473
3476
  if (name === "length") {
3474
3477
  adm.setArrayLength_(value);
3475
- }
3476
- if (typeof name === "symbol" || isNaN(name)) {
3478
+ } else if (typeof name === "symbol" || isNaN(name)) {
3477
3479
  target[name] = value;
3478
3480
  } else {
3479
3481
  // numeric string
@@ -3518,7 +3520,7 @@ class ObservableArrayAdministration {
3518
3520
  return this.values_.length;
3519
3521
  }
3520
3522
  setArrayLength_(newLength) {
3521
- if (typeof newLength !== "number" || isNaN(newLength) || newLength < 0) {
3523
+ if (!Number.isInteger(newLength) || newLength < 0) {
3522
3524
  die(40, newLength);
3523
3525
  }
3524
3526
  let currentLength = this.values_.length;
@@ -4300,7 +4302,8 @@ class ObservableSet {
4300
4302
  }
4301
4303
  if (!this.has(value)) {
4302
4304
  transaction(() => {
4303
- this.data_.add(this.enhancer_(value, undefined));
4305
+ value = this.enhancer_(value, undefined); // report the stored value, like map and array
4306
+ this.data_.add(value);
4304
4307
  this.atom_.reportChanged();
4305
4308
  });
4306
4309
  const notifySpy = isSpyEnabled();