UNPKG

27.8 kBJavaScriptView Raw
1import { Reaction, _allowStateChanges, _allowStateReadsStart, _allowStateReadsEnd, $mobx, createAtom, untracked, isObservableMap, isObservableObject, isObservableArray, observable } from 'mobx';
2import React__default, { PureComponent, Component, forwardRef, memo, createElement } from 'react';
3import { isUsingStaticRendering, Observer, observer as observer$1 } from 'mobx-react-lite';
4export { Observer, isUsingStaticRendering, observerBatching, useAsObservableSource, useLocalStore, useObserver, useStaticRendering } from 'mobx-react-lite';
5
6var symbolId = 0;
7
8function createSymbol(name) {
9 if (typeof Symbol === "function") {
10 return Symbol(name);
11 }
12
13 var symbol = "__$mobx-react " + name + " (" + symbolId + ")";
14 symbolId++;
15 return symbol;
16}
17
18var createdSymbols = {};
19function newSymbol(name) {
20 if (!createdSymbols[name]) {
21 createdSymbols[name] = createSymbol(name);
22 }
23
24 return createdSymbols[name];
25}
26function shallowEqual(objA, objB) {
27 //From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js
28 if (is(objA, objB)) return true;
29
30 if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
31 return false;
32 }
33
34 var keysA = Object.keys(objA);
35 var keysB = Object.keys(objB);
36 if (keysA.length !== keysB.length) return false;
37
38 for (var i = 0; i < keysA.length; i++) {
39 if (!Object.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
40 return false;
41 }
42 }
43
44 return true;
45}
46
47function is(x, y) {
48 // From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js
49 if (x === y) {
50 return x !== 0 || 1 / x === 1 / y;
51 } else {
52 return x !== x && y !== y;
53 }
54} // based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js
55
56
57var hoistBlackList = {
58 $$typeof: 1,
59 render: 1,
60 compare: 1,
61 type: 1,
62 childContextTypes: 1,
63 contextType: 1,
64 contextTypes: 1,
65 defaultProps: 1,
66 getDefaultProps: 1,
67 getDerivedStateFromError: 1,
68 getDerivedStateFromProps: 1,
69 mixins: 1,
70 propTypes: 1
71};
72function copyStaticProperties(base, target) {
73 var protoProps = Object.getOwnPropertyNames(Object.getPrototypeOf(base));
74 Object.getOwnPropertyNames(base).forEach(function (key) {
75 if (!hoistBlackList[key] && protoProps.indexOf(key) === -1) {
76 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(base, key));
77 }
78 });
79}
80/**
81 * Helper to set `prop` to `this` as non-enumerable (hidden prop)
82 * @param target
83 * @param prop
84 * @param value
85 */
86
87function setHiddenProp(target, prop, value) {
88 if (!Object.hasOwnProperty.call(target, prop)) {
89 Object.defineProperty(target, prop, {
90 enumerable: false,
91 configurable: true,
92 writable: true,
93 value: value
94 });
95 } else {
96 target[prop] = value;
97 }
98}
99/**
100 * Utilities for patching componentWillUnmount, to make sure @disposeOnUnmount works correctly icm with user defined hooks
101 * and the handler provided by mobx-react
102 */
103
104var mobxMixins =
105/*#__PURE__*/
106newSymbol("patchMixins");
107var mobxPatchedDefinition =
108/*#__PURE__*/
109newSymbol("patchedDefinition");
110
111function getMixins(target, methodName) {
112 var mixins = target[mobxMixins] = target[mobxMixins] || {};
113 var methodMixins = mixins[methodName] = mixins[methodName] || {};
114 methodMixins.locks = methodMixins.locks || 0;
115 methodMixins.methods = methodMixins.methods || [];
116 return methodMixins;
117}
118
119function wrapper(realMethod, mixins) {
120 var _this = this;
121
122 for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
123 args[_key - 2] = arguments[_key];
124 }
125
126 // locks are used to ensure that mixins are invoked only once per invocation, even on recursive calls
127 mixins.locks++;
128
129 try {
130 var retVal;
131
132 if (realMethod !== undefined && realMethod !== null) {
133 retVal = realMethod.apply(this, args);
134 }
135
136 return retVal;
137 } finally {
138 mixins.locks--;
139
140 if (mixins.locks === 0) {
141 mixins.methods.forEach(function (mx) {
142 mx.apply(_this, args);
143 });
144 }
145 }
146}
147
148function wrapFunction(realMethod, mixins) {
149 var fn = function fn() {
150 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
151 args[_key2] = arguments[_key2];
152 }
153
154 wrapper.call.apply(wrapper, [this, realMethod, mixins].concat(args));
155 };
156
157 return fn;
158}
159
160function patch(target, methodName, mixinMethod) {
161 var mixins = getMixins(target, methodName);
162
163 if (mixins.methods.indexOf(mixinMethod) < 0) {
164 mixins.methods.push(mixinMethod);
165 }
166
167 var oldDefinition = Object.getOwnPropertyDescriptor(target, methodName);
168
169 if (oldDefinition && oldDefinition[mobxPatchedDefinition]) {
170 // already patched definition, do not repatch
171 return;
172 }
173
174 var originalMethod = target[methodName];
175 var newDefinition = createDefinition(target, methodName, oldDefinition ? oldDefinition.enumerable : undefined, mixins, originalMethod);
176 Object.defineProperty(target, methodName, newDefinition);
177}
178
179function createDefinition(target, methodName, enumerable, mixins, originalMethod) {
180 var _ref;
181
182 var wrappedFunc = wrapFunction(originalMethod, mixins);
183 return _ref = {}, _ref[mobxPatchedDefinition] = true, _ref.get = function get() {
184 return wrappedFunc;
185 }, _ref.set = function set(value) {
186 if (this === target) {
187 wrappedFunc = wrapFunction(value, mixins);
188 } else {
189 // when it is an instance of the prototype/a child prototype patch that particular case again separately
190 // since we need to store separate values depending on wether it is the actual instance, the prototype, etc
191 // e.g. the method for super might not be the same as the method for the prototype which might be not the same
192 // as the method for the instance
193 var newDefinition = createDefinition(this, methodName, enumerable, mixins, value);
194 Object.defineProperty(this, methodName, newDefinition);
195 }
196 }, _ref.configurable = true, _ref.enumerable = enumerable, _ref;
197}
198
199var mobxAdminProperty = $mobx || "$mobx";
200var mobxObserverProperty =
201/*#__PURE__*/
202newSymbol("isMobXReactObserver");
203var mobxIsUnmounted =
204/*#__PURE__*/
205newSymbol("isUnmounted");
206var skipRenderKey =
207/*#__PURE__*/
208newSymbol("skipRender");
209var isForcingUpdateKey =
210/*#__PURE__*/
211newSymbol("isForcingUpdate");
212function makeClassComponentObserver(componentClass) {
213 var target = componentClass.prototype;
214
215 if (componentClass[mobxObserverProperty]) {
216 var displayName = getDisplayName(target);
217 console.warn("The provided component class (" + displayName + ") \n has already been declared as an observer component.");
218 } else {
219 componentClass[mobxObserverProperty] = true;
220 }
221
222 if (target.componentWillReact) throw new Error("The componentWillReact life-cycle event is no longer supported");
223
224 if (componentClass["__proto__"] !== PureComponent) {
225 if (!target.shouldComponentUpdate) target.shouldComponentUpdate = observerSCU;else if (target.shouldComponentUpdate !== observerSCU) // n.b. unequal check, instead of existence check, as @observer might be on superclass as well
226 throw new Error("It is not allowed to use shouldComponentUpdate in observer based components.");
227 } // this.props and this.state are made observable, just to make sure @computed fields that
228 // are defined inside the component, and which rely on state or props, re-compute if state or props change
229 // (otherwise the computed wouldn't update and become stale on props change, since props are not observable)
230 // However, this solution is not without it's own problems: https://github.com/mobxjs/mobx-react/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3Aobservable-props-or-not+
231
232
233 makeObservableProp(target, "props");
234 makeObservableProp(target, "state");
235 var baseRender = target.render;
236
237 target.render = function () {
238 return makeComponentReactive.call(this, baseRender);
239 };
240
241 patch(target, "componentWillUnmount", function () {
242 var _this$render$mobxAdmi;
243
244 if (isUsingStaticRendering() === true) return;
245 (_this$render$mobxAdmi = this.render[mobxAdminProperty]) === null || _this$render$mobxAdmi === void 0 ? void 0 : _this$render$mobxAdmi.dispose();
246 this[mobxIsUnmounted] = true;
247
248 if (!this.render[mobxAdminProperty]) {
249 // Render may have been hot-swapped and/or overriden by a subclass.
250 var _displayName = getDisplayName(this);
251
252 console.warn("The reactive render of an observer class component (" + _displayName + ") \n was overriden after MobX attached. This may result in a memory leak if the \n overriden reactive render was not properly disposed.");
253 }
254 });
255 return componentClass;
256} // Generates a friendly name for debugging
257
258function getDisplayName(comp) {
259 return comp.displayName || comp.name || comp.constructor && (comp.constructor.displayName || comp.constructor.name) || "<component>";
260}
261
262function makeComponentReactive(render) {
263 var _this = this;
264
265 if (isUsingStaticRendering() === true) return render.call(this);
266 /**
267 * If props are shallowly modified, react will render anyway,
268 * so atom.reportChanged() should not result in yet another re-render
269 */
270
271 setHiddenProp(this, skipRenderKey, false);
272 /**
273 * forceUpdate will re-assign this.props. We don't want that to cause a loop,
274 * so detect these changes
275 */
276
277 setHiddenProp(this, isForcingUpdateKey, false);
278 var initialName = getDisplayName(this);
279 var baseRender = render.bind(this);
280 var isRenderingPending = false;
281 var reaction = new Reaction(initialName + ".render()", function () {
282 if (!isRenderingPending) {
283 // N.B. Getting here *before mounting* means that a component constructor has side effects (see the relevant test in misc.js)
284 // This unidiomatic React usage but React will correctly warn about this so we continue as usual
285 // See #85 / Pull #44
286 isRenderingPending = true;
287
288 if (_this[mobxIsUnmounted] !== true) {
289 var hasError = true;
290
291 try {
292 setHiddenProp(_this, isForcingUpdateKey, true);
293 if (!_this[skipRenderKey]) Component.prototype.forceUpdate.call(_this);
294 hasError = false;
295 } finally {
296 setHiddenProp(_this, isForcingUpdateKey, false);
297 if (hasError) reaction.dispose();
298 }
299 }
300 }
301 });
302 reaction["reactComponent"] = this;
303 reactiveRender[mobxAdminProperty] = reaction;
304 this.render = reactiveRender;
305
306 function reactiveRender() {
307 isRenderingPending = false;
308 var exception = undefined;
309 var rendering = undefined;
310 reaction.track(function () {
311 try {
312 rendering = _allowStateChanges(false, baseRender);
313 } catch (e) {
314 exception = e;
315 }
316 });
317
318 if (exception) {
319 throw exception;
320 }
321
322 return rendering;
323 }
324
325 return reactiveRender.call(this);
326}
327
328function observerSCU(nextProps, nextState) {
329 if (isUsingStaticRendering()) {
330 console.warn("[mobx-react] It seems that a re-rendering of a React component is triggered while in static (server-side) mode. Please make sure components are rendered only once server-side.");
331 } // update on any state changes (as is the default)
332
333
334 if (this.state !== nextState) {
335 return true;
336 } // update if props are shallowly not equal, inspired by PureRenderMixin
337 // we could return just 'false' here, and avoid the `skipRender` checks etc
338 // however, it is nicer if lifecycle events are triggered like usually,
339 // so we return true here if props are shallowly modified.
340
341
342 return !shallowEqual(this.props, nextProps);
343}
344
345function makeObservableProp(target, propName) {
346 var valueHolderKey = newSymbol("reactProp_" + propName + "_valueHolder");
347 var atomHolderKey = newSymbol("reactProp_" + propName + "_atomHolder");
348
349 function getAtom() {
350 if (!this[atomHolderKey]) {
351 setHiddenProp(this, atomHolderKey, createAtom("reactive " + propName));
352 }
353
354 return this[atomHolderKey];
355 }
356
357 Object.defineProperty(target, propName, {
358 configurable: true,
359 enumerable: true,
360 get: function get() {
361 var prevReadState = false;
362
363 if (_allowStateReadsStart && _allowStateReadsEnd) {
364 prevReadState = _allowStateReadsStart(true);
365 }
366
367 getAtom.call(this).reportObserved();
368
369 if (_allowStateReadsStart && _allowStateReadsEnd) {
370 _allowStateReadsEnd(prevReadState);
371 }
372
373 return this[valueHolderKey];
374 },
375 set: function set(v) {
376 if (!this[isForcingUpdateKey] && !shallowEqual(this[valueHolderKey], v)) {
377 setHiddenProp(this, valueHolderKey, v);
378 setHiddenProp(this, skipRenderKey, true);
379 getAtom.call(this).reportChanged();
380 setHiddenProp(this, skipRenderKey, false);
381 } else {
382 setHiddenProp(this, valueHolderKey, v);
383 }
384 }
385 });
386}
387
388var hasSymbol = typeof Symbol === "function" && Symbol.for; // Using react-is had some issues (and operates on elements, not on types), see #608 / #609
389
390var ReactForwardRefSymbol = hasSymbol ?
391/*#__PURE__*/
392Symbol.for("react.forward_ref") : typeof forwardRef === "function" &&
393/*#__PURE__*/
394forwardRef(function (props) {
395 return null;
396})["$$typeof"];
397var ReactMemoSymbol = hasSymbol ?
398/*#__PURE__*/
399Symbol.for("react.memo") : typeof memo === "function" &&
400/*#__PURE__*/
401memo(function (props) {
402 return null;
403})["$$typeof"];
404/**
405 * Observer function / decorator
406 */
407
408function observer(component) {
409 if (component["isMobxInjector"] === true) {
410 console.warn("Mobx observer: You are trying to use 'observer' on a component that already has 'inject'. Please apply 'observer' before applying 'inject'");
411 }
412
413 if (ReactMemoSymbol && component["$$typeof"] === ReactMemoSymbol) {
414 throw new Error("Mobx observer: You are trying to use 'observer' on a function component wrapped in either another observer or 'React.memo'. The observer already applies 'React.memo' for you.");
415 } // Unwrap forward refs into `<Observer>` component
416 // we need to unwrap the render, because it is the inner render that needs to be tracked,
417 // not the ForwardRef HoC
418
419
420 if (ReactForwardRefSymbol && component["$$typeof"] === ReactForwardRefSymbol) {
421 var baseRender = component["render"];
422 if (typeof baseRender !== "function") throw new Error("render property of ForwardRef was not a function");
423 return forwardRef(function ObserverForwardRef() {
424 var args = arguments;
425 return createElement(Observer, null, function () {
426 return baseRender.apply(undefined, args);
427 });
428 });
429 } // Function component
430
431
432 if (typeof component === "function" && (!component.prototype || !component.prototype.render) && !component["isReactClass"] && !Object.prototype.isPrototypeOf.call(Component, component)) {
433 return observer$1(component);
434 }
435
436 return makeClassComponentObserver(component);
437}
438
439function _extends() {
440 _extends = Object.assign || function (target) {
441 for (var i = 1; i < arguments.length; i++) {
442 var source = arguments[i];
443
444 for (var key in source) {
445 if (Object.prototype.hasOwnProperty.call(source, key)) {
446 target[key] = source[key];
447 }
448 }
449 }
450
451 return target;
452 };
453
454 return _extends.apply(this, arguments);
455}
456
457function _objectWithoutPropertiesLoose(source, excluded) {
458 if (source == null) return {};
459 var target = {};
460 var sourceKeys = Object.keys(source);
461 var key, i;
462
463 for (i = 0; i < sourceKeys.length; i++) {
464 key = sourceKeys[i];
465 if (excluded.indexOf(key) >= 0) continue;
466 target[key] = source[key];
467 }
468
469 return target;
470}
471
472var MobXProviderContext =
473/*#__PURE__*/
474React__default.createContext({});
475function Provider(props) {
476 var children = props.children,
477 stores = _objectWithoutPropertiesLoose(props, ["children"]);
478
479 var parentValue = React__default.useContext(MobXProviderContext);
480 var mutableProviderRef = React__default.useRef(_extends({}, parentValue, stores));
481 var value = mutableProviderRef.current;
482
483 if (process.env.NODE_ENV !== "production") {
484 var newValue = _extends({}, value, stores); // spread in previous state for the context based stores
485
486
487 if (!shallowEqual(value, newValue)) {
488 throw new Error("MobX Provider: The set of provided stores has changed. See: https://github.com/mobxjs/mobx-react#the-set-of-provided-stores-has-changed-error.");
489 }
490 }
491
492 return React__default.createElement(MobXProviderContext.Provider, {
493 value: value
494 }, children);
495}
496Provider.displayName = "MobXProvider";
497
498/**
499 * Store Injection
500 */
501
502function createStoreInjector(grabStoresFn, component, injectNames, makeReactive) {
503 // Support forward refs
504 var Injector = React__default.forwardRef(function (props, ref) {
505 var newProps = _extends({}, props);
506
507 var context = React__default.useContext(MobXProviderContext);
508 Object.assign(newProps, grabStoresFn(context || {}, newProps) || {});
509
510 if (ref) {
511 newProps.ref = ref;
512 }
513
514 return React__default.createElement(component, newProps);
515 });
516 if (makeReactive) Injector = observer(Injector);
517 Injector["isMobxInjector"] = true; // assigned late to suppress observer warning
518 // Static fields from component should be visible on the generated Injector
519
520 copyStaticProperties(component, Injector);
521 Injector["wrappedComponent"] = component;
522 Injector.displayName = getInjectName(component, injectNames);
523 return Injector;
524}
525
526function getInjectName(component, injectNames) {
527 var displayName;
528 var componentName = component.displayName || component.name || component.constructor && component.constructor.name || "Component";
529 if (injectNames) displayName = "inject-with-" + injectNames + "(" + componentName + ")";else displayName = "inject(" + componentName + ")";
530 return displayName;
531}
532
533function grabStoresByName(storeNames) {
534 return function (baseStores, nextProps) {
535 storeNames.forEach(function (storeName) {
536 if (storeName in nextProps // prefer props over stores
537 ) return;
538 if (!(storeName in baseStores)) throw new Error("MobX injector: Store '" + storeName + "' is not available! Make sure it is provided by some Provider");
539 nextProps[storeName] = baseStores[storeName];
540 });
541 return nextProps;
542 };
543}
544/**
545 * higher order component that injects stores to a child.
546 * takes either a varargs list of strings, which are stores read from the context,
547 * or a function that manually maps the available stores from the context to props:
548 * storesToProps(mobxStores, props, context) => newProps
549 */
550
551
552function inject() {
553 for (var _len = arguments.length, storeNames = new Array(_len), _key = 0; _key < _len; _key++) {
554 storeNames[_key] = arguments[_key];
555 }
556
557 if (typeof arguments[0] === "function") {
558 var grabStoresFn = arguments[0];
559 return function (componentClass) {
560 return createStoreInjector(grabStoresFn, componentClass, grabStoresFn.name, true);
561 };
562 } else {
563 return function (componentClass) {
564 return createStoreInjector(grabStoresByName(storeNames), componentClass, storeNames.join("-"), false);
565 };
566 }
567}
568
569var protoStoreKey =
570/*#__PURE__*/
571newSymbol("disposeOnUnmountProto");
572var instStoreKey =
573/*#__PURE__*/
574newSymbol("disposeOnUnmountInst");
575
576function runDisposersOnWillUnmount() {
577 var _this = this;
578 [].concat(this[protoStoreKey] || [], this[instStoreKey] || []).forEach(function (propKeyOrFunction) {
579 var prop = typeof propKeyOrFunction === "string" ? _this[propKeyOrFunction] : propKeyOrFunction;
580
581 if (prop !== undefined && prop !== null) {
582 if (Array.isArray(prop)) prop.map(function (f) {
583 return f();
584 });else prop();
585 }
586 });
587}
588
589function disposeOnUnmount(target, propertyKeyOrFunction) {
590 if (Array.isArray(propertyKeyOrFunction)) {
591 return propertyKeyOrFunction.map(function (fn) {
592 return disposeOnUnmount(target, fn);
593 });
594 }
595
596 var c = Object.getPrototypeOf(target).constructor;
597 var c2 = Object.getPrototypeOf(target.constructor); // Special case for react-hot-loader
598
599 var c3 = Object.getPrototypeOf(Object.getPrototypeOf(target));
600
601 if (!(c === React__default.Component || c === React__default.PureComponent || c2 === React__default.Component || c2 === React__default.PureComponent || c3 === React__default.Component || c3 === React__default.PureComponent)) {
602 throw new Error("[mobx-react] disposeOnUnmount only supports direct subclasses of React.Component or React.PureComponent.");
603 }
604
605 if (typeof propertyKeyOrFunction !== "string" && typeof propertyKeyOrFunction !== "function" && !Array.isArray(propertyKeyOrFunction)) {
606 throw new Error("[mobx-react] disposeOnUnmount only works if the parameter is either a property key or a function.");
607 } // decorator's target is the prototype, so it doesn't have any instance properties like props
608
609
610 var isDecorator = typeof propertyKeyOrFunction === "string"; // add property key / function we want run (disposed) to the store
611
612 var componentWasAlreadyModified = !!target[protoStoreKey] || !!target[instStoreKey];
613 var store = isDecorator ? // decorators are added to the prototype store
614 target[protoStoreKey] || (target[protoStoreKey] = []) : // functions are added to the instance store
615 target[instStoreKey] || (target[instStoreKey] = []);
616 store.push(propertyKeyOrFunction); // tweak the component class componentWillUnmount if not done already
617
618 if (!componentWasAlreadyModified) {
619 patch(target, "componentWillUnmount", runDisposersOnWillUnmount);
620 } // return the disposer as is if invoked as a non decorator
621
622
623 if (typeof propertyKeyOrFunction !== "string") {
624 return propertyKeyOrFunction;
625 }
626}
627
628function createChainableTypeChecker(validator) {
629 function checkType(isRequired, props, propName, componentName, location, propFullName) {
630 for (var _len = arguments.length, rest = new Array(_len > 6 ? _len - 6 : 0), _key = 6; _key < _len; _key++) {
631 rest[_key - 6] = arguments[_key];
632 }
633
634 return untracked(function () {
635 componentName = componentName || "<<anonymous>>";
636 propFullName = propFullName || propName;
637
638 if (props[propName] == null) {
639 if (isRequired) {
640 var actual = props[propName] === null ? "null" : "undefined";
641 return new Error("The " + location + " `" + propFullName + "` is marked as required " + "in `" + componentName + "`, but its value is `" + actual + "`.");
642 }
643
644 return null;
645 } else {
646 // @ts-ignore rest arg is necessary for some React internals - fails tests otherwise
647 return validator.apply(void 0, [props, propName, componentName, location, propFullName].concat(rest));
648 }
649 });
650 }
651
652 var chainedCheckType = checkType.bind(null, false); // Add isRequired to satisfy Requirable
653
654 chainedCheckType.isRequired = checkType.bind(null, true);
655 return chainedCheckType;
656} // Copied from React.PropTypes
657
658
659function isSymbol(propType, propValue) {
660 // Native Symbol.
661 if (propType === "symbol") {
662 return true;
663 } // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
664
665
666 if (propValue["@@toStringTag"] === "Symbol") {
667 return true;
668 } // Fallback for non-spec compliant Symbols which are polyfilled.
669
670
671 if (typeof Symbol === "function" && propValue instanceof Symbol) {
672 return true;
673 }
674
675 return false;
676} // Copied from React.PropTypes
677
678
679function getPropType(propValue) {
680 var propType = typeof propValue;
681
682 if (Array.isArray(propValue)) {
683 return "array";
684 }
685
686 if (propValue instanceof RegExp) {
687 // Old webkits (at least until Android 4.0) return 'function' rather than
688 // 'object' for typeof a RegExp. We'll normalize this here so that /bla/
689 // passes PropTypes.object.
690 return "object";
691 }
692
693 if (isSymbol(propType, propValue)) {
694 return "symbol";
695 }
696
697 return propType;
698} // This handles more types than `getPropType`. Only used for error messages.
699// Copied from React.PropTypes
700
701
702function getPreciseType(propValue) {
703 var propType = getPropType(propValue);
704
705 if (propType === "object") {
706 if (propValue instanceof Date) {
707 return "date";
708 } else if (propValue instanceof RegExp) {
709 return "regexp";
710 }
711 }
712
713 return propType;
714}
715
716function createObservableTypeCheckerCreator(allowNativeType, mobxType) {
717 return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) {
718 return untracked(function () {
719 if (allowNativeType) {
720 if (getPropType(props[propName]) === mobxType.toLowerCase()) return null;
721 }
722
723 var mobxChecker;
724
725 switch (mobxType) {
726 case "Array":
727 mobxChecker = isObservableArray;
728 break;
729
730 case "Object":
731 mobxChecker = isObservableObject;
732 break;
733
734 case "Map":
735 mobxChecker = isObservableMap;
736 break;
737
738 default:
739 throw new Error("Unexpected mobxType: " + mobxType);
740 }
741
742 var propValue = props[propName];
743
744 if (!mobxChecker(propValue)) {
745 var preciseType = getPreciseType(propValue);
746 var nativeTypeExpectationMessage = allowNativeType ? " or javascript `" + mobxType.toLowerCase() + "`" : "";
747 return new Error("Invalid prop `" + propFullName + "` of type `" + preciseType + "` supplied to" + " `" + componentName + "`, expected `mobx.Observable" + mobxType + "`" + nativeTypeExpectationMessage + ".");
748 }
749
750 return null;
751 });
752 });
753}
754
755function createObservableArrayOfTypeChecker(allowNativeType, typeChecker) {
756 return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) {
757 for (var _len2 = arguments.length, rest = new Array(_len2 > 5 ? _len2 - 5 : 0), _key2 = 5; _key2 < _len2; _key2++) {
758 rest[_key2 - 5] = arguments[_key2];
759 }
760
761 return untracked(function () {
762 if (typeof typeChecker !== "function") {
763 return new Error("Property `" + propFullName + "` of component `" + componentName + "` has " + "invalid PropType notation.");
764 } else {
765 var error = createObservableTypeCheckerCreator(allowNativeType, "Array")(props, propName, componentName, location, propFullName);
766 if (error instanceof Error) return error;
767 var propValue = props[propName];
768
769 for (var i = 0; i < propValue.length; i++) {
770 error = typeChecker.apply(void 0, [propValue, i, componentName, location, propFullName + "[" + i + "]"].concat(rest));
771 if (error instanceof Error) return error;
772 }
773
774 return null;
775 }
776 });
777 });
778}
779
780var observableArray =
781/*#__PURE__*/
782createObservableTypeCheckerCreator(false, "Array");
783var observableArrayOf =
784/*#__PURE__*/
785createObservableArrayOfTypeChecker.bind(null, false);
786var observableMap =
787/*#__PURE__*/
788createObservableTypeCheckerCreator(false, "Map");
789var observableObject =
790/*#__PURE__*/
791createObservableTypeCheckerCreator(false, "Object");
792var arrayOrObservableArray =
793/*#__PURE__*/
794createObservableTypeCheckerCreator(true, "Array");
795var arrayOrObservableArrayOf =
796/*#__PURE__*/
797createObservableArrayOfTypeChecker.bind(null, true);
798var objectOrObservableObject =
799/*#__PURE__*/
800createObservableTypeCheckerCreator(true, "Object");
801var PropTypes = {
802 observableArray: observableArray,
803 observableArrayOf: observableArrayOf,
804 observableMap: observableMap,
805 observableObject: observableObject,
806 arrayOrObservableArray: arrayOrObservableArray,
807 arrayOrObservableArrayOf: arrayOrObservableArrayOf,
808 objectOrObservableObject: objectOrObservableObject
809};
810
811if (!Component) throw new Error("mobx-react requires React to be available");
812if (!observable) throw new Error("mobx-react requires mobx to be available");
813
814export { MobXProviderContext, PropTypes, Provider, disposeOnUnmount, inject, observer };
815//# sourceMappingURL=mobxreact.esm.js.map