mobx
Version:
Simple, scalable state management.
1,530 lines (1,316 loc) • 161 kB
JavaScript
'use strict';
var niceErrors = {
0: "Invalid value for configuration 'enforceActions', expected 'never', 'always' or 'observed'",
1: function _(prop) {
return "Cannot decorate undefined property: '" + prop.toString() + "'";
},
2: function _(prop) {
return "invalid decorator for '" + prop.toString() + "'";
},
3: function _(prop) {
return "Cannot decorate '" + prop.toString() + "': action can only be used on properties with a function value.";
},
4: function _(prop) {
return "Cannot decorate '" + prop.toString() + "': computed can only be used on getter properties.";
},
5: "'keys()' can only be used on observable objects, arrays, sets and maps",
6: "'values()' can only be used on observable objects, arrays, sets and maps",
7: "'entries()' can only be used on observable objects, arrays and maps",
8: "'set()' can only be used on observable objects, arrays and maps",
9: "'remove()' can only be used on observable objects, arrays and maps",
10: "'has()' can only be used on observable objects, arrays and maps",
11: "'get()' can only be used on observable objects, arrays and maps",
12: "Invalid annotation",
13: "Dynamic observable objects cannot be frozen",
14: "Intercept handlers should return nothing or a change object",
15: "Observable arrays cannot be frozen",
16: "Modification exception: the internal structure of an observable array was changed.",
17: function _(index, length) {
return "[mobx.array] Index out of bounds, " + index + " is larger than " + length;
},
18: "mobx.map requires Map polyfill for the current browser. Check babel-polyfill or core-js/es6/map.js",
19: function _(other) {
return "Cannot initialize from classes that inherit from Map: " + other.constructor.name;
},
20: function _(other) {
return "Cannot initialize map from " + other;
},
21: function _(dataStructure) {
return "Cannot convert to map from '" + dataStructure + "'";
},
22: "mobx.set requires Set polyfill for the current browser. Check babel-polyfill or core-js/es6/set.js",
23: "It is not possible to get index atoms from arrays",
24: function _(thing) {
return "Cannot obtain administration from " + thing;
},
25: function _(property, name) {
return "the entry '" + property + "' does not exist in the observable map '" + name + "'";
},
26: "please specify a property",
27: function _(property, name) {
return "no observable property '" + property.toString() + "' found on the observable object '" + name + "'";
},
28: function _(thing) {
return "Cannot obtain atom from " + thing;
},
29: "Expecting some object",
30: "invalid action stack. did you forget to finish an action?",
31: "missing option for computed: get",
32: function _(name, derivation) {
return "Cycle detected in computation " + name + ": " + derivation;
},
33: function _(name) {
return "The setter of computed value '" + name + "' is trying to update itself. Did you intend to update an _observable_ value, instead of the computed property?";
},
34: function _(name) {
return "[ComputedValue '" + name + "'] It is not possible to assign a new value to a computed value.";
},
35: "There are multiple, different versions of MobX active. Make sure MobX is loaded only once or use `configure({ isolateGlobalState: true })`",
36: "isolateGlobalState should be called before MobX is running any reactions",
37: function _(method) {
return "[mobx] `observableArray." + method + "()` mutates the array in-place, which is not allowed inside a derivation. Use `array.slice()." + method + "()` instead";
}
};
var errors = niceErrors ;
function die(error) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
{
var e = typeof error === "string" ? error : errors[error];
if (typeof e === "function") e = e.apply(null, args);
throw new Error("[MobX] " + e);
}
}
function getGlobal() {
// @ts-ignore
return typeof global !== "undefined" ? global : window;
}
var assign = Object.assign;
var getDescriptor = Object.getOwnPropertyDescriptor;
var defineProperty = Object.defineProperty;
var objectPrototype = Object.prototype;
var EMPTY_ARRAY = [];
Object.freeze(EMPTY_ARRAY);
var EMPTY_OBJECT = {};
Object.freeze(EMPTY_OBJECT);
var hasProxy = typeof Proxy !== "undefined";
var plainObjectString = /*#__PURE__*/Object.toString();
function assertProxies() {
if (!hasProxy) {
die( "`Proxy` objects are not available in the current environment. Please configure MobX to enable a fallback implementation.`" );
}
}
function warnAboutProxyRequirement(msg) {
if ( globalState.verifyProxies) {
die("MobX is currently configured to be able to run in ES5 mode, but in ES5 MobX won't be able to " + msg);
}
}
function getNextId() {
return ++globalState.mobxGuid;
}
/**
* Makes sure that the provided function is invoked at most once.
*/
function once(func) {
var invoked = false;
return function () {
if (invoked) return;
invoked = true;
return func.apply(this, arguments);
};
}
var noop = function noop() {};
function isFunction(fn) {
return typeof fn === "function";
}
function isStringish(value) {
var t = typeof value;
switch (t) {
case "string":
case "symbol":
case "number":
return true;
}
return false;
}
function isObject(value) {
return value !== null && typeof value === "object";
}
function isPlainObject(value) {
var _proto$constructor;
if (!isObject(value)) return false;
var proto = Object.getPrototypeOf(value);
if (proto == null) return true;
return ((_proto$constructor = proto.constructor) === null || _proto$constructor === void 0 ? void 0 : _proto$constructor.toString()) === plainObjectString;
} // https://stackoverflow.com/a/37865170
function isGenerator(obj) {
var constructor = obj === null || obj === void 0 ? void 0 : obj.constructor;
if (!constructor) return false;
if ("GeneratorFunction" === constructor.name || "GeneratorFunction" === constructor.displayName) return true;
return false;
}
function addHiddenProp(object, propName, value) {
defineProperty(object, propName, {
enumerable: false,
writable: true,
configurable: true,
value: value
});
}
function addHiddenFinalProp(object, propName, value) {
defineProperty(object, propName, {
enumerable: false,
writable: false,
configurable: true,
value: value
});
}
function assertPropertyConfigurable(object, prop) {
{
var descriptor = getDescriptor(object, prop);
if ((descriptor === null || descriptor === void 0 ? void 0 : descriptor.configurable) === false || (descriptor === null || descriptor === void 0 ? void 0 : descriptor.writable) === false) die("Cannot make property '" + stringifyKey(prop) + "' observable, it is not configurable and writable in the target object");
}
}
function createInstanceofPredicate(name, clazz) {
var propName = "isMobX" + name;
clazz.prototype[propName] = true;
return function (x) {
return isObject(x) && x[propName] === true;
};
}
function isES6Map(thing) {
return thing instanceof Map;
}
function isES6Set(thing) {
return thing instanceof Set;
}
var hasGetOwnPropertySymbols = typeof Object.getOwnPropertySymbols !== "undefined";
/**
* Returns the following: own keys, prototype keys & own symbol keys, if they are enumerable.
*/
function getPlainObjectKeys(object) {
var keys = Object.keys(object); // Not supported in IE, so there are not going to be symbol props anyway...
if (!hasGetOwnPropertySymbols) return keys;
var symbols = Object.getOwnPropertySymbols(object);
if (!symbols.length) return keys;
return [].concat(keys, symbols.filter(function (s) {
return objectPrototype.propertyIsEnumerable.call(object, s);
}));
} // From Immer utils
// Returns all own keys, including non-enumerable and symbolic
var ownKeys = typeof Reflect !== "undefined" && Reflect.ownKeys ? Reflect.ownKeys : hasGetOwnPropertySymbols ? function (obj) {
return Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj));
} :
/* istanbul ignore next */
Object.getOwnPropertyNames;
function stringifyKey(key) {
if (typeof key === "string") return key;
if (typeof key === "symbol") return key.toString();
return new String(key).toString();
}
function toPrimitive(value) {
return value === null ? null : typeof value === "object" ? "" + value : value;
}
function hasProp(target, prop) {
return objectPrototype.hasOwnProperty.call(target, prop);
} // From Immer utils
var getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors || function getOwnPropertyDescriptors(target) {
// Polyfill needed for Hermes and IE, see https://github.com/facebook/hermes/issues/274
var res = {}; // Note: without polyfill for ownKeys, symbols won't be picked up
ownKeys(target).forEach(function (key) {
res[key] = getDescriptor(target, key);
});
return res;
};
var mobxDecoratorsSymbol = /*#__PURE__*/Symbol("mobx-decorators");
var mobxAppliedDecoratorsSymbol = /*#__PURE__*/Symbol("mobx-applied-decorators");
function createDecorator(type) {
return assign(function (target, property) {
if (property === undefined) {
// @decorator(arg) member
createDecoratorAndAnnotation(type, target);
} else {
// @decorator member
storeDecorator(target, property, type);
}
}, {
annotationType_: type
});
}
function createDecoratorAndAnnotation(type, arg_) {
return assign(function (target, property) {
storeDecorator(target, property, type, arg_);
}, {
annotationType_: type,
arg_: arg_
});
}
function storeDecorator(target, property, type, arg_) {
var desc = getDescriptor(target, mobxDecoratorsSymbol);
var map;
if (desc) {
map = desc.value;
} else {
map = {};
addHiddenProp(target, mobxDecoratorsSymbol, map);
}
map[property] = {
annotationType_: type,
arg_: arg_
};
}
function applyDecorators(target) {
if (target[mobxAppliedDecoratorsSymbol]) return true;
var current = target; // optimization: this could be cached per prototype!
// (then we can remove the weird short circuiting as well..)
var annotations = [];
while (current && current !== objectPrototype) {
var desc = getDescriptor(current, mobxDecoratorsSymbol);
if (desc) {
if (!annotations.length) {
for (var key in desc.value) {
// second conditions is to recognize actions
if (!hasProp(target, key) && !hasProp(current, key)) {
// not all fields are defined yet, so we are in the makeObservable call of some super class,
// short circuit, here, we will do this again in a later makeObservable call
return true;
}
}
}
annotations.unshift(desc.value);
}
current = Object.getPrototypeOf(current);
}
annotations.forEach(function (a) {
makeObservable(target, a);
});
addHiddenProp(target, mobxAppliedDecoratorsSymbol, true);
return annotations.length > 0;
}
var $mobx = /*#__PURE__*/Symbol("mobx administration");
var Atom = /*#__PURE__*/function () {
// for effective unobserving. BaseAtom has true, for extra optimization, so its onBecomeUnobserved never gets called, because it's not needed
/**
* Create a new atom. For debugging purposes it is recommended to give it a name.
* The onBecomeObserved and onBecomeUnobserved callbacks can be used for resource management.
*/
function Atom(name_) {
if (name_ === void 0) {
name_ = "Atom@" + getNextId();
}
this.name_ = void 0;
this.isPendingUnobservation_ = false;
this.isBeingObserved_ = false;
this.observers_ = new Set();
this.diffValue_ = 0;
this.lastAccessedBy_ = 0;
this.lowestObserverState_ = IDerivationState_.NOT_TRACKING_;
this.onBOL = void 0;
this.onBUOL = void 0;
this.name_ = name_;
} // onBecomeObservedListeners
var _proto = Atom.prototype;
_proto.onBO = function onBO() {
if (this.onBOL) {
this.onBOL.forEach(function (listener) {
return listener();
});
}
};
_proto.onBUO = function onBUO() {
if (this.onBUOL) {
this.onBUOL.forEach(function (listener) {
return listener();
});
}
}
/**
* Invoke this method to notify mobx that your atom has been used somehow.
* Returns true if there is currently a reactive context.
*/
;
_proto.reportObserved = function reportObserved$1() {
return reportObserved(this);
}
/**
* Invoke this method _after_ this method has changed to signal mobx that all its observers should invalidate.
*/
;
_proto.reportChanged = function reportChanged() {
startBatch();
propagateChanged(this);
endBatch();
};
_proto.toString = function toString() {
return this.name_;
};
return Atom;
}();
var isAtom = /*#__PURE__*/createInstanceofPredicate("Atom", Atom);
function createAtom(name, onBecomeObservedHandler, onBecomeUnobservedHandler) {
if (onBecomeObservedHandler === void 0) {
onBecomeObservedHandler = noop;
}
if (onBecomeUnobservedHandler === void 0) {
onBecomeUnobservedHandler = noop;
}
var atom = new Atom(name); // default `noop` listener will not initialize the hook Set
if (onBecomeObservedHandler !== noop) {
onBecomeObserved(atom, onBecomeObservedHandler);
}
if (onBecomeUnobservedHandler !== noop) {
onBecomeUnobserved(atom, onBecomeUnobservedHandler);
}
return atom;
}
function identityComparer(a, b) {
return a === b;
}
function structuralComparer(a, b) {
return deepEqual(a, b);
}
function shallowComparer(a, b) {
return deepEqual(a, b, 1);
}
function defaultComparer(a, b) {
return Object.is(a, b);
}
var comparer = {
identity: identityComparer,
structural: structuralComparer,
"default": defaultComparer,
shallow: shallowComparer
};
function deepEnhancer(v, _, name) {
// it is an observable already, done
if (isObservable(v)) return v; // something that can be converted and mutated?
if (Array.isArray(v)) return observable.array(v, {
name: name
});
if (isPlainObject(v)) return observable.object(v, undefined, {
name: name
});
if (isES6Map(v)) return observable.map(v, {
name: name
});
if (isES6Set(v)) return observable.set(v, {
name: name
});
return v;
}
function shallowEnhancer(v, _, name) {
if (v === undefined || v === null) return v;
if (isObservableObject(v) || isObservableArray(v) || isObservableMap(v) || isObservableSet(v)) return v;
if (Array.isArray(v)) return observable.array(v, {
name: name,
deep: false
});
if (isPlainObject(v)) return observable.object(v, undefined, {
name: name,
deep: false
});
if (isES6Map(v)) return observable.map(v, {
name: name,
deep: false
});
if (isES6Set(v)) return observable.set(v, {
name: name,
deep: false
});
die("The shallow modifier / decorator can only used in combination with arrays, objects, maps and sets");
}
function referenceEnhancer(newValue) {
// never turn into an observable
return newValue;
}
function refStructEnhancer(v, oldValue) {
if ( isObservable(v)) die("observable.struct should not be used with observable values");
if (deepEqual(v, oldValue)) return oldValue;
return v;
}
var _annotationToEnhancer;
var OBSERVABLE = "observable";
var OBSERVABLE_REF = "observable.ref";
var OBSERVABLE_SHALLOW = "observable.shallow";
var OBSERVABLE_STRUCT = "observable.struct"; // Predefined bags of create observable options, to avoid allocating temporarily option objects
// in the majority of cases
var defaultCreateObservableOptions = {
deep: true,
name: undefined,
defaultDecorator: undefined,
proxy: true
};
Object.freeze(defaultCreateObservableOptions);
function asCreateObservableOptions(thing) {
return thing || defaultCreateObservableOptions;
}
function getEnhancerFromOption(options) {
return options.deep === true ? deepEnhancer : options.deep === false ? referenceEnhancer : getEnhancerFromAnnotation(options.defaultDecorator);
}
var annotationToEnhancer = (_annotationToEnhancer = {}, _annotationToEnhancer[OBSERVABLE] = deepEnhancer, _annotationToEnhancer[OBSERVABLE_REF] = referenceEnhancer, _annotationToEnhancer[OBSERVABLE_SHALLOW] = shallowEnhancer, _annotationToEnhancer[OBSERVABLE_STRUCT] = refStructEnhancer, _annotationToEnhancer);
function getEnhancerFromAnnotation(annotation) {
var _annotationToEnhancer2;
return !annotation ? deepEnhancer : (_annotationToEnhancer2 = annotationToEnhancer[annotation.annotationType_]) !== null && _annotationToEnhancer2 !== void 0 ? _annotationToEnhancer2 : die(12);
}
/**
* Turns an object, array or function into a reactive structure.
* @param v the value which should become observable.
*/
function createObservable(v, arg2, arg3) {
// @observable someProp;
if (isStringish(arg2)) {
storeDecorator(v, arg2, OBSERVABLE);
return;
} // it is an observable already, done
if (isObservable(v)) return v; // something that can be converted and mutated?
var res = isPlainObject(v) ? observable.object(v, arg2, arg3) : Array.isArray(v) ? observable.array(v, arg2) : isES6Map(v) ? observable.map(v, arg2) : isES6Set(v) ? observable.set(v, arg2) : v; // this value could be converted to a new observable data structure, return it
if (res !== v) return res;
return observable.box(v);
}
createObservable.annotationType_ = OBSERVABLE;
var observableFactories = {
box: function box(value, options) {
var o = asCreateObservableOptions(options);
return new ObservableValue(value, getEnhancerFromOption(o), o.name, true, o.equals);
},
array: function array(initialValues, options) {
var o = asCreateObservableOptions(options);
return (globalState.useProxies === false || o.proxy === false ? createLegacyArray : createObservableArray)(initialValues, getEnhancerFromOption(o), o.name);
},
map: function map(initialValues, options) {
var o = asCreateObservableOptions(options);
return new ObservableMap(initialValues, getEnhancerFromOption(o), o.name);
},
set: function set(initialValues, options) {
var o = asCreateObservableOptions(options);
return new ObservableSet(initialValues, getEnhancerFromOption(o), o.name);
},
object: function object(props, decorators, options) {
var o = asCreateObservableOptions(options);
var base = {};
asObservableObject(base, options === null || options === void 0 ? void 0 : options.name, getEnhancerFromOption(o));
return extendObservable(globalState.useProxies === false || o.proxy === false ? base : createDynamicObservableObject(base), props, decorators, options);
},
ref: /*#__PURE__*/createDecorator(OBSERVABLE_REF),
shallow: /*#__PURE__*/createDecorator(OBSERVABLE_SHALLOW),
deep: /*#__PURE__*/createDecorator(OBSERVABLE),
struct: /*#__PURE__*/createDecorator(OBSERVABLE_STRUCT)
}; // eslint-disable-next-line
var observable = /*#__PURE__*/assign(createObservable, observableFactories);
var COMPUTED = "computed";
var COMPUTED_STRUCT = "computed.struct";
/**
* Decorator for class properties: @computed get value() { return expr; }.
* For legacy purposes also invokable as ES5 observable created: `computed(() => expr)`;
*/
var computed = function computed(arg1, arg2, arg3) {
if (isStringish(arg2)) {
// @computed
return storeDecorator(arg1, arg2, COMPUTED);
}
if (isPlainObject(arg1)) {
// @computed({ options })
return createDecoratorAndAnnotation(COMPUTED, arg1);
} // computed(expr, options?)
{
if (!isFunction(arg1)) die("First argument to `computed` should be an expression.");
if (isFunction(arg2)) die("A setter as second argument is no longer supported, use `{set: fn }` option instead");
}
var opts = isPlainObject(arg2) ? arg2 : {};
opts.get = arg1;
opts.name = opts.name || arg1.name || "";
/* for generated name */
return new ComputedValue(opts);
};
computed.annotationType_ = COMPUTED;
computed.struct = /*#__PURE__*/assign(function (target, property) {
storeDecorator(target, property, COMPUTED_STRUCT);
}, {
annotationType_: COMPUTED_STRUCT
});
var _getDescriptor$config, _getDescriptor;
// mobx versions
var currentActionId = 0;
var nextActionId = 1;
var isFunctionNameConfigurable = (_getDescriptor$config = (_getDescriptor = /*#__PURE__*/getDescriptor(function () {}, "name")) === null || _getDescriptor === void 0 ? void 0 : _getDescriptor.configurable) !== null && _getDescriptor$config !== void 0 ? _getDescriptor$config : false; // we can safely recycle this object
var tmpNameDescriptor = {
value: "action",
configurable: true,
writable: false,
enumerable: false
};
function createAction(actionName, fn, autoAction, ref) {
if (autoAction === void 0) {
autoAction = false;
}
{
if (!isFunction(fn)) die("`action` can only be invoked on functions");
if (typeof actionName !== "string" || !actionName) die("actions should have valid names, got: '" + actionName + "'");
}
function res() {
return executeAction(actionName, autoAction, fn, ref || this, arguments);
}
res.isMobxAction = true;
if (isFunctionNameConfigurable) {
tmpNameDescriptor.value = actionName;
Object.defineProperty(res, "name", tmpNameDescriptor);
}
return res;
}
function executeAction(actionName, canRunAsDerivation, fn, scope, args) {
var runInfo = _startAction(actionName, canRunAsDerivation, scope, args);
try {
return fn.apply(scope, args);
} catch (err) {
runInfo.error_ = err;
throw err;
} finally {
_endAction(runInfo);
}
}
function _startAction(actionName, canRunAsDerivation, // true for autoAction
scope, args) {
var notifySpy_ = isSpyEnabled() && !!actionName;
var startTime_ = 0;
if ( notifySpy_) {
startTime_ = Date.now();
var flattenedArgs = args ? Array.from(args) : EMPTY_ARRAY;
spyReportStart({
type: ACTION,
name: actionName,
object: scope,
arguments: flattenedArgs
});
}
var prevDerivation_ = globalState.trackingDerivation;
var runAsAction = !canRunAsDerivation || !prevDerivation_;
startBatch();
var prevAllowStateChanges_ = globalState.allowStateChanges; // by default preserve previous allow
if (runAsAction) {
untrackedStart();
prevAllowStateChanges_ = allowStateChangesStart(true);
}
var prevAllowStateReads_ = allowStateReadsStart(true);
var runInfo = {
runAsAction_: runAsAction,
prevDerivation_: prevDerivation_,
prevAllowStateChanges_: prevAllowStateChanges_,
prevAllowStateReads_: prevAllowStateReads_,
notifySpy_: notifySpy_,
startTime_: startTime_,
actionId_: nextActionId++,
parentActionId_: currentActionId
};
currentActionId = runInfo.actionId_;
return runInfo;
}
function _endAction(runInfo) {
if (currentActionId !== runInfo.actionId_) {
die(30);
}
currentActionId = runInfo.parentActionId_;
if (runInfo.error_ !== undefined) {
globalState.suppressReactionErrors = true;
}
allowStateChangesEnd(runInfo.prevAllowStateChanges_);
allowStateReadsEnd(runInfo.prevAllowStateReads_);
endBatch();
if (runInfo.runAsAction_) untrackedEnd(runInfo.prevDerivation_);
if ( runInfo.notifySpy_) {
spyReportEnd({
time: Date.now() - runInfo.startTime_
});
}
globalState.suppressReactionErrors = false;
}
function allowStateChanges(allowStateChanges, func) {
var prev = allowStateChangesStart(allowStateChanges);
try {
return func();
} finally {
allowStateChangesEnd(prev);
}
}
function allowStateChangesStart(allowStateChanges) {
var prev = globalState.allowStateChanges;
globalState.allowStateChanges = allowStateChanges;
return prev;
}
function allowStateChangesEnd(prev) {
globalState.allowStateChanges = prev;
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _createForOfIteratorHelperLoose(o, allowArrayLike) {
var it;
if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
if (it) o = it;
var i = 0;
return function () {
if (i >= o.length) return {
done: true
};
return {
done: false,
value: o[i++]
};
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
it = o[Symbol.iterator]();
return it.next.bind(it);
}
var _Symbol$toPrimitive;
var CREATE = "create";
_Symbol$toPrimitive = Symbol.toPrimitive;
var ObservableValue = /*#__PURE__*/function (_Atom) {
_inheritsLoose(ObservableValue, _Atom);
function ObservableValue(value, enhancer, name_, notifySpy, equals) {
var _this;
if (name_ === void 0) {
name_ = "ObservableValue@" + getNextId();
}
if (notifySpy === void 0) {
notifySpy = true;
}
if (equals === void 0) {
equals = comparer["default"];
}
_this = _Atom.call(this, name_) || this;
_this.enhancer = void 0;
_this.name_ = void 0;
_this.equals = void 0;
_this.hasUnreportedChange_ = false;
_this.interceptors_ = void 0;
_this.changeListeners_ = void 0;
_this.value_ = void 0;
_this.dehancer = void 0;
_this.enhancer = enhancer;
_this.name_ = name_;
_this.equals = equals;
_this.value_ = enhancer(value, undefined, name_);
if ( notifySpy && isSpyEnabled()) {
// only notify spy if this is a stand-alone observable
spyReport({
type: CREATE,
object: _assertThisInitialized(_this),
observableKind: "value",
debugObjectName: _this.name_,
newValue: "" + _this.value_
});
}
return _this;
}
var _proto = ObservableValue.prototype;
_proto.dehanceValue = function dehanceValue(value) {
if (this.dehancer !== undefined) return this.dehancer(value);
return value;
};
_proto.set = function set(newValue) {
var oldValue = this.value_;
newValue = this.prepareNewValue_(newValue);
if (newValue !== globalState.UNCHANGED) {
var notifySpy = isSpyEnabled();
if ( notifySpy) {
spyReportStart({
type: UPDATE,
object: this,
observableKind: "value",
debugObjectName: this.name_,
newValue: newValue,
oldValue: oldValue
});
}
this.setNewValue_(newValue);
if ( notifySpy) spyReportEnd();
}
};
_proto.prepareNewValue_ = function prepareNewValue_(newValue) {
checkIfStateModificationsAreAllowed(this);
if (hasInterceptors(this)) {
var change = interceptChange(this, {
object: this,
type: UPDATE,
newValue: newValue
});
if (!change) return globalState.UNCHANGED;
newValue = change.newValue;
} // apply modifier
newValue = this.enhancer(newValue, this.value_, this.name_);
return this.equals(this.value_, newValue) ? globalState.UNCHANGED : newValue;
};
_proto.setNewValue_ = function setNewValue_(newValue) {
var oldValue = this.value_;
this.value_ = newValue;
this.reportChanged();
if (hasListeners(this)) {
notifyListeners(this, {
type: UPDATE,
object: this,
newValue: newValue,
oldValue: oldValue
});
}
};
_proto.get = function get() {
this.reportObserved();
return this.dehanceValue(this.value_);
};
_proto.intercept_ = function intercept_(handler) {
return registerInterceptor(this, handler);
};
_proto.observe_ = function observe_(listener, fireImmediately) {
if (fireImmediately) listener({
observableKind: "value",
debugObjectName: this.name_,
object: this,
type: UPDATE,
newValue: this.value_,
oldValue: undefined
});
return registerListener(this, listener);
};
_proto.raw = function raw() {
// used by MST ot get undehanced value
return this.value_;
};
_proto.toJSON = function toJSON() {
return this.get();
};
_proto.toString = function toString() {
return this.name_ + "[" + this.value_ + "]";
};
_proto.valueOf = function valueOf() {
return toPrimitive(this.get());
};
_proto[_Symbol$toPrimitive] = function () {
return this.valueOf();
};
return ObservableValue;
}(Atom);
var isObservableValue = /*#__PURE__*/createInstanceofPredicate("ObservableValue", ObservableValue);
var _Symbol$toPrimitive$1;
/**
* A node in the state dependency root that observes other nodes, and can be observed itself.
*
* ComputedValue will remember the result of the computation for the duration of the batch, or
* while being observed.
*
* During this time it will recompute only when one of its direct dependencies changed,
* but only when it is being accessed with `ComputedValue.get()`.
*
* Implementation description:
* 1. First time it's being accessed it will compute and remember result
* give back remembered result until 2. happens
* 2. First time any deep dependency change, propagate POSSIBLY_STALE to all observers, wait for 3.
* 3. When it's being accessed, recompute if any shallow dependency changed.
* if result changed: propagate STALE to all observers, that were POSSIBLY_STALE from the last step.
* go to step 2. either way
*
* If at any point it's outside batch and it isn't observed: reset everything and go to 1.
*/
_Symbol$toPrimitive$1 = Symbol.toPrimitive;
var ComputedValue = /*#__PURE__*/function () {
// nodes we are looking at. Our value depends on these nodes
// during tracking it's an array with new observed observers
// to check for cycles
// N.B: unminified as it is used by MST
/**
* Create a new computed value based on a function expression.
*
* The `name` property is for debug purposes only.
*
* The `equals` property specifies the comparer function to use to determine if a newly produced
* value differs from the previous value. Two comparers are provided in the library; `defaultComparer`
* compares based on identity comparison (===), and `structuralComparer` deeply compares the structure.
* Structural comparison can be convenient if you always produce a new aggregated object and
* don't want to notify observers if it is structurally the same.
* This is useful for working with vectors, mouse coordinates etc.
*/
function ComputedValue(options) {
this.dependenciesState_ = IDerivationState_.NOT_TRACKING_;
this.observing_ = [];
this.newObserving_ = null;
this.isBeingObserved_ = false;
this.isPendingUnobservation_ = false;
this.observers_ = new Set();
this.diffValue_ = 0;
this.runId_ = 0;
this.lastAccessedBy_ = 0;
this.lowestObserverState_ = IDerivationState_.UP_TO_DATE_;
this.unboundDepsCount_ = 0;
this.mapid_ = "#" + getNextId();
this.value_ = new CaughtException(null);
this.name_ = void 0;
this.triggeredBy_ = void 0;
this.isComputing_ = false;
this.isRunningSetter_ = false;
this.derivation = void 0;
this.setter_ = void 0;
this.isTracing_ = TraceMode.NONE;
this.scope_ = void 0;
this.equals_ = void 0;
this.requiresReaction_ = void 0;
this.keepAlive_ = void 0;
this.onBOL = void 0;
this.onBUOL = void 0;
if (!options.get) die(31);
this.derivation = options.get;
this.name_ = options.name || "ComputedValue@" + getNextId();
if (options.set) this.setter_ = createAction(this.name_ + "-setter", options.set);
this.equals_ = options.equals || (options.compareStructural || options.struct ? comparer.structural : comparer["default"]);
this.scope_ = options.context;
this.requiresReaction_ = !!options.requiresReaction;
this.keepAlive_ = !!options.keepAlive;
}
var _proto = ComputedValue.prototype;
_proto.onBecomeStale_ = function onBecomeStale_() {
propagateMaybeChanged(this);
};
_proto.onBO = function onBO() {
if (this.onBOL) {
this.onBOL.forEach(function (listener) {
return listener();
});
}
};
_proto.onBUO = function onBUO() {
if (this.onBUOL) {
this.onBUOL.forEach(function (listener) {
return listener();
});
}
}
/**
* Returns the current value of this computed value.
* Will evaluate its computation first if needed.
*/
;
_proto.get = function get() {
if (this.isComputing_) die(32, this.name_, this.derivation);
if (globalState.inBatch === 0 && // !globalState.trackingDerivatpion &&
this.observers_.size === 0 && !this.keepAlive_) {
if (shouldCompute(this)) {
this.warnAboutUntrackedRead_();
startBatch(); // See perf test 'computed memoization'
this.value_ = this.computeValue_(false);
endBatch();
}
} else {
reportObserved(this);
if (shouldCompute(this)) {
var prevTrackingContext = globalState.trackingContext;
if (this.keepAlive_ && !prevTrackingContext) globalState.trackingContext = this;
if (this.trackAndCompute()) propagateChangeConfirmed(this);
globalState.trackingContext = prevTrackingContext;
}
}
var result = this.value_;
if (isCaughtException(result)) throw result.cause;
return result;
};
_proto.set = function set(value) {
if (this.setter_) {
if (this.isRunningSetter_) die(33, this.name_);
this.isRunningSetter_ = true;
try {
this.setter_.call(this.scope_, value);
} finally {
this.isRunningSetter_ = false;
}
} else die(34, this.name_);
};
_proto.trackAndCompute = function trackAndCompute() {
// N.B: unminified as it is used by MST
var oldValue = this.value_;
var wasSuspended =
/* see #1208 */
this.dependenciesState_ === IDerivationState_.NOT_TRACKING_;
var newValue = this.computeValue_(true);
if ( isSpyEnabled()) {
spyReport({
observableKind: "computed",
debugObjectName: this.name_,
object: this.scope_,
type: "update",
oldValue: this.value_,
newValue: newValue
});
}
var changed = wasSuspended || isCaughtException(oldValue) || isCaughtException(newValue) || !this.equals_(oldValue, newValue);
if (changed) {
this.value_ = newValue;
}
return changed;
};
_proto.computeValue_ = function computeValue_(track) {
this.isComputing_ = true; // don't allow state changes during computation
var prev = allowStateChangesStart(false);
var res;
if (track) {
res = trackDerivedFunction(this, this.derivation, this.scope_);
} else {
if (globalState.disableErrorBoundaries === true) {
res = this.derivation.call(this.scope_);
} else {
try {
res = this.derivation.call(this.scope_);
} catch (e) {
res = new CaughtException(e);
}
}
}
allowStateChangesEnd(prev);
this.isComputing_ = false;
return res;
};
_proto.suspend_ = function suspend_() {
if (!this.keepAlive_) {
clearObserving(this);
this.value_ = undefined; // don't hold on to computed value!
}
};
_proto.observe_ = function observe_(listener, fireImmediately) {
var _this = this;
var firstTime = true;
var prevValue = undefined;
return autorun(function () {
// TODO: why is this in a different place than the spyReport() function? in all other observables it's called in the same place
var newValue = _this.get();
if (!firstTime || fireImmediately) {
var prevU = untrackedStart();
listener({
observableKind: "computed",
debugObjectName: _this.name_,
type: UPDATE,
object: _this,
newValue: newValue,
oldValue: prevValue
});
untrackedEnd(prevU);
}
firstTime = false;
prevValue = newValue;
});
};
_proto.warnAboutUntrackedRead_ = function warnAboutUntrackedRead_() {
if (this.requiresReaction_ === true) {
die("[mobx] Computed value " + this.name_ + " is read outside a reactive context");
}
if (this.isTracing_ !== TraceMode.NONE) {
console.log("[mobx.trace] '" + this.name_ + "' is being read outside a reactive context. Doing a full recompute");
}
if (globalState.computedRequiresReaction) {
console.warn("[mobx] Computed value " + this.name_ + " is being read outside a reactive context. Doing a full recompute");
}
};
_proto.toString = function toString() {
return this.name_ + "[" + this.derivation.toString() + "]";
};
_proto.valueOf = function valueOf() {
return toPrimitive(this.get());
};
_proto[_Symbol$toPrimitive$1] = function () {
return this.valueOf();
};
return ComputedValue;
}();
var isComputedValue = /*#__PURE__*/createInstanceofPredicate("ComputedValue", ComputedValue);
var IDerivationState_;
(function (IDerivationState_) {
// before being run or (outside batch and not being observed)
// at this point derivation is not holding any data about dependency tree
IDerivationState_[IDerivationState_["NOT_TRACKING_"] = -1] = "NOT_TRACKING_"; // no shallow dependency changed since last computation
// won't recalculate derivation
// this is what makes mobx fast
IDerivationState_[IDerivationState_["UP_TO_DATE_"] = 0] = "UP_TO_DATE_"; // some deep dependency changed, but don't know if shallow dependency changed
// will require to check first if UP_TO_DATE or POSSIBLY_STALE
// currently only ComputedValue will propagate POSSIBLY_STALE
//
// having this state is second big optimization:
// don't have to recompute on every dependency change, but only when it's needed
IDerivationState_[IDerivationState_["POSSIBLY_STALE_"] = 1] = "POSSIBLY_STALE_"; // A shallow dependency has changed since last computation and the derivation
// will need to recompute when it's needed next.
IDerivationState_[IDerivationState_["STALE_"] = 2] = "STALE_";
})(IDerivationState_ || (IDerivationState_ = {}));
var TraceMode;
(function (TraceMode) {
TraceMode[TraceMode["NONE"] = 0] = "NONE";
TraceMode[TraceMode["LOG"] = 1] = "LOG";
TraceMode[TraceMode["BREAK"] = 2] = "BREAK";
})(TraceMode || (TraceMode = {}));
var CaughtException = function CaughtException(cause) {
this.cause = void 0;
this.cause = cause; // Empty
};
function isCaughtException(e) {
return e instanceof CaughtException;
}
/**
* Finds out whether any dependency of the derivation has actually changed.
* If dependenciesState is 1 then it will recalculate dependencies,
* if any dependency changed it will propagate it by changing dependenciesState to 2.
*
* By iterating over the dependencies in the same order that they were reported and
* stopping on the first change, all the recalculations are only called for ComputedValues
* that will be tracked by derivation. That is because we assume that if the first x
* dependencies of the derivation doesn't change then the derivation should run the same way
* up until accessing x-th dependency.
*/
function shouldCompute(derivation) {
switch (derivation.dependenciesState_) {
case IDerivationState_.UP_TO_DATE_:
return false;
case IDerivationState_.NOT_TRACKING_:
case IDerivationState_.STALE_:
return true;
case IDerivationState_.POSSIBLY_STALE_:
{
// state propagation can occur outside of action/reactive context #2195
var prevAllowStateReads = allowStateReadsStart(true);
var prevUntracked = untrackedStart(); // no need for those computeds to be reported, they will be picked up in trackDerivedFunction.
var obs = derivation.observing_,
l = obs.length;
for (var i = 0; i < l; i++) {
var obj = obs[i];
if (isComputedValue(obj)) {
if (globalState.disableErrorBoundaries) {
obj.get();
} else {
try {
obj.get();
} catch (e) {
// we are not interested in the value *or* exception at this moment, but if there is one, notify all
untrackedEnd(prevUntracked);
allowStateReadsEnd(prevAllowStateReads);
return true;
}
} // if ComputedValue `obj` actually changed it will be computed and propagated to its observers.
// and `derivation` is an observer of `obj`
// invariantShouldCompute(derivation)
if (derivation.dependenciesState_ === IDerivationState_.STALE_) {
untrackedEnd(prevUntracked);
allowStateReadsEnd(prevAllowStateReads);
return true;
}
}
}
changeDependenciesStateTo0(derivation);
untrackedEnd(prevUntracked);
allowStateReadsEnd(prevAllowStateReads);
return false;
}
}
}
function isComputingDerivation() {
return globalState.trackingDerivation !== null; // filter out actions inside computations
}
function checkIfStateModificationsAreAllowed(atom) {
var hasObservers = atom.observers_.size > 0; // Should not be possible to change observed state outside strict mode, except during initialization, see #563
if (!globalState.allowStateChanges && (hasObservers || globalState.enforceActions === "always")) console.warn("[MobX] " + (globalState.enforceActions ? "Since strict-mode is enabled, changing (observed) observable values without using an action is not allowed. Tried to modify: " : "Side effects like changing state are not allowed at this point. Are you trying to modify state from, for example, a computed value or the render function of a React component? You can wrap side effects in 'runInAction' (or decorate functions with 'action') if needed. Tried to modify: ") + atom.name_);
}
function checkIfStateReadsAreAllowed(observable) {
if ( !globalState.allowStateReads && globalState.observableRequiresReaction) {
console.warn("[mobx] Observable " + observable.name_ + " being read outside a reactive context");
}
}
/**
* Executes the provided function `f` and tracks which observables are being accessed.
* The tracking information is stored on the `derivation` object and the derivation is registered
* as observer of any of the accessed observables.
*/
function trackDerivedFunction(derivation, f, context) {
var prevAllowStateReads = allowStateReadsStart(true); // pre allocate array allocation + room for variation in deps
// array will be trimmed by bindDependencies
changeDependenciesStateTo0(derivation);
derivation.newObserving_ = new Array(derivation.observing_.length + 100);
derivation.unboundDepsCount_ = 0;
derivation.runId_ = ++globalState.runId;
var prevTracking = globalState.trackingDerivation;
globalState.trackingDerivation = derivation;
globalState.inBatch++;
var result;
if (globalState.disableErrorBoundaries === true) {
result = f.call(context);
} else {
try {
result = f.call(context);
} catch (e) {
result = new CaughtException(e);
}
}
globalState.inBatch--;
globalState.trackingDerivation = prevTracking;
bindDependencies(derivation);
warnAboutDerivationWithoutDependencies(derivation);
allowStateReadsEnd(prevAllowStateReads);
return result;
}
function warnAboutDerivationWithoutDependencies(derivation) {
if (derivation.observing_.length !== 0) return;
if (globalState.reactionRequiresObservable || derivation.requiresObservable_) {
console.warn("[mobx] Derivation " + derivation.name_ + " is created/updated without reading any observable value");
}
}
/**
* diffs newObserving with observing.
* update observing to be newObserving with unique observables
* notify observers that become observed/unobserved
*/
function bindDependencies(derivation) {
// invariant(derivation.dependenciesState !== IDerivationState.NOT_TRACKING, "INTERNAL ERROR bindDependencies expects derivation.dependenciesState !== -1");
var prevObserving = derivation.observing_;
var observing = derivation.observing_ = derivation.newObserving_;
var lowestNewObservingDerivationState = IDerivationState_.UP_TO_DATE_; // Go through all new observables and check diffValue: (this list can contain duplicates):
// 0: first occurrence, change to 1 and keep it
// 1: extra occurrence, drop it
var i0 = 0,
l = derivation.unboundDepsCount_;
for (var i = 0; i < l; i++) {
var dep = observing[i];
if (dep.diffValue_ === 0) {
dep.diffValue_ = 1;
if (i0 !== i) observing[i0] = dep;
i0++;
} // Upcast is 'safe' here, because if dep is IObservable, `dependenciesState` will be undefined,
// not hitting the condition
if (dep.dependenciesState_ > lowestNewObservingDerivationState) {
lowestNewObservingDerivationState = dep.dependenciesState_;
}
}
observing.length = i0;
derivation.newObserving_ = null; // newObserving shouldn't be needed outside tracking (statement moved down to work around FF bug, see #614)
// Go through all old observables and check diffValue: (it is unique after last bindDependencies)
// 0: it's not in new observables, unobserve it
// 1: it keeps being observed, don't want to notify it. change to 0
l = prevObserving.length;
while (l--) {
var _dep = prevObserving[l];
if (_dep.diffValue_ === 0) {
removeObserver(_dep, derivation);
}
_dep.diffValue_ = 0;
} // Go through all new observables and check diffValue: (now it should be unique)
// 0: it was set to 0 in last loop. don't need to do anything.
// 1: it wasn't observed, let's observe it. set back to 0
while (i0--) {
var _dep2 = observing[i0];
if (_dep2.diffValue_ === 1) {
_dep2.diffValue_ = 0;
addObserver(_dep2, derivation);
}
} // Some new observed derivations may become stale during this derivation computation
// so they have had no chance to propagate staleness (#916)
if (lowestNewObservingDerivationState !== IDerivationState_.UP_TO_DATE_) {
derivation.dependenciesState_ = lowestNewObservingDerivationState;
derivation.onBecomeStale_();
}
}
function clearObserving(derivation) {
// invariant(globalState.inBatch > 0, "INTERNAL ERROR clearObserving should be called only inside batch");
var obs = derivation.observing_;
derivation.observing_ = [];
var i = obs.length;
while (i--) {
removeObserver(obs[i], derivation);
}
derivation.dependenciesState_ = IDerivationState_.NOT_TRACKING_;
}
function untracked(action) {
var prev = untrackedStart();
try {
return action();
} finally {
untrackedEnd(prev);
}
}
function untrackedStart() {
var prev = globalState.trackingDerivation;
globalState.trackingDerivation = null;
return prev;
}
function untrackedEnd(prev) {
globalState.trackingDerivation = prev;
}
function allowStateReadsStart(allowStateReads) {
var prev = globalState.allowStateReads;
globalState.allowStateReads = allowStateReads;
return prev;
}
function allowStateReadsEnd(prev) {
globalState.allowStateReads = prev;
}
/**
* needed to keep `lowestObserverState` correct. when changing from (2 or 1) to 0
*
*/
function changeDependenciesStateTo0(derivation) {
if (derivation.dependenciesState_ === IDerivationState_.UP_TO_DATE_) return;
derivation.dependenciesState_ = IDerivationState_.UP_TO_DATE_;
var obs = derivation.observing_;
var i = obs.length;
while (i--) {
obs[i].lowestObserverState_ = IDerivationState_.UP_TO_DATE_;
}
}
/**
* These values will persist if global state is reset
*/
var persistentKeys = ["mobxGuid", "spyListeners", "enforceActions", "computedRequiresReaction", "reactionRequiresObservable", "observableRequiresReaction", "allowStateReads", "disableErrorBoundaries", "runId", "UNCHANGED", "useProxies"];
var MobXGlobals = function MobXGlobals() {
this.version = 6;
this.UNCHANGED = {};
this.tracki