mobx 4.15.0 → 4.15.4

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 (57) hide show
  1. package/CHANGELOG.md +827 -552
  2. package/README.md +155 -98
  3. package/lib/api/action.d.ts +13 -25
  4. package/lib/api/actiondecorator.d.ts +27 -16
  5. package/lib/api/autorun.d.ts +24 -24
  6. package/lib/api/become-observed.d.ts +5 -5
  7. package/lib/api/computed.d.ts +14 -14
  8. package/lib/api/configure.d.ts +19 -19
  9. package/lib/api/decorate.d.ts +6 -6
  10. package/lib/api/extendobservable.d.ts +7 -7
  11. package/lib/api/extras.d.ts +10 -10
  12. package/lib/api/flow.d.ts +9 -9
  13. package/lib/api/intercept-read.d.ts +8 -8
  14. package/lib/api/intercept.d.ts +8 -8
  15. package/lib/api/iscomputed.d.ts +3 -3
  16. package/lib/api/isobservable.d.ts +2 -2
  17. package/lib/api/object-api.d.ts +34 -34
  18. package/lib/api/observable.d.ts +54 -54
  19. package/lib/api/observabledecorator.d.ts +6 -6
  20. package/lib/api/observe.d.ts +8 -8
  21. package/lib/api/tojs.d.ts +11 -11
  22. package/lib/api/trace.d.ts +3 -3
  23. package/lib/api/transaction.d.ts +8 -8
  24. package/lib/api/when.d.ts +15 -15
  25. package/lib/core/action.d.ts +22 -22
  26. package/lib/core/atom.d.ts +40 -40
  27. package/lib/core/computedvalue.d.ts +93 -93
  28. package/lib/core/derivation.d.ts +74 -74
  29. package/lib/core/globalstate.d.ts +106 -106
  30. package/lib/core/observable.d.ts +44 -44
  31. package/lib/core/reaction.d.ts +63 -63
  32. package/lib/core/spy.d.ts +6 -6
  33. package/lib/index.js +7 -0
  34. package/lib/internal.d.ts +44 -44
  35. package/lib/mobx.d.ts +19 -19
  36. package/lib/mobx.es6.js +4340 -4330
  37. package/lib/mobx.js +4384 -4419
  38. package/lib/mobx.js.flow +1 -0
  39. package/lib/mobx.min.js +1 -1
  40. package/lib/mobx.module.js +4431 -4421
  41. package/lib/mobx.umd.js +4431 -4419
  42. package/lib/mobx.umd.min.js +1 -1
  43. package/lib/types/intercept-utils.d.ts +9 -9
  44. package/lib/types/listen-utils.d.ts +8 -8
  45. package/lib/types/modifiers.d.ts +7 -7
  46. package/lib/types/observablearray.d.ts +78 -78
  47. package/lib/types/observablemap.d.ts +83 -83
  48. package/lib/types/observableobject.d.ts +65 -65
  49. package/lib/types/observableset.d.ts +49 -49
  50. package/lib/types/observablevalue.d.ts +37 -37
  51. package/lib/types/type-utils.d.ts +4 -4
  52. package/lib/utils/comparer.d.ts +14 -14
  53. package/lib/utils/decorators2.d.ts +7 -7
  54. package/lib/utils/eq.d.ts +1 -1
  55. package/lib/utils/iterable.d.ts +5 -5
  56. package/lib/utils/utils.d.ts +43 -43
  57. package/package.json +7 -89
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
- <img src="docs/mobx.png" alt="logo" height="120" align="right" />
1
+ <img src="docs/assets/mobx.png" alt="logo" height="120" align="right" />
2
2
 
3
3
  # MobX
4
4
 
5
5
  _Simple, scalable state management_
6
6
 
7
- [![CircleCI](https://circleci.com/gh/mobxjs/mobx/tree/mobx4-master.svg?style=svg)](https://circleci.com/gh/mobxjs/mobx/tree/mobx4-master)
7
+ [![CircleCI](https://circleci.com/gh/mobxjs/mobx.svg?style=svg)](https://circleci.com/gh/mobxjs/mobx)
8
8
  [![Coverage Status](https://coveralls.io/repos/mobxjs/mobx/badge.svg?branch=master&service=github)](https://coveralls.io/github/mobxjs/mobx?branch=master)
9
9
  [![Join the chat at https://gitter.im/mobxjs/mobx](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mobxjs/mobx?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
10
10
  [![Discuss MobX on Hashnode](https://hashnode.github.io/badges/mobx.svg)](https://hashnode.com/n/mobx)
@@ -12,50 +12,90 @@ _Simple, scalable state management_
12
12
  [![OpenCollective](https://opencollective.com/mobx/sponsors/badge.svg)](#sponsors)
13
13
  [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
14
14
 
15
- MobX is proudly sponsored by Mendix, Coinbase, Facebook Open Source and many [individual sponsors](#backers)
15
+ MobX is proudly sponsored by Mendix, Coinbase, Facebook Open Source, Canva, Algolia, Guilded, Auction Frontier, Mantro and TalentPlot for 100\$/month or more! And beyond that by many [individual backers](#backers) and through [one time contributions](https://github.com/mobxjs/mobx/blob/master/sponsors.md).
16
16
 
17
- <img src="docs/mendix-logo.png" align="center" width="100" title="Mendix" alt="Mendix" /> <img src="docs/coinbase.jpeg" align="center" width="100" title="Coinbase" alt="Coinbase" /> <img src="docs/fbos.jpeg" align="center" width="100" title="Facebook Open Source" alt="Facebook Open Source" />
17
+ **🥇Gold sponsors (\$250+ pm):** <br/>
18
+ <a href="https://mendix.com/"><img src="docs/assets/mendix-logo.png" align="center" width="100" title="Mendix" alt="Mendix" /></a>
19
+ <a href="http://auctionfrontier.com/"><img src="docs/assets/auctionfrontier.jpeg" align="center" width="100" title="Auction Frontier" alt="Auction Frontier"></a>
20
+
21
+ **🥈Silver sponsors (\$100+ pm):**<br/>
22
+ <a href="https://opensource.facebook.com/"><img src="docs/assets/fbos.jpeg" align="center" width="100" title="Facebook Open Source" alt="Facebook Open Source" /></a>
23
+ <a href="https://www.canva.com/"><img src="docs/assets/canva.png" align="center" width="100" title="Canva" alt="Canva" /></a>
24
+ <a href="https://www.guilded.gg/"><img src="docs/assets/guilded.jpg" align="center" width="100" title="Guilded" alt="Guilded" /></a>
25
+ <a href="https://mantro.net/jobs/warlock"><img src="docs/assets/mantro.png" align="center" width="100" title="mantro GmbH" alt="mantro GmbH"></a>
26
+ <a href="https://www.codefirst.co.uk/"><img src="docs/assets/codefirst.png" align="center" width="100" title="CodeFirst" alt="CodeFirst"/></a>
27
+ <a href="https://blokt.com/"><img src="docs/assets/blokt.jpg" align="center" width="100" title="Blokt" alt="Blokt"/></a>
28
+ <a href="https://www.bugsnag.com/platforms/react-error-reporting?utm_source=MobX&utm_medium=Website&utm_content=open-source&utm_campaign=2019-community&utm_term=20190913"><img src="docs/assets/bugsnag.jpg" align="center" width="100" title="Bugsnag" alt="Bugsnag"/></a>
29
+
30
+ **🥉Bronze sponsors (\$500+ total contributions):**<br/>
31
+ <a href="https://coinbase.com/"><img src="docs/assets/coinbase.jpeg" align="center" width="100" title="Coinbase" alt="Coinbase" /></a>
32
+ <a href="https://www.algolia.com/"><img src="docs/assets/algolia.jpg" align="center" width="100" title="Algolia" alt="Algolia" /></a>
33
+ <a href="https://talentplot.com/"><img src="docs/assets/talentplot.png" align="center" width="100" title="talentplot" alt="talentplot"></a>
34
+ <a href="https://frontendmasters.com/"><img src="docs/assets/frontendmasters.jpg" align="center" width="100" title="Frontend Masters" alt="Frontend Masters"></a>
35
+ <a href="https://careers.dazn.com/"><img src="docs/assets/dazn.png" align="center" width="100" title="DAZN" alt="DAZN"></a>
18
36
 
19
37
  # Installation
20
38
 
21
- * Installation: `npm install mobx --save`. React bindings: `npm install mobx-react --save`. To enable ESNext decorators (optional), see below.
22
- * CDN:
23
- - https://unpkg.com/mobx/lib/mobx.umd.js
24
- - https://cdnjs.com/libraries/mobx
39
+ - Installation: `npm install mobx --save`. React bindings: `npm install mobx-react --save`. To enable ESNext decorators (optional), see below.
40
+ - CDN:
41
+ - https://unpkg.com/mobx/lib/mobx.umd.js
42
+ - https://cdnjs.com/libraries/mobx
43
+
44
+ _Tip: Consider using the faster and smaller ES6 build if targetting a modern environment: `lib/mobx.es6.js`. For example by setting up a webpack alias: `resolve: { alias: { mobx: __dirname + "/node_modules/mobx/lib/mobx.es6.js" }}`_
45
+
46
+ # Browser support
47
+
48
+ | MobX version | Actively supported | Supported browsers | GitHub branch |
49
+ | ------------ | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
50
+ | 5.\* | Yes | Any browser that supports [ES6 Proxies](https://kangax.github.io/compat-table/es6/#test-Proxy) (non polyfillable). _NOT:_ IE 11 and lower, Node 5 and lower | `master` |
51
+ | 4.\* | Yes (LTS) | Any ES5 compliant browser | `mobx4-master` |
52
+ | 1-3.\* | No | Any ES5 compliant browser | No active branch |
53
+
54
+ - All modern browsers are supported.
55
+ - MobX >=5 runs on any browser with [ES6 proxy support](https://kangax.github.io/compat-table/es6/#test-Proxy). In practice this means:
56
+ - no Internet Explorer (Edge is fine)
57
+ - Node.js >= 6
58
+ - React Native:
59
+ - iOS >= 10
60
+ - Android from RN 0.59 (or with manual JavaScript core [upgrade](https://github.com/react-community/jsc-android-buildscripts#how-to-use-it-with-my-react-native-app))
61
+ - Hermes runtime is [not supported](https://github.com/facebook/hermes/issues/28) (Use MobX 4 instead)
62
+ - MobX 4 runs on any ES5 browser and will be actively maintained. The MobX 4 and 5 api's are the same and semantically can achieve the same, but MobX 4 has some [limitations](#mobx-4-vs-mobx-5).
63
+ - The latest versions of libraries like mobx-react, mobx-react-lite, mobx-state-tree etc are kept compatible with both MobX 4 and 5.
25
64
 
26
65
  ## Translations
27
66
 
28
- * [中文](http://cn.mobx.js.org)
67
+ - [中文](http://cn.mobx.js.org)
29
68
 
30
69
  ## Getting started
31
70
 
32
- * <i><a style="color: white; background:green;padding:5px;margin:5px;border-radius:2px" href="https://egghead.io/courses/manage-complex-state-in-react-apps-with-mobx">Egghead.io course</a></i>
33
- * [Ten minute, interactive MobX + React tutorial](https://mobxjs.github.io/mobx/getting-started.html)
34
- * [Official MobX 4 documentation and API overview](https://mobxjs.github.io/mobx/refguide/api.html) ([MobX 3](https://github.com/mobxjs/mobx/blob/54557dc319b04e92e31cb87427bef194ec1c549c/docs/refguide/api.md), [MobX 2](https://github.com/mobxjs/mobx/blob/7c9e7c86e0c6ead141bb0539d33143d0e1f576dd/docs/refguide/api.md))
35
- * Videos:
36
- * [ReactNext 2016: Real World MobX](https://www.youtube.com/watch?v=Aws40KOx90U) - 40m [slides](https://docs.google.com/presentation/d/1DrI6Hc2xIPTLBkfNH8YczOcPXQTOaCIcDESdyVfG_bE/edit?usp=sharing)
37
- * [Practical React with MobX](https://www.youtube.com/watch?v=XGwuM_u7UeQ). In depth introduction and explanation to MobX and React by Matt Ruby on OpenSourceNorth (ES5 only) - 42m.
38
- * LearnCode.academy MobX tutorial [Part I: MobX + React is AWESOME (7m)](https://www.youtube.com/watch?v=_q50BXqkAfI) [Part II: Computed Values and Nested/Referenced Observables (12m.)](https://www.youtube.com/watch?v=nYvNqKrl69s)
39
- * [Screencast: intro to MobX](https://www.youtube.com/watch?v=K8dr8BMU7-8) - 8m
40
- * [Talk: State Management Is Easy, React Amsterdam 2016 conf](https://www.youtube.com/watch?v=ApmSsu3qnf0&feature=youtu.be) ([slides](https://speakerdeck.com/mweststrate/state-management-is-easy-introduction-to-mobx))
41
- * [Boilerplates and related projects](http://mobxjs.github.io/mobx/faq/boilerplates.html)
42
- * More tutorials, blogs, videos, and other helpful resources can be found on the [MobX awesome list](https://github.com/mobxjs/awesome-mobx#awesome-mobx)
43
-
71
+ - <i><a style="color: white; background:green;padding:5px;margin:5px;border-radius:2px" href="https://egghead.io/courses/manage-complex-state-in-react-apps-with-mobx">Egghead.io course</a></i>
72
+ - [Ten minute, interactive MobX + React tutorial](https://mobxjs.github.io/mobx/getting-started)
73
+ - <img src="docs/assets/book.jpg" height="80px"/> [The MobX book](https://books.google.nl/books?id=ALFmDwAAQBAJ&pg=PP1&lpg=PP1&dq=michel+weststrate+mobx+quick+start+guide:+supercharge+the+client+state+in+your+react+apps+with+mobx&source=bl&ots=D460fxti0F&sig=ivDGTxsPNwlOjLHrpKF1nweZFl8&hl=nl&sa=X&ved=2ahUKEwiwl8XO--ncAhWPmbQKHWOYBqIQ6AEwAnoECAkQAQ#v=onepage&q=michel%20weststrate%20mobx%20quick%20start%20guide%3A%20supercharge%20the%20client%20state%20in%20your%20react%20apps%20with%20mobx&f=false) by Pavan Podila and Michel Weststrate (which despite its name is in-depth!)
74
+ - [Official MobX 4 documentation and API overview](https://mobxjs.github.io/mobx/refguide/api.html) ([MobX 3](https://github.com/mobxjs/mobx/blob/54557dc319b04e92e31cb87427bef194ec1c549c/docs/refguide/api.md), [MobX 2](https://github.com/mobxjs/mobx/blob/7c9e7c86e0c6ead141bb0539d33143d0e1f576dd/docs/refguide/api.md))
75
+ - [How to (not) use decorators](https://mobx.js.org/best/decorators.html)
76
+ - Videos:
77
+ - [ReactNext 2016: Real World MobX](https://www.youtube.com/watch?v=Aws40KOx90U) - 40m [slides](https://docs.google.com/presentation/d/1DrI6Hc2xIPTLBkfNH8YczOcPXQTOaCIcDESdyVfG_bE/edit?usp=sharing)
78
+ - [Practical React with MobX](https://www.youtube.com/watch?v=XGwuM_u7UeQ). In depth introduction and explanation to MobX and React by Matt Ruby on OpenSourceNorth (ES5 only) - 42m.
79
+ - LearnCode.academy MobX tutorial [Part I: MobX + React is AWESOME (7m)](https://www.youtube.com/watch?v=_q50BXqkAfI) [Part II: Computed Values and Nested/Referenced Observables (12m.)](https://www.youtube.com/watch?v=nYvNqKrl69s)
80
+ - [Screencast: intro to MobX](https://www.youtube.com/watch?v=K8dr8BMU7-8) - 8m
81
+ - [Talk: State Management Is Easy, React Amsterdam 2016 conf](https://www.youtube.com/watch?v=ApmSsu3qnf0&feature=youtu.be) ([slides](https://speakerdeck.com/mweststrate/state-management-is-easy-introduction-to-mobx))
82
+ - Boilerplates [MobX awesome list](https://github.com/mobxjs/awesome-mobx#boilerplates)
83
+ - Related projects [MobX awesome list](https://github.com/mobxjs/awesome-mobx#related-projects-and-utilities)
84
+ - More tutorials, blogs, videos, and other helpful resources can be found on the [MobX awesome list](https://github.com/mobxjs/awesome-mobx#awesome-mobx)
44
85
 
45
86
  ## Introduction
46
87
 
47
- MobX is a battle tested library that makes state management simple and scalable by transparently applying functional reactive programming (TFRP).
48
- The philosophy behind MobX is very simple:
88
+ MobX is a battle tested, simple and scalable state management library transparently applying functional reactive programming (TFRP). The Mobx design principle is very simple:
49
89
 
50
90
  _Anything that can be derived from the application state, should be derived. Automatically._
51
91
 
52
- which includes the UI, data serialization, server communication, etc.
92
+ This includes the UI, data serialization, server communication, etc.
53
93
 
54
- <img alt="MobX unidirectional flow" src="docs/flow.png" align="center" />
94
+ <img alt="MobX unidirectional flow" src="/docs/assets/flow.png" align="center" />
55
95
 
56
96
  React and MobX together are a powerful combination. React renders the application state by providing mechanisms to translate it into a tree of renderable components. MobX provides the mechanism to store and update the application state that React then uses.
57
97
 
58
- Both React and MobX provide optimal and unique solutions to common problems in application development. React provides mechanisms to optimally render UI by using a virtual DOM that reduces the number of costly DOM mutations. MobX provides mechanisms to optimally synchronize application state with your React components by using a reactive virtual dependency state graph that is only updated when strictly needed and is never stale.
98
+ Both React and MobX provide optimal and unique solutions to common problems in application development. React provides mechanisms to optimally render the UI by using a virtual DOM that reduces the number of costly DOM mutations. MobX provides mechanisms to optimally synchronize application state with React components by using a reactive virtual dependency state graph that is only updated when strictly needed and is never stale.
59
99
 
60
100
  ## Core concepts
61
101
 
@@ -72,27 +112,27 @@ This can simply be done by annotating your class properties with the [@observabl
72
112
  import { observable } from "mobx"
73
113
 
74
114
  class Todo {
75
- id = Math.random();
76
- @observable title = "";
77
- @observable finished = false;
115
+ id = Math.random()
116
+ @observable title = ""
117
+ @observable finished = false
78
118
  }
79
119
  ```
80
120
 
81
121
  Using `observable` is like turning a property of an object into a spreadsheet cell.
82
- But unlike spreadsheets, these values can be not only primitive values, but also references, objects and arrays.
122
+ But, unlike spreadsheets, these values can be not only primitive values, but also references, objects and arrays.
83
123
 
84
124
  If your environment doesn't support decorator syntax, don't worry.
85
125
  You can read [here](http://mobxjs.github.io/mobx/best/decorators.html) about how to set them up.
86
126
  Or you can skip them altoghether, as MobX can be used fine without decorator _syntax_, by leveraging the _decorate_ utility.
87
- Many MobX users do prefer the decorator syntax though, as it is slightly more concise.
127
+ Many MobX users prefer the slightly more concise decorator syntax, but the following snippet achieves the same:
88
128
 
89
129
  ```javascript
90
130
  import { decorate, observable } from "mobx"
91
131
 
92
132
  class Todo {
93
- id = Math.random();
94
- title = "";
95
- finished = false;
133
+ id = Math.random()
134
+ title = ""
135
+ finished = false
96
136
  }
97
137
  decorate(Todo, {
98
138
  title: observable,
@@ -109,9 +149,10 @@ By using the [`@computed`](http://mobxjs.github.io/mobx/refguide/computed-decora
109
149
 
110
150
  ```javascript
111
151
  class TodoList {
112
- @observable todos = [];
113
- @computed get unfinishedTodoCount() {
114
- return this.todos.filter(todo => !todo.finished).length;
152
+ @observable todos = []
153
+ @computed
154
+ get unfinishedTodoCount() {
155
+ return this.todos.filter(todo => !todo.finished).length
115
156
  }
116
157
  }
117
158
  ```
@@ -133,36 +174,39 @@ In short, reactions bridge [reactive](https://en.wikipedia.org/wiki/Reactive_pro
133
174
  If you are using React, you can turn your (stateless function) components into reactive components by simply adding the [`observer`](http://mobxjs.github.io/mobx/refguide/observer-component.html) function / decorator from the `mobx-react` package onto them.
134
175
 
135
176
  ```javascript
136
- import React, {Component} from 'react';
137
- import ReactDOM from 'react-dom';
138
- import {observer} from 'mobx-react';
177
+ import React, { Component } from "react"
178
+ import ReactDOM from "react-dom"
179
+ import { observer } from "mobx-react"
139
180
 
140
181
  @observer
141
182
  class TodoListView extends Component {
142
183
  render() {
143
- return <div>
144
- <ul>
145
- {this.props.todoList.todos.map(todo =>
146
- <TodoView todo={todo} key={todo.id} />
147
- )}
148
- </ul>
149
- Tasks left: {this.props.todoList.unfinishedTodoCount}
150
- </div>
184
+ return (
185
+ <div>
186
+ <ul>
187
+ {this.props.todoList.todos.map(todo => (
188
+ <TodoView todo={todo} key={todo.id} />
189
+ ))}
190
+ </ul>
191
+ Tasks left: {this.props.todoList.unfinishedTodoCount}
192
+ </div>
193
+ )
151
194
  }
152
195
  }
153
196
 
154
- const TodoView = observer(({todo}) =>
197
+ const TodoView = observer(({ todo }) => (
155
198
  <li>
156
199
  <input
157
200
  type="checkbox"
158
201
  checked={todo.finished}
159
- onClick={() => todo.finished = !todo.finished}
160
- />{todo.title}
202
+ onClick={() => (todo.finished = !todo.finished)}
203
+ />
204
+ {todo.title}
161
205
  </li>
162
- )
206
+ ))
163
207
 
164
- const store = new TodoList();
165
- ReactDOM.render(<TodoListView todoList={store} />, document.getElementById('mount'));
208
+ const store = new TodoList()
209
+ ReactDOM.render(<TodoListView todoList={store} />, document.getElementById("mount"))
166
210
  ```
167
211
 
168
212
  `observer` turns React (function) components into derivations of the data they render.
@@ -171,6 +215,7 @@ All components render smartly but are defined in a dumb manner. MobX will simply
171
215
  However, if you would remove the `Tasks left` line (or put it into a separate component), the `TodoListView` will no longer re-render when ticking a box. You can verify this yourself by changing the [JSFiddle](https://jsfiddle.net/mweststrate/wv3yopo0/).
172
216
 
173
217
  #### Custom reactions
218
+
174
219
  Custom reactions can simply be created using the [`autorun`](http://mobxjs.github.io/mobx/refguide/autorun.html),
175
220
  [`reaction`](http://mobxjs.github.io/mobx/refguide/reaction.html) or [`when`](http://mobxjs.github.io/mobx/refguide/when.html) functions to fit your specific situations.
176
221
 
@@ -178,7 +223,7 @@ For example the following `autorun` prints a log message each time the amount of
178
223
 
179
224
  ```javascript
180
225
  autorun(() => {
181
- console.log("Tasks left: " + todos.unfinishedTodoCount)
226
+ console.log(`Tasks left: ${todos.unfinishedTodoCount}`)
182
227
  })
183
228
  ```
184
229
 
@@ -188,7 +233,7 @@ Why does a new message get printed each time the `unfinishedTodoCount` is change
188
233
 
189
234
  _MobX reacts to any existing observable property that is read during the execution of a tracked function._
190
235
 
191
- For an in-depth explanation about how MobX determines to which observables needs to be reacted, check [understanding what MobX reacts to](https://github.com/mobxjs/mobx/blob/gh-pages/docs/best/react.md).
236
+ For an in-depth explanation about how MobX determines to which observables needs to be reacted, check [understanding what MobX reacts to](https://mobx.js.org/best/react.html).
192
237
 
193
238
  ### Actions
194
239
 
@@ -196,22 +241,19 @@ For an in-depth explanation about how MobX determines to which observables needs
196
241
 
197
242
  Unlike many flux frameworks, MobX is unopinionated about how user events should be handled.
198
243
 
199
- * This can be done in a Flux like manner.
200
- * Or by processing events using RxJS.
201
- * Or by simply handling events in the most straightforward way possible, as demonstrated in the above `onClick` handler.
244
+ - This can be done in a Flux like manner.
245
+ - Or by processing events using RxJS.
246
+ - Or by simply handling events in the most straightforward way possible, as demonstrated in the above `onClick` handler.
202
247
 
203
- In the end it all boils down to: Somehow the state should be updated.
248
+ In the end it all boils down to: somehow the state should be updated.
204
249
 
205
- After updating the state `MobX` will take care of the rest in an efficient, glitch-free manner. So simple statements, like below, are enough to automatically update the user interface.
250
+ After updating the state `MobX` will take care of the rest in an efficient, glitch-free manner. So, simple statements, like the ones below, are enough to automatically update the user interface.
206
251
 
207
- There is no technical need for firing events, calling a dispatcher or what more. A React component in the end is nothing more than a fancy representation of your state. A derivation that will be managed by MobX.
252
+ There is no technical need for firing events, calling a dispatcher, etc. A React component in the end is nothing more than a fancy representation of your state, i.e. a derivation that will be managed by MobX.
208
253
 
209
254
  ```javascript
210
- store.todos.push(
211
- new Todo("Get Coffee"),
212
- new Todo("Write simpler code")
213
- );
214
- store.todos[0].finished = true;
255
+ store.todos.push(new Todo("Get Coffee"), new Todo("Write simpler code"))
256
+ store.todos[0].finished = true
215
257
  ```
216
258
 
217
259
  Nonetheless, MobX has an optional built-in concept of [`actions`](https://mobxjs.github.io/mobx/refguide/action.html).
@@ -220,17 +262,17 @@ Use them to your advantage; they will help you to structure your code better and
220
262
 
221
263
  ## MobX: Simple and scalable
222
264
 
223
- MobX is one of the least obtrusive libraries you can use for state management. That makes the `MobX` approach not just simple, but very scalable as well:
265
+ MobX is a simple, very scaleable and unobtrusive state management library.
224
266
 
225
267
  ### Using classes and real references
226
268
 
227
- With MobX you don't need to normalize your data. This makes the library very suitable for very complex domain models (At Mendix for example ~500 different domain classes in a single application).
269
+ With MobX you don't need to normalize your data. This makes the library very suitable for very complex domain models. (At Mendix, for example, there are ~500 different domain classes in a single application.)
228
270
 
229
271
  ### Referential integrity is guaranteed
230
272
 
231
- Since data doesn't need to be normalized, and MobX automatically tracks the relations between state and derivations, you get referential integrity for free. Rendering something that is accessed through three levels of indirection?
273
+ Since data doesn't need to be normalized and MobX automatically tracks the relations between state and derivations, you get referential integrity for free.
232
274
 
233
- No problem, MobX will track them and re-render whenever one of the references changes. As a result staleness bugs are a thing of the past. As a programmer you might forget that changing some data might influence a seemingly unrelated component in a corner case. MobX won't forget.
275
+ Rendering something that is accessed through three levels of indirection? No problem. MobX will track them and re-render whenever one of the references changes. As a result, staleness bugs are eliminated. As a programmer, you might forget that changing some data might influence a seemingly unrelated component, but MobX won't forget.
234
276
 
235
277
  ### Simpler actions are easier to maintain
236
278
 
@@ -238,45 +280,46 @@ As demonstrated above, modifying state when using MobX is very straightforward.
238
280
 
239
281
  ### Fine grained observability is efficient
240
282
 
241
- MobX builds a graph of all the derivations in your application to find the least number of re-computations that is needed to prevent staleness. "Derive everything" might sound expensive, MobX builds a virtual derivation graph to minimize the number of recomputations needed to keep derivations in sync with the state.
283
+ MobX builds a graph of all the derivations in your application to find the least number of re-computations that are needed to prevent staleness. "Derive everything" might sound expensive, but MobX builds a virtual derivation graph to minimize the number of recomputations needed to keep derivations in sync with the state.
242
284
 
243
285
  In fact, when testing MobX at Mendix we found out that using this library to track the relations in our code is often a lot more efficient than pushing changes through our application by using handwritten events or "smart" selector based container components.
244
286
 
245
287
  The simple reason is that MobX will establish far more fine grained 'listeners' on your data than you would do as a programmer.
246
288
 
247
- Secondly MobX sees the causality between derivations so it can order them in such a way that no derivation has to run twice or introduces a glitch.
289
+ Secondly, MobX sees the causality between derivations, so it can order them in such a way that no derivation has to run twice or introduce a glitch.
248
290
 
249
291
  How that works? See this [in-depth explanation of MobX](https://medium.com/@mweststrate/becoming-fully-reactive-an-in-depth-explanation-of-mobservable-55995262a254).
250
292
 
251
293
  ### Easy interoperability
252
294
 
253
- MobX works with plain javascript structures. Due to its unobtrusiveness it works with most javascript libraries out of the box, without needing MobX specific library flavors.
295
+ MobX works with plain JavaScript structures. Due to its unobtrusiveness, it works with most JavaScript libraries out of the box without needing MobX specific library add-ons.
254
296
 
255
- So you can simply keep using your existing router, data fetching, and utility libraries like `react-router`, `director`, `superagent`, `lodash` etc.
297
+ So, you can simply keep using your existing router, data fetching, and utility libraries like `react-router`, `director`, `superagent`, `lodash`, etc.
256
298
 
257
- For the same reason you can use it out of the box both server and client side, in isomorphic applications and with react-native.
299
+ For the same reason, you can use it with both server and client side, isomorphic and react-native applications.
258
300
 
259
- The result of this is that you often need to learn less new concepts when using MobX in comparison to other state management solutions.
301
+ The result of this is that you often need to learn fewer new concepts when using MobX in comparison to other state management solutions.
260
302
 
261
303
  ---
262
304
 
263
-
264
305
  ## Credits
265
306
 
266
- MobX is inspired by reactive programming principles as found in spreadsheets. It is inspired by MVVM frameworks like in MeteorJS tracker, knockout and Vue.js. But MobX brings Transparent Functional Reactive Programming to the next level and provides a stand alone implementation. It implements TFRP in a glitch-free, synchronous, predictable and efficient manner.
307
+ MobX is inspired by reactive programming principles found in spreadsheets. It is inspired by MVVM frameworks such as MeteorJS tracker, Knockout and Vue.js. But, MobX brings Transparent Functional Reactive Programming to the next level and provides a stand alone implementation. It implements TFRP in a glitch-free, synchronous, predictable and efficient manner.
267
308
 
268
- A ton of credits for [Mendix](https://github.com/mendix), for providing the flexibility and support to maintain MobX and the chance to proof the philosophy of MobX in a real, complex, performance critical applications.
309
+ A ton of credit goes to [Mendix](https://github.com/mendix) for providing the flexibility and support to maintain MobX and the chance to prove the philosophy of MobX in real, complex, performance critical applications.
269
310
 
270
- And finally kudos for all the people that believed in, tried, validated and even [sponsored](https://github.com/mobxjs/mobx/blob/master/sponsors.md) MobX.
311
+ And finally, kudos to all the people that believed in, tried, validated and even [sponsored](https://github.com/mobxjs/mobx/blob/master/sponsors.md) MobX.
271
312
 
272
313
  ## Further resources and documentation
273
314
 
274
- * [MobX homepage](http://mobxjs.github.io/mobx/faq/blogs.html)
275
- * [API overview](http://mobxjs.github.io/mobx/refguide/api.html)
276
- * [Tutorials, Blogs & Videos](http://mobxjs.github.io/mobx/faq/blogs.html)
277
- * [Boilerplates](http://mobxjs.github.io/mobx/faq/boilerplates.html)
278
- * [Related projects](http://mobxjs.github.io/mobx/faq/related.html)
279
-
315
+ - <img src="docs/assets/book.jpg" height="80px"/> [The MobX book](https://books.google.nl/books?id=ALFmDwAAQBAJ&pg=PP1&lpg=PP1&dq=michel+weststrate+mobx+quick+start+guide:+supercharge+the+client+state+in+your+react+apps+with+mobx&source=bl&ots=D460fxti0F&sig=ivDGTxsPNwlOjLHrpKF1nweZFl8&hl=nl&sa=X&ved=2ahUKEwiwl8XO--ncAhWPmbQKHWOYBqIQ6AEwAnoECAkQAQ#v=onepage&q=michel%20weststrate%20mobx%20quick%20start%20guide%3A%20supercharge%20the%20client%20state%20in%20your%20react%20apps%20with%20mobx&f=false) by Pavan Podila and Michel Weststrate (which despite its name is in-depth!)
316
+ - [MobX homepage](http://mobxjs.github.io)
317
+ - [API overview](http://mobxjs.github.io/mobx/refguide/api.html)
318
+ - [Tutorials](https://github.com/mobxjs/awesome-mobx#tutorials)
319
+ - [Blogs](https://github.com/mobxjs/awesome-mobx#blogs)
320
+ - [Videos](https://github.com/mobxjs/awesome-mobx#videos)
321
+ - [Boilerplates](https://github.com/mobxjs/awesome-mobx#boilerplates)
322
+ - [MobX awesome list](https://github.com/mobxjs/awesome-mobx#awesome-mobx)
280
323
 
281
324
  ## What others are saying...
282
325
 
@@ -292,26 +335,44 @@ And finally kudos for all the people that believed in, tried, validated and even
292
335
 
293
336
  > The #mobx is the way I always want things to be! It's really surprising simple and fast! Totally awesome! Don't miss it!
294
337
 
338
+ > I've been using MobX for over 2 years now, and it _still_ feels like cheating! 😎
339
+
295
340
  ## Contributing
296
341
 
297
- * Feel free to send small pull requests. Please discuss new features or big changes in a GitHub issue first.
298
- * Use `npm test` to run the basic test suite, `npm run coverage` for the test suite with coverage and `npm run perf` for the performance tests.
342
+ - Feel free to send small pull requests. Please discuss new features or big changes in a GitHub issue first.
343
+ - Use `yarn test` to run the basic test suite.
344
+ - Use `yarn test:ci` for the test suite with coverage.
345
+ - and `yarn test:performance` for the performance tests.
346
+ - Please note that if you want to backport a feature / fix to MobX 4 a second PR needs to be opened to the mobx4-master branch.
347
+
348
+ # MobX 4 vs MobX 5
349
+
350
+ The difference between MobX 4 and MobX 5 is that the latter uses Proxies to do property tracking. As a consequence, MobX 5 runs only on Proxy supporting browsers, in contrast to MobX 4 that runs on any ES 5 environment.
351
+
352
+ The most notable limitations of MobX 4:
353
+
354
+ - Observable arrays are not real arrays, so they won't pass the `Array.isArray()` check. The practical consequence is that you often need to `.slice()` the array first (to get a real array shallow copy) before passing to third party libraries.
355
+ - Adding properties to existing observable objects after creation is not automatically picked up. Instead, either use observable maps or use the the built-in [utility functions](https://mobx.js.org/refguide/object-api.html) to read / write / iterate objects that you want to dynamically add properties to.
356
+
357
+ For more details see the [caveats page](https://mobx.js.org/best/pitfalls.html).
299
358
 
300
359
  ## Flow support
301
- MobX ships with [flow typings](flow-typed/mobx.js). Flow will automatically include them when you import mobx modules. Although you **do not** need to import the types explicitly, you can still do it like this: `import type { ... } from 'mobx'`.
360
+
361
+ MobX ships with [flow typings](flow-typed/mobx.js). Flow will automatically include them when you import MobX modules. Although you **do not** need to import the types explicitly, you can still do it like this: `import type { ... } from 'mobx'`.
302
362
 
303
363
  To use the [flow typings](flow-typed/mobx.js) shipped with MobX:
304
364
 
305
- * In `.flowconfig`, you **cannot** ignore `node_modules`.
306
- * In `.flowconfig`, you **cannot** import it explicitly in the `[libs]` section.
307
- * You **do not** need to install library definition using [flow-typed](https://github.com/flowtype/flow-typed).
365
+ - In `.flowconfig`, you **cannot** ignore `node_modules`.
366
+ - In `.flowconfig`, you **cannot** import it explicitly in the `[libs]` section.
367
+ - You **do not** need to install library definition using [flow-typed](https://github.com/flowtype/flow-typed).
308
368
 
309
369
  ## Donating
310
370
 
311
371
  Was MobX key in making your project a success?
312
- Join our [open collective](https://opencollective.com/mobx#) or use the [donate button](https://mobxjs.github.io/mobx/donate.html)!
372
+ Join our [open collective](https://opencollective.com/mobx#)!
313
373
 
314
374
  ### Backers
375
+
315
376
  Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/mobx#backer)]
316
377
 
317
378
  <a href="https://opencollective.com/mobx/backer/0/website" target="_blank"><img src="https://opencollective.com/mobx/backer/0/avatar.svg"></a>
@@ -375,10 +436,6 @@ Support us with a monthly donation and help us continue our activities. [[Become
375
436
  <a href="https://opencollective.com/mobx/backer/58/website" target="_blank"><img src="https://opencollective.com/mobx/backer/58/avatar.svg"></a>
376
437
  <a href="https://opencollective.com/mobx/backer/59/website" target="_blank"><img src="https://opencollective.com/mobx/backer/59/avatar.svg"></a>
377
438
 
378
- One time donations through paypal are welcome as well and are recorded in the [sponsors](sponsors.md) list.
379
-
380
- [![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://mobxjs.github.io/mobx/donate.html)
381
-
382
439
  ### Sponsors
383
440
 
384
441
  Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/mobx#sponsor)]
@@ -1,25 +1,13 @@
1
- import { IAction } from "../internal";
2
- export interface IActionFactory {
3
- <A1, R, T extends (a1: A1) => R>(fn: T): T & IAction;
4
- <A1, A2, R, T extends (a1: A1, a2: A2) => R>(fn: T): T & IAction;
5
- <A1, A2, A3, R, T extends (a1: A1, a2: A2, a3: A3) => R>(fn: T): T & IAction;
6
- <A1, A2, A3, A4, R, T extends (a1: A1, a2: A2, a3: A3, a4: A4) => R>(fn: T): T & IAction;
7
- <A1, A2, A3, A4, A5, R, T extends (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => R>(fn: T): T & IAction;
8
- <A1, A2, A3, A4, A5, A6, R, T extends (a1: A1, a2: A2, a3: A3, a4: A4, a6: A6) => R>(fn: T): T & IAction;
9
- <A1, R, T extends (a1: A1) => R>(name: string, fn: T): T & IAction;
10
- <A1, A2, R, T extends (a1: A1, a2: A2) => R>(name: string, fn: T): T & IAction;
11
- <A1, A2, A3, R, T extends (a1: A1, a2: A2, a3: A3) => R>(name: string, fn: T): T & IAction;
12
- <A1, A2, A3, A4, R, T extends (a1: A1, a2: A2, a3: A3, a4: A4) => R>(name: string, fn: T): T & IAction;
13
- <A1, A2, A3, A4, A5, R, T extends (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => R>(name: string, fn: T): T & IAction;
14
- <A1, A2, A3, A4, A5, A6, R, T extends (a1: A1, a2: A2, a3: A3, a4: A4, a6: A6) => R>(name: string, fn: T): T & IAction;
15
- <T extends Function>(fn: T): T & IAction;
16
- <T extends Function>(name: string, fn: T): T & IAction;
17
- (customName: string): (target: Object, key: string | symbol, baseDescriptor?: PropertyDescriptor) => void;
18
- (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor): void;
19
- bound(target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor): void;
20
- }
21
- export declare const action: IActionFactory;
22
- export declare function runInAction<T>(block: () => T): T;
23
- export declare function runInAction<T>(name: string, block: () => T): T;
24
- export declare function isAction(thing: any): boolean;
25
- export declare function defineBoundAction(target: any, propertyName: string, fn: Function): void;
1
+ import { IAction } from "../internal";
2
+ export interface IActionFactory {
3
+ <T extends Function | null | undefined>(fn: T): T & IAction;
4
+ <T extends Function | null | undefined>(name: string, fn: T): T & IAction;
5
+ (customName: string): (target: Object, key: string | symbol, baseDescriptor?: PropertyDescriptor) => void;
6
+ (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor): void;
7
+ bound(target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor): void;
8
+ }
9
+ export declare const action: IActionFactory;
10
+ export declare function runInAction<T>(block: () => T): T;
11
+ export declare function runInAction<T>(name: string, block: () => T): T;
12
+ export declare function isAction(thing: any): boolean;
13
+ export declare function defineBoundAction(target: any, propertyName: string, fn: Function): void;
@@ -1,16 +1,27 @@
1
- import { BabelDescriptor } from "../internal";
2
- declare function dontReassignFields(): void;
3
- export declare function namedActionDecorator(name: string): (target: any, prop: any, descriptor: BabelDescriptor) => any;
4
- export declare function actionFieldDecorator(name: string): (target: any, prop: any, descriptor: any) => void;
5
- export declare function boundActionDecorator(target: any, propertyName: any, descriptor: any, applyToInstance?: boolean): {
6
- configurable: boolean;
7
- enumerable: boolean;
8
- get(): any;
9
- set: typeof dontReassignFields;
10
- } | {
11
- enumerable: boolean;
12
- configurable: boolean;
13
- set(v: any): void;
14
- get(): undefined;
15
- } | null;
16
- export {};
1
+ import { BabelDescriptor } from "../internal";
2
+ declare function dontReassignFields(): void;
3
+ export declare function namedActionDecorator(name: string): (target: any, prop: any, descriptor: BabelDescriptor) => void | {
4
+ value: Function & import("../internal").IAction;
5
+ enumerable: boolean;
6
+ configurable: boolean;
7
+ writable: boolean;
8
+ } | {
9
+ enumerable: boolean;
10
+ configurable: boolean;
11
+ writable: boolean;
12
+ initializer(): Function & import("../internal").IAction;
13
+ value?: undefined;
14
+ };
15
+ export declare function actionFieldDecorator(name: string): (target: any, prop: any, descriptor: any) => void;
16
+ export declare function boundActionDecorator(target: any, propertyName: any, descriptor: any, applyToInstance?: boolean): {
17
+ configurable: boolean;
18
+ enumerable: boolean;
19
+ get(): any;
20
+ set: typeof dontReassignFields;
21
+ } | {
22
+ enumerable: boolean;
23
+ configurable: boolean;
24
+ set(v: any): void;
25
+ get(): undefined;
26
+ } | null;
27
+ export {};
@@ -1,24 +1,24 @@
1
- import { IReactionPublic, IReactionDisposer, IEqualsComparer } from "../internal";
2
- export interface IAutorunOptions {
3
- delay?: number;
4
- name?: string;
5
- /**
6
- * Experimental.
7
- * Warns if the view doesn't track observables
8
- */
9
- requiresObservable?: boolean;
10
- scheduler?: (callback: () => void) => any;
11
- onError?: (error: any) => void;
12
- }
13
- /**
14
- * Creates a named reactive view and keeps it alive, so that the view is always
15
- * updated if one of the dependencies changes, even when the view is not further used by something else.
16
- * @param view The reactive view
17
- * @returns disposer function, which can be used to stop the view from being updated in the future.
18
- */
19
- export declare function autorun(view: (r: IReactionPublic) => any, opts?: IAutorunOptions): IReactionDisposer;
20
- export declare type IReactionOptions = IAutorunOptions & {
21
- fireImmediately?: boolean;
22
- equals?: IEqualsComparer<any>;
23
- };
24
- export declare function reaction<T>(expression: (r: IReactionPublic) => T, effect: (arg: T, r: IReactionPublic) => void, opts?: IReactionOptions): IReactionDisposer;
1
+ import { IReactionPublic, IReactionDisposer, IEqualsComparer } from "../internal";
2
+ export interface IAutorunOptions {
3
+ delay?: number;
4
+ name?: string;
5
+ /**
6
+ * Experimental.
7
+ * Warns if the view doesn't track observables
8
+ */
9
+ requiresObservable?: boolean;
10
+ scheduler?: (callback: () => void) => any;
11
+ onError?: (error: any) => void;
12
+ }
13
+ /**
14
+ * Creates a named reactive view and keeps it alive, so that the view is always
15
+ * updated if one of the dependencies changes, even when the view is not further used by something else.
16
+ * @param view The reactive view
17
+ * @returns disposer function, which can be used to stop the view from being updated in the future.
18
+ */
19
+ export declare function autorun(view: (r: IReactionPublic) => any, opts?: IAutorunOptions): IReactionDisposer;
20
+ export declare type IReactionOptions = IAutorunOptions & {
21
+ fireImmediately?: boolean;
22
+ equals?: IEqualsComparer<any>;
23
+ };
24
+ export declare function reaction<T>(expression: (r: IReactionPublic) => T, effect: (arg: T, r: IReactionPublic) => void, opts?: IReactionOptions): IReactionDisposer;
@@ -1,5 +1,5 @@
1
- import { IObservableArray, IObservable, IComputedValue, ObservableMap, ObservableSet, Lambda } from "../internal";
2
- export declare function onBecomeObserved(value: IObservable | IComputedValue<any> | IObservableArray<any> | ObservableMap<any, any> | ObservableSet<any>, listener: Lambda): Lambda;
3
- export declare function onBecomeObserved<K, V = any>(value: ObservableMap<K, V> | Object, property: K, listener: Lambda): Lambda;
4
- export declare function onBecomeUnobserved(value: IObservable | IComputedValue<any> | IObservableArray<any> | ObservableMap<any, any> | ObservableSet<any>, listener: Lambda): Lambda;
5
- export declare function onBecomeUnobserved<K, V = any>(value: ObservableMap<K, V> | Object, property: K, listener: Lambda): Lambda;
1
+ import { IObservableArray, IObservable, IComputedValue, ObservableMap, ObservableSet, Lambda } from "../internal";
2
+ export declare function onBecomeObserved(value: IObservable | IComputedValue<any> | IObservableArray<any> | ObservableMap<any, any> | ObservableSet<any>, listener: Lambda): Lambda;
3
+ export declare function onBecomeObserved<K, V = any>(value: ObservableMap<K, V> | Object, property: K, listener: Lambda): Lambda;
4
+ export declare function onBecomeUnobserved(value: IObservable | IComputedValue<any> | IObservableArray<any> | ObservableMap<any, any> | ObservableSet<any>, listener: Lambda): Lambda;
5
+ export declare function onBecomeUnobserved<K, V = any>(value: ObservableMap<K, V> | Object, property: K, listener: Lambda): Lambda;