mobx 3.1.17 → 3.3.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,3 +1,29 @@
1
+ # 3.3.0
2
+
3
+ * Undeprecated `transaction`, see [#1139](https://github.com/mobxjs/mobx/issues/1139)
4
+ * Fixed typings of reaction [#1136](https://github.com/mobxjs/mobx/issues/1136)
5
+ * It is now possible to re-define a computed property [#1121](https://github.com/mobxjs/mobx/issues/1121)
6
+ * Print an helpful error message when using `@action` on a getter [#971](https://github.com/mobxjs/mobx/issues/971)
7
+ * Improved typings of intercept [#1119](https://github.com/mobxjs/mobx/issues/1119)
8
+ * Made code base Prettier [#1103](https://github.com/mobxjs/mobx/issues/1103)
9
+ * react-native will now by default use the es module build as well.
10
+ * Added support for Weex, see [#1163](https://github.com/mobxjs/mobx/pull/1163/)
11
+ * Added workaround for Firefox issue causing MobX to crash, see [#614](https://github.com/mobxjs/mobx/issues/614)
12
+
13
+ # 3.2.2
14
+
15
+ * Fixes a bug (or a known limitation) described in [#1092](https://github.com/mobxjs/mobx/issue/1092/). It is now possible to have different observable administration on different levels of the prototype chain. By @guillaumeleclerc
16
+ * Fixed a build issue when using mobx in a project that was using rollup, fixes [#1099](https://github.com/mobxjs/mobx/issue/1099/) by @rossipedia
17
+ * Fixed typings of `useStrict`, by @rickbeerendonk
18
+
19
+ # 3.2.1
20
+
21
+ * Introduced customizable value comperators to reactions and computed values. `reaction` and `computed` now support an additional option, `equals`, which takes a comparision function. See [#951](https://github.com/mobxjs/mobx/pull/951/) by @jamiewinder. Fixes #802 and #943. See the updated [`computed` docs](https://mobx.js.org/refguide/computed-decorator.html) for more details.
22
+
23
+ # 3.2.0
24
+
25
+ * MobX will warn again when there are multiple instances of MobX loaded, as this lead to often to confusing bugs if the project setup was not properly. The signal mobx that multiple instances are loaded on purpose, use `mobx.extras.runInSandbox`. See [#1082](https://github.com/mobxjs/mobx/issues/1082) for details.
26
+
1
27
  # 3.1.17
2
28
 
3
29
  * Improved typings of `IObservableArray.intercept`: use more restrictive types for `change` parameter of `handler`, by @bvanreeven
package/README.md CHANGED
@@ -11,6 +11,7 @@ _Simple, scalable state management_
11
11
  [![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://mobxjs.github.io/mobx/donate.html)
12
12
  [![OpenCollective](https://opencollective.com/mobx/backers/badge.svg)](#backers)
13
13
  [![OpenCollective](https://opencollective.com/mobx/sponsors/badge.svg)](#sponsors)
14
+ [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
14
15
 
15
16
  ![npm install mobx](https://nodei.co/npm/mobx.png?downloadRank=true&downloads=true)
16
17
 
@@ -55,7 +56,7 @@ Both React and MobX provide very optimal and unique solutions to common problems
55
56
 
56
57
  ## Core concepts
57
58
 
58
- MobX has only a few core concepts. The following snippets can be tried online using [JSFiddle](https://jsfiddle.net/mweststrate/wv3yopo0/) (or [without ES6 and JSX](https://jsfiddle.net/rubyred/55oc981v/)).
59
+ MobX has only a few core concepts. The following snippets can be tried online using [JSFiddle](https://jsfiddle.net/mweststrate/f0dptdau/2/) (or [without ES6 and JSX](https://jsfiddle.net/rubyred/55oc981v/)).
59
60
 
60
61
  ### Observable state
61
62
 
@@ -1,5 +1,6 @@
1
1
  import { Lambda } from "../utils/utils";
2
2
  import { IReactionPublic, IReactionDisposer } from "../core/reaction";
3
+ import { IEqualsComparer } from "../types/comparer";
3
4
  /**
4
5
  * Creates a reactive view and keeps it alive, so that the view is always
5
6
  * updated if one of the dependencies changes, even when the view is not further used by something else.
@@ -45,6 +46,7 @@ export interface IReactionOptions {
45
46
  compareStructural?: boolean;
46
47
  /** alias for compareStructural */
47
48
  struct?: boolean;
49
+ equals?: IEqualsComparer<any>;
48
50
  name?: string;
49
51
  }
50
52
  /**
@@ -1,7 +1,9 @@
1
+ import { IEqualsComparer } from "../types/comparer";
1
2
  import { IComputedValue } from "../core/computedvalue";
2
3
  export interface IComputedValueOptions<T> {
3
4
  compareStructural?: boolean;
4
5
  struct?: boolean;
6
+ equals?: IEqualsComparer<T>;
5
7
  name?: string;
6
8
  setter?: (value: T) => void;
7
9
  context?: any;
@@ -11,6 +13,7 @@ export interface IComputed {
11
13
  <T>(func: () => T, options: IComputedValueOptions<T>): IComputedValue<T>;
12
14
  (target: Object, key: string | symbol, baseDescriptor?: PropertyDescriptor): void;
13
15
  struct(target: Object, key: string | symbol, baseDescriptor?: PropertyDescriptor): void;
16
+ equals(equals: IEqualsComparer<any>): PropertyDecorator;
14
17
  }
15
18
  /**
16
19
  * Decorator for class properties: @computed get value() { return expr; }.
package/lib/api/expr.d.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  /**
2
- * expr can be used to create temporarily views inside views.
3
- * This can be improved to improve performance if a value changes often, but usually doesn't affect the outcome of an expression.
4
- *
5
- * In the following example the expression prevents that a component is rerender _each time_ the selection changes;
6
- * instead it will only rerenders when the current todo is (de)selected.
7
- *
8
- * reactiveComponent((props) => {
9
- * const todo = props.todo;
10
- * const isSelected = mobx.expr(() => props.viewState.selection === todo);
11
- * return <div className={isSelected ? "todo todo-selected" : "todo"}>{todo.title}</div>
12
- * });
13
- *
14
- */
2
+ * expr can be used to create temporarily views inside views.
3
+ * This can be improved to improve performance if a value changes often, but usually doesn't affect the outcome of an expression.
4
+ *
5
+ * In the following example the expression prevents that a component is rerender _each time_ the selection changes;
6
+ * instead it will only rerenders when the current todo is (de)selected.
7
+ *
8
+ * reactiveComponent((props) => {
9
+ * const todo = props.todo;
10
+ * const isSelected = mobx.expr(() => props.viewState.selection === todo);
11
+ * return <div className={isSelected ? "todo todo-selected" : "todo"}>{todo.title}</div>
12
+ * });
13
+ *
14
+ */
15
15
  export declare function expr<T>(expr: () => T, scope?: any): T;
@@ -1,7 +1,7 @@
1
- import { Lambda } from '../utils/utils';
2
- import { IObservableArray } from '../types/observablearray';
3
- import { ObservableMap } from '../types/observablemap';
4
- import { IObservableValue } from '../types/observablevalue';
1
+ import { Lambda } from "../utils/utils";
2
+ import { IObservableArray } from "../types/observablearray";
3
+ import { ObservableMap } from "../types/observablemap";
4
+ import { IObservableValue } from "../types/observablevalue";
5
5
  export declare type ReadInterceptor<T> = (value: any) => T;
6
6
  /** Experimental feature right now, tested indirectly via Mobx-State-Tree */
7
7
  export declare function interceptReads<T>(value: IObservableValue<T>, handler: ReadInterceptor<T>): Lambda;
@@ -9,4 +9,4 @@ export declare function intercept<T>(observableArray: IObservableArray<T>, handl
9
9
  export declare function intercept<T>(observableMap: ObservableMap<T>, handler: IInterceptor<IMapWillChange<T>>): Lambda;
10
10
  export declare function intercept<T>(observableMap: ObservableMap<T>, property: string, handler: IInterceptor<IValueWillChange<T>>): Lambda;
11
11
  export declare function intercept(object: Object, handler: IInterceptor<IObjectWillChange>): Lambda;
12
- export declare function intercept(object: Object, property: string, handler: IInterceptor<IValueWillChange<any>>): Lambda;
12
+ export declare function intercept<T extends Object, K extends keyof T>(object: T, property: K, handler: IInterceptor<IValueWillChange<any>>): Lambda;
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Returns true if the provided value is reactive.
3
- * @param value object, function or array
4
- * @param propertyName if propertyName is specified, checkes whether value.propertyName is reactive.
5
- */
2
+ * Returns true if the provided value is reactive.
3
+ * @param value object, function or array
4
+ * @param property if property is specified, checks whether value.property is reactive.
5
+ */
6
6
  export declare function isObservable(value: any, property?: string): boolean;
package/lib/api/tojs.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Basically, a deep clone, so that no reactive property will exist anymore.
3
- */
2
+ * Basically, a deep clone, so that no reactive property will exist anymore.
3
+ */
4
4
  export declare function toJS<T>(source: T, detectCycles?: boolean): T;
5
5
  export declare function toJS(source: any, detectCycles?: boolean): any;
6
6
  export declare function toJS(source: any, detectCycles: boolean, __alreadySeen: [any, any][]): any;
@@ -4,7 +4,7 @@ export interface IAction {
4
4
  }
5
5
  export declare function createAction(actionName: string, fn: Function): Function & IAction;
6
6
  export declare function executeAction(actionName: string, fn: Function, scope?: any, args?: IArguments): any;
7
- export declare function useStrict(strict: boolean): any;
7
+ export declare function useStrict(strict: boolean): void;
8
8
  export declare function isStrictModeEnabled(): boolean;
9
9
  export declare function allowStateChanges<T>(allowStateChanges: boolean, func: () => T): T;
10
10
  export declare function allowStateChangesStart(allowStateChanges: boolean): boolean;
@@ -1,6 +1,7 @@
1
1
  import { IObservable } from "./observable";
2
2
  import { IDerivation, IDerivationState, CaughtException } from "./derivation";
3
3
  import { Lambda } from "../utils/utils";
4
+ import { IEqualsComparer } from "../types/comparer";
4
5
  import { IValueDidChange } from "../types/observablevalue";
5
6
  export interface IComputedValue<T> {
6
7
  get(): T;
@@ -10,7 +11,9 @@ export interface IComputedValue<T> {
10
11
  /**
11
12
  * A node in the state dependency root that observes other nodes, and can be observed itself.
12
13
  *
13
- * ComputedValue will remember result of the computation for duration of a batch, or being observed
14
+ * ComputedValue will remember the result of the computation for the duration of the batch, or
15
+ * while being observed.
16
+ *
14
17
  * During this time it will recompute only when one of its direct dependencies changed,
15
18
  * but only when it is being accessed with `ComputedValue.get()`.
16
19
  *
@@ -27,7 +30,7 @@ export interface IComputedValue<T> {
27
30
  export declare class ComputedValue<T> implements IObservable, IComputedValue<T>, IDerivation {
28
31
  derivation: () => T;
29
32
  scope: Object | undefined;
30
- private compareStructural;
33
+ private equals;
31
34
  dependenciesState: IDerivationState;
32
35
  observing: never[];
33
36
  newObserving: null;
@@ -50,12 +53,14 @@ export declare class ComputedValue<T> implements IObservable, IComputedValue<T>,
50
53
  *
51
54
  * The `name` property is for debug purposes only.
52
55
  *
53
- * The `compareStructural` property indicates whether the return values should be compared structurally.
54
- * Normally, a computed value will not notify an upstream observer if a newly produced value is strictly equal to the previously produced value.
55
- * However, enabling compareStructural can be convenient if you always produce an new aggregated object and don't want to notify observers if it is structurally the same.
56
+ * The `equals` property specifies the comparer function to use to determine if a newly produced
57
+ * value differs from the previous value. Two comparers are provided in the library; `defaultComparer`
58
+ * compares based on identity comparison (===), and `structualComparer` deeply compares the structure.
59
+ * Structural comparison can be convenient if you always produce an new aggregated object and
60
+ * don't want to notify observers if it is structurally the same.
56
61
  * This is useful for working with vectors, mouse coordinates etc.
57
62
  */
58
- constructor(derivation: () => T, scope: Object | undefined, compareStructural: boolean, name: string, setter?: (v: T) => void);
63
+ constructor(derivation: () => T, scope: Object | undefined, equals: IEqualsComparer<any>, name: string, setter?: (v: T) => void);
59
64
  onBecomeStale(): void;
60
65
  onBecomeUnobserved(): void;
61
66
  /**
@@ -32,14 +32,15 @@ export declare class CaughtException {
32
32
  }
33
33
  export declare function isCaughtException(e: any): e is CaughtException;
34
34
  /**
35
- * Finds out wether any dependency of derivation actually changed
36
- * If dependenciesState is 1 it will recalculate dependencies,
35
+ * Finds out whether any dependency of the derivation has actually changed.
36
+ * If dependenciesState is 1 then it will recalculate dependencies,
37
37
  * if any dependency changed it will propagate it by changing dependenciesState to 2.
38
38
  *
39
- * By iterating over dependencies in the same order they were reported and stoping on first change
40
- * all recalculations are called only for ComputedValues that will be tracked anyway by derivation.
41
- * That is because we assume that if first x dependencies of derivation doesn't change
42
- * than derivation shuold run the same way up until accessing x-th dependency.
39
+ * By iterating over the dependencies in the same order that they were reported and
40
+ * stopping on the first change, all the recalculations are only called for ComputedValues
41
+ * that will be tracked by derivation. That is because we assume that if the first x
42
+ * dependencies of the derivation doesn't change then the derivation should run the same way
43
+ * up until accessing x-th dependency.
43
44
  */
44
45
  export declare function shouldCompute(derivation: IDerivation): boolean;
45
46
  export declare function isComputingDerivation(): boolean;
@@ -69,6 +69,7 @@ export declare class MobXGlobals {
69
69
  globalReactionErrorHandlers: ((error: any, derivation: IDerivation) => void)[];
70
70
  }
71
71
  export declare let globalState: MobXGlobals;
72
+ export declare function isolateGlobalState(): void;
72
73
  export declare function shareGlobalState(): void;
73
74
  export declare function getGlobalState(): any;
74
75
  export declare function registerGlobals(): void;
@@ -6,7 +6,7 @@ export interface IDepTreeNode {
6
6
  export interface IObservable extends IDepTreeNode {
7
7
  diffValue: number;
8
8
  /**
9
- * Id of the derivation *run* that last accesed this observable.
9
+ * Id of the derivation *run* that last accessed this observable.
10
10
  * If this id equals the *run* id of the current derivation,
11
11
  * the dependency is already established
12
12
  */
package/lib/mobx.d.ts CHANGED
@@ -22,6 +22,7 @@ export { IAtom, Atom, BaseAtom } from "./core/atom";
22
22
  export { useStrict, isStrictModeEnabled, IAction } from "./core/action";
23
23
  export { spy } from "./core/spy";
24
24
  export { IComputedValue } from "./core/computedvalue";
25
+ export { IEqualsComparer, comparer } from "./types/comparer";
25
26
  export { asReference, asFlat, asStructure, asMap } from "./types/modifiers-old";
26
27
  export { IModifierDescriptor, IEnhancer, isModifierDescriptor } from "./types/modifiers";
27
28
  export { IInterceptable, IInterceptor } from "./types/intercept-utils";
@@ -52,8 +53,8 @@ import { IDepTreeNode } from "./core/observable";
52
53
  import { IObserverTree, IDependencyTree } from "./api/extras";
53
54
  import { Lambda } from "./utils/utils";
54
55
  import { IObservableArray } from "./types/observablearray";
55
- import { ObservableMap } from './types/observablemap';
56
- import { IObservableValue } from './types/observablevalue';
56
+ import { ObservableMap } from "./types/observablemap";
57
+ import { IObservableValue } from "./types/observablevalue";
57
58
  export declare const extras: {
58
59
  allowStateChanges: <T>(allowStateChanges: boolean, func: () => T) => T;
59
60
  deepEqual: (a: any, b: any) => any;
@@ -74,6 +75,7 @@ export declare const extras: {
74
75
  onReactionError: (handler: (error: any, derivation: IDerivation) => void) => () => void;
75
76
  reserveArrayBuffer: (max: number) => void;
76
77
  resetGlobalState: () => void;
78
+ isolateGlobalState: () => void;
77
79
  shareGlobalState: () => void;
78
80
  spyReport: (event: any) => void;
79
81
  spyReportEnd: (change?: any) => void;
@@ -99,9 +101,14 @@ declare const everything: {
99
101
  untracked: <T>(action: () => T) => T;
100
102
  Atom: typeof Atom;
101
103
  BaseAtom: typeof BaseAtom;
102
- useStrict: (strict: boolean) => any;
104
+ useStrict: (strict: boolean) => void;
103
105
  isStrictModeEnabled: () => boolean;
104
106
  spy: (listener: (change: any) => void) => Lambda;
107
+ comparer: {
108
+ identity: (a: any, b: any) => boolean;
109
+ structural: (a: any, b: any) => boolean;
110
+ default: (a: any, b: any) => boolean;
111
+ };
105
112
  asReference: <T>(value: T) => T;
106
113
  asFlat: <T>(value: T) => T;
107
114
  asStructure: <T>(value: T) => T;
@@ -146,7 +153,7 @@ declare const everything: {
146
153
  <T>(observableMap: ObservableMap<T>, handler: IInterceptor<IMapWillChange<T>>): Lambda;
147
154
  <T>(observableMap: ObservableMap<T>, property: string, handler: IInterceptor<IValueWillChange<T>>): Lambda;
148
155
  (object: Object, handler: IInterceptor<IObjectWillChange>): Lambda;
149
- (object: Object, property: string, handler: IInterceptor<IValueWillChange<any>>): Lambda;
156
+ <T extends Object, K extends keyof T>(object: T, property: K, handler: IInterceptor<IValueWillChange<any>>): Lambda;
150
157
  };
151
158
  autorun: {
152
159
  (view: (r: IReactionPublic) => any, scope?: any): IReactionDisposer;
@@ -199,6 +206,7 @@ declare const everything: {
199
206
  onReactionError: (handler: (error: any, derivation: IDerivation) => void) => () => void;
200
207
  reserveArrayBuffer: (max: number) => void;
201
208
  resetGlobalState: () => void;
209
+ isolateGlobalState: () => void;
202
210
  shareGlobalState: () => void;
203
211
  spyReport: (event: any) => void;
204
212
  spyReportEnd: (change?: any) => void;