mobx-react
Advanced tools
Comparing version 7.6.0 to 8.0.0
# mobx-react | ||
## 8.0.0 | ||
### Major Changes | ||
- [`44a2cf42`](https://github.com/mobxjs/mobx/commit/44a2cf42dec7635f639ddbfb19202ebc710bac54) [#3590](https://github.com/mobxjs/mobx/pull/3590) Thanks [@urugator](https://github.com/urugator)! - Functional components now use `useSyncExternalStore`, which should prevent tearing - you have to update mobx, otherwise it should behave as previously.<br> | ||
Improved displayName/name handling of functional components as discussed in #3438.<br> | ||
Reactions of uncommited class components are now correctly disposed, fixes #3492.<br> | ||
Reactions don't notify uncommited class components, avoiding the warning, fixes #3492.<br> | ||
Removed symbol "polyfill" and replaced with actual Symbols.<br> | ||
Removed `this.render` replacement detection + warning. `this.render` is no longer configurable/writable (possibly BC).<br> | ||
Class component instance is no longer exposed as `component[$mobx]["reactcomponent"]` (possibly BC).<br> | ||
Deprecated `disposeOnUnmount`, it's not compatible with remounting.<br> | ||
### Patch Changes | ||
- Updated dependencies [[`44a2cf42`](https://github.com/mobxjs/mobx/commit/44a2cf42dec7635f639ddbfb19202ebc710bac54)]: | ||
- mobx-react-lite@4.0.0 | ||
## 7.6.0 | ||
@@ -4,0 +22,0 @@ |
import React from "react"; | ||
declare type Disposer = () => void; | ||
/** | ||
* @deprecated `disposeOnUnmount` is not compatible with React 18 and higher. | ||
*/ | ||
export declare function disposeOnUnmount(target: React.Component<any, any>, propertyKey: PropertyKey): void; | ||
/** | ||
* @deprecated `disposeOnUnmount` is not compatible with React 18 and higher. | ||
*/ | ||
export declare function disposeOnUnmount<TF extends Disposer | Array<Disposer>>(target: React.Component<any, any>, fn: TF): TF; | ||
export {}; |
@@ -12,22 +12,2 @@ 'use strict'; | ||
var symbolId = 0; | ||
function createSymbol(name) { | ||
if (typeof Symbol === "function") { | ||
return Symbol(name); | ||
} | ||
var symbol = "__$mobx-react " + name + " (" + symbolId + ")"; | ||
symbolId++; | ||
return symbol; | ||
} | ||
var createdSymbols = {}; | ||
function newSymbol(name) { | ||
if (!createdSymbols[name]) { | ||
createdSymbols[name] = createSymbol(name); | ||
} | ||
return createdSymbols[name]; | ||
} | ||
function shallowEqual(objA, objB) { | ||
@@ -38,14 +18,10 @@ //From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js | ||
} | ||
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) { | ||
return false; | ||
} | ||
var keysA = Object.keys(objA); | ||
var keysB = Object.keys(objB); | ||
if (keysA.length !== keysB.length) { | ||
return false; | ||
} | ||
for (var i = 0; i < keysA.length; i++) { | ||
@@ -56,6 +32,4 @@ if (!Object.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { | ||
} | ||
return true; | ||
} | ||
function is(x, y) { | ||
@@ -68,5 +42,4 @@ // From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js | ||
} | ||
} // based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js | ||
} | ||
// based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js | ||
var hoistBlackList = { | ||
@@ -97,28 +70,7 @@ $$typeof: 1, | ||
/** | ||
* Helper to set `prop` to `this` as non-enumerable (hidden prop) | ||
* @param target | ||
* @param prop | ||
* @param value | ||
*/ | ||
function setHiddenProp(target, prop, value) { | ||
if (!Object.hasOwnProperty.call(target, prop)) { | ||
Object.defineProperty(target, prop, { | ||
enumerable: false, | ||
configurable: true, | ||
writable: true, | ||
value: value | ||
}); | ||
} else { | ||
target[prop] = value; | ||
} | ||
} | ||
/** | ||
* Utilities for patching componentWillUnmount, to make sure @disposeOnUnmount works correctly icm with user defined hooks | ||
* and the handler provided by mobx-react | ||
*/ | ||
var mobxMixins = /*#__PURE__*/newSymbol("patchMixins"); | ||
var mobxPatchedDefinition = /*#__PURE__*/newSymbol("patchedDefinition"); | ||
var mobxMixins = /*#__PURE__*/Symbol("patchMixins"); | ||
var mobxPatchedDefinition = /*#__PURE__*/Symbol("patchedDefinition"); | ||
function getMixins(target, methodName) { | ||
@@ -131,24 +83,17 @@ var mixins = target[mobxMixins] = target[mobxMixins] || {}; | ||
} | ||
function wrapper(realMethod, mixins) { | ||
var _this = this; | ||
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { | ||
args[_key - 2] = arguments[_key]; | ||
} | ||
// locks are used to ensure that mixins are invoked only once per invocation, even on recursive calls | ||
mixins.locks++; | ||
try { | ||
var retVal; | ||
if (realMethod !== undefined && realMethod !== null) { | ||
retVal = realMethod.apply(this, args); | ||
} | ||
return retVal; | ||
} finally { | ||
mixins.locks--; | ||
if (mixins.locks === 0) { | ||
@@ -161,3 +106,2 @@ mixins.methods.forEach(function (mx) { | ||
} | ||
function wrapFunction(realMethod, mixins) { | ||
@@ -168,18 +112,12 @@ var fn = function fn() { | ||
} | ||
wrapper.call.apply(wrapper, [this, realMethod, mixins].concat(args)); | ||
}; | ||
return fn; | ||
} | ||
function patch(target, methodName, mixinMethod) { | ||
var mixins = getMixins(target, methodName); | ||
if (mixins.methods.indexOf(mixinMethod) < 0) { | ||
mixins.methods.push(mixinMethod); | ||
} | ||
var oldDefinition = Object.getOwnPropertyDescriptor(target, methodName); | ||
if (oldDefinition && oldDefinition[mobxPatchedDefinition]) { | ||
@@ -189,3 +127,2 @@ // already patched definition, do not repatch | ||
} | ||
var originalMethod = target[methodName]; | ||
@@ -195,6 +132,4 @@ var newDefinition = createDefinition(target, methodName, oldDefinition ? oldDefinition.enumerable : undefined, mixins, originalMethod); | ||
} | ||
function createDefinition(target, methodName, enumerable, mixins, originalMethod) { | ||
var _ref; | ||
var wrappedFunc = wrapFunction(originalMethod, mixins); | ||
@@ -217,233 +152,219 @@ return _ref = {}, _ref[mobxPatchedDefinition] = true, _ref.get = function get() { | ||
var mobxAdminProperty = mobx.$mobx || "$mobx"; // BC | ||
var mobxObserverProperty = /*#__PURE__*/newSymbol("isMobXReactObserver"); | ||
var mobxIsUnmounted = /*#__PURE__*/newSymbol("isUnmounted"); | ||
var skipRenderKey = /*#__PURE__*/newSymbol("skipRender"); | ||
var isForcingUpdateKey = /*#__PURE__*/newSymbol("isForcingUpdate"); | ||
var administrationSymbol = /*#__PURE__*/Symbol("ObserverAdministration"); | ||
var isMobXReactObserverSymbol = /*#__PURE__*/Symbol("isMobXReactObserver"); | ||
function getAdministration(component) { | ||
var _component$administra; | ||
// We create administration lazily, because we can't patch constructor | ||
// and the exact moment of initialization partially depends on React internals. | ||
// At the time of writing this, the first thing invoked is one of the observable getter/setter (state/props/context). | ||
return (_component$administra = component[administrationSymbol]) != null ? _component$administra : component[administrationSymbol] = { | ||
reaction: null, | ||
mounted: false, | ||
forceUpdate: null, | ||
name: getDisplayName(component.constructor), | ||
state: undefined, | ||
props: undefined, | ||
context: undefined, | ||
propsAtom: mobx.createAtom("props"), | ||
stateAtom: mobx.createAtom("state"), | ||
contextAtom: mobx.createAtom("context"), | ||
isUpdating: false | ||
}; | ||
} | ||
function makeClassComponentObserver(componentClass) { | ||
var target = componentClass.prototype; | ||
if (componentClass[mobxObserverProperty]) { | ||
var displayName = getDisplayName(target); | ||
var prototype = componentClass.prototype; | ||
if (componentClass[isMobXReactObserverSymbol]) { | ||
var displayName = getDisplayName(componentClass); | ||
console.warn("The provided component class (" + displayName + ")\n has already been declared as an observer component."); | ||
} else { | ||
componentClass[mobxObserverProperty] = true; | ||
componentClass[isMobXReactObserverSymbol] = true; | ||
} | ||
if (target.componentWillReact) { | ||
if (prototype.componentWillReact) { | ||
throw new Error("The componentWillReact life-cycle event is no longer supported"); | ||
} | ||
if (componentClass["__proto__"] !== React.PureComponent) { | ||
if (!target.shouldComponentUpdate) { | ||
target.shouldComponentUpdate = observerSCU; | ||
} else if (target.shouldComponentUpdate !== observerSCU) { | ||
if (!prototype.shouldComponentUpdate) { | ||
prototype.shouldComponentUpdate = observerSCU; | ||
} else if (prototype.shouldComponentUpdate !== observerSCU) { | ||
// n.b. unequal check, instead of existence check, as @observer might be on superclass as well | ||
throw new Error("It is not allowed to use shouldComponentUpdate in observer based components."); | ||
} | ||
} // this.props and this.state are made observable, just to make sure @computed fields that | ||
} | ||
// this.props and this.state are made observable, just to make sure @computed fields that | ||
// are defined inside the component, and which rely on state or props, re-compute if state or props change | ||
// (otherwise the computed wouldn't update and become stale on props change, since props are not observable) | ||
// 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+ | ||
makeObservableProp(target, "props"); | ||
makeObservableProp(target, "state"); | ||
if (componentClass.contextType) { | ||
makeObservableProp(target, "context"); | ||
} | ||
var originalRender = target.render; | ||
Object.defineProperties(prototype, { | ||
props: observablePropsDescriptor, | ||
state: observableStateDescriptor, | ||
context: observableContextDescriptor | ||
}); | ||
var originalRender = prototype.render; | ||
if (typeof originalRender !== "function") { | ||
var _displayName = getDisplayName(target); | ||
var _displayName = getDisplayName(componentClass); | ||
throw new Error("[mobx-react] class component (" + _displayName + ") is missing `render` method." + "\n`observer` requires `render` being a function defined on prototype." + "\n`render = () => {}` or `render = function() {}` is not supported."); | ||
} | ||
target.render = function () { | ||
this.render = mobxReactLite.isUsingStaticRendering() ? originalRender : createReactiveRender.call(this, originalRender); | ||
prototype.render = function () { | ||
Object.defineProperty(this, "render", { | ||
// There is no safe way to replace render, therefore it's forbidden. | ||
configurable: false, | ||
writable: false, | ||
value: mobxReactLite.isUsingStaticRendering() ? originalRender : createReactiveRender.call(this, originalRender) | ||
}); | ||
return this.render(); | ||
}; | ||
patch(target, "componentDidMount", function () { | ||
this[mobxIsUnmounted] = false; | ||
if (!this.render[mobxAdminProperty]) { | ||
// Reaction is re-created automatically during render, but a component can re-mount and skip render #3395. | ||
// To re-create the reaction and re-subscribe to relevant observables we have to force an update. | ||
React.Component.prototype.forceUpdate.call(this); | ||
patch(prototype, "componentDidMount", function () { | ||
var _this = this; | ||
// `componentDidMount` may not be called at all. React can abandon the instance after `render`. | ||
// That's why we use finalization registry to dispose reaction created during render. | ||
// Happens with `<Suspend>` see #3492 | ||
// | ||
// `componentDidMount` can be called immediately after `componentWillUnmount` without calling `render` in between. | ||
// Happens with `<StrictMode>`see #3395. | ||
// | ||
// If `componentDidMount` is called, it's guaranteed to run synchronously with render (similary to `useLayoutEffect`). | ||
// Therefore we don't have to worry about external (observable) state being updated before mount (no state version checking). | ||
// | ||
// Things may change: "In the future, React will provide a feature that lets components preserve state between unmounts" | ||
var admin = getAdministration(this); | ||
admin.mounted = true; | ||
// Component instance committed, prevent reaction disposal. | ||
mobxReactLite._observerFinalizationRegistry.unregister(admin); | ||
// We don't set forceUpdate before mount because it requires a reference to `this`, | ||
// therefore `this` could NOT be garbage collected before mount, | ||
// preventing reaction disposal by FinalizationRegistry and leading to memory leak. | ||
// As an alternative we could have `admin.instanceRef = new WeakRef(this)`, but lets avoid it if possible. | ||
admin.forceUpdate = function () { | ||
return _this.forceUpdate(); | ||
}; | ||
if (!admin.reaction) { | ||
// 1. Instance was unmounted (reaction disposed) and immediately remounted without running render #3395. | ||
// 2. Reaction was disposed by finalization registry before mount. Shouldn't ever happen for class components: | ||
// `componentDidMount` runs synchronously after render, but our registry are deferred (can't run in between). | ||
// In any case we lost subscriptions to observables, so we have to create new reaction and re-render to resubscribe. | ||
// The reaction will be created lazily by following render. | ||
admin.forceUpdate(); | ||
} | ||
}); | ||
patch(target, "componentWillUnmount", function () { | ||
patch(prototype, "componentWillUnmount", function () { | ||
var _admin$reaction; | ||
if (mobxReactLite.isUsingStaticRendering()) { | ||
return; | ||
} | ||
var reaction = this.render[mobxAdminProperty]; | ||
if (reaction) { | ||
reaction.dispose(); // Forces reaction to be re-created on next render | ||
this.render[mobxAdminProperty] = null; | ||
} else { | ||
// Render may have been hot-swapped and/or overridden by a subclass. | ||
var _displayName2 = getDisplayName(this); | ||
console.warn("The reactive render of an observer class component (" + _displayName2 + ")\n was overridden after MobX attached. This may result in a memory leak if the\n overridden reactive render was not properly disposed."); | ||
} | ||
this[mobxIsUnmounted] = true; | ||
var admin = getAdministration(this); | ||
(_admin$reaction = admin.reaction) == null ? void 0 : _admin$reaction.dispose(); | ||
admin.reaction = null; | ||
admin.forceUpdate = null; | ||
admin.mounted = false; | ||
}); | ||
return componentClass; | ||
} // Generates a friendly name for debugging | ||
function getDisplayName(comp) { | ||
return comp.displayName || comp.name || comp.constructor && (comp.constructor.displayName || comp.constructor.name) || "<component>"; | ||
} | ||
// Generates a friendly name for debugging | ||
function getDisplayName(componentClass) { | ||
return componentClass.displayName || componentClass.name || "<component>"; | ||
} | ||
function createReactiveRender(originalRender) { | ||
var _this = this; | ||
/** | ||
* If props are shallowly modified, react will render anyway, | ||
* so atom.reportChanged() should not result in yet another re-render | ||
*/ | ||
setHiddenProp(this, skipRenderKey, false); | ||
/** | ||
* forceUpdate will re-assign this.props. We don't want that to cause a loop, | ||
* so detect these changes | ||
*/ | ||
setHiddenProp(this, isForcingUpdateKey, false); | ||
var initialName = getDisplayName(this); | ||
var boundOriginalRender = originalRender.bind(this); | ||
var isRenderingPending = false; | ||
var createReaction = function createReaction() { | ||
var reaction = new mobx.Reaction(initialName + ".render()", function () { | ||
if (!isRenderingPending) { | ||
// N.B. Getting here *before mounting* means that a component constructor has side effects (see the relevant test in misc.test.tsx) | ||
// This unidiomatic React usage but React will correctly warn about this so we continue as usual | ||
// See #85 / Pull #44 | ||
isRenderingPending = true; | ||
if (_this[mobxIsUnmounted] !== true) { | ||
var hasError = true; | ||
try { | ||
setHiddenProp(_this, isForcingUpdateKey, true); | ||
if (!_this[skipRenderKey]) { | ||
React.Component.prototype.forceUpdate.call(_this); | ||
} | ||
hasError = false; | ||
} finally { | ||
setHiddenProp(_this, isForcingUpdateKey, false); | ||
if (hasError) { | ||
reaction.dispose(); // Forces reaction to be re-created on next render | ||
_this.render[mobxAdminProperty] = null; | ||
} | ||
} | ||
} | ||
var admin = getAdministration(this); | ||
function reactiveRender() { | ||
if (!admin.reaction) { | ||
// Create reaction lazily to support re-mounting #3395 | ||
admin.reaction = createReaction(admin); | ||
if (!admin.mounted) { | ||
// React can abandon this instance and never call `componentDidMount`/`componentWillUnmount`, | ||
// we have to make sure reaction will be disposed. | ||
mobxReactLite._observerFinalizationRegistry.register(this, admin, this); | ||
} | ||
}); | ||
reaction["reactComponent"] = _this; | ||
return reaction; | ||
}; | ||
function reactiveRender() { | ||
var _reactiveRender$mobxA; | ||
isRenderingPending = false; // Create reaction lazily to support re-mounting #3395 | ||
var reaction = (_reactiveRender$mobxA = reactiveRender[mobxAdminProperty]) != null ? _reactiveRender$mobxA : reactiveRender[mobxAdminProperty] = createReaction(); | ||
var exception = undefined; | ||
var rendering = undefined; | ||
reaction.track(function () { | ||
} | ||
var error = undefined; | ||
var renderResult = undefined; | ||
admin.reaction.track(function () { | ||
try { | ||
// TODO@major | ||
// Optimization: replace with _allowStateChangesStart/End (not available in mobx@6.0.0) | ||
rendering = mobx._allowStateChanges(false, boundOriginalRender); | ||
renderResult = mobx._allowStateChanges(false, boundOriginalRender); | ||
} catch (e) { | ||
exception = e; | ||
error = e; | ||
} | ||
}); | ||
if (exception) { | ||
throw exception; | ||
if (error) { | ||
throw error; | ||
} | ||
return rendering; | ||
return renderResult; | ||
} | ||
return reactiveRender; | ||
} | ||
function createReaction(admin) { | ||
return new mobx.Reaction(admin.name + ".render()", function () { | ||
if (admin.isUpdating) { | ||
// Reaction is suppressed when setting new state/props/context, | ||
// this is when component is already being updated. | ||
return; | ||
} | ||
if (!admin.mounted) { | ||
// This is neccessary to avoid react warning about calling forceUpdate on component that isn't mounted yet. | ||
// This happens when component is abandoned after render - our reaction is already created and reacts to changes. | ||
// Due to the synchronous nature of `componenDidMount`, we don't have to worry that component could eventually mount and require update. | ||
return; | ||
} | ||
try { | ||
// forceUpdate sets new `props`, since we made it observable, it would `reportChanged`, causing a loop. | ||
admin.isUpdating = true; | ||
admin.forceUpdate == null ? void 0 : admin.forceUpdate(); | ||
} catch (error) { | ||
var _admin$reaction2; | ||
(_admin$reaction2 = admin.reaction) == null ? void 0 : _admin$reaction2.dispose(); | ||
admin.reaction = null; | ||
} finally { | ||
admin.isUpdating = false; | ||
} | ||
}); | ||
} | ||
function observerSCU(nextProps, nextState) { | ||
if (mobxReactLite.isUsingStaticRendering()) { | ||
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."); | ||
} // update on any state changes (as is the default) | ||
} | ||
// update on any state changes (as is the default) | ||
if (this.state !== nextState) { | ||
return true; | ||
} // update if props are shallowly not equal, inspired by PureRenderMixin | ||
} | ||
// update if props are shallowly not equal, inspired by PureRenderMixin | ||
// we could return just 'false' here, and avoid the `skipRender` checks etc | ||
// however, it is nicer if lifecycle events are triggered like usually, | ||
// so we return true here if props are shallowly modified. | ||
return !shallowEqual(this.props, nextProps); | ||
} | ||
function makeObservableProp(target, propName) { | ||
var valueHolderKey = newSymbol("reactProp_" + propName + "_valueHolder"); | ||
var atomHolderKey = newSymbol("reactProp_" + propName + "_atomHolder"); | ||
function getAtom() { | ||
if (!this[atomHolderKey]) { | ||
setHiddenProp(this, atomHolderKey, mobx.createAtom("reactive " + propName)); | ||
} | ||
return this[atomHolderKey]; | ||
} | ||
Object.defineProperty(target, propName, { | ||
function createObservablePropDescriptor(key) { | ||
var atomKey = key + "Atom"; | ||
return { | ||
configurable: true, | ||
enumerable: true, | ||
get: function get() { | ||
var prevReadState = false; // Why this check? BC? | ||
// @ts-expect-error | ||
if (mobx._allowStateReadsStart && mobx._allowStateReadsEnd) { | ||
prevReadState = mobx._allowStateReadsStart(true); | ||
} | ||
getAtom.call(this).reportObserved(); // Why this check? BC? | ||
// @ts-expect-error | ||
if (mobx._allowStateReadsStart && mobx._allowStateReadsEnd) { | ||
mobx._allowStateReadsEnd(prevReadState); | ||
} | ||
return this[valueHolderKey]; | ||
var admin = getAdministration(this); | ||
var prevReadState = mobx._allowStateReadsStart(true); | ||
admin[atomKey].reportObserved(); | ||
mobx._allowStateReadsEnd(prevReadState); | ||
return admin[key]; | ||
}, | ||
set: function set(v) { | ||
if (!this[isForcingUpdateKey] && !shallowEqual(this[valueHolderKey], v)) { | ||
setHiddenProp(this, valueHolderKey, v); | ||
setHiddenProp(this, skipRenderKey, true); | ||
getAtom.call(this).reportChanged(); | ||
setHiddenProp(this, skipRenderKey, false); | ||
set: function set(value) { | ||
var admin = getAdministration(this); | ||
// forceUpdate issued by reaction sets new props. | ||
// It sets isUpdating to true to prevent loop. | ||
if (!admin.isUpdating && !shallowEqual(admin[key], value)) { | ||
admin[key] = value; | ||
// This notifies all observers including our component, | ||
// but we don't want to cause `forceUpdate`, because component is already updating, | ||
// therefore supress component reaction. | ||
admin.isUpdating = true; | ||
admin[atomKey].reportChanged(); | ||
admin.isUpdating = false; | ||
} else { | ||
setHiddenProp(this, valueHolderKey, v); | ||
admin[key] = value; | ||
} | ||
} | ||
}); | ||
}; | ||
} | ||
var observablePropsDescriptor = /*#__PURE__*/createObservablePropDescriptor("props"); | ||
var observableStateDescriptor = /*#__PURE__*/createObservablePropDescriptor("state"); | ||
var observableContextDescriptor = /*#__PURE__*/createObservablePropDescriptor("context"); | ||
@@ -453,3 +374,2 @@ /** | ||
*/ | ||
function observer(component) { | ||
@@ -459,3 +379,2 @@ if (component["isMobxInjector"] === true) { | ||
} | ||
if (Object.prototype.isPrototypeOf.call(React.Component, component) || Object.prototype.isPrototypeOf.call(React.PureComponent, component)) { | ||
@@ -471,6 +390,5 @@ // Class component | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
_extends = Object.assign ? Object.assign.bind() : function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
@@ -482,9 +400,6 @@ if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
} | ||
return target; | ||
}; | ||
return _extends.apply(this, arguments); | ||
} | ||
function _objectWithoutPropertiesLoose(source, excluded) { | ||
@@ -495,3 +410,2 @@ if (source == null) return {}; | ||
var key, i; | ||
for (i = 0; i < sourceKeys.length; i++) { | ||
@@ -502,3 +416,2 @@ key = sourceKeys[i]; | ||
} | ||
return target; | ||
@@ -511,12 +424,8 @@ } | ||
var children = props.children, | ||
stores = _objectWithoutPropertiesLoose(props, _excluded); | ||
stores = _objectWithoutPropertiesLoose(props, _excluded); | ||
var parentValue = React__default.useContext(MobXProviderContext); | ||
var mutableProviderRef = React__default.useRef(_extends({}, parentValue, stores)); | ||
var value = mutableProviderRef.current; | ||
{ | ||
var newValue = _extends({}, value, stores); // spread in previous state for the context based stores | ||
if (!shallowEqual(value, newValue)) { | ||
@@ -526,3 +435,2 @@ 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."); | ||
} | ||
return React__default.createElement(MobXProviderContext.Provider, { | ||
@@ -537,3 +445,2 @@ value: value | ||
*/ | ||
function createStoreInjector(grabStoresFn, component, injectNames, makeReactive) { | ||
@@ -543,10 +450,7 @@ // Support forward refs | ||
var newProps = _extends({}, props); | ||
var context = React__default.useContext(MobXProviderContext); | ||
Object.assign(newProps, grabStoresFn(context || {}, newProps) || {}); | ||
if (ref) { | ||
newProps.ref = ref; | ||
} | ||
return React__default.createElement(component, newProps); | ||
@@ -557,3 +461,2 @@ }); | ||
// Static fields from component should be visible on the generated Injector | ||
copyStaticProperties(component, Injector); | ||
@@ -564,3 +467,2 @@ Injector["wrappedComponent"] = component; | ||
} | ||
function getInjectName(component, injectNames) { | ||
@@ -572,3 +474,2 @@ var displayName; | ||
} | ||
function grabStoresByName(storeNames) { | ||
@@ -591,4 +492,2 @@ return function (baseStores, nextProps) { | ||
*/ | ||
function inject() { | ||
@@ -598,3 +497,2 @@ for (var _len = arguments.length, storeNames = new Array(_len), _key = 0; _key < _len; _key++) { | ||
} | ||
if (typeof arguments[0] === "function") { | ||
@@ -612,5 +510,6 @@ var grabStoresFn = arguments[0]; | ||
var protoStoreKey = /*#__PURE__*/newSymbol("disposeOnUnmountProto"); | ||
var instStoreKey = /*#__PURE__*/newSymbol("disposeOnUnmountInst"); | ||
var reactMajorVersion = /*#__PURE__*/Number.parseInt( /*#__PURE__*/React__default.version.split(".")[0]); | ||
var warnedAboutDisposeOnUnmountDeprecated = false; | ||
var protoStoreKey = /*#__PURE__*/Symbol("disposeOnUnmountProto"); | ||
var instStoreKey = /*#__PURE__*/Symbol("disposeOnUnmountInst"); | ||
function runDisposersOnWillUnmount() { | ||
@@ -620,3 +519,2 @@ var _this = this; | ||
var prop = typeof propKeyOrFunction === "string" ? _this[propKeyOrFunction] : propKeyOrFunction; | ||
if (prop !== undefined && prop !== null) { | ||
@@ -629,3 +527,5 @@ if (Array.isArray(prop)) prop.map(function (f) { | ||
} | ||
/** | ||
* @deprecated `disposeOnUnmount` is not compatible with React 18 and higher. | ||
*/ | ||
function disposeOnUnmount(target, propertyKeyOrFunction) { | ||
@@ -637,30 +537,35 @@ if (Array.isArray(propertyKeyOrFunction)) { | ||
} | ||
if (!warnedAboutDisposeOnUnmountDeprecated) { | ||
if (reactMajorVersion >= 18) { | ||
console.error("[mobx-react] disposeOnUnmount is not compatible with React 18 and higher. Don't use it."); | ||
} else { | ||
console.warn("[mobx-react] disposeOnUnmount is deprecated. It won't work correctly with React 18 and higher."); | ||
} | ||
warnedAboutDisposeOnUnmountDeprecated = true; | ||
} | ||
var c = Object.getPrototypeOf(target).constructor; | ||
var c2 = Object.getPrototypeOf(target.constructor); // Special case for react-hot-loader | ||
var c2 = Object.getPrototypeOf(target.constructor); | ||
// Special case for react-hot-loader | ||
var c3 = Object.getPrototypeOf(Object.getPrototypeOf(target)); | ||
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)) { | ||
throw new Error("[mobx-react] disposeOnUnmount only supports direct subclasses of React.Component or React.PureComponent."); | ||
} | ||
if (typeof propertyKeyOrFunction !== "string" && typeof propertyKeyOrFunction !== "function" && !Array.isArray(propertyKeyOrFunction)) { | ||
throw new Error("[mobx-react] disposeOnUnmount only works if the parameter is either a property key or a function."); | ||
} // decorator's target is the prototype, so it doesn't have any instance properties like props | ||
var isDecorator = typeof propertyKeyOrFunction === "string"; // add property key / function we want run (disposed) to the store | ||
} | ||
// decorator's target is the prototype, so it doesn't have any instance properties like props | ||
var isDecorator = typeof propertyKeyOrFunction === "string"; | ||
// add property key / function we want run (disposed) to the store | ||
var componentWasAlreadyModified = !!target[protoStoreKey] || !!target[instStoreKey]; | ||
var store = isDecorator ? // decorators are added to the prototype store | ||
target[protoStoreKey] || (target[protoStoreKey] = []) : // functions are added to the instance store | ||
var store = isDecorator ? | ||
// decorators are added to the prototype store | ||
target[protoStoreKey] || (target[protoStoreKey] = []) : | ||
// functions are added to the instance store | ||
target[instStoreKey] || (target[instStoreKey] = []); | ||
store.push(propertyKeyOrFunction); // tweak the component class componentWillUnmount if not done already | ||
store.push(propertyKeyOrFunction); | ||
// tweak the component class componentWillUnmount if not done already | ||
if (!componentWasAlreadyModified) { | ||
patch(target, "componentWillUnmount", runDisposersOnWillUnmount); | ||
} // return the disposer as is if invoked as a non decorator | ||
} | ||
// return the disposer as is if invoked as a non decorator | ||
if (typeof propertyKeyOrFunction !== "string") { | ||
@@ -671,2 +576,3 @@ return propertyKeyOrFunction; | ||
// Copied from React.PropTypes | ||
function createChainableTypeChecker(validator) { | ||
@@ -677,7 +583,5 @@ function checkType(isRequired, props, propName, componentName, location, propFullName) { | ||
} | ||
return mobx.untracked(function () { | ||
componentName = componentName || "<<anonymous>>"; | ||
propFullName = propFullName || propName; | ||
if (props[propName] == null) { | ||
@@ -688,3 +592,2 @@ if (isRequired) { | ||
} | ||
return null; | ||
@@ -697,10 +600,8 @@ } else { | ||
} | ||
var chainedCheckType = checkType.bind(null, false); // Add isRequired to satisfy Requirable | ||
var chainedCheckType = checkType.bind(null, false); | ||
// Add isRequired to satisfy Requirable | ||
chainedCheckType.isRequired = checkType.bind(null, true); | ||
return chainedCheckType; | ||
} // Copied from React.PropTypes | ||
} | ||
// Copied from React.PropTypes | ||
function isSymbol(propType, propValue) { | ||
@@ -710,25 +611,19 @@ // Native Symbol. | ||
return true; | ||
} // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' | ||
} | ||
// 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' | ||
if (propValue["@@toStringTag"] === "Symbol") { | ||
return true; | ||
} // Fallback for non-spec compliant Symbols which are polyfilled. | ||
} | ||
// Fallback for non-spec compliant Symbols which are polyfilled. | ||
if (typeof Symbol === "function" && propValue instanceof Symbol) { | ||
return true; | ||
} | ||
return false; | ||
} // Copied from React.PropTypes | ||
} | ||
// Copied from React.PropTypes | ||
function getPropType(propValue) { | ||
var propType = typeof propValue; | ||
if (Array.isArray(propValue)) { | ||
return "array"; | ||
} | ||
if (propValue instanceof RegExp) { | ||
@@ -740,15 +635,11 @@ // Old webkits (at least until Android 4.0) return 'function' rather than | ||
} | ||
if (isSymbol(propType, propValue)) { | ||
return "symbol"; | ||
} | ||
return propType; | ||
} // This handles more types than `getPropType`. Only used for error messages. | ||
} | ||
// This handles more types than `getPropType`. Only used for error messages. | ||
// Copied from React.PropTypes | ||
function getPreciseType(propValue) { | ||
var propType = getPropType(propValue); | ||
if (propType === "object") { | ||
@@ -761,6 +652,4 @@ if (propValue instanceof Date) { | ||
} | ||
return propType; | ||
} | ||
function createObservableTypeCheckerCreator(allowNativeType, mobxType) { | ||
@@ -772,5 +661,3 @@ return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) { | ||
} | ||
var mobxChecker; | ||
switch (mobxType) { | ||
@@ -780,17 +667,12 @@ case "Array": | ||
break; | ||
case "Object": | ||
mobxChecker = mobx.isObservableObject; | ||
break; | ||
case "Map": | ||
mobxChecker = mobx.isObservableMap; | ||
break; | ||
default: | ||
throw new Error("Unexpected mobxType: " + mobxType); | ||
} | ||
var propValue = props[propName]; | ||
if (!mobxChecker(propValue)) { | ||
@@ -801,3 +683,2 @@ var preciseType = getPreciseType(propValue); | ||
} | ||
return null; | ||
@@ -807,3 +688,2 @@ }); | ||
} | ||
function createObservableArrayOfTypeChecker(allowNativeType, typeChecker) { | ||
@@ -814,3 +694,2 @@ return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) { | ||
} | ||
return mobx.untracked(function () { | ||
@@ -823,3 +702,2 @@ if (typeof typeChecker !== "function") { | ||
var propValue = props[propName]; | ||
for (var i = 0; i < propValue.length; i++) { | ||
@@ -829,3 +707,2 @@ error = typeChecker.apply(void 0, [propValue, i, componentName, location, propFullName + "[" + i + "]"].concat(rest)); | ||
} | ||
return null; | ||
@@ -836,3 +713,2 @@ } | ||
} | ||
var observableArray = /*#__PURE__*/createObservableTypeCheckerCreator(false, "Array"); | ||
@@ -855,4 +731,8 @@ var observableArrayOf = /*#__PURE__*/createObservableArrayOfTypeChecker.bind(null, false); | ||
if (!React.Component) throw new Error("mobx-react requires React to be available"); | ||
if (!mobx.observable) throw new Error("mobx-react requires mobx to be available"); | ||
if (!React.Component) { | ||
throw new Error("mobx-react requires React to be available"); | ||
} | ||
if (!mobx.observable) { | ||
throw new Error("mobx-react requires mobx to be available"); | ||
} | ||
@@ -859,0 +739,0 @@ Object.defineProperty(exports, 'Observer', { |
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,r=require("mobx"),t=require("react"),n=(e=t)&&"object"==typeof e&&"default"in e?e.default:e,o=require("mobx-react-lite"),i=0,a={};function s(e){return a[e]||(a[e]=function(e){if("function"==typeof Symbol)return Symbol(e);var r="__$mobx-react "+e+" ("+i+")";return i++,r}(e)),a[e]}function c(e,r){if(u(e,r))return!0;if("object"!=typeof e||null===e||"object"!=typeof r||null===r)return!1;var t=Object.keys(e),n=Object.keys(r);if(t.length!==n.length)return!1;for(var o=0;o<t.length;o++)if(!Object.hasOwnProperty.call(r,t[o])||!u(e[t[o]],r[t[o]]))return!1;return!0}function u(e,r){return e===r?0!==e||1/e==1/r:e!=e&&r!=r}var l={$$typeof:1,render:1,compare:1,type:1,childContextTypes:1,contextType:1,contextTypes:1,defaultProps:1,getDefaultProps:1,getDerivedStateFromError:1,getDerivedStateFromProps:1,mixins:1,displayName:1,propTypes:1};function p(e,r,t){Object.hasOwnProperty.call(e,r)?e[r]=t:Object.defineProperty(e,r,{enumerable:!1,configurable:!0,writable:!0,value:t})}var f=s("patchMixins"),b=s("patchedDefinition");function d(e,r){for(var t=this,n=arguments.length,o=new Array(n>2?n-2:0),i=2;i<n;i++)o[i-2]=arguments[i];r.locks++;try{var a;return null!=e&&(a=e.apply(this,o)),a}finally{r.locks--,0===r.locks&&r.methods.forEach((function(e){e.apply(t,o)}))}}function y(e,r){return function(){for(var t=arguments.length,n=new Array(t),o=0;o<t;o++)n[o]=arguments[o];d.call.apply(d,[this,e,r].concat(n))}}function v(e,r,t){var n=function(e,r){var t=e[f]=e[f]||{},n=t[r]=t[r]||{};return n.locks=n.locks||0,n.methods=n.methods||[],n}(e,r);n.methods.indexOf(t)<0&&n.methods.push(t);var o=Object.getOwnPropertyDescriptor(e,r);if(!o||!o[b]){var i=function e(r,t,n,o,i){var a,s=y(i,o);return(a={})[b]=!0,a.get=function(){return s},a.set=function(i){if(this===r)s=y(i,o);else{var a=e(this,t,n,o,i);Object.defineProperty(this,t,a)}},a.configurable=!0,a.enumerable=n,a}(e,r,o?o.enumerable:void 0,n,e[r]);Object.defineProperty(e,r,i)}}var m=r.$mobx||"$mobx",h=s("isMobXReactObserver"),O=s("isUnmounted"),g=s("skipRender"),w=s("isForcingUpdate");function j(e){var r=e.prototype;if(e[h]){var n=x(r);console.warn("The provided component class ("+n+")\n has already been declared as an observer component.")}else e[h]=!0;if(r.componentWillReact)throw new Error("The componentWillReact life-cycle event is no longer supported");if(e.__proto__!==t.PureComponent)if(r.shouldComponentUpdate){if(r.shouldComponentUpdate!==S)throw new Error("It is not allowed to use shouldComponentUpdate in observer based components.")}else r.shouldComponentUpdate=S;C(r,"props"),C(r,"state"),e.contextType&&C(r,"context");var i=r.render;if("function"!=typeof i){var a=x(r);throw new Error("[mobx-react] class component ("+a+") is missing `render` method.\n`observer` requires `render` being a function defined on prototype.\n`render = () => {}` or `render = function() {}` is not supported.")}return r.render=function(){return this.render=o.isUsingStaticRendering()?i:P.call(this,i),this.render()},v(r,"componentDidMount",(function(){this[O]=!1,this.render[m]||t.Component.prototype.forceUpdate.call(this)})),v(r,"componentWillUnmount",(function(){if(!o.isUsingStaticRendering()){var e=this.render[m];if(e)e.dispose(),this.render[m]=null;else{var r=x(this);console.warn("The reactive render of an observer class component ("+r+")\n was overridden after MobX attached. This may result in a memory leak if the\n overridden reactive render was not properly disposed.")}this[O]=!0}})),e}function x(e){return e.displayName||e.name||e.constructor&&(e.constructor.displayName||e.constructor.name)||"<component>"}function P(e){var n=this;p(this,g,!1),p(this,w,!1);var o=x(this),i=e.bind(this),a=!1;return function e(){var s;a=!1;var c=null!=(s=e[m])?s:e[m]=function(){var e=new r.Reaction(o+".render()",(function(){if(!a&&(a=!0,!0!==n[O])){var r=!0;try{p(n,w,!0),n[g]||t.Component.prototype.forceUpdate.call(n),r=!1}finally{p(n,w,!1),r&&(e.dispose(),n.render[m]=null)}}}));return e.reactComponent=n,e}(),u=void 0,l=void 0;if(c.track((function(){try{l=r._allowStateChanges(!1,i)}catch(e){u=e}})),u)throw u;return l}}function S(e,r){return o.isUsingStaticRendering()&&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."),this.state!==r||!c(this.props,e)}function C(e,t){var n=s("reactProp_"+t+"_valueHolder"),o=s("reactProp_"+t+"_atomHolder");function i(){return this[o]||p(this,o,r.createAtom("reactive "+t)),this[o]}Object.defineProperty(e,t,{configurable:!0,enumerable:!0,get:function(){var e=!1;return r._allowStateReadsStart&&r._allowStateReadsEnd&&(e=r._allowStateReadsStart(!0)),i.call(this).reportObserved(),r._allowStateReadsStart&&r._allowStateReadsEnd&&r._allowStateReadsEnd(e),this[n]},set:function(e){this[w]||c(this[n],e)?p(this,n,e):(p(this,n,e),p(this,g,!0),i.call(this).reportChanged(),p(this,g,!1))}})}function R(e){return!0===e.isMobxInjector&&console.warn("Mobx observer: You are trying to use `observer` on a component that already has `inject`. Please apply `observer` before applying `inject`"),Object.prototype.isPrototypeOf.call(t.Component,e)||Object.prototype.isPrototypeOf.call(t.PureComponent,e)?j(e):o.observer(e)}function E(){return(E=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}).apply(this,arguments)}var A=["children"],k=n.createContext({});function U(e){var r=e.children,t=function(e,r){if(null==e)return{};var t,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r.indexOf(t=i[n])>=0||(o[t]=e[t]);return o}(e,A),o=n.useContext(k),i=n.useRef(E({},o,t));return n.createElement(k.Provider,{value:i.current},r)}function _(e,r,t,o){var i,a,s,c=n.forwardRef((function(t,o){var i=E({},t),a=n.useContext(k);return Object.assign(i,e(a||{},i)||{}),o&&(i.ref=o),n.createElement(r,i)}));return o&&(c=R(c)),c.isMobxInjector=!0,i=r,a=c,s=Object.getOwnPropertyNames(Object.getPrototypeOf(i)),Object.getOwnPropertyNames(i).forEach((function(e){l[e]||-1!==s.indexOf(e)||Object.defineProperty(a,e,Object.getOwnPropertyDescriptor(i,e))})),c.wrappedComponent=r,c.displayName=function(e,r){var t=e.displayName||e.name||e.constructor&&e.constructor.name||"Component";return r?"inject-with-"+r+"("+t+")":"inject("+t+")"}(r,t),c}function M(e){return function(r,t){return e.forEach((function(e){if(!(e in t)){if(!(e in r))throw new Error("MobX injector: Store '"+e+"' is not available! Make sure it is provided by some Provider");t[e]=r[e]}})),t}}U.displayName="MobXProvider";var T=s("disposeOnUnmountProto"),q=s("disposeOnUnmountInst");function D(){var e=this;[].concat(this[T]||[],this[q]||[]).forEach((function(r){var t="string"==typeof r?e[r]:r;null!=t&&(Array.isArray(t)?t.map((function(e){return e()})):t())}))}function N(e){function t(t,n,o,i,a,s){for(var c=arguments.length,u=new Array(c>6?c-6:0),l=6;l<c;l++)u[l-6]=arguments[l];return r.untracked((function(){return i=i||"<<anonymous>>",s=s||o,null==n[o]?t?new Error("The "+a+" `"+s+"` is marked as required in `"+i+"`, but its value is `"+(null===n[o]?"null":"undefined")+"`."):null:e.apply(void 0,[n,o,i,a,s].concat(u))}))}var n=t.bind(null,!1);return n.isRequired=t.bind(null,!0),n}function I(e){var r=typeof e;return Array.isArray(e)?"array":e instanceof RegExp?"object":function(e,r){return"symbol"===e||"Symbol"===r["@@toStringTag"]||"function"==typeof Symbol&&r instanceof Symbol}(r,e)?"symbol":r}function L(e,t){return N((function(n,o,i,a,s){return r.untracked((function(){if(e&&I(n[o])===t.toLowerCase())return null;var a;switch(t){case"Array":a=r.isObservableArray;break;case"Object":a=r.isObservableObject;break;case"Map":a=r.isObservableMap;break;default:throw new Error("Unexpected mobxType: "+t)}var c=n[o];if(!a(c)){var u=function(e){var r=I(e);if("object"===r){if(e instanceof Date)return"date";if(e instanceof RegExp)return"regexp"}return r}(c),l=e?" or javascript `"+t.toLowerCase()+"`":"";return new Error("Invalid prop `"+s+"` of type `"+u+"` supplied to `"+i+"`, expected `mobx.Observable"+t+"`"+l+".")}return null}))}))}function X(e,t){return N((function(n,o,i,a,s){for(var c=arguments.length,u=new Array(c>5?c-5:0),l=5;l<c;l++)u[l-5]=arguments[l];return r.untracked((function(){if("function"!=typeof t)return new Error("Property `"+s+"` of component `"+i+"` has invalid PropType notation.");var r=L(e,"Array")(n,o,i,a,s);if(r instanceof Error)return r;for(var c=n[o],l=0;l<c.length;l++)if((r=t.apply(void 0,[c,l,i,a,s+"["+l+"]"].concat(u)))instanceof Error)return r;return null}))}))}var $={observableArray:L(!1,"Array"),observableArrayOf:X.bind(null,!1),observableMap:L(!1,"Map"),observableObject:L(!1,"Object"),arrayOrObservableArray:L(!0,"Array"),arrayOrObservableArrayOf:X.bind(null,!0),objectOrObservableObject:L(!0,"Object")};if(!t.Component)throw new Error("mobx-react requires React to be available");if(!r.observable)throw new Error("mobx-react requires mobx to be available");Object.defineProperty(exports,"Observer",{enumerable:!0,get:function(){return o.Observer}}),Object.defineProperty(exports,"enableStaticRendering",{enumerable:!0,get:function(){return o.enableStaticRendering}}),Object.defineProperty(exports,"isUsingStaticRendering",{enumerable:!0,get:function(){return o.isUsingStaticRendering}}),Object.defineProperty(exports,"observerBatching",{enumerable:!0,get:function(){return o.observerBatching}}),Object.defineProperty(exports,"useAsObservableSource",{enumerable:!0,get:function(){return o.useAsObservableSource}}),Object.defineProperty(exports,"useLocalObservable",{enumerable:!0,get:function(){return o.useLocalObservable}}),Object.defineProperty(exports,"useLocalStore",{enumerable:!0,get:function(){return o.useLocalStore}}),Object.defineProperty(exports,"useObserver",{enumerable:!0,get:function(){return o.useObserver}}),Object.defineProperty(exports,"useStaticRendering",{enumerable:!0,get:function(){return o.useStaticRendering}}),exports.MobXProviderContext=k,exports.PropTypes=$,exports.Provider=U,exports.disposeOnUnmount=function e(r,t){if(Array.isArray(t))return t.map((function(t){return e(r,t)}));var o=Object.getPrototypeOf(r).constructor,i=Object.getPrototypeOf(r.constructor),a=Object.getPrototypeOf(Object.getPrototypeOf(r));if(o!==n.Component&&o!==n.PureComponent&&i!==n.Component&&i!==n.PureComponent&&a!==n.Component&&a!==n.PureComponent)throw new Error("[mobx-react] disposeOnUnmount only supports direct subclasses of React.Component or React.PureComponent.");if("string"!=typeof t&&"function"!=typeof t&&!Array.isArray(t))throw new Error("[mobx-react] disposeOnUnmount only works if the parameter is either a property key or a function.");var s=!!r[T]||!!r[q];return("string"==typeof t?r[T]||(r[T]=[]):r[q]||(r[q]=[])).push(t),s||v(r,"componentWillUnmount",D),"string"!=typeof t?t:void 0},exports.inject=function(){for(var e=arguments.length,r=new Array(e),t=0;t<e;t++)r[t]=arguments[t];if("function"==typeof arguments[0]){var n=arguments[0];return function(e){return _(n,e,n.name,!0)}}return function(e){return _(M(r),e,r.join("-"),!1)}},exports.observer=R; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,r=require("mobx"),t=require("react"),n=(e=t)&&"object"==typeof e&&"default"in e?e.default:e,o=require("mobx-react-lite");function i(e,r){if(a(e,r))return!0;if("object"!=typeof e||null===e||"object"!=typeof r||null===r)return!1;var t=Object.keys(e),n=Object.keys(r);if(t.length!==n.length)return!1;for(var o=0;o<t.length;o++)if(!Object.hasOwnProperty.call(r,t[o])||!a(e[t[o]],r[t[o]]))return!1;return!0}function a(e,r){return e===r?0!==e||1/e==1/r:e!=e&&r!=r}var s={$$typeof:1,render:1,compare:1,type:1,childContextTypes:1,contextType:1,contextTypes:1,defaultProps:1,getDefaultProps:1,getDerivedStateFromError:1,getDerivedStateFromProps:1,mixins:1,displayName:1,propTypes:1},c=Symbol("patchMixins"),u=Symbol("patchedDefinition");function p(e,r){for(var t=this,n=arguments.length,o=new Array(n>2?n-2:0),i=2;i<n;i++)o[i-2]=arguments[i];r.locks++;try{var a;return null!=e&&(a=e.apply(this,o)),a}finally{r.locks--,0===r.locks&&r.methods.forEach((function(e){e.apply(t,o)}))}}function l(e,r){return function(){for(var t=arguments.length,n=new Array(t),o=0;o<t;o++)n[o]=arguments[o];p.call.apply(p,[this,e,r].concat(n))}}function f(e,r,t){var n=function(e,r){var t=e[c]=e[c]||{},n=t[r]=t[r]||{};return n.locks=n.locks||0,n.methods=n.methods||[],n}(e,r);n.methods.indexOf(t)<0&&n.methods.push(t);var o=Object.getOwnPropertyDescriptor(e,r);if(!o||!o[u]){var i=function e(r,t,n,o,i){var a,s=l(i,o);return(a={})[u]=!0,a.get=function(){return s},a.set=function(i){if(this===r)s=l(i,o);else{var a=e(this,t,n,o,i);Object.defineProperty(this,t,a)}},a.configurable=!0,a.enumerable=n,a}(e,r,o?o.enumerable:void 0,n,e[r]);Object.defineProperty(e,r,i)}}var b=Symbol("ObserverAdministration"),d=Symbol("isMobXReactObserver");function m(e){var t;return null!=(t=e[b])?t:e[b]={reaction:null,mounted:!1,forceUpdate:null,name:y(e.constructor),state:void 0,props:void 0,context:void 0,propsAtom:r.createAtom("props"),stateAtom:r.createAtom("state"),contextAtom:r.createAtom("context"),isUpdating:!1}}function y(e){return e.displayName||e.name||"<component>"}function v(e){var t=e.bind(this),n=m(this);return function(){n.reaction||(n.reaction=function(e){return new r.Reaction(e.name+".render()",(function(){if(!e.isUpdating&&e.mounted)try{e.isUpdating=!0,null==e.forceUpdate||e.forceUpdate()}catch(t){var r;null==(r=e.reaction)||r.dispose(),e.reaction=null}finally{e.isUpdating=!1}}))}(n),n.mounted||o._observerFinalizationRegistry.register(this,n,this));var e=void 0,i=void 0;if(n.reaction.track((function(){try{i=r._allowStateChanges(!1,t)}catch(r){e=r}})),e)throw e;return i}}function h(e,r){return o.isUsingStaticRendering()&&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."),this.state!==r||!i(this.props,e)}function g(e){var t=e+"Atom";return{configurable:!0,enumerable:!0,get:function(){var n=m(this),o=r._allowStateReadsStart(!0);return n[t].reportObserved(),r._allowStateReadsEnd(o),n[e]},set:function(r){var n=m(this);n.isUpdating||i(n[e],r)?n[e]=r:(n[e]=r,n.isUpdating=!0,n[t].reportChanged(),n.isUpdating=!1)}}}var O=g("props"),j=g("state"),w=g("context");function x(e){return!0===e.isMobxInjector&&console.warn("Mobx observer: You are trying to use `observer` on a component that already has `inject`. Please apply `observer` before applying `inject`"),Object.prototype.isPrototypeOf.call(t.Component,e)||Object.prototype.isPrototypeOf.call(t.PureComponent,e)?function(e){var r=e.prototype;if(e[d]){var n=y(e);console.warn("The provided component class ("+n+")\n has already been declared as an observer component.")}else e[d]=!0;if(r.componentWillReact)throw new Error("The componentWillReact life-cycle event is no longer supported");if(e.__proto__!==t.PureComponent)if(r.shouldComponentUpdate){if(r.shouldComponentUpdate!==h)throw new Error("It is not allowed to use shouldComponentUpdate in observer based components.")}else r.shouldComponentUpdate=h;Object.defineProperties(r,{props:O,state:j,context:w});var i=r.render;if("function"!=typeof i){var a=y(e);throw new Error("[mobx-react] class component ("+a+") is missing `render` method.\n`observer` requires `render` being a function defined on prototype.\n`render = () => {}` or `render = function() {}` is not supported.")}return r.render=function(){return Object.defineProperty(this,"render",{configurable:!1,writable:!1,value:o.isUsingStaticRendering()?i:v.call(this,i)}),this.render()},f(r,"componentDidMount",(function(){var e=this,r=m(this);r.mounted=!0,o._observerFinalizationRegistry.unregister(r),r.forceUpdate=function(){return e.forceUpdate()},r.reaction||r.forceUpdate()})),f(r,"componentWillUnmount",(function(){var e;if(!o.isUsingStaticRendering()){var r=m(this);null==(e=r.reaction)||e.dispose(),r.reaction=null,r.forceUpdate=null,r.mounted=!1}})),e}(e):o.observer(e)}function P(){return(P=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}).apply(this,arguments)}var U=["children"],A=n.createContext({});function S(e){var r=e.children,t=function(e,r){if(null==e)return{};var t,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r.indexOf(t=i[n])>=0||(o[t]=e[t]);return o}(e,U),o=n.useContext(A),i=n.useRef(P({},o,t));return n.createElement(A.Provider,{value:i.current},r)}function R(e,r,t,o){var i,a,c,u=n.forwardRef((function(t,o){var i=P({},t),a=n.useContext(A);return Object.assign(i,e(a||{},i)||{}),o&&(i.ref=o),n.createElement(r,i)}));return o&&(u=x(u)),u.isMobxInjector=!0,i=r,a=u,c=Object.getOwnPropertyNames(Object.getPrototypeOf(i)),Object.getOwnPropertyNames(i).forEach((function(e){s[e]||-1!==c.indexOf(e)||Object.defineProperty(a,e,Object.getOwnPropertyDescriptor(i,e))})),u.wrappedComponent=r,u.displayName=function(e,r){var t=e.displayName||e.name||e.constructor&&e.constructor.name||"Component";return r?"inject-with-"+r+"("+t+")":"inject("+t+")"}(r,t),u}function C(e){return function(r,t){return e.forEach((function(e){if(!(e in t)){if(!(e in r))throw new Error("MobX injector: Store '"+e+"' is not available! Make sure it is provided by some Provider");t[e]=r[e]}})),t}}S.displayName="MobXProvider";var E=Number.parseInt(n.version.split(".")[0]),k=!1,M=Symbol("disposeOnUnmountProto"),T=Symbol("disposeOnUnmountInst");function _(){var e=this;[].concat(this[M]||[],this[T]||[]).forEach((function(r){var t="string"==typeof r?e[r]:r;null!=t&&(Array.isArray(t)?t.map((function(e){return e()})):t())}))}function D(e){function t(t,n,o,i,a,s){for(var c=arguments.length,u=new Array(c>6?c-6:0),p=6;p<c;p++)u[p-6]=arguments[p];return r.untracked((function(){return i=i||"<<anonymous>>",s=s||o,null==n[o]?t?new Error("The "+a+" `"+s+"` is marked as required in `"+i+"`, but its value is `"+(null===n[o]?"null":"undefined")+"`."):null:e.apply(void 0,[n,o,i,a,s].concat(u))}))}var n=t.bind(null,!1);return n.isRequired=t.bind(null,!0),n}function q(e){var r=typeof e;return Array.isArray(e)?"array":e instanceof RegExp?"object":function(e,r){return"symbol"===e||"Symbol"===r["@@toStringTag"]||"function"==typeof Symbol&&r instanceof Symbol}(r,e)?"symbol":r}function I(e,t){return D((function(n,o,i,a,s){return r.untracked((function(){if(e&&q(n[o])===t.toLowerCase())return null;var a;switch(t){case"Array":a=r.isObservableArray;break;case"Object":a=r.isObservableObject;break;case"Map":a=r.isObservableMap;break;default:throw new Error("Unexpected mobxType: "+t)}var c=n[o];if(!a(c)){var u=function(e){var r=q(e);if("object"===r){if(e instanceof Date)return"date";if(e instanceof RegExp)return"regexp"}return r}(c),p=e?" or javascript `"+t.toLowerCase()+"`":"";return new Error("Invalid prop `"+s+"` of type `"+u+"` supplied to `"+i+"`, expected `mobx.Observable"+t+"`"+p+".")}return null}))}))}function N(e,t){return D((function(n,o,i,a,s){for(var c=arguments.length,u=new Array(c>5?c-5:0),p=5;p<c;p++)u[p-5]=arguments[p];return r.untracked((function(){if("function"!=typeof t)return new Error("Property `"+s+"` of component `"+i+"` has invalid PropType notation.");var r=I(e,"Array")(n,o,i,a,s);if(r instanceof Error)return r;for(var c=n[o],p=0;p<c.length;p++)if((r=t.apply(void 0,[c,p,i,a,s+"["+p+"]"].concat(u)))instanceof Error)return r;return null}))}))}var L={observableArray:I(!1,"Array"),observableArrayOf:N.bind(null,!1),observableMap:I(!1,"Map"),observableObject:I(!1,"Object"),arrayOrObservableArray:I(!0,"Array"),arrayOrObservableArrayOf:N.bind(null,!0),objectOrObservableObject:I(!0,"Object")};if(!t.Component)throw new Error("mobx-react requires React to be available");if(!r.observable)throw new Error("mobx-react requires mobx to be available");Object.defineProperty(exports,"Observer",{enumerable:!0,get:function(){return o.Observer}}),Object.defineProperty(exports,"enableStaticRendering",{enumerable:!0,get:function(){return o.enableStaticRendering}}),Object.defineProperty(exports,"isUsingStaticRendering",{enumerable:!0,get:function(){return o.isUsingStaticRendering}}),Object.defineProperty(exports,"observerBatching",{enumerable:!0,get:function(){return o.observerBatching}}),Object.defineProperty(exports,"useAsObservableSource",{enumerable:!0,get:function(){return o.useAsObservableSource}}),Object.defineProperty(exports,"useLocalObservable",{enumerable:!0,get:function(){return o.useLocalObservable}}),Object.defineProperty(exports,"useLocalStore",{enumerable:!0,get:function(){return o.useLocalStore}}),Object.defineProperty(exports,"useObserver",{enumerable:!0,get:function(){return o.useObserver}}),Object.defineProperty(exports,"useStaticRendering",{enumerable:!0,get:function(){return o.useStaticRendering}}),exports.MobXProviderContext=A,exports.PropTypes=L,exports.Provider=S,exports.disposeOnUnmount=function e(r,t){if(Array.isArray(t))return t.map((function(t){return e(r,t)}));k||(E>=18?console.error("[mobx-react] disposeOnUnmount is not compatible with React 18 and higher. Don't use it."):console.warn("[mobx-react] disposeOnUnmount is deprecated. It won't work correctly with React 18 and higher."),k=!0);var o=Object.getPrototypeOf(r).constructor,i=Object.getPrototypeOf(r.constructor),a=Object.getPrototypeOf(Object.getPrototypeOf(r));if(o!==n.Component&&o!==n.PureComponent&&i!==n.Component&&i!==n.PureComponent&&a!==n.Component&&a!==n.PureComponent)throw new Error("[mobx-react] disposeOnUnmount only supports direct subclasses of React.Component or React.PureComponent.");if("string"!=typeof t&&"function"!=typeof t&&!Array.isArray(t))throw new Error("[mobx-react] disposeOnUnmount only works if the parameter is either a property key or a function.");var s=!!r[M]||!!r[T];return("string"==typeof t?r[M]||(r[M]=[]):r[T]||(r[T]=[])).push(t),s||f(r,"componentWillUnmount",_),"string"!=typeof t?t:void 0},exports.inject=function(){for(var e=arguments.length,r=new Array(e),t=0;t<e;t++)r[t]=arguments[t];if("function"==typeof arguments[0]){var n=arguments[0];return function(e){return R(n,e,n.name,!0)}}return function(e){return R(C(r),e,r.join("-"),!1)}},exports.observer=x; | ||
//# sourceMappingURL=mobxreact.cjs.production.min.js.map |
@@ -1,26 +0,6 @@ | ||
import { _allowStateReadsStart, _allowStateReadsEnd, $mobx, _allowStateChanges, createAtom, Reaction, untracked, isObservableMap, isObservableObject, isObservableArray, observable } from 'mobx'; | ||
import { createAtom, _allowStateReadsStart, _allowStateReadsEnd, Reaction, _allowStateChanges, untracked, isObservableMap, isObservableObject, isObservableArray, observable } from 'mobx'; | ||
import React__default, { PureComponent, Component } from 'react'; | ||
import { isUsingStaticRendering, observer as observer$1 } from 'mobx-react-lite'; | ||
import { isUsingStaticRendering, _observerFinalizationRegistry, observer as observer$1 } from 'mobx-react-lite'; | ||
export { Observer, enableStaticRendering, isUsingStaticRendering, observerBatching, useAsObservableSource, useLocalObservable, useLocalStore, useObserver, useStaticRendering } from 'mobx-react-lite'; | ||
var symbolId = 0; | ||
function createSymbol(name) { | ||
if (typeof Symbol === "function") { | ||
return Symbol(name); | ||
} | ||
var symbol = "__$mobx-react " + name + " (" + symbolId + ")"; | ||
symbolId++; | ||
return symbol; | ||
} | ||
var createdSymbols = {}; | ||
function newSymbol(name) { | ||
if (!createdSymbols[name]) { | ||
createdSymbols[name] = createSymbol(name); | ||
} | ||
return createdSymbols[name]; | ||
} | ||
function shallowEqual(objA, objB) { | ||
@@ -31,14 +11,10 @@ //From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js | ||
} | ||
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) { | ||
return false; | ||
} | ||
var keysA = Object.keys(objA); | ||
var keysB = Object.keys(objB); | ||
if (keysA.length !== keysB.length) { | ||
return false; | ||
} | ||
for (var i = 0; i < keysA.length; i++) { | ||
@@ -49,6 +25,4 @@ if (!Object.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { | ||
} | ||
return true; | ||
} | ||
function is(x, y) { | ||
@@ -61,5 +35,4 @@ // From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js | ||
} | ||
} // based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js | ||
} | ||
// based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js | ||
var hoistBlackList = { | ||
@@ -90,28 +63,7 @@ $$typeof: 1, | ||
/** | ||
* Helper to set `prop` to `this` as non-enumerable (hidden prop) | ||
* @param target | ||
* @param prop | ||
* @param value | ||
*/ | ||
function setHiddenProp(target, prop, value) { | ||
if (!Object.hasOwnProperty.call(target, prop)) { | ||
Object.defineProperty(target, prop, { | ||
enumerable: false, | ||
configurable: true, | ||
writable: true, | ||
value: value | ||
}); | ||
} else { | ||
target[prop] = value; | ||
} | ||
} | ||
/** | ||
* Utilities for patching componentWillUnmount, to make sure @disposeOnUnmount works correctly icm with user defined hooks | ||
* and the handler provided by mobx-react | ||
*/ | ||
var mobxMixins = /*#__PURE__*/newSymbol("patchMixins"); | ||
var mobxPatchedDefinition = /*#__PURE__*/newSymbol("patchedDefinition"); | ||
var mobxMixins = /*#__PURE__*/Symbol("patchMixins"); | ||
var mobxPatchedDefinition = /*#__PURE__*/Symbol("patchedDefinition"); | ||
function getMixins(target, methodName) { | ||
@@ -124,24 +76,17 @@ var mixins = target[mobxMixins] = target[mobxMixins] || {}; | ||
} | ||
function wrapper(realMethod, mixins) { | ||
var _this = this; | ||
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { | ||
args[_key - 2] = arguments[_key]; | ||
} | ||
// locks are used to ensure that mixins are invoked only once per invocation, even on recursive calls | ||
mixins.locks++; | ||
try { | ||
var retVal; | ||
if (realMethod !== undefined && realMethod !== null) { | ||
retVal = realMethod.apply(this, args); | ||
} | ||
return retVal; | ||
} finally { | ||
mixins.locks--; | ||
if (mixins.locks === 0) { | ||
@@ -154,3 +99,2 @@ mixins.methods.forEach(function (mx) { | ||
} | ||
function wrapFunction(realMethod, mixins) { | ||
@@ -161,18 +105,12 @@ var fn = function fn() { | ||
} | ||
wrapper.call.apply(wrapper, [this, realMethod, mixins].concat(args)); | ||
}; | ||
return fn; | ||
} | ||
function patch(target, methodName, mixinMethod) { | ||
var mixins = getMixins(target, methodName); | ||
if (mixins.methods.indexOf(mixinMethod) < 0) { | ||
mixins.methods.push(mixinMethod); | ||
} | ||
var oldDefinition = Object.getOwnPropertyDescriptor(target, methodName); | ||
if (oldDefinition && oldDefinition[mobxPatchedDefinition]) { | ||
@@ -182,3 +120,2 @@ // already patched definition, do not repatch | ||
} | ||
var originalMethod = target[methodName]; | ||
@@ -188,6 +125,4 @@ var newDefinition = createDefinition(target, methodName, oldDefinition ? oldDefinition.enumerable : undefined, mixins, originalMethod); | ||
} | ||
function createDefinition(target, methodName, enumerable, mixins, originalMethod) { | ||
var _ref; | ||
var wrappedFunc = wrapFunction(originalMethod, mixins); | ||
@@ -210,233 +145,219 @@ return _ref = {}, _ref[mobxPatchedDefinition] = true, _ref.get = function get() { | ||
var mobxAdminProperty = $mobx || "$mobx"; // BC | ||
var mobxObserverProperty = /*#__PURE__*/newSymbol("isMobXReactObserver"); | ||
var mobxIsUnmounted = /*#__PURE__*/newSymbol("isUnmounted"); | ||
var skipRenderKey = /*#__PURE__*/newSymbol("skipRender"); | ||
var isForcingUpdateKey = /*#__PURE__*/newSymbol("isForcingUpdate"); | ||
var administrationSymbol = /*#__PURE__*/Symbol("ObserverAdministration"); | ||
var isMobXReactObserverSymbol = /*#__PURE__*/Symbol("isMobXReactObserver"); | ||
function getAdministration(component) { | ||
var _component$administra; | ||
// We create administration lazily, because we can't patch constructor | ||
// and the exact moment of initialization partially depends on React internals. | ||
// At the time of writing this, the first thing invoked is one of the observable getter/setter (state/props/context). | ||
return (_component$administra = component[administrationSymbol]) != null ? _component$administra : component[administrationSymbol] = { | ||
reaction: null, | ||
mounted: false, | ||
forceUpdate: null, | ||
name: getDisplayName(component.constructor), | ||
state: undefined, | ||
props: undefined, | ||
context: undefined, | ||
propsAtom: createAtom("props"), | ||
stateAtom: createAtom("state"), | ||
contextAtom: createAtom("context"), | ||
isUpdating: false | ||
}; | ||
} | ||
function makeClassComponentObserver(componentClass) { | ||
var target = componentClass.prototype; | ||
if (componentClass[mobxObserverProperty]) { | ||
var displayName = getDisplayName(target); | ||
var prototype = componentClass.prototype; | ||
if (componentClass[isMobXReactObserverSymbol]) { | ||
var displayName = getDisplayName(componentClass); | ||
console.warn("The provided component class (" + displayName + ")\n has already been declared as an observer component."); | ||
} else { | ||
componentClass[mobxObserverProperty] = true; | ||
componentClass[isMobXReactObserverSymbol] = true; | ||
} | ||
if (target.componentWillReact) { | ||
if (prototype.componentWillReact) { | ||
throw new Error("The componentWillReact life-cycle event is no longer supported"); | ||
} | ||
if (componentClass["__proto__"] !== PureComponent) { | ||
if (!target.shouldComponentUpdate) { | ||
target.shouldComponentUpdate = observerSCU; | ||
} else if (target.shouldComponentUpdate !== observerSCU) { | ||
if (!prototype.shouldComponentUpdate) { | ||
prototype.shouldComponentUpdate = observerSCU; | ||
} else if (prototype.shouldComponentUpdate !== observerSCU) { | ||
// n.b. unequal check, instead of existence check, as @observer might be on superclass as well | ||
throw new Error("It is not allowed to use shouldComponentUpdate in observer based components."); | ||
} | ||
} // this.props and this.state are made observable, just to make sure @computed fields that | ||
} | ||
// this.props and this.state are made observable, just to make sure @computed fields that | ||
// are defined inside the component, and which rely on state or props, re-compute if state or props change | ||
// (otherwise the computed wouldn't update and become stale on props change, since props are not observable) | ||
// 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+ | ||
makeObservableProp(target, "props"); | ||
makeObservableProp(target, "state"); | ||
if (componentClass.contextType) { | ||
makeObservableProp(target, "context"); | ||
} | ||
var originalRender = target.render; | ||
Object.defineProperties(prototype, { | ||
props: observablePropsDescriptor, | ||
state: observableStateDescriptor, | ||
context: observableContextDescriptor | ||
}); | ||
var originalRender = prototype.render; | ||
if (typeof originalRender !== "function") { | ||
var _displayName = getDisplayName(target); | ||
var _displayName = getDisplayName(componentClass); | ||
throw new Error("[mobx-react] class component (" + _displayName + ") is missing `render` method." + "\n`observer` requires `render` being a function defined on prototype." + "\n`render = () => {}` or `render = function() {}` is not supported."); | ||
} | ||
target.render = function () { | ||
this.render = isUsingStaticRendering() ? originalRender : createReactiveRender.call(this, originalRender); | ||
prototype.render = function () { | ||
Object.defineProperty(this, "render", { | ||
// There is no safe way to replace render, therefore it's forbidden. | ||
configurable: false, | ||
writable: false, | ||
value: isUsingStaticRendering() ? originalRender : createReactiveRender.call(this, originalRender) | ||
}); | ||
return this.render(); | ||
}; | ||
patch(target, "componentDidMount", function () { | ||
this[mobxIsUnmounted] = false; | ||
if (!this.render[mobxAdminProperty]) { | ||
// Reaction is re-created automatically during render, but a component can re-mount and skip render #3395. | ||
// To re-create the reaction and re-subscribe to relevant observables we have to force an update. | ||
Component.prototype.forceUpdate.call(this); | ||
patch(prototype, "componentDidMount", function () { | ||
var _this = this; | ||
// `componentDidMount` may not be called at all. React can abandon the instance after `render`. | ||
// That's why we use finalization registry to dispose reaction created during render. | ||
// Happens with `<Suspend>` see #3492 | ||
// | ||
// `componentDidMount` can be called immediately after `componentWillUnmount` without calling `render` in between. | ||
// Happens with `<StrictMode>`see #3395. | ||
// | ||
// If `componentDidMount` is called, it's guaranteed to run synchronously with render (similary to `useLayoutEffect`). | ||
// Therefore we don't have to worry about external (observable) state being updated before mount (no state version checking). | ||
// | ||
// Things may change: "In the future, React will provide a feature that lets components preserve state between unmounts" | ||
var admin = getAdministration(this); | ||
admin.mounted = true; | ||
// Component instance committed, prevent reaction disposal. | ||
_observerFinalizationRegistry.unregister(admin); | ||
// We don't set forceUpdate before mount because it requires a reference to `this`, | ||
// therefore `this` could NOT be garbage collected before mount, | ||
// preventing reaction disposal by FinalizationRegistry and leading to memory leak. | ||
// As an alternative we could have `admin.instanceRef = new WeakRef(this)`, but lets avoid it if possible. | ||
admin.forceUpdate = function () { | ||
return _this.forceUpdate(); | ||
}; | ||
if (!admin.reaction) { | ||
// 1. Instance was unmounted (reaction disposed) and immediately remounted without running render #3395. | ||
// 2. Reaction was disposed by finalization registry before mount. Shouldn't ever happen for class components: | ||
// `componentDidMount` runs synchronously after render, but our registry are deferred (can't run in between). | ||
// In any case we lost subscriptions to observables, so we have to create new reaction and re-render to resubscribe. | ||
// The reaction will be created lazily by following render. | ||
admin.forceUpdate(); | ||
} | ||
}); | ||
patch(target, "componentWillUnmount", function () { | ||
patch(prototype, "componentWillUnmount", function () { | ||
var _admin$reaction; | ||
if (isUsingStaticRendering()) { | ||
return; | ||
} | ||
var reaction = this.render[mobxAdminProperty]; | ||
if (reaction) { | ||
reaction.dispose(); // Forces reaction to be re-created on next render | ||
this.render[mobxAdminProperty] = null; | ||
} else { | ||
// Render may have been hot-swapped and/or overridden by a subclass. | ||
var _displayName2 = getDisplayName(this); | ||
console.warn("The reactive render of an observer class component (" + _displayName2 + ")\n was overridden after MobX attached. This may result in a memory leak if the\n overridden reactive render was not properly disposed."); | ||
} | ||
this[mobxIsUnmounted] = true; | ||
var admin = getAdministration(this); | ||
(_admin$reaction = admin.reaction) == null ? void 0 : _admin$reaction.dispose(); | ||
admin.reaction = null; | ||
admin.forceUpdate = null; | ||
admin.mounted = false; | ||
}); | ||
return componentClass; | ||
} // Generates a friendly name for debugging | ||
function getDisplayName(comp) { | ||
return comp.displayName || comp.name || comp.constructor && (comp.constructor.displayName || comp.constructor.name) || "<component>"; | ||
} | ||
// Generates a friendly name for debugging | ||
function getDisplayName(componentClass) { | ||
return componentClass.displayName || componentClass.name || "<component>"; | ||
} | ||
function createReactiveRender(originalRender) { | ||
var _this = this; | ||
/** | ||
* If props are shallowly modified, react will render anyway, | ||
* so atom.reportChanged() should not result in yet another re-render | ||
*/ | ||
setHiddenProp(this, skipRenderKey, false); | ||
/** | ||
* forceUpdate will re-assign this.props. We don't want that to cause a loop, | ||
* so detect these changes | ||
*/ | ||
setHiddenProp(this, isForcingUpdateKey, false); | ||
var initialName = getDisplayName(this); | ||
var boundOriginalRender = originalRender.bind(this); | ||
var isRenderingPending = false; | ||
var createReaction = function createReaction() { | ||
var reaction = new Reaction(initialName + ".render()", function () { | ||
if (!isRenderingPending) { | ||
// N.B. Getting here *before mounting* means that a component constructor has side effects (see the relevant test in misc.test.tsx) | ||
// This unidiomatic React usage but React will correctly warn about this so we continue as usual | ||
// See #85 / Pull #44 | ||
isRenderingPending = true; | ||
if (_this[mobxIsUnmounted] !== true) { | ||
var hasError = true; | ||
try { | ||
setHiddenProp(_this, isForcingUpdateKey, true); | ||
if (!_this[skipRenderKey]) { | ||
Component.prototype.forceUpdate.call(_this); | ||
} | ||
hasError = false; | ||
} finally { | ||
setHiddenProp(_this, isForcingUpdateKey, false); | ||
if (hasError) { | ||
reaction.dispose(); // Forces reaction to be re-created on next render | ||
_this.render[mobxAdminProperty] = null; | ||
} | ||
} | ||
} | ||
var admin = getAdministration(this); | ||
function reactiveRender() { | ||
if (!admin.reaction) { | ||
// Create reaction lazily to support re-mounting #3395 | ||
admin.reaction = createReaction(admin); | ||
if (!admin.mounted) { | ||
// React can abandon this instance and never call `componentDidMount`/`componentWillUnmount`, | ||
// we have to make sure reaction will be disposed. | ||
_observerFinalizationRegistry.register(this, admin, this); | ||
} | ||
}); | ||
reaction["reactComponent"] = _this; | ||
return reaction; | ||
}; | ||
function reactiveRender() { | ||
var _reactiveRender$mobxA; | ||
isRenderingPending = false; // Create reaction lazily to support re-mounting #3395 | ||
var reaction = (_reactiveRender$mobxA = reactiveRender[mobxAdminProperty]) != null ? _reactiveRender$mobxA : reactiveRender[mobxAdminProperty] = createReaction(); | ||
var exception = undefined; | ||
var rendering = undefined; | ||
reaction.track(function () { | ||
} | ||
var error = undefined; | ||
var renderResult = undefined; | ||
admin.reaction.track(function () { | ||
try { | ||
// TODO@major | ||
// Optimization: replace with _allowStateChangesStart/End (not available in mobx@6.0.0) | ||
rendering = _allowStateChanges(false, boundOriginalRender); | ||
renderResult = _allowStateChanges(false, boundOriginalRender); | ||
} catch (e) { | ||
exception = e; | ||
error = e; | ||
} | ||
}); | ||
if (exception) { | ||
throw exception; | ||
if (error) { | ||
throw error; | ||
} | ||
return rendering; | ||
return renderResult; | ||
} | ||
return reactiveRender; | ||
} | ||
function createReaction(admin) { | ||
return new Reaction(admin.name + ".render()", function () { | ||
if (admin.isUpdating) { | ||
// Reaction is suppressed when setting new state/props/context, | ||
// this is when component is already being updated. | ||
return; | ||
} | ||
if (!admin.mounted) { | ||
// This is neccessary to avoid react warning about calling forceUpdate on component that isn't mounted yet. | ||
// This happens when component is abandoned after render - our reaction is already created and reacts to changes. | ||
// Due to the synchronous nature of `componenDidMount`, we don't have to worry that component could eventually mount and require update. | ||
return; | ||
} | ||
try { | ||
// forceUpdate sets new `props`, since we made it observable, it would `reportChanged`, causing a loop. | ||
admin.isUpdating = true; | ||
admin.forceUpdate == null ? void 0 : admin.forceUpdate(); | ||
} catch (error) { | ||
var _admin$reaction2; | ||
(_admin$reaction2 = admin.reaction) == null ? void 0 : _admin$reaction2.dispose(); | ||
admin.reaction = null; | ||
} finally { | ||
admin.isUpdating = false; | ||
} | ||
}); | ||
} | ||
function observerSCU(nextProps, nextState) { | ||
if (isUsingStaticRendering()) { | ||
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."); | ||
} // update on any state changes (as is the default) | ||
} | ||
// update on any state changes (as is the default) | ||
if (this.state !== nextState) { | ||
return true; | ||
} // update if props are shallowly not equal, inspired by PureRenderMixin | ||
} | ||
// update if props are shallowly not equal, inspired by PureRenderMixin | ||
// we could return just 'false' here, and avoid the `skipRender` checks etc | ||
// however, it is nicer if lifecycle events are triggered like usually, | ||
// so we return true here if props are shallowly modified. | ||
return !shallowEqual(this.props, nextProps); | ||
} | ||
function makeObservableProp(target, propName) { | ||
var valueHolderKey = newSymbol("reactProp_" + propName + "_valueHolder"); | ||
var atomHolderKey = newSymbol("reactProp_" + propName + "_atomHolder"); | ||
function getAtom() { | ||
if (!this[atomHolderKey]) { | ||
setHiddenProp(this, atomHolderKey, createAtom("reactive " + propName)); | ||
} | ||
return this[atomHolderKey]; | ||
} | ||
Object.defineProperty(target, propName, { | ||
function createObservablePropDescriptor(key) { | ||
var atomKey = key + "Atom"; | ||
return { | ||
configurable: true, | ||
enumerable: true, | ||
get: function get() { | ||
var prevReadState = false; // Why this check? BC? | ||
// @ts-expect-error | ||
if (_allowStateReadsStart && _allowStateReadsEnd) { | ||
prevReadState = _allowStateReadsStart(true); | ||
} | ||
getAtom.call(this).reportObserved(); // Why this check? BC? | ||
// @ts-expect-error | ||
if (_allowStateReadsStart && _allowStateReadsEnd) { | ||
_allowStateReadsEnd(prevReadState); | ||
} | ||
return this[valueHolderKey]; | ||
var admin = getAdministration(this); | ||
var prevReadState = _allowStateReadsStart(true); | ||
admin[atomKey].reportObserved(); | ||
_allowStateReadsEnd(prevReadState); | ||
return admin[key]; | ||
}, | ||
set: function set(v) { | ||
if (!this[isForcingUpdateKey] && !shallowEqual(this[valueHolderKey], v)) { | ||
setHiddenProp(this, valueHolderKey, v); | ||
setHiddenProp(this, skipRenderKey, true); | ||
getAtom.call(this).reportChanged(); | ||
setHiddenProp(this, skipRenderKey, false); | ||
set: function set(value) { | ||
var admin = getAdministration(this); | ||
// forceUpdate issued by reaction sets new props. | ||
// It sets isUpdating to true to prevent loop. | ||
if (!admin.isUpdating && !shallowEqual(admin[key], value)) { | ||
admin[key] = value; | ||
// This notifies all observers including our component, | ||
// but we don't want to cause `forceUpdate`, because component is already updating, | ||
// therefore supress component reaction. | ||
admin.isUpdating = true; | ||
admin[atomKey].reportChanged(); | ||
admin.isUpdating = false; | ||
} else { | ||
setHiddenProp(this, valueHolderKey, v); | ||
admin[key] = value; | ||
} | ||
} | ||
}); | ||
}; | ||
} | ||
var observablePropsDescriptor = /*#__PURE__*/createObservablePropDescriptor("props"); | ||
var observableStateDescriptor = /*#__PURE__*/createObservablePropDescriptor("state"); | ||
var observableContextDescriptor = /*#__PURE__*/createObservablePropDescriptor("context"); | ||
@@ -446,3 +367,2 @@ /** | ||
*/ | ||
function observer(component) { | ||
@@ -452,3 +372,2 @@ if (component["isMobxInjector"] === true) { | ||
} | ||
if (Object.prototype.isPrototypeOf.call(Component, component) || Object.prototype.isPrototypeOf.call(PureComponent, component)) { | ||
@@ -464,6 +383,5 @@ // Class component | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
_extends = Object.assign ? Object.assign.bind() : function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
@@ -475,9 +393,6 @@ if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
} | ||
return target; | ||
}; | ||
return _extends.apply(this, arguments); | ||
} | ||
function _objectWithoutPropertiesLoose(source, excluded) { | ||
@@ -488,3 +403,2 @@ if (source == null) return {}; | ||
var key, i; | ||
for (i = 0; i < sourceKeys.length; i++) { | ||
@@ -495,3 +409,2 @@ key = sourceKeys[i]; | ||
} | ||
return target; | ||
@@ -504,12 +417,8 @@ } | ||
var children = props.children, | ||
stores = _objectWithoutPropertiesLoose(props, _excluded); | ||
stores = _objectWithoutPropertiesLoose(props, _excluded); | ||
var parentValue = React__default.useContext(MobXProviderContext); | ||
var mutableProviderRef = React__default.useRef(_extends({}, parentValue, stores)); | ||
var value = mutableProviderRef.current; | ||
{ | ||
var newValue = _extends({}, value, stores); // spread in previous state for the context based stores | ||
if (!shallowEqual(value, newValue)) { | ||
@@ -519,3 +428,2 @@ 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."); | ||
} | ||
return React__default.createElement(MobXProviderContext.Provider, { | ||
@@ -530,3 +438,2 @@ value: value | ||
*/ | ||
function createStoreInjector(grabStoresFn, component, injectNames, makeReactive) { | ||
@@ -536,10 +443,7 @@ // Support forward refs | ||
var newProps = _extends({}, props); | ||
var context = React__default.useContext(MobXProviderContext); | ||
Object.assign(newProps, grabStoresFn(context || {}, newProps) || {}); | ||
if (ref) { | ||
newProps.ref = ref; | ||
} | ||
return React__default.createElement(component, newProps); | ||
@@ -550,3 +454,2 @@ }); | ||
// Static fields from component should be visible on the generated Injector | ||
copyStaticProperties(component, Injector); | ||
@@ -557,3 +460,2 @@ Injector["wrappedComponent"] = component; | ||
} | ||
function getInjectName(component, injectNames) { | ||
@@ -565,3 +467,2 @@ var displayName; | ||
} | ||
function grabStoresByName(storeNames) { | ||
@@ -584,4 +485,2 @@ return function (baseStores, nextProps) { | ||
*/ | ||
function inject() { | ||
@@ -591,3 +490,2 @@ for (var _len = arguments.length, storeNames = new Array(_len), _key = 0; _key < _len; _key++) { | ||
} | ||
if (typeof arguments[0] === "function") { | ||
@@ -605,5 +503,6 @@ var grabStoresFn = arguments[0]; | ||
var protoStoreKey = /*#__PURE__*/newSymbol("disposeOnUnmountProto"); | ||
var instStoreKey = /*#__PURE__*/newSymbol("disposeOnUnmountInst"); | ||
var reactMajorVersion = /*#__PURE__*/Number.parseInt( /*#__PURE__*/React__default.version.split(".")[0]); | ||
var warnedAboutDisposeOnUnmountDeprecated = false; | ||
var protoStoreKey = /*#__PURE__*/Symbol("disposeOnUnmountProto"); | ||
var instStoreKey = /*#__PURE__*/Symbol("disposeOnUnmountInst"); | ||
function runDisposersOnWillUnmount() { | ||
@@ -613,3 +512,2 @@ var _this = this; | ||
var prop = typeof propKeyOrFunction === "string" ? _this[propKeyOrFunction] : propKeyOrFunction; | ||
if (prop !== undefined && prop !== null) { | ||
@@ -622,3 +520,5 @@ if (Array.isArray(prop)) prop.map(function (f) { | ||
} | ||
/** | ||
* @deprecated `disposeOnUnmount` is not compatible with React 18 and higher. | ||
*/ | ||
function disposeOnUnmount(target, propertyKeyOrFunction) { | ||
@@ -630,30 +530,35 @@ if (Array.isArray(propertyKeyOrFunction)) { | ||
} | ||
if (!warnedAboutDisposeOnUnmountDeprecated) { | ||
if (reactMajorVersion >= 18) { | ||
console.error("[mobx-react] disposeOnUnmount is not compatible with React 18 and higher. Don't use it."); | ||
} else { | ||
console.warn("[mobx-react] disposeOnUnmount is deprecated. It won't work correctly with React 18 and higher."); | ||
} | ||
warnedAboutDisposeOnUnmountDeprecated = true; | ||
} | ||
var c = Object.getPrototypeOf(target).constructor; | ||
var c2 = Object.getPrototypeOf(target.constructor); // Special case for react-hot-loader | ||
var c2 = Object.getPrototypeOf(target.constructor); | ||
// Special case for react-hot-loader | ||
var c3 = Object.getPrototypeOf(Object.getPrototypeOf(target)); | ||
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)) { | ||
throw new Error("[mobx-react] disposeOnUnmount only supports direct subclasses of React.Component or React.PureComponent."); | ||
} | ||
if (typeof propertyKeyOrFunction !== "string" && typeof propertyKeyOrFunction !== "function" && !Array.isArray(propertyKeyOrFunction)) { | ||
throw new Error("[mobx-react] disposeOnUnmount only works if the parameter is either a property key or a function."); | ||
} // decorator's target is the prototype, so it doesn't have any instance properties like props | ||
var isDecorator = typeof propertyKeyOrFunction === "string"; // add property key / function we want run (disposed) to the store | ||
} | ||
// decorator's target is the prototype, so it doesn't have any instance properties like props | ||
var isDecorator = typeof propertyKeyOrFunction === "string"; | ||
// add property key / function we want run (disposed) to the store | ||
var componentWasAlreadyModified = !!target[protoStoreKey] || !!target[instStoreKey]; | ||
var store = isDecorator ? // decorators are added to the prototype store | ||
target[protoStoreKey] || (target[protoStoreKey] = []) : // functions are added to the instance store | ||
var store = isDecorator ? | ||
// decorators are added to the prototype store | ||
target[protoStoreKey] || (target[protoStoreKey] = []) : | ||
// functions are added to the instance store | ||
target[instStoreKey] || (target[instStoreKey] = []); | ||
store.push(propertyKeyOrFunction); // tweak the component class componentWillUnmount if not done already | ||
store.push(propertyKeyOrFunction); | ||
// tweak the component class componentWillUnmount if not done already | ||
if (!componentWasAlreadyModified) { | ||
patch(target, "componentWillUnmount", runDisposersOnWillUnmount); | ||
} // return the disposer as is if invoked as a non decorator | ||
} | ||
// return the disposer as is if invoked as a non decorator | ||
if (typeof propertyKeyOrFunction !== "string") { | ||
@@ -664,2 +569,3 @@ return propertyKeyOrFunction; | ||
// Copied from React.PropTypes | ||
function createChainableTypeChecker(validator) { | ||
@@ -670,7 +576,5 @@ function checkType(isRequired, props, propName, componentName, location, propFullName) { | ||
} | ||
return untracked(function () { | ||
componentName = componentName || "<<anonymous>>"; | ||
propFullName = propFullName || propName; | ||
if (props[propName] == null) { | ||
@@ -681,3 +585,2 @@ if (isRequired) { | ||
} | ||
return null; | ||
@@ -690,10 +593,8 @@ } else { | ||
} | ||
var chainedCheckType = checkType.bind(null, false); // Add isRequired to satisfy Requirable | ||
var chainedCheckType = checkType.bind(null, false); | ||
// Add isRequired to satisfy Requirable | ||
chainedCheckType.isRequired = checkType.bind(null, true); | ||
return chainedCheckType; | ||
} // Copied from React.PropTypes | ||
} | ||
// Copied from React.PropTypes | ||
function isSymbol(propType, propValue) { | ||
@@ -703,25 +604,19 @@ // Native Symbol. | ||
return true; | ||
} // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' | ||
} | ||
// 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' | ||
if (propValue["@@toStringTag"] === "Symbol") { | ||
return true; | ||
} // Fallback for non-spec compliant Symbols which are polyfilled. | ||
} | ||
// Fallback for non-spec compliant Symbols which are polyfilled. | ||
if (typeof Symbol === "function" && propValue instanceof Symbol) { | ||
return true; | ||
} | ||
return false; | ||
} // Copied from React.PropTypes | ||
} | ||
// Copied from React.PropTypes | ||
function getPropType(propValue) { | ||
var propType = typeof propValue; | ||
if (Array.isArray(propValue)) { | ||
return "array"; | ||
} | ||
if (propValue instanceof RegExp) { | ||
@@ -733,15 +628,11 @@ // Old webkits (at least until Android 4.0) return 'function' rather than | ||
} | ||
if (isSymbol(propType, propValue)) { | ||
return "symbol"; | ||
} | ||
return propType; | ||
} // This handles more types than `getPropType`. Only used for error messages. | ||
} | ||
// This handles more types than `getPropType`. Only used for error messages. | ||
// Copied from React.PropTypes | ||
function getPreciseType(propValue) { | ||
var propType = getPropType(propValue); | ||
if (propType === "object") { | ||
@@ -754,6 +645,4 @@ if (propValue instanceof Date) { | ||
} | ||
return propType; | ||
} | ||
function createObservableTypeCheckerCreator(allowNativeType, mobxType) { | ||
@@ -765,5 +654,3 @@ return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) { | ||
} | ||
var mobxChecker; | ||
switch (mobxType) { | ||
@@ -773,17 +660,12 @@ case "Array": | ||
break; | ||
case "Object": | ||
mobxChecker = isObservableObject; | ||
break; | ||
case "Map": | ||
mobxChecker = isObservableMap; | ||
break; | ||
default: | ||
throw new Error("Unexpected mobxType: " + mobxType); | ||
} | ||
var propValue = props[propName]; | ||
if (!mobxChecker(propValue)) { | ||
@@ -794,3 +676,2 @@ var preciseType = getPreciseType(propValue); | ||
} | ||
return null; | ||
@@ -800,3 +681,2 @@ }); | ||
} | ||
function createObservableArrayOfTypeChecker(allowNativeType, typeChecker) { | ||
@@ -807,3 +687,2 @@ return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) { | ||
} | ||
return untracked(function () { | ||
@@ -816,3 +695,2 @@ if (typeof typeChecker !== "function") { | ||
var propValue = props[propName]; | ||
for (var i = 0; i < propValue.length; i++) { | ||
@@ -822,3 +700,2 @@ error = typeChecker.apply(void 0, [propValue, i, componentName, location, propFullName + "[" + i + "]"].concat(rest)); | ||
} | ||
return null; | ||
@@ -829,3 +706,2 @@ } | ||
} | ||
var observableArray = /*#__PURE__*/createObservableTypeCheckerCreator(false, "Array"); | ||
@@ -848,6 +724,10 @@ var observableArrayOf = /*#__PURE__*/createObservableArrayOfTypeChecker.bind(null, false); | ||
if (!Component) throw new Error("mobx-react requires React to be available"); | ||
if (!observable) throw new Error("mobx-react requires mobx to be available"); | ||
if (!Component) { | ||
throw new Error("mobx-react requires React to be available"); | ||
} | ||
if (!observable) { | ||
throw new Error("mobx-react requires mobx to be available"); | ||
} | ||
export { MobXProviderContext, PropTypes, Provider, disposeOnUnmount, inject, observer }; | ||
//# sourceMappingURL=mobxreact.esm.development.js.map |
@@ -1,26 +0,6 @@ | ||
import { _allowStateReadsStart, _allowStateReadsEnd, $mobx, _allowStateChanges, createAtom, Reaction, untracked, isObservableMap, isObservableObject, isObservableArray, observable } from 'mobx'; | ||
import { createAtom, _allowStateReadsStart, _allowStateReadsEnd, Reaction, _allowStateChanges, untracked, isObservableMap, isObservableObject, isObservableArray, observable } from 'mobx'; | ||
import React__default, { PureComponent, Component } from 'react'; | ||
import { isUsingStaticRendering, observer as observer$1 } from 'mobx-react-lite'; | ||
import { isUsingStaticRendering, _observerFinalizationRegistry, observer as observer$1 } from 'mobx-react-lite'; | ||
export { Observer, enableStaticRendering, isUsingStaticRendering, observerBatching, useAsObservableSource, useLocalObservable, useLocalStore, useObserver, useStaticRendering } from 'mobx-react-lite'; | ||
var symbolId = 0; | ||
function createSymbol(name) { | ||
if (typeof Symbol === "function") { | ||
return Symbol(name); | ||
} | ||
var symbol = "__$mobx-react " + name + " (" + symbolId + ")"; | ||
symbolId++; | ||
return symbol; | ||
} | ||
var createdSymbols = {}; | ||
function newSymbol(name) { | ||
if (!createdSymbols[name]) { | ||
createdSymbols[name] = createSymbol(name); | ||
} | ||
return createdSymbols[name]; | ||
} | ||
function shallowEqual(objA, objB) { | ||
@@ -31,14 +11,10 @@ //From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js | ||
} | ||
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) { | ||
return false; | ||
} | ||
var keysA = Object.keys(objA); | ||
var keysB = Object.keys(objB); | ||
if (keysA.length !== keysB.length) { | ||
return false; | ||
} | ||
for (var i = 0; i < keysA.length; i++) { | ||
@@ -49,6 +25,4 @@ if (!Object.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { | ||
} | ||
return true; | ||
} | ||
function is(x, y) { | ||
@@ -61,5 +35,4 @@ // From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js | ||
} | ||
} // based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js | ||
} | ||
// based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js | ||
var hoistBlackList = { | ||
@@ -90,28 +63,7 @@ $$typeof: 1, | ||
/** | ||
* Helper to set `prop` to `this` as non-enumerable (hidden prop) | ||
* @param target | ||
* @param prop | ||
* @param value | ||
*/ | ||
function setHiddenProp(target, prop, value) { | ||
if (!Object.hasOwnProperty.call(target, prop)) { | ||
Object.defineProperty(target, prop, { | ||
enumerable: false, | ||
configurable: true, | ||
writable: true, | ||
value: value | ||
}); | ||
} else { | ||
target[prop] = value; | ||
} | ||
} | ||
/** | ||
* Utilities for patching componentWillUnmount, to make sure @disposeOnUnmount works correctly icm with user defined hooks | ||
* and the handler provided by mobx-react | ||
*/ | ||
var mobxMixins = /*#__PURE__*/newSymbol("patchMixins"); | ||
var mobxPatchedDefinition = /*#__PURE__*/newSymbol("patchedDefinition"); | ||
var mobxMixins = /*#__PURE__*/Symbol("patchMixins"); | ||
var mobxPatchedDefinition = /*#__PURE__*/Symbol("patchedDefinition"); | ||
function getMixins(target, methodName) { | ||
@@ -124,24 +76,17 @@ var mixins = target[mobxMixins] = target[mobxMixins] || {}; | ||
} | ||
function wrapper(realMethod, mixins) { | ||
var _this = this; | ||
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { | ||
args[_key - 2] = arguments[_key]; | ||
} | ||
// locks are used to ensure that mixins are invoked only once per invocation, even on recursive calls | ||
mixins.locks++; | ||
try { | ||
var retVal; | ||
if (realMethod !== undefined && realMethod !== null) { | ||
retVal = realMethod.apply(this, args); | ||
} | ||
return retVal; | ||
} finally { | ||
mixins.locks--; | ||
if (mixins.locks === 0) { | ||
@@ -154,3 +99,2 @@ mixins.methods.forEach(function (mx) { | ||
} | ||
function wrapFunction(realMethod, mixins) { | ||
@@ -161,18 +105,12 @@ var fn = function fn() { | ||
} | ||
wrapper.call.apply(wrapper, [this, realMethod, mixins].concat(args)); | ||
}; | ||
return fn; | ||
} | ||
function patch(target, methodName, mixinMethod) { | ||
var mixins = getMixins(target, methodName); | ||
if (mixins.methods.indexOf(mixinMethod) < 0) { | ||
mixins.methods.push(mixinMethod); | ||
} | ||
var oldDefinition = Object.getOwnPropertyDescriptor(target, methodName); | ||
if (oldDefinition && oldDefinition[mobxPatchedDefinition]) { | ||
@@ -182,3 +120,2 @@ // already patched definition, do not repatch | ||
} | ||
var originalMethod = target[methodName]; | ||
@@ -188,6 +125,4 @@ var newDefinition = createDefinition(target, methodName, oldDefinition ? oldDefinition.enumerable : undefined, mixins, originalMethod); | ||
} | ||
function createDefinition(target, methodName, enumerable, mixins, originalMethod) { | ||
var _ref; | ||
var wrappedFunc = wrapFunction(originalMethod, mixins); | ||
@@ -210,233 +145,219 @@ return _ref = {}, _ref[mobxPatchedDefinition] = true, _ref.get = function get() { | ||
var mobxAdminProperty = $mobx || "$mobx"; // BC | ||
var mobxObserverProperty = /*#__PURE__*/newSymbol("isMobXReactObserver"); | ||
var mobxIsUnmounted = /*#__PURE__*/newSymbol("isUnmounted"); | ||
var skipRenderKey = /*#__PURE__*/newSymbol("skipRender"); | ||
var isForcingUpdateKey = /*#__PURE__*/newSymbol("isForcingUpdate"); | ||
var administrationSymbol = /*#__PURE__*/Symbol("ObserverAdministration"); | ||
var isMobXReactObserverSymbol = /*#__PURE__*/Symbol("isMobXReactObserver"); | ||
function getAdministration(component) { | ||
var _component$administra; | ||
// We create administration lazily, because we can't patch constructor | ||
// and the exact moment of initialization partially depends on React internals. | ||
// At the time of writing this, the first thing invoked is one of the observable getter/setter (state/props/context). | ||
return (_component$administra = component[administrationSymbol]) != null ? _component$administra : component[administrationSymbol] = { | ||
reaction: null, | ||
mounted: false, | ||
forceUpdate: null, | ||
name: getDisplayName(component.constructor), | ||
state: undefined, | ||
props: undefined, | ||
context: undefined, | ||
propsAtom: createAtom("props"), | ||
stateAtom: createAtom("state"), | ||
contextAtom: createAtom("context"), | ||
isUpdating: false | ||
}; | ||
} | ||
function makeClassComponentObserver(componentClass) { | ||
var target = componentClass.prototype; | ||
if (componentClass[mobxObserverProperty]) { | ||
var displayName = getDisplayName(target); | ||
var prototype = componentClass.prototype; | ||
if (componentClass[isMobXReactObserverSymbol]) { | ||
var displayName = getDisplayName(componentClass); | ||
console.warn("The provided component class (" + displayName + ")\n has already been declared as an observer component."); | ||
} else { | ||
componentClass[mobxObserverProperty] = true; | ||
componentClass[isMobXReactObserverSymbol] = true; | ||
} | ||
if (target.componentWillReact) { | ||
if (prototype.componentWillReact) { | ||
throw new Error("The componentWillReact life-cycle event is no longer supported"); | ||
} | ||
if (componentClass["__proto__"] !== PureComponent) { | ||
if (!target.shouldComponentUpdate) { | ||
target.shouldComponentUpdate = observerSCU; | ||
} else if (target.shouldComponentUpdate !== observerSCU) { | ||
if (!prototype.shouldComponentUpdate) { | ||
prototype.shouldComponentUpdate = observerSCU; | ||
} else if (prototype.shouldComponentUpdate !== observerSCU) { | ||
// n.b. unequal check, instead of existence check, as @observer might be on superclass as well | ||
throw new Error("It is not allowed to use shouldComponentUpdate in observer based components."); | ||
} | ||
} // this.props and this.state are made observable, just to make sure @computed fields that | ||
} | ||
// this.props and this.state are made observable, just to make sure @computed fields that | ||
// are defined inside the component, and which rely on state or props, re-compute if state or props change | ||
// (otherwise the computed wouldn't update and become stale on props change, since props are not observable) | ||
// 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+ | ||
makeObservableProp(target, "props"); | ||
makeObservableProp(target, "state"); | ||
if (componentClass.contextType) { | ||
makeObservableProp(target, "context"); | ||
} | ||
var originalRender = target.render; | ||
Object.defineProperties(prototype, { | ||
props: observablePropsDescriptor, | ||
state: observableStateDescriptor, | ||
context: observableContextDescriptor | ||
}); | ||
var originalRender = prototype.render; | ||
if (typeof originalRender !== "function") { | ||
var _displayName = getDisplayName(target); | ||
var _displayName = getDisplayName(componentClass); | ||
throw new Error("[mobx-react] class component (" + _displayName + ") is missing `render` method." + "\n`observer` requires `render` being a function defined on prototype." + "\n`render = () => {}` or `render = function() {}` is not supported."); | ||
} | ||
target.render = function () { | ||
this.render = isUsingStaticRendering() ? originalRender : createReactiveRender.call(this, originalRender); | ||
prototype.render = function () { | ||
Object.defineProperty(this, "render", { | ||
// There is no safe way to replace render, therefore it's forbidden. | ||
configurable: false, | ||
writable: false, | ||
value: isUsingStaticRendering() ? originalRender : createReactiveRender.call(this, originalRender) | ||
}); | ||
return this.render(); | ||
}; | ||
patch(target, "componentDidMount", function () { | ||
this[mobxIsUnmounted] = false; | ||
if (!this.render[mobxAdminProperty]) { | ||
// Reaction is re-created automatically during render, but a component can re-mount and skip render #3395. | ||
// To re-create the reaction and re-subscribe to relevant observables we have to force an update. | ||
Component.prototype.forceUpdate.call(this); | ||
patch(prototype, "componentDidMount", function () { | ||
var _this = this; | ||
// `componentDidMount` may not be called at all. React can abandon the instance after `render`. | ||
// That's why we use finalization registry to dispose reaction created during render. | ||
// Happens with `<Suspend>` see #3492 | ||
// | ||
// `componentDidMount` can be called immediately after `componentWillUnmount` without calling `render` in between. | ||
// Happens with `<StrictMode>`see #3395. | ||
// | ||
// If `componentDidMount` is called, it's guaranteed to run synchronously with render (similary to `useLayoutEffect`). | ||
// Therefore we don't have to worry about external (observable) state being updated before mount (no state version checking). | ||
// | ||
// Things may change: "In the future, React will provide a feature that lets components preserve state between unmounts" | ||
var admin = getAdministration(this); | ||
admin.mounted = true; | ||
// Component instance committed, prevent reaction disposal. | ||
_observerFinalizationRegistry.unregister(admin); | ||
// We don't set forceUpdate before mount because it requires a reference to `this`, | ||
// therefore `this` could NOT be garbage collected before mount, | ||
// preventing reaction disposal by FinalizationRegistry and leading to memory leak. | ||
// As an alternative we could have `admin.instanceRef = new WeakRef(this)`, but lets avoid it if possible. | ||
admin.forceUpdate = function () { | ||
return _this.forceUpdate(); | ||
}; | ||
if (!admin.reaction) { | ||
// 1. Instance was unmounted (reaction disposed) and immediately remounted without running render #3395. | ||
// 2. Reaction was disposed by finalization registry before mount. Shouldn't ever happen for class components: | ||
// `componentDidMount` runs synchronously after render, but our registry are deferred (can't run in between). | ||
// In any case we lost subscriptions to observables, so we have to create new reaction and re-render to resubscribe. | ||
// The reaction will be created lazily by following render. | ||
admin.forceUpdate(); | ||
} | ||
}); | ||
patch(target, "componentWillUnmount", function () { | ||
patch(prototype, "componentWillUnmount", function () { | ||
var _admin$reaction; | ||
if (isUsingStaticRendering()) { | ||
return; | ||
} | ||
var reaction = this.render[mobxAdminProperty]; | ||
if (reaction) { | ||
reaction.dispose(); // Forces reaction to be re-created on next render | ||
this.render[mobxAdminProperty] = null; | ||
} else { | ||
// Render may have been hot-swapped and/or overridden by a subclass. | ||
var _displayName2 = getDisplayName(this); | ||
console.warn("The reactive render of an observer class component (" + _displayName2 + ")\n was overridden after MobX attached. This may result in a memory leak if the\n overridden reactive render was not properly disposed."); | ||
} | ||
this[mobxIsUnmounted] = true; | ||
var admin = getAdministration(this); | ||
(_admin$reaction = admin.reaction) == null ? void 0 : _admin$reaction.dispose(); | ||
admin.reaction = null; | ||
admin.forceUpdate = null; | ||
admin.mounted = false; | ||
}); | ||
return componentClass; | ||
} // Generates a friendly name for debugging | ||
function getDisplayName(comp) { | ||
return comp.displayName || comp.name || comp.constructor && (comp.constructor.displayName || comp.constructor.name) || "<component>"; | ||
} | ||
// Generates a friendly name for debugging | ||
function getDisplayName(componentClass) { | ||
return componentClass.displayName || componentClass.name || "<component>"; | ||
} | ||
function createReactiveRender(originalRender) { | ||
var _this = this; | ||
/** | ||
* If props are shallowly modified, react will render anyway, | ||
* so atom.reportChanged() should not result in yet another re-render | ||
*/ | ||
setHiddenProp(this, skipRenderKey, false); | ||
/** | ||
* forceUpdate will re-assign this.props. We don't want that to cause a loop, | ||
* so detect these changes | ||
*/ | ||
setHiddenProp(this, isForcingUpdateKey, false); | ||
var initialName = getDisplayName(this); | ||
var boundOriginalRender = originalRender.bind(this); | ||
var isRenderingPending = false; | ||
var createReaction = function createReaction() { | ||
var reaction = new Reaction(initialName + ".render()", function () { | ||
if (!isRenderingPending) { | ||
// N.B. Getting here *before mounting* means that a component constructor has side effects (see the relevant test in misc.test.tsx) | ||
// This unidiomatic React usage but React will correctly warn about this so we continue as usual | ||
// See #85 / Pull #44 | ||
isRenderingPending = true; | ||
if (_this[mobxIsUnmounted] !== true) { | ||
var hasError = true; | ||
try { | ||
setHiddenProp(_this, isForcingUpdateKey, true); | ||
if (!_this[skipRenderKey]) { | ||
Component.prototype.forceUpdate.call(_this); | ||
} | ||
hasError = false; | ||
} finally { | ||
setHiddenProp(_this, isForcingUpdateKey, false); | ||
if (hasError) { | ||
reaction.dispose(); // Forces reaction to be re-created on next render | ||
_this.render[mobxAdminProperty] = null; | ||
} | ||
} | ||
} | ||
var admin = getAdministration(this); | ||
function reactiveRender() { | ||
if (!admin.reaction) { | ||
// Create reaction lazily to support re-mounting #3395 | ||
admin.reaction = createReaction(admin); | ||
if (!admin.mounted) { | ||
// React can abandon this instance and never call `componentDidMount`/`componentWillUnmount`, | ||
// we have to make sure reaction will be disposed. | ||
_observerFinalizationRegistry.register(this, admin, this); | ||
} | ||
}); | ||
reaction["reactComponent"] = _this; | ||
return reaction; | ||
}; | ||
function reactiveRender() { | ||
var _reactiveRender$mobxA; | ||
isRenderingPending = false; // Create reaction lazily to support re-mounting #3395 | ||
var reaction = (_reactiveRender$mobxA = reactiveRender[mobxAdminProperty]) != null ? _reactiveRender$mobxA : reactiveRender[mobxAdminProperty] = createReaction(); | ||
var exception = undefined; | ||
var rendering = undefined; | ||
reaction.track(function () { | ||
} | ||
var error = undefined; | ||
var renderResult = undefined; | ||
admin.reaction.track(function () { | ||
try { | ||
// TODO@major | ||
// Optimization: replace with _allowStateChangesStart/End (not available in mobx@6.0.0) | ||
rendering = _allowStateChanges(false, boundOriginalRender); | ||
renderResult = _allowStateChanges(false, boundOriginalRender); | ||
} catch (e) { | ||
exception = e; | ||
error = e; | ||
} | ||
}); | ||
if (exception) { | ||
throw exception; | ||
if (error) { | ||
throw error; | ||
} | ||
return rendering; | ||
return renderResult; | ||
} | ||
return reactiveRender; | ||
} | ||
function createReaction(admin) { | ||
return new Reaction(admin.name + ".render()", function () { | ||
if (admin.isUpdating) { | ||
// Reaction is suppressed when setting new state/props/context, | ||
// this is when component is already being updated. | ||
return; | ||
} | ||
if (!admin.mounted) { | ||
// This is neccessary to avoid react warning about calling forceUpdate on component that isn't mounted yet. | ||
// This happens when component is abandoned after render - our reaction is already created and reacts to changes. | ||
// Due to the synchronous nature of `componenDidMount`, we don't have to worry that component could eventually mount and require update. | ||
return; | ||
} | ||
try { | ||
// forceUpdate sets new `props`, since we made it observable, it would `reportChanged`, causing a loop. | ||
admin.isUpdating = true; | ||
admin.forceUpdate == null ? void 0 : admin.forceUpdate(); | ||
} catch (error) { | ||
var _admin$reaction2; | ||
(_admin$reaction2 = admin.reaction) == null ? void 0 : _admin$reaction2.dispose(); | ||
admin.reaction = null; | ||
} finally { | ||
admin.isUpdating = false; | ||
} | ||
}); | ||
} | ||
function observerSCU(nextProps, nextState) { | ||
if (isUsingStaticRendering()) { | ||
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."); | ||
} // update on any state changes (as is the default) | ||
} | ||
// update on any state changes (as is the default) | ||
if (this.state !== nextState) { | ||
return true; | ||
} // update if props are shallowly not equal, inspired by PureRenderMixin | ||
} | ||
// update if props are shallowly not equal, inspired by PureRenderMixin | ||
// we could return just 'false' here, and avoid the `skipRender` checks etc | ||
// however, it is nicer if lifecycle events are triggered like usually, | ||
// so we return true here if props are shallowly modified. | ||
return !shallowEqual(this.props, nextProps); | ||
} | ||
function makeObservableProp(target, propName) { | ||
var valueHolderKey = newSymbol("reactProp_" + propName + "_valueHolder"); | ||
var atomHolderKey = newSymbol("reactProp_" + propName + "_atomHolder"); | ||
function getAtom() { | ||
if (!this[atomHolderKey]) { | ||
setHiddenProp(this, atomHolderKey, createAtom("reactive " + propName)); | ||
} | ||
return this[atomHolderKey]; | ||
} | ||
Object.defineProperty(target, propName, { | ||
function createObservablePropDescriptor(key) { | ||
var atomKey = key + "Atom"; | ||
return { | ||
configurable: true, | ||
enumerable: true, | ||
get: function get() { | ||
var prevReadState = false; // Why this check? BC? | ||
// @ts-expect-error | ||
if (_allowStateReadsStart && _allowStateReadsEnd) { | ||
prevReadState = _allowStateReadsStart(true); | ||
} | ||
getAtom.call(this).reportObserved(); // Why this check? BC? | ||
// @ts-expect-error | ||
if (_allowStateReadsStart && _allowStateReadsEnd) { | ||
_allowStateReadsEnd(prevReadState); | ||
} | ||
return this[valueHolderKey]; | ||
var admin = getAdministration(this); | ||
var prevReadState = _allowStateReadsStart(true); | ||
admin[atomKey].reportObserved(); | ||
_allowStateReadsEnd(prevReadState); | ||
return admin[key]; | ||
}, | ||
set: function set(v) { | ||
if (!this[isForcingUpdateKey] && !shallowEqual(this[valueHolderKey], v)) { | ||
setHiddenProp(this, valueHolderKey, v); | ||
setHiddenProp(this, skipRenderKey, true); | ||
getAtom.call(this).reportChanged(); | ||
setHiddenProp(this, skipRenderKey, false); | ||
set: function set(value) { | ||
var admin = getAdministration(this); | ||
// forceUpdate issued by reaction sets new props. | ||
// It sets isUpdating to true to prevent loop. | ||
if (!admin.isUpdating && !shallowEqual(admin[key], value)) { | ||
admin[key] = value; | ||
// This notifies all observers including our component, | ||
// but we don't want to cause `forceUpdate`, because component is already updating, | ||
// therefore supress component reaction. | ||
admin.isUpdating = true; | ||
admin[atomKey].reportChanged(); | ||
admin.isUpdating = false; | ||
} else { | ||
setHiddenProp(this, valueHolderKey, v); | ||
admin[key] = value; | ||
} | ||
} | ||
}); | ||
}; | ||
} | ||
var observablePropsDescriptor = /*#__PURE__*/createObservablePropDescriptor("props"); | ||
var observableStateDescriptor = /*#__PURE__*/createObservablePropDescriptor("state"); | ||
var observableContextDescriptor = /*#__PURE__*/createObservablePropDescriptor("context"); | ||
@@ -446,3 +367,2 @@ /** | ||
*/ | ||
function observer(component) { | ||
@@ -452,3 +372,2 @@ if (component["isMobxInjector"] === true) { | ||
} | ||
if (Object.prototype.isPrototypeOf.call(Component, component) || Object.prototype.isPrototypeOf.call(PureComponent, component)) { | ||
@@ -464,6 +383,5 @@ // Class component | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
_extends = Object.assign ? Object.assign.bind() : function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
@@ -475,9 +393,6 @@ if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
} | ||
return target; | ||
}; | ||
return _extends.apply(this, arguments); | ||
} | ||
function _objectWithoutPropertiesLoose(source, excluded) { | ||
@@ -488,3 +403,2 @@ if (source == null) return {}; | ||
var key, i; | ||
for (i = 0; i < sourceKeys.length; i++) { | ||
@@ -495,3 +409,2 @@ key = sourceKeys[i]; | ||
} | ||
return target; | ||
@@ -504,12 +417,8 @@ } | ||
var children = props.children, | ||
stores = _objectWithoutPropertiesLoose(props, _excluded); | ||
stores = _objectWithoutPropertiesLoose(props, _excluded); | ||
var parentValue = React__default.useContext(MobXProviderContext); | ||
var mutableProviderRef = React__default.useRef(_extends({}, parentValue, stores)); | ||
var value = mutableProviderRef.current; | ||
if (process.env.NODE_ENV !== "production") { | ||
var newValue = _extends({}, value, stores); // spread in previous state for the context based stores | ||
if (!shallowEqual(value, newValue)) { | ||
@@ -519,3 +428,2 @@ 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."); | ||
} | ||
return React__default.createElement(MobXProviderContext.Provider, { | ||
@@ -530,3 +438,2 @@ value: value | ||
*/ | ||
function createStoreInjector(grabStoresFn, component, injectNames, makeReactive) { | ||
@@ -536,10 +443,7 @@ // Support forward refs | ||
var newProps = _extends({}, props); | ||
var context = React__default.useContext(MobXProviderContext); | ||
Object.assign(newProps, grabStoresFn(context || {}, newProps) || {}); | ||
if (ref) { | ||
newProps.ref = ref; | ||
} | ||
return React__default.createElement(component, newProps); | ||
@@ -550,3 +454,2 @@ }); | ||
// Static fields from component should be visible on the generated Injector | ||
copyStaticProperties(component, Injector); | ||
@@ -557,3 +460,2 @@ Injector["wrappedComponent"] = component; | ||
} | ||
function getInjectName(component, injectNames) { | ||
@@ -565,3 +467,2 @@ var displayName; | ||
} | ||
function grabStoresByName(storeNames) { | ||
@@ -584,4 +485,2 @@ return function (baseStores, nextProps) { | ||
*/ | ||
function inject() { | ||
@@ -591,3 +490,2 @@ for (var _len = arguments.length, storeNames = new Array(_len), _key = 0; _key < _len; _key++) { | ||
} | ||
if (typeof arguments[0] === "function") { | ||
@@ -605,5 +503,6 @@ var grabStoresFn = arguments[0]; | ||
var protoStoreKey = /*#__PURE__*/newSymbol("disposeOnUnmountProto"); | ||
var instStoreKey = /*#__PURE__*/newSymbol("disposeOnUnmountInst"); | ||
var reactMajorVersion = /*#__PURE__*/Number.parseInt( /*#__PURE__*/React__default.version.split(".")[0]); | ||
var warnedAboutDisposeOnUnmountDeprecated = false; | ||
var protoStoreKey = /*#__PURE__*/Symbol("disposeOnUnmountProto"); | ||
var instStoreKey = /*#__PURE__*/Symbol("disposeOnUnmountInst"); | ||
function runDisposersOnWillUnmount() { | ||
@@ -613,3 +512,2 @@ var _this = this; | ||
var prop = typeof propKeyOrFunction === "string" ? _this[propKeyOrFunction] : propKeyOrFunction; | ||
if (prop !== undefined && prop !== null) { | ||
@@ -622,3 +520,5 @@ if (Array.isArray(prop)) prop.map(function (f) { | ||
} | ||
/** | ||
* @deprecated `disposeOnUnmount` is not compatible with React 18 and higher. | ||
*/ | ||
function disposeOnUnmount(target, propertyKeyOrFunction) { | ||
@@ -630,30 +530,35 @@ if (Array.isArray(propertyKeyOrFunction)) { | ||
} | ||
if (!warnedAboutDisposeOnUnmountDeprecated) { | ||
if (reactMajorVersion >= 18) { | ||
console.error("[mobx-react] disposeOnUnmount is not compatible with React 18 and higher. Don't use it."); | ||
} else { | ||
console.warn("[mobx-react] disposeOnUnmount is deprecated. It won't work correctly with React 18 and higher."); | ||
} | ||
warnedAboutDisposeOnUnmountDeprecated = true; | ||
} | ||
var c = Object.getPrototypeOf(target).constructor; | ||
var c2 = Object.getPrototypeOf(target.constructor); // Special case for react-hot-loader | ||
var c2 = Object.getPrototypeOf(target.constructor); | ||
// Special case for react-hot-loader | ||
var c3 = Object.getPrototypeOf(Object.getPrototypeOf(target)); | ||
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)) { | ||
throw new Error("[mobx-react] disposeOnUnmount only supports direct subclasses of React.Component or React.PureComponent."); | ||
} | ||
if (typeof propertyKeyOrFunction !== "string" && typeof propertyKeyOrFunction !== "function" && !Array.isArray(propertyKeyOrFunction)) { | ||
throw new Error("[mobx-react] disposeOnUnmount only works if the parameter is either a property key or a function."); | ||
} // decorator's target is the prototype, so it doesn't have any instance properties like props | ||
var isDecorator = typeof propertyKeyOrFunction === "string"; // add property key / function we want run (disposed) to the store | ||
} | ||
// decorator's target is the prototype, so it doesn't have any instance properties like props | ||
var isDecorator = typeof propertyKeyOrFunction === "string"; | ||
// add property key / function we want run (disposed) to the store | ||
var componentWasAlreadyModified = !!target[protoStoreKey] || !!target[instStoreKey]; | ||
var store = isDecorator ? // decorators are added to the prototype store | ||
target[protoStoreKey] || (target[protoStoreKey] = []) : // functions are added to the instance store | ||
var store = isDecorator ? | ||
// decorators are added to the prototype store | ||
target[protoStoreKey] || (target[protoStoreKey] = []) : | ||
// functions are added to the instance store | ||
target[instStoreKey] || (target[instStoreKey] = []); | ||
store.push(propertyKeyOrFunction); // tweak the component class componentWillUnmount if not done already | ||
store.push(propertyKeyOrFunction); | ||
// tweak the component class componentWillUnmount if not done already | ||
if (!componentWasAlreadyModified) { | ||
patch(target, "componentWillUnmount", runDisposersOnWillUnmount); | ||
} // return the disposer as is if invoked as a non decorator | ||
} | ||
// return the disposer as is if invoked as a non decorator | ||
if (typeof propertyKeyOrFunction !== "string") { | ||
@@ -664,2 +569,3 @@ return propertyKeyOrFunction; | ||
// Copied from React.PropTypes | ||
function createChainableTypeChecker(validator) { | ||
@@ -670,7 +576,5 @@ function checkType(isRequired, props, propName, componentName, location, propFullName) { | ||
} | ||
return untracked(function () { | ||
componentName = componentName || "<<anonymous>>"; | ||
propFullName = propFullName || propName; | ||
if (props[propName] == null) { | ||
@@ -681,3 +585,2 @@ if (isRequired) { | ||
} | ||
return null; | ||
@@ -690,10 +593,8 @@ } else { | ||
} | ||
var chainedCheckType = checkType.bind(null, false); // Add isRequired to satisfy Requirable | ||
var chainedCheckType = checkType.bind(null, false); | ||
// Add isRequired to satisfy Requirable | ||
chainedCheckType.isRequired = checkType.bind(null, true); | ||
return chainedCheckType; | ||
} // Copied from React.PropTypes | ||
} | ||
// Copied from React.PropTypes | ||
function isSymbol(propType, propValue) { | ||
@@ -703,25 +604,19 @@ // Native Symbol. | ||
return true; | ||
} // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' | ||
} | ||
// 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' | ||
if (propValue["@@toStringTag"] === "Symbol") { | ||
return true; | ||
} // Fallback for non-spec compliant Symbols which are polyfilled. | ||
} | ||
// Fallback for non-spec compliant Symbols which are polyfilled. | ||
if (typeof Symbol === "function" && propValue instanceof Symbol) { | ||
return true; | ||
} | ||
return false; | ||
} // Copied from React.PropTypes | ||
} | ||
// Copied from React.PropTypes | ||
function getPropType(propValue) { | ||
var propType = typeof propValue; | ||
if (Array.isArray(propValue)) { | ||
return "array"; | ||
} | ||
if (propValue instanceof RegExp) { | ||
@@ -733,15 +628,11 @@ // Old webkits (at least until Android 4.0) return 'function' rather than | ||
} | ||
if (isSymbol(propType, propValue)) { | ||
return "symbol"; | ||
} | ||
return propType; | ||
} // This handles more types than `getPropType`. Only used for error messages. | ||
} | ||
// This handles more types than `getPropType`. Only used for error messages. | ||
// Copied from React.PropTypes | ||
function getPreciseType(propValue) { | ||
var propType = getPropType(propValue); | ||
if (propType === "object") { | ||
@@ -754,6 +645,4 @@ if (propValue instanceof Date) { | ||
} | ||
return propType; | ||
} | ||
function createObservableTypeCheckerCreator(allowNativeType, mobxType) { | ||
@@ -765,5 +654,3 @@ return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) { | ||
} | ||
var mobxChecker; | ||
switch (mobxType) { | ||
@@ -773,17 +660,12 @@ case "Array": | ||
break; | ||
case "Object": | ||
mobxChecker = isObservableObject; | ||
break; | ||
case "Map": | ||
mobxChecker = isObservableMap; | ||
break; | ||
default: | ||
throw new Error("Unexpected mobxType: " + mobxType); | ||
} | ||
var propValue = props[propName]; | ||
if (!mobxChecker(propValue)) { | ||
@@ -794,3 +676,2 @@ var preciseType = getPreciseType(propValue); | ||
} | ||
return null; | ||
@@ -800,3 +681,2 @@ }); | ||
} | ||
function createObservableArrayOfTypeChecker(allowNativeType, typeChecker) { | ||
@@ -807,3 +687,2 @@ return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) { | ||
} | ||
return untracked(function () { | ||
@@ -816,3 +695,2 @@ if (typeof typeChecker !== "function") { | ||
var propValue = props[propName]; | ||
for (var i = 0; i < propValue.length; i++) { | ||
@@ -822,3 +700,2 @@ error = typeChecker.apply(void 0, [propValue, i, componentName, location, propFullName + "[" + i + "]"].concat(rest)); | ||
} | ||
return null; | ||
@@ -829,3 +706,2 @@ } | ||
} | ||
var observableArray = /*#__PURE__*/createObservableTypeCheckerCreator(false, "Array"); | ||
@@ -848,6 +724,10 @@ var observableArrayOf = /*#__PURE__*/createObservableArrayOfTypeChecker.bind(null, false); | ||
if (!Component) throw new Error("mobx-react requires React to be available"); | ||
if (!observable) throw new Error("mobx-react requires mobx to be available"); | ||
if (!Component) { | ||
throw new Error("mobx-react requires React to be available"); | ||
} | ||
if (!observable) { | ||
throw new Error("mobx-react requires mobx to be available"); | ||
} | ||
export { MobXProviderContext, PropTypes, Provider, disposeOnUnmount, inject, observer }; | ||
//# sourceMappingURL=mobxreact.esm.js.map |
@@ -1,2 +0,2 @@ | ||
import{_allowStateReadsStart as e,_allowStateReadsEnd as r,$mobx as t,_allowStateChanges as n,createAtom as o,Reaction as i,untracked as a,isObservableMap as c,isObservableObject as s,isObservableArray as u,observable as l}from"mobx";import f,{PureComponent as p,Component as d}from"react";import{isUsingStaticRendering as b,observer as y}from"mobx-react-lite";export{Observer,enableStaticRendering,isUsingStaticRendering,observerBatching,useAsObservableSource,useLocalObservable,useLocalStore,useObserver,useStaticRendering}from"mobx-react-lite";var v=0,m={};function h(e){return m[e]||(m[e]=function(e){if("function"==typeof Symbol)return Symbol(e);var r="__$mobx-react "+e+" ("+v+")";return v++,r}(e)),m[e]}function O(e,r){if(g(e,r))return!0;if("object"!=typeof e||null===e||"object"!=typeof r||null===r)return!1;var t=Object.keys(e),n=Object.keys(r);if(t.length!==n.length)return!1;for(var o=0;o<t.length;o++)if(!Object.hasOwnProperty.call(r,t[o])||!g(e[t[o]],r[t[o]]))return!1;return!0}function g(e,r){return e===r?0!==e||1/e==1/r:e!=e&&r!=r}var w={$$typeof:1,render:1,compare:1,type:1,childContextTypes:1,contextType:1,contextTypes:1,defaultProps:1,getDefaultProps:1,getDerivedStateFromError:1,getDerivedStateFromProps:1,mixins:1,displayName:1,propTypes:1};function j(e,r,t){Object.hasOwnProperty.call(e,r)?e[r]=t:Object.defineProperty(e,r,{enumerable:!1,configurable:!0,writable:!0,value:t})}var x=h("patchMixins"),P=h("patchedDefinition");function E(e,r){for(var t=this,n=arguments.length,o=new Array(n>2?n-2:0),i=2;i<n;i++)o[i-2]=arguments[i];r.locks++;try{var a;return null!=e&&(a=e.apply(this,o)),a}finally{r.locks--,0===r.locks&&r.methods.forEach((function(e){e.apply(t,o)}))}}function A(e,r){return function(){for(var t=arguments.length,n=new Array(t),o=0;o<t;o++)n[o]=arguments[o];E.call.apply(E,[this,e,r].concat(n))}}function C(e,r,t){var n=function(e,r){var t=e[x]=e[x]||{},n=t[r]=t[r]||{};return n.locks=n.locks||0,n.methods=n.methods||[],n}(e,r);n.methods.indexOf(t)<0&&n.methods.push(t);var o=Object.getOwnPropertyDescriptor(e,r);if(!o||!o[P]){var i=function e(r,t,n,o,i){var a,c=A(i,o);return(a={})[P]=!0,a.get=function(){return c},a.set=function(i){if(this===r)c=A(i,o);else{var a=e(this,t,n,o,i);Object.defineProperty(this,t,a)}},a.configurable=!0,a.enumerable=n,a}(e,r,o?o.enumerable:void 0,n,e[r]);Object.defineProperty(e,r,i)}}var k=t||"$mobx",R=h("isMobXReactObserver"),U=h("isUnmounted"),S=h("skipRender"),M=h("isForcingUpdate");function T(e){var r=e.prototype;if(e[R]){var t=_(r);console.warn("The provided component class ("+t+")\n has already been declared as an observer component.")}else e[R]=!0;if(r.componentWillReact)throw new Error("The componentWillReact life-cycle event is no longer supported");if(e.__proto__!==p)if(r.shouldComponentUpdate){if(r.shouldComponentUpdate!==N)throw new Error("It is not allowed to use shouldComponentUpdate in observer based components.")}else r.shouldComponentUpdate=N;I(r,"props"),I(r,"state"),e.contextType&&I(r,"context");var n=r.render;if("function"!=typeof n){var o=_(r);throw new Error("[mobx-react] class component ("+o+") is missing `render` method.\n`observer` requires `render` being a function defined on prototype.\n`render = () => {}` or `render = function() {}` is not supported.")}return r.render=function(){return this.render=b()?n:D.call(this,n),this.render()},C(r,"componentDidMount",(function(){this[U]=!1,this.render[k]||d.prototype.forceUpdate.call(this)})),C(r,"componentWillUnmount",(function(){if(!b()){var e=this.render[k];if(e)e.dispose(),this.render[k]=null;else{var r=_(this);console.warn("The reactive render of an observer class component ("+r+")\n was overridden after MobX attached. This may result in a memory leak if the\n overridden reactive render was not properly disposed.")}this[U]=!0}})),e}function _(e){return e.displayName||e.name||e.constructor&&(e.constructor.displayName||e.constructor.name)||"<component>"}function D(e){var r=this;j(this,S,!1),j(this,M,!1);var t=_(this),o=e.bind(this),a=!1;return function e(){var c;a=!1;var s=null!=(c=e[k])?c:e[k]=function(){var e=new i(t+".render()",(function(){if(!a&&(a=!0,!0!==r[U])){var t=!0;try{j(r,M,!0),r[S]||d.prototype.forceUpdate.call(r),t=!1}finally{j(r,M,!1),t&&(e.dispose(),r.render[k]=null)}}}));return e.reactComponent=r,e}(),u=void 0,l=void 0;if(s.track((function(){try{l=n(!1,o)}catch(e){u=e}})),u)throw u;return l}}function N(e,r){return b()&&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."),this.state!==r||!O(this.props,e)}function I(t,n){var i=h("reactProp_"+n+"_valueHolder"),a=h("reactProp_"+n+"_atomHolder");function c(){return this[a]||j(this,a,o("reactive "+n)),this[a]}Object.defineProperty(t,n,{configurable:!0,enumerable:!0,get:function(){var t=!1;return e&&r&&(t=e(!0)),c.call(this).reportObserved(),e&&r&&r(t),this[i]},set:function(e){this[M]||O(this[i],e)?j(this,i,e):(j(this,i,e),j(this,S,!0),c.call(this).reportChanged(),j(this,S,!1))}})}function q(e){return!0===e.isMobxInjector&&console.warn("Mobx observer: You are trying to use `observer` on a component that already has `inject`. Please apply `observer` before applying `inject`"),Object.prototype.isPrototypeOf.call(d,e)||Object.prototype.isPrototypeOf.call(p,e)?T(e):y(e)}function L(){return(L=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}).apply(this,arguments)}var W=["children"],X=f.createContext({});function $(e){var r=e.children,t=function(e,r){if(null==e)return{};var t,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r.indexOf(t=i[n])>=0||(o[t]=e[t]);return o}(e,W),n=f.useContext(X),o=f.useRef(L({},n,t));return f.createElement(X.Provider,{value:o.current},r)}function F(e,r,t,n){var o,i,a,c=f.forwardRef((function(t,n){var o=L({},t),i=f.useContext(X);return Object.assign(o,e(i||{},o)||{}),n&&(o.ref=n),f.createElement(r,o)}));return n&&(c=q(c)),c.isMobxInjector=!0,o=r,i=c,a=Object.getOwnPropertyNames(Object.getPrototypeOf(o)),Object.getOwnPropertyNames(o).forEach((function(e){w[e]||-1!==a.indexOf(e)||Object.defineProperty(i,e,Object.getOwnPropertyDescriptor(o,e))})),c.wrappedComponent=r,c.displayName=function(e,r){var t=e.displayName||e.name||e.constructor&&e.constructor.name||"Component";return r?"inject-with-"+r+"("+t+")":"inject("+t+")"}(r,t),c}function H(e){return function(r,t){return e.forEach((function(e){if(!(e in t)){if(!(e in r))throw new Error("MobX injector: Store '"+e+"' is not available! Make sure it is provided by some Provider");t[e]=r[e]}})),t}}function B(){for(var e=arguments.length,r=new Array(e),t=0;t<e;t++)r[t]=arguments[t];if("function"==typeof arguments[0]){var n=arguments[0];return function(e){return F(n,e,n.name,!0)}}return function(e){return F(H(r),e,r.join("-"),!1)}}$.displayName="MobXProvider";var Y=h("disposeOnUnmountProto"),z=h("disposeOnUnmountInst");function G(){var e=this;[].concat(this[Y]||[],this[z]||[]).forEach((function(r){var t="string"==typeof r?e[r]:r;null!=t&&(Array.isArray(t)?t.map((function(e){return e()})):t())}))}function J(e,r){if(Array.isArray(r))return r.map((function(r){return J(e,r)}));var t=Object.getPrototypeOf(e).constructor,n=Object.getPrototypeOf(e.constructor),o=Object.getPrototypeOf(Object.getPrototypeOf(e));if(t!==f.Component&&t!==f.PureComponent&&n!==f.Component&&n!==f.PureComponent&&o!==f.Component&&o!==f.PureComponent)throw new Error("[mobx-react] disposeOnUnmount only supports direct subclasses of React.Component or React.PureComponent.");if("string"!=typeof r&&"function"!=typeof r&&!Array.isArray(r))throw new Error("[mobx-react] disposeOnUnmount only works if the parameter is either a property key or a function.");var i=!!e[Y]||!!e[z];return("string"==typeof r?e[Y]||(e[Y]=[]):e[z]||(e[z]=[])).push(r),i||C(e,"componentWillUnmount",G),"string"!=typeof r?r:void 0}function K(e){function r(r,t,n,o,i,c){for(var s=arguments.length,u=new Array(s>6?s-6:0),l=6;l<s;l++)u[l-6]=arguments[l];return a((function(){return o=o||"<<anonymous>>",c=c||n,null==t[n]?r?new Error("The "+i+" `"+c+"` is marked as required in `"+o+"`, but its value is `"+(null===t[n]?"null":"undefined")+"`."):null:e.apply(void 0,[t,n,o,i,c].concat(u))}))}var t=r.bind(null,!1);return t.isRequired=r.bind(null,!0),t}function Q(e){var r=typeof e;return Array.isArray(e)?"array":e instanceof RegExp?"object":function(e,r){return"symbol"===e||"Symbol"===r["@@toStringTag"]||"function"==typeof Symbol&&r instanceof Symbol}(r,e)?"symbol":r}function V(e,r){return K((function(t,n,o,i,l){return a((function(){if(e&&Q(t[n])===r.toLowerCase())return null;var i;switch(r){case"Array":i=u;break;case"Object":i=s;break;case"Map":i=c;break;default:throw new Error("Unexpected mobxType: "+r)}var a=t[n];if(!i(a)){var f=function(e){var r=Q(e);if("object"===r){if(e instanceof Date)return"date";if(e instanceof RegExp)return"regexp"}return r}(a),p=e?" or javascript `"+r.toLowerCase()+"`":"";return new Error("Invalid prop `"+l+"` of type `"+f+"` supplied to `"+o+"`, expected `mobx.Observable"+r+"`"+p+".")}return null}))}))}function Z(e,r){return K((function(t,n,o,i,c){for(var s=arguments.length,u=new Array(s>5?s-5:0),l=5;l<s;l++)u[l-5]=arguments[l];return a((function(){if("function"!=typeof r)return new Error("Property `"+c+"` of component `"+o+"` has invalid PropType notation.");var a=V(e,"Array")(t,n,o,i,c);if(a instanceof Error)return a;for(var s=t[n],l=0;l<s.length;l++)if((a=r.apply(void 0,[s,l,o,i,c+"["+l+"]"].concat(u)))instanceof Error)return a;return null}))}))}var ee={observableArray:V(!1,"Array"),observableArrayOf:Z.bind(null,!1),observableMap:V(!1,"Map"),observableObject:V(!1,"Object"),arrayOrObservableArray:V(!0,"Array"),arrayOrObservableArrayOf:Z.bind(null,!0),objectOrObservableObject:V(!0,"Object")};if(!d)throw new Error("mobx-react requires React to be available");if(!l)throw new Error("mobx-react requires mobx to be available");export{X as MobXProviderContext,ee as PropTypes,$ as Provider,J as disposeOnUnmount,B as inject,q as observer}; | ||
import{createAtom as e,_allowStateReadsStart as r,_allowStateReadsEnd as t,Reaction as n,_allowStateChanges as o,untracked as i,isObservableMap as a,isObservableObject as c,isObservableArray as s,observable as u}from"mobx";import p,{PureComponent as l,Component as f}from"react";import{isUsingStaticRendering as d,_observerFinalizationRegistry as b,observer as m}from"mobx-react-lite";export{Observer,enableStaticRendering,isUsingStaticRendering,observerBatching,useAsObservableSource,useLocalObservable,useLocalStore,useObserver,useStaticRendering}from"mobx-react-lite";function y(e,r){if(v(e,r))return!0;if("object"!=typeof e||null===e||"object"!=typeof r||null===r)return!1;var t=Object.keys(e),n=Object.keys(r);if(t.length!==n.length)return!1;for(var o=0;o<t.length;o++)if(!Object.hasOwnProperty.call(r,t[o])||!v(e[t[o]],r[t[o]]))return!1;return!0}function v(e,r){return e===r?0!==e||1/e==1/r:e!=e&&r!=r}var h={$$typeof:1,render:1,compare:1,type:1,childContextTypes:1,contextType:1,contextTypes:1,defaultProps:1,getDefaultProps:1,getDerivedStateFromError:1,getDerivedStateFromProps:1,mixins:1,displayName:1,propTypes:1},O=Symbol("patchMixins"),g=Symbol("patchedDefinition");function w(e,r){for(var t=this,n=arguments.length,o=new Array(n>2?n-2:0),i=2;i<n;i++)o[i-2]=arguments[i];r.locks++;try{var a;return null!=e&&(a=e.apply(this,o)),a}finally{r.locks--,0===r.locks&&r.methods.forEach((function(e){e.apply(t,o)}))}}function j(e,r){return function(){for(var t=arguments.length,n=new Array(t),o=0;o<t;o++)n[o]=arguments[o];w.call.apply(w,[this,e,r].concat(n))}}function x(e,r,t){var n=function(e,r){var t=e[O]=e[O]||{},n=t[r]=t[r]||{};return n.locks=n.locks||0,n.methods=n.methods||[],n}(e,r);n.methods.indexOf(t)<0&&n.methods.push(t);var o=Object.getOwnPropertyDescriptor(e,r);if(!o||!o[g]){var i=function e(r,t,n,o,i){var a,c=j(i,o);return(a={})[g]=!0,a.get=function(){return c},a.set=function(i){if(this===r)c=j(i,o);else{var a=e(this,t,n,o,i);Object.defineProperty(this,t,a)}},a.configurable=!0,a.enumerable=n,a}(e,r,o?o.enumerable:void 0,n,e[r]);Object.defineProperty(e,r,i)}}var P=Symbol("ObserverAdministration"),U=Symbol("isMobXReactObserver");function A(r){var t;return null!=(t=r[P])?t:r[P]={reaction:null,mounted:!1,forceUpdate:null,name:E(r.constructor),state:void 0,props:void 0,context:void 0,propsAtom:e("props"),stateAtom:e("state"),contextAtom:e("context"),isUpdating:!1}}function E(e){return e.displayName||e.name||"<component>"}function C(e){var r=e.bind(this),t=A(this);return function(){t.reaction||(t.reaction=function(e){return new n(e.name+".render()",(function(){if(!e.isUpdating&&e.mounted)try{e.isUpdating=!0,null==e.forceUpdate||e.forceUpdate()}catch(t){var r;null==(r=e.reaction)||r.dispose(),e.reaction=null}finally{e.isUpdating=!1}}))}(t),t.mounted||b.register(this,t,this));var e=void 0,i=void 0;if(t.reaction.track((function(){try{i=o(!1,r)}catch(r){e=r}})),e)throw e;return i}}function k(e,r){return d()&&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."),this.state!==r||!y(this.props,e)}function S(e){var n=e+"Atom";return{configurable:!0,enumerable:!0,get:function(){var o=A(this),i=r(!0);return o[n].reportObserved(),t(i),o[e]},set:function(r){var t=A(this);t.isUpdating||y(t[e],r)?t[e]=r:(t[e]=r,t.isUpdating=!0,t[n].reportChanged(),t.isUpdating=!1)}}}var R=S("props"),M=S("state"),T=S("context");function D(e){return!0===e.isMobxInjector&&console.warn("Mobx observer: You are trying to use `observer` on a component that already has `inject`. Please apply `observer` before applying `inject`"),Object.prototype.isPrototypeOf.call(f,e)||Object.prototype.isPrototypeOf.call(l,e)?function(e){var r=e.prototype;if(e[U]){var t=E(e);console.warn("The provided component class ("+t+")\n has already been declared as an observer component.")}else e[U]=!0;if(r.componentWillReact)throw new Error("The componentWillReact life-cycle event is no longer supported");if(e.__proto__!==l)if(r.shouldComponentUpdate){if(r.shouldComponentUpdate!==k)throw new Error("It is not allowed to use shouldComponentUpdate in observer based components.")}else r.shouldComponentUpdate=k;Object.defineProperties(r,{props:R,state:M,context:T});var n=r.render;if("function"!=typeof n){var o=E(e);throw new Error("[mobx-react] class component ("+o+") is missing `render` method.\n`observer` requires `render` being a function defined on prototype.\n`render = () => {}` or `render = function() {}` is not supported.")}return r.render=function(){return Object.defineProperty(this,"render",{configurable:!1,writable:!1,value:d()?n:C.call(this,n)}),this.render()},x(r,"componentDidMount",(function(){var e=this,r=A(this);r.mounted=!0,b.unregister(r),r.forceUpdate=function(){return e.forceUpdate()},r.reaction||r.forceUpdate()})),x(r,"componentWillUnmount",(function(){var e;if(!d()){var r=A(this);null==(e=r.reaction)||e.dispose(),r.reaction=null,r.forceUpdate=null,r.mounted=!1}})),e}(e):m(e)}function I(){return(I=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}).apply(this,arguments)}var N=["children"],q=p.createContext({});function L(e){var r=e.children,t=function(e,r){if(null==e)return{};var t,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r.indexOf(t=i[n])>=0||(o[t]=e[t]);return o}(e,N),n=p.useContext(q),o=p.useRef(I({},n,t));return p.createElement(q.Provider,{value:o.current},r)}function W(e,r,t,n){var o,i,a,c=p.forwardRef((function(t,n){var o=I({},t),i=p.useContext(q);return Object.assign(o,e(i||{},o)||{}),n&&(o.ref=n),p.createElement(r,o)}));return n&&(c=D(c)),c.isMobxInjector=!0,o=r,i=c,a=Object.getOwnPropertyNames(Object.getPrototypeOf(o)),Object.getOwnPropertyNames(o).forEach((function(e){h[e]||-1!==a.indexOf(e)||Object.defineProperty(i,e,Object.getOwnPropertyDescriptor(o,e))})),c.wrappedComponent=r,c.displayName=function(e,r){var t=e.displayName||e.name||e.constructor&&e.constructor.name||"Component";return r?"inject-with-"+r+"("+t+")":"inject("+t+")"}(r,t),c}function _(e){return function(r,t){return e.forEach((function(e){if(!(e in t)){if(!(e in r))throw new Error("MobX injector: Store '"+e+"' is not available! Make sure it is provided by some Provider");t[e]=r[e]}})),t}}function X(){for(var e=arguments.length,r=new Array(e),t=0;t<e;t++)r[t]=arguments[t];if("function"==typeof arguments[0]){var n=arguments[0];return function(e){return W(n,e,n.name,!0)}}return function(e){return W(_(r),e,r.join("-"),!1)}}L.displayName="MobXProvider";var F=Number.parseInt(p.version.split(".")[0]),$=!1,B=Symbol("disposeOnUnmountProto"),Y=Symbol("disposeOnUnmountInst");function z(){var e=this;[].concat(this[B]||[],this[Y]||[]).forEach((function(r){var t="string"==typeof r?e[r]:r;null!=t&&(Array.isArray(t)?t.map((function(e){return e()})):t())}))}function G(e,r){if(Array.isArray(r))return r.map((function(r){return G(e,r)}));$||(F>=18?console.error("[mobx-react] disposeOnUnmount is not compatible with React 18 and higher. Don't use it."):console.warn("[mobx-react] disposeOnUnmount is deprecated. It won't work correctly with React 18 and higher."),$=!0);var t=Object.getPrototypeOf(e).constructor,n=Object.getPrototypeOf(e.constructor),o=Object.getPrototypeOf(Object.getPrototypeOf(e));if(t!==p.Component&&t!==p.PureComponent&&n!==p.Component&&n!==p.PureComponent&&o!==p.Component&&o!==p.PureComponent)throw new Error("[mobx-react] disposeOnUnmount only supports direct subclasses of React.Component or React.PureComponent.");if("string"!=typeof r&&"function"!=typeof r&&!Array.isArray(r))throw new Error("[mobx-react] disposeOnUnmount only works if the parameter is either a property key or a function.");var i=!!e[B]||!!e[Y];return("string"==typeof r?e[B]||(e[B]=[]):e[Y]||(e[Y]=[])).push(r),i||x(e,"componentWillUnmount",z),"string"!=typeof r?r:void 0}function H(e){function r(r,t,n,o,a,c){for(var s=arguments.length,u=new Array(s>6?s-6:0),p=6;p<s;p++)u[p-6]=arguments[p];return i((function(){return o=o||"<<anonymous>>",c=c||n,null==t[n]?r?new Error("The "+a+" `"+c+"` is marked as required in `"+o+"`, but its value is `"+(null===t[n]?"null":"undefined")+"`."):null:e.apply(void 0,[t,n,o,a,c].concat(u))}))}var t=r.bind(null,!1);return t.isRequired=r.bind(null,!0),t}function J(e){var r=typeof e;return Array.isArray(e)?"array":e instanceof RegExp?"object":function(e,r){return"symbol"===e||"Symbol"===r["@@toStringTag"]||"function"==typeof Symbol&&r instanceof Symbol}(r,e)?"symbol":r}function K(e,r){return H((function(t,n,o,u,p){return i((function(){if(e&&J(t[n])===r.toLowerCase())return null;var i;switch(r){case"Array":i=s;break;case"Object":i=c;break;case"Map":i=a;break;default:throw new Error("Unexpected mobxType: "+r)}var u=t[n];if(!i(u)){var l=function(e){var r=J(e);if("object"===r){if(e instanceof Date)return"date";if(e instanceof RegExp)return"regexp"}return r}(u),f=e?" or javascript `"+r.toLowerCase()+"`":"";return new Error("Invalid prop `"+p+"` of type `"+l+"` supplied to `"+o+"`, expected `mobx.Observable"+r+"`"+f+".")}return null}))}))}function Q(e,r){return H((function(t,n,o,a,c){for(var s=arguments.length,u=new Array(s>5?s-5:0),p=5;p<s;p++)u[p-5]=arguments[p];return i((function(){if("function"!=typeof r)return new Error("Property `"+c+"` of component `"+o+"` has invalid PropType notation.");var i=K(e,"Array")(t,n,o,a,c);if(i instanceof Error)return i;for(var s=t[n],p=0;p<s.length;p++)if((i=r.apply(void 0,[s,p,o,a,c+"["+p+"]"].concat(u)))instanceof Error)return i;return null}))}))}var V={observableArray:K(!1,"Array"),observableArrayOf:Q.bind(null,!1),observableMap:K(!1,"Map"),observableObject:K(!1,"Object"),arrayOrObservableArray:K(!0,"Array"),arrayOrObservableArrayOf:Q.bind(null,!0),objectOrObservableObject:K(!0,"Object")};if(!f)throw new Error("mobx-react requires React to be available");if(!u)throw new Error("mobx-react requires mobx to be available");export{q as MobXProviderContext,V as PropTypes,L as Provider,G as disposeOnUnmount,X as inject,D as observer}; | ||
//# sourceMappingURL=mobxreact.esm.production.min.js.map |
@@ -9,22 +9,2 @@ (function (global, factory) { | ||
var symbolId = 0; | ||
function createSymbol(name) { | ||
if (typeof Symbol === "function") { | ||
return Symbol(name); | ||
} | ||
var symbol = "__$mobx-react " + name + " (" + symbolId + ")"; | ||
symbolId++; | ||
return symbol; | ||
} | ||
var createdSymbols = {}; | ||
function newSymbol(name) { | ||
if (!createdSymbols[name]) { | ||
createdSymbols[name] = createSymbol(name); | ||
} | ||
return createdSymbols[name]; | ||
} | ||
function shallowEqual(objA, objB) { | ||
@@ -35,14 +15,10 @@ //From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js | ||
} | ||
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) { | ||
return false; | ||
} | ||
var keysA = Object.keys(objA); | ||
var keysB = Object.keys(objB); | ||
if (keysA.length !== keysB.length) { | ||
return false; | ||
} | ||
for (var i = 0; i < keysA.length; i++) { | ||
@@ -53,6 +29,4 @@ if (!Object.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { | ||
} | ||
return true; | ||
} | ||
function is(x, y) { | ||
@@ -65,5 +39,4 @@ // From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js | ||
} | ||
} // based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js | ||
} | ||
// based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js | ||
var hoistBlackList = { | ||
@@ -94,28 +67,7 @@ $$typeof: 1, | ||
/** | ||
* Helper to set `prop` to `this` as non-enumerable (hidden prop) | ||
* @param target | ||
* @param prop | ||
* @param value | ||
*/ | ||
function setHiddenProp(target, prop, value) { | ||
if (!Object.hasOwnProperty.call(target, prop)) { | ||
Object.defineProperty(target, prop, { | ||
enumerable: false, | ||
configurable: true, | ||
writable: true, | ||
value: value | ||
}); | ||
} else { | ||
target[prop] = value; | ||
} | ||
} | ||
/** | ||
* Utilities for patching componentWillUnmount, to make sure @disposeOnUnmount works correctly icm with user defined hooks | ||
* and the handler provided by mobx-react | ||
*/ | ||
var mobxMixins = /*#__PURE__*/newSymbol("patchMixins"); | ||
var mobxPatchedDefinition = /*#__PURE__*/newSymbol("patchedDefinition"); | ||
var mobxMixins = /*#__PURE__*/Symbol("patchMixins"); | ||
var mobxPatchedDefinition = /*#__PURE__*/Symbol("patchedDefinition"); | ||
function getMixins(target, methodName) { | ||
@@ -128,24 +80,17 @@ var mixins = target[mobxMixins] = target[mobxMixins] || {}; | ||
} | ||
function wrapper(realMethod, mixins) { | ||
var _this = this; | ||
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { | ||
args[_key - 2] = arguments[_key]; | ||
} | ||
// locks are used to ensure that mixins are invoked only once per invocation, even on recursive calls | ||
mixins.locks++; | ||
try { | ||
var retVal; | ||
if (realMethod !== undefined && realMethod !== null) { | ||
retVal = realMethod.apply(this, args); | ||
} | ||
return retVal; | ||
} finally { | ||
mixins.locks--; | ||
if (mixins.locks === 0) { | ||
@@ -158,3 +103,2 @@ mixins.methods.forEach(function (mx) { | ||
} | ||
function wrapFunction(realMethod, mixins) { | ||
@@ -165,18 +109,12 @@ var fn = function fn() { | ||
} | ||
wrapper.call.apply(wrapper, [this, realMethod, mixins].concat(args)); | ||
}; | ||
return fn; | ||
} | ||
function patch(target, methodName, mixinMethod) { | ||
var mixins = getMixins(target, methodName); | ||
if (mixins.methods.indexOf(mixinMethod) < 0) { | ||
mixins.methods.push(mixinMethod); | ||
} | ||
var oldDefinition = Object.getOwnPropertyDescriptor(target, methodName); | ||
if (oldDefinition && oldDefinition[mobxPatchedDefinition]) { | ||
@@ -186,3 +124,2 @@ // already patched definition, do not repatch | ||
} | ||
var originalMethod = target[methodName]; | ||
@@ -192,6 +129,4 @@ var newDefinition = createDefinition(target, methodName, oldDefinition ? oldDefinition.enumerable : undefined, mixins, originalMethod); | ||
} | ||
function createDefinition(target, methodName, enumerable, mixins, originalMethod) { | ||
var _ref; | ||
var wrappedFunc = wrapFunction(originalMethod, mixins); | ||
@@ -214,233 +149,219 @@ return _ref = {}, _ref[mobxPatchedDefinition] = true, _ref.get = function get() { | ||
var mobxAdminProperty = mobx.$mobx || "$mobx"; // BC | ||
var mobxObserverProperty = /*#__PURE__*/newSymbol("isMobXReactObserver"); | ||
var mobxIsUnmounted = /*#__PURE__*/newSymbol("isUnmounted"); | ||
var skipRenderKey = /*#__PURE__*/newSymbol("skipRender"); | ||
var isForcingUpdateKey = /*#__PURE__*/newSymbol("isForcingUpdate"); | ||
var administrationSymbol = /*#__PURE__*/Symbol("ObserverAdministration"); | ||
var isMobXReactObserverSymbol = /*#__PURE__*/Symbol("isMobXReactObserver"); | ||
function getAdministration(component) { | ||
var _component$administra; | ||
// We create administration lazily, because we can't patch constructor | ||
// and the exact moment of initialization partially depends on React internals. | ||
// At the time of writing this, the first thing invoked is one of the observable getter/setter (state/props/context). | ||
return (_component$administra = component[administrationSymbol]) != null ? _component$administra : component[administrationSymbol] = { | ||
reaction: null, | ||
mounted: false, | ||
forceUpdate: null, | ||
name: getDisplayName(component.constructor), | ||
state: undefined, | ||
props: undefined, | ||
context: undefined, | ||
propsAtom: mobx.createAtom("props"), | ||
stateAtom: mobx.createAtom("state"), | ||
contextAtom: mobx.createAtom("context"), | ||
isUpdating: false | ||
}; | ||
} | ||
function makeClassComponentObserver(componentClass) { | ||
var target = componentClass.prototype; | ||
if (componentClass[mobxObserverProperty]) { | ||
var displayName = getDisplayName(target); | ||
var prototype = componentClass.prototype; | ||
if (componentClass[isMobXReactObserverSymbol]) { | ||
var displayName = getDisplayName(componentClass); | ||
console.warn("The provided component class (" + displayName + ")\n has already been declared as an observer component."); | ||
} else { | ||
componentClass[mobxObserverProperty] = true; | ||
componentClass[isMobXReactObserverSymbol] = true; | ||
} | ||
if (target.componentWillReact) { | ||
if (prototype.componentWillReact) { | ||
throw new Error("The componentWillReact life-cycle event is no longer supported"); | ||
} | ||
if (componentClass["__proto__"] !== React.PureComponent) { | ||
if (!target.shouldComponentUpdate) { | ||
target.shouldComponentUpdate = observerSCU; | ||
} else if (target.shouldComponentUpdate !== observerSCU) { | ||
if (!prototype.shouldComponentUpdate) { | ||
prototype.shouldComponentUpdate = observerSCU; | ||
} else if (prototype.shouldComponentUpdate !== observerSCU) { | ||
// n.b. unequal check, instead of existence check, as @observer might be on superclass as well | ||
throw new Error("It is not allowed to use shouldComponentUpdate in observer based components."); | ||
} | ||
} // this.props and this.state are made observable, just to make sure @computed fields that | ||
} | ||
// this.props and this.state are made observable, just to make sure @computed fields that | ||
// are defined inside the component, and which rely on state or props, re-compute if state or props change | ||
// (otherwise the computed wouldn't update and become stale on props change, since props are not observable) | ||
// 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+ | ||
makeObservableProp(target, "props"); | ||
makeObservableProp(target, "state"); | ||
if (componentClass.contextType) { | ||
makeObservableProp(target, "context"); | ||
} | ||
var originalRender = target.render; | ||
Object.defineProperties(prototype, { | ||
props: observablePropsDescriptor, | ||
state: observableStateDescriptor, | ||
context: observableContextDescriptor | ||
}); | ||
var originalRender = prototype.render; | ||
if (typeof originalRender !== "function") { | ||
var _displayName = getDisplayName(target); | ||
var _displayName = getDisplayName(componentClass); | ||
throw new Error("[mobx-react] class component (" + _displayName + ") is missing `render` method." + "\n`observer` requires `render` being a function defined on prototype." + "\n`render = () => {}` or `render = function() {}` is not supported."); | ||
} | ||
target.render = function () { | ||
this.render = mobxReactLite.isUsingStaticRendering() ? originalRender : createReactiveRender.call(this, originalRender); | ||
prototype.render = function () { | ||
Object.defineProperty(this, "render", { | ||
// There is no safe way to replace render, therefore it's forbidden. | ||
configurable: false, | ||
writable: false, | ||
value: mobxReactLite.isUsingStaticRendering() ? originalRender : createReactiveRender.call(this, originalRender) | ||
}); | ||
return this.render(); | ||
}; | ||
patch(target, "componentDidMount", function () { | ||
this[mobxIsUnmounted] = false; | ||
if (!this.render[mobxAdminProperty]) { | ||
// Reaction is re-created automatically during render, but a component can re-mount and skip render #3395. | ||
// To re-create the reaction and re-subscribe to relevant observables we have to force an update. | ||
React.Component.prototype.forceUpdate.call(this); | ||
patch(prototype, "componentDidMount", function () { | ||
var _this = this; | ||
// `componentDidMount` may not be called at all. React can abandon the instance after `render`. | ||
// That's why we use finalization registry to dispose reaction created during render. | ||
// Happens with `<Suspend>` see #3492 | ||
// | ||
// `componentDidMount` can be called immediately after `componentWillUnmount` without calling `render` in between. | ||
// Happens with `<StrictMode>`see #3395. | ||
// | ||
// If `componentDidMount` is called, it's guaranteed to run synchronously with render (similary to `useLayoutEffect`). | ||
// Therefore we don't have to worry about external (observable) state being updated before mount (no state version checking). | ||
// | ||
// Things may change: "In the future, React will provide a feature that lets components preserve state between unmounts" | ||
var admin = getAdministration(this); | ||
admin.mounted = true; | ||
// Component instance committed, prevent reaction disposal. | ||
mobxReactLite._observerFinalizationRegistry.unregister(admin); | ||
// We don't set forceUpdate before mount because it requires a reference to `this`, | ||
// therefore `this` could NOT be garbage collected before mount, | ||
// preventing reaction disposal by FinalizationRegistry and leading to memory leak. | ||
// As an alternative we could have `admin.instanceRef = new WeakRef(this)`, but lets avoid it if possible. | ||
admin.forceUpdate = function () { | ||
return _this.forceUpdate(); | ||
}; | ||
if (!admin.reaction) { | ||
// 1. Instance was unmounted (reaction disposed) and immediately remounted without running render #3395. | ||
// 2. Reaction was disposed by finalization registry before mount. Shouldn't ever happen for class components: | ||
// `componentDidMount` runs synchronously after render, but our registry are deferred (can't run in between). | ||
// In any case we lost subscriptions to observables, so we have to create new reaction and re-render to resubscribe. | ||
// The reaction will be created lazily by following render. | ||
admin.forceUpdate(); | ||
} | ||
}); | ||
patch(target, "componentWillUnmount", function () { | ||
patch(prototype, "componentWillUnmount", function () { | ||
var _admin$reaction; | ||
if (mobxReactLite.isUsingStaticRendering()) { | ||
return; | ||
} | ||
var reaction = this.render[mobxAdminProperty]; | ||
if (reaction) { | ||
reaction.dispose(); // Forces reaction to be re-created on next render | ||
this.render[mobxAdminProperty] = null; | ||
} else { | ||
// Render may have been hot-swapped and/or overridden by a subclass. | ||
var _displayName2 = getDisplayName(this); | ||
console.warn("The reactive render of an observer class component (" + _displayName2 + ")\n was overridden after MobX attached. This may result in a memory leak if the\n overridden reactive render was not properly disposed."); | ||
} | ||
this[mobxIsUnmounted] = true; | ||
var admin = getAdministration(this); | ||
(_admin$reaction = admin.reaction) == null ? void 0 : _admin$reaction.dispose(); | ||
admin.reaction = null; | ||
admin.forceUpdate = null; | ||
admin.mounted = false; | ||
}); | ||
return componentClass; | ||
} // Generates a friendly name for debugging | ||
function getDisplayName(comp) { | ||
return comp.displayName || comp.name || comp.constructor && (comp.constructor.displayName || comp.constructor.name) || "<component>"; | ||
} | ||
// Generates a friendly name for debugging | ||
function getDisplayName(componentClass) { | ||
return componentClass.displayName || componentClass.name || "<component>"; | ||
} | ||
function createReactiveRender(originalRender) { | ||
var _this = this; | ||
/** | ||
* If props are shallowly modified, react will render anyway, | ||
* so atom.reportChanged() should not result in yet another re-render | ||
*/ | ||
setHiddenProp(this, skipRenderKey, false); | ||
/** | ||
* forceUpdate will re-assign this.props. We don't want that to cause a loop, | ||
* so detect these changes | ||
*/ | ||
setHiddenProp(this, isForcingUpdateKey, false); | ||
var initialName = getDisplayName(this); | ||
var boundOriginalRender = originalRender.bind(this); | ||
var isRenderingPending = false; | ||
var createReaction = function createReaction() { | ||
var reaction = new mobx.Reaction(initialName + ".render()", function () { | ||
if (!isRenderingPending) { | ||
// N.B. Getting here *before mounting* means that a component constructor has side effects (see the relevant test in misc.test.tsx) | ||
// This unidiomatic React usage but React will correctly warn about this so we continue as usual | ||
// See #85 / Pull #44 | ||
isRenderingPending = true; | ||
if (_this[mobxIsUnmounted] !== true) { | ||
var hasError = true; | ||
try { | ||
setHiddenProp(_this, isForcingUpdateKey, true); | ||
if (!_this[skipRenderKey]) { | ||
React.Component.prototype.forceUpdate.call(_this); | ||
} | ||
hasError = false; | ||
} finally { | ||
setHiddenProp(_this, isForcingUpdateKey, false); | ||
if (hasError) { | ||
reaction.dispose(); // Forces reaction to be re-created on next render | ||
_this.render[mobxAdminProperty] = null; | ||
} | ||
} | ||
} | ||
var admin = getAdministration(this); | ||
function reactiveRender() { | ||
if (!admin.reaction) { | ||
// Create reaction lazily to support re-mounting #3395 | ||
admin.reaction = createReaction(admin); | ||
if (!admin.mounted) { | ||
// React can abandon this instance and never call `componentDidMount`/`componentWillUnmount`, | ||
// we have to make sure reaction will be disposed. | ||
mobxReactLite._observerFinalizationRegistry.register(this, admin, this); | ||
} | ||
}); | ||
reaction["reactComponent"] = _this; | ||
return reaction; | ||
}; | ||
function reactiveRender() { | ||
var _reactiveRender$mobxA; | ||
isRenderingPending = false; // Create reaction lazily to support re-mounting #3395 | ||
var reaction = (_reactiveRender$mobxA = reactiveRender[mobxAdminProperty]) != null ? _reactiveRender$mobxA : reactiveRender[mobxAdminProperty] = createReaction(); | ||
var exception = undefined; | ||
var rendering = undefined; | ||
reaction.track(function () { | ||
} | ||
var error = undefined; | ||
var renderResult = undefined; | ||
admin.reaction.track(function () { | ||
try { | ||
// TODO@major | ||
// Optimization: replace with _allowStateChangesStart/End (not available in mobx@6.0.0) | ||
rendering = mobx._allowStateChanges(false, boundOriginalRender); | ||
renderResult = mobx._allowStateChanges(false, boundOriginalRender); | ||
} catch (e) { | ||
exception = e; | ||
error = e; | ||
} | ||
}); | ||
if (exception) { | ||
throw exception; | ||
if (error) { | ||
throw error; | ||
} | ||
return rendering; | ||
return renderResult; | ||
} | ||
return reactiveRender; | ||
} | ||
function createReaction(admin) { | ||
return new mobx.Reaction(admin.name + ".render()", function () { | ||
if (admin.isUpdating) { | ||
// Reaction is suppressed when setting new state/props/context, | ||
// this is when component is already being updated. | ||
return; | ||
} | ||
if (!admin.mounted) { | ||
// This is neccessary to avoid react warning about calling forceUpdate on component that isn't mounted yet. | ||
// This happens when component is abandoned after render - our reaction is already created and reacts to changes. | ||
// Due to the synchronous nature of `componenDidMount`, we don't have to worry that component could eventually mount and require update. | ||
return; | ||
} | ||
try { | ||
// forceUpdate sets new `props`, since we made it observable, it would `reportChanged`, causing a loop. | ||
admin.isUpdating = true; | ||
admin.forceUpdate == null ? void 0 : admin.forceUpdate(); | ||
} catch (error) { | ||
var _admin$reaction2; | ||
(_admin$reaction2 = admin.reaction) == null ? void 0 : _admin$reaction2.dispose(); | ||
admin.reaction = null; | ||
} finally { | ||
admin.isUpdating = false; | ||
} | ||
}); | ||
} | ||
function observerSCU(nextProps, nextState) { | ||
if (mobxReactLite.isUsingStaticRendering()) { | ||
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."); | ||
} // update on any state changes (as is the default) | ||
} | ||
// update on any state changes (as is the default) | ||
if (this.state !== nextState) { | ||
return true; | ||
} // update if props are shallowly not equal, inspired by PureRenderMixin | ||
} | ||
// update if props are shallowly not equal, inspired by PureRenderMixin | ||
// we could return just 'false' here, and avoid the `skipRender` checks etc | ||
// however, it is nicer if lifecycle events are triggered like usually, | ||
// so we return true here if props are shallowly modified. | ||
return !shallowEqual(this.props, nextProps); | ||
} | ||
function makeObservableProp(target, propName) { | ||
var valueHolderKey = newSymbol("reactProp_" + propName + "_valueHolder"); | ||
var atomHolderKey = newSymbol("reactProp_" + propName + "_atomHolder"); | ||
function getAtom() { | ||
if (!this[atomHolderKey]) { | ||
setHiddenProp(this, atomHolderKey, mobx.createAtom("reactive " + propName)); | ||
} | ||
return this[atomHolderKey]; | ||
} | ||
Object.defineProperty(target, propName, { | ||
function createObservablePropDescriptor(key) { | ||
var atomKey = key + "Atom"; | ||
return { | ||
configurable: true, | ||
enumerable: true, | ||
get: function get() { | ||
var prevReadState = false; // Why this check? BC? | ||
// @ts-expect-error | ||
if (mobx._allowStateReadsStart && mobx._allowStateReadsEnd) { | ||
prevReadState = mobx._allowStateReadsStart(true); | ||
} | ||
getAtom.call(this).reportObserved(); // Why this check? BC? | ||
// @ts-expect-error | ||
if (mobx._allowStateReadsStart && mobx._allowStateReadsEnd) { | ||
mobx._allowStateReadsEnd(prevReadState); | ||
} | ||
return this[valueHolderKey]; | ||
var admin = getAdministration(this); | ||
var prevReadState = mobx._allowStateReadsStart(true); | ||
admin[atomKey].reportObserved(); | ||
mobx._allowStateReadsEnd(prevReadState); | ||
return admin[key]; | ||
}, | ||
set: function set(v) { | ||
if (!this[isForcingUpdateKey] && !shallowEqual(this[valueHolderKey], v)) { | ||
setHiddenProp(this, valueHolderKey, v); | ||
setHiddenProp(this, skipRenderKey, true); | ||
getAtom.call(this).reportChanged(); | ||
setHiddenProp(this, skipRenderKey, false); | ||
set: function set(value) { | ||
var admin = getAdministration(this); | ||
// forceUpdate issued by reaction sets new props. | ||
// It sets isUpdating to true to prevent loop. | ||
if (!admin.isUpdating && !shallowEqual(admin[key], value)) { | ||
admin[key] = value; | ||
// This notifies all observers including our component, | ||
// but we don't want to cause `forceUpdate`, because component is already updating, | ||
// therefore supress component reaction. | ||
admin.isUpdating = true; | ||
admin[atomKey].reportChanged(); | ||
admin.isUpdating = false; | ||
} else { | ||
setHiddenProp(this, valueHolderKey, v); | ||
admin[key] = value; | ||
} | ||
} | ||
}); | ||
}; | ||
} | ||
var observablePropsDescriptor = /*#__PURE__*/createObservablePropDescriptor("props"); | ||
var observableStateDescriptor = /*#__PURE__*/createObservablePropDescriptor("state"); | ||
var observableContextDescriptor = /*#__PURE__*/createObservablePropDescriptor("context"); | ||
@@ -450,3 +371,2 @@ /** | ||
*/ | ||
function observer(component) { | ||
@@ -456,3 +376,2 @@ if (component["isMobxInjector"] === true) { | ||
} | ||
if (Object.prototype.isPrototypeOf.call(React.Component, component) || Object.prototype.isPrototypeOf.call(React.PureComponent, component)) { | ||
@@ -468,6 +387,5 @@ // Class component | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
_extends = Object.assign ? Object.assign.bind() : function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
@@ -479,9 +397,6 @@ if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
} | ||
return target; | ||
}; | ||
return _extends.apply(this, arguments); | ||
} | ||
function _objectWithoutPropertiesLoose(source, excluded) { | ||
@@ -492,3 +407,2 @@ if (source == null) return {}; | ||
var key, i; | ||
for (i = 0; i < sourceKeys.length; i++) { | ||
@@ -499,3 +413,2 @@ key = sourceKeys[i]; | ||
} | ||
return target; | ||
@@ -508,12 +421,8 @@ } | ||
var children = props.children, | ||
stores = _objectWithoutPropertiesLoose(props, _excluded); | ||
stores = _objectWithoutPropertiesLoose(props, _excluded); | ||
var parentValue = React__default.useContext(MobXProviderContext); | ||
var mutableProviderRef = React__default.useRef(_extends({}, parentValue, stores)); | ||
var value = mutableProviderRef.current; | ||
{ | ||
var newValue = _extends({}, value, stores); // spread in previous state for the context based stores | ||
if (!shallowEqual(value, newValue)) { | ||
@@ -523,3 +432,2 @@ 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."); | ||
} | ||
return React__default.createElement(MobXProviderContext.Provider, { | ||
@@ -534,3 +442,2 @@ value: value | ||
*/ | ||
function createStoreInjector(grabStoresFn, component, injectNames, makeReactive) { | ||
@@ -540,10 +447,7 @@ // Support forward refs | ||
var newProps = _extends({}, props); | ||
var context = React__default.useContext(MobXProviderContext); | ||
Object.assign(newProps, grabStoresFn(context || {}, newProps) || {}); | ||
if (ref) { | ||
newProps.ref = ref; | ||
} | ||
return React__default.createElement(component, newProps); | ||
@@ -554,3 +458,2 @@ }); | ||
// Static fields from component should be visible on the generated Injector | ||
copyStaticProperties(component, Injector); | ||
@@ -561,3 +464,2 @@ Injector["wrappedComponent"] = component; | ||
} | ||
function getInjectName(component, injectNames) { | ||
@@ -569,3 +471,2 @@ var displayName; | ||
} | ||
function grabStoresByName(storeNames) { | ||
@@ -588,4 +489,2 @@ return function (baseStores, nextProps) { | ||
*/ | ||
function inject() { | ||
@@ -595,3 +494,2 @@ for (var _len = arguments.length, storeNames = new Array(_len), _key = 0; _key < _len; _key++) { | ||
} | ||
if (typeof arguments[0] === "function") { | ||
@@ -609,5 +507,6 @@ var grabStoresFn = arguments[0]; | ||
var protoStoreKey = /*#__PURE__*/newSymbol("disposeOnUnmountProto"); | ||
var instStoreKey = /*#__PURE__*/newSymbol("disposeOnUnmountInst"); | ||
var reactMajorVersion = /*#__PURE__*/Number.parseInt( /*#__PURE__*/React__default.version.split(".")[0]); | ||
var warnedAboutDisposeOnUnmountDeprecated = false; | ||
var protoStoreKey = /*#__PURE__*/Symbol("disposeOnUnmountProto"); | ||
var instStoreKey = /*#__PURE__*/Symbol("disposeOnUnmountInst"); | ||
function runDisposersOnWillUnmount() { | ||
@@ -617,3 +516,2 @@ var _this = this; | ||
var prop = typeof propKeyOrFunction === "string" ? _this[propKeyOrFunction] : propKeyOrFunction; | ||
if (prop !== undefined && prop !== null) { | ||
@@ -626,3 +524,5 @@ if (Array.isArray(prop)) prop.map(function (f) { | ||
} | ||
/** | ||
* @deprecated `disposeOnUnmount` is not compatible with React 18 and higher. | ||
*/ | ||
function disposeOnUnmount(target, propertyKeyOrFunction) { | ||
@@ -634,30 +534,35 @@ if (Array.isArray(propertyKeyOrFunction)) { | ||
} | ||
if (!warnedAboutDisposeOnUnmountDeprecated) { | ||
if (reactMajorVersion >= 18) { | ||
console.error("[mobx-react] disposeOnUnmount is not compatible with React 18 and higher. Don't use it."); | ||
} else { | ||
console.warn("[mobx-react] disposeOnUnmount is deprecated. It won't work correctly with React 18 and higher."); | ||
} | ||
warnedAboutDisposeOnUnmountDeprecated = true; | ||
} | ||
var c = Object.getPrototypeOf(target).constructor; | ||
var c2 = Object.getPrototypeOf(target.constructor); // Special case for react-hot-loader | ||
var c2 = Object.getPrototypeOf(target.constructor); | ||
// Special case for react-hot-loader | ||
var c3 = Object.getPrototypeOf(Object.getPrototypeOf(target)); | ||
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)) { | ||
throw new Error("[mobx-react] disposeOnUnmount only supports direct subclasses of React.Component or React.PureComponent."); | ||
} | ||
if (typeof propertyKeyOrFunction !== "string" && typeof propertyKeyOrFunction !== "function" && !Array.isArray(propertyKeyOrFunction)) { | ||
throw new Error("[mobx-react] disposeOnUnmount only works if the parameter is either a property key or a function."); | ||
} // decorator's target is the prototype, so it doesn't have any instance properties like props | ||
var isDecorator = typeof propertyKeyOrFunction === "string"; // add property key / function we want run (disposed) to the store | ||
} | ||
// decorator's target is the prototype, so it doesn't have any instance properties like props | ||
var isDecorator = typeof propertyKeyOrFunction === "string"; | ||
// add property key / function we want run (disposed) to the store | ||
var componentWasAlreadyModified = !!target[protoStoreKey] || !!target[instStoreKey]; | ||
var store = isDecorator ? // decorators are added to the prototype store | ||
target[protoStoreKey] || (target[protoStoreKey] = []) : // functions are added to the instance store | ||
var store = isDecorator ? | ||
// decorators are added to the prototype store | ||
target[protoStoreKey] || (target[protoStoreKey] = []) : | ||
// functions are added to the instance store | ||
target[instStoreKey] || (target[instStoreKey] = []); | ||
store.push(propertyKeyOrFunction); // tweak the component class componentWillUnmount if not done already | ||
store.push(propertyKeyOrFunction); | ||
// tweak the component class componentWillUnmount if not done already | ||
if (!componentWasAlreadyModified) { | ||
patch(target, "componentWillUnmount", runDisposersOnWillUnmount); | ||
} // return the disposer as is if invoked as a non decorator | ||
} | ||
// return the disposer as is if invoked as a non decorator | ||
if (typeof propertyKeyOrFunction !== "string") { | ||
@@ -668,2 +573,3 @@ return propertyKeyOrFunction; | ||
// Copied from React.PropTypes | ||
function createChainableTypeChecker(validator) { | ||
@@ -674,7 +580,5 @@ function checkType(isRequired, props, propName, componentName, location, propFullName) { | ||
} | ||
return mobx.untracked(function () { | ||
componentName = componentName || "<<anonymous>>"; | ||
propFullName = propFullName || propName; | ||
if (props[propName] == null) { | ||
@@ -685,3 +589,2 @@ if (isRequired) { | ||
} | ||
return null; | ||
@@ -694,10 +597,8 @@ } else { | ||
} | ||
var chainedCheckType = checkType.bind(null, false); // Add isRequired to satisfy Requirable | ||
var chainedCheckType = checkType.bind(null, false); | ||
// Add isRequired to satisfy Requirable | ||
chainedCheckType.isRequired = checkType.bind(null, true); | ||
return chainedCheckType; | ||
} // Copied from React.PropTypes | ||
} | ||
// Copied from React.PropTypes | ||
function isSymbol(propType, propValue) { | ||
@@ -707,25 +608,19 @@ // Native Symbol. | ||
return true; | ||
} // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' | ||
} | ||
// 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' | ||
if (propValue["@@toStringTag"] === "Symbol") { | ||
return true; | ||
} // Fallback for non-spec compliant Symbols which are polyfilled. | ||
} | ||
// Fallback for non-spec compliant Symbols which are polyfilled. | ||
if (typeof Symbol === "function" && propValue instanceof Symbol) { | ||
return true; | ||
} | ||
return false; | ||
} // Copied from React.PropTypes | ||
} | ||
// Copied from React.PropTypes | ||
function getPropType(propValue) { | ||
var propType = typeof propValue; | ||
if (Array.isArray(propValue)) { | ||
return "array"; | ||
} | ||
if (propValue instanceof RegExp) { | ||
@@ -737,15 +632,11 @@ // Old webkits (at least until Android 4.0) return 'function' rather than | ||
} | ||
if (isSymbol(propType, propValue)) { | ||
return "symbol"; | ||
} | ||
return propType; | ||
} // This handles more types than `getPropType`. Only used for error messages. | ||
} | ||
// This handles more types than `getPropType`. Only used for error messages. | ||
// Copied from React.PropTypes | ||
function getPreciseType(propValue) { | ||
var propType = getPropType(propValue); | ||
if (propType === "object") { | ||
@@ -758,6 +649,4 @@ if (propValue instanceof Date) { | ||
} | ||
return propType; | ||
} | ||
function createObservableTypeCheckerCreator(allowNativeType, mobxType) { | ||
@@ -769,5 +658,3 @@ return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) { | ||
} | ||
var mobxChecker; | ||
switch (mobxType) { | ||
@@ -777,17 +664,12 @@ case "Array": | ||
break; | ||
case "Object": | ||
mobxChecker = mobx.isObservableObject; | ||
break; | ||
case "Map": | ||
mobxChecker = mobx.isObservableMap; | ||
break; | ||
default: | ||
throw new Error("Unexpected mobxType: " + mobxType); | ||
} | ||
var propValue = props[propName]; | ||
if (!mobxChecker(propValue)) { | ||
@@ -798,3 +680,2 @@ var preciseType = getPreciseType(propValue); | ||
} | ||
return null; | ||
@@ -804,3 +685,2 @@ }); | ||
} | ||
function createObservableArrayOfTypeChecker(allowNativeType, typeChecker) { | ||
@@ -811,3 +691,2 @@ return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) { | ||
} | ||
return mobx.untracked(function () { | ||
@@ -820,3 +699,2 @@ if (typeof typeChecker !== "function") { | ||
var propValue = props[propName]; | ||
for (var i = 0; i < propValue.length; i++) { | ||
@@ -826,3 +704,2 @@ error = typeChecker.apply(void 0, [propValue, i, componentName, location, propFullName + "[" + i + "]"].concat(rest)); | ||
} | ||
return null; | ||
@@ -833,3 +710,2 @@ } | ||
} | ||
var observableArray = /*#__PURE__*/createObservableTypeCheckerCreator(false, "Array"); | ||
@@ -852,4 +728,8 @@ var observableArrayOf = /*#__PURE__*/createObservableArrayOfTypeChecker.bind(null, false); | ||
if (!React.Component) throw new Error("mobx-react requires React to be available"); | ||
if (!mobx.observable) throw new Error("mobx-react requires mobx to be available"); | ||
if (!React.Component) { | ||
throw new Error("mobx-react requires React to be available"); | ||
} | ||
if (!mobx.observable) { | ||
throw new Error("mobx-react requires mobx to be available"); | ||
} | ||
@@ -856,0 +736,0 @@ Object.defineProperty(exports, 'Observer', { |
@@ -1,2 +0,2 @@ | ||
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("mobx"),require("react"),require("mobx-react-lite")):"function"==typeof define&&define.amd?define(["exports","mobx","react","mobx-react-lite"],r):r((e=e||self).mobxReact={},e.mobx,e.React,e.mobxReactLite)}(this,(function(e,r,t,n){"use strict";var o="default"in t?t.default:t,i=0,a={};function c(e){return a[e]||(a[e]=function(e){if("function"==typeof Symbol)return Symbol(e);var r="__$mobx-react "+e+" ("+i+")";return i++,r}(e)),a[e]}function s(e,r){if(u(e,r))return!0;if("object"!=typeof e||null===e||"object"!=typeof r||null===r)return!1;var t=Object.keys(e),n=Object.keys(r);if(t.length!==n.length)return!1;for(var o=0;o<t.length;o++)if(!Object.hasOwnProperty.call(r,t[o])||!u(e[t[o]],r[t[o]]))return!1;return!0}function u(e,r){return e===r?0!==e||1/e==1/r:e!=e&&r!=r}var l={$$typeof:1,render:1,compare:1,type:1,childContextTypes:1,contextType:1,contextTypes:1,defaultProps:1,getDefaultProps:1,getDerivedStateFromError:1,getDerivedStateFromProps:1,mixins:1,displayName:1,propTypes:1};function f(e,r,t){Object.hasOwnProperty.call(e,r)?e[r]=t:Object.defineProperty(e,r,{enumerable:!1,configurable:!0,writable:!0,value:t})}var p=c("patchMixins"),b=c("patchedDefinition");function d(e,r){for(var t=this,n=arguments.length,o=new Array(n>2?n-2:0),i=2;i<n;i++)o[i-2]=arguments[i];r.locks++;try{var a;return null!=e&&(a=e.apply(this,o)),a}finally{r.locks--,0===r.locks&&r.methods.forEach((function(e){e.apply(t,o)}))}}function y(e,r){return function(){for(var t=arguments.length,n=new Array(t),o=0;o<t;o++)n[o]=arguments[o];d.call.apply(d,[this,e,r].concat(n))}}function m(e,r,t){var n=function(e,r){var t=e[p]=e[p]||{},n=t[r]=t[r]||{};return n.locks=n.locks||0,n.methods=n.methods||[],n}(e,r);n.methods.indexOf(t)<0&&n.methods.push(t);var o=Object.getOwnPropertyDescriptor(e,r);if(!o||!o[b]){var i=function e(r,t,n,o,i){var a,c=y(i,o);return(a={})[b]=!0,a.get=function(){return c},a.set=function(i){if(this===r)c=y(i,o);else{var a=e(this,t,n,o,i);Object.defineProperty(this,t,a)}},a.configurable=!0,a.enumerable=n,a}(e,r,o?o.enumerable:void 0,n,e[r]);Object.defineProperty(e,r,i)}}var v=r.$mobx||"$mobx",h=c("isMobXReactObserver"),O=c("isUnmounted"),g=c("skipRender"),w=c("isForcingUpdate");function j(e){var r=e.prototype;if(e[h]){var o=P(r);console.warn("The provided component class ("+o+")\n has already been declared as an observer component.")}else e[h]=!0;if(r.componentWillReact)throw new Error("The componentWillReact life-cycle event is no longer supported");if(e.__proto__!==t.PureComponent)if(r.shouldComponentUpdate){if(r.shouldComponentUpdate!==R)throw new Error("It is not allowed to use shouldComponentUpdate in observer based components.")}else r.shouldComponentUpdate=R;S(r,"props"),S(r,"state"),e.contextType&&S(r,"context");var i=r.render;if("function"!=typeof i){var a=P(r);throw new Error("[mobx-react] class component ("+a+") is missing `render` method.\n`observer` requires `render` being a function defined on prototype.\n`render = () => {}` or `render = function() {}` is not supported.")}return r.render=function(){return this.render=n.isUsingStaticRendering()?i:x.call(this,i),this.render()},m(r,"componentDidMount",(function(){this[O]=!1,this.render[v]||t.Component.prototype.forceUpdate.call(this)})),m(r,"componentWillUnmount",(function(){if(!n.isUsingStaticRendering()){var e=this.render[v];if(e)e.dispose(),this.render[v]=null;else{var r=P(this);console.warn("The reactive render of an observer class component ("+r+")\n was overridden after MobX attached. This may result in a memory leak if the\n overridden reactive render was not properly disposed.")}this[O]=!0}})),e}function P(e){return e.displayName||e.name||e.constructor&&(e.constructor.displayName||e.constructor.name)||"<component>"}function x(e){var n=this;f(this,g,!1),f(this,w,!1);var o=P(this),i=e.bind(this),a=!1;return function e(){var c;a=!1;var s=null!=(c=e[v])?c:e[v]=function(){var e=new r.Reaction(o+".render()",(function(){if(!a&&(a=!0,!0!==n[O])){var r=!0;try{f(n,w,!0),n[g]||t.Component.prototype.forceUpdate.call(n),r=!1}finally{f(n,w,!1),r&&(e.dispose(),n.render[v]=null)}}}));return e.reactComponent=n,e}(),u=void 0,l=void 0;if(s.track((function(){try{l=r._allowStateChanges(!1,i)}catch(e){u=e}})),u)throw u;return l}}function R(e,r){return n.isUsingStaticRendering()&&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."),this.state!==r||!s(this.props,e)}function S(e,t){var n=c("reactProp_"+t+"_valueHolder"),o=c("reactProp_"+t+"_atomHolder");function i(){return this[o]||f(this,o,r.createAtom("reactive "+t)),this[o]}Object.defineProperty(e,t,{configurable:!0,enumerable:!0,get:function(){var e=!1;return r._allowStateReadsStart&&r._allowStateReadsEnd&&(e=r._allowStateReadsStart(!0)),i.call(this).reportObserved(),r._allowStateReadsStart&&r._allowStateReadsEnd&&r._allowStateReadsEnd(e),this[n]},set:function(e){this[w]||s(this[n],e)?f(this,n,e):(f(this,n,e),f(this,g,!0),i.call(this).reportChanged(),f(this,g,!1))}})}function C(e){return!0===e.isMobxInjector&&console.warn("Mobx observer: You are trying to use `observer` on a component that already has `inject`. Please apply `observer` before applying `inject`"),Object.prototype.isPrototypeOf.call(t.Component,e)||Object.prototype.isPrototypeOf.call(t.PureComponent,e)?j(e):n.observer(e)}function E(){return(E=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}).apply(this,arguments)}var A=["children"],k=o.createContext({});function U(e){var r=e.children,t=function(e,r){if(null==e)return{};var t,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r.indexOf(t=i[n])>=0||(o[t]=e[t]);return o}(e,A),n=o.useContext(k),i=o.useRef(E({},n,t));return o.createElement(k.Provider,{value:i.current},r)}function _(e,r,t,n){var i,a,c,s=o.forwardRef((function(t,n){var i=E({},t),a=o.useContext(k);return Object.assign(i,e(a||{},i)||{}),n&&(i.ref=n),o.createElement(r,i)}));return n&&(s=C(s)),s.isMobxInjector=!0,i=r,a=s,c=Object.getOwnPropertyNames(Object.getPrototypeOf(i)),Object.getOwnPropertyNames(i).forEach((function(e){l[e]||-1!==c.indexOf(e)||Object.defineProperty(a,e,Object.getOwnPropertyDescriptor(i,e))})),s.wrappedComponent=r,s.displayName=function(e,r){var t=e.displayName||e.name||e.constructor&&e.constructor.name||"Component";return r?"inject-with-"+r+"("+t+")":"inject("+t+")"}(r,t),s}function M(e){return function(r,t){return e.forEach((function(e){if(!(e in t)){if(!(e in r))throw new Error("MobX injector: Store '"+e+"' is not available! Make sure it is provided by some Provider");t[e]=r[e]}})),t}}U.displayName="MobXProvider";var T=c("disposeOnUnmountProto"),q=c("disposeOnUnmountInst");function D(){var e=this;[].concat(this[T]||[],this[q]||[]).forEach((function(r){var t="string"==typeof r?e[r]:r;null!=t&&(Array.isArray(t)?t.map((function(e){return e()})):t())}))}function N(e){function t(t,n,o,i,a,c){for(var s=arguments.length,u=new Array(s>6?s-6:0),l=6;l<s;l++)u[l-6]=arguments[l];return r.untracked((function(){return i=i||"<<anonymous>>",c=c||o,null==n[o]?t?new Error("The "+a+" `"+c+"` is marked as required in `"+i+"`, but its value is `"+(null===n[o]?"null":"undefined")+"`."):null:e.apply(void 0,[n,o,i,a,c].concat(u))}))}var n=t.bind(null,!1);return n.isRequired=t.bind(null,!0),n}function L(e){var r=typeof e;return Array.isArray(e)?"array":e instanceof RegExp?"object":function(e,r){return"symbol"===e||"Symbol"===r["@@toStringTag"]||"function"==typeof Symbol&&r instanceof Symbol}(r,e)?"symbol":r}function I(e,t){return N((function(n,o,i,a,c){return r.untracked((function(){if(e&&L(n[o])===t.toLowerCase())return null;var a;switch(t){case"Array":a=r.isObservableArray;break;case"Object":a=r.isObservableObject;break;case"Map":a=r.isObservableMap;break;default:throw new Error("Unexpected mobxType: "+t)}var s=n[o];if(!a(s)){var u=function(e){var r=L(e);if("object"===r){if(e instanceof Date)return"date";if(e instanceof RegExp)return"regexp"}return r}(s),l=e?" or javascript `"+t.toLowerCase()+"`":"";return new Error("Invalid prop `"+c+"` of type `"+u+"` supplied to `"+i+"`, expected `mobx.Observable"+t+"`"+l+".")}return null}))}))}function X(e,t){return N((function(n,o,i,a,c){for(var s=arguments.length,u=new Array(s>5?s-5:0),l=5;l<s;l++)u[l-5]=arguments[l];return r.untracked((function(){if("function"!=typeof t)return new Error("Property `"+c+"` of component `"+i+"` has invalid PropType notation.");var r=I(e,"Array")(n,o,i,a,c);if(r instanceof Error)return r;for(var s=n[o],l=0;l<s.length;l++)if((r=t.apply(void 0,[s,l,i,a,c+"["+l+"]"].concat(u)))instanceof Error)return r;return null}))}))}var $={observableArray:I(!1,"Array"),observableArrayOf:X.bind(null,!1),observableMap:I(!1,"Map"),observableObject:I(!1,"Object"),arrayOrObservableArray:I(!0,"Array"),arrayOrObservableArrayOf:X.bind(null,!0),objectOrObservableObject:I(!0,"Object")};if(!t.Component)throw new Error("mobx-react requires React to be available");if(!r.observable)throw new Error("mobx-react requires mobx to be available");Object.defineProperty(e,"Observer",{enumerable:!0,get:function(){return n.Observer}}),Object.defineProperty(e,"enableStaticRendering",{enumerable:!0,get:function(){return n.enableStaticRendering}}),Object.defineProperty(e,"isUsingStaticRendering",{enumerable:!0,get:function(){return n.isUsingStaticRendering}}),Object.defineProperty(e,"observerBatching",{enumerable:!0,get:function(){return n.observerBatching}}),Object.defineProperty(e,"useAsObservableSource",{enumerable:!0,get:function(){return n.useAsObservableSource}}),Object.defineProperty(e,"useLocalObservable",{enumerable:!0,get:function(){return n.useLocalObservable}}),Object.defineProperty(e,"useLocalStore",{enumerable:!0,get:function(){return n.useLocalStore}}),Object.defineProperty(e,"useObserver",{enumerable:!0,get:function(){return n.useObserver}}),Object.defineProperty(e,"useStaticRendering",{enumerable:!0,get:function(){return n.useStaticRendering}}),e.MobXProviderContext=k,e.PropTypes=$,e.Provider=U,e.disposeOnUnmount=function e(r,t){if(Array.isArray(t))return t.map((function(t){return e(r,t)}));var n=Object.getPrototypeOf(r).constructor,i=Object.getPrototypeOf(r.constructor),a=Object.getPrototypeOf(Object.getPrototypeOf(r));if(n!==o.Component&&n!==o.PureComponent&&i!==o.Component&&i!==o.PureComponent&&a!==o.Component&&a!==o.PureComponent)throw new Error("[mobx-react] disposeOnUnmount only supports direct subclasses of React.Component or React.PureComponent.");if("string"!=typeof t&&"function"!=typeof t&&!Array.isArray(t))throw new Error("[mobx-react] disposeOnUnmount only works if the parameter is either a property key or a function.");var c=!!r[T]||!!r[q];return("string"==typeof t?r[T]||(r[T]=[]):r[q]||(r[q]=[])).push(t),c||m(r,"componentWillUnmount",D),"string"!=typeof t?t:void 0},e.inject=function(){for(var e=arguments.length,r=new Array(e),t=0;t<e;t++)r[t]=arguments[t];if("function"==typeof arguments[0]){var n=arguments[0];return function(e){return _(n,e,n.name,!0)}}return function(e){return _(M(r),e,r.join("-"),!1)}},e.observer=C,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("mobx"),require("react"),require("mobx-react-lite")):"function"==typeof define&&define.amd?define(["exports","mobx","react","mobx-react-lite"],r):r((e=e||self).mobxReact={},e.mobx,e.React,e.mobxReactLite)}(this,(function(e,r,t,n){"use strict";var o="default"in t?t.default:t;function i(e,r){if(a(e,r))return!0;if("object"!=typeof e||null===e||"object"!=typeof r||null===r)return!1;var t=Object.keys(e),n=Object.keys(r);if(t.length!==n.length)return!1;for(var o=0;o<t.length;o++)if(!Object.hasOwnProperty.call(r,t[o])||!a(e[t[o]],r[t[o]]))return!1;return!0}function a(e,r){return e===r?0!==e||1/e==1/r:e!=e&&r!=r}var c={$$typeof:1,render:1,compare:1,type:1,childContextTypes:1,contextType:1,contextTypes:1,defaultProps:1,getDefaultProps:1,getDerivedStateFromError:1,getDerivedStateFromProps:1,mixins:1,displayName:1,propTypes:1},s=Symbol("patchMixins"),u=Symbol("patchedDefinition");function l(e,r){for(var t=this,n=arguments.length,o=new Array(n>2?n-2:0),i=2;i<n;i++)o[i-2]=arguments[i];r.locks++;try{var a;return null!=e&&(a=e.apply(this,o)),a}finally{r.locks--,0===r.locks&&r.methods.forEach((function(e){e.apply(t,o)}))}}function f(e,r){return function(){for(var t=arguments.length,n=new Array(t),o=0;o<t;o++)n[o]=arguments[o];l.call.apply(l,[this,e,r].concat(n))}}function p(e,r,t){var n=function(e,r){var t=e[s]=e[s]||{},n=t[r]=t[r]||{};return n.locks=n.locks||0,n.methods=n.methods||[],n}(e,r);n.methods.indexOf(t)<0&&n.methods.push(t);var o=Object.getOwnPropertyDescriptor(e,r);if(!o||!o[u]){var i=function e(r,t,n,o,i){var a,c=f(i,o);return(a={})[u]=!0,a.get=function(){return c},a.set=function(i){if(this===r)c=f(i,o);else{var a=e(this,t,n,o,i);Object.defineProperty(this,t,a)}},a.configurable=!0,a.enumerable=n,a}(e,r,o?o.enumerable:void 0,n,e[r]);Object.defineProperty(e,r,i)}}var b=Symbol("ObserverAdministration"),d=Symbol("isMobXReactObserver");function m(e){var t;return null!=(t=e[b])?t:e[b]={reaction:null,mounted:!1,forceUpdate:null,name:y(e.constructor),state:void 0,props:void 0,context:void 0,propsAtom:r.createAtom("props"),stateAtom:r.createAtom("state"),contextAtom:r.createAtom("context"),isUpdating:!1}}function y(e){return e.displayName||e.name||"<component>"}function v(e){var t=e.bind(this),o=m(this);return function(){o.reaction||(o.reaction=function(e){return new r.Reaction(e.name+".render()",(function(){if(!e.isUpdating&&e.mounted)try{e.isUpdating=!0,null==e.forceUpdate||e.forceUpdate()}catch(t){var r;null==(r=e.reaction)||r.dispose(),e.reaction=null}finally{e.isUpdating=!1}}))}(o),o.mounted||n._observerFinalizationRegistry.register(this,o,this));var e=void 0,i=void 0;if(o.reaction.track((function(){try{i=r._allowStateChanges(!1,t)}catch(r){e=r}})),e)throw e;return i}}function h(e,r){return n.isUsingStaticRendering()&&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."),this.state!==r||!i(this.props,e)}function g(e){var t=e+"Atom";return{configurable:!0,enumerable:!0,get:function(){var n=m(this),o=r._allowStateReadsStart(!0);return n[t].reportObserved(),r._allowStateReadsEnd(o),n[e]},set:function(r){var n=m(this);n.isUpdating||i(n[e],r)?n[e]=r:(n[e]=r,n.isUpdating=!0,n[t].reportChanged(),n.isUpdating=!1)}}}var O=g("props"),j=g("state"),w=g("context");function P(e){return!0===e.isMobxInjector&&console.warn("Mobx observer: You are trying to use `observer` on a component that already has `inject`. Please apply `observer` before applying `inject`"),Object.prototype.isPrototypeOf.call(t.Component,e)||Object.prototype.isPrototypeOf.call(t.PureComponent,e)?function(e){var r=e.prototype;if(e[d]){var o=y(e);console.warn("The provided component class ("+o+")\n has already been declared as an observer component.")}else e[d]=!0;if(r.componentWillReact)throw new Error("The componentWillReact life-cycle event is no longer supported");if(e.__proto__!==t.PureComponent)if(r.shouldComponentUpdate){if(r.shouldComponentUpdate!==h)throw new Error("It is not allowed to use shouldComponentUpdate in observer based components.")}else r.shouldComponentUpdate=h;Object.defineProperties(r,{props:O,state:j,context:w});var i=r.render;if("function"!=typeof i){var a=y(e);throw new Error("[mobx-react] class component ("+a+") is missing `render` method.\n`observer` requires `render` being a function defined on prototype.\n`render = () => {}` or `render = function() {}` is not supported.")}return r.render=function(){return Object.defineProperty(this,"render",{configurable:!1,writable:!1,value:n.isUsingStaticRendering()?i:v.call(this,i)}),this.render()},p(r,"componentDidMount",(function(){var e=this,r=m(this);r.mounted=!0,n._observerFinalizationRegistry.unregister(r),r.forceUpdate=function(){return e.forceUpdate()},r.reaction||r.forceUpdate()})),p(r,"componentWillUnmount",(function(){var e;if(!n.isUsingStaticRendering()){var r=m(this);null==(e=r.reaction)||e.dispose(),r.reaction=null,r.forceUpdate=null,r.mounted=!1}})),e}(e):n.observer(e)}function x(){return(x=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}).apply(this,arguments)}var U=["children"],A=o.createContext({});function R(e){var r=e.children,t=function(e,r){if(null==e)return{};var t,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r.indexOf(t=i[n])>=0||(o[t]=e[t]);return o}(e,U),n=o.useContext(A),i=o.useRef(x({},n,t));return o.createElement(A.Provider,{value:i.current},r)}function S(e,r,t,n){var i,a,s,u=o.forwardRef((function(t,n){var i=x({},t),a=o.useContext(A);return Object.assign(i,e(a||{},i)||{}),n&&(i.ref=n),o.createElement(r,i)}));return n&&(u=P(u)),u.isMobxInjector=!0,i=r,a=u,s=Object.getOwnPropertyNames(Object.getPrototypeOf(i)),Object.getOwnPropertyNames(i).forEach((function(e){c[e]||-1!==s.indexOf(e)||Object.defineProperty(a,e,Object.getOwnPropertyDescriptor(i,e))})),u.wrappedComponent=r,u.displayName=function(e,r){var t=e.displayName||e.name||e.constructor&&e.constructor.name||"Component";return r?"inject-with-"+r+"("+t+")":"inject("+t+")"}(r,t),u}function C(e){return function(r,t){return e.forEach((function(e){if(!(e in t)){if(!(e in r))throw new Error("MobX injector: Store '"+e+"' is not available! Make sure it is provided by some Provider");t[e]=r[e]}})),t}}R.displayName="MobXProvider";var E=Number.parseInt(o.version.split(".")[0]),k=!1,M=Symbol("disposeOnUnmountProto"),T=Symbol("disposeOnUnmountInst");function _(){var e=this;[].concat(this[M]||[],this[T]||[]).forEach((function(r){var t="string"==typeof r?e[r]:r;null!=t&&(Array.isArray(t)?t.map((function(e){return e()})):t())}))}function D(e){function t(t,n,o,i,a,c){for(var s=arguments.length,u=new Array(s>6?s-6:0),l=6;l<s;l++)u[l-6]=arguments[l];return r.untracked((function(){return i=i||"<<anonymous>>",c=c||o,null==n[o]?t?new Error("The "+a+" `"+c+"` is marked as required in `"+i+"`, but its value is `"+(null===n[o]?"null":"undefined")+"`."):null:e.apply(void 0,[n,o,i,a,c].concat(u))}))}var n=t.bind(null,!1);return n.isRequired=t.bind(null,!0),n}function q(e){var r=typeof e;return Array.isArray(e)?"array":e instanceof RegExp?"object":function(e,r){return"symbol"===e||"Symbol"===r["@@toStringTag"]||"function"==typeof Symbol&&r instanceof Symbol}(r,e)?"symbol":r}function I(e,t){return D((function(n,o,i,a,c){return r.untracked((function(){if(e&&q(n[o])===t.toLowerCase())return null;var a;switch(t){case"Array":a=r.isObservableArray;break;case"Object":a=r.isObservableObject;break;case"Map":a=r.isObservableMap;break;default:throw new Error("Unexpected mobxType: "+t)}var s=n[o];if(!a(s)){var u=function(e){var r=q(e);if("object"===r){if(e instanceof Date)return"date";if(e instanceof RegExp)return"regexp"}return r}(s),l=e?" or javascript `"+t.toLowerCase()+"`":"";return new Error("Invalid prop `"+c+"` of type `"+u+"` supplied to `"+i+"`, expected `mobx.Observable"+t+"`"+l+".")}return null}))}))}function N(e,t){return D((function(n,o,i,a,c){for(var s=arguments.length,u=new Array(s>5?s-5:0),l=5;l<s;l++)u[l-5]=arguments[l];return r.untracked((function(){if("function"!=typeof t)return new Error("Property `"+c+"` of component `"+i+"` has invalid PropType notation.");var r=I(e,"Array")(n,o,i,a,c);if(r instanceof Error)return r;for(var s=n[o],l=0;l<s.length;l++)if((r=t.apply(void 0,[s,l,i,a,c+"["+l+"]"].concat(u)))instanceof Error)return r;return null}))}))}var L={observableArray:I(!1,"Array"),observableArrayOf:N.bind(null,!1),observableMap:I(!1,"Map"),observableObject:I(!1,"Object"),arrayOrObservableArray:I(!0,"Array"),arrayOrObservableArrayOf:N.bind(null,!0),objectOrObservableObject:I(!0,"Object")};if(!t.Component)throw new Error("mobx-react requires React to be available");if(!r.observable)throw new Error("mobx-react requires mobx to be available");Object.defineProperty(e,"Observer",{enumerable:!0,get:function(){return n.Observer}}),Object.defineProperty(e,"enableStaticRendering",{enumerable:!0,get:function(){return n.enableStaticRendering}}),Object.defineProperty(e,"isUsingStaticRendering",{enumerable:!0,get:function(){return n.isUsingStaticRendering}}),Object.defineProperty(e,"observerBatching",{enumerable:!0,get:function(){return n.observerBatching}}),Object.defineProperty(e,"useAsObservableSource",{enumerable:!0,get:function(){return n.useAsObservableSource}}),Object.defineProperty(e,"useLocalObservable",{enumerable:!0,get:function(){return n.useLocalObservable}}),Object.defineProperty(e,"useLocalStore",{enumerable:!0,get:function(){return n.useLocalStore}}),Object.defineProperty(e,"useObserver",{enumerable:!0,get:function(){return n.useObserver}}),Object.defineProperty(e,"useStaticRendering",{enumerable:!0,get:function(){return n.useStaticRendering}}),e.MobXProviderContext=A,e.PropTypes=L,e.Provider=R,e.disposeOnUnmount=function e(r,t){if(Array.isArray(t))return t.map((function(t){return e(r,t)}));k||(E>=18?console.error("[mobx-react] disposeOnUnmount is not compatible with React 18 and higher. Don't use it."):console.warn("[mobx-react] disposeOnUnmount is deprecated. It won't work correctly with React 18 and higher."),k=!0);var n=Object.getPrototypeOf(r).constructor,i=Object.getPrototypeOf(r.constructor),a=Object.getPrototypeOf(Object.getPrototypeOf(r));if(n!==o.Component&&n!==o.PureComponent&&i!==o.Component&&i!==o.PureComponent&&a!==o.Component&&a!==o.PureComponent)throw new Error("[mobx-react] disposeOnUnmount only supports direct subclasses of React.Component or React.PureComponent.");if("string"!=typeof t&&"function"!=typeof t&&!Array.isArray(t))throw new Error("[mobx-react] disposeOnUnmount only works if the parameter is either a property key or a function.");var c=!!r[M]||!!r[T];return("string"==typeof t?r[M]||(r[M]=[]):r[T]||(r[T]=[])).push(t),c||p(r,"componentWillUnmount",_),"string"!=typeof t?t:void 0},e.inject=function(){for(var e=arguments.length,r=new Array(e),t=0;t<e;t++)r[t]=arguments[t];if("function"==typeof arguments[0]){var n=arguments[0];return function(e){return S(n,e,n.name,!0)}}return function(e){return S(C(r),e,r.join("-"),!1)}},e.observer=P,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=mobxreact.umd.production.min.js.map |
@@ -1,2 +0,2 @@ | ||
/// <reference types="react" /> | ||
export declare function makeClassComponentObserver(componentClass: React.ComponentClass<any, any>): React.ComponentClass<any, any>; | ||
import { ComponentClass } from "react"; | ||
export declare function makeClassComponentObserver(componentClass: ComponentClass<any, any>): ComponentClass<any, any>; |
@@ -1,2 +0,1 @@ | ||
export declare function newSymbol(name: string): symbol | string; | ||
export declare function shallowEqual(objA: any, objB: any): boolean; | ||
@@ -3,0 +2,0 @@ export declare function copyStaticProperties(base: object, target: object): void; |
{ | ||
"name": "mobx-react", | ||
"version": "7.6.0", | ||
"version": "8.0.0", | ||
"description": "React bindings for MobX. Create fully reactive components.", | ||
@@ -39,6 +39,6 @@ "source": "src/index.ts", | ||
"dependencies": { | ||
"mobx-react-lite": "^3.4.0" | ||
"mobx-react-lite": "^4.0.0" | ||
}, | ||
"peerDependencies": { | ||
"mobx": "^6.1.0", | ||
"mobx": "^6.9.0", | ||
"react": "^16.8.0 || ^17 || ^18" | ||
@@ -55,4 +55,5 @@ }, | ||
"devDependencies": { | ||
"mobx": "^6.7.0", | ||
"mobx-react-lite": "^3.4.0" | ||
"mobx": "^6.9.0", | ||
"mobx-react-lite": "^4.0.0", | ||
"expose-gc": "^1.0.0" | ||
}, | ||
@@ -59,0 +60,0 @@ "keywords": [ |
@@ -14,11 +14,11 @@ # mobx-react | ||
## Choosing your version | ||
## Compatibility matrix | ||
There are currently two actively maintained versions of mobx-react: | ||
Only the latest version is actively maintained. If you're missing a fix or a feature in older version, consider upgrading or using [patch-package](https://www.npmjs.com/package/patch-package) | ||
| NPM Version | Support MobX version | Supported React versions | Supports hook based components | | ||
| ----------- | -------------------- | ------------------------ | -------------------------------------------------------------------------------- | | ||
| v7 | 6.\* | 16.8+ | Yes | | ||
| v6 | 4._ / 5._ | 16.8+ | Yes | | ||
| v5 | 4._ / 5._ | 0.13+ | No, but it is possible to use `<Observer>` sections inside hook based components | | ||
| v7 | 6.\* | >16.8 | Yes | | ||
| v6 | 4.\* / 5.\* | >16.8 <18 | Yes | | ||
| v5 | 4.\* / 5.\* | >0.13 <18 | No, but it is possible to use `<Observer>` sections inside hook based components | | ||
@@ -140,4 +140,2 @@ mobx-react 6 / 7 is a repackage of the smaller [mobx-react-lite](https://github.com/mobxjs/mobx/tree/main/packages/mobx-react-lite) package + following features from the `mobx-react@5` package added: | ||
[User guide](https://mobx-react.js.org/state-local) | ||
Local observable state can be introduced by using the `useLocalObservable` hook, that runs once to create an observable store. A quick example would be: | ||
@@ -223,4 +221,2 @@ | ||
See also [the migration guide to React Hooks](https://mobx-react.js.org/recipes-migration). | ||
_Note: usually there is no need anymore to use `Provider` / `inject` in new code bases; most of its features are now covered by `React.createContext`._ | ||
@@ -276,3 +272,3 @@ | ||
Values provided through `Provider` should be final. Make sure that if you put things in `context` that might change over time, that they are `@observable` or provide some other means to listen to changes, like callbacks. However, if your stores will change over time, like an observable value of another store, MobX will throw an error. | ||
This restriction exists mainly for legacy reasons. If you have a scenario where you need to modify the set of stores, please leave a comment about it in this issue https://github.com/mobxjs/mobx-react/issues/745. Or a preferred way is to [use React Context](https://mobx-react.js.org/recipes-context) directly which does not have this restriction. | ||
This restriction exists mainly for legacy reasons. If you have a scenario where you need to modify the set of stores, please leave a comment about it in this issue https://github.com/mobxjs/mobx-react/issues/745. Or a preferred way is to [use React Context](https://reactjs.org/docs/context.html) directly which does not have this restriction. | ||
@@ -405,4 +401,2 @@ #### Inject as function | ||
By [migrating to React Hooks](https://mobx-react.js.org/recipes-migration) you can avoid problems with TypeScript. | ||
#### Testing store injection | ||
@@ -409,0 +403,0 @@ |
import React from "react" | ||
import { patch, newSymbol } from "./utils/utils" | ||
import { patch } from "./utils/utils" | ||
const reactMajorVersion = Number.parseInt(React.version.split(".")[0]) | ||
let warnedAboutDisposeOnUnmountDeprecated = false | ||
type Disposer = () => void | ||
const protoStoreKey = newSymbol("disposeOnUnmountProto") | ||
const instStoreKey = newSymbol("disposeOnUnmountInst") | ||
const protoStoreKey = Symbol("disposeOnUnmountProto") | ||
const instStoreKey = Symbol("disposeOnUnmountInst") | ||
@@ -20,3 +23,10 @@ function runDisposersOnWillUnmount() { | ||
/** | ||
* @deprecated `disposeOnUnmount` is not compatible with React 18 and higher. | ||
*/ | ||
export function disposeOnUnmount(target: React.Component<any, any>, propertyKey: PropertyKey): void | ||
/** | ||
* @deprecated `disposeOnUnmount` is not compatible with React 18 and higher. | ||
*/ | ||
export function disposeOnUnmount<TF extends Disposer | Array<Disposer>>( | ||
@@ -27,2 +37,5 @@ target: React.Component<any, any>, | ||
/** | ||
* @deprecated `disposeOnUnmount` is not compatible with React 18 and higher. | ||
*/ | ||
export function disposeOnUnmount( | ||
@@ -36,2 +49,15 @@ target: React.Component<any, any>, | ||
if (!warnedAboutDisposeOnUnmountDeprecated) { | ||
if (reactMajorVersion >= 18) { | ||
console.error( | ||
"[mobx-react] disposeOnUnmount is not compatible with React 18 and higher. Don't use it." | ||
) | ||
} else { | ||
console.warn( | ||
"[mobx-react] disposeOnUnmount is deprecated. It won't work correctly with React 18 and higher." | ||
) | ||
} | ||
warnedAboutDisposeOnUnmountDeprecated = true | ||
} | ||
const c = Object.getPrototypeOf(target).constructor | ||
@@ -38,0 +64,0 @@ const c2 = Object.getPrototypeOf(target.constructor) |
import { observable } from "mobx" | ||
import { Component } from "react" | ||
if (!Component) throw new Error("mobx-react requires React to be available") | ||
if (!observable) throw new Error("mobx-react requires mobx to be available") | ||
if (!Component) { | ||
throw new Error("mobx-react requires React to be available") | ||
} | ||
if (!observable) { | ||
throw new Error("mobx-react requires mobx to be available") | ||
} | ||
export { | ||
@@ -8,0 +13,0 @@ Observer, |
@@ -1,2 +0,2 @@ | ||
import { PureComponent, Component } from "react" | ||
import { PureComponent, Component, ComponentClass, ClassAttributes } from "react" | ||
import { | ||
@@ -6,23 +6,59 @@ createAtom, | ||
Reaction, | ||
$mobx, | ||
_allowStateReadsStart, | ||
_allowStateReadsEnd | ||
_allowStateReadsEnd, | ||
_getGlobalState, | ||
IAtom | ||
} from "mobx" | ||
import { isUsingStaticRendering } from "mobx-react-lite" | ||
import { | ||
isUsingStaticRendering, | ||
_observerFinalizationRegistry as observerFinalizationRegistry | ||
} from "mobx-react-lite" | ||
import { shallowEqual, patch } from "./utils/utils" | ||
import { newSymbol, shallowEqual, setHiddenProp, patch } from "./utils/utils" | ||
const administrationSymbol = Symbol("ObserverAdministration") | ||
const isMobXReactObserverSymbol = Symbol("isMobXReactObserver") | ||
const mobxAdminProperty = $mobx || "$mobx" // BC | ||
const mobxObserverProperty = newSymbol("isMobXReactObserver") | ||
const mobxIsUnmounted = newSymbol("isUnmounted") | ||
const skipRenderKey = newSymbol("skipRender") | ||
const isForcingUpdateKey = newSymbol("isForcingUpdate") | ||
type ObserverAdministration = { | ||
reaction: Reaction | null // also serves as disposed flag | ||
forceUpdate: Function | null | ||
mounted: boolean // we could use forceUpdate as mounted flag | ||
name: string | ||
propsAtom: IAtom | ||
stateAtom: IAtom | ||
contextAtom: IAtom | ||
props: any | ||
state: any | ||
context: any | ||
// Setting this.props causes forceUpdate, because this.props is observable. | ||
// forceUpdate sets this.props. | ||
// This flag is used to avoid the loop. | ||
isUpdating: boolean | ||
} | ||
function getAdministration(component: Component): ObserverAdministration { | ||
// We create administration lazily, because we can't patch constructor | ||
// and the exact moment of initialization partially depends on React internals. | ||
// At the time of writing this, the first thing invoked is one of the observable getter/setter (state/props/context). | ||
return (component[administrationSymbol] ??= { | ||
reaction: null, | ||
mounted: false, | ||
forceUpdate: null, | ||
name: getDisplayName(component.constructor as ComponentClass), | ||
state: undefined, | ||
props: undefined, | ||
context: undefined, | ||
propsAtom: createAtom("props"), | ||
stateAtom: createAtom("state"), | ||
contextAtom: createAtom("context"), | ||
isUpdating: false | ||
}) | ||
} | ||
export function makeClassComponentObserver( | ||
componentClass: React.ComponentClass<any, any> | ||
): React.ComponentClass<any, any> { | ||
const target = componentClass.prototype | ||
componentClass: ComponentClass<any, any> | ||
): ComponentClass<any, any> { | ||
const { prototype } = componentClass | ||
if (componentClass[mobxObserverProperty]) { | ||
const displayName = getDisplayName(target) | ||
if (componentClass[isMobXReactObserverSymbol]) { | ||
const displayName = getDisplayName(componentClass) | ||
console.warn( | ||
@@ -33,12 +69,12 @@ `The provided component class (${displayName}) | ||
} else { | ||
componentClass[mobxObserverProperty] = true | ||
componentClass[isMobXReactObserverSymbol] = true | ||
} | ||
if (target.componentWillReact) { | ||
if (prototype.componentWillReact) { | ||
throw new Error("The componentWillReact life-cycle event is no longer supported") | ||
} | ||
if (componentClass["__proto__"] !== PureComponent) { | ||
if (!target.shouldComponentUpdate) { | ||
target.shouldComponentUpdate = observerSCU | ||
} else if (target.shouldComponentUpdate !== observerSCU) { | ||
if (!prototype.shouldComponentUpdate) { | ||
prototype.shouldComponentUpdate = observerSCU | ||
} else if (prototype.shouldComponentUpdate !== observerSCU) { | ||
// n.b. unequal check, instead of existence check, as @observer might be on superclass as well | ||
@@ -55,11 +91,11 @@ throw new Error( | ||
// 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+ | ||
makeObservableProp(target, "props") | ||
makeObservableProp(target, "state") | ||
if (componentClass.contextType) { | ||
makeObservableProp(target, "context") | ||
} | ||
Object.defineProperties(prototype, { | ||
props: observablePropsDescriptor, | ||
state: observableStateDescriptor, | ||
context: observableContextDescriptor | ||
}) | ||
const originalRender = target.render | ||
const originalRender = prototype.render | ||
if (typeof originalRender !== "function") { | ||
const displayName = getDisplayName(target) | ||
const displayName = getDisplayName(componentClass) | ||
throw new Error( | ||
@@ -71,38 +107,62 @@ `[mobx-react] class component (${displayName}) is missing \`render\` method.` + | ||
} | ||
target.render = function () { | ||
this.render = isUsingStaticRendering() | ||
? originalRender | ||
: createReactiveRender.call(this, originalRender) | ||
prototype.render = function () { | ||
Object.defineProperty(this, "render", { | ||
// There is no safe way to replace render, therefore it's forbidden. | ||
configurable: false, | ||
writable: false, | ||
value: isUsingStaticRendering() | ||
? originalRender | ||
: createReactiveRender.call(this, originalRender) | ||
}) | ||
return this.render() | ||
} | ||
patch(target, "componentDidMount", function () { | ||
this[mobxIsUnmounted] = false | ||
if (!this.render[mobxAdminProperty]) { | ||
// Reaction is re-created automatically during render, but a component can re-mount and skip render #3395. | ||
// To re-create the reaction and re-subscribe to relevant observables we have to force an update. | ||
Component.prototype.forceUpdate.call(this) | ||
patch(prototype, "componentDidMount", function () { | ||
// `componentDidMount` may not be called at all. React can abandon the instance after `render`. | ||
// That's why we use finalization registry to dispose reaction created during render. | ||
// Happens with `<Suspend>` see #3492 | ||
// | ||
// `componentDidMount` can be called immediately after `componentWillUnmount` without calling `render` in between. | ||
// Happens with `<StrictMode>`see #3395. | ||
// | ||
// If `componentDidMount` is called, it's guaranteed to run synchronously with render (similary to `useLayoutEffect`). | ||
// Therefore we don't have to worry about external (observable) state being updated before mount (no state version checking). | ||
// | ||
// Things may change: "In the future, React will provide a feature that lets components preserve state between unmounts" | ||
const admin = getAdministration(this) | ||
admin.mounted = true | ||
// Component instance committed, prevent reaction disposal. | ||
observerFinalizationRegistry.unregister(admin) | ||
// We don't set forceUpdate before mount because it requires a reference to `this`, | ||
// therefore `this` could NOT be garbage collected before mount, | ||
// preventing reaction disposal by FinalizationRegistry and leading to memory leak. | ||
// As an alternative we could have `admin.instanceRef = new WeakRef(this)`, but lets avoid it if possible. | ||
admin.forceUpdate = () => this.forceUpdate() | ||
if (!admin.reaction) { | ||
// 1. Instance was unmounted (reaction disposed) and immediately remounted without running render #3395. | ||
// 2. Reaction was disposed by finalization registry before mount. Shouldn't ever happen for class components: | ||
// `componentDidMount` runs synchronously after render, but our registry are deferred (can't run in between). | ||
// In any case we lost subscriptions to observables, so we have to create new reaction and re-render to resubscribe. | ||
// The reaction will be created lazily by following render. | ||
admin.forceUpdate() | ||
} | ||
}) | ||
patch(target, "componentWillUnmount", function () { | ||
patch(prototype, "componentWillUnmount", function () { | ||
if (isUsingStaticRendering()) { | ||
return | ||
} | ||
const admin = getAdministration(this) | ||
admin.reaction?.dispose() | ||
admin.reaction = null | ||
admin.forceUpdate = null | ||
admin.mounted = false | ||
}) | ||
const reaction = this.render[mobxAdminProperty] | ||
if (reaction) { | ||
reaction.dispose() | ||
// Forces reaction to be re-created on next render | ||
this.render[mobxAdminProperty] = null | ||
} else { | ||
// Render may have been hot-swapped and/or overridden by a subclass. | ||
const displayName = getDisplayName(this) | ||
console.warn( | ||
`The reactive render of an observer class component (${displayName}) | ||
was overridden after MobX attached. This may result in a memory leak if the | ||
overridden reactive render was not properly disposed.` | ||
) | ||
} | ||
this[mobxIsUnmounted] = true | ||
}) | ||
return componentClass | ||
@@ -112,77 +172,37 @@ } | ||
// Generates a friendly name for debugging | ||
function getDisplayName(comp: any) { | ||
return ( | ||
comp.displayName || | ||
comp.name || | ||
(comp.constructor && (comp.constructor.displayName || comp.constructor.name)) || | ||
"<component>" | ||
) | ||
function getDisplayName(componentClass: ComponentClass) { | ||
return componentClass.displayName || componentClass.name || "<component>" | ||
} | ||
function createReactiveRender(originalRender: any) { | ||
/** | ||
* If props are shallowly modified, react will render anyway, | ||
* so atom.reportChanged() should not result in yet another re-render | ||
*/ | ||
setHiddenProp(this, skipRenderKey, false) | ||
/** | ||
* forceUpdate will re-assign this.props. We don't want that to cause a loop, | ||
* so detect these changes | ||
*/ | ||
setHiddenProp(this, isForcingUpdateKey, false) | ||
const initialName = getDisplayName(this) | ||
const boundOriginalRender = originalRender.bind(this) | ||
let isRenderingPending = false | ||
const admin = getAdministration(this) | ||
const createReaction = () => { | ||
const reaction = new Reaction(`${initialName}.render()`, () => { | ||
if (!isRenderingPending) { | ||
// N.B. Getting here *before mounting* means that a component constructor has side effects (see the relevant test in misc.test.tsx) | ||
// This unidiomatic React usage but React will correctly warn about this so we continue as usual | ||
// See #85 / Pull #44 | ||
isRenderingPending = true | ||
if (this[mobxIsUnmounted] !== true) { | ||
let hasError = true | ||
try { | ||
setHiddenProp(this, isForcingUpdateKey, true) | ||
if (!this[skipRenderKey]) { | ||
Component.prototype.forceUpdate.call(this) | ||
} | ||
hasError = false | ||
} finally { | ||
setHiddenProp(this, isForcingUpdateKey, false) | ||
if (hasError) { | ||
reaction.dispose() | ||
// Forces reaction to be re-created on next render | ||
this.render[mobxAdminProperty] = null | ||
} | ||
} | ||
} | ||
function reactiveRender() { | ||
if (!admin.reaction) { | ||
// Create reaction lazily to support re-mounting #3395 | ||
admin.reaction = createReaction(admin) | ||
if (!admin.mounted) { | ||
// React can abandon this instance and never call `componentDidMount`/`componentWillUnmount`, | ||
// we have to make sure reaction will be disposed. | ||
observerFinalizationRegistry.register(this, admin, this) | ||
} | ||
}) | ||
reaction["reactComponent"] = this | ||
return reaction | ||
} | ||
} | ||
function reactiveRender() { | ||
isRenderingPending = false | ||
// Create reaction lazily to support re-mounting #3395 | ||
const reaction = (reactiveRender[mobxAdminProperty] ??= createReaction()) | ||
let exception: unknown = undefined | ||
let rendering = undefined | ||
reaction.track(() => { | ||
let error: unknown = undefined | ||
let renderResult = undefined | ||
admin.reaction.track(() => { | ||
try { | ||
// TODO@major | ||
// Optimization: replace with _allowStateChangesStart/End (not available in mobx@6.0.0) | ||
rendering = _allowStateChanges(false, boundOriginalRender) | ||
renderResult = _allowStateChanges(false, boundOriginalRender) | ||
} catch (e) { | ||
exception = e | ||
error = e | ||
} | ||
}) | ||
if (exception) { | ||
throw exception | ||
if (error) { | ||
throw error | ||
} | ||
return rendering | ||
return renderResult | ||
} | ||
@@ -193,3 +213,31 @@ | ||
function observerSCU(nextProps: React.ClassAttributes<any>, nextState: any): boolean { | ||
function createReaction(admin: ObserverAdministration) { | ||
return new Reaction(`${admin.name}.render()`, () => { | ||
if (admin.isUpdating) { | ||
// Reaction is suppressed when setting new state/props/context, | ||
// this is when component is already being updated. | ||
return | ||
} | ||
if (!admin.mounted) { | ||
// This is neccessary to avoid react warning about calling forceUpdate on component that isn't mounted yet. | ||
// This happens when component is abandoned after render - our reaction is already created and reacts to changes. | ||
// Due to the synchronous nature of `componenDidMount`, we don't have to worry that component could eventually mount and require update. | ||
return | ||
} | ||
try { | ||
// forceUpdate sets new `props`, since we made it observable, it would `reportChanged`, causing a loop. | ||
admin.isUpdating = true | ||
admin.forceUpdate?.() | ||
} catch (error) { | ||
admin.reaction?.dispose() | ||
admin.reaction = null | ||
} finally { | ||
admin.isUpdating = false | ||
} | ||
}) | ||
} | ||
function observerSCU(nextProps: ClassAttributes<any>, nextState: any): boolean { | ||
if (isUsingStaticRendering()) { | ||
@@ -211,43 +259,39 @@ console.warn( | ||
function makeObservableProp(target: any, propName: string): void { | ||
const valueHolderKey = newSymbol(`reactProp_${propName}_valueHolder`) | ||
const atomHolderKey = newSymbol(`reactProp_${propName}_atomHolder`) | ||
function getAtom() { | ||
if (!this[atomHolderKey]) { | ||
setHiddenProp(this, atomHolderKey, createAtom("reactive " + propName)) | ||
} | ||
return this[atomHolderKey] | ||
} | ||
Object.defineProperty(target, propName, { | ||
function createObservablePropDescriptor(key: "props" | "state" | "context") { | ||
const atomKey = `${key}Atom` | ||
return { | ||
configurable: true, | ||
enumerable: true, | ||
get: function () { | ||
let prevReadState = false | ||
get() { | ||
const admin = getAdministration(this) | ||
// Why this check? BC? | ||
// @ts-expect-error | ||
if (_allowStateReadsStart && _allowStateReadsEnd) { | ||
prevReadState = _allowStateReadsStart(true) | ||
} | ||
getAtom.call(this).reportObserved() | ||
let prevReadState = _allowStateReadsStart(true) | ||
// Why this check? BC? | ||
// @ts-expect-error | ||
if (_allowStateReadsStart && _allowStateReadsEnd) { | ||
_allowStateReadsEnd(prevReadState) | ||
} | ||
admin[atomKey].reportObserved() | ||
return this[valueHolderKey] | ||
_allowStateReadsEnd(prevReadState) | ||
return admin[key] | ||
}, | ||
set: function set(v) { | ||
if (!this[isForcingUpdateKey] && !shallowEqual(this[valueHolderKey], v)) { | ||
setHiddenProp(this, valueHolderKey, v) | ||
setHiddenProp(this, skipRenderKey, true) | ||
getAtom.call(this).reportChanged() | ||
setHiddenProp(this, skipRenderKey, false) | ||
set(value) { | ||
const admin = getAdministration(this) | ||
// forceUpdate issued by reaction sets new props. | ||
// It sets isUpdating to true to prevent loop. | ||
if (!admin.isUpdating && !shallowEqual(admin[key], value)) { | ||
admin[key] = value | ||
// This notifies all observers including our component, | ||
// but we don't want to cause `forceUpdate`, because component is already updating, | ||
// therefore supress component reaction. | ||
admin.isUpdating = true | ||
admin[atomKey].reportChanged() | ||
admin.isUpdating = false | ||
} else { | ||
setHiddenProp(this, valueHolderKey, v) | ||
admin[key] = value | ||
} | ||
} | ||
}) | ||
} | ||
} | ||
const observablePropsDescriptor = createObservablePropDescriptor("props") | ||
const observableStateDescriptor = createObservablePropDescriptor("state") | ||
const observableContextDescriptor = createObservablePropDescriptor("context") |
@@ -1,19 +0,1 @@ | ||
let symbolId = 0 | ||
function createSymbol(name: string): symbol | string { | ||
if (typeof Symbol === "function") { | ||
return Symbol(name) | ||
} | ||
const symbol = `__$mobx-react ${name} (${symbolId})` | ||
symbolId++ | ||
return symbol | ||
} | ||
const createdSymbols = {} | ||
export function newSymbol(name: string): symbol | string { | ||
if (!createdSymbols[name]) { | ||
createdSymbols[name] = createSymbol(name) | ||
} | ||
return createdSymbols[name] | ||
} | ||
export function shallowEqual(objA: any, objB: any): boolean { | ||
@@ -99,4 +81,4 @@ //From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js | ||
*/ | ||
const mobxMixins = newSymbol("patchMixins") | ||
const mobxPatchedDefinition = newSymbol("patchedDefinition") | ||
const mobxMixins = Symbol("patchMixins") | ||
const mobxPatchedDefinition = Symbol("patchedDefinition") | ||
@@ -179,2 +161,3 @@ export interface Mixins extends Record<string, any> { | ||
return { | ||
// @ts-ignore | ||
[mobxPatchedDefinition]: true, | ||
@@ -181,0 +164,0 @@ get: function () { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
641772
3945
3
1
497
+ Addedmobx-react-lite@4.0.7(transitive)
+ Addeduse-sync-external-store@1.2.2(transitive)
- Removedmobx-react-lite@3.4.3(transitive)
Updatedmobx-react-lite@^4.0.0