react-mobx-observed
Version:
`@observed` decorator for MobX and React/React-Native projects.
201 lines • 10 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var mobx_1 = require("mobx");
var unsubscribeMap;
/**
* Makes the property `observable` and then connects the property to the `source` observable.
* Whenever the `source` emits a value, the property will be updated accordingly.
*
* **NOTE**: This decorator also adds `loadData` function to the class to reset all dependent properties.
*
* **RECOMMENDATION**: Mark the property as `readonly`.
*
* @export
* @template T Property type.
* @param {IParams<T>} params Parameters.
* @returns {PropertyDecorator} Property decorator.
*/
function observed(params) {
if (!unsubscribeMap) {
unsubscribeMap = new WeakMap();
}
return function (target, propertyName) {
var source = params.source, select = params.select, _a = params.loadImmediately, loadImmediately = _a === void 0 ? true : _a, computedBy = params.computedBy, makeSideEffects = params.makeSideEffects;
var shouldUpdate = params.shouldUpdate, onPropsChange = params.onPropsChange, _b = params.isSourceComputed, isSourceComputed = _b === void 0 ? false : _b;
if (typeof computedBy === 'function') {
isSourceComputed = true;
}
var observableProperty = mobx_1.observable(target, propertyName);
Object.defineProperty(target, propertyName, observableProperty);
var subscription;
function loadData() {
var _a;
var _this = this;
var _b, _c;
if (unsubscribeMap.has(this)) {
var subscriptions = unsubscribeMap.get(this);
if (propertyName in subscriptions) {
subscriptions[propertyName].unsubscribe();
delete subscriptions[propertyName];
}
}
(_b = this.clearError) === null || _b === void 0 ? void 0 : _b.call(this);
(_c = this.startLoading) === null || _c === void 0 ? void 0 : _c.call(this);
var index = 0;
var isSet = false;
var source$;
if (typeof source === 'function') {
source$ = source.call(this);
}
else {
source$ = source;
}
subscription = source$.subscribe({
error: function (error) {
mobx_1.transaction(function () {
var _a, _b;
(_a = _this.stopLoading) === null || _a === void 0 ? void 0 : _a.call(_this);
(_b = _this.setError) === null || _b === void 0 ? void 0 : _b.call(_this, error);
});
},
next: function (value) {
mobx_1.transaction(function () {
var _a;
if (makeSideEffects) {
var sideEffects_1 = makeSideEffects.call(_this, value);
if (typeof sideEffects_1 === 'object') {
var _loop_1 = function (key) {
if (!(key in _this)) {
return "continue";
}
if (key === '_') {
return "continue";
}
mobx_1.runInAction(function () { return _this[key] = sideEffects_1[key]; });
};
for (var key in sideEffects_1) {
_loop_1(key);
}
}
}
if (typeof select === 'function') {
if (isSet) {
return;
}
var willBeSelected = select.call(_this, value, index++);
if (!willBeSelected) {
return;
}
else if (typeof willBeSelected === 'object') {
if (!willBeSelected.select) {
return;
}
value = willBeSelected.value;
}
mobx_1.runInAction(function () { return _this[propertyName] = value; });
(_a = _this.stopLoading) === null || _a === void 0 ? void 0 : _a.call(_this);
isSet = true;
}
else {
mobx_1.runInAction(function () {
_this[propertyName] = value;
});
}
}, _this);
},
complete: function () {
var _a;
(_a = _this.stopLoading) === null || _a === void 0 ? void 0 : _a.call(_this);
subscription = undefined;
}
});
if (unsubscribeMap.has(this)) {
unsubscribeMap.get(this)[propertyName] = subscription;
}
else {
var subscriptions = (_a = {},
_a[propertyName] = subscription,
_a);
unsubscribeMap.set(this, subscriptions);
}
}
var originalLoadFunction = target['loadData'];
Object.defineProperty(target, 'loadData', {
configurable: true,
value: function () {
originalLoadFunction === null || originalLoadFunction === void 0 ? void 0 : originalLoadFunction.call(this !== null && this !== void 0 ? this : target);
loadData.call(this !== null && this !== void 0 ? this : target);
}
});
var computedValueDisposer;
if (loadImmediately) {
var originalDidMountFunction_1 = target['componentDidMount'];
Object.defineProperty(target, 'componentDidMount', {
configurable: true,
value: function (a, b, c) {
var _this = this;
originalDidMountFunction_1 === null || originalDidMountFunction_1 === void 0 ? void 0 : originalDidMountFunction_1.call(this !== null && this !== void 0 ? this : target, a, b, c);
loadData.call(this !== null && this !== void 0 ? this : target);
if (isSourceComputed) {
var funcToBeComputed = (computedBy !== null && computedBy !== void 0 ? computedBy : source).bind(this !== null && this !== void 0 ? this : target);
computedValueDisposer = mobx_1.computed(funcToBeComputed).observe(function (_change) {
loadData.call(_this !== null && _this !== void 0 ? _this : target);
});
}
}
});
if (isSourceComputed) {
var originalWillUnmountFunction_1 = target['componentWillUnmount'];
Object.defineProperty(target, 'componentWillUnmount', {
configurable: true,
value: function () {
originalWillUnmountFunction_1 === null || originalWillUnmountFunction_1 === void 0 ? void 0 : originalWillUnmountFunction_1.call(this !== null && this !== void 0 ? this : target);
subscription === null || subscription === void 0 ? void 0 : subscription.unsubscribe();
computedValueDisposer === null || computedValueDisposer === void 0 ? void 0 : computedValueDisposer();
}
});
}
}
if (typeof onPropsChange === 'string') {
if (onPropsChange) {
onPropsChange = [onPropsChange];
}
}
if (Array.isArray(onPropsChange)) {
if (typeof shouldUpdate !== 'function') {
shouldUpdate = function (prevProps) {
for (var _i = 0, _a = onPropsChange; _i < _a.length; _i++) {
var propName = _a[_i];
var previous = prevProps[propName];
var current = this.props[propName];
if (previous !== current) {
return true;
}
}
return false;
};
}
}
if (typeof shouldUpdate === 'function') {
var originalUpdateFunction_1 = target['componentDidUpdate'];
Object.defineProperty(target, 'componentDidUpdate', {
value: function (prevProps, prevState, snapshot) {
var _this = this;
originalUpdateFunction_1 === null || originalUpdateFunction_1 === void 0 ? void 0 : originalUpdateFunction_1.call(this, prevProps, prevState, snapshot);
if (shouldUpdate.call(this, prevProps, prevState, snapshot)) {
loadData.call(this);
if (isSourceComputed) {
computedValueDisposer === null || computedValueDisposer === void 0 ? void 0 : computedValueDisposer();
var funcToBeComputed = (computedBy !== null && computedBy !== void 0 ? computedBy : source).bind(this !== null && this !== void 0 ? this : target);
computedValueDisposer = mobx_1.computed(funcToBeComputed).observe(function (_change) {
loadData.call(_this !== null && _this !== void 0 ? _this : target);
});
}
}
}
});
}
};
}
exports.observed = observed;
//# sourceMappingURL=index.js.map