UNPKG

@connectv/core

Version:

agent-based reactive programming library for typescript/javascript

180 lines 7.83 kB
"use strict"; 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