@platform/state
Version:
A small, simple, strongly typed, [rx/observable] state-machine.
133 lines (132 loc) • 4.82 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.StateObject = void 0;
var tslib_1 = require("tslib");
var util_value_1 = require("@platform/util.value");
var immer_1 = require("immer");
var rxjs_1 = require("rxjs");
var operators_1 = require("rxjs/operators");
var common_1 = require("../common");
var Patch_1 = require("../Patch");
var events = require("./StateObject.events");
var merge = require("./StateObject.merge");
if (typeof immer_1.setAutoFreeze === 'function') {
immer_1.setAutoFreeze(false);
}
if (typeof immer_1.enablePatches === 'function') {
immer_1.enablePatches();
}
var StateObject = (function () {
function StateObject(args) {
var _this = this;
this._dispose$ = new rxjs_1.Subject();
this.dispose$ = this._dispose$.pipe(operators_1.share());
this._event$ = new rxjs_1.Subject();
this.event = events.create(this._event$, this._dispose$);
this.change = function (fn, options) {
if (options === void 0) { options = {}; }
var cid = util_value_1.id.cuid();
var type = (options.action || '').trim();
var from = _this.state;
var _a = next(from, fn), to = _a.to, op = _a.op, patches = _a.patches;
if (Patch_1.Patch.isEmpty(patches)) {
return { op: op, cid: cid, patches: patches };
}
var changing = {
op: op,
cid: cid,
from: from,
to: to,
patches: patches,
cancelled: false,
cancel: function () { return (changing.cancelled = true); },
action: type,
};
_this.fire({ type: 'StateObject/changing', payload: changing });
var cancelled = changing.cancelled ? changing : undefined;
if (cancelled) {
_this.fire({ type: 'StateObject/cancelled', payload: cancelled });
}
var changed = cancelled
? undefined
: { op: op, cid: cid, from: from, to: to, patches: patches, action: type };
if (changed) {
_this._state = to;
_this.fire({ type: 'StateObject/changed', payload: changed });
}
return {
op: op,
cid: cid,
changed: changed,
cancelled: cancelled,
patches: patches,
};
};
this.fire = function (e) { return _this._event$.next(e); };
this._state = tslib_1.__assign({}, args.initial);
this.original = this.state;
}
StateObject.create = function (initial) {
return new StateObject({ initial: initial });
};
StateObject.readonly = function (obj) {
return obj;
};
StateObject.toObject = function (input) {
return immer_1.isDraft(input) ? immer_1.original(input) : input;
};
StateObject.isStateObject = function (input) {
return common_1.is.stateObject(input);
};
StateObject.prototype.dispose = function () {
if (!this.isDisposed) {
this.fire({
type: 'StateObject/disposed',
payload: { original: this.original, final: this.state },
});
this._dispose$.next();
this._dispose$.complete();
}
};
Object.defineProperty(StateObject.prototype, "isDisposed", {
get: function () {
return this._dispose$.isStopped;
},
enumerable: false,
configurable: true
});
Object.defineProperty(StateObject.prototype, "state", {
get: function () {
return this._state;
},
enumerable: false,
configurable: true
});
Object.defineProperty(StateObject.prototype, "readonly", {
get: function () {
return this;
},
enumerable: false,
configurable: true
});
StateObject.merge = merge.create(StateObject.create);
return StateObject;
}());
exports.StateObject = StateObject;
var next = function (from, fn) {
if (typeof fn === 'function') {
var _a = immer_1.produceWithPatches(from, function (draft) {
fn(draft);
return undefined;
}), to = _a[0], forward = _a[1], backward = _a[2];
var patches = Patch_1.Patch.toPatchSet(forward, backward);
var op = 'update';
return { op: op, to: to, patches: patches };
}
else {
var _b = immer_1.produceWithPatches(from, function () { return fn; }), to = _b[0], forward = _b[1], backward = _b[2];
var patches = Patch_1.Patch.toPatchSet(forward, backward);
var op = 'replace';
return { op: op, to: to, patches: patches };
}
};