@rimbu/graph
Version:
Immutable Graph data structures for TypeScript
250 lines • 10.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GraphNonEmpty = void 0;
var tslib_1 = require("tslib");
var common_1 = require("@rimbu/common");
var stream_1 = require("@rimbu/stream");
var map_custom_1 = require("@rimbu/collection-types/map-custom");
var GraphNonEmpty = /** @class */ (function (_super) {
tslib_1.__extends(GraphNonEmpty, _super);
function GraphNonEmpty(isDirected, context, linkMap, connectionSize) {
var _this = _super.call(this) || this;
_this.isDirected = isDirected;
_this.context = context;
_this.linkMap = linkMap;
_this.connectionSize = connectionSize;
return _this;
}
GraphNonEmpty.prototype.copy = function (linkMap, connectionSize) {
if (linkMap === this.linkMap && connectionSize === this.connectionSize)
return this;
return this.context.createNonEmpty(linkMap, connectionSize);
};
GraphNonEmpty.prototype.copyE = function (linkMap, connectionSize) {
if (linkMap.nonEmpty())
return this.copy(linkMap, connectionSize);
return this.context.empty();
};
GraphNonEmpty.prototype.assumeNonEmpty = function () {
return this;
};
GraphNonEmpty.prototype.asNormal = function () {
return this;
};
GraphNonEmpty.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))) {
f([node, target], state.nextIndex(), state.halt);
}
}
}
};
GraphNonEmpty.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 (target) { return [node, target]; });
});
};
Object.defineProperty(GraphNonEmpty.prototype, "nodeSize", {
get: function () {
return this.linkMap.size;
},
enumerable: false,
configurable: true
});
GraphNonEmpty.prototype.streamNodes = function () {
return this.linkMap.streamKeys();
};
GraphNonEmpty.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 (node2) { return [node1, node2]; });
});
};
GraphNonEmpty.prototype.hasNode = function (node) {
return this.linkMap.hasKey(node);
};
GraphNonEmpty.prototype.hasConnection = function (node1, node2) {
var _a;
var targets = this.linkMap.get(node1);
return (_a = targets === null || targets === void 0 ? void 0 : targets.has(node2)) !== null && _a !== void 0 ? _a : false;
};
GraphNonEmpty.prototype.getConnectionStreamFrom = function (node1) {
var targets = this.linkMap.get(node1);
if (undefined === targets)
return stream_1.Stream.empty();
return targets.stream().map(function (node2) { return [node1, node2]; });
};
GraphNonEmpty.prototype.getConnectionStreamTo = function (node) {
if (this.isDirected) {
return this.linkMap.stream().collect(function (_a, _, skip) {
var _b = tslib_1.__read(_a, 2), source = _b[0], targets = _b[1];
if (!(targets === null || targets === void 0 ? void 0 : targets.has(node)))
return skip;
return [source, node];
});
}
var targets = this.linkMap.get(node);
if (undefined === targets)
return stream_1.Stream.empty();
return targets.stream().map(function (node1) { return [node1, node]; });
};
GraphNonEmpty.prototype.getConnectionsFrom = function (node1) {
return this.linkMap.get(node1, this.context.linkConnectionsContext.empty());
};
GraphNonEmpty.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;
};
GraphNonEmpty.prototype.isSource = function (node) {
return (this.linkMap.hasKey(node) &&
this.linkMap.streamValues().every(function (targets) { return !targets.has(node); }));
};
GraphNonEmpty.prototype.addNode = function (node) {
return this.copy(this.linkMap
.modifyAt(node, { ifNew: this.context.linkConnectionsContext.empty })
.assumeNonEmpty(), this.connectionSize);
};
GraphNonEmpty.prototype.addNodes = function (nodes) {
var builder = this.toBuilder();
builder.addNodes(nodes);
return builder.build().assumeNonEmpty();
};
GraphNonEmpty.prototype.removeNode = function (node) {
var builder = this.toBuilder();
builder.removeNode(node);
return builder.build();
};
GraphNonEmpty.prototype.removeNodes = function (nodes) {
var builder = this.toBuilder();
builder.removeNodes(nodes);
return builder.build();
};
GraphNonEmpty.prototype.connect = function (node1, node2) {
var _this = this;
var newLinkMap = this.linkMap.modifyAt(node1, {
ifNew: this.context.linkConnectionsContext.of(node2),
ifExists: function (targets) { return targets.add(node2); },
});
if (newLinkMap === this.linkMap)
return this;
var newConnectionSize = this.connectionSize + 1;
if (node1 === node2) {
return this.context.createNonEmpty(newLinkMap, newConnectionSize);
}
if (this.isDirected) {
return this.copy(newLinkMap
.modifyAt(node2, {
ifNew: function () { return _this.context.linkConnectionsContext.empty(); },
})
.assumeNonEmpty(), newConnectionSize);
}
return this.copy(newLinkMap
.modifyAt(node2, {
ifNew: function () { return _this.context.linkConnectionsContext.of(node1); },
ifExists: function (targets) { return targets.add(node1); },
})
.assumeNonEmpty(), newConnectionSize);
};
GraphNonEmpty.prototype.connectAll = function (links) {
var builder = this.toBuilder();
builder.connectAll(links);
return builder.build().assumeNonEmpty();
};
GraphNonEmpty.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.remove(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.remove(node1); }), newConnectionSize);
};
GraphNonEmpty.prototype.disconnectAll = function (links) {
var builder = this.toBuilder();
builder.disconnectAll(links);
return builder.build().assumeNonEmpty();
};
GraphNonEmpty.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.has(source); })) {
return source;
}
return skip;
});
return this.removeNodes(unconnectedNodes);
};
GraphNonEmpty.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: ']' }));
},
});
};
GraphNonEmpty.prototype.toJSON = function () {
return {
dataType: this.context.typeTag,
value: this.linkMap
.stream()
.map(function (entry) {
return [
entry[0],
entry[1]
.stream()
.map(function (v) { return [v]; })
.toArray(),
];
})
.toArray(),
};
};
GraphNonEmpty.prototype.toBuilder = function () {
return this.context.createBuilder(this);
};
return GraphNonEmpty;
}(map_custom_1.NonEmptyBase));
exports.GraphNonEmpty = GraphNonEmpty;
//# sourceMappingURL=non-empty.cjs.map