UNPKG

180 kBJavaScriptView Raw
1/** MobX - (c) Michel Weststrate 2015 - 2020 - MIT Licensed */
2'use strict';
3
4Object.defineProperty(exports, '__esModule', { value: true });
5
6/*! *****************************************************************************
7Copyright (c) Microsoft Corporation. All rights reserved.
8Licensed under the Apache License, Version 2.0 (the "License"); you may not use
9this file except in compliance with the License. You may obtain a copy of the
10License at http://www.apache.org/licenses/LICENSE-2.0
11
12THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
14WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
15MERCHANTABLITY OR NON-INFRINGEMENT.
16
17See the Apache Version 2.0 License for specific language governing permissions
18and limitations under the License.
19***************************************************************************** */
20/* global Reflect, Promise */
21
22var extendStatics = function(d, b) {
23 extendStatics = Object.setPrototypeOf ||
24 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
25 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
26 return extendStatics(d, b);
27};
28
29function __extends(d, b) {
30 extendStatics(d, b);
31 function __() { this.constructor = d; }
32 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
33}
34
35var __assign = function() {
36 __assign = Object.assign || function __assign(t) {
37 for (var s, i = 1, n = arguments.length; i < n; i++) {
38 s = arguments[i];
39 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
40 }
41 return t;
42 };
43 return __assign.apply(this, arguments);
44};
45
46function __read(o, n) {
47 var m = typeof Symbol === "function" && o[Symbol.iterator];
48 if (!m) return o;
49 var i = m.call(o), r, ar = [], e;
50 try {
51 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
52 }
53 catch (error) { e = { error: error }; }
54 finally {
55 try {
56 if (r && !r.done && (m = i["return"])) m.call(i);
57 }
58 finally { if (e) throw e.error; }
59 }
60 return ar;
61}
62
63function __spread() {
64 for (var ar = [], i = 0; i < arguments.length; i++)
65 ar = ar.concat(__read(arguments[i]));
66 return ar;
67}
68
69var OBFUSCATED_ERROR = "An invariant failed, however the error is obfuscated because this is an production build.";
70var EMPTY_ARRAY = [];
71Object.freeze(EMPTY_ARRAY);
72var EMPTY_OBJECT = {};
73Object.freeze(EMPTY_OBJECT);
74var mockGlobal = {};
75function getGlobal() {
76 if (typeof window !== "undefined") {
77 return window;
78 }
79 if (typeof global !== "undefined") {
80 return global;
81 }
82 if (typeof self !== "undefined") {
83 return self;
84 }
85 return mockGlobal;
86}
87function getNextId() {
88 return ++globalState.mobxGuid;
89}
90function fail(message) {
91 invariant(false, message);
92 throw "X"; // unreachable
93}
94function invariant(check, message) {
95 if (!check)
96 throw new Error("[mobx] " + (message || OBFUSCATED_ERROR));
97}
98/**
99 * Prints a deprecation message, but only one time.
100 * Returns false if the deprecated message was already printed before
101 */
102var deprecatedMessages = [];
103function deprecated(msg, thing) {
104 if (thing) {
105 return deprecated("'" + msg + "', use '" + thing + "' instead.");
106 }
107 if (deprecatedMessages.indexOf(msg) !== -1)
108 return false;
109 deprecatedMessages.push(msg);
110 console.error("[mobx] Deprecated: " + msg);
111 return true;
112}
113/**
114 * Makes sure that the provided function is invoked at most once.
115 */
116function once(func) {
117 var invoked = false;
118 return function () {
119 if (invoked)
120 return;
121 invoked = true;
122 return func.apply(this, arguments);
123 };
124}
125var noop = function () { };
126function unique(list) {
127 var res = [];
128 list.forEach(function (item) {
129 if (res.indexOf(item) === -1)
130 res.push(item);
131 });
132 return res;
133}
134function isObject(value) {
135 return value !== null && typeof value === "object";
136}
137function isPlainObject(value) {
138 if (value === null || typeof value !== "object")
139 return false;
140 var proto = Object.getPrototypeOf(value);
141 return proto === Object.prototype || proto === null;
142}
143function convertToMap(dataStructure) {
144 if (isES6Map(dataStructure) || isObservableMap(dataStructure)) {
145 return dataStructure;
146 }
147 else if (Array.isArray(dataStructure)) {
148 return new Map(dataStructure);
149 }
150 else if (isPlainObject(dataStructure)) {
151 return new Map(Object.entries(dataStructure));
152 }
153 else {
154 return fail("Cannot convert to map from '" + dataStructure + "'");
155 }
156}
157function makeNonEnumerable(object, propNames) {
158 for (var i = 0; i < propNames.length; i++) {
159 addHiddenProp(object, propNames[i], object[propNames[i]]);
160 }
161}
162function addHiddenProp(object, propName, value) {
163 Object.defineProperty(object, propName, {
164 enumerable: false,
165 writable: true,
166 configurable: true,
167 value: value
168 });
169}
170function addHiddenFinalProp(object, propName, value) {
171 Object.defineProperty(object, propName, {
172 enumerable: false,
173 writable: false,
174 configurable: true,
175 value: value
176 });
177}
178function isPropertyConfigurable(object, prop) {
179 var descriptor = Object.getOwnPropertyDescriptor(object, prop);
180 return !descriptor || (descriptor.configurable !== false && descriptor.writable !== false);
181}
182function assertPropertyConfigurable(object, prop) {
183 if (!isPropertyConfigurable(object, prop))
184 fail("Cannot make property '" + prop + "' observable, it is not configurable and writable in the target object");
185}
186function createInstanceofPredicate(name, clazz) {
187 var propName = "isMobX" + name;
188 clazz.prototype[propName] = true;
189 return function (x) {
190 return isObject(x) && x[propName] === true;
191 };
192}
193function areBothNaN(a, b) {
194 return typeof a === "number" && typeof b === "number" && isNaN(a) && isNaN(b);
195}
196/**
197 * Returns whether the argument is an array, disregarding observability.
198 */
199function isArrayLike(x) {
200 return Array.isArray(x) || isObservableArray(x);
201}
202function isES6Map(thing) {
203 if (getGlobal().Map !== undefined && thing instanceof getGlobal().Map)
204 return true;
205 return false;
206}
207function isES6Set(thing) {
208 return thing instanceof Set;
209}
210// use Array.from in Mobx 5
211function iteratorToArray(it) {
212 var res = [];
213 while (true) {
214 var r = it.next();
215 if (r.done)
216 break;
217 res.push(r.value);
218 }
219 return res;
220}
221function primitiveSymbol() {
222 // es-disable-next-line
223 return (typeof Symbol === "function" && Symbol.toPrimitive) || "@@toPrimitive";
224}
225function toPrimitive(value) {
226 return value === null ? null : typeof value === "object" ? "" + value : value;
227}
228
229function iteratorSymbol() {
230 return (typeof Symbol === "function" && Symbol.iterator) || "@@iterator";
231}
232function declareIterator(prototType, iteratorFactory) {
233 addHiddenFinalProp(prototType, iteratorSymbol(), iteratorFactory);
234}
235function makeIterable(iterator) {
236 iterator[iteratorSymbol()] = getSelf;
237 return iterator;
238}
239function toStringTagSymbol() {
240 return (typeof Symbol === "function" && Symbol.toStringTag) || "@@toStringTag";
241}
242function getSelf() {
243 return this;
244}
245
246/**
247 * Anything that can be used to _store_ state is an Atom in mobx. Atoms have two important jobs
248 *
249 * 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
250 * 2) they should notify mobx whenever they have _changed_. This way mobx can re-run any functions (derivations) that are using this atom.
251 */
252var Atom = /** @class */ (function () {
253 /**
254 * Create a new atom. For debugging purposes it is recommended to give it a name.
255 * The onBecomeObserved and onBecomeUnobserved callbacks can be used for resource management.
256 */
257 function Atom(name) {
258 if (name === void 0) { name = "Atom@" + getNextId(); }
259 this.name = name;
260 this.isPendingUnobservation = false; // for effective unobserving. BaseAtom has true, for extra optimization, so its onBecomeUnobserved never gets called, because it's not needed
261 this.isBeingObserved = false;
262 this.observers = [];
263 this.observersIndexes = {};
264 this.diffValue = 0;
265 this.lastAccessedBy = 0;
266 this.lowestObserverState = exports.IDerivationState.NOT_TRACKING;
267 }
268 Atom.prototype.onBecomeUnobserved = function () {
269 // noop
270 };
271 Atom.prototype.onBecomeObserved = function () {
272 /* noop */
273 };
274 /**
275 * Invoke this method to notify mobx that your atom has been used somehow.
276 * Returns true if there is currently a reactive context.
277 */
278 Atom.prototype.reportObserved = function () {
279 return reportObserved(this);
280 };
281 /**
282 * Invoke this method _after_ this method has changed to signal mobx that all its observers should invalidate.
283 */
284 Atom.prototype.reportChanged = function () {
285 startBatch();
286 propagateChanged(this);
287 endBatch();
288 };
289 Atom.prototype.toString = function () {
290 return this.name;
291 };
292 return Atom;
293}());
294var isAtom = createInstanceofPredicate("Atom", Atom);
295function createAtom(name, onBecomeObservedHandler, onBecomeUnobservedHandler) {
296 if (onBecomeObservedHandler === void 0) { onBecomeObservedHandler = noop; }
297 if (onBecomeUnobservedHandler === void 0) { onBecomeUnobservedHandler = noop; }
298 var atom = new Atom(name);
299 onBecomeObserved(atom, onBecomeObservedHandler);
300 onBecomeUnobserved(atom, onBecomeUnobservedHandler);
301 return atom;
302}
303
304function identityComparer(a, b) {
305 return a === b;
306}
307function structuralComparer(a, b) {
308 return deepEqual(a, b);
309}
310function shallowComparer(a, b) {
311 return deepEqual(a, b, 1);
312}
313function defaultComparer(a, b) {
314 return areBothNaN(a, b) || identityComparer(a, b);
315}
316var comparer = {
317 identity: identityComparer,
318 structural: structuralComparer,
319 default: defaultComparer,
320 shallow: shallowComparer
321};
322
323var enumerableDescriptorCache = {};
324var nonEnumerableDescriptorCache = {};
325function createPropertyInitializerDescriptor(prop, enumerable) {
326 var cache = enumerable ? enumerableDescriptorCache : nonEnumerableDescriptorCache;
327 return (cache[prop] ||
328 (cache[prop] = {
329 configurable: true,
330 enumerable: enumerable,
331 get: function () {
332 initializeInstance(this);
333 return this[prop];
334 },
335 set: function (value) {
336 initializeInstance(this);
337 this[prop] = value;
338 }
339 }));
340}
341function initializeInstance(target) {
342 if (target.__mobxDidRunLazyInitializers === true)
343 return;
344 var decorators = target.__mobxDecorators;
345 if (decorators) {
346 addHiddenProp(target, "__mobxDidRunLazyInitializers", true);
347 for (var key in decorators) {
348 var d = decorators[key];
349 d.propertyCreator(target, d.prop, d.descriptor, d.decoratorTarget, d.decoratorArguments);
350 }
351 }
352}
353function createPropDecorator(propertyInitiallyEnumerable, propertyCreator) {
354 return function decoratorFactory() {
355 var decoratorArguments;
356 var decorator = function decorate(target, prop, descriptor, applyImmediately
357 // This is a special parameter to signal the direct application of a decorator, allow extendObservable to skip the entire type decoration part,
358 // as the instance to apply the decorator to equals the target
359 ) {
360 if (applyImmediately === true) {
361 propertyCreator(target, prop, descriptor, target, decoratorArguments);
362 return null;
363 }
364 if (!quacksLikeADecorator(arguments))
365 fail("This function is a decorator, but it wasn't invoked like a decorator");
366 if (!Object.prototype.hasOwnProperty.call(target, "__mobxDecorators")) {
367 var inheritedDecorators = target.__mobxDecorators;
368 addHiddenProp(target, "__mobxDecorators", __assign({}, inheritedDecorators));
369 }
370 target.__mobxDecorators[prop] = {
371 prop: prop,
372 propertyCreator: propertyCreator,
373 descriptor: descriptor,
374 decoratorTarget: target,
375 decoratorArguments: decoratorArguments
376 };
377 return createPropertyInitializerDescriptor(prop, propertyInitiallyEnumerable);
378 };
379 if (quacksLikeADecorator(arguments)) {
380 // @decorator
381 decoratorArguments = EMPTY_ARRAY;
382 return decorator.apply(null, arguments);
383 }
384 else {
385 // @decorator(args)
386 decoratorArguments = Array.prototype.slice.call(arguments);
387 return decorator;
388 }
389 };
390}
391function quacksLikeADecorator(args) {
392 return (((args.length === 2 || args.length === 3) && typeof args[1] === "string") ||
393 (args.length === 4 && args[3] === true));
394}
395
396function deepEnhancer(v, _, name) {
397 // it is an observable already, done
398 if (isObservable(v))
399 return v;
400 // something that can be converted and mutated?
401 if (Array.isArray(v))
402 return observable.array(v, { name: name });
403 if (isPlainObject(v))
404 return observable.object(v, undefined, { name: name });
405 if (isES6Map(v))
406 return observable.map(v, { name: name });
407 if (isES6Set(v))
408 return observable.set(v, { name: name });
409 return v;
410}
411function shallowEnhancer(v, _, name) {
412 if (v === undefined || v === null)
413 return v;
414 if (isObservableObject(v) || isObservableArray(v) || isObservableMap(v) || isObservableSet(v))
415 return v;
416 if (Array.isArray(v))
417 return observable.array(v, { name: name, deep: false });
418 if (isPlainObject(v))
419 return observable.object(v, undefined, { name: name, deep: false });
420 if (isES6Map(v))
421 return observable.map(v, { name: name, deep: false });
422 if (isES6Set(v))
423 return observable.set(v, { name: name, deep: false });
424 return fail("The shallow modifier / decorator can only used in combination with arrays, objects, maps and sets");
425}
426function referenceEnhancer(newValue) {
427 // never turn into an observable
428 return newValue;
429}
430function refStructEnhancer(v, oldValue, name) {
431 if (isObservable(v))
432 throw "observable.struct should not be used with observable values";
433 if (deepEqual(v, oldValue))
434 return oldValue;
435 return v;
436}
437
438function createDecoratorForEnhancer(enhancer) {
439 invariant(enhancer);
440 var decorator = createPropDecorator(true, function (target, propertyName, descriptor, _decoratorTarget, decoratorArgs) {
441 {
442 invariant(!descriptor || !descriptor.get, "@observable cannot be used on getter (property \"" + propertyName + "\"), use @computed instead.");
443 }
444 var initialValue = descriptor
445 ? descriptor.initializer
446 ? descriptor.initializer.call(target)
447 : descriptor.value
448 : undefined;
449 defineObservableProperty(target, propertyName, initialValue, enhancer);
450 });
451 var res =
452 // Extra process checks, as this happens during module initialization
453 typeof process !== "undefined" && process.env && "development" !== "production"
454 ? function observableDecorator() {
455 // This wrapper function is just to detect illegal decorator invocations, deprecate in a next version
456 // and simply return the created prop decorator
457 if (arguments.length < 2)
458 return fail("Incorrect decorator invocation. @observable decorator doesn't expect any arguments");
459 return decorator.apply(null, arguments);
460 }
461 : decorator;
462 res.enhancer = enhancer;
463 return res;
464}
465
466// Predefined bags of create observable options, to avoid allocating temporarily option objects
467// in the majority of cases
468var defaultCreateObservableOptions = {
469 deep: true,
470 name: undefined,
471 defaultDecorator: undefined
472};
473var shallowCreateObservableOptions = {
474 deep: false,
475 name: undefined,
476 defaultDecorator: undefined
477};
478Object.freeze(defaultCreateObservableOptions);
479Object.freeze(shallowCreateObservableOptions);
480function assertValidOption(key) {
481 if (!/^(deep|name|equals|defaultDecorator)$/.test(key))
482 fail("invalid option for (extend)observable: " + key);
483}
484function asCreateObservableOptions(thing) {
485 if (thing === null || thing === undefined)
486 return defaultCreateObservableOptions;
487 if (typeof thing === "string")
488 return { name: thing, deep: true };
489 {
490 if (typeof thing !== "object")
491 return fail("expected options object");
492 Object.keys(thing).forEach(assertValidOption);
493 }
494 return thing;
495}
496function getEnhancerFromOptions(options) {
497 return options.defaultDecorator
498 ? options.defaultDecorator.enhancer
499 : options.deep === false
500 ? referenceEnhancer
501 : deepEnhancer;
502}
503var deepDecorator = createDecoratorForEnhancer(deepEnhancer);
504var shallowDecorator = createDecoratorForEnhancer(shallowEnhancer);
505var refDecorator = createDecoratorForEnhancer(referenceEnhancer);
506var refStructDecorator = createDecoratorForEnhancer(refStructEnhancer);
507/**
508 * Turns an object, array or function into a reactive structure.
509 * @param v the value which should become observable.
510 */
511function createObservable(v, arg2, arg3) {
512 // @observable someProp;
513 if (typeof arguments[1] === "string") {
514 return deepDecorator.apply(null, arguments);
515 }
516 // it is an observable already, done
517 if (isObservable(v))
518 return v;
519 // something that can be converted and mutated?
520 var res = isPlainObject(v)
521 ? observable.object(v, arg2, arg3)
522 : Array.isArray(v)
523 ? observable.array(v, arg2)
524 : isES6Map(v)
525 ? observable.map(v, arg2)
526 : isES6Set(v)
527 ? observable.set(v, arg2)
528 : v;
529 // this value could be converted to a new observable data structure, return it
530 if (res !== v)
531 return res;
532 // otherwise, just box it
533 fail("The provided value could not be converted into an observable. If you want just create an observable reference to the object use 'observable.box(value)'");
534}
535var observableFactories = {
536 box: function (value, options) {
537 if (arguments.length > 2)
538 incorrectlyUsedAsDecorator("box");
539 var o = asCreateObservableOptions(options);
540 return new ObservableValue(value, getEnhancerFromOptions(o), o.name, true, o.equals);
541 },
542 shallowBox: function (value, name) {
543 if (arguments.length > 2)
544 incorrectlyUsedAsDecorator("shallowBox");
545 deprecated("observable.shallowBox", "observable.box(value, { deep: false })");
546 return observable.box(value, { name: name, deep: false });
547 },
548 array: function (initialValues, options) {
549 if (arguments.length > 2)
550 incorrectlyUsedAsDecorator("array");
551 var o = asCreateObservableOptions(options);
552 return new ObservableArray(initialValues, getEnhancerFromOptions(o), o.name);
553 },
554 shallowArray: function (initialValues, name) {
555 if (arguments.length > 2)
556 incorrectlyUsedAsDecorator("shallowArray");
557 deprecated("observable.shallowArray", "observable.array(values, { deep: false })");
558 return observable.array(initialValues, { name: name, deep: false });
559 },
560 map: function (initialValues, options) {
561 if (arguments.length > 2)
562 incorrectlyUsedAsDecorator("map");
563 var o = asCreateObservableOptions(options);
564 return new ObservableMap(initialValues, getEnhancerFromOptions(o), o.name);
565 },
566 shallowMap: function (initialValues, name) {
567 if (arguments.length > 2)
568 incorrectlyUsedAsDecorator("shallowMap");
569 deprecated("observable.shallowMap", "observable.map(values, { deep: false })");
570 return observable.map(initialValues, { name: name, deep: false });
571 },
572 set: function (initialValues, options) {
573 if (arguments.length > 2)
574 incorrectlyUsedAsDecorator("set");
575 var o = asCreateObservableOptions(options);
576 return new ObservableSet(initialValues, getEnhancerFromOptions(o), o.name);
577 },
578 object: function (props, decorators, options) {
579 if (typeof arguments[1] === "string")
580 incorrectlyUsedAsDecorator("object");
581 var o = asCreateObservableOptions(options);
582 return extendObservable({}, props, decorators, o);
583 },
584 shallowObject: function (props, name) {
585 if (typeof arguments[1] === "string")
586 incorrectlyUsedAsDecorator("shallowObject");
587 deprecated("observable.shallowObject", "observable.object(values, {}, { deep: false })");
588 return observable.object(props, {}, { name: name, deep: false });
589 },
590 ref: refDecorator,
591 shallow: shallowDecorator,
592 deep: deepDecorator,
593 struct: refStructDecorator
594};
595var observable = createObservable;
596// weird trick to keep our typings nicely with our funcs, and still extend the observable function
597Object.keys(observableFactories).forEach(function (name) { return (observable[name] = observableFactories[name]); });
598function incorrectlyUsedAsDecorator(methodName) {
599 fail(
600 // "development" !== "production" &&
601 "Expected one or two arguments to observable." + methodName + ". Did you accidentally try to use observable." + methodName + " as decorator?");
602}
603
604var computedDecorator = createPropDecorator(false, function (instance, propertyName, descriptor, decoratorTarget, decoratorArgs) {
605 var get = descriptor.get, set = descriptor.set; // initialValue is the descriptor for get / set props
606 // Optimization: faster on decorator target or instance? Assuming target
607 // Optimization: find out if declaring on instance isn't just faster. (also makes the property descriptor simpler). But, more memory usage..
608 // Forcing instance now, fixes hot reloadig issues on React Native:
609 var options = decoratorArgs[0] || {};
610 defineComputedProperty(instance, propertyName, __assign({ get: get, set: set }, options));
611});
612var computedStructDecorator = computedDecorator({ equals: comparer.structural });
613/**
614 * Decorator for class properties: @computed get value() { return expr; }.
615 * For legacy purposes also invokable as ES5 observable created: `computed(() => expr)`;
616 */
617var computed = function computed(arg1, arg2, arg3) {
618 if (typeof arg2 === "string") {
619 // @computed
620 return computedDecorator.apply(null, arguments);
621 }
622 if (arg1 !== null && typeof arg1 === "object" && arguments.length === 1) {
623 // @computed({ options })
624 return computedDecorator.apply(null, arguments);
625 }
626 // computed(expr, options?)
627 {
628 invariant(typeof arg1 === "function", "First argument to `computed` should be an expression.");
629 invariant(arguments.length < 3, "Computed takes one or two arguments if used as function");
630 }
631 var opts = typeof arg2 === "object" ? arg2 : {};
632 opts.get = arg1;
633 opts.set = typeof arg2 === "function" ? arg2 : opts.set;
634 opts.name = opts.name || arg1.name || ""; /* for generated name */
635 return new ComputedValue(opts);
636};
637computed.struct = computedStructDecorator;
638
639(function (IDerivationState) {
640 // before being run or (outside batch and not being observed)
641 // at this point derivation is not holding any data about dependency tree
642 IDerivationState[IDerivationState["NOT_TRACKING"] = -1] = "NOT_TRACKING";
643 // no shallow dependency changed since last computation
644 // won't recalculate derivation
645 // this is what makes mobx fast
646 IDerivationState[IDerivationState["UP_TO_DATE"] = 0] = "UP_TO_DATE";
647 // some deep dependency changed, but don't know if shallow dependency changed
648 // will require to check first if UP_TO_DATE or POSSIBLY_STALE
649 // currently only ComputedValue will propagate POSSIBLY_STALE
650 //
651 // having this state is second big optimization:
652 // don't have to recompute on every dependency change, but only when it's needed
653 IDerivationState[IDerivationState["POSSIBLY_STALE"] = 1] = "POSSIBLY_STALE";
654 // A shallow dependency has changed since last computation and the derivation
655 // will need to recompute when it's needed next.
656 IDerivationState[IDerivationState["STALE"] = 2] = "STALE";
657})(exports.IDerivationState || (exports.IDerivationState = {}));
658var TraceMode;
659(function (TraceMode) {
660 TraceMode[TraceMode["NONE"] = 0] = "NONE";
661 TraceMode[TraceMode["LOG"] = 1] = "LOG";
662 TraceMode[TraceMode["BREAK"] = 2] = "BREAK";
663})(TraceMode || (TraceMode = {}));
664var CaughtException = /** @class */ (function () {
665 function CaughtException(cause) {
666 this.cause = cause;
667 // Empty
668 }
669 return CaughtException;
670}());
671function isCaughtException(e) {
672 return e instanceof CaughtException;
673}
674/**
675 * Finds out whether any dependency of the derivation has actually changed.
676 * If dependenciesState is 1 then it will recalculate dependencies,
677 * if any dependency changed it will propagate it by changing dependenciesState to 2.
678 *
679 * By iterating over the dependencies in the same order that they were reported and
680 * stopping on the first change, all the recalculations are only called for ComputedValues
681 * that will be tracked by derivation. That is because we assume that if the first x
682 * dependencies of the derivation doesn't change then the derivation should run the same way
683 * up until accessing x-th dependency.
684 */
685function shouldCompute(derivation) {
686 switch (derivation.dependenciesState) {
687 case exports.IDerivationState.UP_TO_DATE:
688 return false;
689 case exports.IDerivationState.NOT_TRACKING:
690 case exports.IDerivationState.STALE:
691 return true;
692 case exports.IDerivationState.POSSIBLY_STALE: {
693 // state propagation can occur outside of action/reactive context #2195
694 var prevAllowStateReads = allowStateReadsStart(true);
695 var prevUntracked = untrackedStart(); // no need for those computeds to be reported, they will be picked up in trackDerivedFunction.
696 var obs = derivation.observing, l = obs.length;
697 for (var i = 0; i < l; i++) {
698 var obj = obs[i];
699 if (isComputedValue(obj)) {
700 if (globalState.disableErrorBoundaries) {
701 obj.get();
702 }
703 else {
704 try {
705 obj.get();
706 }
707 catch (e) {
708 // we are not interested in the value *or* exception at this moment, but if there is one, notify all
709 untrackedEnd(prevUntracked);
710 allowStateReadsEnd(prevAllowStateReads);
711 return true;
712 }
713 }
714 // if ComputedValue `obj` actually changed it will be computed and propagated to its observers.
715 // and `derivation` is an observer of `obj`
716 // invariantShouldCompute(derivation)
717 if (derivation.dependenciesState === exports.IDerivationState.STALE) {
718 untrackedEnd(prevUntracked);
719 allowStateReadsEnd(prevAllowStateReads);
720 return true;
721 }
722 }
723 }
724 changeDependenciesStateTo0(derivation);
725 untrackedEnd(prevUntracked);
726 allowStateReadsEnd(prevAllowStateReads);
727 return false;
728 }
729 }
730}
731// function invariantShouldCompute(derivation: IDerivation) {
732// const newDepState = (derivation as any).dependenciesState
733// if (
734// "development" === "production" &&
735// (newDepState === IDerivationState.POSSIBLY_STALE ||
736// newDepState === IDerivationState.NOT_TRACKING)
737// )
738// fail("Illegal dependency state")
739// }
740function isComputingDerivation() {
741 return globalState.trackingDerivation !== null; // filter out actions inside computations
742}
743function checkIfStateModificationsAreAllowed(atom) {
744 var hasObservers = atom.observers.length > 0;
745 // Should never be possible to change an observed observable from inside computed, see #798
746 if (globalState.computationDepth > 0 && hasObservers)
747 fail("Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: " + atom.name);
748 // Should not be possible to change observed state outside strict mode, except during initialization, see #563
749 if (!globalState.allowStateChanges && (hasObservers || globalState.enforceActions === "strict"))
750 fail((globalState.enforceActions
751 ? "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: "
752 : "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: ") +
753 atom.name);
754}
755function checkIfStateReadsAreAllowed(observable) {
756 if (!globalState.allowStateReads &&
757 globalState.observableRequiresReaction) {
758 console.warn("[mobx] Observable " + observable.name + " being read outside a reactive context");
759 }
760}
761/**
762 * Executes the provided function `f` and tracks which observables are being accessed.
763 * The tracking information is stored on the `derivation` object and the derivation is registered
764 * as observer of any of the accessed observables.
765 */
766function trackDerivedFunction(derivation, f, context) {
767 var prevAllowStateReads = allowStateReadsStart(true);
768 // pre allocate array allocation + room for variation in deps
769 // array will be trimmed by bindDependencies
770 changeDependenciesStateTo0(derivation);
771 derivation.newObserving = new Array(derivation.observing.length + 100);
772 derivation.unboundDepsCount = 0;
773 derivation.runId = ++globalState.runId;
774 var prevTracking = globalState.trackingDerivation;
775 globalState.trackingDerivation = derivation;
776 var result;
777 if (globalState.disableErrorBoundaries === true) {
778 result = f.call(context);
779 }
780 else {
781 try {
782 result = f.call(context);
783 }
784 catch (e) {
785 result = new CaughtException(e);
786 }
787 }
788 globalState.trackingDerivation = prevTracking;
789 bindDependencies(derivation);
790 if (derivation.observing.length === 0) {
791 warnAboutDerivationWithoutDependencies(derivation);
792 }
793 allowStateReadsEnd(prevAllowStateReads);
794 return result;
795}
796function warnAboutDerivationWithoutDependencies(derivation) {
797 if (globalState.reactionRequiresObservable || derivation.requiresObservable) {
798 console.warn("[mobx] Derivation " + derivation.name + " is created/updated without reading any observable value");
799 }
800}
801/**
802 * diffs newObserving with observing.
803 * update observing to be newObserving with unique observables
804 * notify observers that become observed/unobserved
805 */
806function bindDependencies(derivation) {
807 // invariant(derivation.dependenciesState !== IDerivationState.NOT_TRACKING, "INTERNAL ERROR bindDependencies expects derivation.dependenciesState !== -1");
808 var prevObserving = derivation.observing;
809 var observing = (derivation.observing = derivation.newObserving);
810 var lowestNewObservingDerivationState = exports.IDerivationState.UP_TO_DATE;
811 // Go through all new observables and check diffValue: (this list can contain duplicates):
812 // 0: first occurrence, change to 1 and keep it
813 // 1: extra occurrence, drop it
814 var i0 = 0, l = derivation.unboundDepsCount;
815 for (var i = 0; i < l; i++) {
816 var dep = observing[i];
817 if (dep.diffValue === 0) {
818 dep.diffValue = 1;
819 if (i0 !== i)
820 observing[i0] = dep;
821 i0++;
822 }
823 // Upcast is 'safe' here, because if dep is IObservable, `dependenciesState` will be undefined,
824 // not hitting the condition
825 if (dep.dependenciesState > lowestNewObservingDerivationState) {
826 lowestNewObservingDerivationState = dep.dependenciesState;
827 }
828 }
829 observing.length = i0;
830 derivation.newObserving = null; // newObserving shouldn't be needed outside tracking (statement moved down to work around FF bug, see #614)
831 // Go through all old observables and check diffValue: (it is unique after last bindDependencies)
832 // 0: it's not in new observables, unobserve it
833 // 1: it keeps being observed, don't want to notify it. change to 0
834 l = prevObserving.length;
835 while (l--) {
836 var dep = prevObserving[l];
837 if (dep.diffValue === 0) {
838 removeObserver(dep, derivation);
839 }
840 dep.diffValue = 0;
841 }
842 // Go through all new observables and check diffValue: (now it should be unique)
843 // 0: it was set to 0 in last loop. don't need to do anything.
844 // 1: it wasn't observed, let's observe it. set back to 0
845 while (i0--) {
846 var dep = observing[i0];
847 if (dep.diffValue === 1) {
848 dep.diffValue = 0;
849 addObserver(dep, derivation);
850 }
851 }
852 // Some new observed derivations may become stale during this derivation computation
853 // so they have had no chance to propagate staleness (#916)
854 if (lowestNewObservingDerivationState !== exports.IDerivationState.UP_TO_DATE) {
855 derivation.dependenciesState = lowestNewObservingDerivationState;
856 derivation.onBecomeStale();
857 }
858}
859function clearObserving(derivation) {
860 // invariant(globalState.inBatch > 0, "INTERNAL ERROR clearObserving should be called only inside batch");
861 var obs = derivation.observing;
862 derivation.observing = [];
863 var i = obs.length;
864 while (i--)
865 removeObserver(obs[i], derivation);
866 derivation.dependenciesState = exports.IDerivationState.NOT_TRACKING;
867}
868function untracked(action) {
869 var prev = untrackedStart();
870 var res = action();
871 untrackedEnd(prev);
872 return res;
873}
874function untrackedStart() {
875 var prev = globalState.trackingDerivation;
876 globalState.trackingDerivation = null;
877 return prev;
878}
879function untrackedEnd(prev) {
880 globalState.trackingDerivation = prev;
881}
882function allowStateReadsStart(allowStateReads) {
883 var prev = globalState.allowStateReads;
884 globalState.allowStateReads = allowStateReads;
885 return prev;
886}
887function allowStateReadsEnd(prev) {
888 globalState.allowStateReads = prev;
889}
890/**
891 * needed to keep `lowestObserverState` correct. when changing from (2 or 1) to 0
892 *
893 */
894function changeDependenciesStateTo0(derivation) {
895 if (derivation.dependenciesState === exports.IDerivationState.UP_TO_DATE)
896 return;
897 derivation.dependenciesState = exports.IDerivationState.UP_TO_DATE;
898 var obs = derivation.observing;
899 var i = obs.length;
900 while (i--)
901 obs[i].lowestObserverState = exports.IDerivationState.UP_TO_DATE;
902}
903
904// we don't use globalState for these in order to avoid possible issues with multiple
905// mobx versions
906var currentActionId = 0;
907var nextActionId = 1;
908var functionNameDescriptor = Object.getOwnPropertyDescriptor(function () { }, "name");
909var isFunctionNameConfigurable = functionNameDescriptor && functionNameDescriptor.configurable;
910function createAction(actionName, fn) {
911 {
912 invariant(typeof fn === "function", "`action` can only be invoked on functions");
913 if (typeof actionName !== "string" || !actionName)
914 fail("actions should have valid names, got: '" + actionName + "'");
915 }
916 var res = function () {
917 return executeAction(actionName, fn, this, arguments);
918 };
919 {
920 if (isFunctionNameConfigurable) {
921 Object.defineProperty(res, "name", { value: actionName });
922 }
923 }
924 res.isMobxAction = true;
925 return res;
926}
927function executeAction(actionName, fn, scope, args) {
928 var runInfo = _startAction(actionName, scope, args);
929 try {
930 return fn.apply(scope, args);
931 }
932 catch (err) {
933 runInfo.error = err;
934 throw err;
935 }
936 finally {
937 _endAction(runInfo);
938 }
939}
940function _startAction(actionName, scope, args) {
941 var notifySpy = isSpyEnabled() && !!actionName;
942 var startTime = 0;
943 if (notifySpy) {
944 startTime = Date.now();
945 var l = (args && args.length) || 0;
946 var flattendArgs = new Array(l);
947 if (l > 0)
948 for (var i = 0; i < l; i++)
949 flattendArgs[i] = args[i];
950 spyReportStart({
951 type: "action",
952 name: actionName,
953 object: scope,
954 arguments: flattendArgs
955 });
956 }
957 var prevDerivation = untrackedStart();
958 startBatch();
959 var prevAllowStateChanges = allowStateChangesStart(true);
960 var prevAllowStateReads = allowStateReadsStart(true);
961 var runInfo = {
962 prevDerivation: prevDerivation,
963 prevAllowStateChanges: prevAllowStateChanges,
964 prevAllowStateReads: prevAllowStateReads,
965 notifySpy: notifySpy,
966 startTime: startTime,
967 actionId: nextActionId++,
968 parentActionId: currentActionId
969 };
970 currentActionId = runInfo.actionId;
971 return runInfo;
972}
973function _endAction(runInfo) {
974 if (currentActionId !== runInfo.actionId) {
975 fail("invalid action stack. did you forget to finish an action?");
976 }
977 currentActionId = runInfo.parentActionId;
978 if (runInfo.error !== undefined) {
979 globalState.suppressReactionErrors = true;
980 }
981 allowStateChangesEnd(runInfo.prevAllowStateChanges);
982 allowStateReadsEnd(runInfo.prevAllowStateReads);
983 endBatch();
984 untrackedEnd(runInfo.prevDerivation);
985 if (runInfo.notifySpy) {
986 spyReportEnd({ time: Date.now() - runInfo.startTime });
987 }
988 globalState.suppressReactionErrors = false;
989}
990function allowStateChanges(allowStateChanges, func) {
991 var prev = allowStateChangesStart(allowStateChanges);
992 var res;
993 try {
994 res = func();
995 }
996 finally {
997 allowStateChangesEnd(prev);
998 }
999 return res;
1000}
1001function allowStateChangesStart(allowStateChanges) {
1002 var prev = globalState.allowStateChanges;
1003 globalState.allowStateChanges = allowStateChanges;
1004 return prev;
1005}
1006function allowStateChangesEnd(prev) {
1007 globalState.allowStateChanges = prev;
1008}
1009function allowStateChangesInsideComputed(func) {
1010 var prev = globalState.computationDepth;
1011 globalState.computationDepth = 0;
1012 var res;
1013 try {
1014 res = func();
1015 }
1016 finally {
1017 globalState.computationDepth = prev;
1018 }
1019 return res;
1020}
1021
1022var ObservableValue = /** @class */ (function (_super) {
1023 __extends(ObservableValue, _super);
1024 function ObservableValue(value, enhancer, name, notifySpy, equals) {
1025 if (name === void 0) { name = "ObservableValue@" + getNextId(); }
1026 if (notifySpy === void 0) { notifySpy = true; }
1027 if (equals === void 0) { equals = comparer.default; }
1028 var _this = _super.call(this, name) || this;
1029 _this.enhancer = enhancer;
1030 _this.name = name;
1031 _this.equals = equals;
1032 _this.hasUnreportedChange = false;
1033 _this.value = enhancer(value, undefined, name);
1034 if (notifySpy && isSpyEnabled()) {
1035 // only notify spy if this is a stand-alone observable
1036 spyReport({ type: "create", name: _this.name, newValue: "" + _this.value });
1037 }
1038 return _this;
1039 }
1040 ObservableValue.prototype.dehanceValue = function (value) {
1041 if (this.dehancer !== undefined)
1042 return this.dehancer(value);
1043 return value;
1044 };
1045 ObservableValue.prototype.set = function (newValue) {
1046 var oldValue = this.value;
1047 newValue = this.prepareNewValue(newValue);
1048 if (newValue !== globalState.UNCHANGED) {
1049 var notifySpy = isSpyEnabled();
1050 if (notifySpy) {
1051 spyReportStart({
1052 type: "update",
1053 name: this.name,
1054 newValue: newValue,
1055 oldValue: oldValue
1056 });
1057 }
1058 this.setNewValue(newValue);
1059 if (notifySpy)
1060 spyReportEnd();
1061 }
1062 };
1063 ObservableValue.prototype.prepareNewValue = function (newValue) {
1064 checkIfStateModificationsAreAllowed(this);
1065 if (hasInterceptors(this)) {
1066 var change = interceptChange(this, {
1067 object: this,
1068 type: "update",
1069 newValue: newValue
1070 });
1071 if (!change)
1072 return globalState.UNCHANGED;
1073 newValue = change.newValue;
1074 }
1075 // apply modifier
1076 newValue = this.enhancer(newValue, this.value, this.name);
1077 return this.equals(this.value, newValue) ? globalState.UNCHANGED : newValue;
1078 };
1079 ObservableValue.prototype.setNewValue = function (newValue) {
1080 var oldValue = this.value;
1081 this.value = newValue;
1082 this.reportChanged();
1083 if (hasListeners(this)) {
1084 notifyListeners(this, {
1085 type: "update",
1086 object: this,
1087 newValue: newValue,
1088 oldValue: oldValue
1089 });
1090 }
1091 };
1092 ObservableValue.prototype.get = function () {
1093 this.reportObserved();
1094 return this.dehanceValue(this.value);
1095 };
1096 ObservableValue.prototype.intercept = function (handler) {
1097 return registerInterceptor(this, handler);
1098 };
1099 ObservableValue.prototype.observe = function (listener, fireImmediately) {
1100 if (fireImmediately)
1101 listener({
1102 object: this,
1103 type: "update",
1104 newValue: this.value,
1105 oldValue: undefined
1106 });
1107 return registerListener(this, listener);
1108 };
1109 ObservableValue.prototype.toJSON = function () {
1110 return this.get();
1111 };
1112 ObservableValue.prototype.toString = function () {
1113 return this.name + "[" + this.value + "]";
1114 };
1115 ObservableValue.prototype.valueOf = function () {
1116 return toPrimitive(this.get());
1117 };
1118 return ObservableValue;
1119}(Atom));
1120ObservableValue.prototype[primitiveSymbol()] = ObservableValue.prototype.valueOf;
1121var isObservableValue = createInstanceofPredicate("ObservableValue", ObservableValue);
1122
1123/**
1124 * A node in the state dependency root that observes other nodes, and can be observed itself.
1125 *
1126 * ComputedValue will remember the result of the computation for the duration of the batch, or
1127 * while being observed.
1128 *
1129 * During this time it will recompute only when one of its direct dependencies changed,
1130 * but only when it is being accessed with `ComputedValue.get()`.
1131 *
1132 * Implementation description:
1133 * 1. First time it's being accessed it will compute and remember result
1134 * give back remembered result until 2. happens
1135 * 2. First time any deep dependency change, propagate POSSIBLY_STALE to all observers, wait for 3.
1136 * 3. When it's being accessed, recompute if any shallow dependency changed.
1137 * if result changed: propagate STALE to all observers, that were POSSIBLY_STALE from the last step.
1138 * go to step 2. either way
1139 *
1140 * If at any point it's outside batch and it isn't observed: reset everything and go to 1.
1141 */
1142var ComputedValue = /** @class */ (function () {
1143 /**
1144 * Create a new computed value based on a function expression.
1145 *
1146 * The `name` property is for debug purposes only.
1147 *
1148 * The `equals` property specifies the comparer function to use to determine if a newly produced
1149 * value differs from the previous value. Two comparers are provided in the library; `defaultComparer`
1150 * compares based on identity comparison (===), and `structualComparer` deeply compares the structure.
1151 * Structural comparison can be convenient if you always produce a new aggregated object and
1152 * don't want to notify observers if it is structurally the same.
1153 * This is useful for working with vectors, mouse coordinates etc.
1154 */
1155 function ComputedValue(options) {
1156 this.dependenciesState = exports.IDerivationState.NOT_TRACKING;
1157 this.observing = []; // nodes we are looking at. Our value depends on these nodes
1158 this.newObserving = null; // during tracking it's an array with new observed observers
1159 this.isBeingObserved = false;
1160 this.isPendingUnobservation = false;
1161 this.observers = [];
1162 this.observersIndexes = {};
1163 this.diffValue = 0;
1164 this.runId = 0;
1165 this.lastAccessedBy = 0;
1166 this.lowestObserverState = exports.IDerivationState.UP_TO_DATE;
1167 this.unboundDepsCount = 0;
1168 this.__mapid = "#" + getNextId();
1169 this.value = new CaughtException(null);
1170 this.isComputing = false; // to check for cycles
1171 this.isRunningSetter = false;
1172 this.isTracing = TraceMode.NONE;
1173 invariant(options.get, "missing option for computed: get");
1174 this.derivation = options.get;
1175 this.name = options.name || "ComputedValue@" + getNextId();
1176 if (options.set)
1177 this.setter = createAction(this.name + "-setter", options.set);
1178 this.equals =
1179 options.equals ||
1180 (options.compareStructural || options.struct
1181 ? comparer.structural
1182 : comparer.default);
1183 this.scope = options.context;
1184 this.requiresReaction = !!options.requiresReaction;
1185 this.keepAlive = !!options.keepAlive;
1186 }
1187 ComputedValue.prototype.onBecomeStale = function () {
1188 propagateMaybeChanged(this);
1189 };
1190 ComputedValue.prototype.onBecomeUnobserved = function () { };
1191 ComputedValue.prototype.onBecomeObserved = function () { };
1192 /**
1193 * Returns the current value of this computed value.
1194 * Will evaluate its computation first if needed.
1195 */
1196 ComputedValue.prototype.get = function () {
1197 if (this.isComputing)
1198 fail("Cycle detected in computation " + this.name + ": " + this.derivation);
1199 if (globalState.inBatch === 0 && this.observers.length === 0 && !this.keepAlive) {
1200 if (shouldCompute(this)) {
1201 this.warnAboutUntrackedRead();
1202 startBatch(); // See perf test 'computed memoization'
1203 this.value = this.computeValue(false);
1204 endBatch();
1205 }
1206 }
1207 else {
1208 reportObserved(this);
1209 if (shouldCompute(this))
1210 if (this.trackAndCompute())
1211 propagateChangeConfirmed(this);
1212 }
1213 var result = this.value;
1214 if (isCaughtException(result))
1215 throw result.cause;
1216 return result;
1217 };
1218 ComputedValue.prototype.peek = function () {
1219 var res = this.computeValue(false);
1220 if (isCaughtException(res))
1221 throw res.cause;
1222 return res;
1223 };
1224 ComputedValue.prototype.set = function (value) {
1225 if (this.setter) {
1226 invariant(!this.isRunningSetter, "The setter of computed value '" + this.name + "' is trying to update itself. Did you intend to update an _observable_ value, instead of the computed property?");
1227 this.isRunningSetter = true;
1228 try {
1229 this.setter.call(this.scope, value);
1230 }
1231 finally {
1232 this.isRunningSetter = false;
1233 }
1234 }
1235 else
1236 invariant(false, "[ComputedValue '" + this.name + "'] It is not possible to assign a new value to a computed value.");
1237 };
1238 ComputedValue.prototype.trackAndCompute = function () {
1239 if (isSpyEnabled()) {
1240 spyReport({
1241 object: this.scope,
1242 type: "compute",
1243 name: this.name
1244 });
1245 }
1246 var oldValue = this.value;
1247 var wasSuspended =
1248 /* see #1208 */ this.dependenciesState === exports.IDerivationState.NOT_TRACKING;
1249 var newValue = this.computeValue(true);
1250 var changed = wasSuspended ||
1251 isCaughtException(oldValue) ||
1252 isCaughtException(newValue) ||
1253 !this.equals(oldValue, newValue);
1254 if (changed) {
1255 this.value = newValue;
1256 }
1257 return changed;
1258 };
1259 ComputedValue.prototype.computeValue = function (track) {
1260 this.isComputing = true;
1261 globalState.computationDepth++;
1262 var res;
1263 if (track) {
1264 res = trackDerivedFunction(this, this.derivation, this.scope);
1265 }
1266 else {
1267 if (globalState.disableErrorBoundaries === true) {
1268 res = this.derivation.call(this.scope);
1269 }
1270 else {
1271 try {
1272 res = this.derivation.call(this.scope);
1273 }
1274 catch (e) {
1275 res = new CaughtException(e);
1276 }
1277 }
1278 }
1279 globalState.computationDepth--;
1280 this.isComputing = false;
1281 return res;
1282 };
1283 ComputedValue.prototype.suspend = function () {
1284 if (!this.keepAlive) {
1285 clearObserving(this);
1286 this.value = undefined; // don't hold on to computed value!
1287 }
1288 };
1289 ComputedValue.prototype.observe = function (listener, fireImmediately) {
1290 var _this = this;
1291 var firstTime = true;
1292 var prevValue = undefined;
1293 return autorun(function () {
1294 var newValue = _this.get();
1295 if (!firstTime || fireImmediately) {
1296 var prevU = untrackedStart();
1297 listener({
1298 type: "update",
1299 object: _this,
1300 newValue: newValue,
1301 oldValue: prevValue
1302 });
1303 untrackedEnd(prevU);
1304 }
1305 firstTime = false;
1306 prevValue = newValue;
1307 });
1308 };
1309 ComputedValue.prototype.warnAboutUntrackedRead = function () {
1310 if (this.requiresReaction === true) {
1311 fail("[mobx] Computed value " + this.name + " is read outside a reactive context");
1312 }
1313 if (this.isTracing !== TraceMode.NONE) {
1314 console.log("[mobx.trace] '" + this.name + "' is being read outside a reactive context. Doing a full recompute");
1315 }
1316 if (globalState.computedRequiresReaction) {
1317 console.warn("[mobx] Computed value " + this.name + " is being read outside a reactive context. Doing a full recompute");
1318 }
1319 };
1320 ComputedValue.prototype.toJSON = function () {
1321 return this.get();
1322 };
1323 ComputedValue.prototype.toString = function () {
1324 return this.name + "[" + this.derivation.toString() + "]";
1325 };
1326 ComputedValue.prototype.valueOf = function () {
1327 return toPrimitive(this.get());
1328 };
1329 return ComputedValue;
1330}());
1331ComputedValue.prototype[primitiveSymbol()] = ComputedValue.prototype.valueOf;
1332var isComputedValue = createInstanceofPredicate("ComputedValue", ComputedValue);
1333
1334/**
1335 * These values will persist if global state is reset
1336 */
1337var persistentKeys = [
1338 "mobxGuid",
1339 "spyListeners",
1340 "enforceActions",
1341 "computedRequiresReaction",
1342 "reactionRequiresObservable",
1343 "observableRequiresReaction",
1344 "allowStateReads",
1345 "disableErrorBoundaries",
1346 "runId",
1347 "UNCHANGED"
1348];
1349var MobXGlobals = /** @class */ (function () {
1350 function MobXGlobals() {
1351 /**
1352 * MobXGlobals version.
1353 * MobX compatiblity with other versions loaded in memory as long as this version matches.
1354 * It indicates that the global state still stores similar information
1355 *
1356 * N.B: this version is unrelated to the package version of MobX, and is only the version of the
1357 * internal state storage of MobX, and can be the same across many different package versions
1358 */
1359 this.version = 5;
1360 /**
1361 * globally unique token to signal unchanged
1362 */
1363 this.UNCHANGED = {};
1364 /**
1365 * Currently running derivation
1366 */
1367 this.trackingDerivation = null;
1368 /**
1369 * Are we running a computation currently? (not a reaction)
1370 */
1371 this.computationDepth = 0;
1372 /**
1373 * Each time a derivation is tracked, it is assigned a unique run-id
1374 */
1375 this.runId = 0;
1376 /**
1377 * 'guid' for general purpose. Will be persisted amongst resets.
1378 */
1379 this.mobxGuid = 0;
1380 /**
1381 * Are we in a batch block? (and how many of them)
1382 */
1383 this.inBatch = 0;
1384 /**
1385 * Observables that don't have observers anymore, and are about to be
1386 * suspended, unless somebody else accesses it in the same batch
1387 *
1388 * @type {IObservable[]}
1389 */
1390 this.pendingUnobservations = [];
1391 /**
1392 * List of scheduled, not yet executed, reactions.
1393 */
1394 this.pendingReactions = [];
1395 /**
1396 * Are we currently processing reactions?
1397 */
1398 this.isRunningReactions = false;
1399 /**
1400 * Is it allowed to change observables at this point?
1401 * In general, MobX doesn't allow that when running computations and React.render.
1402 * To ensure that those functions stay pure.
1403 */
1404 this.allowStateChanges = true;
1405 /**
1406 * Is it allowed to read observables at this point?
1407 * Used to hold the state needed for `observableRequiresReaction`
1408 */
1409 this.allowStateReads = true;
1410 /**
1411 * If strict mode is enabled, state changes are by default not allowed
1412 */
1413 this.enforceActions = false;
1414 /**
1415 * Spy callbacks
1416 */
1417 this.spyListeners = [];
1418 /**
1419 * Globally attached error handlers that react specifically to errors in reactions
1420 */
1421 this.globalReactionErrorHandlers = [];
1422 /**
1423 * Warn if computed values are accessed outside a reactive context
1424 */
1425 this.computedRequiresReaction = false;
1426 /**
1427 * (Experimental)
1428 * Warn if you try to create to derivation / reactive context without accessing any observable.
1429 */
1430 this.reactionRequiresObservable = false;
1431 /**
1432 * (Experimental)
1433 * Warn if observables are accessed outside a reactive context
1434 */
1435 this.observableRequiresReaction = false;
1436 /**
1437 * Allows overwriting of computed properties, useful in tests but not prod as it can cause
1438 * memory leaks. See https://github.com/mobxjs/mobx/issues/1867
1439 */
1440 this.computedConfigurable = false;
1441 /*
1442 * Don't catch and rethrow exceptions. This is useful for inspecting the state of
1443 * the stack when an exception occurs while debugging.
1444 */
1445 this.disableErrorBoundaries = false;
1446 /*
1447 * If true, we are already handling an exception in an action. Any errors in reactions should be supressed, as
1448 * they are not the cause, see: https://github.com/mobxjs/mobx/issues/1836
1449 */
1450 this.suppressReactionErrors = false;
1451 }
1452 return MobXGlobals;
1453}());
1454var canMergeGlobalState = true;
1455var isolateCalled = false;
1456var globalState = (function () {
1457 var global = getGlobal();
1458 if (global.__mobxInstanceCount > 0 && !global.__mobxGlobals)
1459 canMergeGlobalState = false;
1460 if (global.__mobxGlobals && global.__mobxGlobals.version !== new MobXGlobals().version)
1461 canMergeGlobalState = false;
1462 if (!canMergeGlobalState) {
1463 setTimeout(function () {
1464 if (!isolateCalled) {
1465 fail("There are multiple, different versions of MobX active. Make sure MobX is loaded only once or use `configure({ isolateGlobalState: true })`");
1466 }
1467 }, 1);
1468 return new MobXGlobals();
1469 }
1470 else if (global.__mobxGlobals) {
1471 global.__mobxInstanceCount += 1;
1472 if (!global.__mobxGlobals.UNCHANGED)
1473 global.__mobxGlobals.UNCHANGED = {}; // make merge backward compatible
1474 return global.__mobxGlobals;
1475 }
1476 else {
1477 global.__mobxInstanceCount = 1;
1478 return (global.__mobxGlobals = new MobXGlobals());
1479 }
1480})();
1481function isolateGlobalState() {
1482 if (globalState.pendingReactions.length ||
1483 globalState.inBatch ||
1484 globalState.isRunningReactions)
1485 fail("isolateGlobalState should be called before MobX is running any reactions");
1486 isolateCalled = true;
1487 if (canMergeGlobalState) {
1488 if (--getGlobal().__mobxInstanceCount === 0)
1489 getGlobal().__mobxGlobals = undefined;
1490 globalState = new MobXGlobals();
1491 }
1492}
1493function getGlobalState() {
1494 return globalState;
1495}
1496/**
1497 * For testing purposes only; this will break the internal state of existing observables,
1498 * but can be used to get back at a stable state after throwing errors
1499 */
1500function resetGlobalState() {
1501 var defaultGlobals = new MobXGlobals();
1502 for (var key in defaultGlobals)
1503 if (persistentKeys.indexOf(key) === -1)
1504 globalState[key] = defaultGlobals[key];
1505 globalState.allowStateChanges = !globalState.enforceActions;
1506}
1507
1508function hasObservers(observable) {
1509 return observable.observers && observable.observers.length > 0;
1510}
1511function getObservers(observable) {
1512 return observable.observers;
1513}
1514// function invariantObservers(observable: IObservable) {
1515// const list = observable.observers
1516// const map = observable.observersIndexes
1517// const l = list.length
1518// for (let i = 0; i < l; i++) {
1519// const id = list[i].__mapid
1520// if (i) {
1521// invariant(map[id] === i, "INTERNAL ERROR maps derivation.__mapid to index in list") // for performance
1522// } else {
1523// invariant(!(id in map), "INTERNAL ERROR observer on index 0 shouldn't be held in map.") // for performance
1524// }
1525// }
1526// invariant(
1527// list.length === 0 || Object.keys(map).length === list.length - 1,
1528// "INTERNAL ERROR there is no junk in map"
1529// )
1530// }
1531function addObserver(observable, node) {
1532 // invariant(node.dependenciesState !== -1, "INTERNAL ERROR, can add only dependenciesState !== -1");
1533 // invariant(observable._observers.indexOf(node) === -1, "INTERNAL ERROR add already added node");
1534 // invariantObservers(observable);
1535 var l = observable.observers.length;
1536 if (l) {
1537 // because object assignment is relatively expensive, let's not store data about index 0.
1538 observable.observersIndexes[node.__mapid] = l;
1539 }
1540 observable.observers[l] = node;
1541 if (observable.lowestObserverState > node.dependenciesState)
1542 observable.lowestObserverState = node.dependenciesState;
1543 // invariantObservers(observable);
1544 // invariant(observable._observers.indexOf(node) !== -1, "INTERNAL ERROR didn't add node");
1545}
1546function removeObserver(observable, node) {
1547 // invariant(globalState.inBatch > 0, "INTERNAL ERROR, remove should be called only inside batch");
1548 // invariant(observable._observers.indexOf(node) !== -1, "INTERNAL ERROR remove already removed node");
1549 // invariantObservers(observable);
1550 if (observable.observers.length === 1) {
1551 // deleting last observer
1552 observable.observers.length = 0;
1553 queueForUnobservation(observable);
1554 }
1555 else {
1556 // deleting from _observersIndexes is straight forward, to delete from _observers, let's swap `node` with last element
1557 var list = observable.observers;
1558 var map = observable.observersIndexes;
1559 var filler = list.pop(); // get last element, which should fill the place of `node`, so the array doesn't have holes
1560 if (filler !== node) {
1561 // otherwise node was the last element, which already got removed from array
1562 var index = map[node.__mapid] || 0; // getting index of `node`. this is the only place we actually use map.
1563 if (index) {
1564 // map store all indexes but 0, see comment in `addObserver`
1565 map[filler.__mapid] = index;
1566 }
1567 else {
1568 delete map[filler.__mapid];
1569 }
1570 list[index] = filler;
1571 }
1572 delete map[node.__mapid];
1573 }
1574 // invariantObservers(observable);
1575 // invariant(observable._observers.indexOf(node) === -1, "INTERNAL ERROR remove already removed node2");
1576}
1577function queueForUnobservation(observable) {
1578 if (observable.isPendingUnobservation === false) {
1579 // invariant(observable._observers.length === 0, "INTERNAL ERROR, should only queue for unobservation unobserved observables");
1580 observable.isPendingUnobservation = true;
1581 globalState.pendingUnobservations.push(observable);
1582 }
1583}
1584/**
1585 * Batch starts a transaction, at least for purposes of memoizing ComputedValues when nothing else does.
1586 * During a batch `onBecomeUnobserved` will be called at most once per observable.
1587 * Avoids unnecessary recalculations.
1588 */
1589function startBatch() {
1590 globalState.inBatch++;
1591}
1592function endBatch() {
1593 if (--globalState.inBatch === 0) {
1594 runReactions();
1595 // the batch is actually about to finish, all unobserving should happen here.
1596 var list = globalState.pendingUnobservations;
1597 for (var i = 0; i < list.length; i++) {
1598 var observable = list[i];
1599 observable.isPendingUnobservation = false;
1600 if (observable.observers.length === 0) {
1601 if (observable.isBeingObserved) {
1602 // if this observable had reactive observers, trigger the hooks
1603 observable.isBeingObserved = false;
1604 observable.onBecomeUnobserved();
1605 }
1606 if (observable instanceof ComputedValue) {
1607 // computed values are automatically teared down when the last observer leaves
1608 // this process happens recursively, this computed might be the last observabe of another, etc..
1609 observable.suspend();
1610 }
1611 }
1612 }
1613 globalState.pendingUnobservations = [];
1614 }
1615}
1616function reportObserved(observable) {
1617 checkIfStateReadsAreAllowed(observable);
1618 var derivation = globalState.trackingDerivation;
1619 if (derivation !== null) {
1620 /**
1621 * Simple optimization, give each derivation run an unique id (runId)
1622 * Check if last time this observable was accessed the same runId is used
1623 * if this is the case, the relation is already known
1624 */
1625 if (derivation.runId !== observable.lastAccessedBy) {
1626 observable.lastAccessedBy = derivation.runId;
1627 derivation.newObserving[derivation.unboundDepsCount++] = observable;
1628 if (!observable.isBeingObserved) {
1629 observable.isBeingObserved = true;
1630 observable.onBecomeObserved();
1631 }
1632 }
1633 return true;
1634 }
1635 else if (observable.observers.length === 0 && globalState.inBatch > 0) {
1636 queueForUnobservation(observable);
1637 }
1638 return false;
1639}
1640// function invariantLOS(observable: IObservable, msg: string) {
1641// // it's expensive so better not run it in produciton. but temporarily helpful for testing
1642// const min = getObservers(observable).reduce((a, b) => Math.min(a, b.dependenciesState), 2)
1643// if (min >= observable.lowestObserverState) return // <- the only assumption about `lowestObserverState`
1644// throw new Error(
1645// "lowestObserverState is wrong for " +
1646// msg +
1647// " because " +
1648// min +
1649// " < " +
1650// observable.lowestObserverState
1651// )
1652// }
1653/**
1654 * NOTE: current propagation mechanism will in case of self reruning autoruns behave unexpectedly
1655 * It will propagate changes to observers from previous run
1656 * It's hard or maybe impossible (with reasonable perf) to get it right with current approach
1657 * Hopefully self reruning autoruns aren't a feature people should depend on
1658 * Also most basic use cases should be ok
1659 */
1660// Called by Atom when its value changes
1661function propagateChanged(observable) {
1662 // invariantLOS(observable, "changed start");
1663 if (observable.lowestObserverState === exports.IDerivationState.STALE)
1664 return;
1665 observable.lowestObserverState = exports.IDerivationState.STALE;
1666 var observers = observable.observers;
1667 var i = observers.length;
1668 while (i--) {
1669 var d = observers[i];
1670 if (d.dependenciesState === exports.IDerivationState.UP_TO_DATE) {
1671 if (d.isTracing !== TraceMode.NONE) {
1672 logTraceInfo(d, observable);
1673 }
1674 d.onBecomeStale();
1675 }
1676 d.dependenciesState = exports.IDerivationState.STALE;
1677 }
1678 // invariantLOS(observable, "changed end");
1679}
1680// Called by ComputedValue when it recalculate and its value changed
1681function propagateChangeConfirmed(observable) {
1682 // invariantLOS(observable, "confirmed start");
1683 if (observable.lowestObserverState === exports.IDerivationState.STALE)
1684 return;
1685 observable.lowestObserverState = exports.IDerivationState.STALE;
1686 var observers = observable.observers;
1687 var i = observers.length;
1688 while (i--) {
1689 var d = observers[i];
1690 if (d.dependenciesState === exports.IDerivationState.POSSIBLY_STALE)
1691 d.dependenciesState = exports.IDerivationState.STALE;
1692 else if (d.dependenciesState === exports.IDerivationState.UP_TO_DATE // this happens during computing of `d`, just keep lowestObserverState up to date.
1693 )
1694 observable.lowestObserverState = exports.IDerivationState.UP_TO_DATE;
1695 }
1696 // invariantLOS(observable, "confirmed end");
1697}
1698// Used by computed when its dependency changed, but we don't wan't to immediately recompute.
1699function propagateMaybeChanged(observable) {
1700 // invariantLOS(observable, "maybe start");
1701 if (observable.lowestObserverState !== exports.IDerivationState.UP_TO_DATE)
1702 return;
1703 observable.lowestObserverState = exports.IDerivationState.POSSIBLY_STALE;
1704 var observers = observable.observers;
1705 var i = observers.length;
1706 while (i--) {
1707 var d = observers[i];
1708 if (d.dependenciesState === exports.IDerivationState.UP_TO_DATE) {
1709 d.dependenciesState = exports.IDerivationState.POSSIBLY_STALE;
1710 if (d.isTracing !== TraceMode.NONE) {
1711 logTraceInfo(d, observable);
1712 }
1713 d.onBecomeStale();
1714 }
1715 }
1716 // invariantLOS(observable, "maybe end");
1717}
1718function logTraceInfo(derivation, observable) {
1719 console.log("[mobx.trace] '" + derivation.name + "' is invalidated due to a change in: '" + observable.name + "'");
1720 if (derivation.isTracing === TraceMode.BREAK) {
1721 var lines = [];
1722 printDepTree(getDependencyTree(derivation), lines, 1);
1723 // prettier-ignore
1724 new Function("debugger;\n/*\nTracing '" + derivation.name + "'\n\nYou are entering this break point because derivation '" + derivation.name + "' is being traced and '" + observable.name + "' is now forcing it to update.\nJust follow the stacktrace you should now see in the devtools to see precisely what piece of your code is causing this update\nThe stackframe you are looking for is at least ~6-8 stack-frames up.\n\n" + (derivation instanceof ComputedValue ? derivation.derivation.toString().replace(/[*]\//g, "/") : "") + "\n\nThe dependencies for this derivation are:\n\n" + lines.join("\n") + "\n*/\n ")();
1725 }
1726}
1727function printDepTree(tree, lines, depth) {
1728 if (lines.length >= 1000) {
1729 lines.push("(and many more)");
1730 return;
1731 }
1732 lines.push("" + new Array(depth).join("\t") + tree.name); // MWE: not the fastest, but the easiest way :)
1733 if (tree.dependencies)
1734 tree.dependencies.forEach(function (child) { return printDepTree(child, lines, depth + 1); });
1735}
1736
1737var Reaction = /** @class */ (function () {
1738 function Reaction(name, onInvalidate, errorHandler, requiresObservable) {
1739 if (name === void 0) { name = "Reaction@" + getNextId(); }
1740 if (requiresObservable === void 0) { requiresObservable = false; }
1741 this.name = name;
1742 this.onInvalidate = onInvalidate;
1743 this.errorHandler = errorHandler;
1744 this.requiresObservable = requiresObservable;
1745 this.observing = []; // nodes we are looking at. Our value depends on these nodes
1746 this.newObserving = [];
1747 this.dependenciesState = exports.IDerivationState.NOT_TRACKING;
1748 this.diffValue = 0;
1749 this.runId = 0;
1750 this.unboundDepsCount = 0;
1751 this.__mapid = "#" + getNextId();
1752 this.isDisposed = false;
1753 this._isScheduled = false;
1754 this._isTrackPending = false;
1755 this._isRunning = false;
1756 this.isTracing = TraceMode.NONE;
1757 }
1758 Reaction.prototype.onBecomeStale = function () {
1759 this.schedule();
1760 };
1761 Reaction.prototype.schedule = function () {
1762 if (!this._isScheduled) {
1763 this._isScheduled = true;
1764 globalState.pendingReactions.push(this);
1765 runReactions();
1766 }
1767 };
1768 Reaction.prototype.isScheduled = function () {
1769 return this._isScheduled;
1770 };
1771 /**
1772 * internal, use schedule() if you intend to kick off a reaction
1773 */
1774 Reaction.prototype.runReaction = function () {
1775 if (!this.isDisposed) {
1776 startBatch();
1777 this._isScheduled = false;
1778 if (shouldCompute(this)) {
1779 this._isTrackPending = true;
1780 try {
1781 this.onInvalidate();
1782 if (this._isTrackPending && isSpyEnabled()) {
1783 // onInvalidate didn't trigger track right away..
1784 spyReport({
1785 name: this.name,
1786 type: "scheduled-reaction"
1787 });
1788 }
1789 }
1790 catch (e) {
1791 this.reportExceptionInDerivation(e);
1792 }
1793 }
1794 endBatch();
1795 }
1796 };
1797 Reaction.prototype.track = function (fn) {
1798 startBatch();
1799 var notify = isSpyEnabled();
1800 var startTime;
1801 if (notify) {
1802 startTime = Date.now();
1803 spyReportStart({
1804 name: this.name,
1805 type: "reaction"
1806 });
1807 }
1808 this._isRunning = true;
1809 var result = trackDerivedFunction(this, fn, undefined);
1810 this._isRunning = false;
1811 this._isTrackPending = false;
1812 if (this.isDisposed) {
1813 // disposed during last run. Clean up everything that was bound after the dispose call.
1814 clearObserving(this);
1815 }
1816 if (isCaughtException(result))
1817 this.reportExceptionInDerivation(result.cause);
1818 if (notify) {
1819 spyReportEnd({
1820 time: Date.now() - startTime
1821 });
1822 }
1823 endBatch();
1824 };
1825 Reaction.prototype.reportExceptionInDerivation = function (error) {
1826 var _this = this;
1827 if (this.errorHandler) {
1828 this.errorHandler(error, this);
1829 return;
1830 }
1831 if (globalState.disableErrorBoundaries)
1832 throw error;
1833 var message = "[mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: '" + this + "'";
1834 if (globalState.suppressReactionErrors) {
1835 console.warn("[mobx] (error in reaction '" + this.name + "' suppressed, fix error of causing action below)"); // prettier-ignore
1836 }
1837 else {
1838 console.error(message, error);
1839 /** If debugging brought you here, please, read the above message :-). Tnx! */
1840 }
1841 if (isSpyEnabled()) {
1842 spyReport({
1843 type: "error",
1844 name: this.name,
1845 message: message,
1846 error: "" + error
1847 });
1848 }
1849 globalState.globalReactionErrorHandlers.forEach(function (f) { return f(error, _this); });
1850 };
1851 Reaction.prototype.dispose = function () {
1852 if (!this.isDisposed) {
1853 this.isDisposed = true;
1854 if (!this._isRunning) {
1855 // if disposed while running, clean up later. Maybe not optimal, but rare case
1856 startBatch();
1857 clearObserving(this);
1858 endBatch();
1859 }
1860 }
1861 };
1862 Reaction.prototype.getDisposer = function () {
1863 var r = this.dispose.bind(this);
1864 r.$mobx = this;
1865 return r;
1866 };
1867 Reaction.prototype.toString = function () {
1868 return "Reaction[" + this.name + "]";
1869 };
1870 Reaction.prototype.trace = function (enterBreakPoint) {
1871 if (enterBreakPoint === void 0) { enterBreakPoint = false; }
1872 trace(this, enterBreakPoint);
1873 };
1874 return Reaction;
1875}());
1876function onReactionError(handler) {
1877 globalState.globalReactionErrorHandlers.push(handler);
1878 return function () {
1879 var idx = globalState.globalReactionErrorHandlers.indexOf(handler);
1880 if (idx >= 0)
1881 globalState.globalReactionErrorHandlers.splice(idx, 1);
1882 };
1883}
1884/**
1885 * Magic number alert!
1886 * Defines within how many times a reaction is allowed to re-trigger itself
1887 * until it is assumed that this is gonna be a never ending loop...
1888 */
1889var MAX_REACTION_ITERATIONS = 100;
1890var reactionScheduler = function (f) { return f(); };
1891function runReactions() {
1892 // Trampolining, if runReactions are already running, new reactions will be picked up
1893 if (globalState.inBatch > 0 || globalState.isRunningReactions)
1894 return;
1895 reactionScheduler(runReactionsHelper);
1896}
1897function runReactionsHelper() {
1898 globalState.isRunningReactions = true;
1899 var allReactions = globalState.pendingReactions;
1900 var iterations = 0;
1901 // While running reactions, new reactions might be triggered.
1902 // Hence we work with two variables and check whether
1903 // we converge to no remaining reactions after a while.
1904 while (allReactions.length > 0) {
1905 if (++iterations === MAX_REACTION_ITERATIONS) {
1906 console.error("Reaction doesn't converge to a stable state after " + MAX_REACTION_ITERATIONS + " iterations." +
1907 (" Probably there is a cycle in the reactive function: " + allReactions[0]));
1908 allReactions.splice(0); // clear reactions
1909 }
1910 var remainingReactions = allReactions.splice(0);
1911 for (var i = 0, l = remainingReactions.length; i < l; i++)
1912 remainingReactions[i].runReaction();
1913 }
1914 globalState.isRunningReactions = false;
1915}
1916var isReaction = createInstanceofPredicate("Reaction", Reaction);
1917function setReactionScheduler(fn) {
1918 var baseScheduler = reactionScheduler;
1919 reactionScheduler = function (f) { return fn(function () { return baseScheduler(f); }); };
1920}
1921
1922function isSpyEnabled() {
1923 return !!globalState.spyListeners.length;
1924}
1925function spyReport(event) {
1926 if (!globalState.spyListeners.length)
1927 return;
1928 var listeners = globalState.spyListeners;
1929 for (var i = 0, l = listeners.length; i < l; i++)
1930 listeners[i](event);
1931}
1932function spyReportStart(event) {
1933 var change = __assign(__assign({}, event), { spyReportStart: true });
1934 spyReport(change);
1935}
1936var END_EVENT = { spyReportEnd: true };
1937function spyReportEnd(change) {
1938 if (change)
1939 spyReport(__assign(__assign({}, change), { spyReportEnd: true }));
1940 else
1941 spyReport(END_EVENT);
1942}
1943function spy(listener) {
1944 globalState.spyListeners.push(listener);
1945 return once(function () {
1946 globalState.spyListeners = globalState.spyListeners.filter(function (l) { return l !== listener; });
1947 });
1948}
1949
1950function dontReassignFields() {
1951 fail("@action fields are not reassignable");
1952}
1953function namedActionDecorator(name) {
1954 return function (target, prop, descriptor) {
1955 if (descriptor) {
1956 if (descriptor.get !== undefined) {
1957 return fail("@action cannot be used with getters");
1958 }
1959 // babel / typescript
1960 // @action method() { }
1961 if (descriptor.value) {
1962 // typescript
1963 return {
1964 value: createAction(name, descriptor.value),
1965 enumerable: false,
1966 configurable: true,
1967 writable: true // for typescript, this must be writable, otherwise it cannot inherit :/ (see inheritable actions test)
1968 };
1969 }
1970 // babel only: @action method = () => {}
1971 var initializer_1 = descriptor.initializer;
1972 return {
1973 enumerable: false,
1974 configurable: true,
1975 writable: true,
1976 initializer: function () {
1977 // N.B: we can't immediately invoke initializer; this would be wrong
1978 return createAction(name, initializer_1.call(this));
1979 }
1980 };
1981 }
1982 // bound instance methods
1983 return actionFieldDecorator(name).apply(this, arguments);
1984 };
1985}
1986function actionFieldDecorator(name) {
1987 // Simple property that writes on first invocation to the current instance
1988 return function (target, prop, descriptor) {
1989 Object.defineProperty(target, prop, {
1990 configurable: true,
1991 enumerable: false,
1992 get: function () {
1993 return undefined;
1994 },
1995 set: function (value) {
1996 addHiddenProp(this, prop, action(name, value));
1997 }
1998 });
1999 };
2000}
2001function boundActionDecorator(target, propertyName, descriptor, applyToInstance) {
2002 if (applyToInstance === true) {
2003 defineBoundAction(target, propertyName, descriptor.value);
2004 return null;
2005 }
2006 if (descriptor) {
2007 // if (descriptor.value)
2008 // Typescript / Babel: @action.bound method() { }
2009 // also: babel @action.bound method = () => {}
2010 return {
2011 configurable: true,
2012 enumerable: false,
2013 get: function () {
2014 defineBoundAction(this, propertyName, descriptor.value || descriptor.initializer.call(this));
2015 return this[propertyName];
2016 },
2017 set: dontReassignFields
2018 };
2019 }
2020 // field decorator Typescript @action.bound method = () => {}
2021 return {
2022 enumerable: false,
2023 configurable: true,
2024 set: function (v) {
2025 defineBoundAction(this, propertyName, v);
2026 },
2027 get: function () {
2028 return undefined;
2029 }
2030 };
2031}
2032
2033var action = function action(arg1, arg2, arg3, arg4) {
2034 // action(fn() {})
2035 if (arguments.length === 1 && typeof arg1 === "function")
2036 return createAction(arg1.name || "<unnamed action>", arg1);
2037 // action("name", fn() {})
2038 if (arguments.length === 2 && typeof arg2 === "function")
2039 return createAction(arg1, arg2);
2040 // @action("name") fn() {}
2041 if (arguments.length === 1 && typeof arg1 === "string")
2042 return namedActionDecorator(arg1);
2043 // @action fn() {}
2044 if (arg4 === true) {
2045 // apply to instance immediately
2046 arg1[arg2] = createAction(arg1.name || arg2, arg3.value);
2047 }
2048 else {
2049 return namedActionDecorator(arg2).apply(null, arguments);
2050 }
2051};
2052action.bound = boundActionDecorator;
2053function runInAction(arg1, arg2) {
2054 // TODO: deprecate?
2055 var actionName = typeof arg1 === "string" ? arg1 : arg1.name || "<unnamed action>";
2056 var fn = typeof arg1 === "function" ? arg1 : arg2;
2057 {
2058 invariant(typeof fn === "function" && fn.length === 0, "`runInAction` expects a function without arguments");
2059 if (typeof actionName !== "string" || !actionName)
2060 fail("actions should have valid names, got: '" + actionName + "'");
2061 }
2062 return executeAction(actionName, fn, this, undefined);
2063}
2064function isAction(thing) {
2065 return typeof thing === "function" && thing.isMobxAction === true;
2066}
2067function defineBoundAction(target, propertyName, fn) {
2068 addHiddenProp(target, propertyName, createAction(propertyName, fn.bind(target)));
2069}
2070
2071/**
2072 * Creates a named reactive view and keeps it alive, so that the view is always
2073 * updated if one of the dependencies changes, even when the view is not further used by something else.
2074 * @param view The reactive view
2075 * @returns disposer function, which can be used to stop the view from being updated in the future.
2076 */
2077function autorun(view, opts) {
2078 if (opts === void 0) { opts = EMPTY_OBJECT; }
2079 {
2080 invariant(typeof view === "function", "Autorun expects a function as first argument");
2081 invariant(isAction(view) === false, "Autorun does not accept actions since actions are untrackable");
2082 }
2083 var name = (opts && opts.name) || view.name || "Autorun@" + getNextId();
2084 var runSync = !opts.scheduler && !opts.delay;
2085 var reaction;
2086 if (runSync) {
2087 // normal autorun
2088 reaction = new Reaction(name, function () {
2089 this.track(reactionRunner);
2090 }, opts.onError, opts.requiresObservable);
2091 }
2092 else {
2093 var scheduler_1 = createSchedulerFromOptions(opts);
2094 // debounced autorun
2095 var isScheduled_1 = false;
2096 reaction = new Reaction(name, function () {
2097 if (!isScheduled_1) {
2098 isScheduled_1 = true;
2099 scheduler_1(function () {
2100 isScheduled_1 = false;
2101 if (!reaction.isDisposed)
2102 reaction.track(reactionRunner);
2103 });
2104 }
2105 }, opts.onError, opts.requiresObservable);
2106 }
2107 function reactionRunner() {
2108 view(reaction);
2109 }
2110 reaction.schedule();
2111 return reaction.getDisposer();
2112}
2113var run = function (f) { return f(); };
2114function createSchedulerFromOptions(opts) {
2115 return opts.scheduler
2116 ? opts.scheduler
2117 : opts.delay
2118 ? function (f) { return setTimeout(f, opts.delay); }
2119 : run;
2120}
2121function reaction(expression, effect, opts) {
2122 if (opts === void 0) { opts = EMPTY_OBJECT; }
2123 if (typeof opts === "boolean") {
2124 opts = { fireImmediately: opts };
2125 deprecated("Using fireImmediately as argument is deprecated. Use '{ fireImmediately: true }' instead");
2126 }
2127 {
2128 invariant(typeof expression === "function", "First argument to reaction should be a function");
2129 invariant(typeof opts === "object", "Third argument of reactions should be an object");
2130 }
2131 var name = opts.name || "Reaction@" + getNextId();
2132 var effectAction = action(name, opts.onError ? wrapErrorHandler(opts.onError, effect) : effect);
2133 var runSync = !opts.scheduler && !opts.delay;
2134 var scheduler = createSchedulerFromOptions(opts);
2135 var firstTime = true;
2136 var isScheduled = false;
2137 var value;
2138 var equals = opts.compareStructural
2139 ? comparer.structural
2140 : opts.equals || comparer.default;
2141 var r = new Reaction(name, function () {
2142 if (firstTime || runSync) {
2143 reactionRunner();
2144 }
2145 else if (!isScheduled) {
2146 isScheduled = true;
2147 scheduler(reactionRunner);
2148 }
2149 }, opts.onError, opts.requiresObservable);
2150 function reactionRunner() {
2151 isScheduled = false; // Q: move into reaction runner?
2152 if (r.isDisposed)
2153 return;
2154 var changed = false;
2155 r.track(function () {
2156 var nextValue = expression(r);
2157 changed = firstTime || !equals(value, nextValue);
2158 value = nextValue;
2159 });
2160 if (firstTime && opts.fireImmediately)
2161 effectAction(value, r);
2162 if (!firstTime && changed === true)
2163 effectAction(value, r);
2164 if (firstTime)
2165 firstTime = false;
2166 }
2167 r.schedule();
2168 return r.getDisposer();
2169}
2170function wrapErrorHandler(errorHandler, baseFn) {
2171 return function () {
2172 try {
2173 return baseFn.apply(this, arguments);
2174 }
2175 catch (e) {
2176 errorHandler.call(this, e);
2177 }
2178 };
2179}
2180
2181function onBecomeObserved(thing, arg2, arg3) {
2182 return interceptHook("onBecomeObserved", thing, arg2, arg3);
2183}
2184function onBecomeUnobserved(thing, arg2, arg3) {
2185 return interceptHook("onBecomeUnobserved", thing, arg2, arg3);
2186}
2187function interceptHook(hook, thing, arg2, arg3) {
2188 var atom = typeof arg3 === "function" ? getAtom(thing, arg2) : getAtom(thing);
2189 var cb = typeof arg3 === "function" ? arg3 : arg2;
2190 var orig = atom[hook];
2191 if (typeof orig !== "function")
2192 return fail("Not an atom that can be (un)observed");
2193 atom[hook] = function () {
2194 orig.call(this);
2195 cb.call(this);
2196 };
2197 return function () {
2198 atom[hook] = orig;
2199 };
2200}
2201
2202function configure(options) {
2203 var enforceActions = options.enforceActions, computedRequiresReaction = options.computedRequiresReaction, computedConfigurable = options.computedConfigurable, disableErrorBoundaries = options.disableErrorBoundaries, arrayBuffer = options.arrayBuffer, reactionScheduler = options.reactionScheduler, reactionRequiresObservable = options.reactionRequiresObservable, observableRequiresReaction = options.observableRequiresReaction;
2204 if (options.isolateGlobalState === true) {
2205 isolateGlobalState();
2206 }
2207 if (enforceActions !== undefined) {
2208 if (typeof enforceActions === "boolean" || enforceActions === "strict")
2209 deprecated("Deprecated value for 'enforceActions', use 'false' => '\"never\"', 'true' => '\"observed\"', '\"strict\"' => \"'always'\" instead");
2210 var ea = void 0;
2211 switch (enforceActions) {
2212 case true:
2213 case "observed":
2214 ea = true;
2215 break;
2216 case false:
2217 case "never":
2218 ea = false;
2219 break;
2220 case "strict":
2221 case "always":
2222 ea = "strict";
2223 break;
2224 default:
2225 fail("Invalid value for 'enforceActions': '" + enforceActions + "', expected 'never', 'always' or 'observed'");
2226 }
2227 globalState.enforceActions = ea;
2228 globalState.allowStateChanges = ea === true || ea === "strict" ? false : true;
2229 }
2230 if (computedRequiresReaction !== undefined) {
2231 globalState.computedRequiresReaction = !!computedRequiresReaction;
2232 }
2233 if (reactionRequiresObservable !== undefined) {
2234 globalState.reactionRequiresObservable = !!reactionRequiresObservable;
2235 }
2236 if (observableRequiresReaction !== undefined) {
2237 globalState.observableRequiresReaction = !!observableRequiresReaction;
2238 globalState.allowStateReads = !globalState.observableRequiresReaction;
2239 }
2240 if (computedConfigurable !== undefined) {
2241 globalState.computedConfigurable = !!computedConfigurable;
2242 }
2243 if (disableErrorBoundaries !== undefined) {
2244 if (disableErrorBoundaries === true)
2245 console.warn("WARNING: Debug feature only. MobX will NOT recover from errors if this is on.");
2246 globalState.disableErrorBoundaries = !!disableErrorBoundaries;
2247 }
2248 if (typeof arrayBuffer === "number") {
2249 reserveArrayBuffer(arrayBuffer);
2250 }
2251 if (reactionScheduler) {
2252 setReactionScheduler(reactionScheduler);
2253 }
2254}
2255
2256function decorate(thing, decorators) {
2257 if (!isPlainObject(decorators))
2258 fail("Decorators should be a key value map");
2259 var target = typeof thing === "function" ? thing.prototype : thing;
2260 var _loop_1 = function (prop) {
2261 var propertyDecorators = decorators[prop];
2262 if (!Array.isArray(propertyDecorators)) {
2263 propertyDecorators = [propertyDecorators];
2264 }
2265 // prettier-ignore
2266 if (!propertyDecorators.every(function (decorator) { return typeof decorator === "function"; }))
2267 fail("Decorate: expected a decorator function or array of decorator functions for '" + prop + "'");
2268 var descriptor = Object.getOwnPropertyDescriptor(target, prop);
2269 var newDescriptor = propertyDecorators.reduce(function (accDescriptor, decorator) { return decorator(target, prop, accDescriptor); }, descriptor);
2270 if (newDescriptor)
2271 Object.defineProperty(target, prop, newDescriptor);
2272 };
2273 for (var prop in decorators) {
2274 _loop_1(prop);
2275 }
2276 return thing;
2277}
2278
2279function extendShallowObservable(target, properties, decorators) {
2280 deprecated("'extendShallowObservable' is deprecated, use 'extendObservable(target, props, { deep: false })' instead");
2281 return extendObservable(target, properties, decorators, shallowCreateObservableOptions);
2282}
2283function extendObservable(target, properties, decorators, options) {
2284 {
2285 invariant(arguments.length >= 2 && arguments.length <= 4, "'extendObservable' expected 2-4 arguments");
2286 invariant(typeof target === "object", "'extendObservable' expects an object as first argument");
2287 invariant(!isObservableMap(target), "'extendObservable' should not be used on maps, use map.merge instead");
2288 invariant(!isObservable(properties), "Extending an object with another observable (object) is not supported. Please construct an explicit propertymap, using `toJS` if need. See issue #540");
2289 if (decorators)
2290 for (var key in decorators)
2291 if (!(key in properties))
2292 fail("Trying to declare a decorator for unspecified property '" + key + "'");
2293 }
2294 options = asCreateObservableOptions(options);
2295 var defaultDecorator = options.defaultDecorator || (options.deep === false ? refDecorator : deepDecorator);
2296 initializeInstance(target);
2297 asObservableObject(target, options.name, defaultDecorator.enhancer); // make sure object is observable, even without initial props
2298 startBatch();
2299 try {
2300 for (var key in properties) {
2301 var descriptor = Object.getOwnPropertyDescriptor(properties, key);
2302 {
2303 if (isComputed(descriptor.value))
2304 fail("Passing a 'computed' as initial property value is no longer supported by extendObservable. Use a getter or decorator instead");
2305 }
2306 var decorator = decorators && key in decorators
2307 ? decorators[key]
2308 : descriptor.get
2309 ? computedDecorator
2310 : defaultDecorator;
2311 if (typeof decorator !== "function")
2312 return fail("Not a valid decorator for '" + key + "', got: " + decorator);
2313 var resultDescriptor = decorator(target, key, descriptor, true);
2314 if (resultDescriptor // otherwise, assume already applied, due to `applyToInstance`
2315 )
2316 Object.defineProperty(target, key, resultDescriptor);
2317 }
2318 }
2319 finally {
2320 endBatch();
2321 }
2322 return target;
2323}
2324
2325function getDependencyTree(thing, property) {
2326 return nodeToDependencyTree(getAtom(thing, property));
2327}
2328function nodeToDependencyTree(node) {
2329 var result = {
2330 name: node.name
2331 };
2332 if (node.observing && node.observing.length > 0)
2333 result.dependencies = unique(node.observing).map(nodeToDependencyTree);
2334 return result;
2335}
2336function getObserverTree(thing, property) {
2337 return nodeToObserverTree(getAtom(thing, property));
2338}
2339function nodeToObserverTree(node) {
2340 var result = {
2341 name: node.name
2342 };
2343 if (hasObservers(node))
2344 result.observers = getObservers(node).map(nodeToObserverTree);
2345 return result;
2346}
2347
2348var generatorId = 0;
2349function FlowCancellationError() {
2350 this.message = "FLOW_CANCELLED";
2351}
2352FlowCancellationError.prototype = Object.create(Error.prototype);
2353function isFlowCancellationError(error) {
2354 return error instanceof FlowCancellationError;
2355}
2356function flow(generator) {
2357 if (arguments.length !== 1)
2358 fail("Flow expects one 1 argument and cannot be used as decorator");
2359 var name = generator.name || "<unnamed flow>";
2360 // Implementation based on https://github.com/tj/co/blob/master/index.js
2361 return function () {
2362 var ctx = this;
2363 var args = arguments;
2364 var runId = ++generatorId;
2365 var gen = action(name + " - runid: " + runId + " - init", generator).apply(ctx, args);
2366 var rejector;
2367 var pendingPromise = undefined;
2368 var res = new Promise(function (resolve, reject) {
2369 var stepId = 0;
2370 rejector = reject;
2371 function onFulfilled(res) {
2372 pendingPromise = undefined;
2373 var ret;
2374 try {
2375 ret = action(name + " - runid: " + runId + " - yield " + stepId++, gen.next).call(gen, res);
2376 }
2377 catch (e) {
2378 return reject(e);
2379 }
2380 next(ret);
2381 }
2382 function onRejected(err) {
2383 pendingPromise = undefined;
2384 var ret;
2385 try {
2386 ret = action(name + " - runid: " + runId + " - yield " + stepId++, gen.throw).call(gen, err);
2387 }
2388 catch (e) {
2389 return reject(e);
2390 }
2391 next(ret);
2392 }
2393 function next(ret) {
2394 if (ret && typeof ret.then === "function") {
2395 // an async iterator
2396 ret.then(next, reject);
2397 return;
2398 }
2399 if (ret.done)
2400 return resolve(ret.value);
2401 pendingPromise = Promise.resolve(ret.value);
2402 return pendingPromise.then(onFulfilled, onRejected);
2403 }
2404 onFulfilled(undefined); // kick off the process
2405 });
2406 res.cancel = action(name + " - runid: " + runId + " - cancel", function () {
2407 try {
2408 if (pendingPromise)
2409 cancelPromise(pendingPromise);
2410 // Finally block can return (or yield) stuff..
2411 var res_1 = gen.return(undefined);
2412 // eat anything that promise would do, it's cancelled!
2413 var yieldedPromise = Promise.resolve(res_1.value);
2414 yieldedPromise.then(noop, noop);
2415 cancelPromise(yieldedPromise); // maybe it can be cancelled :)
2416 // reject our original promise
2417 rejector(new FlowCancellationError());
2418 }
2419 catch (e) {
2420 rejector(e); // there could be a throwing finally block
2421 }
2422 });
2423 return res;
2424 };
2425}
2426function cancelPromise(promise) {
2427 if (typeof promise.cancel === "function")
2428 promise.cancel();
2429}
2430
2431function interceptReads(thing, propOrHandler, handler) {
2432 var target;
2433 if (isObservableMap(thing) || isObservableArray(thing) || isObservableValue(thing)) {
2434 target = getAdministration(thing);
2435 }
2436 else if (isObservableObject(thing)) {
2437 if (typeof propOrHandler !== "string")
2438 return fail("InterceptReads can only be used with a specific property, not with an object in general");
2439 target = getAdministration(thing, propOrHandler);
2440 }
2441 else {
2442 return fail("Expected observable map, object or array as first array");
2443 }
2444 if (target.dehancer !== undefined)
2445 return fail("An intercept reader was already established");
2446 target.dehancer = typeof propOrHandler === "function" ? propOrHandler : handler;
2447 return function () {
2448 target.dehancer = undefined;
2449 };
2450}
2451
2452function intercept(thing, propOrHandler, handler) {
2453 if (typeof handler === "function")
2454 return interceptProperty(thing, propOrHandler, handler);
2455 else
2456 return interceptInterceptable(thing, propOrHandler);
2457}
2458function interceptInterceptable(thing, handler) {
2459 return getAdministration(thing).intercept(handler);
2460}
2461function interceptProperty(thing, property, handler) {
2462 return getAdministration(thing, property).intercept(handler);
2463}
2464
2465function _isComputed(value, property) {
2466 if (value === null || value === undefined)
2467 return false;
2468 if (property !== undefined) {
2469 if (isObservableObject(value) === false)
2470 return false;
2471 if (!value.$mobx.values[property])
2472 return false;
2473 var atom = getAtom(value, property);
2474 return isComputedValue(atom);
2475 }
2476 return isComputedValue(value);
2477}
2478function isComputed(value) {
2479 if (arguments.length > 1)
2480 return fail("isComputed expects only 1 argument. Use isObservableProp to inspect the observability of a property");
2481 return _isComputed(value);
2482}
2483function isComputedProp(value, propName) {
2484 if (typeof propName !== "string")
2485 return fail("isComputed expected a property name as second argument");
2486 return _isComputed(value, propName);
2487}
2488
2489function _isObservable(value, property) {
2490 if (value === null || value === undefined)
2491 return false;
2492 if (property !== undefined) {
2493 if (isObservableMap(value) || isObservableArray(value))
2494 return fail("isObservable(object, propertyName) is not supported for arrays and maps. Use map.has or array.length instead.");
2495 if (isObservableObject(value)) {
2496 var o = value.$mobx;
2497 return o.values && !!o.values[property];
2498 }
2499 return false;
2500 }
2501 // For first check, see #701
2502 return (isObservableObject(value) ||
2503 !!value.$mobx ||
2504 isAtom(value) ||
2505 isReaction(value) ||
2506 isComputedValue(value));
2507}
2508function isObservable(value) {
2509 if (arguments.length !== 1)
2510 fail("isObservable expects only 1 argument. Use isObservableProp to inspect the observability of a property");
2511 return _isObservable(value);
2512}
2513function isObservableProp(value, propName) {
2514 if (typeof propName !== "string")
2515 return fail("expected a property name as second argument");
2516 return _isObservable(value, propName);
2517}
2518
2519function keys(obj) {
2520 if (isObservableObject(obj)) {
2521 return obj.$mobx.getKeys();
2522 }
2523 if (isObservableMap(obj)) {
2524 return obj._keys.slice();
2525 }
2526 if (isObservableSet(obj)) {
2527 return iteratorToArray(obj.keys());
2528 }
2529 if (isObservableArray(obj)) {
2530 return obj.map(function (_, index) { return index; });
2531 }
2532 return fail("'keys()' can only be used on observable objects, arrays, sets and maps");
2533}
2534function values(obj) {
2535 if (isObservableObject(obj)) {
2536 return keys(obj).map(function (key) { return obj[key]; });
2537 }
2538 if (isObservableMap(obj)) {
2539 return keys(obj).map(function (key) { return obj.get(key); });
2540 }
2541 if (isObservableSet(obj)) {
2542 return iteratorToArray(obj.values());
2543 }
2544 if (isObservableArray(obj)) {
2545 return obj.slice();
2546 }
2547 return fail("'values()' can only be used on observable objects, arrays, sets and maps");
2548}
2549function entries(obj) {
2550 if (isObservableObject(obj)) {
2551 return keys(obj).map(function (key) { return [key, obj[key]]; });
2552 }
2553 if (isObservableMap(obj)) {
2554 return keys(obj).map(function (key) { return [key, obj.get(key)]; });
2555 }
2556 if (isObservableSet(obj)) {
2557 return iteratorToArray(obj.entries());
2558 }
2559 if (isObservableArray(obj)) {
2560 return obj.map(function (key, index) { return [index, key]; });
2561 }
2562 return fail("'entries()' can only be used on observable objects, arrays and maps");
2563}
2564function set(obj, key, value) {
2565 if (arguments.length === 2 && !isObservableSet(obj)) {
2566 startBatch();
2567 var values_1 = key;
2568 try {
2569 for (var key_1 in values_1)
2570 set(obj, key_1, values_1[key_1]);
2571 }
2572 finally {
2573 endBatch();
2574 }
2575 return;
2576 }
2577 if (isObservableObject(obj)) {
2578 var adm = obj.$mobx;
2579 var existingObservable = adm.values[key];
2580 if (existingObservable) {
2581 adm.write(obj, key, value);
2582 }
2583 else {
2584 defineObservableProperty(obj, key, value, adm.defaultEnhancer);
2585 }
2586 }
2587 else if (isObservableMap(obj)) {
2588 obj.set(key, value);
2589 }
2590 else if (isObservableSet(obj)) {
2591 obj.add(key);
2592 }
2593 else if (isObservableArray(obj)) {
2594 if (typeof key !== "number")
2595 key = parseInt(key, 10);
2596 invariant(key >= 0, "Not a valid index: '" + key + "'");
2597 startBatch();
2598 if (key >= obj.length)
2599 obj.length = key + 1;
2600 obj[key] = value;
2601 endBatch();
2602 }
2603 else {
2604 return fail("'set()' can only be used on observable objects, arrays and maps");
2605 }
2606}
2607function remove(obj, key) {
2608 if (isObservableObject(obj)) {
2609 obj.$mobx.remove(key);
2610 }
2611 else if (isObservableMap(obj)) {
2612 obj.delete(key);
2613 }
2614 else if (isObservableSet(obj)) {
2615 obj.delete(key);
2616 }
2617 else if (isObservableArray(obj)) {
2618 if (typeof key !== "number")
2619 key = parseInt(key, 10);
2620 invariant(key >= 0, "Not a valid index: '" + key + "'");
2621 obj.splice(key, 1);
2622 }
2623 else {
2624 return fail("'remove()' can only be used on observable objects, arrays and maps");
2625 }
2626}
2627function has(obj, key) {
2628 if (isObservableObject(obj)) {
2629 // return keys(obj).indexOf(key) >= 0
2630 var adm = getAdministration(obj);
2631 adm.getKeys(); // make sure we get notified of key changes, but for performance, use the values map to look up existence
2632 return !!adm.values[key];
2633 }
2634 else if (isObservableMap(obj)) {
2635 return obj.has(key);
2636 }
2637 else if (isObservableSet(obj)) {
2638 return obj.has(key);
2639 }
2640 else if (isObservableArray(obj)) {
2641 return key >= 0 && key < obj.length;
2642 }
2643 else {
2644 return fail("'has()' can only be used on observable objects, arrays and maps");
2645 }
2646}
2647function get(obj, key) {
2648 if (!has(obj, key))
2649 return undefined;
2650 if (isObservableObject(obj)) {
2651 return obj[key];
2652 }
2653 else if (isObservableMap(obj)) {
2654 return obj.get(key);
2655 }
2656 else if (isObservableArray(obj)) {
2657 return obj[key];
2658 }
2659 else {
2660 return fail("'get()' can only be used on observable objects, arrays and maps");
2661 }
2662}
2663
2664function observe(thing, propOrCb, cbOrFire, fireImmediately) {
2665 if (typeof cbOrFire === "function")
2666 return observeObservableProperty(thing, propOrCb, cbOrFire, fireImmediately);
2667 else
2668 return observeObservable(thing, propOrCb, cbOrFire);
2669}
2670function observeObservable(thing, listener, fireImmediately) {
2671 return getAdministration(thing).observe(listener, fireImmediately);
2672}
2673function observeObservableProperty(thing, property, listener, fireImmediately) {
2674 return getAdministration(thing, property).observe(listener, fireImmediately);
2675}
2676
2677var defaultOptions = {
2678 detectCycles: true,
2679 exportMapsAsObjects: true,
2680 recurseEverything: false
2681};
2682function cache(map, key, value, options) {
2683 if (options.detectCycles)
2684 map.set(key, value);
2685 return value;
2686}
2687function toJSHelper(source, options, __alreadySeen) {
2688 if (!options.recurseEverything && !isObservable(source))
2689 return source;
2690 if (typeof source !== "object")
2691 return source;
2692 // Directly return null if source is null
2693 if (source === null)
2694 return null;
2695 // Directly return the Date object itself if contained in the observable
2696 if (source instanceof Date)
2697 return source;
2698 if (isObservableValue(source))
2699 return toJSHelper(source.get(), options, __alreadySeen);
2700 // make sure we track the keys of the object
2701 if (isObservable(source))
2702 keys(source);
2703 var detectCycles = options.detectCycles === true;
2704 if (detectCycles && source !== null && __alreadySeen.has(source)) {
2705 return __alreadySeen.get(source);
2706 }
2707 if (isObservableArray(source) || Array.isArray(source)) {
2708 var res_1 = cache(__alreadySeen, source, [], options);
2709 var toAdd = source.map(function (value) { return toJSHelper(value, options, __alreadySeen); });
2710 res_1.length = toAdd.length;
2711 for (var i = 0, l = toAdd.length; i < l; i++)
2712 res_1[i] = toAdd[i];
2713 return res_1;
2714 }
2715 if (isObservableSet(source) || Object.getPrototypeOf(source) === Set.prototype) {
2716 if (options.exportMapsAsObjects === false) {
2717 var res_2 = cache(__alreadySeen, source, new Set(), options);
2718 source.forEach(function (value) {
2719 res_2.add(toJSHelper(value, options, __alreadySeen));
2720 });
2721 return res_2;
2722 }
2723 else {
2724 var res_3 = cache(__alreadySeen, source, [], options);
2725 source.forEach(function (value) {
2726 res_3.push(toJSHelper(value, options, __alreadySeen));
2727 });
2728 return res_3;
2729 }
2730 }
2731 if (isObservableMap(source) || Object.getPrototypeOf(source) === Map.prototype) {
2732 if (options.exportMapsAsObjects === false) {
2733 var res_4 = cache(__alreadySeen, source, new Map(), options);
2734 source.forEach(function (value, key) {
2735 res_4.set(key, toJSHelper(value, options, __alreadySeen));
2736 });
2737 return res_4;
2738 }
2739 else {
2740 var res_5 = cache(__alreadySeen, source, {}, options);
2741 source.forEach(function (value, key) {
2742 res_5[key] = toJSHelper(value, options, __alreadySeen);
2743 });
2744 return res_5;
2745 }
2746 }
2747 // Fallback to the situation that source is an ObservableObject or a plain object
2748 var res = cache(__alreadySeen, source, {}, options);
2749 for (var key in source) {
2750 res[key] = toJSHelper(source[key], options, __alreadySeen);
2751 }
2752 return res;
2753}
2754function toJS(source, options) {
2755 // backward compatibility
2756 if (typeof options === "boolean")
2757 options = { detectCycles: options };
2758 if (!options)
2759 options = defaultOptions;
2760 options.detectCycles =
2761 options.detectCycles === undefined
2762 ? options.recurseEverything === true
2763 : options.detectCycles === true;
2764 var __alreadySeen;
2765 if (options.detectCycles)
2766 __alreadySeen = new Map();
2767 return toJSHelper(source, options, __alreadySeen);
2768}
2769
2770function trace() {
2771 var args = [];
2772 for (var _i = 0; _i < arguments.length; _i++) {
2773 args[_i] = arguments[_i];
2774 }
2775 var enterBreakPoint = false;
2776 if (typeof args[args.length - 1] === "boolean")
2777 enterBreakPoint = args.pop();
2778 var derivation = getAtomFromArgs(args);
2779 if (!derivation) {
2780 return fail("'trace(break?)' can only be used inside a tracked computed value or a Reaction. Consider passing in the computed value or reaction explicitly");
2781 }
2782 if (derivation.isTracing === TraceMode.NONE) {
2783 console.log("[mobx.trace] '" + derivation.name + "' tracing enabled");
2784 }
2785 derivation.isTracing = enterBreakPoint ? TraceMode.BREAK : TraceMode.LOG;
2786}
2787function getAtomFromArgs(args) {
2788 switch (args.length) {
2789 case 0:
2790 return globalState.trackingDerivation;
2791 case 1:
2792 return getAtom(args[0]);
2793 case 2:
2794 return getAtom(args[0], args[1]);
2795 }
2796}
2797
2798/**
2799 * During a transaction no views are updated until the end of the transaction.
2800 * The transaction will be run synchronously nonetheless.
2801 *
2802 * @param action a function that updates some reactive state
2803 * @returns any value that was returned by the 'action' parameter.
2804 */
2805function transaction(action, thisArg) {
2806 if (thisArg === void 0) { thisArg = undefined; }
2807 startBatch();
2808 try {
2809 return action.apply(thisArg);
2810 }
2811 finally {
2812 endBatch();
2813 }
2814}
2815
2816function when(predicate, arg1, arg2) {
2817 if (arguments.length === 1 || (arg1 && typeof arg1 === "object"))
2818 return whenPromise(predicate, arg1);
2819 return _when(predicate, arg1, arg2 || {});
2820}
2821function _when(predicate, effect, opts) {
2822 var timeoutHandle;
2823 if (typeof opts.timeout === "number") {
2824 timeoutHandle = setTimeout(function () {
2825 if (!disposer.$mobx.isDisposed) {
2826 disposer();
2827 var error = new Error("WHEN_TIMEOUT");
2828 if (opts.onError)
2829 opts.onError(error);
2830 else
2831 throw error;
2832 }
2833 }, opts.timeout);
2834 }
2835 opts.name = opts.name || "When@" + getNextId();
2836 var effectAction = createAction(opts.name + "-effect", effect);
2837 var disposer = autorun(function (r) {
2838 if (predicate()) {
2839 r.dispose();
2840 if (timeoutHandle)
2841 clearTimeout(timeoutHandle);
2842 effectAction();
2843 }
2844 }, opts);
2845 return disposer;
2846}
2847function whenPromise(predicate, opts) {
2848 if (opts && opts.onError)
2849 return fail("the options 'onError' and 'promise' cannot be combined");
2850 var cancel;
2851 var res = new Promise(function (resolve, reject) {
2852 var disposer = _when(predicate, resolve, __assign(__assign({}, opts), { onError: reject }));
2853 cancel = function () {
2854 disposer();
2855 reject("WHEN_CANCELLED");
2856 };
2857 });
2858 res.cancel = cancel;
2859 return res;
2860}
2861
2862function hasInterceptors(interceptable) {
2863 return interceptable.interceptors !== undefined && interceptable.interceptors.length > 0;
2864}
2865function registerInterceptor(interceptable, handler) {
2866 var interceptors = interceptable.interceptors || (interceptable.interceptors = []);
2867 interceptors.push(handler);
2868 return once(function () {
2869 var idx = interceptors.indexOf(handler);
2870 if (idx !== -1)
2871 interceptors.splice(idx, 1);
2872 });
2873}
2874function interceptChange(interceptable, change) {
2875 var prevU = untrackedStart();
2876 try {
2877 var interceptors = interceptable.interceptors;
2878 if (interceptors)
2879 for (var i = 0, l = interceptors.length; i < l; i++) {
2880 change = interceptors[i](change);
2881 invariant(!change || change.type, "Intercept handlers should return nothing or a change object");
2882 if (!change)
2883 break;
2884 }
2885 return change;
2886 }
2887 finally {
2888 untrackedEnd(prevU);
2889 }
2890}
2891
2892function hasListeners(listenable) {
2893 return listenable.changeListeners !== undefined && listenable.changeListeners.length > 0;
2894}
2895function registerListener(listenable, handler) {
2896 var listeners = listenable.changeListeners || (listenable.changeListeners = []);
2897 listeners.push(handler);
2898 return once(function () {
2899 var idx = listeners.indexOf(handler);
2900 if (idx !== -1)
2901 listeners.splice(idx, 1);
2902 });
2903}
2904function notifyListeners(listenable, change) {
2905 var prevU = untrackedStart();
2906 var listeners = listenable.changeListeners;
2907 if (!listeners)
2908 return;
2909 listeners = listeners.slice();
2910 for (var i = 0, l = listeners.length; i < l; i++) {
2911 listeners[i](change);
2912 }
2913 untrackedEnd(prevU);
2914}
2915
2916var MAX_SPLICE_SIZE = 10000; // See e.g. https://github.com/mobxjs/mobx/issues/859
2917// Detects bug in safari 9.1.1 (or iOS 9 safari mobile). See #364
2918var safariPrototypeSetterInheritanceBug = (function () {
2919 var v = false;
2920 var p = {};
2921 Object.defineProperty(p, "0", {
2922 set: function () {
2923 v = true;
2924 }
2925 });
2926 Object.create(p)["0"] = 1;
2927 return v === false;
2928})();
2929/**
2930 * This array buffer contains two lists of properties, so that all arrays
2931 * can recycle their property definitions, which significantly improves performance of creating
2932 * properties on the fly.
2933 */
2934var OBSERVABLE_ARRAY_BUFFER_SIZE = 0;
2935// Typescript workaround to make sure ObservableArray extends Array
2936var StubArray = /** @class */ (function () {
2937 function StubArray() {
2938 }
2939 return StubArray;
2940}());
2941function inherit(ctor, proto) {
2942 if (typeof Object["setPrototypeOf"] !== "undefined") {
2943 Object["setPrototypeOf"](ctor.prototype, proto);
2944 }
2945 else if (typeof ctor.prototype.__proto__ !== "undefined") {
2946 ctor.prototype.__proto__ = proto;
2947 }
2948 else {
2949 ctor["prototype"] = proto;
2950 }
2951}
2952inherit(StubArray, Array.prototype);
2953// Weex freeze Array.prototype
2954// Make them writeable and configurable in prototype chain
2955// https://github.com/alibaba/weex/pull/1529
2956if (Object.isFrozen(Array)) {
2957 [
2958 "constructor",
2959 "push",
2960 "shift",
2961 "concat",
2962 "pop",
2963 "unshift",
2964 "replace",
2965 "find",
2966 "findIndex",
2967 "splice",
2968 "reverse",
2969 "sort"
2970 ].forEach(function (key) {
2971 Object.defineProperty(StubArray.prototype, key, {
2972 configurable: true,
2973 writable: true,
2974 value: Array.prototype[key]
2975 });
2976 });
2977}
2978var ObservableArrayAdministration = /** @class */ (function () {
2979 function ObservableArrayAdministration(name, enhancer, array, owned) {
2980 this.array = array;
2981 this.owned = owned;
2982 this.values = [];
2983 this.lastKnownLength = 0;
2984 this.atom = new Atom(name || "ObservableArray@" + getNextId());
2985 this.enhancer = function (newV, oldV) { return enhancer(newV, oldV, name + "[..]"); };
2986 }
2987 ObservableArrayAdministration.prototype.dehanceValue = function (value) {
2988 if (this.dehancer !== undefined)
2989 return this.dehancer(value);
2990 return value;
2991 };
2992 ObservableArrayAdministration.prototype.dehanceValues = function (values) {
2993 if (this.dehancer !== undefined && values.length > 0)
2994 return values.map(this.dehancer);
2995 return values;
2996 };
2997 ObservableArrayAdministration.prototype.intercept = function (handler) {
2998 return registerInterceptor(this, handler);
2999 };
3000 ObservableArrayAdministration.prototype.observe = function (listener, fireImmediately) {
3001 if (fireImmediately === void 0) { fireImmediately = false; }
3002 if (fireImmediately) {
3003 listener({
3004 object: this.array,
3005 type: "splice",
3006 index: 0,
3007 added: this.values.slice(),
3008 addedCount: this.values.length,
3009 removed: [],
3010 removedCount: 0
3011 });
3012 }
3013 return registerListener(this, listener);
3014 };
3015 ObservableArrayAdministration.prototype.getArrayLength = function () {
3016 this.atom.reportObserved();
3017 return this.values.length;
3018 };
3019 ObservableArrayAdministration.prototype.setArrayLength = function (newLength) {
3020 if (typeof newLength !== "number" || newLength < 0)
3021 throw new Error("[mobx.array] Out of range: " + newLength);
3022 var currentLength = this.values.length;
3023 if (newLength === currentLength)
3024 return;
3025 else if (newLength > currentLength) {
3026 var newItems = new Array(newLength - currentLength);
3027 for (var i = 0; i < newLength - currentLength; i++)
3028 newItems[i] = undefined; // No Array.fill everywhere...
3029 this.spliceWithArray(currentLength, 0, newItems);
3030 }
3031 else
3032 this.spliceWithArray(newLength, currentLength - newLength);
3033 };
3034 // adds / removes the necessary numeric properties to this object
3035 ObservableArrayAdministration.prototype.updateArrayLength = function (oldLength, delta) {
3036 if (oldLength !== this.lastKnownLength)
3037 throw new Error("[mobx] Modification exception: the internal structure of an observable array was changed. Did you use peek() to change it?");
3038 this.lastKnownLength += delta;
3039 if (delta > 0 && oldLength + delta + 1 > OBSERVABLE_ARRAY_BUFFER_SIZE)
3040 reserveArrayBuffer(oldLength + delta + 1);
3041 };
3042 ObservableArrayAdministration.prototype.spliceWithArray = function (index, deleteCount, newItems) {
3043 var _this = this;
3044 checkIfStateModificationsAreAllowed(this.atom);
3045 var length = this.values.length;
3046 if (index === undefined)
3047 index = 0;
3048 else if (index > length)
3049 index = length;
3050 else if (index < 0)
3051 index = Math.max(0, length + index);
3052 if (arguments.length === 1)
3053 deleteCount = length - index;
3054 else if (deleteCount === undefined || deleteCount === null)
3055 deleteCount = 0;
3056 else
3057 deleteCount = Math.max(0, Math.min(deleteCount, length - index));
3058 if (newItems === undefined)
3059 newItems = EMPTY_ARRAY;
3060 if (hasInterceptors(this)) {
3061 var change = interceptChange(this, {
3062 object: this.array,
3063 type: "splice",
3064 index: index,
3065 removedCount: deleteCount,
3066 added: newItems
3067 });
3068 if (!change)
3069 return EMPTY_ARRAY;
3070 deleteCount = change.removedCount;
3071 newItems = change.added;
3072 }
3073 newItems =
3074 newItems.length === 0 ? newItems : newItems.map(function (v) { return _this.enhancer(v, undefined); });
3075 var lengthDelta = newItems.length - deleteCount;
3076 this.updateArrayLength(length, lengthDelta); // create or remove new entries
3077 var res = this.spliceItemsIntoValues(index, deleteCount, newItems);
3078 if (deleteCount !== 0 || newItems.length !== 0)
3079 this.notifyArraySplice(index, newItems, res);
3080 return this.dehanceValues(res);
3081 };
3082 ObservableArrayAdministration.prototype.spliceItemsIntoValues = function (index, deleteCount, newItems) {
3083 var _a;
3084 if (newItems.length < MAX_SPLICE_SIZE) {
3085 return (_a = this.values).splice.apply(_a, __spread([index, deleteCount], newItems));
3086 }
3087 else {
3088 var res = this.values.slice(index, index + deleteCount);
3089 this.values = this.values
3090 .slice(0, index)
3091 .concat(newItems, this.values.slice(index + deleteCount));
3092 return res;
3093 }
3094 };
3095 ObservableArrayAdministration.prototype.notifyArrayChildUpdate = function (index, newValue, oldValue) {
3096 var notifySpy = !this.owned && isSpyEnabled();
3097 var notify = hasListeners(this);
3098 var change = notify || notifySpy
3099 ? {
3100 object: this.array,
3101 type: "update",
3102 index: index,
3103 newValue: newValue,
3104 oldValue: oldValue
3105 }
3106 : null;
3107 if (notifySpy)
3108 spyReportStart(__assign(__assign({}, change), { name: this.atom.name }));
3109 this.atom.reportChanged();
3110 if (notify)
3111 notifyListeners(this, change);
3112 if (notifySpy)
3113 spyReportEnd();
3114 };
3115 ObservableArrayAdministration.prototype.notifyArraySplice = function (index, added, removed) {
3116 var notifySpy = !this.owned && isSpyEnabled();
3117 var notify = hasListeners(this);
3118 var change = notify || notifySpy
3119 ? {
3120 object: this.array,
3121 type: "splice",
3122 index: index,
3123 removed: removed,
3124 added: added,
3125 removedCount: removed.length,
3126 addedCount: added.length
3127 }
3128 : null;
3129 if (notifySpy)
3130 spyReportStart(__assign(__assign({}, change), { name: this.atom.name }));
3131 this.atom.reportChanged();
3132 // conform: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/observe
3133 if (notify)
3134 notifyListeners(this, change);
3135 if (notifySpy)
3136 spyReportEnd();
3137 };
3138 return ObservableArrayAdministration;
3139}());
3140var ObservableArray = /** @class */ (function (_super) {
3141 __extends(ObservableArray, _super);
3142 function ObservableArray(initialValues, enhancer, name, owned) {
3143 if (name === void 0) { name = "ObservableArray@" + getNextId(); }
3144 if (owned === void 0) { owned = false; }
3145 var _this = _super.call(this) || this;
3146 var adm = new ObservableArrayAdministration(name, enhancer, _this, owned);
3147 addHiddenFinalProp(_this, "$mobx", adm);
3148 if (initialValues && initialValues.length) {
3149 var prev = allowStateChangesStart(true);
3150 _this.spliceWithArray(0, 0, initialValues);
3151 allowStateChangesEnd(prev);
3152 }
3153 if (safariPrototypeSetterInheritanceBug) {
3154 // Seems that Safari won't use numeric prototype setter untill any * numeric property is
3155 // defined on the instance. After that it works fine, even if this property is deleted.
3156 Object.defineProperty(adm.array, "0", ENTRY_0);
3157 }
3158 return _this;
3159 }
3160 ObservableArray.prototype.intercept = function (handler) {
3161 return this.$mobx.intercept(handler);
3162 };
3163 ObservableArray.prototype.observe = function (listener, fireImmediately) {
3164 if (fireImmediately === void 0) { fireImmediately = false; }
3165 return this.$mobx.observe(listener, fireImmediately);
3166 };
3167 ObservableArray.prototype.clear = function () {
3168 return this.splice(0);
3169 };
3170 ObservableArray.prototype.concat = function () {
3171 var arrays = [];
3172 for (var _i = 0; _i < arguments.length; _i++) {
3173 arrays[_i] = arguments[_i];
3174 }
3175 this.$mobx.atom.reportObserved();
3176 return Array.prototype.concat.apply(this.peek(), arrays.map(function (a) { return (isObservableArray(a) ? a.peek() : a); }));
3177 };
3178 ObservableArray.prototype.replace = function (newItems) {
3179 return this.$mobx.spliceWithArray(0, this.$mobx.values.length, newItems);
3180 };
3181 /**
3182 * Converts this array back to a (shallow) javascript structure.
3183 * For a deep clone use mobx.toJS
3184 */
3185 ObservableArray.prototype.toJS = function () {
3186 return this.slice();
3187 };
3188 ObservableArray.prototype.toJSON = function () {
3189 // Used by JSON.stringify
3190 return this.toJS();
3191 };
3192 ObservableArray.prototype.peek = function () {
3193 this.$mobx.atom.reportObserved();
3194 return this.$mobx.dehanceValues(this.$mobx.values);
3195 };
3196 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
3197 ObservableArray.prototype.find = function (predicate, thisArg, fromIndex) {
3198 if (fromIndex === void 0) { fromIndex = 0; }
3199 if (arguments.length === 3)
3200 deprecated("The array.find fromIndex argument to find will not be supported anymore in the next major");
3201 var idx = this.findIndex.apply(this, arguments);
3202 return idx === -1 ? undefined : this.get(idx);
3203 };
3204 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
3205 ObservableArray.prototype.findIndex = function (predicate, thisArg, fromIndex) {
3206 if (fromIndex === void 0) { fromIndex = 0; }
3207 if (arguments.length === 3)
3208 deprecated("The array.findIndex fromIndex argument to find will not be supported anymore in the next major");
3209 var items = this.peek(), l = items.length;
3210 for (var i = fromIndex; i < l; i++)
3211 if (predicate.call(thisArg, items[i], i, this))
3212 return i;
3213 return -1;
3214 };
3215 /*
3216 * functions that do alter the internal structure of the array, (based on lib.es6.d.ts)
3217 * since these functions alter the inner structure of the array, the have side effects.
3218 * Because the have side effects, they should not be used in computed function,
3219 * and for that reason the do not call dependencyState.notifyObserved
3220 */
3221 ObservableArray.prototype.splice = function (index, deleteCount) {
3222 var newItems = [];
3223 for (var _i = 2; _i < arguments.length; _i++) {
3224 newItems[_i - 2] = arguments[_i];
3225 }
3226 switch (arguments.length) {
3227 case 0:
3228 return [];
3229 case 1:
3230 return this.$mobx.spliceWithArray(index);
3231 case 2:
3232 return this.$mobx.spliceWithArray(index, deleteCount);
3233 }
3234 return this.$mobx.spliceWithArray(index, deleteCount, newItems);
3235 };
3236 ObservableArray.prototype.spliceWithArray = function (index, deleteCount, newItems) {
3237 return this.$mobx.spliceWithArray(index, deleteCount, newItems);
3238 };
3239 ObservableArray.prototype.push = function () {
3240 var items = [];
3241 for (var _i = 0; _i < arguments.length; _i++) {
3242 items[_i] = arguments[_i];
3243 }
3244 var adm = this.$mobx;
3245 adm.spliceWithArray(adm.values.length, 0, items);
3246 return adm.values.length;
3247 };
3248 ObservableArray.prototype.pop = function () {
3249 return this.splice(Math.max(this.$mobx.values.length - 1, 0), 1)[0];
3250 };
3251 ObservableArray.prototype.shift = function () {
3252 return this.splice(0, 1)[0];
3253 };
3254 ObservableArray.prototype.unshift = function () {
3255 var items = [];
3256 for (var _i = 0; _i < arguments.length; _i++) {
3257 items[_i] = arguments[_i];
3258 }
3259 var adm = this.$mobx;
3260 adm.spliceWithArray(0, 0, items);
3261 return adm.values.length;
3262 };
3263 ObservableArray.prototype.reverse = function () {
3264 // reverse by default mutates in place before returning the result
3265 // which makes it both a 'derivation' and a 'mutation'.
3266 // so we deviate from the default and just make it an dervitation
3267 var clone = this.slice();
3268 return clone.reverse.apply(clone, arguments);
3269 };
3270 ObservableArray.prototype.sort = function (compareFn) {
3271 // sort by default mutates in place before returning the result
3272 // which goes against all good practices. Let's not change the array in place!
3273 var clone = this.slice();
3274 return clone.sort.apply(clone, arguments);
3275 };
3276 ObservableArray.prototype.remove = function (value) {
3277 var idx = this.$mobx.dehanceValues(this.$mobx.values).indexOf(value);
3278 if (idx > -1) {
3279 this.splice(idx, 1);
3280 return true;
3281 }
3282 return false;
3283 };
3284 ObservableArray.prototype.move = function (fromIndex, toIndex) {
3285 deprecated("observableArray.move is deprecated, use .slice() & .replace() instead");
3286 function checkIndex(index) {
3287 if (index < 0) {
3288 throw new Error("[mobx.array] Index out of bounds: " + index + " is negative");
3289 }
3290 var length = this.$mobx.values.length;
3291 if (index >= length) {
3292 throw new Error("[mobx.array] Index out of bounds: " + index + " is not smaller than " + length);
3293 }
3294 }
3295 checkIndex.call(this, fromIndex);
3296 checkIndex.call(this, toIndex);
3297 if (fromIndex === toIndex) {
3298 return;
3299 }
3300 var oldItems = this.$mobx.values;
3301 var newItems;
3302 if (fromIndex < toIndex) {
3303 newItems = __spread(oldItems.slice(0, fromIndex), oldItems.slice(fromIndex + 1, toIndex + 1), [
3304 oldItems[fromIndex]
3305 ], oldItems.slice(toIndex + 1));
3306 }
3307 else {
3308 // toIndex < fromIndex
3309 newItems = __spread(oldItems.slice(0, toIndex), [
3310 oldItems[fromIndex]
3311 ], oldItems.slice(toIndex, fromIndex), oldItems.slice(fromIndex + 1));
3312 }
3313 this.replace(newItems);
3314 };
3315 // See #734, in case property accessors are unreliable...
3316 ObservableArray.prototype.get = function (index) {
3317 var impl = this.$mobx;
3318 if (impl) {
3319 if (index < impl.values.length) {
3320 impl.atom.reportObserved();
3321 return impl.dehanceValue(impl.values[index]);
3322 }
3323 console.warn("[mobx.array] Attempt to read an array index (" + index + ") that is out of bounds (" + impl.values.length + "). Please check length first. Out of bound indices will not be tracked by MobX");
3324 }
3325 return undefined;
3326 };
3327 // See #734, in case property accessors are unreliable...
3328 ObservableArray.prototype.set = function (index, newValue) {
3329 var adm = this.$mobx;
3330 var values = adm.values;
3331 if (index < values.length) {
3332 // update at index in range
3333 checkIfStateModificationsAreAllowed(adm.atom);
3334 var oldValue = values[index];
3335 if (hasInterceptors(adm)) {
3336 var change = interceptChange(adm, {
3337 type: "update",
3338 object: this,
3339 index: index,
3340 newValue: newValue
3341 });
3342 if (!change)
3343 return;
3344 newValue = change.newValue;
3345 }
3346 newValue = adm.enhancer(newValue, oldValue);
3347 var changed = newValue !== oldValue;
3348 if (changed) {
3349 values[index] = newValue;
3350 adm.notifyArrayChildUpdate(index, newValue, oldValue);
3351 }
3352 }
3353 else if (index === values.length) {
3354 // add a new item
3355 adm.spliceWithArray(index, 0, [newValue]);
3356 }
3357 else {
3358 // out of bounds
3359 throw new Error("[mobx.array] Index out of bounds, " + index + " is larger than " + values.length);
3360 }
3361 };
3362 return ObservableArray;
3363}(StubArray));
3364declareIterator(ObservableArray.prototype, function () {
3365 this.$mobx.atom.reportObserved();
3366 var self = this;
3367 var nextIndex = 0;
3368 return makeIterable({
3369 next: function () {
3370 return nextIndex < self.length
3371 ? { value: self[nextIndex++], done: false }
3372 : { done: true, value: undefined };
3373 }
3374 });
3375});
3376Object.defineProperty(ObservableArray.prototype, "length", {
3377 enumerable: false,
3378 configurable: true,
3379 get: function () {
3380 return this.$mobx.getArrayLength();
3381 },
3382 set: function (newLength) {
3383 this.$mobx.setArrayLength(newLength);
3384 }
3385});
3386addHiddenProp(ObservableArray.prototype, toStringTagSymbol(), "Array");
3387[
3388 "every",
3389 "filter",
3390 "forEach",
3391 "indexOf",
3392 "join",
3393 "lastIndexOf",
3394 "map",
3395 "reduce",
3396 "reduceRight",
3397 "slice",
3398 "some",
3399 "toString",
3400 "toLocaleString"
3401].forEach(function (funcName) {
3402 var baseFunc = Array.prototype[funcName];
3403 invariant(typeof baseFunc === "function", "Base function not defined on Array prototype: '" + funcName + "'");
3404 addHiddenProp(ObservableArray.prototype, funcName, function () {
3405 return baseFunc.apply(this.peek(), arguments);
3406 });
3407});
3408/**
3409 * We don't want those to show up in `for (const key in ar)` ...
3410 */
3411makeNonEnumerable(ObservableArray.prototype, [
3412 "constructor",
3413 "intercept",
3414 "observe",
3415 "clear",
3416 "concat",
3417 "get",
3418 "replace",
3419 "toJS",
3420 "toJSON",
3421 "peek",
3422 "find",
3423 "findIndex",
3424 "splice",
3425 "spliceWithArray",
3426 "push",
3427 "pop",
3428 "set",
3429 "shift",
3430 "unshift",
3431 "reverse",
3432 "sort",
3433 "remove",
3434 "move",
3435 "toString",
3436 "toLocaleString"
3437]);
3438// See #364
3439var ENTRY_0 = createArrayEntryDescriptor(0);
3440function createArrayEntryDescriptor(index) {
3441 return {
3442 enumerable: false,
3443 configurable: false,
3444 get: function () {
3445 return this.get(index);
3446 },
3447 set: function (value) {
3448 this.set(index, value);
3449 }
3450 };
3451}
3452function createArrayBufferItem(index) {
3453 Object.defineProperty(ObservableArray.prototype, "" + index, createArrayEntryDescriptor(index));
3454}
3455function reserveArrayBuffer(max) {
3456 for (var index = OBSERVABLE_ARRAY_BUFFER_SIZE; index < max; index++)
3457 createArrayBufferItem(index);
3458 OBSERVABLE_ARRAY_BUFFER_SIZE = max;
3459}
3460reserveArrayBuffer(1000);
3461var isObservableArrayAdministration = createInstanceofPredicate("ObservableArrayAdministration", ObservableArrayAdministration);
3462function isObservableArray(thing) {
3463 return isObject(thing) && isObservableArrayAdministration(thing.$mobx);
3464}
3465
3466var ObservableMapMarker = {};
3467var ObservableMap = /** @class */ (function () {
3468 function ObservableMap(initialData, enhancer, name) {
3469 if (enhancer === void 0) { enhancer = deepEnhancer; }
3470 if (name === void 0) { name = "ObservableMap@" + getNextId(); }
3471 this.enhancer = enhancer;
3472 this.name = name;
3473 this.$mobx = ObservableMapMarker;
3474 this._keys = (new ObservableArray(undefined, referenceEnhancer, this.name + ".keys()", true));
3475 if (typeof Map !== "function") {
3476 throw new Error("mobx.map requires Map polyfill for the current browser. Check babel-polyfill or core-js/es6/map.js");
3477 }
3478 this._data = new Map();
3479 this._hasMap = new Map();
3480 this.merge(initialData);
3481 }
3482 ObservableMap.prototype._has = function (key) {
3483 return this._data.has(key);
3484 };
3485 ObservableMap.prototype.has = function (key) {
3486 var _this = this;
3487 if (!globalState.trackingDerivation)
3488 return this._has(key);
3489 var entry = this._hasMap.get(key);
3490 if (!entry) {
3491 // todo: replace with atom (breaking change)
3492 var newEntry = (entry = new ObservableValue(this._has(key), referenceEnhancer, this.name + "." + stringifyKey(key) + "?", false));
3493 this._hasMap.set(key, newEntry);
3494 onBecomeUnobserved(newEntry, function () { return _this._hasMap.delete(key); });
3495 }
3496 return entry.get();
3497 };
3498 ObservableMap.prototype.set = function (key, value) {
3499 var hasKey = this._has(key);
3500 if (hasInterceptors(this)) {
3501 var change = interceptChange(this, {
3502 type: hasKey ? "update" : "add",
3503 object: this,
3504 newValue: value,
3505 name: key
3506 });
3507 if (!change)
3508 return this;
3509 value = change.newValue;
3510 }
3511 if (hasKey) {
3512 this._updateValue(key, value);
3513 }
3514 else {
3515 this._addValue(key, value);
3516 }
3517 return this;
3518 };
3519 ObservableMap.prototype.delete = function (key) {
3520 var _this = this;
3521 if (hasInterceptors(this)) {
3522 var change = interceptChange(this, {
3523 type: "delete",
3524 object: this,
3525 name: key
3526 });
3527 if (!change)
3528 return false;
3529 }
3530 if (this._has(key)) {
3531 var notifySpy = isSpyEnabled();
3532 var notify = hasListeners(this);
3533 var change = notify || notifySpy
3534 ? {
3535 type: "delete",
3536 object: this,
3537 oldValue: this._data.get(key).value,
3538 name: key
3539 }
3540 : null;
3541 if (notifySpy)
3542 spyReportStart(__assign(__assign({}, change), { name: this.name, key: key }));
3543 transaction(function () {
3544 _this._keys.remove(key);
3545 _this._updateHasMapEntry(key, false);
3546 var observable = _this._data.get(key);
3547 observable.setNewValue(undefined);
3548 _this._data.delete(key);
3549 });
3550 if (notify)
3551 notifyListeners(this, change);
3552 if (notifySpy)
3553 spyReportEnd();
3554 return true;
3555 }
3556 return false;
3557 };
3558 ObservableMap.prototype._updateHasMapEntry = function (key, value) {
3559 var entry = this._hasMap.get(key);
3560 if (entry) {
3561 entry.setNewValue(value);
3562 }
3563 };
3564 ObservableMap.prototype._updateValue = function (key, newValue) {
3565 var observable = this._data.get(key);
3566 newValue = observable.prepareNewValue(newValue);
3567 if (newValue !== globalState.UNCHANGED) {
3568 var notifySpy = isSpyEnabled();
3569 var notify = hasListeners(this);
3570 var change = notify || notifySpy
3571 ? {
3572 type: "update",
3573 object: this,
3574 oldValue: observable.value,
3575 name: key,
3576 newValue: newValue
3577 }
3578 : null;
3579 if (notifySpy)
3580 spyReportStart(__assign(__assign({}, change), { name: this.name, key: key }));
3581 observable.setNewValue(newValue);
3582 if (notify)
3583 notifyListeners(this, change);
3584 if (notifySpy)
3585 spyReportEnd();
3586 }
3587 };
3588 ObservableMap.prototype._addValue = function (key, newValue) {
3589 var _this = this;
3590 transaction(function () {
3591 var observable = new ObservableValue(newValue, _this.enhancer, _this.name + "." + stringifyKey(key), false);
3592 _this._data.set(key, observable);
3593 newValue = observable.value; // value might have been changed
3594 _this._updateHasMapEntry(key, true);
3595 _this._keys.push(key);
3596 });
3597 var notifySpy = isSpyEnabled();
3598 var notify = hasListeners(this);
3599 var change = notify || notifySpy
3600 ? {
3601 type: "add",
3602 object: this,
3603 name: key,
3604 newValue: newValue
3605 }
3606 : null;
3607 if (notifySpy)
3608 spyReportStart(__assign(__assign({}, change), { name: this.name, key: key }));
3609 if (notify)
3610 notifyListeners(this, change);
3611 if (notifySpy)
3612 spyReportEnd();
3613 };
3614 ObservableMap.prototype.get = function (key) {
3615 if (this.has(key))
3616 return this.dehanceValue(this._data.get(key).get());
3617 return this.dehanceValue(undefined);
3618 };
3619 ObservableMap.prototype.dehanceValue = function (value) {
3620 if (this.dehancer !== undefined) {
3621 return this.dehancer(value);
3622 }
3623 return value;
3624 };
3625 ObservableMap.prototype.keys = function () {
3626 return this._keys[iteratorSymbol()]();
3627 };
3628 ObservableMap.prototype.values = function () {
3629 var self = this;
3630 var nextIndex = 0;
3631 return makeIterable({
3632 next: function () {
3633 return nextIndex < self._keys.length
3634 ? { value: self.get(self._keys[nextIndex++]), done: false }
3635 : { value: undefined, done: true };
3636 }
3637 });
3638 };
3639 ObservableMap.prototype.entries = function () {
3640 var self = this;
3641 var nextIndex = 0;
3642 return makeIterable({
3643 next: function () {
3644 if (nextIndex < self._keys.length) {
3645 var key = self._keys[nextIndex++];
3646 return {
3647 value: [key, self.get(key)],
3648 done: false
3649 };
3650 }
3651 return { done: true };
3652 }
3653 });
3654 };
3655 ObservableMap.prototype.forEach = function (callback, thisArg) {
3656 var _this = this;
3657 this._keys.forEach(function (key) { return callback.call(thisArg, _this.get(key), key, _this); });
3658 };
3659 /** Merge another object into this object, returns this. */
3660 ObservableMap.prototype.merge = function (other) {
3661 var _this = this;
3662 if (isObservableMap(other)) {
3663 other = other.toJS();
3664 }
3665 transaction(function () {
3666 if (isPlainObject(other))
3667 Object.keys(other).forEach(function (key) { return _this.set(key, other[key]); });
3668 else if (Array.isArray(other))
3669 other.forEach(function (_a) {
3670 var _b = __read(_a, 2), key = _b[0], value = _b[1];
3671 return _this.set(key, value);
3672 });
3673 else if (isES6Map(other)) {
3674 if (other.constructor !== Map)
3675 fail("Cannot initialize from classes that inherit from Map: " + other.constructor.name); // prettier-ignore
3676 else
3677 other.forEach(function (value, key) { return _this.set(key, value); });
3678 }
3679 else if (other !== null && other !== undefined)
3680 fail("Cannot initialize map from " + other);
3681 });
3682 return this;
3683 };
3684 ObservableMap.prototype.clear = function () {
3685 var _this = this;
3686 transaction(function () {
3687 untracked(function () {
3688 _this._keys.slice().forEach(function (key) { return _this.delete(key); });
3689 });
3690 });
3691 };
3692 ObservableMap.prototype.replace = function (values) {
3693 var _this = this;
3694 transaction(function () {
3695 var replacementMap = convertToMap(values);
3696 var oldKeys = _this._keys;
3697 var newKeys = Array.from(replacementMap.keys());
3698 var keysChanged = false;
3699 for (var i = 0; i < oldKeys.length; i++) {
3700 var oldKey = oldKeys[i];
3701 // key order change
3702 if (oldKeys.length === newKeys.length && oldKey !== newKeys[i]) {
3703 keysChanged = true;
3704 }
3705 // deleted key
3706 if (!replacementMap.has(oldKey)) {
3707 keysChanged = true;
3708 _this.delete(oldKey);
3709 }
3710 }
3711 replacementMap.forEach(function (value, key) {
3712 // new key
3713 if (!_this._data.has(key)) {
3714 keysChanged = true;
3715 }
3716 _this.set(key, value);
3717 });
3718 if (keysChanged) {
3719 _this._keys.replace(newKeys);
3720 }
3721 });
3722 return this;
3723 };
3724 Object.defineProperty(ObservableMap.prototype, "size", {
3725 get: function () {
3726 return this._keys.length;
3727 },
3728 enumerable: true,
3729 configurable: true
3730 });
3731 /**
3732 * Returns a plain object that represents this map.
3733 * Note that all the keys being stringified.
3734 * If there are duplicating keys after converting them to strings, behaviour is undetermined.
3735 */
3736 ObservableMap.prototype.toPOJO = function () {
3737 var _this = this;
3738 var res = {};
3739 this._keys.forEach(function (key) { return (res[typeof key === "symbol" ? key : stringifyKey(key)] = _this.get(key)); });
3740 return res;
3741 };
3742 /**
3743 * Returns a shallow non observable object clone of this map.
3744 * Note that the values migth still be observable. For a deep clone use mobx.toJS.
3745 */
3746 ObservableMap.prototype.toJS = function () {
3747 var _this = this;
3748 var res = new Map();
3749 this._keys.forEach(function (key) { return res.set(key, _this.get(key)); });
3750 return res;
3751 };
3752 ObservableMap.prototype.toJSON = function () {
3753 // Used by JSON.stringify
3754 return this.toPOJO();
3755 };
3756 ObservableMap.prototype.toString = function () {
3757 var _this = this;
3758 return (this.name +
3759 "[{ " +
3760 this._keys.map(function (key) { return stringifyKey(key) + ": " + ("" + _this.get(key)); }).join(", ") +
3761 " }]");
3762 };
3763 /**
3764 * Observes this object. Triggers for the events 'add', 'update' and 'delete'.
3765 * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe
3766 * for callback details
3767 */
3768 ObservableMap.prototype.observe = function (listener, fireImmediately) {
3769 invariant(fireImmediately !== true, "`observe` doesn't support fireImmediately=true in combination with maps.");
3770 return registerListener(this, listener);
3771 };
3772 ObservableMap.prototype.intercept = function (handler) {
3773 return registerInterceptor(this, handler);
3774 };
3775 return ObservableMap;
3776}());
3777function stringifyKey(key) {
3778 if (key && key.toString)
3779 return key.toString();
3780 else
3781 return new String(key).toString();
3782}
3783declareIterator(ObservableMap.prototype, function () {
3784 return this.entries();
3785});
3786addHiddenFinalProp(ObservableMap.prototype, toStringTagSymbol(), "Map");
3787/* 'var' fixes small-build issue */
3788var isObservableMap = createInstanceofPredicate("ObservableMap", ObservableMap);
3789
3790var ObservableSetMarker = {};
3791var ObservableSet = /** @class */ (function () {
3792 function ObservableSet(initialData, enhancer, name) {
3793 if (enhancer === void 0) { enhancer = deepEnhancer; }
3794 if (name === void 0) { name = "ObservableSet@" + getNextId(); }
3795 this.name = name;
3796 this.$mobx = ObservableSetMarker;
3797 this._data = new Set();
3798 this._atom = createAtom(this.name);
3799 if (typeof Set !== "function") {
3800 throw new Error("mobx.set requires Set polyfill for the current browser. Check babel-polyfill or core-js/es6/set.js");
3801 }
3802 this.enhancer = function (newV, oldV) { return enhancer(newV, oldV, name); };
3803 if (initialData) {
3804 this.replace(initialData);
3805 }
3806 }
3807 ObservableSet.prototype.dehanceValue = function (value) {
3808 if (this.dehancer !== undefined) {
3809 return this.dehancer(value);
3810 }
3811 return value;
3812 };
3813 ObservableSet.prototype.clear = function () {
3814 var _this = this;
3815 transaction(function () {
3816 untracked(function () {
3817 _this._data.forEach(function (value) {
3818 _this.delete(value);
3819 });
3820 });
3821 });
3822 };
3823 ObservableSet.prototype.forEach = function (callbackFn, thisArg) {
3824 var _this = this;
3825 this._data.forEach(function (value) {
3826 callbackFn.call(thisArg, value, value, _this);
3827 });
3828 };
3829 Object.defineProperty(ObservableSet.prototype, "size", {
3830 get: function () {
3831 this._atom.reportObserved();
3832 return this._data.size;
3833 },
3834 enumerable: true,
3835 configurable: true
3836 });
3837 ObservableSet.prototype.add = function (value) {
3838 var _this = this;
3839 checkIfStateModificationsAreAllowed(this._atom);
3840 if (hasInterceptors(this)) {
3841 var change = interceptChange(this, {
3842 type: "add",
3843 object: this,
3844 newValue: value
3845 });
3846 if (!change)
3847 return this;
3848 // TODO: ideally, value = change.value would be done here, so that values can be
3849 // changed by interceptor. Same applies for other Set and Map api's.
3850 }
3851 if (!this.has(value)) {
3852 transaction(function () {
3853 _this._data.add(_this.enhancer(value, undefined));
3854 _this._atom.reportChanged();
3855 });
3856 var notifySpy = isSpyEnabled();
3857 var notify = hasListeners(this);
3858 var change = notify || notifySpy
3859 ? {
3860 type: "add",
3861 object: this,
3862 newValue: value
3863 }
3864 : null;
3865 if (notifySpy && "development" !== "production")
3866 spyReportStart(change);
3867 if (notify)
3868 notifyListeners(this, change);
3869 if (notifySpy && "development" !== "production")
3870 spyReportEnd();
3871 }
3872 return this;
3873 };
3874 ObservableSet.prototype.delete = function (value) {
3875 var _this = this;
3876 if (hasInterceptors(this)) {
3877 var change = interceptChange(this, {
3878 type: "delete",
3879 object: this,
3880 oldValue: value
3881 });
3882 if (!change)
3883 return false;
3884 }
3885 if (this.has(value)) {
3886 var notifySpy = isSpyEnabled();
3887 var notify = hasListeners(this);
3888 var change = notify || notifySpy
3889 ? {
3890 type: "delete",
3891 object: this,
3892 oldValue: value
3893 }
3894 : null;
3895 if (notifySpy && "development" !== "production")
3896 spyReportStart(__assign(__assign({}, change), { name: this.name }));
3897 transaction(function () {
3898 _this._atom.reportChanged();
3899 _this._data.delete(value);
3900 });
3901 if (notify)
3902 notifyListeners(this, change);
3903 if (notifySpy && "development" !== "production")
3904 spyReportEnd();
3905 return true;
3906 }
3907 return false;
3908 };
3909 ObservableSet.prototype.has = function (value) {
3910 this._atom.reportObserved();
3911 return this._data.has(this.dehanceValue(value));
3912 };
3913 ObservableSet.prototype.entries = function () {
3914 var nextIndex = 0;
3915 var keys = iteratorToArray(this.keys());
3916 var values = iteratorToArray(this.values());
3917 return makeIterable({
3918 next: function () {
3919 var index = nextIndex;
3920 nextIndex += 1;
3921 return index < values.length
3922 ? { value: [keys[index], values[index]], done: false }
3923 : { done: true };
3924 }
3925 });
3926 };
3927 ObservableSet.prototype.keys = function () {
3928 return this.values();
3929 };
3930 ObservableSet.prototype.values = function () {
3931 this._atom.reportObserved();
3932 var self = this;
3933 var nextIndex = 0;
3934 var observableValues;
3935 if (this._data.values !== undefined) {
3936 observableValues = iteratorToArray(this._data.values());
3937 }
3938 else {
3939 // There is no values function in IE11
3940 observableValues = [];
3941 this._data.forEach(function (e) { return observableValues.push(e); });
3942 }
3943 return makeIterable({
3944 next: function () {
3945 return nextIndex < observableValues.length
3946 ? { value: self.dehanceValue(observableValues[nextIndex++]), done: false }
3947 : { done: true };
3948 }
3949 });
3950 };
3951 ObservableSet.prototype.replace = function (other) {
3952 var _this = this;
3953 if (isObservableSet(other)) {
3954 other = other.toJS();
3955 }
3956 transaction(function () {
3957 if (Array.isArray(other)) {
3958 _this.clear();
3959 other.forEach(function (value) { return _this.add(value); });
3960 }
3961 else if (isES6Set(other)) {
3962 _this.clear();
3963 other.forEach(function (value) { return _this.add(value); });
3964 }
3965 else if (other !== null && other !== undefined) {
3966 fail("Cannot initialize set from " + other);
3967 }
3968 });
3969 return this;
3970 };
3971 ObservableSet.prototype.observe = function (listener, fireImmediately) {
3972 // TODO 'fireImmediately' can be true?
3973 invariant(fireImmediately !== true, "`observe` doesn't support fireImmediately=true in combination with sets.");
3974 return registerListener(this, listener);
3975 };
3976 ObservableSet.prototype.intercept = function (handler) {
3977 return registerInterceptor(this, handler);
3978 };
3979 ObservableSet.prototype.toJS = function () {
3980 return new Set(this);
3981 };
3982 ObservableSet.prototype.toString = function () {
3983 return this.name + "[ " + iteratorToArray(this.keys()).join(", ") + " ]";
3984 };
3985 return ObservableSet;
3986}());
3987declareIterator(ObservableSet.prototype, function () {
3988 return this.values();
3989});
3990addHiddenFinalProp(ObservableSet.prototype, toStringTagSymbol(), "Set");
3991var isObservableSet = createInstanceofPredicate("ObservableSet", ObservableSet);
3992
3993var ObservableObjectAdministration = /** @class */ (function () {
3994 function ObservableObjectAdministration(target, name, defaultEnhancer) {
3995 this.target = target;
3996 this.name = name;
3997 this.defaultEnhancer = defaultEnhancer;
3998 this.values = {};
3999 }
4000 ObservableObjectAdministration.prototype.read = function (owner, key) {
4001 return this.values[key].get();
4002 };
4003 ObservableObjectAdministration.prototype.write = function (owner, key, newValue) {
4004 var instance = this.target;
4005 var observable = this.values[key];
4006 if (observable instanceof ComputedValue) {
4007 observable.set(newValue);
4008 return;
4009 }
4010 // intercept
4011 if (hasInterceptors(this)) {
4012 var change = interceptChange(this, {
4013 type: "update",
4014 object: instance,
4015 name: key,
4016 newValue: newValue
4017 });
4018 if (!change)
4019 return;
4020 newValue = change.newValue;
4021 }
4022 newValue = observable.prepareNewValue(newValue);
4023 // notify spy & observers
4024 if (newValue !== globalState.UNCHANGED) {
4025 var notify = hasListeners(this);
4026 var notifySpy = isSpyEnabled();
4027 var change = notify || notifySpy
4028 ? {
4029 type: "update",
4030 object: instance,
4031 oldValue: observable.value,
4032 name: key,
4033 newValue: newValue
4034 }
4035 : null;
4036 if (notifySpy)
4037 spyReportStart(__assign(__assign({}, change), { name: this.name, key: key }));
4038 observable.setNewValue(newValue);
4039 if (notify)
4040 notifyListeners(this, change);
4041 if (notifySpy)
4042 spyReportEnd();
4043 }
4044 };
4045 ObservableObjectAdministration.prototype.remove = function (key) {
4046 if (!this.values[key])
4047 return;
4048 var target = this.target;
4049 if (hasInterceptors(this)) {
4050 var change = interceptChange(this, {
4051 object: target,
4052 name: key,
4053 type: "remove"
4054 });
4055 if (!change)
4056 return;
4057 }
4058 try {
4059 startBatch();
4060 var notify = hasListeners(this);
4061 var notifySpy = isSpyEnabled();
4062 var oldValue = this.values[key].get();
4063 if (this.keys)
4064 this.keys.remove(key);
4065 delete this.values[key];
4066 delete this.target[key];
4067 var change = notify || notifySpy
4068 ? {
4069 type: "remove",
4070 object: target,
4071 oldValue: oldValue,
4072 name: key
4073 }
4074 : null;
4075 if (notifySpy)
4076 spyReportStart(__assign(__assign({}, change), { name: this.name, key: key }));
4077 if (notify)
4078 notifyListeners(this, change);
4079 if (notifySpy)
4080 spyReportEnd();
4081 }
4082 finally {
4083 endBatch();
4084 }
4085 };
4086 ObservableObjectAdministration.prototype.illegalAccess = function (owner, propName) {
4087 /**
4088 * This happens if a property is accessed through the prototype chain, but the property was
4089 * declared directly as own property on the prototype.
4090 *
4091 * E.g.:
4092 * class A {
4093 * }
4094 * extendObservable(A.prototype, { x: 1 })
4095 *
4096 * classB extens A {
4097 * }
4098 * console.log(new B().x)
4099 *
4100 * It is unclear whether the property should be considered 'static' or inherited.
4101 * Either use `console.log(A.x)`
4102 * or: decorate(A, { x: observable })
4103 *
4104 * When using decorate, the property will always be redeclared as own property on the actual instance
4105 */
4106 console.warn("Property '" + propName + "' of '" + owner + "' was accessed through the prototype chain. Use 'decorate' instead to declare the prop or access it statically through it's owner");
4107 };
4108 /**
4109 * Observes this object. Triggers for the events 'add', 'update' and 'delete'.
4110 * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe
4111 * for callback details
4112 */
4113 ObservableObjectAdministration.prototype.observe = function (callback, fireImmediately) {
4114 invariant(fireImmediately !== true, "`observe` doesn't support the fire immediately property for observable objects.");
4115 return registerListener(this, callback);
4116 };
4117 ObservableObjectAdministration.prototype.intercept = function (handler) {
4118 return registerInterceptor(this, handler);
4119 };
4120 ObservableObjectAdministration.prototype.getKeys = function () {
4121 var _this = this;
4122 if (this.keys === undefined) {
4123 this.keys = (new ObservableArray(Object.keys(this.values).filter(function (key) { return _this.values[key] instanceof ObservableValue; }), referenceEnhancer, "keys(" + this.name + ")", true));
4124 }
4125 return this.keys.slice();
4126 };
4127 return ObservableObjectAdministration;
4128}());
4129function asObservableObject(target, name, defaultEnhancer) {
4130 if (name === void 0) { name = ""; }
4131 if (defaultEnhancer === void 0) { defaultEnhancer = deepEnhancer; }
4132 var adm = target.$mobx;
4133 if (adm)
4134 return adm;
4135 invariant(Object.isExtensible(target), "Cannot make the designated object observable; it is not extensible");
4136 if (!isPlainObject(target))
4137 name = (target.constructor.name || "ObservableObject") + "@" + getNextId();
4138 if (!name)
4139 name = "ObservableObject@" + getNextId();
4140 adm = new ObservableObjectAdministration(target, name, defaultEnhancer);
4141 addHiddenFinalProp(target, "$mobx", adm);
4142 return adm;
4143}
4144function defineObservableProperty(target, propName, newValue, enhancer) {
4145 var adm = asObservableObject(target);
4146 assertPropertyConfigurable(target, propName);
4147 if (hasInterceptors(adm)) {
4148 var change = interceptChange(adm, {
4149 object: target,
4150 name: propName,
4151 type: "add",
4152 newValue: newValue
4153 });
4154 if (!change)
4155 return;
4156 newValue = change.newValue;
4157 }
4158 var observable = (adm.values[propName] = new ObservableValue(newValue, enhancer, adm.name + "." + propName, false));
4159 newValue = observable.value; // observableValue might have changed it
4160 Object.defineProperty(target, propName, generateObservablePropConfig(propName));
4161 if (adm.keys)
4162 adm.keys.push(propName);
4163 notifyPropertyAddition(adm, target, propName, newValue);
4164}
4165function defineComputedProperty(target, // which objects holds the observable and provides `this` context?
4166propName, options) {
4167 var adm = asObservableObject(target);
4168 options.name = adm.name + "." + propName;
4169 options.context = target;
4170 adm.values[propName] = new ComputedValue(options);
4171 Object.defineProperty(target, propName, generateComputedPropConfig(propName));
4172}
4173var observablePropertyConfigs = Object.create(null);
4174var computedPropertyConfigs = Object.create(null);
4175function generateObservablePropConfig(propName) {
4176 return (observablePropertyConfigs[propName] ||
4177 (observablePropertyConfigs[propName] = {
4178 configurable: true,
4179 enumerable: true,
4180 get: function () {
4181 return this.$mobx.read(this, propName);
4182 },
4183 set: function (v) {
4184 this.$mobx.write(this, propName, v);
4185 }
4186 }));
4187}
4188function getAdministrationForComputedPropOwner(owner) {
4189 var adm = owner.$mobx;
4190 if (!adm) {
4191 // because computed props are declared on proty,
4192 // the current instance might not have been initialized yet
4193 initializeInstance(owner);
4194 return owner.$mobx;
4195 }
4196 return adm;
4197}
4198function generateComputedPropConfig(propName) {
4199 return (computedPropertyConfigs[propName] ||
4200 (computedPropertyConfigs[propName] = {
4201 configurable: globalState.computedConfigurable,
4202 enumerable: false,
4203 get: function () {
4204 return getAdministrationForComputedPropOwner(this).read(this, propName);
4205 },
4206 set: function (v) {
4207 getAdministrationForComputedPropOwner(this).write(this, propName, v);
4208 }
4209 }));
4210}
4211function notifyPropertyAddition(adm, object, key, newValue) {
4212 var notify = hasListeners(adm);
4213 var notifySpy = isSpyEnabled();
4214 var change = notify || notifySpy
4215 ? {
4216 type: "add",
4217 object: object,
4218 name: key,
4219 newValue: newValue
4220 }
4221 : null;
4222 if (notifySpy)
4223 spyReportStart(__assign(__assign({}, change), { name: adm.name, key: key }));
4224 if (notify)
4225 notifyListeners(adm, change);
4226 if (notifySpy)
4227 spyReportEnd();
4228}
4229var isObservableObjectAdministration = createInstanceofPredicate("ObservableObjectAdministration", ObservableObjectAdministration);
4230function isObservableObject(thing) {
4231 if (isObject(thing)) {
4232 // Initializers run lazily when transpiling to babel, so make sure they are run...
4233 initializeInstance(thing);
4234 return isObservableObjectAdministration(thing.$mobx);
4235 }
4236 return false;
4237}
4238
4239function getAtom(thing, property) {
4240 if (typeof thing === "object" && thing !== null) {
4241 if (isObservableArray(thing)) {
4242 if (property !== undefined)
4243 fail("It is not possible to get index atoms from arrays");
4244 return thing.$mobx.atom;
4245 }
4246 if (isObservableSet(thing)) {
4247 return thing.$mobx;
4248 }
4249 if (isObservableMap(thing)) {
4250 var anyThing = thing;
4251 if (property === undefined)
4252 return getAtom(anyThing._keys);
4253 var observable = anyThing._data.get(property) || anyThing._hasMap.get(property);
4254 if (!observable)
4255 fail("the entry '" + property + "' does not exist in the observable map '" + getDebugName(thing) + "'");
4256 return observable;
4257 }
4258 // Initializers run lazily when transpiling to babel, so make sure they are run...
4259 initializeInstance(thing);
4260 if (property && !thing.$mobx)
4261 thing[property]; // See #1072
4262 if (isObservableObject(thing)) {
4263 if (!property)
4264 return fail("please specify a property");
4265 var observable = thing.$mobx.values[property];
4266 if (!observable)
4267 fail("no observable property '" + property + "' found on the observable object '" + getDebugName(thing) + "'");
4268 return observable;
4269 }
4270 if (isAtom(thing) || isComputedValue(thing) || isReaction(thing)) {
4271 return thing;
4272 }
4273 }
4274 else if (typeof thing === "function") {
4275 if (isReaction(thing.$mobx)) {
4276 // disposer function
4277 return thing.$mobx;
4278 }
4279 }
4280 return fail("Cannot obtain atom from " + thing);
4281}
4282function getAdministration(thing, property) {
4283 if (!thing)
4284 fail("Expecting some object");
4285 if (property !== undefined)
4286 return getAdministration(getAtom(thing, property));
4287 if (isAtom(thing) || isComputedValue(thing) || isReaction(thing))
4288 return thing;
4289 if (isObservableMap(thing) || isObservableSet(thing))
4290 return thing;
4291 // Initializers run lazily when transpiling to babel, so make sure they are run...
4292 initializeInstance(thing);
4293 if (thing.$mobx)
4294 return thing.$mobx;
4295 fail("Cannot obtain administration from " + thing);
4296}
4297function getDebugName(thing, property) {
4298 var named;
4299 if (property !== undefined)
4300 named = getAtom(thing, property);
4301 else if (isObservableObject(thing) || isObservableMap(thing) || isObservableSet(thing))
4302 named = getAdministration(thing);
4303 else
4304 named = getAtom(thing); // valid for arrays as well
4305 return named.name;
4306}
4307
4308var toString = Object.prototype.toString;
4309function deepEqual(a, b, depth) {
4310 if (depth === void 0) { depth = -1; }
4311 return eq(a, b, depth);
4312}
4313// Copied from https://github.com/jashkenas/underscore/blob/5c237a7c682fb68fd5378203f0bf22dce1624854/underscore.js#L1186-L1289
4314// Internal recursive comparison function for `isEqual`.
4315function eq(a, b, depth, aStack, bStack) {
4316 // Identical objects are equal. `0 === -0`, but they aren't identical.
4317 // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
4318 if (a === b)
4319 return a !== 0 || 1 / a === 1 / b;
4320 // `null` or `undefined` only equal to itself (strict comparison).
4321 if (a == null || b == null)
4322 return false;
4323 // `NaN`s are equivalent, but non-reflexive.
4324 if (a !== a)
4325 return b !== b;
4326 // Exhaust primitive checks
4327 var type = typeof a;
4328 if (type !== "function" && type !== "object" && typeof b != "object")
4329 return false;
4330 // Unwrap any wrapped objects.
4331 a = unwrap(a);
4332 b = unwrap(b);
4333 // Compare `[[Class]]` names.
4334 var className = toString.call(a);
4335 if (className !== toString.call(b))
4336 return false;
4337 switch (className) {
4338 // Strings, numbers, regular expressions, dates, and booleans are compared by value.
4339 case "[object RegExp]":
4340 // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
4341 case "[object String]":
4342 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
4343 // equivalent to `new String("5")`.
4344 return "" + a === "" + b;
4345 case "[object Number]":
4346 // `NaN`s are equivalent, but non-reflexive.
4347 // Object(NaN) is equivalent to NaN.
4348 if (+a !== +a)
4349 return +b !== +b;
4350 // An `egal` comparison is performed for other numeric values.
4351 return +a === 0 ? 1 / +a === 1 / b : +a === +b;
4352 case "[object Date]":
4353 case "[object Boolean]":
4354 // Coerce dates and booleans to numeric primitive values. Dates are compared by their
4355 // millisecond representations. Note that invalid dates with millisecond representations
4356 // of `NaN` are not equivalent.
4357 return +a === +b;
4358 case "[object Symbol]":
4359 return (
4360 // eslint-disable-next-line
4361 typeof Symbol !== "undefined" && Symbol.valueOf.call(a) === Symbol.valueOf.call(b));
4362 }
4363 var areArrays = className === "[object Array]";
4364 if (!areArrays) {
4365 if (typeof a != "object" || typeof b != "object")
4366 return false;
4367 // Objects with different constructors are not equivalent, but `Object`s or `Array`s
4368 // from different frames are.
4369 var aCtor = a.constructor, bCtor = b.constructor;
4370 if (aCtor !== bCtor &&
4371 !(typeof aCtor === "function" &&
4372 aCtor instanceof aCtor &&
4373 typeof bCtor === "function" &&
4374 bCtor instanceof bCtor) &&
4375 ("constructor" in a && "constructor" in b)) {
4376 return false;
4377 }
4378 }
4379 if (depth === 0) {
4380 return false;
4381 }
4382 else if (depth < 0) {
4383 depth = -1;
4384 }
4385 // Assume equality for cyclic structures. The algorithm for detecting cyclic
4386 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
4387 // Initializing stack of traversed objects.
4388 // It's done here since we only need them for objects and arrays comparison.
4389 aStack = aStack || [];
4390 bStack = bStack || [];
4391 var length = aStack.length;
4392 while (length--) {
4393 // Linear search. Performance is inversely proportional to the number of
4394 // unique nested structures.
4395 if (aStack[length] === a)
4396 return bStack[length] === b;
4397 }
4398 // Add the first object to the stack of traversed objects.
4399 aStack.push(a);
4400 bStack.push(b);
4401 // Recursively compare objects and arrays.
4402 if (areArrays) {
4403 // Compare array lengths to determine if a deep comparison is necessary.
4404 length = a.length;
4405 if (length !== b.length)
4406 return false;
4407 // Deep compare the contents, ignoring non-numeric properties.
4408 while (length--) {
4409 if (!eq(a[length], b[length], depth - 1, aStack, bStack))
4410 return false;
4411 }
4412 }
4413 else {
4414 // Deep compare objects.
4415 var keys = Object.keys(a);
4416 var key = void 0;
4417 length = keys.length;
4418 // Ensure that both objects contain the same number of properties before comparing deep equality.
4419 if (Object.keys(b).length !== length)
4420 return false;
4421 while (length--) {
4422 // Deep compare each member
4423 key = keys[length];
4424 if (!(has$1(b, key) && eq(a[key], b[key], depth - 1, aStack, bStack)))
4425 return false;
4426 }
4427 }
4428 // Remove the first object from the stack of traversed objects.
4429 aStack.pop();
4430 bStack.pop();
4431 return true;
4432}
4433function unwrap(a) {
4434 if (isObservableArray(a))
4435 return a.peek();
4436 if (isES6Map(a) || isObservableMap(a))
4437 return iteratorToArray(a.entries());
4438 if (isES6Set(a) || isObservableSet(a))
4439 return iteratorToArray(a.entries());
4440 return a;
4441}
4442function has$1(a, key) {
4443 return Object.prototype.hasOwnProperty.call(a, key);
4444}
4445
4446/*
4447The only reason for this file to exist is pure horror:
4448Without it rollup can make the bundling fail at any point in time; when it rolls up the files in the wrong order
4449it will cause undefined errors (for example because super classes or local variables not being hosted).
4450With this file that will still happen,
4451but at least in this file we can magically reorder the imports with trial and error until the build succeeds again.
4452*/
4453
4454/**
4455 * (c) Michel Weststrate 2015 - 2019
4456 * MIT Licensed
4457 *
4458 * Welcome to the mobx sources! To get an global overview of how MobX internally works,
4459 * this is a good place to start:
4460 * https://medium.com/@mweststrate/becoming-fully-reactive-an-in-depth-explanation-of-mobservable-55995262a254#.xvbh6qd74
4461 *
4462 * Source folders:
4463 * ===============
4464 *
4465 * - api/ Most of the public static methods exposed by the module can be found here.
4466 * - core/ Implementation of the MobX algorithm; atoms, derivations, reactions, dependency trees, optimizations. Cool stuff can be found here.
4467 * - types/ All the magic that is need to have observable objects, arrays and values is in this folder. Including the modifiers like `asFlat`.
4468 * - utils/ Utility stuff.
4469 *
4470 */
4471try {
4472}
4473catch (e) {
4474 var g = getGlobal();
4475 if (typeof process === "undefined")
4476 g.process = {};
4477 g.process.env = {};
4478}
4479(function () {
4480 function testCodeMinification() { }
4481 if (testCodeMinification.name !== "testCodeMinification" &&
4482 "development" !== "production" &&
4483 typeof process !== 'undefined' && process.env.IGNORE_MOBX_MINIFY_WARNING !== "true") {
4484 // trick so it doesn't get replaced
4485 var varName = ["process", "env", "NODE_ENV"].join(".");
4486 console.warn("[mobx] you are running a minified build, but '" + varName + "' was not set to 'production' in your bundler. This results in an unnecessarily large and slow bundle");
4487 }
4488})();
4489// forward compatibility with mobx, so that packages can easily support mobx 4 & 5
4490var $mobx = "$mobx";
4491if (typeof __MOBX_DEVTOOLS_GLOBAL_HOOK__ === "object") {
4492 // See: https://github.com/andykog/mobx-devtools/
4493 __MOBX_DEVTOOLS_GLOBAL_HOOK__.injectMobx({
4494 spy: spy,
4495 extras: {
4496 getDebugName: getDebugName
4497 },
4498 $mobx: $mobx
4499 });
4500}
4501// TODO: remove in some future build
4502if (typeof module !== "undefined" &&
4503 typeof module.exports !== "undefined") {
4504 var warnedAboutDefaultExport_1 = false;
4505 Object.defineProperty(module.exports, "default", {
4506 enumerable: false,
4507 get: function () {
4508 if (!warnedAboutDefaultExport_1) {
4509 warnedAboutDefaultExport_1 = true;
4510 console.warn("The MobX package does not have a default export. Use 'import { thing } from \"mobx\"' (recommended) or 'import * as mobx from \"mobx\"' instead.\"");
4511 }
4512 return undefined;
4513 }
4514 });
4515 [
4516 "extras",
4517 "Atom",
4518 "BaseAtom",
4519 "asFlat",
4520 "asMap",
4521 "asReference",
4522 "asStructure",
4523 "autorunAsync",
4524 "createTranformer",
4525 "expr",
4526 "isModifierDescriptor",
4527 "isStrictModeEnabled",
4528 "map",
4529 "useStrict",
4530 "whyRun"
4531 ].forEach(function (prop) {
4532 Object.defineProperty(module.exports, prop, {
4533 enumerable: false,
4534 get: function () {
4535 fail("'" + prop + "' is no longer part of the public MobX api. Please consult the changelog to find out where this functionality went");
4536 },
4537 set: function () { }
4538 });
4539 });
4540}
4541
4542exports.$mobx = $mobx;
4543exports.FlowCancellationError = FlowCancellationError;
4544exports.ObservableMap = ObservableMap;
4545exports.ObservableSet = ObservableSet;
4546exports.Reaction = Reaction;
4547exports._allowStateChanges = allowStateChanges;
4548exports._allowStateChangesInsideComputed = allowStateChangesInsideComputed;
4549exports._allowStateReadsEnd = allowStateReadsEnd;
4550exports._allowStateReadsStart = allowStateReadsStart;
4551exports._endAction = _endAction;
4552exports._getAdministration = getAdministration;
4553exports._getGlobalState = getGlobalState;
4554exports._interceptReads = interceptReads;
4555exports._isComputingDerivation = isComputingDerivation;
4556exports._resetGlobalState = resetGlobalState;
4557exports._startAction = _startAction;
4558exports.action = action;
4559exports.autorun = autorun;
4560exports.comparer = comparer;
4561exports.computed = computed;
4562exports.configure = configure;
4563exports.createAtom = createAtom;
4564exports.decorate = decorate;
4565exports.entries = entries;
4566exports.extendObservable = extendObservable;
4567exports.extendShallowObservable = extendShallowObservable;
4568exports.flow = flow;
4569exports.get = get;
4570exports.getAtom = getAtom;
4571exports.getDebugName = getDebugName;
4572exports.getDependencyTree = getDependencyTree;
4573exports.getObserverTree = getObserverTree;
4574exports.has = has;
4575exports.intercept = intercept;
4576exports.isAction = isAction;
4577exports.isArrayLike = isArrayLike;
4578exports.isBoxedObservable = isObservableValue;
4579exports.isComputed = isComputed;
4580exports.isComputedProp = isComputedProp;
4581exports.isFlowCancellationError = isFlowCancellationError;
4582exports.isObservable = isObservable;
4583exports.isObservableArray = isObservableArray;
4584exports.isObservableMap = isObservableMap;
4585exports.isObservableObject = isObservableObject;
4586exports.isObservableProp = isObservableProp;
4587exports.isObservableSet = isObservableSet;
4588exports.keys = keys;
4589exports.observable = observable;
4590exports.observe = observe;
4591exports.onBecomeObserved = onBecomeObserved;
4592exports.onBecomeUnobserved = onBecomeUnobserved;
4593exports.onReactionError = onReactionError;
4594exports.reaction = reaction;
4595exports.remove = remove;
4596exports.runInAction = runInAction;
4597exports.set = set;
4598exports.spy = spy;
4599exports.toJS = toJS;
4600exports.trace = trace;
4601exports.transaction = transaction;
4602exports.untracked = untracked;
4603exports.values = values;
4604exports.when = when;