mobx 6.1.8 → 6.9.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.
Files changed (91) hide show
  1. package/CHANGELOG.md +224 -7
  2. package/README.md +54 -52
  3. package/dist/api/annotation.d.ts +6 -12
  4. package/dist/api/autorun.d.ts +4 -4
  5. package/dist/api/flow.d.ts +1 -0
  6. package/dist/api/intercept.d.ts +5 -5
  7. package/dist/api/object-api.d.ts +2 -0
  8. package/dist/api/observable.d.ts +5 -1
  9. package/dist/api/observe.d.ts +4 -4
  10. package/dist/api/tojs.d.ts +4 -1
  11. package/dist/api/when.d.ts +8 -0
  12. package/dist/core/atom.d.ts +1 -1
  13. package/dist/core/computedvalue.d.ts +0 -1
  14. package/dist/core/globalstate.d.ts +4 -0
  15. package/dist/core/reaction.d.ts +2 -2
  16. package/dist/errors.d.ts +4 -2
  17. package/dist/internal.d.ts +1 -0
  18. package/dist/mobx.cjs.development.js +1477 -1719
  19. package/dist/mobx.cjs.development.js.map +1 -1
  20. package/dist/mobx.cjs.production.min.js +1 -1
  21. package/dist/mobx.cjs.production.min.js.map +1 -1
  22. package/dist/mobx.d.ts +1 -1
  23. package/dist/mobx.esm.development.js +1475 -1720
  24. package/dist/mobx.esm.development.js.map +1 -1
  25. package/dist/mobx.esm.js +1492 -1726
  26. package/dist/mobx.esm.js.map +1 -1
  27. package/dist/mobx.esm.production.min.js +1 -1
  28. package/dist/mobx.esm.production.min.js.map +1 -1
  29. package/dist/mobx.umd.development.js +1477 -1719
  30. package/dist/mobx.umd.development.js.map +1 -1
  31. package/dist/mobx.umd.production.min.js +1 -1
  32. package/dist/mobx.umd.production.min.js.map +1 -1
  33. package/dist/types/actionannotation.d.ts +7 -1
  34. package/dist/types/autoannotation.d.ts +3 -0
  35. package/dist/types/observablemap.d.ts +5 -4
  36. package/dist/types/observableobject.d.ts +6 -9
  37. package/dist/types/observableset.d.ts +4 -4
  38. package/dist/types/observablevalue.d.ts +3 -5
  39. package/dist/utils/utils.d.ts +4 -4
  40. package/package.json +1 -1
  41. package/src/api/action.ts +8 -3
  42. package/src/api/annotation.ts +14 -44
  43. package/src/api/autorun.ts +38 -17
  44. package/src/api/computed.ts +5 -2
  45. package/src/api/configure.ts +6 -2
  46. package/src/api/decorators.ts +1 -1
  47. package/src/api/extendobservable.ts +12 -6
  48. package/src/api/extras.ts +4 -2
  49. package/src/api/flow.ts +17 -5
  50. package/src/api/intercept-read.ts +4 -2
  51. package/src/api/intercept.ts +10 -7
  52. package/src/api/iscomputed.ts +14 -8
  53. package/src/api/isobservable.ts +10 -4
  54. package/src/api/makeObservable.ts +35 -36
  55. package/src/api/object-api.ts +42 -14
  56. package/src/api/observable.ts +39 -25
  57. package/src/api/observe.ts +9 -6
  58. package/src/api/tojs.ts +20 -10
  59. package/src/api/trace.ts +6 -2
  60. package/src/api/when.ts +34 -9
  61. package/src/core/action.ts +11 -5
  62. package/src/core/atom.ts +9 -2
  63. package/src/core/computedvalue.ts +48 -27
  64. package/src/core/derivation.ts +34 -12
  65. package/src/core/globalstate.ts +25 -7
  66. package/src/core/observable.ts +23 -13
  67. package/src/core/reaction.ts +16 -7
  68. package/src/core/spy.ts +20 -7
  69. package/src/errors.ts +16 -3
  70. package/src/internal.ts +1 -0
  71. package/src/mobx.ts +6 -2
  72. package/src/types/actionannotation.ts +30 -52
  73. package/src/types/autoannotation.ts +107 -0
  74. package/src/types/computedannotation.ts +7 -37
  75. package/src/types/dynamicobject.ts +12 -6
  76. package/src/types/flowannotation.ts +40 -41
  77. package/src/types/intercept-utils.ts +9 -3
  78. package/src/types/legacyobservablearray.ts +26 -3
  79. package/src/types/listen-utils.ts +6 -2
  80. package/src/types/modifiers.ts +52 -16
  81. package/src/types/observableannotation.ts +7 -34
  82. package/src/types/observablearray.ts +106 -45
  83. package/src/types/observablemap.ts +71 -35
  84. package/src/types/observableobject.ts +88 -82
  85. package/src/types/observableset.ts +32 -13
  86. package/src/types/observablevalue.ts +16 -10
  87. package/src/types/overrideannotation.ts +4 -2
  88. package/src/types/type-utils.ts +34 -12
  89. package/src/utils/comparer.ts +5 -1
  90. package/src/utils/eq.ts +45 -15
  91. package/src/utils/utils.ts +39 -16
@@ -1,2 +1,8 @@
1
- import { Annotation } from "../internal";
1
+ import { ObservableObjectAdministration, Annotation } from "../internal";
2
2
  export declare function createActionAnnotation(name: string, options?: object): Annotation;
3
+ export declare function createActionDescriptor(adm: ObservableObjectAdministration, annotation: Annotation, key: PropertyKey, descriptor: PropertyDescriptor, safeDescriptors?: boolean): {
4
+ value: Function;
5
+ configurable: boolean;
6
+ enumerable: boolean;
7
+ writable: boolean;
8
+ };
@@ -0,0 +1,3 @@
1
+ import { Annotation } from "../internal";
2
+ export declare const autoAnnotation: Annotation;
3
+ export declare function createAutoAnnotation(options?: object): Annotation;
@@ -3,7 +3,9 @@ export interface IKeyValueMap<V = any> {
3
3
  [key: string]: V;
4
4
  }
5
5
  export declare type IMapEntry<K = any, V = any> = [K, V];
6
+ export declare type IReadonlyMapEntry<K = any, V = any> = readonly [K, V];
6
7
  export declare type IMapEntries<K = any, V = any> = IMapEntry<K, V>[];
8
+ export declare type IReadonlyMapEntries<K = any, V = any> = IReadonlyMapEntry<K, V>[];
7
9
  export declare type IMapDidChange<K = any, V = any> = {
8
10
  observableKind: "map";
9
11
  debugObjectName: string;
@@ -32,7 +34,7 @@ export interface IMapWillChange<K = any, V = any> {
32
34
  }
33
35
  export declare const ADD = "add";
34
36
  export declare const DELETE = "delete";
35
- export declare type IObservableMapInitialValues<K = any, V = any> = IMapEntries<K, V> | IKeyValueMap<V> | Map<K, V>;
37
+ export declare type IObservableMapInitialValues<K = any, V = any> = IMapEntries<K, V> | IReadonlyMapEntries<K, V> | IKeyValueMap<V> | Map<K, V>;
36
38
  export declare class ObservableMap<K = any, V = any> implements Map<K, V>, IInterceptable<IMapWillChange<K, V>>, IListenable {
37
39
  enhancer_: IEnhancer<V>;
38
40
  name_: string;
@@ -48,7 +50,6 @@ export declare class ObservableMap<K = any, V = any> implements Map<K, V>, IInte
48
50
  has(key: K): boolean;
49
51
  set(key: K, value: V): this;
50
52
  delete(key: K): boolean;
51
- private updateHasMapEntry_;
52
53
  private updateValue_;
53
54
  private addValue_;
54
55
  get(key: K): V | undefined;
@@ -59,9 +60,9 @@ export declare class ObservableMap<K = any, V = any> implements Map<K, V>, IInte
59
60
  [Symbol.iterator](): IterableIterator<IMapEntry<K, V>>;
60
61
  forEach(callback: (value: V, key: K, object: Map<K, V>) => void, thisArg?: any): void;
61
62
  /** Merge another object into this object, returns this. */
62
- merge(other: ObservableMap<K, V> | IKeyValueMap<V> | any): ObservableMap<K, V>;
63
+ merge(other?: IObservableMapInitialValues<K, V>): ObservableMap<K, V>;
63
64
  clear(): void;
64
- replace(values: ObservableMap<K, V> | IKeyValueMap<V> | any): ObservableMap<K, V>;
65
+ replace(values: IObservableMapInitialValues<K, V>): ObservableMap<K, V>;
65
66
  get size(): number;
66
67
  toString(): string;
67
68
  toJSON(): [K, V][];
@@ -1,5 +1,4 @@
1
1
  import { CreateObservableOptions, Annotation, ComputedValue, IAtom, IComputedValueOptions, IEnhancer, IInterceptable, IListenable, Lambda, ObservableValue } from "../internal";
2
- export declare const inferredAnnotationsSymbol: unique symbol;
3
2
  export declare type IObjectDidChange<T = any> = {
4
3
  observableKind: "object";
5
4
  name: PropertyKey;
@@ -28,10 +27,9 @@ export declare type IObjectWillChange<T = any> = {
28
27
  };
29
28
  export declare class ObservableObjectAdministration implements IInterceptable<IObjectWillChange>, IListenable {
30
29
  target_: any;
31
- values_: Map<string | number | symbol, ObservableValue<any> | ComputedValue<any>>;
30
+ values_: Map<PropertyKey, ObservableValue<any> | ComputedValue<any>>;
32
31
  name_: string;
33
32
  defaultAnnotation_: Annotation;
34
- autoBind_: boolean;
35
33
  keysAtom_: IAtom;
36
34
  changeListeners_: any;
37
35
  interceptors_: any;
@@ -39,14 +37,14 @@ export declare class ObservableObjectAdministration implements IInterceptable<IO
39
37
  isPlainObject_: boolean;
40
38
  appliedAnnotations_?: object;
41
39
  private pendingKeys_;
42
- constructor(target_: any, values_: Map<string | number | symbol, ObservableValue<any> | ComputedValue<any>>, name_: string, defaultAnnotation_?: Annotation, autoBind_?: boolean);
40
+ constructor(target_: any, values_: Map<PropertyKey, ObservableValue<any> | ComputedValue<any>>, name_: string, defaultAnnotation_?: Annotation);
43
41
  getObservablePropValue_(key: PropertyKey): any;
44
42
  setObservablePropValue_(key: PropertyKey, newValue: any): boolean | null;
45
43
  get_(key: PropertyKey): any;
46
44
  /**
47
45
  * @param {PropertyKey} key
48
46
  * @param {any} value
49
- * @param {Annotation|boolean} annotation true - infer from descriptor, false - copy as is
47
+ * @param {Annotation|boolean} annotation true - use default annotation, false - copy as is
50
48
  * @param {boolean} proxyTrap whether it's called from proxy trap
51
49
  * @returns {boolean|null} true on success, false on failure (proxyTrap + non-configurable), null when cancelled by interceptor
52
50
  */
@@ -54,18 +52,17 @@ export declare class ObservableObjectAdministration implements IInterceptable<IO
54
52
  has_(key: PropertyKey): boolean;
55
53
  /**
56
54
  * @param {PropertyKey} key
57
- * @param {Annotation|boolean} annotation true - infer from object or it's prototype, false - ignore
55
+ * @param {Annotation|boolean} annotation true - use default annotation, false - ignore prop
58
56
  */
59
57
  make_(key: PropertyKey, annotation: Annotation | boolean): void;
60
58
  /**
61
59
  * @param {PropertyKey} key
62
60
  * @param {PropertyDescriptor} descriptor
63
- * @param {Annotation|boolean} annotation true - infer from descriptor, false - copy as is
61
+ * @param {Annotation|boolean} annotation true - use default annotation, false - copy as is
64
62
  * @param {boolean} proxyTrap whether it's called from proxy trap
65
63
  * @returns {boolean|null} true on success, false on failure (proxyTrap + non-configurable), null when cancelled by interceptor
66
64
  */
67
65
  extend_(key: PropertyKey, descriptor: PropertyDescriptor, annotation: Annotation | boolean, proxyTrap?: boolean): boolean | null;
68
- inferAnnotation_(key: PropertyKey): Annotation | false;
69
66
  /**
70
67
  * @param {PropertyKey} key
71
68
  * @param {PropertyDescriptor} descriptor
@@ -90,7 +87,7 @@ export declare class ObservableObjectAdministration implements IInterceptable<IO
90
87
  observe_(callback: (changes: IObjectDidChange) => void, fireImmediately?: boolean): Lambda;
91
88
  intercept_(handler: any): Lambda;
92
89
  notifyPropertyAddition_(key: PropertyKey, value: any): void;
93
- ownKeys_(): PropertyKey[];
90
+ ownKeys_(): ArrayLike<string | symbol>;
94
91
  keys_(): PropertyKey[];
95
92
  }
96
93
  export interface IIsObservableObject {
@@ -1,4 +1,4 @@
1
- import { $mobx, IEnhancer, IListenable, Lambda, IInterceptable, IInterceptor } from "../internal";
1
+ import { $mobx, IEnhancer, IListenable, Lambda, IInterceptable, IInterceptor, IAtom } from "../internal";
2
2
  export declare type IObservableSetInitialValues<T> = Set<T> | readonly T[];
3
3
  export declare type ISetDidChange<T = any> = {
4
4
  object: ObservableSet<T>;
@@ -26,7 +26,7 @@ export declare class ObservableSet<T = any> implements Set<T>, IInterceptable<IS
26
26
  name_: string;
27
27
  [$mobx]: {};
28
28
  private data_;
29
- private atom_;
29
+ atom_: IAtom;
30
30
  changeListeners_: any;
31
31
  interceptors_: any;
32
32
  dehancer: any;
@@ -37,8 +37,8 @@ export declare class ObservableSet<T = any> implements Set<T>, IInterceptable<IS
37
37
  forEach(callbackFn: (value: T, value2: T, set: Set<T>) => void, thisArg?: any): void;
38
38
  get size(): number;
39
39
  add(value: T): this;
40
- delete(value: any): boolean;
41
- has(value: any): boolean;
40
+ delete(value: T): boolean;
41
+ has(value: T): boolean;
42
42
  entries(): IterableIterator<[T, T]>;
43
43
  keys(): IterableIterator<T>;
44
44
  values(): IterableIterator<T>;
@@ -9,21 +9,19 @@ export declare type IValueDidChange<T = any> = {
9
9
  observableKind: "value";
10
10
  object: IObservableValue<T>;
11
11
  debugObjectName: string;
12
- newValue: unknown;
13
- oldValue: unknown;
12
+ newValue: T;
13
+ oldValue: T | undefined;
14
14
  };
15
15
  export declare type IBoxDidChange<T = any> = {
16
16
  type: "create";
17
17
  observableKind: "value";
18
18
  object: IObservableValue<T>;
19
19
  debugObjectName: string;
20
- newValue: unknown;
20
+ newValue: T;
21
21
  } | IValueDidChange<T>;
22
22
  export interface IObservableValue<T> {
23
23
  get(): T;
24
24
  set(value: T): void;
25
- intercept_(handler: IInterceptor<IValueWillChange<T>>): Lambda;
26
- observe_(listener: (change: IValueDidChange<T>) => void, fireImmediately?: boolean): Lambda;
27
25
  }
28
26
  export declare class ObservableValue<T> extends Atom implements IObservableValue<T>, IInterceptable<IValueWillChange<T>>, IListenable {
29
27
  enhancer: IEnhancer<T>;
@@ -4,8 +4,8 @@ export declare const assign: {
4
4
  <T_2, U_2, V_1, W>(target: T_2, source1: U_2, source2: V_1, source3: W): T_2 & U_2 & V_1 & W;
5
5
  (target: object, ...sources: any[]): any;
6
6
  };
7
- export declare const getDescriptor: (o: any, p: string | number | symbol) => PropertyDescriptor | undefined;
8
- export declare const defineProperty: (o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType<any>) => any;
7
+ export declare const getDescriptor: (o: any, p: PropertyKey) => PropertyDescriptor | undefined;
8
+ export declare const defineProperty: <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T;
9
9
  export declare const objectPrototype: Object;
10
10
  export declare const EMPTY_ARRAY: never[];
11
11
  export declare const EMPTY_OBJECT: {};
@@ -30,13 +30,13 @@ export declare function isGenerator(obj: any): boolean;
30
30
  export declare function addHiddenProp(object: any, propName: PropertyKey, value: any): void;
31
31
  export declare function addHiddenFinalProp(object: any, propName: PropertyKey, value: any): void;
32
32
  export declare function createInstanceofPredicate<T>(name: string, theClass: new (...args: any[]) => T): (x: any) => x is T;
33
- export declare function isES6Map(thing: any): boolean;
33
+ export declare function isES6Map(thing: any): thing is Map<any, any>;
34
34
  export declare function isES6Set(thing: any): thing is Set<any>;
35
35
  /**
36
36
  * Returns the following: own enumerable keys and symbols.
37
37
  */
38
38
  export declare function getPlainObjectKeys(object: any): (string | symbol)[];
39
- export declare const ownKeys: (target: any) => PropertyKey[];
39
+ export declare const ownKeys: (target: any) => Array<string | symbol>;
40
40
  export declare function stringifyKey(key: any): string;
41
41
  export declare function toPrimitive(value: any): any;
42
42
  export declare function hasProp(target: Object, prop: PropertyKey): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobx",
3
- "version": "6.1.8",
3
+ "version": "6.9.0",
4
4
  "description": "Simple, scalable state management.",
5
5
  "source": "src/mobx.ts",
6
6
  "main": "dist/index.js",
package/src/api/action.ts CHANGED
@@ -45,10 +45,13 @@ export interface IActionFactory extends Annotation, PropertyDecorator {
45
45
  function createActionFactory(autoAction: boolean): IActionFactory {
46
46
  const res: IActionFactory = function action(arg1, arg2?): any {
47
47
  // action(fn() {})
48
- if (isFunction(arg1))
48
+ if (isFunction(arg1)) {
49
49
  return createAction(arg1.name || DEFAULT_ACTION_NAME, arg1, autoAction)
50
+ }
50
51
  // action("name", fn() {})
51
- if (isFunction(arg2)) return createAction(arg1, arg2, autoAction)
52
+ if (isFunction(arg2)) {
53
+ return createAction(arg1, arg2, autoAction)
54
+ }
52
55
  // @action
53
56
  if (isStringish(arg2)) {
54
57
  return storeAnnotation(arg1, arg2, autoAction ? autoActionAnnotation : actionAnnotation)
@@ -63,7 +66,9 @@ function createActionFactory(autoAction: boolean): IActionFactory {
63
66
  )
64
67
  }
65
68
 
66
- if (__DEV__) die("Invalid arguments for `action`")
69
+ if (__DEV__) {
70
+ die("Invalid arguments for `action`")
71
+ }
67
72
  } as IActionFactory
68
73
  return res
69
74
  }
@@ -1,17 +1,19 @@
1
- import {
2
- ObservableObjectAdministration,
3
- isGenerator,
4
- isFunction,
5
- autoAction,
6
- isAction,
7
- flow,
8
- computed,
9
- isFlow
10
- } from "../internal"
1
+ import { ObservableObjectAdministration, isFunction } from "../internal"
2
+
3
+ export const enum MakeResult {
4
+ Cancel,
5
+ Break,
6
+ Continue
7
+ }
11
8
 
12
9
  export type Annotation = {
13
10
  annotationType_: string
14
- make_(adm: ObservableObjectAdministration, key: PropertyKey): void
11
+ make_(
12
+ adm: ObservableObjectAdministration,
13
+ key: PropertyKey,
14
+ descriptor: PropertyDescriptor,
15
+ source: object
16
+ ): MakeResult
15
17
  extend_(
16
18
  adm: ObservableObjectAdministration,
17
19
  key: PropertyKey,
@@ -30,39 +32,7 @@ export type AnnotationMapEntry =
30
32
  // declare annotations for private/ protected members, see #2339
31
33
  export type AnnotationsMap<T, AdditionalFields extends PropertyKey> = {
32
34
  [P in Exclude<keyof T, "toString">]?: AnnotationMapEntry
33
- } &
34
- Record<AdditionalFields, AnnotationMapEntry>
35
-
36
- /**
37
- * Infers the best fitting annotation from property descriptor or false if the field shoudn't be annotated
38
- * - getter(+setter) -> computed
39
- * - setter w/o getter -> false (ignore)
40
- * - flow -> false (ignore)
41
- * - generator -> flow
42
- * - action -> false (ignore)
43
- * - function -> action (optionally bound)
44
- * - other -> defaultAnnotation
45
- */
46
- export function inferAnnotationFromDescriptor(
47
- desc: PropertyDescriptor,
48
- defaultAnnotation: Annotation,
49
- autoBind: boolean
50
- ): Annotation | false {
51
- if (desc.get) return computed
52
- if (desc.set) return false // ignore lone setter
53
- // If already wrapped in action/flow, don't do that another time, but assume it is already set up properly.
54
- return isFunction(desc.value)
55
- ? isGenerator(desc.value)
56
- ? isFlow(desc.value)
57
- ? false
58
- : flow
59
- : isAction(desc.value)
60
- ? false
61
- : autoBind
62
- ? autoAction.bound
63
- : autoAction
64
- : defaultAnnotation
65
- }
35
+ } & Record<AdditionalFields, AnnotationMapEntry>
66
36
 
67
37
  export function isAnnotation(thing: any) {
68
38
  return (
@@ -38,8 +38,12 @@ export function autorun(
38
38
  opts: IAutorunOptions = EMPTY_OBJECT
39
39
  ): IReactionDisposer {
40
40
  if (__DEV__) {
41
- if (!isFunction(view)) die("Autorun expects a function as first argument")
42
- if (isAction(view)) die("Autorun does not accept actions since actions are untrackable")
41
+ if (!isFunction(view)) {
42
+ die("Autorun expects a function as first argument")
43
+ }
44
+ if (isAction(view)) {
45
+ die("Autorun does not accept actions since actions are untrackable")
46
+ }
43
47
  }
44
48
 
45
49
  const name: string =
@@ -69,7 +73,9 @@ export function autorun(
69
73
  isScheduled = true
70
74
  scheduler(() => {
71
75
  isScheduled = false
72
- if (!reaction.isDisposed_) reaction.track(reactionRunner)
76
+ if (!reaction.isDisposed_) {
77
+ reaction.track(reactionRunner)
78
+ }
73
79
  })
74
80
  }
75
81
  },
@@ -86,14 +92,14 @@ export function autorun(
86
92
  return reaction.getDisposer_()
87
93
  }
88
94
 
89
- export type IReactionOptions = IAutorunOptions & {
90
- fireImmediately?: boolean
91
- equals?: IEqualsComparer<any>
95
+ export type IReactionOptions<T, FireImmediately extends boolean> = IAutorunOptions & {
96
+ fireImmediately?: FireImmediately
97
+ equals?: IEqualsComparer<T>
92
98
  }
93
99
 
94
100
  const run = (f: Lambda) => f()
95
101
 
96
- function createSchedulerFromOptions(opts: IReactionOptions) {
102
+ function createSchedulerFromOptions(opts: IAutorunOptions) {
97
103
  return opts.scheduler
98
104
  ? opts.scheduler
99
105
  : opts.delay
@@ -101,15 +107,22 @@ function createSchedulerFromOptions(opts: IReactionOptions) {
101
107
  : run
102
108
  }
103
109
 
104
- export function reaction<T>(
110
+ export function reaction<T, FireImmediately extends boolean = false>(
105
111
  expression: (r: IReactionPublic) => T,
106
- effect: (arg: T, prev: T, r: IReactionPublic) => void,
107
- opts: IReactionOptions = EMPTY_OBJECT
112
+ effect: (
113
+ arg: T,
114
+ prev: FireImmediately extends true ? T | undefined : T,
115
+ r: IReactionPublic
116
+ ) => void,
117
+ opts: IReactionOptions<T, FireImmediately> = EMPTY_OBJECT
108
118
  ): IReactionDisposer {
109
119
  if (__DEV__) {
110
- if (!isFunction(expression) || !isFunction(effect))
120
+ if (!isFunction(expression) || !isFunction(effect)) {
111
121
  die("First and second argument to reaction should be functions")
112
- if (!isPlainObject(opts)) die("Third argument of reactions should be an object")
122
+ }
123
+ if (!isPlainObject(opts)) {
124
+ die("Third argument of reactions should be an object")
125
+ }
113
126
  }
114
127
  const name = opts.name ?? (__DEV__ ? "Reaction@" + getNextId() : "Reaction")
115
128
  const effectAction = action(
@@ -122,9 +135,9 @@ export function reaction<T>(
122
135
  let firstTime = true
123
136
  let isScheduled = false
124
137
  let value: T
125
- let oldValue: T = undefined as any // only an issue with fireImmediately
138
+ let oldValue: T | undefined
126
139
 
127
- const equals = (opts as any).compareStructural
140
+ const equals: IEqualsComparer<T> = (opts as any).compareStructural
128
141
  ? comparer.structural
129
142
  : opts.equals || comparer.default
130
143
 
@@ -144,7 +157,9 @@ export function reaction<T>(
144
157
 
145
158
  function reactionRunner() {
146
159
  isScheduled = false
147
- if (r.isDisposed_) return
160
+ if (r.isDisposed_) {
161
+ return
162
+ }
148
163
  let changed: boolean = false
149
164
  r.track(() => {
150
165
  const nextValue = allowStateChanges(false, () => expression(r))
@@ -152,8 +167,14 @@ export function reaction<T>(
152
167
  oldValue = value
153
168
  value = nextValue
154
169
  })
155
- if (firstTime && opts.fireImmediately!) effectAction(value, oldValue, r)
156
- else if (!firstTime && changed) effectAction(value, oldValue, r)
170
+
171
+ // This casting is nesessary as TS cannot infer proper type in current funciton implementation
172
+ type OldValue = FireImmediately extends true ? T | undefined : T
173
+ if (firstTime && opts.fireImmediately!) {
174
+ effectAction(value, oldValue as OldValue, r)
175
+ } else if (!firstTime && changed) {
176
+ effectAction(value, oldValue as OldValue, r)
177
+ }
157
178
  firstTime = false
158
179
  }
159
180
 
@@ -46,11 +46,14 @@ export const computed: IComputedFactory = function computed(arg1, arg2) {
46
46
 
47
47
  // computed(expr, options?)
48
48
  if (__DEV__) {
49
- if (!isFunction(arg1)) die("First argument to `computed` should be an expression.")
50
- if (isFunction(arg2))
49
+ if (!isFunction(arg1)) {
50
+ die("First argument to `computed` should be an expression.")
51
+ }
52
+ if (isFunction(arg2)) {
51
53
  die(
52
54
  "A setter as second argument is no longer supported, use `{ set: fn }` option instead"
53
55
  )
56
+ }
54
57
  }
55
58
  const opts: IComputedValueOptions<any> = isPlainObject(arg2) ? arg2 : {}
56
59
  opts.get = arg1
@@ -34,7 +34,9 @@ export function configure(options: {
34
34
  ? false
35
35
  : typeof Proxy !== "undefined"
36
36
  }
37
- if (useProxies === "ifavailable") globalState.verifyProxies = true
37
+ if (useProxies === "ifavailable") {
38
+ globalState.verifyProxies = true
39
+ }
38
40
  if (enforceActions !== undefined) {
39
41
  const ea = enforceActions === ALWAYS ? ALWAYS : enforceActions === OBSERVED
40
42
  globalState.enforceActions = ea
@@ -47,7 +49,9 @@ export function configure(options: {
47
49
  "disableErrorBoundaries",
48
50
  "safeDescriptors"
49
51
  ].forEach(key => {
50
- if (key in options) globalState[key] = !!options[key]
52
+ if (key in options) {
53
+ globalState[key] = !!options[key]
54
+ }
51
55
  })
52
56
  globalState.allowStateReads = !globalState.observableRequiresReaction
53
57
  if (__DEV__ && globalState.disableErrorBoundaries === true) {
@@ -51,7 +51,7 @@ function assertNotDecorated(prototype: object, annotation: Annotation, key: Prop
51
51
  `Cannot apply '@${requestedAnnotationType}' to '${fieldName}':` +
52
52
  `\nThe field is already decorated with '@${currentAnnotationType}'.` +
53
53
  `\nRe-decorating fields is not allowed.` +
54
- `\nUse '@override' decorator for methods overriden by subclass.`
54
+ `\nUse '@override' decorator for methods overridden by subclass.`
55
55
  )
56
56
  }
57
57
  }
@@ -21,15 +21,21 @@ export function extendObservable<A extends Object, B extends Object>(
21
21
  options?: CreateObservableOptions
22
22
  ): A & B {
23
23
  if (__DEV__) {
24
- if (arguments.length > 4) die("'extendObservable' expected 2-4 arguments")
25
- if (typeof target !== "object")
24
+ if (arguments.length > 4) {
25
+ die("'extendObservable' expected 2-4 arguments")
26
+ }
27
+ if (typeof target !== "object") {
26
28
  die("'extendObservable' expects an object as first argument")
27
- if (isObservableMap(target))
29
+ }
30
+ if (isObservableMap(target)) {
28
31
  die("'extendObservable' should not be used on maps, use map.merge instead")
29
- if (!isPlainObject(properties))
30
- die(`'extendObservabe' only accepts plain objects as second argument`)
31
- if (isObservable(properties) || isObservable(annotations))
32
+ }
33
+ if (!isPlainObject(properties)) {
34
+ die(`'extendObservable' only accepts plain objects as second argument`)
35
+ }
36
+ if (isObservable(properties) || isObservable(annotations)) {
32
37
  die(`Extending an object with another observable (object) is not supported`)
38
+ }
33
39
  }
34
40
  // Pull descriptors first, so we don't have to deal with props added by administration ($mobx)
35
41
  const descriptors = getOwnPropertyDescriptors(properties)
package/src/api/extras.ts CHANGED
@@ -18,8 +18,9 @@ function nodeToDependencyTree(node: IDepTreeNode): IDependencyTree {
18
18
  const result: IDependencyTree = {
19
19
  name: node.name_
20
20
  }
21
- if (node.observing_ && node.observing_.length > 0)
21
+ if (node.observing_ && node.observing_.length > 0) {
22
22
  result.dependencies = unique(node.observing_).map(nodeToDependencyTree)
23
+ }
23
24
  return result
24
25
  }
25
26
 
@@ -31,8 +32,9 @@ function nodeToObserverTree(node: IDepTreeNode): IObserverTree {
31
32
  const result: IObserverTree = {
32
33
  name: node.name_
33
34
  }
34
- if (hasObservers(node as any))
35
+ if (hasObservers(node as any)) {
35
36
  result.observers = Array.from(<any>getObservers(node as any)).map(<any>nodeToObserverTree)
37
+ }
36
38
  return result
37
39
  }
38
40
 
package/src/api/flow.ts CHANGED
@@ -6,7 +6,8 @@ import {
6
6
  Annotation,
7
7
  isStringish,
8
8
  storeAnnotation,
9
- createFlowAnnotation
9
+ createFlowAnnotation,
10
+ createDecoratorAnnotation
10
11
  } from "../internal"
11
12
 
12
13
  export const FLOW = "flow"
@@ -28,9 +29,11 @@ interface Flow extends Annotation, PropertyDecorator {
28
29
  <R, Args extends any[]>(
29
30
  generator: (...args: Args) => Generator<any, R, any> | AsyncGenerator<any, R, any>
30
31
  ): (...args: Args) => CancellablePromise<R>
32
+ bound: Annotation & PropertyDecorator
31
33
  }
32
34
 
33
35
  const flowAnnotation = createFlowAnnotation("flow")
36
+ const flowBoundAnnotation = createFlowAnnotation("flow.bound", { bound: true })
34
37
 
35
38
  export const flow: Flow = Object.assign(
36
39
  function flow(arg1, arg2?) {
@@ -39,8 +42,9 @@ export const flow: Flow = Object.assign(
39
42
  return storeAnnotation(arg1, arg2, flowAnnotation)
40
43
  }
41
44
  // flow(fn)
42
- if (__DEV__ && arguments.length !== 1)
45
+ if (__DEV__ && arguments.length !== 1) {
43
46
  die(`Flow expects single argument with generator function`)
47
+ }
44
48
  const generator = arg1
45
49
  const name = generator.name || "<unnamed flow>"
46
50
 
@@ -92,7 +96,9 @@ export const flow: Flow = Object.assign(
92
96
  ret.then(next, reject)
93
97
  return
94
98
  }
95
- if (ret.done) return resolve(ret.value)
99
+ if (ret.done) {
100
+ return resolve(ret.value)
101
+ }
96
102
  pendingPromise = Promise.resolve(ret.value) as any
97
103
  return pendingPromise!.then(onFulfilled, onRejected)
98
104
  }
@@ -102,7 +108,9 @@ export const flow: Flow = Object.assign(
102
108
 
103
109
  promise.cancel = action(`${name} - runid: ${runId} - cancel`, function () {
104
110
  try {
105
- if (pendingPromise) cancelPromise(pendingPromise)
111
+ if (pendingPromise) {
112
+ cancelPromise(pendingPromise)
113
+ }
106
114
  // Finally block can return (or yield) stuff..
107
115
  const res = gen.return!(undefined as any)
108
116
  // eat anything that promise would do, it's cancelled!
@@ -123,8 +131,12 @@ export const flow: Flow = Object.assign(
123
131
  flowAnnotation
124
132
  )
125
133
 
134
+ flow.bound = createDecoratorAnnotation(flowBoundAnnotation)
135
+
126
136
  function cancelPromise(promise) {
127
- if (isFunction(promise.cancel)) promise.cancel()
137
+ if (isFunction(promise.cancel)) {
138
+ promise.cancel()
139
+ }
128
140
  }
129
141
 
130
142
  export function flowResult<T>(
@@ -39,16 +39,18 @@ export function interceptReads(thing, propOrHandler?, handler?): Lambda {
39
39
  if (isObservableMap(thing) || isObservableArray(thing) || isObservableValue(thing)) {
40
40
  target = getAdministration(thing)
41
41
  } else if (isObservableObject(thing)) {
42
- if (__DEV__ && !isStringish(propOrHandler))
42
+ if (__DEV__ && !isStringish(propOrHandler)) {
43
43
  return die(
44
44
  `InterceptReads can only be used with a specific property, not with an object in general`
45
45
  )
46
+ }
46
47
  target = getAdministration(thing, propOrHandler)
47
48
  } else if (__DEV__) {
48
49
  return die(`Expected observable map, object or array as first array`)
49
50
  }
50
- if (__DEV__ && target.dehancer !== undefined)
51
+ if (__DEV__ && target.dehancer !== undefined) {
51
52
  return die(`An intercept reader was already established`)
53
+ }
52
54
  target.dehancer = typeof propOrHandler === "function" ? propOrHandler : handler
53
55
  return () => {
54
56
  target.dehancer = undefined
@@ -20,19 +20,19 @@ export function intercept<T>(
20
20
  handler: IInterceptor<IValueWillChange<T>>
21
21
  ): Lambda
22
22
  export function intercept<T>(
23
- observableArray: IObservableArray<T>,
23
+ observableArray: IObservableArray<T> | Array<T>,
24
24
  handler: IInterceptor<IArrayWillChange<T> | IArrayWillSplice<T>>
25
25
  ): Lambda
26
26
  export function intercept<K, V>(
27
- observableMap: ObservableMap<K, V>,
27
+ observableMap: ObservableMap<K, V> | Map<K, V>,
28
28
  handler: IInterceptor<IMapWillChange<K, V>>
29
29
  ): Lambda
30
30
  export function intercept<V>(
31
- observableMap: ObservableSet<V>,
31
+ observableSet: ObservableSet<V> | Set<V>,
32
32
  handler: IInterceptor<ISetWillChange<V>>
33
33
  ): Lambda
34
34
  export function intercept<K, V>(
35
- observableMap: ObservableMap<K, V>,
35
+ observableMap: ObservableMap<K, V> | Map<K, V>,
36
36
  property: K,
37
37
  handler: IInterceptor<IValueWillChange<V>>
38
38
  ): Lambda
@@ -40,11 +40,14 @@ export function intercept(object: object, handler: IInterceptor<IObjectWillChang
40
40
  export function intercept<T extends object, K extends keyof T>(
41
41
  object: T,
42
42
  property: K,
43
- handler: IInterceptor<IValueWillChange<any>>
43
+ handler: IInterceptor<IValueWillChange<T[K]>>
44
44
  ): Lambda
45
45
  export function intercept(thing, propOrHandler?, handler?): Lambda {
46
- if (isFunction(handler)) return interceptProperty(thing, propOrHandler, handler)
47
- else return interceptInterceptable(thing, propOrHandler)
46
+ if (isFunction(handler)) {
47
+ return interceptProperty(thing, propOrHandler, handler)
48
+ } else {
49
+ return interceptInterceptable(thing, propOrHandler)
50
+ }
48
51
  }
49
52
 
50
53
  function interceptInterceptable(thing, handler) {