@connectv/core
Version:
agent-based reactive programming library for typescript/javascript
180 lines • 7.83 kB
JavaScript
;
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var operators_1 = require("rxjs/operators");
var emission_1 = require("../shared/emission");
var keyed_array_diff_1 = require("../util/keyed-array-diff");
var map_1 = require("../pin/map");
var sink_1 = require("../pin/sink");
var group_1 = require("../pin/group");
var value_1 = require("../pin/value");
var pipe_1 = require("../pin/pipe");
var simple_deep_1 = require("./simple-deep");
/**
*
* Represents a [keyed deep state](https://connective.dev/docs/deep#keyed-deep).
*
*/
var KeyedDeep = /** @class */ (function (_super) {
__extends(KeyedDeep, _super);
/**
*
* @param stateOrAccessor underlying state of this deep state or a state tree accessor (for sub-states)
* @param keyfunc key function to be used to track entities within the state's value
* @param compare equality function used to detect changes. If state is passed as first argument this is ignored.
*
*/
function KeyedDeep(stateOrAccessor, keyfunc, compare) {
var _this_1 = _super.call(this, stateOrAccessor, compare, {
inputs: ['value'],
outputs: ['value', 'changes']
}) || this;
_this_1.keyfunc = keyfunc;
_this_1._keyMap = {};
return _this_1;
}
/**
*
* Creates a sub-state bound to entity identified by given key. Entity `x` is
* said to be identified by key `k` if `state.keyfunc(x) === k`.
*
* @param key the identifier of the entity to track
* @param factory the factory function to be used to construct the sub-state
*
*/
KeyedDeep.prototype.key = function (key, factory) {
var _this_1 = this;
var initialized = false;
var _this = this;
var _factory = factory || (function (accessor, compare) { return new simple_deep_1.SimpleDeep(accessor, compare); });
return _factory({
initial: (_this._keyMap[key] || { item: undefined }).item
|| (Object.values(this.value) || []).find(function (i) { return _this_1.keyfunc(i) == key; }),
get: group_1.group(_this.changes, _this.reemit).to(map_1.map(function () { return (_this._keyMap[key] || { item: undefined }).item; })),
set: sink_1.sink(function (v, context) {
var _a, _b;
try {
var _entry = _this._keyMap[key];
if (_entry) {
_entry.item = v;
if (_this.accessor) {
_this.value = (Array.isArray(_this.value)) ?
Object.assign([], _this.value, (_a = {}, _a[_entry.index] = v, _a)) :
Object.assign({}, _this.value, (_b = {}, _b[_entry.index] = v, _b));
}
else {
_this.value[_entry.index] = v;
if (initialized)
_this_1.reemit.emit(emission_1.emission(v, context));
else
initialized = true;
}
}
}
catch (err) { }
}),
bind: function (track) { return track(this.set.subscribe()); },
}, this.state.compare);
};
/**
*
* Returns a [pin](https://connective.dev/docs/pin) that reflects the reactive value of
* the index of entity identified by given key in the state's value. Entity `x` is said
* to be identified by key `k` if `state.keyfunc(x) === k`.
*
* @param key the key to identify target entity with
*
*/
KeyedDeep.prototype.index = function (key) {
var _this_1 = this;
var initial;
if (this._keyMap[key])
initial = this._keyMap[key].index;
else
initial = ((Object.entries(this.value) || []).find(function (_a) {
var index = _a[0], item = _a[1];
return _this_1.keyfunc(item) == key;
})
|| [-1, undefined])[0];
return group_1.group(value_1.value(initial), group_1.group(this.changes, this.reemit).to(map_1.map(function () { return (_this_1._keyMap[key] || { index: -1 }).index; }))).to(pipe_1.pipe(operators_1.distinctUntilKeyChanged('value')));
};
/**
*
* Will bind the underlying state, and cause deep change-detection to happen upon
* changes of the state value. [Read this](https://connective.dev/docs/deep#change-detection)
* for more information on deep change-detection.
*
* If this is a sub-state, also enables up-propagation
* of state value, causing the parent state to pick up changes made to the value of this
* sub-state. [Read this](https://connective.dev/docs/deep#two-way-keyed) for more details
* and examples.
*
*/
KeyedDeep.prototype.bind = function () {
_super.prototype.bind.call(this);
this.track(this.changes.subscribe());
return this;
};
Object.defineProperty(KeyedDeep.prototype, "keys", {
/**
*
* Keys that entities within the value of the state are identified with. Entity
* `x` is said to be indetified with key `k` if `state.keyfunc(x) === k`.
*
* **WARNING** the keys will not be calculcated unless deep change-detection is active.
* You can ensure deep change-detection is active by subscribing on `.changes` or
* calling `.bind()`. [Read this](https://connective.dev/docs/deep#change-detection)
* for more information on deep change-detection.
*
*/
get: function () {
return Object.keys(this._keyMap);
},
enumerable: true,
configurable: true
});
Object.defineProperty(KeyedDeep.prototype, "changes", {
/**
*
* A [pin](https://connective.dev/docs/pin) that emits changes to this deep state's list value.
* These changes include entities being added to the list, removed from it or moved around in it.
* [Read this](https://connective.dev/docs/deep#change-detection) for more information on
* deep change-detection.
*
*/
get: function () { return this.out('changes'); },
enumerable: true,
configurable: true
});
KeyedDeep.prototype.createOutput = function (label) {
var _this_1 = this;
if (label === 'changes') {
this.output; // --> wire output before hand
var initial_1 = true;
return this.state.to(map_1.map(function (value, done) {
var result = keyed_array_diff_1.diff(value, _this_1._keyMap, _this_1.keyfunc);
_this_1._keyMap = result.newKeyMap;
var changes = Object.assign({}, result.changes, { initial: initial_1 });
initial_1 = false;
done(changes);
}));
}
else
return _super.prototype.createOutput.call(this, label);
};
return KeyedDeep;
}(simple_deep_1.SimpleDeep));
exports.KeyedDeep = KeyedDeep;
//# sourceMappingURL=keyed-deep.js.map