UNPKG

@rimbu/graph

Version:

Immutable Graph data structures for TypeScript

245 lines 9.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GraphBuilder = void 0; var tslib_1 = require("tslib"); var base_1 = require("@rimbu/base"); var stream_1 = require("@rimbu/stream"); var index_cjs_1 = require("../../common/index.cjs"); var GraphBuilder = /** @class */ (function () { function GraphBuilder(isDirected, context, source) { var _this = this; this.isDirected = isDirected; this.context = context; this.source = source; this.connectionSize = 0; this._lock = 0; // prettier-ignore this.hasNode = function (node) { var _a, _b; return (_b = (_a = _this.source) === null || _a === void 0 ? void 0 : _a.hasNode(node)) !== null && _b !== void 0 ? _b : _this.linkMap.hasKey(node); }; // prettier-ignore this.hasConnection = function (node1, node2) { var _a; if (undefined !== _this.source) { return _this.source.hasConnection(node1, node2); } var targets = _this.linkMap.get(node1); return (_a = targets === null || targets === void 0 ? void 0 : targets.has(node2)) !== null && _a !== void 0 ? _a : false; }; this.addNodeInternal = function (node) { var changed = _this.linkMap.modifyAt(node, { ifNew: _this.context.linkConnectionsContext.builder, }); if (changed) _this.source = undefined; return changed; }; this.addNode = function (node) { _this.checkLock(); return _this.addNodeInternal(node); }; this.addNodes = function (nodes) { _this.checkLock(); return (stream_1.Stream.from(nodes).filterPure({ pred: _this.addNodeInternal }).count() > 0); }; // prettier-ignore this.removeNodeInternal = function (node) { var targets = _this.linkMap.removeKey(node); if (undefined === targets) return false; _this.source = undefined; if (_this.isDirected) { _this.linkMap.forEach(function (_a) { var _b = tslib_1.__read(_a, 2), sourceNode = _b[0], targets = _b[1]; if (targets.remove(node)) { if (sourceNode !== node) _this.connectionSize--; } }); } else { _this.connectionSize -= targets.size; targets.forEach(function (target) { return _this.linkMap.updateAt(target, function (values) { values.remove(node); return values; }); }); } return true; }; // prettier-ignore this.removeNode = function (node) { _this.checkLock(); return _this.removeNodeInternal(node); }; // prettier-ignore this.removeNodes = function (nodes) { _this.checkLock(); return stream_1.Stream.from(nodes).filterPure({ pred: _this.removeNodeInternal }).count() > 0; }; this.connectInternal = function (node1, node2) { var changed = false; _this.linkMap.modifyAt(node1, { ifNew: function () { var targetBuilder = _this.context.linkConnectionsContext.builder(); targetBuilder.add(node2); _this.connectionSize++; changed = true; return targetBuilder; }, ifExists: function (targets) { if (targets.add(node2)) { _this.connectionSize++; changed = true; } return targets; }, }); if (changed) _this.source = undefined; if (changed && node1 !== node2) { _this.linkMap.modifyAt(node2, { ifNew: function () { var targetBuilder = _this.context.linkConnectionsContext.builder(); if (!_this.isDirected) targetBuilder.add(node1); return targetBuilder; }, ifExists: function (targets) { if (!_this.isDirected) targets.add(node1); return targets; }, }); } return changed; }; this.connect = function (node1, node2) { _this.checkLock(); return _this.connectInternal(node1, node2); }; this.connectAll = function (connections) { _this.checkLock(); return (stream_1.Stream.applyFilter(connections, { pred: _this.connectInternal, }).count() > 0); }; this.connectIfNodesExist = function (node1, node2) { _this.checkLock(); var changed = false; _this.linkMap.updateAt(node1, function (targets) { if (_this.linkMap.hasKey(node2) && targets.add(node2)) { _this.connectionSize++; changed = true; } return targets; }); if (changed && !_this.isDirected) { _this.source = undefined; _this.linkMap.updateAt(node2, function (targets) { targets.add(node1); return targets; }); } return changed; }; this.addGraphElement = function (element) { if (index_cjs_1.GraphElement.isLink(element)) { return _this.connectInternal(element[0], element[1]); } return _this.addNodeInternal(element[0]); }; this.addGraphElements = function (elements) { return (stream_1.Stream.from(elements).filterPure({ pred: _this.addGraphElement }).count() > 0); }; // prettier-ignore this.disconnectInternal = function (node1, node2) { if (!_this.linkMap.context.isValidKey(node1) || !_this.linkMap.context.isValidKey(node2)) { return false; } var changed = false; _this.linkMap.updateAt(node1, function (targets) { if (targets.remove(node2)) { _this.connectionSize--; changed = true; } return targets; }); if (changed) _this.source = undefined; if (changed && node1 !== node2 && !_this.isDirected) { _this.linkMap.updateAt(node2, function (targets) { targets.remove(node1); return targets; }); } return changed; }; // prettier-ignore this.disconnect = function (node1, node2) { _this.checkLock(); return _this.disconnectInternal(node1, node2); }; // prettier-ignore this.disconnectAll = function (connections) { _this.checkLock(); return (stream_1.Stream.applyFilter(connections, { pred: _this.disconnectInternal }).count() > 0); }; this.build = function () { if (undefined !== _this.source) return _this.source; if (_this.isEmpty) return _this.context.empty(); var linkMap = _this.linkMap .buildMapValues(function (targets) { return targets.build(); }) .assumeNonEmpty(); return _this.context.createNonEmpty(linkMap, _this.connectionSize); }; if (undefined !== source) this.connectionSize = source.connectionSize; } GraphBuilder.prototype.checkLock = function () { if (this._lock) base_1.RimbuError.throwModifiedBuilderWhileLoopingOverItError(); }; Object.defineProperty(GraphBuilder.prototype, "linkMap", { get: function () { if (undefined === this._linkMap) { if (undefined === this.source) { this._linkMap = this.context.linkMapContext.builder(); } else { this._linkMap = this.source.linkMap .mapValues(function (targets) { return targets.toBuilder(); }) .toBuilder(); } } return this._linkMap; }, enumerable: false, configurable: true }); Object.defineProperty(GraphBuilder.prototype, "isEmpty", { get: function () { var _a, _b; return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.isEmpty) !== null && _b !== void 0 ? _b : this.linkMap.isEmpty; }, enumerable: false, configurable: true }); Object.defineProperty(GraphBuilder.prototype, "nodeSize", { get: function () { var _a, _b; return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.nodeSize) !== null && _b !== void 0 ? _b : this.linkMap.size; }, enumerable: false, configurable: true }); return GraphBuilder; }()); exports.GraphBuilder = GraphBuilder; //# sourceMappingURL=builder.cjs.map