@rimbu/graph
Version:
Immutable Graph data structures for TypeScript
245 lines • 9.66 kB
JavaScript
"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