computed-async-mobx
Version:
Define a computed by returning a Promise
128 lines • 5.06 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.promisedComputedInternal = exports.promisedComputed = exports.isPromiseLike = void 0;
var mobx_1 = require("mobx");
var mobxShim_1 = require("./mobxShim");
var mobx_utils_1 = require("mobx-utils");
function isPromiseLike(result) {
return result && typeof result.then === "function";
}
exports.isPromiseLike = isPromiseLike;
function value(value) {
return { ok: true, value: value };
}
function error(error) {
return { ok: false, error: error };
}
var PromisedComputed = /** @class */ (function () {
function PromisedComputed(init, fetch, disableReactionChecking) {
var _this = this;
this.fetch = fetch;
this.disableReactionChecking = disableReactionChecking;
mobx_1.runInAction(function () { return _this.refreshCallCount = 0; });
this.cached = value(init);
}
Object.defineProperty(PromisedComputed.prototype, "currentState", {
get: function () {
try {
this.refreshCallCount;
var promiseOrValue = this.fetch();
return isPromiseLike(promiseOrValue)
? mobx_utils_1.fromPromise(promiseOrValue.then(value, function (e) { return error(e); }))
: value(promiseOrValue);
}
catch (x) {
return error(x);
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(PromisedComputed.prototype, "busy", {
get: function () {
var s = this.currentState;
return !!(mobx_utils_1.isPromiseBasedObservable(s) && s.state === "pending");
},
enumerable: false,
configurable: true
});
PromisedComputed.prototype.refresh = function () {
this.refreshCallCount++;
};
PromisedComputed.prototype.get = function () {
if (!this.disableReactionChecking &&
!mobxShim_1.getGlobalState().trackingDerivation) {
throw new Error("promisedComputed must be used inside reactions");
}
return this.value;
};
/**
* This exists purely to support scenarios such as unit tests that
* want to verify the most recent value outside of a reactive context
*/
PromisedComputed.prototype.getNonReactive = function () {
var _this = this;
var result = undefined;
mobx_1.autorun(function () { return result = _this.get(); })();
return result;
};
Object.defineProperty(PromisedComputed.prototype, "value", {
get: function () {
var s = this.currentState;
var r = !mobx_utils_1.isPromiseBasedObservable(s) ? s :
s.state === "fulfilled" ? s.value :
this.cached;
this.cached = r;
if (r.ok) {
return r.value;
}
throw r.error;
},
enumerable: false,
configurable: true
});
__decorate([
mobx_1.observable
], PromisedComputed.prototype, "refreshCallCount", void 0);
__decorate([
mobx_1.computed
], PromisedComputed.prototype, "currentState", null);
__decorate([
mobx_1.computed
], PromisedComputed.prototype, "busy", null);
__decorate([
mobx_1.action
], PromisedComputed.prototype, "refresh", null);
__decorate([
mobx_1.computed
], PromisedComputed.prototype, "value", null);
return PromisedComputed;
}());
/**
* Similar to the standard computed, except that it converts promises into
* plain values, unwrapping them when they resolve and updating to the new
* value. The supplied function may return a plain value in which case the
* update is entirely synchronous like standard computed.
*
* As with the standard computed, exceptions (and rejected promises) are
* propagated as re-thrown exceptions. To avoid this, perform your own
* error handling in your supplied function.
*
* @param init Value to assume until the promise first resolves
* @param compute Evaluates to a promised or plain value
*/
function promisedComputed(init, compute) {
return new PromisedComputed(init, compute);
}
exports.promisedComputed = promisedComputed;
function promisedComputedInternal(init, compute) {
return new PromisedComputed(init, compute, true);
}
exports.promisedComputedInternal = promisedComputedInternal;
//# sourceMappingURL=promisedComputed.js.map