UNPKG

@rimbu/graph

Version:

Immutable Graph data structures for TypeScript

354 lines 15.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ValuedGraphNonEmpty = void 0; var tslib_1 = require("tslib"); var map_custom_1 = require("@rimbu/collection-types/map-custom"); var common_1 = require("@rimbu/common"); var stream_1 = require("@rimbu/stream"); var ValuedGraphNonEmpty = /** @class */ (function (_super) { tslib_1.__extends(ValuedGraphNonEmpty, _super); function ValuedGraphNonEmpty(isDirected, context, linkMap, connectionSize) { var _this = _super.call(this) || this; _this.isDirected = isDirected; _this.context = context; _this.linkMap = linkMap; _this.connectionSize = connectionSize; return _this; } ValuedGraphNonEmpty.prototype.copy = function (linkMap, connectionSize) { if (linkMap === this.linkMap && connectionSize === this.connectionSize) { return this; } return this.context.createNonEmpty(linkMap, connectionSize); }; ValuedGraphNonEmpty.prototype.copyE = function (linkMap, connectionSize) { if (linkMap.nonEmpty()) { return this.copy(linkMap, connectionSize); } return this.context.empty(); }; ValuedGraphNonEmpty.prototype.assumeNonEmpty = function () { return this; }; ValuedGraphNonEmpty.prototype.asNormal = function () { return this; }; ValuedGraphNonEmpty.prototype.forEach = function (f, options) { if (options === void 0) { options = {}; } var _a = options.state, state = _a === void 0 ? (0, common_1.TraverseState)() : _a; var mapIter = this.linkMap[Symbol.iterator](); var done = Symbol(); var targetsEntry; while (!state.halted && done !== (targetsEntry = mapIter.fastNext(done))) { var _b = tslib_1.__read(targetsEntry, 2), node = _b[0], targets = _b[1]; if (targets.isEmpty) { f([node], state.nextIndex(), state.halt); } else { var targetsIter = targets[Symbol.iterator](); var target = void 0; while (!state.halted && done !== (target = targetsIter.fastNext(done))) { var _c = tslib_1.__read(target, 2), targetNode = _c[0], value = _c[1]; f([node, targetNode, value], state.nextIndex(), state.halt); } } } }; ValuedGraphNonEmpty.prototype.stream = function () { return this.linkMap.stream().flatMap(function (_a) { var _b = tslib_1.__read(_a, 2), node = _b[0], targets = _b[1]; if (!targets.nonEmpty()) return [[node]]; return targets .stream() .map(function (_a) { var _b = tslib_1.__read(_a, 2), target = _b[0], value = _b[1]; return [node, target, value]; }); }); }; Object.defineProperty(ValuedGraphNonEmpty.prototype, "nodeSize", { get: function () { return this.linkMap.size; }, enumerable: false, configurable: true }); ValuedGraphNonEmpty.prototype.streamNodes = function () { return this.linkMap.streamKeys(); }; ValuedGraphNonEmpty.prototype.streamConnections = function () { return this.linkMap .stream() .flatMap(function (_a) { var _b = tslib_1.__read(_a, 2), node1 = _b[0], targets = _b[1]; return targets .stream() .map(function (_a) { var _b = tslib_1.__read(_a, 2), node2 = _b[0], value = _b[1]; return [node1, node2, value]; }); }); }; ValuedGraphNonEmpty.prototype.hasNode = function (node) { return this.linkMap.hasKey(node); }; ValuedGraphNonEmpty.prototype.hasConnection = function (node1, node2) { var _a; var targets = this.linkMap.get(node1); return (_a = targets === null || targets === void 0 ? void 0 : targets.hasKey(node2)) !== null && _a !== void 0 ? _a : false; }; ValuedGraphNonEmpty.prototype.getValue = function (node1, node2, otherwise) { var targets = this.linkMap.get(node1); if (undefined === targets) return (0, common_1.OptLazy)(otherwise); return targets.get(node2, otherwise); }; ValuedGraphNonEmpty.prototype.getConnectionStreamFrom = function (node1) { var targets = this.linkMap.get(node1); if (undefined === targets) return stream_1.Stream.empty(); return targets .stream() .map(function (_a) { var _b = tslib_1.__read(_a, 2), node2 = _b[0], value = _b[1]; return [node1, node2, value]; }); }; ValuedGraphNonEmpty.prototype.getConnectionStreamTo = function (node) { if (this.isDirected) { return this.streamConnections().filter(function (_a) { var _b = tslib_1.__read(_a, 2), _ = _b[0], node2 = _b[1]; return node2 === node; }); } var targets = this.linkMap.get(node); if (undefined === targets) return stream_1.Stream.empty(); return targets .stream() .map(function (_a) { var _b = tslib_1.__read(_a, 2), node1 = _b[0], value = _b[1]; return [node1, node, value]; }); }; ValuedGraphNonEmpty.prototype.getConnectionsFrom = function (node1) { return this.linkMap.get(node1, this.context.linkConnectionsContext.empty()); }; ValuedGraphNonEmpty.prototype.isSink = function (node) { var _a; var targets = this.linkMap.get(node); return (_a = targets === null || targets === void 0 ? void 0 : targets.isEmpty) !== null && _a !== void 0 ? _a : false; }; ValuedGraphNonEmpty.prototype.isSource = function (node) { return (this.linkMap.hasKey(node) && this.linkMap.streamValues().every(function (targets) { return !targets.hasKey(node); })); }; ValuedGraphNonEmpty.prototype.addNode = function (node) { return this.copy(this.linkMap .modifyAt(node, { ifNew: this.context.linkConnectionsContext.empty }) .assumeNonEmpty(), this.connectionSize); }; ValuedGraphNonEmpty.prototype.addNodes = function (nodes) { var builder = this.toBuilder(); builder.addNodes(nodes); return builder.build().assumeNonEmpty(); }; ValuedGraphNonEmpty.prototype.removeNode = function (node) { var builder = this.toBuilder(); builder.removeNode(node); return builder.build(); }; ValuedGraphNonEmpty.prototype.removeNodes = function (nodes) { var builder = this.toBuilder(); builder.removeNodes(nodes); return builder.build(); }; ValuedGraphNonEmpty.prototype.connect = function (node1, node2, value) { var _this = this; var newLinkMap = this.linkMap.modifyAt(node1, { ifNew: this.context.linkConnectionsContext.of([node2, value]), ifExists: function (targets) { return targets.set(node2, value); }, }); if (newLinkMap === this.linkMap) return this; var newConnectionSize = this.connectionSize + 1; if (Object.is(node1, node2) || this.isDirected) { return this.context.createNonEmpty(newLinkMap.assumeNonEmpty(), newConnectionSize); } return this.copy(newLinkMap .modifyAt(node2, { ifNew: function () { if (_this.isDirected) { return _this.context.linkConnectionsContext.empty(); } return _this.context.linkConnectionsContext.of([node1, value]); }, }) .assumeNonEmpty(), newConnectionSize); }; ValuedGraphNonEmpty.prototype.connectAll = function (links) { var builder = this.toBuilder(); builder.connectAll(links); return builder.build().assumeNonEmpty(); }; ValuedGraphNonEmpty.prototype.modifyAt = function (node1, node2, options) { var _this = this; var newConnectionSize = this.connectionSize; var addedOrUpdatedValue; var newLinkMap = this.linkMap.modifyAt(node1, { ifNew: function (none) { if (undefined === options.ifNew) return none; var newValue = (0, common_1.OptLazyOr)(options.ifNew, none); if (none === newValue) return none; addedOrUpdatedValue = newValue; newConnectionSize++; return _this.context.linkMapContext.of([node2, newValue]); }, ifExists: function (valueMap) { var ifExists = options.ifExists; if (undefined === ifExists) return valueMap; return valueMap.modifyAt(node2, { ifNew: function (none) { if (undefined === options.ifNew) return none; var newValue = (0, common_1.OptLazyOr)(options.ifNew, none); if (none === newValue) return none; addedOrUpdatedValue = newValue; newConnectionSize++; return newValue; }, ifExists: function (currentValue, remove) { var newValue = ifExists instanceof Function ? ifExists(currentValue, remove) : ifExists; if (Object.is(newValue, currentValue)) return currentValue; if (remove === newValue) { newConnectionSize--; } else { addedOrUpdatedValue = newValue; } return newValue; }, }); }, }); if (newLinkMap === this.linkMap) return this; if (this.isDirected) { return this.copy(newLinkMap.assumeNonEmpty(), newConnectionSize); } // edge graph, need to update counterpart if (newConnectionSize === this.connectionSize) { // value was updated var newLinkMap2_1 = newLinkMap.modifyAt(node2, { ifNew: function () { return _this.context.linkMapContext.of([node1, addedOrUpdatedValue]); }, ifExists: function (valueMap) { return valueMap.set(node1, addedOrUpdatedValue); }, }); return this.copy(newLinkMap2_1.assumeNonEmpty(), newConnectionSize); } if (newConnectionSize < this.connectionSize) { // value was removed var newLinkMap2_2 = newLinkMap.modifyAt(node2, { ifExists: function (valueMap) { return valueMap.removeKey(node1); }, }); return this.copy(newLinkMap2_2.assumeNonEmpty(), newConnectionSize); } // value was added var newLinkMap2 = newLinkMap.modifyAt(node2, { ifNew: function () { return _this.context.linkMapContext.of([node1, addedOrUpdatedValue]); }, ifExists: function (valueMap) { return valueMap.set(node1, addedOrUpdatedValue); }, }); return this.copy(newLinkMap2.assumeNonEmpty(), newConnectionSize); }; ValuedGraphNonEmpty.prototype.disconnect = function (node1, node2) { if (!this.linkMap.context.isValidKey(node1) || !this.linkMap.context.isValidKey(node2)) return this; var newLinkMap = this.linkMap.updateAt(node1, function (targets) { return targets.removeKey(node2); }); if (newLinkMap === this.linkMap) return this; var newConnectionSize = this.connectionSize - 1; if (this.isDirected) return this.copy(newLinkMap, newConnectionSize); return this.copy(newLinkMap.updateAt(node2, function (targets) { return targets.removeKey(node1); }), newConnectionSize); }; ValuedGraphNonEmpty.prototype.disconnectAll = function (links) { var builder = this.toBuilder(); builder.disconnectAll(links); return builder.build().assumeNonEmpty(); }; ValuedGraphNonEmpty.prototype.removeUnconnectedNodes = function () { var _this = this; if (!this.isDirected) { var newLinkMap = this.linkMap.filter(function (_a) { var _b = tslib_1.__read(_a, 2), _ = _b[0], targets = _b[1]; return targets.nonEmpty(); }); return this.copyE(newLinkMap, this.connectionSize); } var unconnectedNodes = this.linkMap .stream() .collect(function (_a, _, skip) { var _b = tslib_1.__read(_a, 2), source = _b[0], targets = _b[1]; if (targets.isEmpty && !_this.linkMap.streamValues().some(function (t) { return t.hasKey(source); })) { return source; } return skip; }); return this.removeNodes(unconnectedNodes); }; ValuedGraphNonEmpty.prototype.mapValues = function (mapFun) { var newLinkMap = this.linkMap.mapValues(function (targets, node1) { return targets.mapValues(function (value, node2) { return mapFun(value, node1, node2); }); }); return this.context.createNonEmpty(newLinkMap, this.connectionSize); }; ValuedGraphNonEmpty.prototype.toString = function () { var connector = this.isDirected ? '->' : '<->'; return this.linkMap.stream().join({ start: "".concat(this.context.typeTag, "(\n "), sep: ',\n ', end: '\n)', valueToString: function (_a) { var _b = tslib_1.__read(_a, 2), node = _b[0], targets = _b[1]; return "".concat(node, " ").concat(connector, " ").concat(targets.stream().join({ start: '[', sep: ', ', end: ']', valueToString: function (_a) { var _b = tslib_1.__read(_a, 2), node2 = _b[0], value = _b[1]; return "{".concat(node2, ": ").concat(value, "}"); }, })); }, }); }; ValuedGraphNonEmpty.prototype.toJSON = function () { return { dataType: this.context.typeTag, value: this.linkMap .stream() .map(function (entry) { return [entry[0], entry[1].toArray()]; }) .toArray(), }; }; ValuedGraphNonEmpty.prototype.toBuilder = function () { return this.context.createBuilder(this); }; return ValuedGraphNonEmpty; }(map_custom_1.NonEmptyBase)); exports.ValuedGraphNonEmpty = ValuedGraphNonEmpty; //# sourceMappingURL=non-empty.cjs.map