UNPKG

146 kBJavaScriptView Raw
1(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.mobx = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2(function (global){
3/** MobX - (c) Michel Weststrate 2015, 2016 - MIT Licensed */
4'use strict';
5
6Object.defineProperty(exports, '__esModule', { value: true });
7
8/*! *****************************************************************************
9Copyright (c) Microsoft Corporation. All rights reserved.
10Licensed under the Apache License, Version 2.0 (the "License"); you may not use
11this file except in compliance with the License. You may obtain a copy of the
12License at http://www.apache.org/licenses/LICENSE-2.0
13
14THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17MERCHANTABLITY OR NON-INFRINGEMENT.
18
19See the Apache Version 2.0 License for specific language governing permissions
20and limitations under the License.
21***************************************************************************** */
22/* global Reflect, Promise */
23
24var extendStatics = Object.setPrototypeOf ||
25 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
26 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
27
28function __extends(d, b) {
29 extendStatics(d, b);
30 function __() { this.constructor = d; }
31 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
32}
33
34/**
35 * Anything that can be used to _store_ state is an Atom in mobx. Atoms have two important jobs
36 *
37 * 1) detect when they are being _used_ and report this (using reportObserved). This allows mobx to make the connection between running functions and the data they used
38 * 2) they should notify mobx whenever they have _changed_. This way mobx can re-run any functions (derivations) that are using this atom.
39 */
40var BaseAtom = (function () {
41 /**
42 * Create a new atom. For debugging purposes it is recommended to give it a name.
43 * The onBecomeObserved and onBecomeUnobserved callbacks can be used for resource management.
44 */
45 function BaseAtom(name) {
46 if (name === void 0) { name = "Atom@" + getNextId(); }
47 this.name = name;
48 this.isPendingUnobservation = true; // for effective unobserving. BaseAtom has true, for extra optimization, so its onBecomeUnobserved never gets called, because it's not needed
49 this.observers = [];
50 this.observersIndexes = {};
51 this.diffValue = 0;
52 this.lastAccessedBy = 0;
53 this.lowestObserverState = exports.IDerivationState.NOT_TRACKING;
54 }
55 BaseAtom.prototype.onBecomeUnobserved = function () {
56 // noop
57 };
58 /**
59 * Invoke this method to notify mobx that your atom has been used somehow.
60 */
61 BaseAtom.prototype.reportObserved = function () {
62 reportObserved(this);
63 };
64 /**
65 * Invoke this method _after_ this method has changed to signal mobx that all its observers should invalidate.
66 */
67 BaseAtom.prototype.reportChanged = function () {
68 startBatch();
69 propagateChanged(this);
70 endBatch();
71 };
72 BaseAtom.prototype.toString = function () {
73 return this.name;
74 };
75 return BaseAtom;
76}());
77var Atom = (function (_super) {
78 __extends(Atom, _super);
79 /**
80 * Create a new atom. For debugging purposes it is recommended to give it a name.
81 * The onBecomeObserved and onBecomeUnobserved callbacks can be used for resource management.
82 */
83 function Atom(name, onBecomeObservedHandler, onBecomeUnobservedHandler) {
84 if (name === void 0) { name = "Atom@" + getNextId(); }
85 if (onBecomeObservedHandler === void 0) { onBecomeObservedHandler = noop; }
86 if (onBecomeUnobservedHandler === void 0) { onBecomeUnobservedHandler = noop; }
87 var _this = _super.call(this, name) || this;
88 _this.name = name;
89 _this.onBecomeObservedHandler = onBecomeObservedHandler;
90 _this.onBecomeUnobservedHandler = onBecomeUnobservedHandler;
91 _this.isPendingUnobservation = false; // for effective unobserving.
92 _this.isBeingTracked = false;
93 return _this;
94 }
95 Atom.prototype.reportObserved = function () {
96 startBatch();
97 _super.prototype.reportObserved.call(this);
98 if (!this.isBeingTracked) {
99 this.isBeingTracked = true;
100 this.onBecomeObservedHandler();
101 }
102 endBatch();
103 return !!globalState.trackingDerivation;
104 // return doesn't really give useful info, because it can be as well calling computed which calls atom (no reactions)
105 // also it could not trigger when calculating reaction dependent on Atom because Atom's value was cached by computed called by given reaction.
106 };
107 Atom.prototype.onBecomeUnobserved = function () {
108 this.isBeingTracked = false;
109 this.onBecomeUnobservedHandler();
110 };
111 return Atom;
112}(BaseAtom));
113var isAtom = createInstanceofPredicate("Atom", BaseAtom);
114
115function hasInterceptors(interceptable) {
116 return interceptable.interceptors && interceptable.interceptors.length > 0;
117}
118function registerInterceptor(interceptable, handler) {
119 var interceptors = interceptable.interceptors || (interceptable.interceptors = []);
120 interceptors.push(handler);
121 return once(function () {
122 var idx = interceptors.indexOf(handler);
123 if (idx !== -1)
124 interceptors.splice(idx, 1);
125 });
126}
127function interceptChange(interceptable, change) {
128 var prevU = untrackedStart();
129 try {
130 var interceptors = interceptable.interceptors;
131 if (interceptors)
132 for (var i = 0, l = interceptors.length; i < l; i++) {
133 change = interceptors[i](change);
134 invariant(!change || change.type, "Intercept handlers should return nothing or a change object");
135 if (!change)
136 break;
137 }
138 return change;
139 }
140 finally {
141 untrackedEnd(prevU);
142 }
143}
144
145function hasListeners(listenable) {
146 return listenable.changeListeners && listenable.changeListeners.length > 0;
147}
148function registerListener(listenable, handler) {
149 var listeners = listenable.changeListeners || (listenable.changeListeners = []);
150 listeners.push(handler);
151 return once(function () {
152 var idx = listeners.indexOf(handler);
153 if (idx !== -1)
154 listeners.splice(idx, 1);
155 });
156}
157function notifyListeners(listenable, change) {
158 var prevU = untrackedStart();
159 var listeners = listenable.changeListeners;
160 if (!listeners)
161 return;
162 listeners = listeners.slice();
163 for (var i = 0, l = listeners.length; i < l; i++) {
164 listeners[i](change);
165 }
166 untrackedEnd(prevU);
167}
168
169function isSpyEnabled() {
170 return !!globalState.spyListeners.length;
171}
172function spyReport(event) {
173 if (!globalState.spyListeners.length)
174 return;
175 var listeners = globalState.spyListeners;
176 for (var i = 0, l = listeners.length; i < l; i++)
177 listeners[i](event);
178}
179function spyReportStart(event) {
180 var change = objectAssign({}, event, { spyReportStart: true });
181 spyReport(change);
182}
183var END_EVENT = { spyReportEnd: true };
184function spyReportEnd(change) {
185 if (change)
186 spyReport(objectAssign({}, change, END_EVENT));
187 else
188 spyReport(END_EVENT);
189}
190function spy(listener) {
191 globalState.spyListeners.push(listener);
192 return once(function () {
193 var idx = globalState.spyListeners.indexOf(listener);
194 if (idx !== -1)
195 globalState.spyListeners.splice(idx, 1);
196 });
197}
198
199function iteratorSymbol() {
200 return (typeof Symbol === "function" && Symbol.iterator) || "@@iterator";
201}
202var IS_ITERATING_MARKER = "__$$iterating";
203function arrayAsIterator(array) {
204 // returning an array for entries(), values() etc for maps was a mis-interpretation of the specs..,
205 // yet it is quite convenient to be able to use the response both as array directly and as iterator
206 // it is suboptimal, but alas...
207 invariant(array[IS_ITERATING_MARKER] !== true, "Illegal state: cannot recycle array as iterator");
208 addHiddenFinalProp(array, IS_ITERATING_MARKER, true);
209 var idx = -1;
210 addHiddenFinalProp(array, "next", function next() {
211 idx++;
212 return {
213 done: idx >= this.length,
214 value: idx < this.length ? this[idx] : undefined
215 };
216 });
217 return array;
218}
219function declareIterator(prototType, iteratorFactory) {
220 addHiddenFinalProp(prototType, iteratorSymbol(), iteratorFactory);
221}
222
223var MAX_SPLICE_SIZE = 10000; // See e.g. https://github.com/mobxjs/mobx/issues/859
224// Detects bug in safari 9.1.1 (or iOS 9 safari mobile). See #364
225var safariPrototypeSetterInheritanceBug = (function () {
226 var v = false;
227 var p = {};
228 Object.defineProperty(p, "0", {
229 set: function () {
230 v = true;
231 }
232 });
233 Object.create(p)["0"] = 1;
234 return v === false;
235})();
236/**
237 * This array buffer contains two lists of properties, so that all arrays
238 * can recycle their property definitions, which significantly improves performance of creating
239 * properties on the fly.
240 */
241var OBSERVABLE_ARRAY_BUFFER_SIZE = 0;
242// Typescript workaround to make sure ObservableArray extends Array
243var StubArray = (function () {
244 function StubArray() {
245 }
246 return StubArray;
247}());
248function inherit(ctor, proto) {
249 if (typeof Object["setPrototypeOf"] !== "undefined") {
250 Object["setPrototypeOf"](ctor.prototype, proto);
251 }
252 else if (typeof ctor.prototype.__proto__ !== "undefined") {
253 ctor.prototype.__proto__ = proto;
254 }
255 else {
256 ctor["prototype"] = proto;
257 }
258}
259inherit(StubArray, Array.prototype);
260// Weex freeze Array.prototype
261// Make them writeable and configurable in prototype chain
262// https://github.com/alibaba/weex/pull/1529
263if (Object.isFrozen(Array)) {
264
265 [
266 "constructor",
267 "push",
268 "shift",
269 "concat",
270 "pop",
271 "unshift",
272 "replace",
273 "find",
274 "findIndex",
275 "splice",
276 "reverse",
277 "sort"
278 ].forEach(function (key) {
279 Object.defineProperty(StubArray.prototype, key, {
280 configurable: true,
281 writable: true,
282 value: Array.prototype[key]
283 });
284 });
285}
286var ObservableArrayAdministration = (function () {
287 function ObservableArrayAdministration(name, enhancer, array, owned) {
288 this.array = array;
289 this.owned = owned;
290 this.values = [];
291 this.lastKnownLength = 0;
292 this.interceptors = null;
293 this.changeListeners = null;
294 this.atom = new BaseAtom(name || "ObservableArray@" + getNextId());
295 this.enhancer = function (newV, oldV) { return enhancer(newV, oldV, name + "[..]"); };
296 }
297 ObservableArrayAdministration.prototype.dehanceValue = function (value) {
298 if (this.dehancer !== undefined)
299 return this.dehancer(value);
300 return value;
301 };
302 ObservableArrayAdministration.prototype.dehanceValues = function (values) {
303 if (this.dehancer !== undefined)
304 return values.map(this.dehancer);
305 return values;
306 };
307 ObservableArrayAdministration.prototype.intercept = function (handler) {
308 return registerInterceptor(this, handler);
309 };
310 ObservableArrayAdministration.prototype.observe = function (listener, fireImmediately) {
311 if (fireImmediately === void 0) { fireImmediately = false; }
312 if (fireImmediately) {
313 listener({
314 object: this.array,
315 type: "splice",
316 index: 0,
317 added: this.values.slice(),
318 addedCount: this.values.length,
319 removed: [],
320 removedCount: 0
321 });
322 }
323 return registerListener(this, listener);
324 };
325 ObservableArrayAdministration.prototype.getArrayLength = function () {
326 this.atom.reportObserved();
327 return this.values.length;
328 };
329 ObservableArrayAdministration.prototype.setArrayLength = function (newLength) {
330 if (typeof newLength !== "number" || newLength < 0)
331 throw new Error("[mobx.array] Out of range: " + newLength);
332 var currentLength = this.values.length;
333 if (newLength === currentLength)
334 return;
335 else if (newLength > currentLength) {
336 var newItems = new Array(newLength - currentLength);
337 for (var i = 0; i < newLength - currentLength; i++)
338 newItems[i] = undefined; // No Array.fill everywhere...
339 this.spliceWithArray(currentLength, 0, newItems);
340 }
341 else
342 this.spliceWithArray(newLength, currentLength - newLength);
343 };
344 // adds / removes the necessary numeric properties to this object
345 ObservableArrayAdministration.prototype.updateArrayLength = function (oldLength, delta) {
346 if (oldLength !== this.lastKnownLength)
347 throw new Error("[mobx] Modification exception: the internal structure of an observable array was changed. Did you use peek() to change it?");
348 this.lastKnownLength += delta;
349 if (delta > 0 && oldLength + delta + 1 > OBSERVABLE_ARRAY_BUFFER_SIZE)
350 reserveArrayBuffer(oldLength + delta + 1);
351 };
352 ObservableArrayAdministration.prototype.spliceWithArray = function (index, deleteCount, newItems) {
353 var _this = this;
354 checkIfStateModificationsAreAllowed(this.atom);
355 var length = this.values.length;
356 if (index === undefined)
357 index = 0;
358 else if (index > length)
359 index = length;
360 else if (index < 0)
361 index = Math.max(0, length + index);
362 if (arguments.length === 1)
363 deleteCount = length - index;
364 else if (deleteCount === undefined || deleteCount === null)
365 deleteCount = 0;
366 else
367 deleteCount = Math.max(0, Math.min(deleteCount, length - index));
368 if (newItems === undefined)
369 newItems = [];
370 if (hasInterceptors(this)) {
371 var change = interceptChange(this, {
372 object: this.array,
373 type: "splice",
374 index: index,
375 removedCount: deleteCount,
376 added: newItems
377 });
378 if (!change)
379 return EMPTY_ARRAY;
380 deleteCount = change.removedCount;
381 newItems = change.added;
382 }
383 newItems = newItems.map(function (v) { return _this.enhancer(v, undefined); });
384 var lengthDelta = newItems.length - deleteCount;
385 this.updateArrayLength(length, lengthDelta); // create or remove new entries
386 var res = this.spliceItemsIntoValues(index, deleteCount, newItems);
387 if (deleteCount !== 0 || newItems.length !== 0)
388 this.notifyArraySplice(index, newItems, res);
389 return this.dehanceValues(res);
390 };
391 ObservableArrayAdministration.prototype.spliceItemsIntoValues = function (index, deleteCount, newItems) {
392 if (newItems.length < MAX_SPLICE_SIZE) {
393 return (_a = this.values).splice.apply(_a, [index, deleteCount].concat(newItems));
394 }
395 else {
396 var res = this.values.slice(index, index + deleteCount);
397 this.values = this.values
398 .slice(0, index)
399 .concat(newItems, this.values.slice(index + deleteCount));
400 return res;
401 }
402 var _a;
403 };
404 ObservableArrayAdministration.prototype.notifyArrayChildUpdate = function (index, newValue, oldValue) {
405 var notifySpy = !this.owned && isSpyEnabled();
406 var notify = hasListeners(this);
407 var change = notify || notifySpy
408 ? {
409 object: this.array,
410 type: "update",
411 index: index,
412 newValue: newValue,
413 oldValue: oldValue
414 }
415 : null;
416 if (notifySpy)
417 spyReportStart(change);
418 this.atom.reportChanged();
419 if (notify)
420 notifyListeners(this, change);
421 if (notifySpy)
422 spyReportEnd();
423 };
424 ObservableArrayAdministration.prototype.notifyArraySplice = function (index, added, removed) {
425 var notifySpy = !this.owned && isSpyEnabled();
426 var notify = hasListeners(this);
427 var change = notify || notifySpy
428 ? {
429 object: this.array,
430 type: "splice",
431 index: index,
432 removed: removed,
433 added: added,
434 removedCount: removed.length,
435 addedCount: added.length
436 }
437 : null;
438 if (notifySpy)
439 spyReportStart(change);
440 this.atom.reportChanged();
441 // conform: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/observe
442 if (notify)
443 notifyListeners(this, change);
444 if (notifySpy)
445 spyReportEnd();
446 };
447 return ObservableArrayAdministration;
448}());
449var ObservableArray = (function (_super) {
450 __extends(ObservableArray, _super);
451 function ObservableArray(initialValues, enhancer, name, owned) {
452 if (name === void 0) { name = "ObservableArray@" + getNextId(); }
453 if (owned === void 0) { owned = false; }
454 var _this = _super.call(this) || this;
455 var adm = new ObservableArrayAdministration(name, enhancer, _this, owned);
456 addHiddenFinalProp(_this, "$mobx", adm);
457 if (initialValues && initialValues.length) {
458 _this.spliceWithArray(0, 0, initialValues);
459 }
460 if (safariPrototypeSetterInheritanceBug) {
461 // Seems that Safari won't use numeric prototype setter untill any * numeric property is
462 // defined on the instance. After that it works fine, even if this property is deleted.
463 Object.defineProperty(adm.array, "0", ENTRY_0);
464 }
465 return _this;
466 }
467 ObservableArray.prototype.intercept = function (handler) {
468 return this.$mobx.intercept(handler);
469 };
470 ObservableArray.prototype.observe = function (listener, fireImmediately) {
471 if (fireImmediately === void 0) { fireImmediately = false; }
472 return this.$mobx.observe(listener, fireImmediately);
473 };
474 ObservableArray.prototype.clear = function () {
475 return this.splice(0);
476 };
477 ObservableArray.prototype.concat = function () {
478 var arrays = [];
479 for (var _i = 0; _i < arguments.length; _i++) {
480 arrays[_i] = arguments[_i];
481 }
482 this.$mobx.atom.reportObserved();
483 return Array.prototype.concat.apply(this.peek(), arrays.map(function (a) { return (isObservableArray(a) ? a.peek() : a); }));
484 };
485 ObservableArray.prototype.replace = function (newItems) {
486 return this.$mobx.spliceWithArray(0, this.$mobx.values.length, newItems);
487 };
488 /**
489 * Converts this array back to a (shallow) javascript structure.
490 * For a deep clone use mobx.toJS
491 */
492 ObservableArray.prototype.toJS = function () {
493 return this.slice();
494 };
495 ObservableArray.prototype.toJSON = function () {
496 // Used by JSON.stringify
497 return this.toJS();
498 };
499 ObservableArray.prototype.peek = function () {
500 this.$mobx.atom.reportObserved();
501 return this.$mobx.dehanceValues(this.$mobx.values);
502 };
503 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
504 ObservableArray.prototype.find = function (predicate, thisArg, fromIndex) {
505 if (fromIndex === void 0) { fromIndex = 0; }
506 var idx = this.findIndex.apply(this, arguments);
507 return idx === -1 ? undefined : this.get(idx);
508 };
509 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
510 ObservableArray.prototype.findIndex = function (predicate, thisArg, fromIndex) {
511 if (fromIndex === void 0) { fromIndex = 0; }
512 var items = this.peek(), l = items.length;
513 for (var i = fromIndex; i < l; i++)
514 if (predicate.call(thisArg, items[i], i, this))
515 return i;
516 return -1;
517 };
518 /*
519 * functions that do alter the internal structure of the array, (based on lib.es6.d.ts)
520 * since these functions alter the inner structure of the array, the have side effects.
521 * Because the have side effects, they should not be used in computed function,
522 * and for that reason the do not call dependencyState.notifyObserved
523 */
524 ObservableArray.prototype.splice = function (index, deleteCount) {
525 var newItems = [];
526 for (var _i = 2; _i < arguments.length; _i++) {
527 newItems[_i - 2] = arguments[_i];
528 }
529 switch (arguments.length) {
530 case 0:
531 return [];
532 case 1:
533 return this.$mobx.spliceWithArray(index);
534 case 2:
535 return this.$mobx.spliceWithArray(index, deleteCount);
536 }
537 return this.$mobx.spliceWithArray(index, deleteCount, newItems);
538 };
539 ObservableArray.prototype.spliceWithArray = function (index, deleteCount, newItems) {
540 return this.$mobx.spliceWithArray(index, deleteCount, newItems);
541 };
542 ObservableArray.prototype.push = function () {
543 var items = [];
544 for (var _i = 0; _i < arguments.length; _i++) {
545 items[_i] = arguments[_i];
546 }
547 var adm = this.$mobx;
548 adm.spliceWithArray(adm.values.length, 0, items);
549 return adm.values.length;
550 };
551 ObservableArray.prototype.pop = function () {
552 return this.splice(Math.max(this.$mobx.values.length - 1, 0), 1)[0];
553 };
554 ObservableArray.prototype.shift = function () {
555 return this.splice(0, 1)[0];
556 };
557 ObservableArray.prototype.unshift = function () {
558 var items = [];
559 for (var _i = 0; _i < arguments.length; _i++) {
560 items[_i] = arguments[_i];
561 }
562 var adm = this.$mobx;
563 adm.spliceWithArray(0, 0, items);
564 return adm.values.length;
565 };
566 ObservableArray.prototype.reverse = function () {
567 // reverse by default mutates in place before returning the result
568 // which makes it both a 'derivation' and a 'mutation'.
569 // so we deviate from the default and just make it an dervitation
570 var clone = this.slice();
571 return clone.reverse.apply(clone, arguments);
572 };
573 ObservableArray.prototype.sort = function (compareFn) {
574 // sort by default mutates in place before returning the result
575 // which goes against all good practices. Let's not change the array in place!
576 var clone = this.slice();
577 return clone.sort.apply(clone, arguments);
578 };
579 ObservableArray.prototype.remove = function (value) {
580 var idx = this.$mobx.dehanceValues(this.$mobx.values).indexOf(value);
581 if (idx > -1) {
582 this.splice(idx, 1);
583 return true;
584 }
585 return false;
586 };
587 ObservableArray.prototype.move = function (fromIndex, toIndex) {
588 function checkIndex(index) {
589 if (index < 0) {
590 throw new Error("[mobx.array] Index out of bounds: " + index + " is negative");
591 }
592 var length = this.$mobx.values.length;
593 if (index >= length) {
594 throw new Error("[mobx.array] Index out of bounds: " + index + " is not smaller than " + length);
595 }
596 }
597 checkIndex.call(this, fromIndex);
598 checkIndex.call(this, toIndex);
599 if (fromIndex === toIndex) {
600 return;
601 }
602 var oldItems = this.$mobx.values;
603 var newItems;
604 if (fromIndex < toIndex) {
605 newItems = oldItems.slice(0, fromIndex).concat(oldItems.slice(fromIndex + 1, toIndex + 1), [
606 oldItems[fromIndex]
607 ], oldItems.slice(toIndex + 1));
608 }
609 else {
610 // toIndex < fromIndex
611 newItems = oldItems.slice(0, toIndex).concat([
612 oldItems[fromIndex]
613 ], oldItems.slice(toIndex, fromIndex), oldItems.slice(fromIndex + 1));
614 }
615 this.replace(newItems);
616 };
617 // See #734, in case property accessors are unreliable...
618 ObservableArray.prototype.get = function (index) {
619 var impl = this.$mobx;
620 if (impl) {
621 if (index < impl.values.length) {
622 impl.atom.reportObserved();
623 return impl.dehanceValue(impl.values[index]);
624 }
625 console.warn("[mobx.array] Attempt to read an array index (" + index + ") that is out of bounds (" + impl
626 .values
627 .length + "). Please check length first. Out of bound indices will not be tracked by MobX");
628 }
629 return undefined;
630 };
631 // See #734, in case property accessors are unreliable...
632 ObservableArray.prototype.set = function (index, newValue) {
633 var adm = this.$mobx;
634 var values = adm.values;
635 if (index < values.length) {
636 // update at index in range
637 checkIfStateModificationsAreAllowed(adm.atom);
638 var oldValue = values[index];
639 if (hasInterceptors(adm)) {
640 var change = interceptChange(adm, {
641 type: "update",
642 object: this,
643 index: index,
644 newValue: newValue
645 });
646 if (!change)
647 return;
648 newValue = change.newValue;
649 }
650 newValue = adm.enhancer(newValue, oldValue);
651 var changed = newValue !== oldValue;
652 if (changed) {
653 values[index] = newValue;
654 adm.notifyArrayChildUpdate(index, newValue, oldValue);
655 }
656 }
657 else if (index === values.length) {
658 // add a new item
659 adm.spliceWithArray(index, 0, [newValue]);
660 }
661 else {
662 // out of bounds
663 throw new Error("[mobx.array] Index out of bounds, " + index + " is larger than " + values.length);
664 }
665 };
666 return ObservableArray;
667}(StubArray));
668declareIterator(ObservableArray.prototype, function () {
669 return arrayAsIterator(this.slice());
670});
671Object.defineProperty(ObservableArray.prototype, "length", {
672 enumerable: false,
673 configurable: true,
674 get: function () {
675 return this.$mobx.getArrayLength();
676 },
677 set: function (newLength) {
678 this.$mobx.setArrayLength(newLength);
679 }
680});
681[
682 "every",
683 "filter",
684 "forEach",
685 "indexOf",
686 "join",
687 "lastIndexOf",
688 "map",
689 "reduce",
690 "reduceRight",
691 "slice",
692 "some",
693 "toString",
694 "toLocaleString"
695].forEach(function (funcName) {
696 var baseFunc = Array.prototype[funcName];
697 invariant(typeof baseFunc === "function", "Base function not defined on Array prototype: '" + funcName + "'");
698 addHiddenProp(ObservableArray.prototype, funcName, function () {
699 return baseFunc.apply(this.peek(), arguments);
700 });
701});
702/**
703 * We don't want those to show up in `for (const key in ar)` ...
704 */
705makeNonEnumerable(ObservableArray.prototype, [
706 "constructor",
707 "intercept",
708 "observe",
709 "clear",
710 "concat",
711 "get",
712 "replace",
713 "toJS",
714 "toJSON",
715 "peek",
716 "find",
717 "findIndex",
718 "splice",
719 "spliceWithArray",
720 "push",
721 "pop",
722 "set",
723 "shift",
724 "unshift",
725 "reverse",
726 "sort",
727 "remove",
728 "move",
729 "toString",
730 "toLocaleString"
731]);
732// See #364
733var ENTRY_0 = createArrayEntryDescriptor(0);
734function createArrayEntryDescriptor(index) {
735 return {
736 enumerable: false,
737 configurable: false,
738 get: function () {
739 // TODO: Check `this`?, see #752?
740 return this.get(index);
741 },
742 set: function (value) {
743 this.set(index, value);
744 }
745 };
746}
747function createArrayBufferItem(index) {
748 Object.defineProperty(ObservableArray.prototype, "" + index, createArrayEntryDescriptor(index));
749}
750function reserveArrayBuffer(max) {
751 for (var index = OBSERVABLE_ARRAY_BUFFER_SIZE; index < max; index++)
752 createArrayBufferItem(index);
753 OBSERVABLE_ARRAY_BUFFER_SIZE = max;
754}
755reserveArrayBuffer(1000);
756var isObservableArrayAdministration = createInstanceofPredicate("ObservableArrayAdministration", ObservableArrayAdministration);
757function isObservableArray(thing) {
758 return isObject(thing) && isObservableArrayAdministration(thing.$mobx);
759}
760
761var UNCHANGED = {};
762var ObservableValue = (function (_super) {
763 __extends(ObservableValue, _super);
764 function ObservableValue(value, enhancer, name, notifySpy) {
765 if (name === void 0) { name = "ObservableValue@" + getNextId(); }
766 if (notifySpy === void 0) { notifySpy = true; }
767 var _this = _super.call(this, name) || this;
768 _this.enhancer = enhancer;
769 _this.hasUnreportedChange = false;
770 _this.dehancer = undefined;
771 _this.value = enhancer(value, undefined, name);
772 if (notifySpy && isSpyEnabled()) {
773 // only notify spy if this is a stand-alone observable
774 spyReport({ type: "create", object: _this, newValue: _this.value });
775 }
776 return _this;
777 }
778 ObservableValue.prototype.dehanceValue = function (value) {
779 if (this.dehancer !== undefined)
780 return this.dehancer(value);
781 return value;
782 };
783 ObservableValue.prototype.set = function (newValue) {
784 var oldValue = this.value;
785 newValue = this.prepareNewValue(newValue);
786 if (newValue !== UNCHANGED) {
787 var notifySpy = isSpyEnabled();
788 if (notifySpy) {
789 spyReportStart({
790 type: "update",
791 object: this,
792 newValue: newValue,
793 oldValue: oldValue
794 });
795 }
796 this.setNewValue(newValue);
797 if (notifySpy)
798 spyReportEnd();
799 }
800 };
801 ObservableValue.prototype.prepareNewValue = function (newValue) {
802 checkIfStateModificationsAreAllowed(this);
803 if (hasInterceptors(this)) {
804 var change = interceptChange(this, {
805 object: this,
806 type: "update",
807 newValue: newValue
808 });
809 if (!change)
810 return UNCHANGED;
811 newValue = change.newValue;
812 }
813 // apply modifier
814 newValue = this.enhancer(newValue, this.value, this.name);
815 return this.value !== newValue ? newValue : UNCHANGED;
816 };
817 ObservableValue.prototype.setNewValue = function (newValue) {
818 var oldValue = this.value;
819 this.value = newValue;
820 this.reportChanged();
821 if (hasListeners(this)) {
822 notifyListeners(this, {
823 type: "update",
824 object: this,
825 newValue: newValue,
826 oldValue: oldValue
827 });
828 }
829 };
830 ObservableValue.prototype.get = function () {
831 this.reportObserved();
832 return this.dehanceValue(this.value);
833 };
834 ObservableValue.prototype.intercept = function (handler) {
835 return registerInterceptor(this, handler);
836 };
837 ObservableValue.prototype.observe = function (listener, fireImmediately) {
838 if (fireImmediately)
839 listener({
840 object: this,
841 type: "update",
842 newValue: this.value,
843 oldValue: undefined
844 });
845 return registerListener(this, listener);
846 };
847 ObservableValue.prototype.toJSON = function () {
848 return this.get();
849 };
850 ObservableValue.prototype.toString = function () {
851 return this.name + "[" + this.value + "]";
852 };
853 ObservableValue.prototype.valueOf = function () {
854 return toPrimitive(this.get());
855 };
856 return ObservableValue;
857}(BaseAtom));
858ObservableValue.prototype[primitiveSymbol()] = ObservableValue.prototype.valueOf;
859var isObservableValue = createInstanceofPredicate("ObservableValue", ObservableValue);
860
861var messages = {
862 m001: "It is not allowed to assign new values to @action fields",
863 m002: "`runInAction` expects a function",
864 m003: "`runInAction` expects a function without arguments",
865 m004: "autorun expects a function",
866 m005: "Warning: attempted to pass an action to autorun. Actions are untracked and will not trigger on state changes. Use `reaction` or wrap only your state modification code in an action.",
867 m006: "Warning: attempted to pass an action to autorunAsync. Actions are untracked and will not trigger on state changes. Use `reaction` or wrap only your state modification code in an action.",
868 m007: "reaction only accepts 2 or 3 arguments. If migrating from MobX 2, please provide an options object",
869 m008: "wrapping reaction expression in `asReference` is no longer supported, use options object instead",
870 m009: "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'. It looks like it was used on a property.",
871 m010: "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'",
872 m011: "First argument to `computed` should be an expression. If using computed as decorator, don't pass it arguments",
873 m012: "computed takes one or two arguments if used as function",
874 m013: "[mobx.expr] 'expr' should only be used inside other reactive functions.",
875 m014: "extendObservable expected 2 or more arguments",
876 m015: "extendObservable expects an object as first argument",
877 m016: "extendObservable should not be used on maps, use map.merge instead",
878 m017: "all arguments of extendObservable should be objects",
879 m018: "extending an object with another observable (object) is not supported. Please construct an explicit propertymap, using `toJS` if need. See issue #540",
880 m019: "[mobx.isObservable] isObservable(object, propertyName) is not supported for arrays and maps. Use map.has or array.length instead.",
881 m020: "modifiers can only be used for individual object properties",
882 m021: "observable expects zero or one arguments",
883 m022: "@observable can not be used on getters, use @computed instead",
884 m024: "whyRun() can only be used if a derivation is active, or by passing an computed value / reaction explicitly. If you invoked whyRun from inside a computation; the computation is currently suspended but re-evaluating because somebody requested its value.",
885 m025: "whyRun can only be used on reactions and computed values",
886 m026: "`action` can only be invoked on functions",
887 m028: "It is not allowed to set `useStrict` when a derivation is running",
888 m029: "INTERNAL ERROR only onBecomeUnobserved shouldn't be called twice in a row",
889 m030a: "Since strict-mode is enabled, changing observed observable values outside actions is not allowed. Please wrap the code in an `action` if this change is intended. Tried to modify: ",
890 m030b: "Side effects like changing state are not allowed at this point. Are you trying to modify state from, for example, the render function of a React component? Tried to modify: ",
891 m031: "Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: ",
892 m032: "* This computation is suspended (not in use by any reaction) and won't run automatically.\n Didn't expect this computation to be suspended at this point?\n 1. Make sure this computation is used by a reaction (reaction, autorun, observer).\n 2. Check whether you are using this computation synchronously (in the same stack as they reaction that needs it).",
893 m033: "`observe` doesn't support the fire immediately property for observable maps.",
894 m034: "`mobx.map` is deprecated, use `new ObservableMap` or `mobx.observable.map` instead",
895 m035: "Cannot make the designated object observable; it is not extensible",
896 m036: "It is not possible to get index atoms from arrays",
897 m037: "Hi there! I'm sorry you have just run into an exception.\nIf your debugger ends up here, know that some reaction (like the render() of an observer component, autorun or reaction)\nthrew an exception and that mobx caught it, to avoid that it brings the rest of your application down.\nThe original cause of the exception (the code that caused this reaction to run (again)), is still in the stack.\n\nHowever, more interesting is the actual stack trace of the error itself.\nHopefully the error is an instanceof Error, because in that case you can inspect the original stack of the error from where it was thrown.\nSee `error.stack` property, or press the very subtle \"(...)\" link you see near the console.error message that probably brought you here.\nThat stack is more interesting than the stack of this console.error itself.\n\nIf the exception you see is an exception you created yourself, make sure to use `throw new Error(\"Oops\")` instead of `throw \"Oops\"`,\nbecause the javascript environment will only preserve the original stack trace in the first form.\n\nYou can also make sure the debugger pauses the next time this very same exception is thrown by enabling \"Pause on caught exception\".\n(Note that it might pause on many other, unrelated exception as well).\n\nIf that all doesn't help you out, feel free to open an issue https://github.com/mobxjs/mobx/issues!\n",
898 m038: "Missing items in this list?\n 1. Check whether all used values are properly marked as observable (use isObservable to verify)\n 2. Make sure you didn't dereference values too early. MobX observes props, not primitives. E.g: use 'person.name' instead of 'name' in your computation.\n"
899};
900function getMessage(id) {
901 return messages[id];
902}
903
904function createAction(actionName, fn) {
905 invariant(typeof fn === "function", getMessage("m026"));
906 invariant(typeof actionName === "string" && actionName.length > 0, "actions should have valid names, got: '" + actionName + "'");
907 var res = function () {
908 return executeAction(actionName, fn, this, arguments);
909 };
910 res.originalFn = fn;
911 res.isMobxAction = true;
912 return res;
913}
914function executeAction(actionName, fn, scope, args) {
915 var runInfo = startAction(actionName, fn, scope, args);
916 try {
917 return fn.apply(scope, args);
918 }
919 finally {
920 endAction(runInfo);
921 }
922}
923function startAction(actionName, fn, scope, args) {
924 var notifySpy = isSpyEnabled() && !!actionName;
925 var startTime = 0;
926 if (notifySpy) {
927 startTime = Date.now();
928 var l = (args && args.length) || 0;
929 var flattendArgs = new Array(l);
930 if (l > 0)
931 for (var i = 0; i < l; i++)
932 flattendArgs[i] = args[i];
933 spyReportStart({
934 type: "action",
935 name: actionName,
936 fn: fn,
937 object: scope,
938 arguments: flattendArgs
939 });
940 }
941 var prevDerivation = untrackedStart();
942 startBatch();
943 var prevAllowStateChanges = allowStateChangesStart(true);
944 return {
945 prevDerivation: prevDerivation,
946 prevAllowStateChanges: prevAllowStateChanges,
947 notifySpy: notifySpy,
948 startTime: startTime
949 };
950}
951function endAction(runInfo) {
952 allowStateChangesEnd(runInfo.prevAllowStateChanges);
953 endBatch();
954 untrackedEnd(runInfo.prevDerivation);
955 if (runInfo.notifySpy)
956 spyReportEnd({ time: Date.now() - runInfo.startTime });
957}
958function useStrict(strict) {
959 invariant(globalState.trackingDerivation === null, getMessage("m028"));
960 globalState.strictMode = strict;
961 globalState.allowStateChanges = !strict;
962}
963function isStrictModeEnabled() {
964 return globalState.strictMode;
965}
966function allowStateChanges(allowStateChanges, func) {
967 // TODO: deprecate / refactor this function in next major
968 // Currently only used by `@observer`
969 // Proposed change: remove first param, rename to `forbidStateChanges`,
970 // require error callback instead of the hardcoded error message now used
971 // Use `inAction` instead of allowStateChanges in derivation.ts to check strictMode
972 var prev = allowStateChangesStart(allowStateChanges);
973 var res;
974 try {
975 res = func();
976 }
977 finally {
978 allowStateChangesEnd(prev);
979 }
980 return res;
981}
982function allowStateChangesStart(allowStateChanges) {
983 var prev = globalState.allowStateChanges;
984 globalState.allowStateChanges = allowStateChanges;
985 return prev;
986}
987function allowStateChangesEnd(prev) {
988 globalState.allowStateChanges = prev;
989}
990
991/**
992 * Constructs a decorator, that normalizes the differences between
993 * TypeScript and Babel. Mainly caused by the fact that legacy-decorator cannot assign
994 * values during instance creation to properties that have a getter setter.
995 *
996 * - Sigh -
997 *
998 * Also takes care of the difference between @decorator field and @decorator(args) field, and different forms of values.
999 * For performance (cpu and mem) reasons the properties are always defined on the prototype (at least initially).
1000 * This means that these properties despite being enumerable might not show up in Object.keys() (but they will show up in for...in loops).
1001 */
1002function createClassPropertyDecorator(
1003 /**
1004 * This function is invoked once, when the property is added to a new instance.
1005 * When this happens is not strictly determined due to differences in TS and Babel:
1006 * Typescript: Usually when constructing the new instance
1007 * Babel, sometimes Typescript: during the first get / set
1008 * Both: when calling `runLazyInitializers(instance)`
1009 */
1010 onInitialize, get, set, enumerable,
1011 /**
1012 * Can this decorator invoked with arguments? e.g. @decorator(args)
1013 */
1014 allowCustomArguments) {
1015 function classPropertyDecorator(target, key, descriptor, customArgs, argLen) {
1016 if (argLen === void 0) { argLen = 0; }
1017 invariant(allowCustomArguments || quacksLikeADecorator(arguments), "This function is a decorator, but it wasn't invoked like a decorator");
1018 if (!descriptor) {
1019 // typescript (except for getter / setters)
1020 var newDescriptor = {
1021 enumerable: enumerable,
1022 configurable: true,
1023 get: function () {
1024 if (!this.__mobxInitializedProps || this.__mobxInitializedProps[key] !== true)
1025 typescriptInitializeProperty(this, key, undefined, onInitialize, customArgs, descriptor);
1026 return get.call(this, key);
1027 },
1028 set: function (v) {
1029 if (!this.__mobxInitializedProps || this.__mobxInitializedProps[key] !== true) {
1030 typescriptInitializeProperty(this, key, v, onInitialize, customArgs, descriptor);
1031 }
1032 else {
1033 set.call(this, key, v);
1034 }
1035 }
1036 };
1037 if (arguments.length < 3 || (arguments.length === 5 && argLen < 3)) {
1038 // Typescript target is ES3, so it won't define property for us
1039 // or using Reflect.decorate polyfill, which will return no descriptor
1040 // (see https://github.com/mobxjs/mobx/issues/333)
1041 Object.defineProperty(target, key, newDescriptor);
1042 }
1043 return newDescriptor;
1044 }
1045 else {
1046 // babel and typescript getter / setter props
1047 if (!hasOwnProperty(target, "__mobxLazyInitializers")) {
1048 addHiddenProp(target, "__mobxLazyInitializers", (target.__mobxLazyInitializers && target.__mobxLazyInitializers.slice()) || [] // support inheritance
1049 );
1050 }
1051 var value_1 = descriptor.value, initializer_1 = descriptor.initializer;
1052 target.__mobxLazyInitializers.push(function (instance) {
1053 onInitialize(instance, key, initializer_1 ? initializer_1.call(instance) : value_1, customArgs, descriptor);
1054 });
1055 return {
1056 enumerable: enumerable,
1057 configurable: true,
1058 get: function () {
1059 if (this.__mobxDidRunLazyInitializers !== true)
1060 runLazyInitializers(this);
1061 return get.call(this, key);
1062 },
1063 set: function (v) {
1064 if (this.__mobxDidRunLazyInitializers !== true)
1065 runLazyInitializers(this);
1066 set.call(this, key, v);
1067 }
1068 };
1069 }
1070 }
1071 if (allowCustomArguments) {
1072 /** If custom arguments are allowed, we should return a function that returns a decorator */
1073 return function () {
1074 /** Direct invocation: @decorator bla */
1075 if (quacksLikeADecorator(arguments))
1076 return classPropertyDecorator.apply(null, arguments);
1077 /** Indirect invocation: @decorator(args) bla */
1078 var outerArgs = arguments;
1079 var argLen = arguments.length;
1080 return function (target, key, descriptor) {
1081 return classPropertyDecorator(target, key, descriptor, outerArgs, argLen);
1082 };
1083 };
1084 }
1085 return classPropertyDecorator;
1086}
1087function typescriptInitializeProperty(instance, key, v, onInitialize, customArgs, baseDescriptor) {
1088 if (!hasOwnProperty(instance, "__mobxInitializedProps"))
1089 addHiddenProp(instance, "__mobxInitializedProps", {});
1090 instance.__mobxInitializedProps[key] = true;
1091 onInitialize(instance, key, v, customArgs, baseDescriptor);
1092}
1093function runLazyInitializers(instance) {
1094 if (instance.__mobxDidRunLazyInitializers === true)
1095 return;
1096 if (instance.__mobxLazyInitializers) {
1097 addHiddenProp(instance, "__mobxDidRunLazyInitializers", true);
1098 instance.__mobxDidRunLazyInitializers &&
1099 instance.__mobxLazyInitializers.forEach(function (initializer) { return initializer(instance); });
1100 }
1101}
1102function quacksLikeADecorator(args) {
1103 return (args.length === 2 || args.length === 3) && typeof args[1] === "string";
1104}
1105
1106var actionFieldDecorator = createClassPropertyDecorator(function (target, key, value, args, originalDescriptor) {
1107 var actionName = args && args.length === 1 ? args[0] : value.name || key || "<unnamed action>";
1108 var wrappedAction = action(actionName, value);
1109 addHiddenProp(target, key, wrappedAction);
1110}, function (key) {
1111 return this[key];
1112}, function () {
1113 invariant(false, getMessage("m001"));
1114}, false, true);
1115var boundActionDecorator = createClassPropertyDecorator(function (target, key, value) {
1116 defineBoundAction(target, key, value);
1117}, function (key) {
1118 return this[key];
1119}, function () {
1120 invariant(false, getMessage("m001"));
1121}, false, false);
1122var action = function action(arg1, arg2, arg3, arg4) {
1123 if (arguments.length === 1 && typeof arg1 === "function")
1124 return createAction(arg1.name || "<unnamed action>", arg1);
1125 if (arguments.length === 2 && typeof arg2 === "function")
1126 return createAction(arg1, arg2);
1127 if (arguments.length === 1 && typeof arg1 === "string")
1128 return namedActionDecorator(arg1);
1129 return namedActionDecorator(arg2).apply(null, arguments);
1130};
1131action.bound = function boundAction(arg1, arg2, arg3) {
1132 if (typeof arg1 === "function") {
1133 var action_1 = createAction("<not yet bound action>", arg1);
1134 action_1.autoBind = true;
1135 return action_1;
1136 }
1137 return boundActionDecorator.apply(null, arguments);
1138};
1139function namedActionDecorator(name) {
1140 return function (target, prop, descriptor) {
1141 if (descriptor && typeof descriptor.value === "function") {
1142 // TypeScript @action method() { }. Defined on proto before being decorated
1143 // Don't use the field decorator if we are just decorating a method
1144 descriptor.value = createAction(name, descriptor.value);
1145 descriptor.enumerable = false;
1146 descriptor.configurable = true;
1147 return descriptor;
1148 }
1149 if (descriptor !== undefined && descriptor.get !== undefined) {
1150 throw new Error("[mobx] action is not expected to be used with getters");
1151 }
1152 // bound instance methods
1153 return actionFieldDecorator(name).apply(this, arguments);
1154 };
1155}
1156function runInAction(arg1, arg2, arg3) {
1157 var actionName = typeof arg1 === "string" ? arg1 : arg1.name || "<unnamed action>";
1158 var fn = typeof arg1 === "function" ? arg1 : arg2;
1159 var scope = typeof arg1 === "function" ? arg2 : arg3;
1160 invariant(typeof fn === "function", getMessage("m002"));
1161 invariant(fn.length === 0, getMessage("m003"));
1162 invariant(typeof actionName === "string" && actionName.length > 0, "actions should have valid names, got: '" + actionName + "'");
1163 return executeAction(actionName, fn, scope, undefined);
1164}
1165function isAction(thing) {
1166 return typeof thing === "function" && thing.isMobxAction === true;
1167}
1168function defineBoundAction(target, propertyName, fn) {
1169 var res = function () {
1170 return executeAction(propertyName, fn, target, arguments);
1171 };
1172 res.isMobxAction = true;
1173 addHiddenProp(target, propertyName, res);
1174}
1175
1176function identityComparer(a, b) {
1177 return a === b;
1178}
1179function structuralComparer(a, b) {
1180 if (typeof a === "number" && typeof b === "number" && isNaN(a) && isNaN(b)) {
1181 return true;
1182 }
1183 return deepEqual(a, b);
1184}
1185function defaultComparer(a, b) {
1186 if (typeof a === "number" && typeof b === "number" && isNaN(a) && isNaN(b)) {
1187 return true;
1188 }
1189 return identityComparer(a, b);
1190}
1191var comparer = {
1192 identity: identityComparer,
1193 structural: structuralComparer,
1194 default: defaultComparer
1195};
1196
1197function autorun(arg1, arg2, arg3) {
1198 var name, view, scope;
1199 if (typeof arg1 === "string") {
1200 name = arg1;
1201 view = arg2;
1202 scope = arg3;
1203 }
1204 else {
1205 name = arg1.name || "Autorun@" + getNextId();
1206 view = arg1;
1207 scope = arg2;
1208 }
1209 invariant(typeof view === "function", getMessage("m004"));
1210 invariant(isAction(view) === false, getMessage("m005"));
1211 if (scope)
1212 view = view.bind(scope);
1213 var reaction = new Reaction(name, function () {
1214 this.track(reactionRunner);
1215 });
1216 function reactionRunner() {
1217 view(reaction);
1218 }
1219 reaction.schedule();
1220 return reaction.getDisposer();
1221}
1222function when(arg1, arg2, arg3, arg4) {
1223 var name, predicate, effect, scope;
1224 if (typeof arg1 === "string") {
1225 name = arg1;
1226 predicate = arg2;
1227 effect = arg3;
1228 scope = arg4;
1229 }
1230 else {
1231 name = "When@" + getNextId();
1232 predicate = arg1;
1233 effect = arg2;
1234 scope = arg3;
1235 }
1236 var disposer = autorun(name, function (r) {
1237 if (predicate.call(scope)) {
1238 r.dispose();
1239 var prevUntracked = untrackedStart();
1240 effect.call(scope);
1241 untrackedEnd(prevUntracked);
1242 }
1243 });
1244 return disposer;
1245}
1246function autorunAsync(arg1, arg2, arg3, arg4) {
1247 var name, func, delay, scope;
1248 if (typeof arg1 === "string") {
1249 name = arg1;
1250 func = arg2;
1251 delay = arg3;
1252 scope = arg4;
1253 }
1254 else {
1255 name = arg1.name || "AutorunAsync@" + getNextId();
1256 func = arg1;
1257 delay = arg2;
1258 scope = arg3;
1259 }
1260 invariant(isAction(func) === false, getMessage("m006"));
1261 if (delay === void 0)
1262 delay = 1;
1263 if (scope)
1264 func = func.bind(scope);
1265 var isScheduled = false;
1266 var r = new Reaction(name, function () {
1267 if (!isScheduled) {
1268 isScheduled = true;
1269 setTimeout(function () {
1270 isScheduled = false;
1271 if (!r.isDisposed)
1272 r.track(reactionRunner);
1273 }, delay);
1274 }
1275 });
1276 function reactionRunner() {
1277 func(r);
1278 }
1279 r.schedule();
1280 return r.getDisposer();
1281}
1282function reaction(expression, effect, arg3) {
1283 if (arguments.length > 3) {
1284 fail(getMessage("m007"));
1285 }
1286 if (isModifierDescriptor(expression)) {
1287 fail(getMessage("m008"));
1288 }
1289 var opts;
1290 if (typeof arg3 === "object") {
1291 opts = arg3;
1292 }
1293 else {
1294 opts = {};
1295 }
1296 opts.name =
1297 opts.name || expression.name || effect.name || "Reaction@" + getNextId();
1298 opts.fireImmediately = arg3 === true || opts.fireImmediately === true;
1299 opts.delay = opts.delay || 0;
1300 opts.compareStructural = opts.compareStructural || opts.struct || false;
1301 // TODO: creates ugly spy events, use `effect = (r) => runInAction(opts.name, () => effect(r))` instead
1302 effect = action(opts.name, opts.context ? effect.bind(opts.context) : effect);
1303 if (opts.context) {
1304 expression = expression.bind(opts.context);
1305 }
1306 var firstTime = true;
1307 var isScheduled = false;
1308 var value;
1309 var equals = opts.equals
1310 ? opts.equals
1311 : opts.compareStructural || opts.struct ? comparer.structural : comparer.default;
1312 var r = new Reaction(opts.name, function () {
1313 if (firstTime || opts.delay < 1) {
1314 reactionRunner();
1315 }
1316 else if (!isScheduled) {
1317 isScheduled = true;
1318 setTimeout(function () {
1319 isScheduled = false;
1320 reactionRunner();
1321 }, opts.delay);
1322 }
1323 });
1324 function reactionRunner() {
1325 if (r.isDisposed)
1326 return;
1327 var changed = false;
1328 r.track(function () {
1329 var nextValue = expression(r);
1330 changed = firstTime || !equals(value, nextValue);
1331 value = nextValue;
1332 });
1333 if (firstTime && opts.fireImmediately)
1334 effect(value, r);
1335 if (!firstTime && changed === true)
1336 effect(value, r);
1337 if (firstTime)
1338 firstTime = false;
1339 }
1340 r.schedule();
1341 return r.getDisposer();
1342}
1343
1344/**
1345 * A node in the state dependency root that observes other nodes, and can be observed itself.
1346 *
1347 * ComputedValue will remember the result of the computation for the duration of the batch, or
1348 * while being observed.
1349 *
1350 * During this time it will recompute only when one of its direct dependencies changed,
1351 * but only when it is being accessed with `ComputedValue.get()`.
1352 *
1353 * Implementation description:
1354 * 1. First time it's being accessed it will compute and remember result
1355 * give back remembered result until 2. happens
1356 * 2. First time any deep dependency change, propagate POSSIBLY_STALE to all observers, wait for 3.
1357 * 3. When it's being accessed, recompute if any shallow dependency changed.
1358 * if result changed: propagate STALE to all observers, that were POSSIBLY_STALE from the last step.
1359 * go to step 2. either way
1360 *
1361 * If at any point it's outside batch and it isn't observed: reset everything and go to 1.
1362 */
1363var ComputedValue = (function () {
1364 /**
1365 * Create a new computed value based on a function expression.
1366 *
1367 * The `name` property is for debug purposes only.
1368 *
1369 * The `equals` property specifies the comparer function to use to determine if a newly produced
1370 * value differs from the previous value. Two comparers are provided in the library; `defaultComparer`
1371 * compares based on identity comparison (===), and `structualComparer` deeply compares the structure.
1372 * Structural comparison can be convenient if you always produce an new aggregated object and
1373 * don't want to notify observers if it is structurally the same.
1374 * This is useful for working with vectors, mouse coordinates etc.
1375 */
1376 function ComputedValue(derivation, scope, equals, name, setter) {
1377 this.derivation = derivation;
1378 this.scope = scope;
1379 this.equals = equals;
1380 this.dependenciesState = exports.IDerivationState.NOT_TRACKING;
1381 this.observing = []; // nodes we are looking at. Our value depends on these nodes
1382 this.newObserving = null; // during tracking it's an array with new observed observers
1383 this.isPendingUnobservation = false;
1384 this.observers = [];
1385 this.observersIndexes = {};
1386 this.diffValue = 0;
1387 this.runId = 0;
1388 this.lastAccessedBy = 0;
1389 this.lowestObserverState = exports.IDerivationState.UP_TO_DATE;
1390 this.unboundDepsCount = 0;
1391 this.__mapid = "#" + getNextId();
1392 this.value = new CaughtException(null);
1393 this.isComputing = false; // to check for cycles
1394 this.isRunningSetter = false;
1395 this.name = name || "ComputedValue@" + getNextId();
1396 if (setter)
1397 this.setter = createAction(name + "-setter", setter);
1398 }
1399 ComputedValue.prototype.onBecomeStale = function () {
1400 propagateMaybeChanged(this);
1401 };
1402 ComputedValue.prototype.onBecomeUnobserved = function () {
1403 clearObserving(this);
1404 this.value = undefined;
1405 };
1406 /**
1407 * Returns the current value of this computed value.
1408 * Will evaluate its computation first if needed.
1409 */
1410 ComputedValue.prototype.get = function () {
1411 invariant(!this.isComputing, "Cycle detected in computation " + this.name, this.derivation);
1412 if (globalState.inBatch === 0) {
1413 // This is an minor optimization which could be omitted to simplify the code
1414 // The computedValue is accessed outside of any mobx stuff. Batch observing should be enough and don't need
1415 // tracking as it will never be called again inside this batch.
1416 startBatch();
1417 if (shouldCompute(this))
1418 this.value = this.computeValue(false);
1419 endBatch();
1420 }
1421 else {
1422 reportObserved(this);
1423 if (shouldCompute(this))
1424 if (this.trackAndCompute())
1425 propagateChangeConfirmed(this);
1426 }
1427 var result = this.value;
1428 if (isCaughtException(result))
1429 throw result.cause;
1430 return result;
1431 };
1432 ComputedValue.prototype.peek = function () {
1433 var res = this.computeValue(false);
1434 if (isCaughtException(res))
1435 throw res.cause;
1436 return res;
1437 };
1438 ComputedValue.prototype.set = function (value) {
1439 if (this.setter) {
1440 invariant(!this.isRunningSetter, "The setter of computed value '" + this
1441 .name + "' is trying to update itself. Did you intend to update an _observable_ value, instead of the computed property?");
1442 this.isRunningSetter = true;
1443 try {
1444 this.setter.call(this.scope, value);
1445 }
1446 finally {
1447 this.isRunningSetter = false;
1448 }
1449 }
1450 else
1451 invariant(false, "[ComputedValue '" + this
1452 .name + "'] It is not possible to assign a new value to a computed value.");
1453 };
1454 ComputedValue.prototype.trackAndCompute = function () {
1455 if (isSpyEnabled()) {
1456 spyReport({
1457 object: this.scope,
1458 type: "compute",
1459 fn: this.derivation
1460 });
1461 }
1462 var oldValue = this.value;
1463 var newValue = (this.value = this.computeValue(true));
1464 return (isCaughtException(oldValue) ||
1465 isCaughtException(newValue) ||
1466 !this.equals(oldValue, newValue));
1467 };
1468 ComputedValue.prototype.computeValue = function (track) {
1469 this.isComputing = true;
1470 globalState.computationDepth++;
1471 var res;
1472 if (track) {
1473 res = trackDerivedFunction(this, this.derivation, this.scope);
1474 }
1475 else {
1476 try {
1477 res = this.derivation.call(this.scope);
1478 }
1479 catch (e) {
1480 res = new CaughtException(e);
1481 }
1482 }
1483 globalState.computationDepth--;
1484 this.isComputing = false;
1485 return res;
1486 };
1487 ComputedValue.prototype.observe = function (listener, fireImmediately) {
1488 var _this = this;
1489 var firstTime = true;
1490 var prevValue = undefined;
1491 return autorun(function () {
1492 var newValue = _this.get();
1493 if (!firstTime || fireImmediately) {
1494 var prevU = untrackedStart();
1495 listener({
1496 type: "update",
1497 object: _this,
1498 newValue: newValue,
1499 oldValue: prevValue
1500 });
1501 untrackedEnd(prevU);
1502 }
1503 firstTime = false;
1504 prevValue = newValue;
1505 });
1506 };
1507 ComputedValue.prototype.toJSON = function () {
1508 return this.get();
1509 };
1510 ComputedValue.prototype.toString = function () {
1511 return this.name + "[" + this.derivation.toString() + "]";
1512 };
1513 ComputedValue.prototype.valueOf = function () {
1514 return toPrimitive(this.get());
1515 };
1516 ComputedValue.prototype.whyRun = function () {
1517 var isTracking = Boolean(globalState.trackingDerivation);
1518 var observing = unique(this.isComputing ? this.newObserving : this.observing).map(function (dep) { return dep.name; });
1519 var observers = unique(getObservers(this).map(function (dep) { return dep.name; }));
1520 return ("\nWhyRun? computation '" + this.name + "':\n * Running because: " + (isTracking
1521 ? "[active] the value of this computation is needed by a reaction"
1522 : this.isComputing
1523 ? "[get] The value of this computed was requested outside a reaction"
1524 : "[idle] not running at the moment") + "\n" +
1525 (this.dependenciesState === exports.IDerivationState.NOT_TRACKING
1526 ? getMessage("m032")
1527 : " * This computation will re-run if any of the following observables changes:\n " + joinStrings(observing) + "\n " + (this.isComputing && isTracking
1528 ? " (... or any observable accessed during the remainder of the current run)"
1529 : "") + "\n\t" + getMessage("m038") + "\n\n * If the outcome of this computation changes, the following observers will be re-run:\n " + joinStrings(observers) + "\n"));
1530 };
1531 return ComputedValue;
1532}());
1533ComputedValue.prototype[primitiveSymbol()] = ComputedValue.prototype.valueOf;
1534var isComputedValue = createInstanceofPredicate("ComputedValue", ComputedValue);
1535
1536var ObservableObjectAdministration = (function () {
1537 function ObservableObjectAdministration(target, name) {
1538 this.target = target;
1539 this.name = name;
1540 this.values = {};
1541 this.changeListeners = null;
1542 this.interceptors = null;
1543 }
1544 /**
1545 * Observes this object. Triggers for the events 'add', 'update' and 'delete'.
1546 * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe
1547 * for callback details
1548 */
1549 ObservableObjectAdministration.prototype.observe = function (callback, fireImmediately) {
1550 invariant(fireImmediately !== true, "`observe` doesn't support the fire immediately property for observable objects.");
1551 return registerListener(this, callback);
1552 };
1553 ObservableObjectAdministration.prototype.intercept = function (handler) {
1554 return registerInterceptor(this, handler);
1555 };
1556 return ObservableObjectAdministration;
1557}());
1558function asObservableObject(target, name) {
1559 if (isObservableObject(target) && target.hasOwnProperty("$mobx"))
1560 return target.$mobx;
1561 invariant(Object.isExtensible(target), getMessage("m035"));
1562 if (!isPlainObject(target))
1563 name = (target.constructor.name || "ObservableObject") + "@" + getNextId();
1564 if (!name)
1565 name = "ObservableObject@" + getNextId();
1566 var adm = new ObservableObjectAdministration(target, name);
1567 addHiddenFinalProp(target, "$mobx", adm);
1568 return adm;
1569}
1570function defineObservablePropertyFromDescriptor(adm, propName, descriptor, defaultEnhancer) {
1571 if (adm.values[propName] && !isComputedValue(adm.values[propName])) {
1572 // already observable property
1573 invariant("value" in descriptor, "The property " + propName + " in " + adm.name + " is already observable, cannot redefine it as computed property");
1574 adm.target[propName] = descriptor.value; // the property setter will make 'value' reactive if needed.
1575 return;
1576 }
1577 // not yet observable property
1578 if ("value" in descriptor) {
1579 // not a computed value
1580 if (isModifierDescriptor(descriptor.value)) {
1581 // x : ref(someValue)
1582 var modifierDescriptor = descriptor.value;
1583 defineObservableProperty(adm, propName, modifierDescriptor.initialValue, modifierDescriptor.enhancer);
1584 }
1585 else if (isAction(descriptor.value) && descriptor.value.autoBind === true) {
1586 defineBoundAction(adm.target, propName, descriptor.value.originalFn);
1587 }
1588 else if (isComputedValue(descriptor.value)) {
1589 // x: computed(someExpr)
1590 defineComputedPropertyFromComputedValue(adm, propName, descriptor.value);
1591 }
1592 else {
1593 // x: someValue
1594 defineObservableProperty(adm, propName, descriptor.value, defaultEnhancer);
1595 }
1596 }
1597 else {
1598 // get x() { return 3 } set x(v) { }
1599 defineComputedProperty(adm, propName, descriptor.get, descriptor.set, comparer.default, true);
1600 }
1601}
1602function defineObservableProperty(adm, propName, newValue, enhancer) {
1603 assertPropertyConfigurable(adm.target, propName);
1604 if (hasInterceptors(adm)) {
1605 var change = interceptChange(adm, {
1606 object: adm.target,
1607 name: propName,
1608 type: "add",
1609 newValue: newValue
1610 });
1611 if (!change)
1612 return;
1613 newValue = change.newValue;
1614 }
1615 var observable = (adm.values[propName] = new ObservableValue(newValue, enhancer, adm.name + "." + propName, false));
1616 newValue = observable.value; // observableValue might have changed it
1617 Object.defineProperty(adm.target, propName, generateObservablePropConfig(propName));
1618 notifyPropertyAddition(adm, adm.target, propName, newValue);
1619}
1620function defineComputedProperty(adm, propName, getter, setter, equals, asInstanceProperty) {
1621 if (asInstanceProperty)
1622 assertPropertyConfigurable(adm.target, propName);
1623 adm.values[propName] = new ComputedValue(getter, adm.target, equals, adm.name + "." + propName, setter);
1624 if (asInstanceProperty) {
1625 Object.defineProperty(adm.target, propName, generateComputedPropConfig(propName));
1626 }
1627}
1628function defineComputedPropertyFromComputedValue(adm, propName, computedValue) {
1629 var name = adm.name + "." + propName;
1630 computedValue.name = name;
1631 if (!computedValue.scope)
1632 computedValue.scope = adm.target;
1633 adm.values[propName] = computedValue;
1634 Object.defineProperty(adm.target, propName, generateComputedPropConfig(propName));
1635}
1636var observablePropertyConfigs = {};
1637var computedPropertyConfigs = {};
1638function generateObservablePropConfig(propName) {
1639 return (observablePropertyConfigs[propName] ||
1640 (observablePropertyConfigs[propName] = {
1641 configurable: true,
1642 enumerable: true,
1643 get: function () {
1644 return this.$mobx.values[propName].get();
1645 },
1646 set: function (v) {
1647 setPropertyValue(this, propName, v);
1648 }
1649 }));
1650}
1651function generateComputedPropConfig(propName) {
1652 return (computedPropertyConfigs[propName] ||
1653 (computedPropertyConfigs[propName] = {
1654 configurable: true,
1655 enumerable: false,
1656 get: function () {
1657 return this.$mobx.values[propName].get();
1658 },
1659 set: function (v) {
1660 return this.$mobx.values[propName].set(v);
1661 }
1662 }));
1663}
1664function setPropertyValue(instance, name, newValue) {
1665 var adm = instance.$mobx;
1666 var observable = adm.values[name];
1667 // intercept
1668 if (hasInterceptors(adm)) {
1669 var change = interceptChange(adm, {
1670 type: "update",
1671 object: instance,
1672 name: name,
1673 newValue: newValue
1674 });
1675 if (!change)
1676 return;
1677 newValue = change.newValue;
1678 }
1679 newValue = observable.prepareNewValue(newValue);
1680 // notify spy & observers
1681 if (newValue !== UNCHANGED) {
1682 var notify = hasListeners(adm);
1683 var notifySpy = isSpyEnabled();
1684 var change = notify || notifySpy
1685 ? {
1686 type: "update",
1687 object: instance,
1688 oldValue: observable.value,
1689 name: name,
1690 newValue: newValue
1691 }
1692 : null;
1693 if (notifySpy)
1694 spyReportStart(change);
1695 observable.setNewValue(newValue);
1696 if (notify)
1697 notifyListeners(adm, change);
1698 if (notifySpy)
1699 spyReportEnd();
1700 }
1701}
1702function notifyPropertyAddition(adm, object, name, newValue) {
1703 var notify = hasListeners(adm);
1704 var notifySpy = isSpyEnabled();
1705 var change = notify || notifySpy
1706 ? {
1707 type: "add",
1708 object: object,
1709 name: name,
1710 newValue: newValue
1711 }
1712 : null;
1713 if (notifySpy)
1714 spyReportStart(change);
1715 if (notify)
1716 notifyListeners(adm, change);
1717 if (notifySpy)
1718 spyReportEnd();
1719}
1720var isObservableObjectAdministration = createInstanceofPredicate("ObservableObjectAdministration", ObservableObjectAdministration);
1721function isObservableObject(thing) {
1722 if (isObject(thing)) {
1723 // Initializers run lazily when transpiling to babel, so make sure they are run...
1724 runLazyInitializers(thing);
1725 return isObservableObjectAdministration(thing.$mobx);
1726 }
1727 return false;
1728}
1729
1730/**
1731 * Returns true if the provided value is reactive.
1732 * @param value object, function or array
1733 * @param property if property is specified, checks whether value.property is reactive.
1734 */
1735function isObservable(value, property) {
1736 if (value === null || value === undefined)
1737 return false;
1738 if (property !== undefined) {
1739 if (isObservableArray(value) || isObservableMap(value))
1740 throw new Error(getMessage("m019"));
1741 else if (isObservableObject(value)) {
1742 var o = value.$mobx;
1743 return o.values && !!o.values[property];
1744 }
1745 return false;
1746 }
1747 // For first check, see #701
1748 return (isObservableObject(value) ||
1749 !!value.$mobx ||
1750 isAtom(value) ||
1751 isReaction(value) ||
1752 isComputedValue(value));
1753}
1754
1755function createDecoratorForEnhancer(enhancer) {
1756 invariant(!!enhancer, ":(");
1757 return createClassPropertyDecorator(function (target, name, baseValue, _, baseDescriptor) {
1758 assertPropertyConfigurable(target, name);
1759 invariant(!baseDescriptor || !baseDescriptor.get, getMessage("m022"));
1760 var adm = asObservableObject(target, undefined);
1761 defineObservableProperty(adm, name, baseValue, enhancer);
1762 }, function (name) {
1763 var observable = this.$mobx.values[name];
1764 if (observable === undefined // See #505
1765 )
1766 return undefined;
1767 return observable.get();
1768 }, function (name, value) {
1769 setPropertyValue(this, name, value);
1770 }, true, false);
1771}
1772
1773function extendObservable(target) {
1774 var properties = [];
1775 for (var _i = 1; _i < arguments.length; _i++) {
1776 properties[_i - 1] = arguments[_i];
1777 }
1778 return extendObservableHelper(target, deepEnhancer, properties);
1779}
1780function extendShallowObservable(target) {
1781 var properties = [];
1782 for (var _i = 1; _i < arguments.length; _i++) {
1783 properties[_i - 1] = arguments[_i];
1784 }
1785 return extendObservableHelper(target, referenceEnhancer, properties);
1786}
1787function extendObservableHelper(target, defaultEnhancer, properties) {
1788 invariant(arguments.length >= 2, getMessage("m014"));
1789 invariant(typeof target === "object", getMessage("m015"));
1790 invariant(!isObservableMap(target), getMessage("m016"));
1791 properties.forEach(function (propSet) {
1792 invariant(typeof propSet === "object", getMessage("m017"));
1793 invariant(!isObservable(propSet), getMessage("m018"));
1794 });
1795 var adm = asObservableObject(target);
1796 var definedProps = {};
1797 // Note could be optimised if properties.length === 1
1798 for (var i = properties.length - 1; i >= 0; i--) {
1799 var propSet = properties[i];
1800 for (var key in propSet)
1801 if (definedProps[key] !== true && hasOwnProperty(propSet, key)) {
1802 definedProps[key] = true;
1803 if (target === propSet && !isPropertyConfigurable(target, key))
1804 continue; // see #111, skip non-configurable or non-writable props for `observable(object)`.
1805 var descriptor = Object.getOwnPropertyDescriptor(propSet, key);
1806 defineObservablePropertyFromDescriptor(adm, key, descriptor, defaultEnhancer);
1807 }
1808 }
1809 return target;
1810}
1811
1812var deepDecorator = createDecoratorForEnhancer(deepEnhancer);
1813var shallowDecorator = createDecoratorForEnhancer(shallowEnhancer);
1814var refDecorator = createDecoratorForEnhancer(referenceEnhancer);
1815var deepStructDecorator = createDecoratorForEnhancer(deepStructEnhancer);
1816var refStructDecorator = createDecoratorForEnhancer(refStructEnhancer);
1817/**
1818 * Turns an object, array or function into a reactive structure.
1819 * @param v the value which should become observable.
1820 */
1821function createObservable(v) {
1822 if (v === void 0) { v = undefined; }
1823 // @observable someProp;
1824 if (typeof arguments[1] === "string")
1825 return deepDecorator.apply(null, arguments);
1826 invariant(arguments.length <= 1, getMessage("m021"));
1827 invariant(!isModifierDescriptor(v), getMessage("m020"));
1828 // it is an observable already, done
1829 if (isObservable(v))
1830 return v;
1831 // something that can be converted and mutated?
1832 var res = deepEnhancer(v, undefined, undefined);
1833 // this value could be converted to a new observable data structure, return it
1834 if (res !== v)
1835 return res;
1836 // otherwise, just box it
1837 return observable.box(v);
1838}
1839var IObservableFactories = (function () {
1840 function IObservableFactories() {
1841 }
1842 IObservableFactories.prototype.box = function (value, name) {
1843 if (arguments.length > 2)
1844 incorrectlyUsedAsDecorator("box");
1845 return new ObservableValue(value, deepEnhancer, name);
1846 };
1847 IObservableFactories.prototype.shallowBox = function (value, name) {
1848 if (arguments.length > 2)
1849 incorrectlyUsedAsDecorator("shallowBox");
1850 return new ObservableValue(value, referenceEnhancer, name);
1851 };
1852 IObservableFactories.prototype.array = function (initialValues, name) {
1853 if (arguments.length > 2)
1854 incorrectlyUsedAsDecorator("array");
1855 return new ObservableArray(initialValues, deepEnhancer, name);
1856 };
1857 IObservableFactories.prototype.shallowArray = function (initialValues, name) {
1858 if (arguments.length > 2)
1859 incorrectlyUsedAsDecorator("shallowArray");
1860 return new ObservableArray(initialValues, referenceEnhancer, name);
1861 };
1862 IObservableFactories.prototype.map = function (initialValues, name) {
1863 if (arguments.length > 2)
1864 incorrectlyUsedAsDecorator("map");
1865 return new ObservableMap(initialValues, deepEnhancer, name);
1866 };
1867 IObservableFactories.prototype.shallowMap = function (initialValues, name) {
1868 if (arguments.length > 2)
1869 incorrectlyUsedAsDecorator("shallowMap");
1870 return new ObservableMap(initialValues, referenceEnhancer, name);
1871 };
1872 IObservableFactories.prototype.object = function (props, name) {
1873 if (arguments.length > 2)
1874 incorrectlyUsedAsDecorator("object");
1875 var res = {};
1876 // convert to observable object
1877 asObservableObject(res, name);
1878 // add properties
1879 extendObservable(res, props);
1880 return res;
1881 };
1882 IObservableFactories.prototype.shallowObject = function (props, name) {
1883 if (arguments.length > 2)
1884 incorrectlyUsedAsDecorator("shallowObject");
1885 var res = {};
1886 asObservableObject(res, name);
1887 extendShallowObservable(res, props);
1888 return res;
1889 };
1890 IObservableFactories.prototype.ref = function () {
1891 if (arguments.length < 2) {
1892 // although ref creates actually a modifier descriptor, the type of the resultig properties
1893 // of the object is `T` in the end, when the descriptors are interpreted
1894 return createModifierDescriptor(referenceEnhancer, arguments[0]);
1895 }
1896 else {
1897 return refDecorator.apply(null, arguments);
1898 }
1899 };
1900 IObservableFactories.prototype.shallow = function () {
1901 if (arguments.length < 2) {
1902 // although ref creates actually a modifier descriptor, the type of the resultig properties
1903 // of the object is `T` in the end, when the descriptors are interpreted
1904 return createModifierDescriptor(shallowEnhancer, arguments[0]);
1905 }
1906 else {
1907 return shallowDecorator.apply(null, arguments);
1908 }
1909 };
1910 IObservableFactories.prototype.deep = function () {
1911 if (arguments.length < 2) {
1912 // although ref creates actually a modifier descriptor, the type of the resultig properties
1913 // of the object is `T` in the end, when the descriptors are interpreted
1914 return createModifierDescriptor(deepEnhancer, arguments[0]);
1915 }
1916 else {
1917 return deepDecorator.apply(null, arguments);
1918 }
1919 };
1920 IObservableFactories.prototype.struct = function () {
1921 if (arguments.length < 2) {
1922 // although ref creates actually a modifier descriptor, the type of the resultig properties
1923 // of the object is `T` in the end, when the descriptors are interpreted
1924 return createModifierDescriptor(deepStructEnhancer, arguments[0]);
1925 }
1926 else {
1927 return deepStructDecorator.apply(null, arguments);
1928 }
1929 };
1930 return IObservableFactories;
1931}());
1932var observable = createObservable;
1933// weird trick to keep our typings nicely with our funcs, and still extend the observable function
1934// ES6 class methods aren't enumerable, can't use Object.keys
1935Object.getOwnPropertyNames(IObservableFactories.prototype)
1936 .filter(function (name) { return name !== "constructor"; })
1937 .forEach(function (name) { return (observable[name] = IObservableFactories.prototype[name]); });
1938observable.deep.struct = observable.struct;
1939observable.ref.struct = function () {
1940 if (arguments.length < 2) {
1941 return createModifierDescriptor(refStructEnhancer, arguments[0]);
1942 }
1943 else {
1944 return refStructDecorator.apply(null, arguments);
1945 }
1946};
1947function incorrectlyUsedAsDecorator(methodName) {
1948 fail("Expected one or two arguments to observable." + methodName + ". Did you accidentally try to use observable." + methodName + " as decorator?");
1949}
1950
1951function isModifierDescriptor(thing) {
1952 return typeof thing === "object" && thing !== null && thing.isMobxModifierDescriptor === true;
1953}
1954function createModifierDescriptor(enhancer, initialValue) {
1955 invariant(!isModifierDescriptor(initialValue), "Modifiers cannot be nested");
1956 return {
1957 isMobxModifierDescriptor: true,
1958 initialValue: initialValue,
1959 enhancer: enhancer
1960 };
1961}
1962function deepEnhancer(v, _, name) {
1963 if (isModifierDescriptor(v))
1964 fail("You tried to assign a modifier wrapped value to a collection, please define modifiers when creating the collection, not when modifying it");
1965 // it is an observable already, done
1966 if (isObservable(v))
1967 return v;
1968 // something that can be converted and mutated?
1969 if (Array.isArray(v))
1970 return observable.array(v, name);
1971 if (isPlainObject(v))
1972 return observable.object(v, name);
1973 if (isES6Map(v))
1974 return observable.map(v, name);
1975 return v;
1976}
1977function shallowEnhancer(v, _, name) {
1978 if (isModifierDescriptor(v))
1979 fail("You tried to assign a modifier wrapped value to a collection, please define modifiers when creating the collection, not when modifying it");
1980 if (v === undefined || v === null)
1981 return v;
1982 if (isObservableObject(v) || isObservableArray(v) || isObservableMap(v))
1983 return v;
1984 if (Array.isArray(v))
1985 return observable.shallowArray(v, name);
1986 if (isPlainObject(v))
1987 return observable.shallowObject(v, name);
1988 if (isES6Map(v))
1989 return observable.shallowMap(v, name);
1990 return fail("The shallow modifier / decorator can only used in combination with arrays, objects and maps");
1991}
1992function referenceEnhancer(newValue) {
1993 // never turn into an observable
1994 return newValue;
1995}
1996function deepStructEnhancer(v, oldValue, name) {
1997 // don't confuse structurally compare enhancer with ref enhancer! The latter is probably
1998 // more suited for immutable objects
1999 if (deepEqual(v, oldValue))
2000 return oldValue;
2001 // it is an observable already, done
2002 if (isObservable(v))
2003 return v;
2004 // something that can be converted and mutated?
2005 if (Array.isArray(v))
2006 return new ObservableArray(v, deepStructEnhancer, name);
2007 if (isES6Map(v))
2008 return new ObservableMap(v, deepStructEnhancer, name);
2009 if (isPlainObject(v)) {
2010 var res = {};
2011 asObservableObject(res, name);
2012 extendObservableHelper(res, deepStructEnhancer, [v]);
2013 return res;
2014 }
2015 return v;
2016}
2017function refStructEnhancer(v, oldValue, name) {
2018 if (deepEqual(v, oldValue))
2019 return oldValue;
2020 return v;
2021}
2022
2023/**
2024 * During a transaction no views are updated until the end of the transaction.
2025 * The transaction will be run synchronously nonetheless.
2026 *
2027 * @param action a function that updates some reactive state
2028 * @returns any value that was returned by the 'action' parameter.
2029 */
2030function transaction(action, thisArg) {
2031 if (thisArg === void 0) { thisArg = undefined; }
2032 startBatch();
2033 try {
2034 return action.apply(thisArg);
2035 }
2036 finally {
2037 endBatch();
2038 }
2039}
2040
2041var ObservableMapMarker = {};
2042var ObservableMap = (function () {
2043 function ObservableMap(initialData, enhancer, name) {
2044 if (enhancer === void 0) { enhancer = deepEnhancer; }
2045 if (name === void 0) { name = "ObservableMap@" + getNextId(); }
2046 this.enhancer = enhancer;
2047 this.name = name;
2048 this.$mobx = ObservableMapMarker;
2049 this._data = Object.create(null);
2050 this._hasMap = Object.create(null); // hasMap, not hashMap >-).
2051 this._keys = new ObservableArray(undefined, referenceEnhancer, this.name + ".keys()", true);
2052 this.interceptors = null;
2053 this.changeListeners = null;
2054 this.dehancer = undefined;
2055 this.merge(initialData);
2056 }
2057 ObservableMap.prototype._has = function (key) {
2058 return typeof this._data[key] !== "undefined";
2059 };
2060 ObservableMap.prototype.has = function (key) {
2061 if (!this.isValidKey(key))
2062 return false;
2063 key = "" + key;
2064 if (this._hasMap[key])
2065 return this._hasMap[key].get();
2066 return this._updateHasMapEntry(key, false).get();
2067 };
2068 ObservableMap.prototype.set = function (key, value) {
2069 this.assertValidKey(key);
2070 key = "" + key;
2071 var hasKey = this._has(key);
2072 if (hasInterceptors(this)) {
2073 var change = interceptChange(this, {
2074 type: hasKey ? "update" : "add",
2075 object: this,
2076 newValue: value,
2077 name: key
2078 });
2079 if (!change)
2080 return this;
2081 value = change.newValue;
2082 }
2083 if (hasKey) {
2084 this._updateValue(key, value);
2085 }
2086 else {
2087 this._addValue(key, value);
2088 }
2089 return this;
2090 };
2091 ObservableMap.prototype.delete = function (key) {
2092 var _this = this;
2093 this.assertValidKey(key);
2094 key = "" + key;
2095 if (hasInterceptors(this)) {
2096 var change = interceptChange(this, {
2097 type: "delete",
2098 object: this,
2099 name: key
2100 });
2101 if (!change)
2102 return false;
2103 }
2104 if (this._has(key)) {
2105 var notifySpy = isSpyEnabled();
2106 var notify = hasListeners(this);
2107 var change = notify || notifySpy
2108 ? {
2109 type: "delete",
2110 object: this,
2111 oldValue: this._data[key].value,
2112 name: key
2113 }
2114 : null;
2115 if (notifySpy)
2116 spyReportStart(change);
2117 transaction(function () {
2118 _this._keys.remove(key);
2119 _this._updateHasMapEntry(key, false);
2120 var observable$$1 = _this._data[key];
2121 observable$$1.setNewValue(undefined);
2122 _this._data[key] = undefined;
2123 });
2124 if (notify)
2125 notifyListeners(this, change);
2126 if (notifySpy)
2127 spyReportEnd();
2128 return true;
2129 }
2130 return false;
2131 };
2132 ObservableMap.prototype._updateHasMapEntry = function (key, value) {
2133 // optimization; don't fill the hasMap if we are not observing, or remove entry if there are no observers anymore
2134 var entry = this._hasMap[key];
2135 if (entry) {
2136 entry.setNewValue(value);
2137 }
2138 else {
2139 entry = this._hasMap[key] = new ObservableValue(value, referenceEnhancer, this.name + "." + key + "?", false);
2140 }
2141 return entry;
2142 };
2143 ObservableMap.prototype._updateValue = function (name, newValue) {
2144 var observable$$1 = this._data[name];
2145 newValue = observable$$1.prepareNewValue(newValue);
2146 if (newValue !== UNCHANGED) {
2147 var notifySpy = isSpyEnabled();
2148 var notify = hasListeners(this);
2149 var change = notify || notifySpy
2150 ? {
2151 type: "update",
2152 object: this,
2153 oldValue: observable$$1.value,
2154 name: name,
2155 newValue: newValue
2156 }
2157 : null;
2158 if (notifySpy)
2159 spyReportStart(change);
2160 observable$$1.setNewValue(newValue);
2161 if (notify)
2162 notifyListeners(this, change);
2163 if (notifySpy)
2164 spyReportEnd();
2165 }
2166 };
2167 ObservableMap.prototype._addValue = function (name, newValue) {
2168 var _this = this;
2169 transaction(function () {
2170 var observable$$1 = (_this._data[name] = new ObservableValue(newValue, _this.enhancer, _this.name + "." + name, false));
2171 newValue = observable$$1.value; // value might have been changed
2172 _this._updateHasMapEntry(name, true);
2173 _this._keys.push(name);
2174 });
2175 var notifySpy = isSpyEnabled();
2176 var notify = hasListeners(this);
2177 var change = notify || notifySpy
2178 ? {
2179 type: "add",
2180 object: this,
2181 name: name,
2182 newValue: newValue
2183 }
2184 : null;
2185 if (notifySpy)
2186 spyReportStart(change);
2187 if (notify)
2188 notifyListeners(this, change);
2189 if (notifySpy)
2190 spyReportEnd();
2191 };
2192 ObservableMap.prototype.get = function (key) {
2193 key = "" + key;
2194 if (this.has(key))
2195 return this.dehanceValue(this._data[key].get());
2196 return this.dehanceValue(undefined);
2197 };
2198 ObservableMap.prototype.dehanceValue = function (value) {
2199 if (this.dehancer !== undefined) {
2200 return this.dehancer(value);
2201 }
2202 return value;
2203 };
2204 ObservableMap.prototype.keys = function () {
2205 return arrayAsIterator(this._keys.slice());
2206 };
2207 ObservableMap.prototype.values = function () {
2208 return arrayAsIterator(this._keys.map(this.get, this));
2209 };
2210 ObservableMap.prototype.entries = function () {
2211 var _this = this;
2212 return arrayAsIterator(this._keys.map(function (key) { return [key, _this.get(key)]; }));
2213 };
2214 ObservableMap.prototype.forEach = function (callback, thisArg) {
2215 var _this = this;
2216 this.keys().forEach(function (key) { return callback.call(thisArg, _this.get(key), key, _this); });
2217 };
2218 /** Merge another object into this object, returns this. */
2219 ObservableMap.prototype.merge = function (other) {
2220 var _this = this;
2221 if (isObservableMap(other)) {
2222 other = other.toJS();
2223 }
2224 transaction(function () {
2225 if (isPlainObject(other))
2226 Object.keys(other).forEach(function (key) { return _this.set(key, other[key]); });
2227 else if (Array.isArray(other))
2228 other.forEach(function (_a) {
2229 var key = _a[0], value = _a[1];
2230 return _this.set(key, value);
2231 });
2232 else if (isES6Map(other))
2233 other.forEach(function (value, key) { return _this.set(key, value); });
2234 else if (other !== null && other !== undefined)
2235 fail("Cannot initialize map from " + other);
2236 });
2237 return this;
2238 };
2239 ObservableMap.prototype.clear = function () {
2240 var _this = this;
2241 transaction(function () {
2242 untracked(function () {
2243 _this.keys().forEach(_this.delete, _this);
2244 });
2245 });
2246 };
2247 ObservableMap.prototype.replace = function (values) {
2248 var _this = this;
2249 transaction(function () {
2250 _this.clear();
2251 _this.merge(values);
2252 });
2253 return this;
2254 };
2255 Object.defineProperty(ObservableMap.prototype, "size", {
2256 get: function () {
2257 return this._keys.length;
2258 },
2259 enumerable: true,
2260 configurable: true
2261 });
2262 /**
2263 * Returns a shallow non observable object clone of this map.
2264 * Note that the values might still be observable. For a deep clone use mobx.toJS.
2265 */
2266 ObservableMap.prototype.toJS = function () {
2267 var _this = this;
2268 var res = {};
2269 this.keys().forEach(function (key) { return (res[key] = _this.get(key)); });
2270 return res;
2271 };
2272 ObservableMap.prototype.toJSON = function () {
2273 // Used by JSON.stringify
2274 return this.toJS();
2275 };
2276 ObservableMap.prototype.isValidKey = function (key) {
2277 if (key === null || key === undefined)
2278 return false;
2279 if (typeof key === "string" || typeof key === "number" || typeof key === "boolean")
2280 return true;
2281 return false;
2282 };
2283 ObservableMap.prototype.assertValidKey = function (key) {
2284 if (!this.isValidKey(key))
2285 throw new Error("[mobx.map] Invalid key: '" + key + "', only strings, numbers and booleans are accepted as key in observable maps.");
2286 };
2287 ObservableMap.prototype.toString = function () {
2288 var _this = this;
2289 return (this.name +
2290 "[{ " +
2291 this.keys().map(function (key) { return key + ": " + ("" + _this.get(key)); }).join(", ") +
2292 " }]");
2293 };
2294 /**
2295 * Observes this object. Triggers for the events 'add', 'update' and 'delete'.
2296 * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe
2297 * for callback details
2298 */
2299 ObservableMap.prototype.observe = function (listener, fireImmediately) {
2300 invariant(fireImmediately !== true, getMessage("m033"));
2301 return registerListener(this, listener);
2302 };
2303 ObservableMap.prototype.intercept = function (handler) {
2304 return registerInterceptor(this, handler);
2305 };
2306 return ObservableMap;
2307}());
2308declareIterator(ObservableMap.prototype, function () {
2309 return this.entries();
2310});
2311function map(initialValues) {
2312 deprecated("`mobx.map` is deprecated, use `new ObservableMap` or `mobx.observable.map` instead");
2313 return observable.map(initialValues);
2314}
2315/* 'var' fixes small-build issue */
2316var isObservableMap = createInstanceofPredicate("ObservableMap", ObservableMap);
2317
2318var EMPTY_ARRAY = [];
2319Object.freeze(EMPTY_ARRAY);
2320function getGlobal() {
2321 return typeof window !== "undefined" ? window : global;
2322}
2323function getNextId() {
2324 return ++globalState.mobxGuid;
2325}
2326function fail(message, thing) {
2327 invariant(false, message, thing);
2328 throw "X"; // unreachable
2329}
2330function invariant(check, message, thing) {
2331 if (!check)
2332 throw new Error("[mobx] Invariant failed: " + message + (thing ? " in '" + thing + "'" : ""));
2333}
2334/**
2335 * Prints a deprecation message, but only one time.
2336 * Returns false if the deprecated message was already printed before
2337 */
2338var deprecatedMessages = [];
2339function deprecated(msg) {
2340 if (deprecatedMessages.indexOf(msg) !== -1)
2341 return false;
2342 deprecatedMessages.push(msg);
2343 console.error("[mobx] Deprecated: " + msg);
2344 return true;
2345}
2346/**
2347 * Makes sure that the provided function is invoked at most once.
2348 */
2349function once(func) {
2350 var invoked = false;
2351 return function () {
2352 if (invoked)
2353 return;
2354 invoked = true;
2355 return func.apply(this, arguments);
2356 };
2357}
2358var noop = function () { };
2359function unique(list) {
2360 var res = [];
2361 list.forEach(function (item) {
2362 if (res.indexOf(item) === -1)
2363 res.push(item);
2364 });
2365 return res;
2366}
2367function joinStrings(things, limit, separator) {
2368 if (limit === void 0) { limit = 100; }
2369 if (separator === void 0) { separator = " - "; }
2370 if (!things)
2371 return "";
2372 var sliced = things.slice(0, limit);
2373 return "" + sliced.join(separator) + (things.length > limit
2374 ? " (... and " + (things.length - limit) + "more)"
2375 : "");
2376}
2377function isObject(value) {
2378 return value !== null && typeof value === "object";
2379}
2380function isPlainObject(value) {
2381 if (value === null || typeof value !== "object")
2382 return false;
2383 var proto = Object.getPrototypeOf(value);
2384 return proto === Object.prototype || proto === null;
2385}
2386function objectAssign() {
2387 var res = arguments[0];
2388 for (var i = 1, l = arguments.length; i < l; i++) {
2389 var source = arguments[i];
2390 for (var key in source)
2391 if (hasOwnProperty(source, key)) {
2392 res[key] = source[key];
2393 }
2394 }
2395 return res;
2396}
2397var prototypeHasOwnProperty = Object.prototype.hasOwnProperty;
2398function hasOwnProperty(object, propName) {
2399 return prototypeHasOwnProperty.call(object, propName);
2400}
2401function makeNonEnumerable(object, propNames) {
2402 for (var i = 0; i < propNames.length; i++) {
2403 addHiddenProp(object, propNames[i], object[propNames[i]]);
2404 }
2405}
2406function addHiddenProp(object, propName, value) {
2407 Object.defineProperty(object, propName, {
2408 enumerable: false,
2409 writable: true,
2410 configurable: true,
2411 value: value
2412 });
2413}
2414function addHiddenFinalProp(object, propName, value) {
2415 Object.defineProperty(object, propName, {
2416 enumerable: false,
2417 writable: false,
2418 configurable: true,
2419 value: value
2420 });
2421}
2422function isPropertyConfigurable(object, prop) {
2423 var descriptor = Object.getOwnPropertyDescriptor(object, prop);
2424 return !descriptor || (descriptor.configurable !== false && descriptor.writable !== false);
2425}
2426function assertPropertyConfigurable(object, prop) {
2427 invariant(isPropertyConfigurable(object, prop), "Cannot make property '" + prop + "' observable, it is not configurable and writable in the target object");
2428}
2429function getEnumerableKeys(obj) {
2430 var res = [];
2431 for (var key in obj)
2432 res.push(key);
2433 return res;
2434}
2435/**
2436 * Naive deepEqual. Doesn't check for prototype, non-enumerable or out-of-range properties on arrays.
2437 * If you have such a case, you probably should use this function but something fancier :).
2438 */
2439function deepEqual(a, b) {
2440 if (a === null && b === null)
2441 return true;
2442 if (a === undefined && b === undefined)
2443 return true;
2444 if (typeof a !== "object")
2445 return a === b;
2446 var aIsArray = isArrayLike(a);
2447 var aIsMap = isMapLike(a);
2448 if (aIsArray !== isArrayLike(b)) {
2449 return false;
2450 }
2451 else if (aIsMap !== isMapLike(b)) {
2452 return false;
2453 }
2454 else if (aIsArray) {
2455 if (a.length !== b.length)
2456 return false;
2457 for (var i = a.length - 1; i >= 0; i--)
2458 if (!deepEqual(a[i], b[i]))
2459 return false;
2460 return true;
2461 }
2462 else if (aIsMap) {
2463 if (a.size !== b.size)
2464 return false;
2465 var equals_1 = true;
2466 a.forEach(function (value, key) {
2467 equals_1 = equals_1 && deepEqual(b.get(key), value);
2468 });
2469 return equals_1;
2470 }
2471 else if (typeof a === "object" && typeof b === "object") {
2472 if (a === null || b === null)
2473 return false;
2474 if (isMapLike(a) && isMapLike(b)) {
2475 if (a.size !== b.size)
2476 return false;
2477 // Freaking inefficient.... Create PR if you run into this :) Much appreciated!
2478 return deepEqual(observable.shallowMap(a).entries(), observable.shallowMap(b).entries());
2479 }
2480 if (getEnumerableKeys(a).length !== getEnumerableKeys(b).length)
2481 return false;
2482 for (var prop in a) {
2483 if (!(prop in b))
2484 return false;
2485 if (!deepEqual(a[prop], b[prop]))
2486 return false;
2487 }
2488 return true;
2489 }
2490 return false;
2491}
2492function createInstanceofPredicate(name, clazz) {
2493 var propName = "isMobX" + name;
2494 clazz.prototype[propName] = true;
2495 return function (x) {
2496 return isObject(x) && x[propName] === true;
2497 };
2498}
2499/**
2500 * Returns whether the argument is an array, disregarding observability.
2501 */
2502function isArrayLike(x) {
2503 return Array.isArray(x) || isObservableArray(x);
2504}
2505function isMapLike(x) {
2506 return isES6Map(x) || isObservableMap(x);
2507}
2508function isES6Map(thing) {
2509 if (getGlobal().Map !== undefined && thing instanceof getGlobal().Map)
2510 return true;
2511 return false;
2512}
2513function primitiveSymbol() {
2514 return (typeof Symbol === "function" && Symbol.toPrimitive) || "@@toPrimitive";
2515}
2516function toPrimitive(value) {
2517 return value === null ? null : typeof value === "object" ? "" + value : value;
2518}
2519
2520/**
2521 * These values will persist if global state is reset
2522 */
2523var persistentKeys = ["mobxGuid", "resetId", "spyListeners", "strictMode", "runId"];
2524var MobXGlobals = (function () {
2525 function MobXGlobals() {
2526 /**
2527 * MobXGlobals version.
2528 * MobX compatiblity with other versions loaded in memory as long as this version matches.
2529 * It indicates that the global state still stores similar information
2530 */
2531 this.version = 5;
2532 /**
2533 * Currently running derivation
2534 */
2535 this.trackingDerivation = null;
2536 /**
2537 * Are we running a computation currently? (not a reaction)
2538 */
2539 this.computationDepth = 0;
2540 /**
2541 * Each time a derivation is tracked, it is assigned a unique run-id
2542 */
2543 this.runId = 0;
2544 /**
2545 * 'guid' for general purpose. Will be persisted amongst resets.
2546 */
2547 this.mobxGuid = 0;
2548 /**
2549 * Are we in a batch block? (and how many of them)
2550 */
2551 this.inBatch = 0;
2552 /**
2553 * Observables that don't have observers anymore, and are about to be
2554 * suspended, unless somebody else accesses it in the same batch
2555 *
2556 * @type {IObservable[]}
2557 */
2558 this.pendingUnobservations = [];
2559 /**
2560 * List of scheduled, not yet executed, reactions.
2561 */
2562 this.pendingReactions = [];
2563 /**
2564 * Are we currently processing reactions?
2565 */
2566 this.isRunningReactions = false;
2567 /**
2568 * Is it allowed to change observables at this point?
2569 * In general, MobX doesn't allow that when running computations and React.render.
2570 * To ensure that those functions stay pure.
2571 */
2572 this.allowStateChanges = true;
2573 /**
2574 * If strict mode is enabled, state changes are by default not allowed
2575 */
2576 this.strictMode = false;
2577 /**
2578 * Used by createTransformer to detect that the global state has been reset.
2579 */
2580 this.resetId = 0;
2581 /**
2582 * Spy callbacks
2583 */
2584 this.spyListeners = [];
2585 /**
2586 * Globally attached error handlers that react specifically to errors in reactions
2587 */
2588 this.globalReactionErrorHandlers = [];
2589 }
2590 return MobXGlobals;
2591}());
2592var globalState = new MobXGlobals();
2593var shareGlobalStateCalled = false;
2594var runInIsolationCalled = false;
2595var warnedAboutMultipleInstances = false;
2596{
2597 var global_1 = getGlobal();
2598 if (!global_1.__mobxInstanceCount) {
2599 global_1.__mobxInstanceCount = 1;
2600 }
2601 else {
2602 global_1.__mobxInstanceCount++;
2603 setTimeout(function () {
2604 if (!shareGlobalStateCalled && !runInIsolationCalled && !warnedAboutMultipleInstances) {
2605 warnedAboutMultipleInstances = true;
2606 console.warn("[mobx] Warning: there are multiple mobx instances active. This might lead to unexpected results. See https://github.com/mobxjs/mobx/issues/1082 for details.");
2607 }
2608 });
2609 }
2610}
2611function isolateGlobalState() {
2612 runInIsolationCalled = true;
2613 getGlobal().__mobxInstanceCount--;
2614}
2615function shareGlobalState() {
2616 // TODO: remove in 4.0; just use peer dependencies instead.
2617 deprecated("Using `shareGlobalState` is not recommended, use peer dependencies instead. See https://github.com/mobxjs/mobx/issues/1082 for details.");
2618 shareGlobalStateCalled = true;
2619 var global = getGlobal();
2620 var ownState = globalState;
2621 /**
2622 * Backward compatibility check
2623 */
2624 if (global.__mobservableTrackingStack || global.__mobservableViewStack)
2625 throw new Error("[mobx] An incompatible version of mobservable is already loaded.");
2626 if (global.__mobxGlobal && global.__mobxGlobal.version !== ownState.version)
2627 throw new Error("[mobx] An incompatible version of mobx is already loaded.");
2628 if (global.__mobxGlobal)
2629 globalState = global.__mobxGlobal;
2630 else
2631 global.__mobxGlobal = ownState;
2632}
2633function getGlobalState() {
2634 return globalState;
2635}
2636
2637/**
2638 * For testing purposes only; this will break the internal state of existing observables,
2639 * but can be used to get back at a stable state after throwing errors
2640 */
2641function resetGlobalState() {
2642 globalState.resetId++;
2643 var defaultGlobals = new MobXGlobals();
2644 for (var key in defaultGlobals)
2645 if (persistentKeys.indexOf(key) === -1)
2646 globalState[key] = defaultGlobals[key];
2647 globalState.allowStateChanges = !globalState.strictMode;
2648}
2649
2650function hasObservers(observable) {
2651 return observable.observers && observable.observers.length > 0;
2652}
2653function getObservers(observable) {
2654 return observable.observers;
2655}
2656function addObserver(observable, node) {
2657 // invariant(node.dependenciesState !== -1, "INTERNAL ERROR, can add only dependenciesState !== -1");
2658 // invariant(observable._observers.indexOf(node) === -1, "INTERNAL ERROR add already added node");
2659 // invariantObservers(observable);
2660 var l = observable.observers.length;
2661 if (l) {
2662 // because object assignment is relatively expensive, let's not store data about index 0.
2663 observable.observersIndexes[node.__mapid] = l;
2664 }
2665 observable.observers[l] = node;
2666 if (observable.lowestObserverState > node.dependenciesState)
2667 observable.lowestObserverState = node.dependenciesState;
2668 // invariantObservers(observable);
2669 // invariant(observable._observers.indexOf(node) !== -1, "INTERNAL ERROR didn't add node");
2670}
2671function removeObserver(observable, node) {
2672 // invariant(globalState.inBatch > 0, "INTERNAL ERROR, remove should be called only inside batch");
2673 // invariant(observable._observers.indexOf(node) !== -1, "INTERNAL ERROR remove already removed node");
2674 // invariantObservers(observable);
2675 if (observable.observers.length === 1) {
2676 // deleting last observer
2677 observable.observers.length = 0;
2678 queueForUnobservation(observable);
2679 }
2680 else {
2681 // deleting from _observersIndexes is straight forward, to delete from _observers, let's swap `node` with last element
2682 var list = observable.observers;
2683 var map = observable.observersIndexes;
2684 var filler = list.pop(); // get last element, which should fill the place of `node`, so the array doesn't have holes
2685 if (filler !== node) {
2686 // otherwise node was the last element, which already got removed from array
2687 var index = map[node.__mapid] || 0; // getting index of `node`. this is the only place we actually use map.
2688 if (index) {
2689 // map store all indexes but 0, see comment in `addObserver`
2690 map[filler.__mapid] = index;
2691 }
2692 else {
2693 delete map[filler.__mapid];
2694 }
2695 list[index] = filler;
2696 }
2697 delete map[node.__mapid];
2698 }
2699 // invariantObservers(observable);
2700 // invariant(observable._observers.indexOf(node) === -1, "INTERNAL ERROR remove already removed node2");
2701}
2702function queueForUnobservation(observable) {
2703 if (!observable.isPendingUnobservation) {
2704 // invariant(globalState.inBatch > 0, "INTERNAL ERROR, remove should be called only inside batch");
2705 // invariant(observable._observers.length === 0, "INTERNAL ERROR, should only queue for unobservation unobserved observables");
2706 observable.isPendingUnobservation = true;
2707 globalState.pendingUnobservations.push(observable);
2708 }
2709}
2710/**
2711 * Batch starts a transaction, at least for purposes of memoizing ComputedValues when nothing else does.
2712 * During a batch `onBecomeUnobserved` will be called at most once per observable.
2713 * Avoids unnecessary recalculations.
2714 */
2715function startBatch() {
2716 globalState.inBatch++;
2717}
2718function endBatch() {
2719 if (--globalState.inBatch === 0) {
2720 runReactions();
2721 // the batch is actually about to finish, all unobserving should happen here.
2722 var list = globalState.pendingUnobservations;
2723 for (var i = 0; i < list.length; i++) {
2724 var observable = list[i];
2725 observable.isPendingUnobservation = false;
2726 if (observable.observers.length === 0) {
2727 observable.onBecomeUnobserved();
2728 // NOTE: onBecomeUnobserved might push to `pendingUnobservations`
2729 }
2730 }
2731 globalState.pendingUnobservations = [];
2732 }
2733}
2734function reportObserved(observable) {
2735 var derivation = globalState.trackingDerivation;
2736 if (derivation !== null) {
2737 /**
2738 * Simple optimization, give each derivation run an unique id (runId)
2739 * Check if last time this observable was accessed the same runId is used
2740 * if this is the case, the relation is already known
2741 */
2742 if (derivation.runId !== observable.lastAccessedBy) {
2743 observable.lastAccessedBy = derivation.runId;
2744 derivation.newObserving[derivation.unboundDepsCount++] = observable;
2745 }
2746 }
2747 else if (observable.observers.length === 0) {
2748 queueForUnobservation(observable);
2749 }
2750}
2751/**
2752 * NOTE: current propagation mechanism will in case of self reruning autoruns behave unexpectedly
2753 * It will propagate changes to observers from previous run
2754 * It's hard or maybe impossible (with reasonable perf) to get it right with current approach
2755 * Hopefully self reruning autoruns aren't a feature people should depend on
2756 * Also most basic use cases should be ok
2757 */
2758// Called by Atom when its value changes
2759function propagateChanged(observable) {
2760 // invariantLOS(observable, "changed start");
2761 if (observable.lowestObserverState === exports.IDerivationState.STALE)
2762 return;
2763 observable.lowestObserverState = exports.IDerivationState.STALE;
2764 var observers = observable.observers;
2765 var i = observers.length;
2766 while (i--) {
2767 var d = observers[i];
2768 if (d.dependenciesState === exports.IDerivationState.UP_TO_DATE)
2769 d.onBecomeStale();
2770 d.dependenciesState = exports.IDerivationState.STALE;
2771 }
2772 // invariantLOS(observable, "changed end");
2773}
2774// Called by ComputedValue when it recalculate and its value changed
2775function propagateChangeConfirmed(observable) {
2776 // invariantLOS(observable, "confirmed start");
2777 if (observable.lowestObserverState === exports.IDerivationState.STALE)
2778 return;
2779 observable.lowestObserverState = exports.IDerivationState.STALE;
2780 var observers = observable.observers;
2781 var i = observers.length;
2782 while (i--) {
2783 var d = observers[i];
2784 if (d.dependenciesState === exports.IDerivationState.POSSIBLY_STALE)
2785 d.dependenciesState = exports.IDerivationState.STALE;
2786 else if (d.dependenciesState === exports.IDerivationState.UP_TO_DATE // this happens during computing of `d`, just keep lowestObserverState up to date.
2787 )
2788 observable.lowestObserverState = exports.IDerivationState.UP_TO_DATE;
2789 }
2790 // invariantLOS(observable, "confirmed end");
2791}
2792// Used by computed when its dependency changed, but we don't wan't to immediately recompute.
2793function propagateMaybeChanged(observable) {
2794 // invariantLOS(observable, "maybe start");
2795 if (observable.lowestObserverState !== exports.IDerivationState.UP_TO_DATE)
2796 return;
2797 observable.lowestObserverState = exports.IDerivationState.POSSIBLY_STALE;
2798 var observers = observable.observers;
2799 var i = observers.length;
2800 while (i--) {
2801 var d = observers[i];
2802 if (d.dependenciesState === exports.IDerivationState.UP_TO_DATE) {
2803 d.dependenciesState = exports.IDerivationState.POSSIBLY_STALE;
2804 d.onBecomeStale();
2805 }
2806 }
2807 // invariantLOS(observable, "maybe end");
2808}
2809
2810(function (IDerivationState) {
2811 // before being run or (outside batch and not being observed)
2812 // at this point derivation is not holding any data about dependency tree
2813 IDerivationState[IDerivationState["NOT_TRACKING"] = -1] = "NOT_TRACKING";
2814 // no shallow dependency changed since last computation
2815 // won't recalculate derivation
2816 // this is what makes mobx fast
2817 IDerivationState[IDerivationState["UP_TO_DATE"] = 0] = "UP_TO_DATE";
2818 // some deep dependency changed, but don't know if shallow dependency changed
2819 // will require to check first if UP_TO_DATE or POSSIBLY_STALE
2820 // currently only ComputedValue will propagate POSSIBLY_STALE
2821 //
2822 // having this state is second big optimization:
2823 // don't have to recompute on every dependency change, but only when it's needed
2824 IDerivationState[IDerivationState["POSSIBLY_STALE"] = 1] = "POSSIBLY_STALE";
2825 // A shallow dependency has changed since last computation and the derivation
2826 // will need to recompute when it's needed next.
2827 IDerivationState[IDerivationState["STALE"] = 2] = "STALE";
2828})(exports.IDerivationState || (exports.IDerivationState = {}));
2829var CaughtException = (function () {
2830 function CaughtException(cause) {
2831 this.cause = cause;
2832 // Empty
2833 }
2834 return CaughtException;
2835}());
2836function isCaughtException(e) {
2837 return e instanceof CaughtException;
2838}
2839/**
2840 * Finds out whether any dependency of the derivation has actually changed.
2841 * If dependenciesState is 1 then it will recalculate dependencies,
2842 * if any dependency changed it will propagate it by changing dependenciesState to 2.
2843 *
2844 * By iterating over the dependencies in the same order that they were reported and
2845 * stopping on the first change, all the recalculations are only called for ComputedValues
2846 * that will be tracked by derivation. That is because we assume that if the first x
2847 * dependencies of the derivation doesn't change then the derivation should run the same way
2848 * up until accessing x-th dependency.
2849 */
2850function shouldCompute(derivation) {
2851 switch (derivation.dependenciesState) {
2852 case exports.IDerivationState.UP_TO_DATE:
2853 return false;
2854 case exports.IDerivationState.NOT_TRACKING:
2855 case exports.IDerivationState.STALE:
2856 return true;
2857 case exports.IDerivationState.POSSIBLY_STALE: {
2858 var prevUntracked = untrackedStart(); // no need for those computeds to be reported, they will be picked up in trackDerivedFunction.
2859 var obs = derivation.observing, l = obs.length;
2860 for (var i = 0; i < l; i++) {
2861 var obj = obs[i];
2862 if (isComputedValue(obj)) {
2863 try {
2864 obj.get();
2865 }
2866 catch (e) {
2867 // we are not interested in the value *or* exception at this moment, but if there is one, notify all
2868 untrackedEnd(prevUntracked);
2869 return true;
2870 }
2871 // if ComputedValue `obj` actually changed it will be computed and propagated to its observers.
2872 // and `derivation` is an observer of `obj`
2873 if (derivation.dependenciesState === exports.IDerivationState.STALE) {
2874 untrackedEnd(prevUntracked);
2875 return true;
2876 }
2877 }
2878 }
2879 changeDependenciesStateTo0(derivation);
2880 untrackedEnd(prevUntracked);
2881 return false;
2882 }
2883 }
2884}
2885function isComputingDerivation() {
2886 return globalState.trackingDerivation !== null; // filter out actions inside computations
2887}
2888function checkIfStateModificationsAreAllowed(atom) {
2889 var hasObservers$$1 = atom.observers.length > 0;
2890 // Should never be possible to change an observed observable from inside computed, see #798
2891 if (globalState.computationDepth > 0 && hasObservers$$1)
2892 fail(getMessage("m031") + atom.name);
2893 // Should not be possible to change observed state outside strict mode, except during initialization, see #563
2894 if (!globalState.allowStateChanges && hasObservers$$1)
2895 fail(getMessage(globalState.strictMode ? "m030a" : "m030b") + atom.name);
2896}
2897/**
2898 * Executes the provided function `f` and tracks which observables are being accessed.
2899 * The tracking information is stored on the `derivation` object and the derivation is registered
2900 * as observer of any of the accessed observables.
2901 */
2902function trackDerivedFunction(derivation, f, context) {
2903 // pre allocate array allocation + room for variation in deps
2904 // array will be trimmed by bindDependencies
2905 changeDependenciesStateTo0(derivation);
2906 derivation.newObserving = new Array(derivation.observing.length + 100);
2907 derivation.unboundDepsCount = 0;
2908 derivation.runId = ++globalState.runId;
2909 var prevTracking = globalState.trackingDerivation;
2910 globalState.trackingDerivation = derivation;
2911 var result;
2912 try {
2913 result = f.call(context);
2914 }
2915 catch (e) {
2916 result = new CaughtException(e);
2917 }
2918 globalState.trackingDerivation = prevTracking;
2919 bindDependencies(derivation);
2920 return result;
2921}
2922/**
2923 * diffs newObserving with observing.
2924 * update observing to be newObserving with unique observables
2925 * notify observers that become observed/unobserved
2926 */
2927function bindDependencies(derivation) {
2928 // invariant(derivation.dependenciesState !== IDerivationState.NOT_TRACKING, "INTERNAL ERROR bindDependencies expects derivation.dependenciesState !== -1");
2929 var prevObserving = derivation.observing;
2930 var observing = (derivation.observing = derivation.newObserving);
2931 var lowestNewObservingDerivationState = exports.IDerivationState.UP_TO_DATE;
2932 // Go through all new observables and check diffValue: (this list can contain duplicates):
2933 // 0: first occurrence, change to 1 and keep it
2934 // 1: extra occurrence, drop it
2935 var i0 = 0, l = derivation.unboundDepsCount;
2936 for (var i = 0; i < l; i++) {
2937 var dep = observing[i];
2938 if (dep.diffValue === 0) {
2939 dep.diffValue = 1;
2940 if (i0 !== i)
2941 observing[i0] = dep;
2942 i0++;
2943 }
2944 // Upcast is 'safe' here, because if dep is IObservable, `dependenciesState` will be undefined,
2945 // not hitting the condition
2946 if (dep.dependenciesState > lowestNewObservingDerivationState) {
2947 lowestNewObservingDerivationState = dep.dependenciesState;
2948 }
2949 }
2950 observing.length = i0;
2951 derivation.newObserving = null; // newObserving shouldn't be needed outside tracking (statement moved down to work around FF bug, see #614)
2952 // Go through all old observables and check diffValue: (it is unique after last bindDependencies)
2953 // 0: it's not in new observables, unobserve it
2954 // 1: it keeps being observed, don't want to notify it. change to 0
2955 l = prevObserving.length;
2956 while (l--) {
2957 var dep = prevObserving[l];
2958 if (dep.diffValue === 0) {
2959 removeObserver(dep, derivation);
2960 }
2961 dep.diffValue = 0;
2962 }
2963 // Go through all new observables and check diffValue: (now it should be unique)
2964 // 0: it was set to 0 in last loop. don't need to do anything.
2965 // 1: it wasn't observed, let's observe it. set back to 0
2966 while (i0--) {
2967 var dep = observing[i0];
2968 if (dep.diffValue === 1) {
2969 dep.diffValue = 0;
2970 addObserver(dep, derivation);
2971 }
2972 }
2973 // Some new observed derivations may become stale during this derivation computation
2974 // so they have had no chance to propagate staleness (#916)
2975 if (lowestNewObservingDerivationState !== exports.IDerivationState.UP_TO_DATE) {
2976 derivation.dependenciesState = lowestNewObservingDerivationState;
2977 derivation.onBecomeStale();
2978 }
2979}
2980function clearObserving(derivation) {
2981 // invariant(globalState.inBatch > 0, "INTERNAL ERROR clearObserving should be called only inside batch");
2982 var obs = derivation.observing;
2983 derivation.observing = [];
2984 var i = obs.length;
2985 while (i--)
2986 removeObserver(obs[i], derivation);
2987 derivation.dependenciesState = exports.IDerivationState.NOT_TRACKING;
2988}
2989function untracked(action) {
2990 var prev = untrackedStart();
2991 var res = action();
2992 untrackedEnd(prev);
2993 return res;
2994}
2995function untrackedStart() {
2996 var prev = globalState.trackingDerivation;
2997 globalState.trackingDerivation = null;
2998 return prev;
2999}
3000function untrackedEnd(prev) {
3001 globalState.trackingDerivation = prev;
3002}
3003/**
3004 * needed to keep `lowestObserverState` correct. when changing from (2 or 1) to 0
3005 *
3006 */
3007function changeDependenciesStateTo0(derivation) {
3008 if (derivation.dependenciesState === exports.IDerivationState.UP_TO_DATE)
3009 return;
3010 derivation.dependenciesState = exports.IDerivationState.UP_TO_DATE;
3011 var obs = derivation.observing;
3012 var i = obs.length;
3013 while (i--)
3014 obs[i].lowestObserverState = exports.IDerivationState.UP_TO_DATE;
3015}
3016
3017var Reaction = (function () {
3018 function Reaction(name, onInvalidate) {
3019 if (name === void 0) { name = "Reaction@" + getNextId(); }
3020 this.name = name;
3021 this.onInvalidate = onInvalidate;
3022 this.observing = []; // nodes we are looking at. Our value depends on these nodes
3023 this.newObserving = [];
3024 this.dependenciesState = exports.IDerivationState.NOT_TRACKING;
3025 this.diffValue = 0;
3026 this.runId = 0;
3027 this.unboundDepsCount = 0;
3028 this.__mapid = "#" + getNextId();
3029 this.isDisposed = false;
3030 this._isScheduled = false;
3031 this._isTrackPending = false;
3032 this._isRunning = false;
3033 }
3034 Reaction.prototype.onBecomeStale = function () {
3035 this.schedule();
3036 };
3037 Reaction.prototype.schedule = function () {
3038 if (!this._isScheduled) {
3039 this._isScheduled = true;
3040 globalState.pendingReactions.push(this);
3041 runReactions();
3042 }
3043 };
3044 Reaction.prototype.isScheduled = function () {
3045 return this._isScheduled;
3046 };
3047 /**
3048 * internal, use schedule() if you intend to kick off a reaction
3049 */
3050 Reaction.prototype.runReaction = function () {
3051 if (!this.isDisposed) {
3052 startBatch();
3053 this._isScheduled = false;
3054 if (shouldCompute(this)) {
3055 this._isTrackPending = true;
3056 this.onInvalidate();
3057 if (this._isTrackPending && isSpyEnabled()) {
3058 // onInvalidate didn't trigger track right away..
3059 spyReport({
3060 object: this,
3061 type: "scheduled-reaction"
3062 });
3063 }
3064 }
3065 endBatch();
3066 }
3067 };
3068 Reaction.prototype.track = function (fn) {
3069 startBatch();
3070 var notify = isSpyEnabled();
3071 var startTime;
3072 if (notify) {
3073 startTime = Date.now();
3074 spyReportStart({
3075 object: this,
3076 type: "reaction",
3077 fn: fn
3078 });
3079 }
3080 this._isRunning = true;
3081 var result = trackDerivedFunction(this, fn, undefined);
3082 this._isRunning = false;
3083 this._isTrackPending = false;
3084 if (this.isDisposed) {
3085 // disposed during last run. Clean up everything that was bound after the dispose call.
3086 clearObserving(this);
3087 }
3088 if (isCaughtException(result))
3089 this.reportExceptionInDerivation(result.cause);
3090 if (notify) {
3091 spyReportEnd({
3092 time: Date.now() - startTime
3093 });
3094 }
3095 endBatch();
3096 };
3097 Reaction.prototype.reportExceptionInDerivation = function (error) {
3098 var _this = this;
3099 if (this.errorHandler) {
3100 this.errorHandler(error, this);
3101 return;
3102 }
3103 var message = "[mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: '" + this;
3104 var messageToUser = getMessage("m037");
3105 console.error(message || messageToUser /* latter will not be true, make sure uglify doesn't remove */, error);
3106 /** If debugging brought you here, please, read the above message :-). Tnx! */
3107 if (isSpyEnabled()) {
3108 spyReport({
3109 type: "error",
3110 message: message,
3111 error: error,
3112 object: this
3113 });
3114 }
3115 globalState.globalReactionErrorHandlers.forEach(function (f) { return f(error, _this); });
3116 };
3117 Reaction.prototype.dispose = function () {
3118 if (!this.isDisposed) {
3119 this.isDisposed = true;
3120 if (!this._isRunning) {
3121 // if disposed while running, clean up later. Maybe not optimal, but rare case
3122 startBatch();
3123 clearObserving(this);
3124 endBatch();
3125 }
3126 }
3127 };
3128 Reaction.prototype.getDisposer = function () {
3129 var r = this.dispose.bind(this);
3130 r.$mobx = this;
3131 r.onError = registerErrorHandler;
3132 return r;
3133 };
3134 Reaction.prototype.toString = function () {
3135 return "Reaction[" + this.name + "]";
3136 };
3137 Reaction.prototype.whyRun = function () {
3138 var observing = unique(this._isRunning ? this.newObserving : this.observing).map(function (dep) { return dep.name; });
3139 return "\nWhyRun? reaction '" + this.name + "':\n * Status: [" + (this.isDisposed
3140 ? "stopped"
3141 : this._isRunning ? "running" : this.isScheduled() ? "scheduled" : "idle") + "]\n * This reaction will re-run if any of the following observables changes:\n " + joinStrings(observing) + "\n " + (this._isRunning
3142 ? " (... or any observable accessed during the remainder of the current run)"
3143 : "") + "\n\t" + getMessage("m038") + "\n";
3144 };
3145 return Reaction;
3146}());
3147function registerErrorHandler(handler) {
3148 invariant(this && this.$mobx && isReaction(this.$mobx), "Invalid `this`");
3149 invariant(!this.$mobx.errorHandler, "Only one onErrorHandler can be registered");
3150 this.$mobx.errorHandler = handler;
3151}
3152function onReactionError(handler) {
3153 globalState.globalReactionErrorHandlers.push(handler);
3154 return function () {
3155 var idx = globalState.globalReactionErrorHandlers.indexOf(handler);
3156 if (idx >= 0)
3157 globalState.globalReactionErrorHandlers.splice(idx, 1);
3158 };
3159}
3160/**
3161 * Magic number alert!
3162 * Defines within how many times a reaction is allowed to re-trigger itself
3163 * until it is assumed that this is gonna be a never ending loop...
3164 */
3165var MAX_REACTION_ITERATIONS = 100;
3166var reactionScheduler = function (f) { return f(); };
3167function runReactions() {
3168 // Trampolining, if runReactions are already running, new reactions will be picked up
3169 if (globalState.inBatch > 0 || globalState.isRunningReactions)
3170 return;
3171 reactionScheduler(runReactionsHelper);
3172}
3173function runReactionsHelper() {
3174 globalState.isRunningReactions = true;
3175 var allReactions = globalState.pendingReactions;
3176 var iterations = 0;
3177 // While running reactions, new reactions might be triggered.
3178 // Hence we work with two variables and check whether
3179 // we converge to no remaining reactions after a while.
3180 while (allReactions.length > 0) {
3181 if (++iterations === MAX_REACTION_ITERATIONS) {
3182 console.error("Reaction doesn't converge to a stable state after " + MAX_REACTION_ITERATIONS + " iterations." +
3183 (" Probably there is a cycle in the reactive function: " + allReactions[0]));
3184 allReactions.splice(0); // clear reactions
3185 }
3186 var remainingReactions = allReactions.splice(0);
3187 for (var i = 0, l = remainingReactions.length; i < l; i++)
3188 remainingReactions[i].runReaction();
3189 }
3190 globalState.isRunningReactions = false;
3191}
3192var isReaction = createInstanceofPredicate("Reaction", Reaction);
3193function setReactionScheduler(fn) {
3194 var baseScheduler = reactionScheduler;
3195 reactionScheduler = function (f) { return fn(function () { return baseScheduler(f); }); };
3196}
3197
3198function asReference(value) {
3199 deprecated("asReference is deprecated, use observable.ref instead");
3200 return observable.ref(value);
3201}
3202function asStructure(value) {
3203 deprecated("asStructure is deprecated. Use observable.struct, computed.struct or reaction options instead.");
3204 return observable.struct(value);
3205}
3206function asFlat(value) {
3207 deprecated("asFlat is deprecated, use observable.shallow instead");
3208 return observable.shallow(value);
3209}
3210function asMap(data) {
3211 deprecated("asMap is deprecated, use observable.map or observable.shallowMap instead");
3212 return observable.map(data || {});
3213}
3214
3215function createComputedDecorator(equals) {
3216 return createClassPropertyDecorator(function (target, name, _, __, originalDescriptor) {
3217 invariant(typeof originalDescriptor !== "undefined", getMessage("m009"));
3218 invariant(typeof originalDescriptor.get === "function", getMessage("m010"));
3219 var adm = asObservableObject(target, "");
3220 defineComputedProperty(adm, name, originalDescriptor.get, originalDescriptor.set, equals, false);
3221 }, function (name) {
3222 var observable = this.$mobx.values[name];
3223 if (observable === undefined // See #505
3224 )
3225 return undefined;
3226 return observable.get();
3227 }, function (name, value) {
3228 this.$mobx.values[name].set(value);
3229 }, false, false);
3230}
3231var computedDecorator = createComputedDecorator(comparer.default);
3232var computedStructDecorator = createComputedDecorator(comparer.structural);
3233/**
3234 * Decorator for class properties: @computed get value() { return expr; }.
3235 * For legacy purposes also invokable as ES5 observable created: `computed(() => expr)`;
3236 */
3237var computed = function computed(arg1, arg2, arg3) {
3238 if (typeof arg2 === "string") {
3239 return computedDecorator.apply(null, arguments);
3240 }
3241 invariant(typeof arg1 === "function", getMessage("m011"));
3242 invariant(arguments.length < 3, getMessage("m012"));
3243 var opts = typeof arg2 === "object" ? arg2 : {};
3244 opts.setter = typeof arg2 === "function" ? arg2 : opts.setter;
3245 var equals = opts.equals
3246 ? opts.equals
3247 : opts.compareStructural || opts.struct ? comparer.structural : comparer.default;
3248 return new ComputedValue(arg1, opts.context, equals, opts.name || arg1.name || "", opts.setter);
3249};
3250computed.struct = computedStructDecorator;
3251computed.equals = createComputedDecorator;
3252
3253function getAtom(thing, property) {
3254 if (typeof thing === "object" && thing !== null) {
3255 if (isObservableArray(thing)) {
3256 invariant(property === undefined, getMessage("m036"));
3257 return thing.$mobx.atom;
3258 }
3259 if (isObservableMap(thing)) {
3260 var anyThing = thing;
3261 if (property === undefined)
3262 return getAtom(anyThing._keys);
3263 var observable = anyThing._data[property] || anyThing._hasMap[property];
3264 invariant(!!observable, "the entry '" + property + "' does not exist in the observable map '" + getDebugName(thing) + "'");
3265 return observable;
3266 }
3267 // Initializers run lazily when transpiling to babel, so make sure they are run...
3268 runLazyInitializers(thing);
3269 if (property && !thing.$mobx)
3270 thing[property]; // See #1072 // TODO: remove in 4.0
3271 if (isObservableObject(thing)) {
3272 if (!property)
3273 return fail("please specify a property");
3274 var observable = thing.$mobx.values[property];
3275 invariant(!!observable, "no observable property '" + property + "' found on the observable object '" + getDebugName(thing) + "'");
3276 return observable;
3277 }
3278 if (isAtom(thing) || isComputedValue(thing) || isReaction(thing)) {
3279 return thing;
3280 }
3281 }
3282 else if (typeof thing === "function") {
3283 if (isReaction(thing.$mobx)) {
3284 // disposer function
3285 return thing.$mobx;
3286 }
3287 }
3288 return fail("Cannot obtain atom from " + thing);
3289}
3290function getAdministration(thing, property) {
3291 invariant(thing, "Expecting some object");
3292 if (property !== undefined)
3293 return getAdministration(getAtom(thing, property));
3294 if (isAtom(thing) || isComputedValue(thing) || isReaction(thing))
3295 return thing;
3296 if (isObservableMap(thing))
3297 return thing;
3298 // Initializers run lazily when transpiling to babel, so make sure they are run...
3299 runLazyInitializers(thing);
3300 if (thing.$mobx)
3301 return thing.$mobx;
3302 invariant(false, "Cannot obtain administration from " + thing);
3303}
3304function getDebugName(thing, property) {
3305 var named;
3306 if (property !== undefined)
3307 named = getAtom(thing, property);
3308 else if (isObservableObject(thing) || isObservableMap(thing))
3309 named = getAdministration(thing);
3310 else
3311 named = getAtom(thing); // valid for arrays as well
3312 return named.name;
3313}
3314
3315function isComputed(value, property) {
3316 if (value === null || value === undefined)
3317 return false;
3318 if (property !== undefined) {
3319 if (isObservableObject(value) === false)
3320 return false;
3321 if (!value.$mobx.values[property])
3322 return false;
3323 var atom = getAtom(value, property);
3324 return isComputedValue(atom);
3325 }
3326 return isComputedValue(value);
3327}
3328
3329function observe(thing, propOrCb, cbOrFire, fireImmediately) {
3330 if (typeof cbOrFire === "function")
3331 return observeObservableProperty(thing, propOrCb, cbOrFire, fireImmediately);
3332 else
3333 return observeObservable(thing, propOrCb, cbOrFire);
3334}
3335function observeObservable(thing, listener, fireImmediately) {
3336 return getAdministration(thing).observe(listener, fireImmediately);
3337}
3338function observeObservableProperty(thing, property, listener, fireImmediately) {
3339 return getAdministration(thing, property).observe(listener, fireImmediately);
3340}
3341
3342function intercept(thing, propOrHandler, handler) {
3343 if (typeof handler === "function")
3344 return interceptProperty(thing, propOrHandler, handler);
3345 else
3346 return interceptInterceptable(thing, propOrHandler);
3347}
3348function interceptInterceptable(thing, handler) {
3349 return getAdministration(thing).intercept(handler);
3350}
3351function interceptProperty(thing, property, handler) {
3352 return getAdministration(thing, property).intercept(handler);
3353}
3354
3355/**
3356 * expr can be used to create temporarily views inside views.
3357 * This can be improved to improve performance if a value changes often, but usually doesn't affect the outcome of an expression.
3358 *
3359 * In the following example the expression prevents that a component is rerender _each time_ the selection changes;
3360 * instead it will only rerenders when the current todo is (de)selected.
3361 *
3362 * reactiveComponent((props) => {
3363 * const todo = props.todo;
3364 * const isSelected = mobx.expr(() => props.viewState.selection === todo);
3365 * return <div className={isSelected ? "todo todo-selected" : "todo"}>{todo.title}</div>
3366 * });
3367 *
3368 */
3369function expr(expr, scope) {
3370 if (!isComputingDerivation())
3371 console.warn(getMessage("m013"));
3372 // optimization: would be more efficient if the expr itself wouldn't be evaluated first on the next change, but just a 'changed' signal would be fired
3373 return computed(expr, { context: scope }).get();
3374}
3375
3376function toJS(source, detectCycles, __alreadySeen) {
3377 if (detectCycles === void 0) { detectCycles = true; }
3378 if (__alreadySeen === void 0) { __alreadySeen = []; }
3379 // optimization: using ES6 map would be more efficient!
3380 // optimization: lift this function outside toJS, this makes recursion expensive
3381 function cache(value) {
3382 if (detectCycles)
3383 __alreadySeen.push([source, value]);
3384 return value;
3385 }
3386 if (isObservable(source)) {
3387 if (detectCycles && __alreadySeen === null)
3388 __alreadySeen = [];
3389 if (detectCycles && source !== null && typeof source === "object") {
3390 for (var i = 0, l = __alreadySeen.length; i < l; i++)
3391 if (__alreadySeen[i][0] === source)
3392 return __alreadySeen[i][1];
3393 }
3394 if (isObservableArray(source)) {
3395 var res = cache([]);
3396 var toAdd = source.map(function (value) { return toJS(value, detectCycles, __alreadySeen); });
3397 res.length = toAdd.length;
3398 for (var i = 0, l = toAdd.length; i < l; i++)
3399 res[i] = toAdd[i];
3400 return res;
3401 }
3402 if (isObservableObject(source)) {
3403 var res = cache({});
3404 for (var key in source)
3405 res[key] = toJS(source[key], detectCycles, __alreadySeen);
3406 return res;
3407 }
3408 if (isObservableMap(source)) {
3409 var res_1 = cache({});
3410 source.forEach(function (value, key) { return (res_1[key] = toJS(value, detectCycles, __alreadySeen)); });
3411 return res_1;
3412 }
3413 if (isObservableValue(source))
3414 return toJS(source.get(), detectCycles, __alreadySeen);
3415 }
3416 return source;
3417}
3418
3419function createTransformer(transformer, onCleanup) {
3420 invariant(typeof transformer === "function" && transformer.length < 2, "createTransformer expects a function that accepts one argument");
3421 // Memoizes: object id -> reactive view that applies transformer to the object
3422 var objectCache = {};
3423 // If the resetId changes, we will clear the object cache, see #163
3424 // This construction is used to avoid leaking refs to the objectCache directly
3425 var resetId = globalState.resetId;
3426 // Local transformer class specifically for this transformer
3427 var Transformer = (function (_super) {
3428 __extends(Transformer, _super);
3429 function Transformer(sourceIdentifier, sourceObject) {
3430 var _this = _super.call(this, function () { return transformer(sourceObject); }, undefined, comparer.default, "Transformer-" + transformer.name + "-" + sourceIdentifier, undefined) || this;
3431 _this.sourceIdentifier = sourceIdentifier;
3432 _this.sourceObject = sourceObject;
3433 return _this;
3434 }
3435 Transformer.prototype.onBecomeUnobserved = function () {
3436 var lastValue = this.value;
3437 _super.prototype.onBecomeUnobserved.call(this);
3438 delete objectCache[this.sourceIdentifier];
3439 if (onCleanup)
3440 onCleanup(lastValue, this.sourceObject);
3441 };
3442 return Transformer;
3443 }(ComputedValue));
3444 return function (object) {
3445 if (resetId !== globalState.resetId) {
3446 objectCache = {};
3447 resetId = globalState.resetId;
3448 }
3449 var identifier = getMemoizationId(object);
3450 var reactiveTransformer = objectCache[identifier];
3451 if (reactiveTransformer)
3452 return reactiveTransformer.get();
3453 // Not in cache; create a reactive view
3454 reactiveTransformer = objectCache[identifier] = new Transformer(identifier, object);
3455 return reactiveTransformer.get();
3456 };
3457}
3458function getMemoizationId(object) {
3459 if (typeof object === "string" || typeof object === "number")
3460 return object;
3461 if (object === null || typeof object !== "object")
3462 throw new Error("[mobx] transform expected some kind of object or primitive value, got: " + object);
3463 var tid = object.$transformId;
3464 if (tid === undefined) {
3465 tid = getNextId();
3466 addHiddenProp(object, "$transformId", tid);
3467 }
3468 return tid;
3469}
3470
3471function log(msg) {
3472 console.log(msg);
3473 return msg;
3474}
3475function whyRun(thing, prop) {
3476 switch (arguments.length) {
3477 case 0:
3478 thing = globalState.trackingDerivation;
3479 if (!thing)
3480 return log(getMessage("m024"));
3481 break;
3482 case 2:
3483 thing = getAtom(thing, prop);
3484 break;
3485 }
3486 thing = getAtom(thing);
3487 if (isComputedValue(thing))
3488 return log(thing.whyRun());
3489 else if (isReaction(thing))
3490 return log(thing.whyRun());
3491 return fail(getMessage("m025"));
3492}
3493
3494function getDependencyTree(thing, property) {
3495 return nodeToDependencyTree(getAtom(thing, property));
3496}
3497function nodeToDependencyTree(node) {
3498 var result = {
3499 name: node.name
3500 };
3501 if (node.observing && node.observing.length > 0)
3502 result.dependencies = unique(node.observing).map(nodeToDependencyTree);
3503 return result;
3504}
3505function getObserverTree(thing, property) {
3506 return nodeToObserverTree(getAtom(thing, property));
3507}
3508function nodeToObserverTree(node) {
3509 var result = {
3510 name: node.name
3511 };
3512 if (hasObservers(node))
3513 result.observers = getObservers(node).map(nodeToObserverTree);
3514 return result;
3515}
3516
3517function interceptReads(thing, propOrHandler, handler) {
3518 var target;
3519 if (isObservableMap(thing) || isObservableArray(thing) || isObservableValue(thing)) {
3520 target = getAdministration(thing);
3521 }
3522 else if (isObservableObject(thing)) {
3523 if (typeof propOrHandler !== "string")
3524 return fail("InterceptReads can only be used with a specific property, not with an object in general");
3525 target = getAdministration(thing, propOrHandler);
3526 }
3527 else {
3528 return fail("Expected observable map, object or array as first array");
3529 }
3530 if (target.dehancer !== undefined)
3531 return fail("An intercept reader was already established");
3532 target.dehancer = typeof propOrHandler === "function" ? propOrHandler : handler;
3533 return function () {
3534 target.dehancer = undefined;
3535 };
3536}
3537
3538/**
3539 * (c) Michel Weststrate 2015 - 2016
3540 * MIT Licensed
3541 *
3542 * Welcome to the mobx sources! To get an global overview of how MobX internally works,
3543 * this is a good place to start:
3544 * https://medium.com/@mweststrate/becoming-fully-reactive-an-in-depth-explanation-of-mobservable-55995262a254#.xvbh6qd74
3545 *
3546 * Source folders:
3547 * ===============
3548 *
3549 * - api/ Most of the public static methods exposed by the module can be found here.
3550 * - core/ Implementation of the MobX algorithm; atoms, derivations, reactions, dependency trees, optimizations. Cool stuff can be found here.
3551 * - types/ All the magic that is need to have observable objects, arrays and values is in this folder. Including the modifiers like `asFlat`.
3552 * - utils/ Utility stuff.
3553 *
3554 */
3555var extras = {
3556 allowStateChanges: allowStateChanges,
3557 deepEqual: deepEqual,
3558 getAtom: getAtom,
3559 getDebugName: getDebugName,
3560 getDependencyTree: getDependencyTree,
3561 getAdministration: getAdministration,
3562 getGlobalState: getGlobalState,
3563 getObserverTree: getObserverTree,
3564 interceptReads: interceptReads,
3565 isComputingDerivation: isComputingDerivation,
3566 isSpyEnabled: isSpyEnabled,
3567 onReactionError: onReactionError,
3568 reserveArrayBuffer: reserveArrayBuffer,
3569 resetGlobalState: resetGlobalState,
3570 isolateGlobalState: isolateGlobalState,
3571 shareGlobalState: shareGlobalState,
3572 spyReport: spyReport,
3573 spyReportEnd: spyReportEnd,
3574 spyReportStart: spyReportStart,
3575 setReactionScheduler: setReactionScheduler
3576};
3577var everything = {
3578 Reaction: Reaction,
3579 untracked: untracked,
3580 Atom: Atom,
3581 BaseAtom: BaseAtom,
3582 useStrict: useStrict,
3583 isStrictModeEnabled: isStrictModeEnabled,
3584 spy: spy,
3585 comparer: comparer,
3586 asReference: asReference,
3587 asFlat: asFlat,
3588 asStructure: asStructure,
3589 asMap: asMap,
3590 isModifierDescriptor: isModifierDescriptor,
3591 isObservableObject: isObservableObject,
3592 isBoxedObservable: isObservableValue,
3593 isObservableArray: isObservableArray,
3594 ObservableMap: ObservableMap,
3595 isObservableMap: isObservableMap,
3596 map: map,
3597 transaction: transaction,
3598 observable: observable,
3599 computed: computed,
3600 isObservable: isObservable,
3601 isComputed: isComputed,
3602 extendObservable: extendObservable,
3603 extendShallowObservable: extendShallowObservable,
3604 observe: observe,
3605 intercept: intercept,
3606 autorun: autorun,
3607 autorunAsync: autorunAsync,
3608 when: when,
3609 reaction: reaction,
3610 action: action,
3611 isAction: isAction,
3612 runInAction: runInAction,
3613 expr: expr,
3614 toJS: toJS,
3615 createTransformer: createTransformer,
3616 whyRun: whyRun,
3617 isArrayLike: isArrayLike,
3618 extras: extras
3619};
3620var warnedAboutDefaultExport = false;
3621var _loop_1 = function (p) {
3622 var val = everything[p];
3623 Object.defineProperty(everything, p, {
3624 get: function () {
3625 if (!warnedAboutDefaultExport) {
3626 warnedAboutDefaultExport = true;
3627 console.warn("Using default export (`import mobx from 'mobx'`) is deprecated " +
3628 "and won’t work in mobx@4.0.0\n" +
3629 "Use `import * as mobx from 'mobx'` instead");
3630 }
3631 return val;
3632 }
3633 });
3634};
3635for (var p in everything) {
3636 _loop_1(p);
3637}
3638if (typeof __MOBX_DEVTOOLS_GLOBAL_HOOK__ === "object") {
3639 __MOBX_DEVTOOLS_GLOBAL_HOOK__.injectMobx({ spy: spy, extras: extras });
3640}
3641
3642exports.extras = extras;
3643exports['default'] = everything;
3644exports.Reaction = Reaction;
3645exports.untracked = untracked;
3646exports.Atom = Atom;
3647exports.BaseAtom = BaseAtom;
3648exports.useStrict = useStrict;
3649exports.isStrictModeEnabled = isStrictModeEnabled;
3650exports.spy = spy;
3651exports.comparer = comparer;
3652exports.asReference = asReference;
3653exports.asFlat = asFlat;
3654exports.asStructure = asStructure;
3655exports.asMap = asMap;
3656exports.isModifierDescriptor = isModifierDescriptor;
3657exports.isObservableObject = isObservableObject;
3658exports.isBoxedObservable = isObservableValue;
3659exports.isObservableArray = isObservableArray;
3660exports.ObservableMap = ObservableMap;
3661exports.isObservableMap = isObservableMap;
3662exports.map = map;
3663exports.transaction = transaction;
3664exports.observable = observable;
3665exports.IObservableFactories = IObservableFactories;
3666exports.computed = computed;
3667exports.isObservable = isObservable;
3668exports.isComputed = isComputed;
3669exports.extendObservable = extendObservable;
3670exports.extendShallowObservable = extendShallowObservable;
3671exports.observe = observe;
3672exports.intercept = intercept;
3673exports.autorun = autorun;
3674exports.autorunAsync = autorunAsync;
3675exports.when = when;
3676exports.reaction = reaction;
3677exports.action = action;
3678exports.isAction = isAction;
3679exports.runInAction = runInAction;
3680exports.expr = expr;
3681exports.toJS = toJS;
3682exports.createTransformer = createTransformer;
3683exports.whyRun = whyRun;
3684exports.isArrayLike = isArrayLike;
3685
3686}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3687},{}]},{},[1])(1)
3688});
\No newline at end of file