node-relation
Advanced tools
Comparing version 1.2.0 to 2.0.0
@@ -1,2 +0,2 @@ | ||
export default class AdvancedArray<T> extends Array { | ||
export default class AdvancedArray<T> extends Array<T> { | ||
constructor(...params: T[]); | ||
@@ -9,3 +9,2 @@ has(t: T): boolean; | ||
deduplication(): void; | ||
[Symbol.iterator](): IterableIterator<T>; | ||
} |
@@ -14,29 +14,2 @@ var __extends = (this && this.__extends) || (function () { | ||
})(); | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
@@ -107,23 +80,2 @@ var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
}; | ||
AdvancedArray.prototype[Symbol.iterator] = function () { | ||
var i, len, t; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
i = 0, len = this.length; | ||
_a.label = 1; | ||
case 1: | ||
if (!(i < len)) return [3 /*break*/, 4]; | ||
t = this[i]; | ||
return [4 /*yield*/, t]; | ||
case 2: | ||
_a.sent(); | ||
_a.label = 3; | ||
case 3: | ||
i++; | ||
return [3 /*break*/, 1]; | ||
case 4: return [2 /*return*/]; | ||
} | ||
}); | ||
}; | ||
return AdvancedArray; | ||
@@ -130,0 +82,0 @@ }(Array)); |
@@ -1,74 +0,89 @@ | ||
import AdvancedArray from './AdvancedArray'; | ||
declare type RelationNode = string | number | Symbol; | ||
declare class Relation extends AdvancedArray<RelationNode> { | ||
declare type RelationNode = string | number; | ||
declare type RelationNodeTuple = [RelationNode, RelationNode]; | ||
export default class Relation { | ||
private readonly relations; | ||
constructor(...tuples: RelationNodeTuple[]); | ||
/** 릴레이션이 가지고 있는 모든 노드 목록을 배열로 반환합니다. */ | ||
get nodes(): RelationNode[]; | ||
/** 릴레이션이 가지고 있는 1:1 관계를 튜플로 변환하여 목록을 배열로 반환합니다. */ | ||
get tuples(): RelationNodeTuple[]; | ||
/** | ||
* 튜플이 대상 노드를 가지고 있는지 여부를 반환합니다. | ||
* @param tuple 검색할 튜플입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
private isTupleHasNode; | ||
/** | ||
* 튜플에서 대상 노드와 쌍을 맺는 다른 노드를 반환합니다. 없다면 null을 반환합니다. | ||
* @param tuple 검색할 튜플입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
private getMateNode; | ||
/** | ||
* 매개변수로 받은 두 개의 노드를 새로운 튜플로 만들어 반환합니다. | ||
* @param a 대상 노드입니다. | ||
* @param b 대상 노드입니다. | ||
*/ | ||
private createTuple; | ||
/** | ||
* 매개변수로 받은 노드를 알고 있는 모든 릴레이션을 지정합니다. | ||
* @param target 대상 노드입니다. | ||
* @param relation 저장될 릴레이션입니다. | ||
*/ | ||
private recursiveToSetTuple; | ||
/** | ||
* 릴레이션이 대상 노드를 가지고 있는지 여부를 반환합니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
hasNode(node: RelationNode): boolean; | ||
/** | ||
* 매개변수로 받은 두 개의 노드로 이루어진 튜플이 존재하는지 여부를 반환합니다. | ||
* @param a 대상 노드입니다. | ||
* @param b 대상 노드입니다. | ||
*/ | ||
hasTuple(a: RelationNode, b: RelationNode): boolean; | ||
/** | ||
* 대상 노드와 관계를 형성하고 있는 모든 노드 목록을 배열로 반환합니다. 여러 노드를 매개변수로 전달하면, 합집합이 됩니다. | ||
* 배열에 대상 노드는 포함되지 않으니 주의하십시오. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
getRelativeNodes(...nodes: RelationNode[]): RelationNode[]; | ||
/** | ||
* 노드 간 새로운 관계를 형성합니다. 중심 노드를 기준으로 대상 노드와 관계를 형성합니다. | ||
* 형성된 결과를 새로운 릴레이션으로 만들어 반환합니다. | ||
* 가령 `setRelation('language', 'korean', 'english', 'japanese')` 메서드는 `['langauge', 'korean'], ['language', 'english'], ['language', 'japanese']` 튜플을 생성합니다. | ||
* 따라서 language 노드를 삭제할 경우 korean, english, japanese 노드들 사이의 관계성은 사라집니다. | ||
* @param target 중심 노드입니다. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
setRelation(target: RelationNode, ...nodes: RelationNode[]): Relation; | ||
/** | ||
* 대상 노드와 관계를 맺고 있는 노드만 추려내어 새로운 릴레이션으로 만들어 반환합니다. | ||
* 여러 노드를 매개변수로 전달하면, 합집합이 됩니다. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
getRelation(...nodes: RelationNode[]): Relation; | ||
/** | ||
* 대상 노드를 알고 있는 모든 관계를 추려내어 새로운 릴레이션으로 만들어 반환합니다. | ||
* 여러 노드를 매개변수로 전달하면, 합집합이 됩니다. | ||
* '알고 있다'는 것은, 직접적으로 관계되어 있거나, 다른 노드의 중계로 연결되어 있는 경우를 의미합니다. | ||
* 예를 들어 A--B--C, D--E 의 형태로 노드가 관계되어 있을 경우, A와 C는 B를 경유합니다. 이 경우, A와 C는 서로를 '알고 있다'고 표현합니다. | ||
* 하지만 D는 A, B, C와 어떤 관련도 없으므로 알고 있지 못합니다. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
getLegionRelation(...nodes: RelationNode[]): Relation; | ||
/** | ||
* 노드 간 형성된 관계를 제거합니다. 중심 노드를 기준으로 대상 노드와 관계를 제거합니다. | ||
* 형성된 결과를 새로운 릴레이션으로 만들어 반환합니다. | ||
* @param target 중심 노드입니다. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
deleteRelation(target: RelationNode, ...nodes: RelationNode[]): Relation; | ||
/** | ||
* 노드를 삭제합니다. 삭제된 노드와 형성되어 있던 관계는 제거됩니다. | ||
* 형성된 결과를 새로운 릴레이션으로 만들어 반환합니다. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
deleteNode(...nodes: RelationNode[]): Relation; | ||
} | ||
declare class RelationGroup extends AdvancedArray<Relation> { | ||
get relations(): Relation[]; | ||
get nodes(): RelationNode[]; | ||
} | ||
/** | ||
* 새로운 RelationGroup 인스턴스를 만들어 반환합니다. | ||
* @param group 초기값입니다. Relation 인스턴스를 매개변수로 넘깁니다. | ||
*/ | ||
declare function create(...relations: Relation[]): RelationGroup; | ||
/** | ||
* 대상 노드를 포함하고 있지 않는 모든 릴레이션을 묶어 새로운 RelationGroup 인스턴스를 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param nodes 포함되지 않을 노드입니다. | ||
*/ | ||
declare function exclude(group: RelationGroup, ...nodes: RelationNode[]): RelationGroup; | ||
/** | ||
* RelationGroup 인스턴스의 릴레이션을 모두 제거하여 초기화합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
*/ | ||
declare function clear(group: RelationGroup): RelationGroup; | ||
/** | ||
* 대상 노드를 포함하고 있는 릴레이션에서 대상 노드를 제거한 새로운 릴레이션을 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
declare function createRelationRelatives(group: RelationGroup, node: RelationNode): Relation; | ||
/** | ||
* 서로 관련 있는 노드를 매개변수로 넘겨 릴레이션으로 지정합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param nodes 서로 관련성을 가지는 노드입니다. | ||
*/ | ||
declare function setRelation(group: RelationGroup, ...node: RelationNode[]): Relation; | ||
/** | ||
* 대상 노드를 포함하고 있는 릴레이션을 반환합니다. 어떤 릴레이션도 대상 노드를 가지고 있지 않다면 null을 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
declare function getRelation(group: RelationGroup, node: RelationNode): Relation | null; | ||
/** | ||
* 대상 노드를 모두 포함하고 있는 릴레이션을 반환합니다. 해당되는 릴레이션이 없다면 null을 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
declare function getRelationEvery(group: RelationGroup, ...nodes: RelationNode[]): Relation | null; | ||
/** | ||
* RelationGroup 인스턴스에 담긴 모든 노드를 배열로 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @deprecated group.nodes getter를 사용하십시오. | ||
*/ | ||
declare function getNodes(group: RelationGroup): RelationNode[]; | ||
/** | ||
* RelationGroup 인스턴스가 대상 노드를 포함하고 있는지 여부를 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
declare function hasNode(group: RelationGroup, node: RelationNode): boolean; | ||
/** | ||
* 릴레이션이 대상 노드를 포함하고 있다면 노드를 삭제하고, 해당 릴레이션을 반환합니다. 어떤 릴레이션도 대상 노드를 가지고 있지 않다면 null을 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
declare function deleteNode(group: RelationGroup, node: RelationNode): Relation | null; | ||
/** | ||
* 대상 노드를 포함하고 있는 릴레이션을 RelationGroup 인스턴스에서 삭제합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
declare function dropRelation(group: RelationGroup, node: RelationNode): void; | ||
export { create, exclude, clear, hasNode, getNodes, deleteNode, createRelationRelatives, setRelation, getRelation, getRelationEvery, dropRelation, }; | ||
export {}; |
@@ -1,14 +0,12 @@ | ||
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 (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
var __values = (this && this.__values) || function(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
return function (d, b) { | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
@@ -34,13 +32,2 @@ var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
}; | ||
var __values = (this && this.__values) || function(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -60,41 +47,42 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.dropRelation = exports.getRelationEvery = exports.getRelation = exports.setRelation = exports.createRelationRelatives = exports.deleteNode = exports.getNodes = exports.hasNode = exports.clear = exports.exclude = exports.create = void 0; | ||
var AdvancedArray_1 = __importDefault(require("./AdvancedArray")); | ||
var Relation = /** @class */ (function (_super) { | ||
__extends(Relation, _super); | ||
var Relation = /** @class */ (function () { | ||
function Relation() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
var e_1, _a; | ||
var tuples = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
tuples[_i] = arguments[_i]; | ||
} | ||
this.relations = new AdvancedArray_1.default; | ||
try { | ||
for (var tuples_1 = __values(tuples), tuples_1_1 = tuples_1.next(); !tuples_1_1.done; tuples_1_1 = tuples_1.next()) { | ||
var tuple = tuples_1_1.value; | ||
var _b = __read(tuple, 2), a = _b[0], b = _b[1]; | ||
if (this.hasTuple(a, b)) { | ||
continue; | ||
} | ||
this.relations.push(tuple); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (tuples_1_1 && !tuples_1_1.done && (_a = tuples_1.return)) _a.call(tuples_1); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
} | ||
Object.defineProperty(Relation.prototype, "nodes", { | ||
/** 릴레이션이 가지고 있는 모든 노드 목록을 배열로 반환합니다. */ | ||
get: function () { | ||
return __spread(this); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
return Relation; | ||
}(AdvancedArray_1.default)); | ||
var RelationGroup = /** @class */ (function (_super) { | ||
__extends(RelationGroup, _super); | ||
function RelationGroup() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
} | ||
Object.defineProperty(RelationGroup.prototype, "relations", { | ||
get: function () { | ||
return __spread(this); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(RelationGroup.prototype, "nodes", { | ||
get: function () { | ||
var e_1, _a; | ||
var nodes = []; | ||
var e_2, _a; | ||
var nodes = new AdvancedArray_1.default; | ||
try { | ||
for (var _b = __values(this), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var relation = _c.value; | ||
nodes.push.apply(nodes, __spread(relation.nodes)); | ||
for (var _b = __values(this.tuples), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var tuple = _c.value; | ||
nodes.ensure(tuple[0]); | ||
nodes.ensure(tuple[1]); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
@@ -104,5 +92,5 @@ try { | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
return nodes; | ||
return __spread(nodes); | ||
}, | ||
@@ -112,48 +100,54 @@ enumerable: false, | ||
}); | ||
return RelationGroup; | ||
}(AdvancedArray_1.default)); | ||
/** | ||
* 새로운 RelationGroup 인스턴스를 만들어 반환합니다. | ||
* @param group 초기값입니다. Relation 인스턴스를 매개변수로 넘깁니다. | ||
*/ | ||
function create() { | ||
var e_2, _a; | ||
var relations = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
relations[_i] = arguments[_i]; | ||
} | ||
var group = new RelationGroup; | ||
try { | ||
for (var relations_1 = __values(relations), relations_1_1 = relations_1.next(); !relations_1_1.done; relations_1_1 = relations_1.next()) { | ||
var relation = relations_1_1.value; | ||
group.push(relation); | ||
} | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
try { | ||
if (relations_1_1 && !relations_1_1.done && (_a = relations_1.return)) _a.call(relations_1); | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
return group; | ||
} | ||
exports.create = create; | ||
/** | ||
* 대상 노드를 포함하고 있지 않는 모든 릴레이션을 묶어 새로운 RelationGroup 인스턴스를 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param nodes 포함되지 않을 노드입니다. | ||
*/ | ||
function exclude(group) { | ||
var nodes = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
nodes[_i - 1] = arguments[_i]; | ||
} | ||
var excludeRelations = group.filter(function (relation) { | ||
Object.defineProperty(Relation.prototype, "tuples", { | ||
/** 릴레이션이 가지고 있는 1:1 관계를 튜플로 변환하여 목록을 배열로 반환합니다. */ | ||
get: function () { | ||
return __spread(this.relations); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
/** | ||
* 튜플이 대상 노드를 가지고 있는지 여부를 반환합니다. | ||
* @param tuple 검색할 튜플입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
Relation.prototype.isTupleHasNode = function (tuple, node) { | ||
return tuple.indexOf(node) !== -1; | ||
}; | ||
/** | ||
* 튜플에서 대상 노드와 쌍을 맺는 다른 노드를 반환합니다. 없다면 null을 반환합니다. | ||
* @param tuple 검색할 튜플입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
Relation.prototype.getMateNode = function (tuple, node) { | ||
if (tuple[0] === node) | ||
return tuple[1]; | ||
if (tuple[1] === node) | ||
return tuple[0]; | ||
return null; | ||
}; | ||
/** | ||
* 매개변수로 받은 두 개의 노드를 새로운 튜플로 만들어 반환합니다. | ||
* @param a 대상 노드입니다. | ||
* @param b 대상 노드입니다. | ||
*/ | ||
Relation.prototype.createTuple = function (a, b) { | ||
return [a, b].sort(); | ||
}; | ||
/** | ||
* 매개변수로 받은 노드를 알고 있는 모든 릴레이션을 지정합니다. | ||
* @param target 대상 노드입니다. | ||
* @param relation 저장될 릴레이션입니다. | ||
*/ | ||
Relation.prototype.recursiveToSetTuple = function (target, relation) { | ||
var e_3, _a; | ||
var nodes = this.getRelativeNodes(target); | ||
try { | ||
for (var nodes_1 = __values(nodes), nodes_1_1 = nodes_1.next(); !nodes_1_1.done; nodes_1_1 = nodes_1.next()) { | ||
var node = nodes_1_1.value; | ||
if (relation.has(node)) | ||
return false; | ||
if (relation.hasTuple(target, node)) { | ||
continue; | ||
} | ||
relation.relations.push(this.createTuple(target, node)); | ||
this.recursiveToSetTuple(node, relation); | ||
} | ||
@@ -168,134 +162,112 @@ } | ||
} | ||
return true; | ||
}); | ||
return create.apply(void 0, __spread(excludeRelations)); | ||
} | ||
exports.exclude = exclude; | ||
/** | ||
* RelationGroup 인스턴스의 릴레이션을 모두 제거하여 초기화합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
*/ | ||
function clear(group) { | ||
group.clear(); | ||
return group; | ||
} | ||
exports.clear = clear; | ||
/** | ||
* 대상 노드를 포함하고 있는 릴레이션에서 대상 노드를 제거한 새로운 릴레이션을 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
function createRelationRelatives(group, node) { | ||
var relation = new Relation; | ||
var matchedRelation = getRelation(group, node); | ||
if (matchedRelation) { | ||
var nodes = new (AdvancedArray_1.default.bind.apply(AdvancedArray_1.default, __spread([void 0], matchedRelation.nodes)))(); | ||
nodes.delete(node); | ||
relation.push.apply(relation, __spread(nodes)); | ||
} | ||
return relation; | ||
} | ||
exports.createRelationRelatives = createRelationRelatives; | ||
/** | ||
* 서로 관련 있는 노드를 매개변수로 넘겨 릴레이션으로 지정합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param nodes 서로 관련성을 가지는 노드입니다. | ||
*/ | ||
function setRelation(group) { | ||
var e_4, _a, e_5, _b, e_6, _c; | ||
var node = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
node[_i - 1] = arguments[_i]; | ||
} | ||
var allKeys = new AdvancedArray_1.default; | ||
allKeys.push.apply(allKeys, __spread(node)); | ||
allKeys.deduplication(); | ||
var relations = new AdvancedArray_1.default; | ||
var newRelation = new (Relation.bind.apply(Relation, __spread([void 0], allKeys)))(); | ||
try { | ||
for (var allKeys_1 = __values(allKeys), allKeys_1_1 = allKeys_1.next(); !allKeys_1_1.done; allKeys_1_1 = allKeys_1.next()) { | ||
var key = allKeys_1_1.value; | ||
var matchedRelation = getRelation(group, key); | ||
if (matchedRelation) | ||
relations.ensure(matchedRelation); | ||
} | ||
} | ||
catch (e_4_1) { e_4 = { error: e_4_1 }; } | ||
finally { | ||
}; | ||
/** | ||
* 릴레이션이 대상 노드를 가지고 있는지 여부를 반환합니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
Relation.prototype.hasNode = function (node) { | ||
var e_4, _a; | ||
try { | ||
if (allKeys_1_1 && !allKeys_1_1.done && (_a = allKeys_1.return)) _a.call(allKeys_1); | ||
for (var _b = __values(this.relations), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var tuple = _c.value; | ||
if (this.isTupleHasNode(tuple, node)) | ||
return true; | ||
} | ||
} | ||
finally { if (e_4) throw e_4.error; } | ||
} | ||
try { | ||
for (var relations_2 = __values(relations), relations_2_1 = relations_2.next(); !relations_2_1.done; relations_2_1 = relations_2.next()) { | ||
var relation = relations_2_1.value; | ||
catch (e_4_1) { e_4 = { error: e_4_1 }; } | ||
finally { | ||
try { | ||
for (var relation_1 = (e_6 = void 0, __values(relation)), relation_1_1 = relation_1.next(); !relation_1_1.done; relation_1_1 = relation_1.next()) { | ||
var relationNode = relation_1_1.value; | ||
newRelation.ensure(relationNode); | ||
} | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
} | ||
catch (e_6_1) { e_6 = { error: e_6_1 }; } | ||
finally { | ||
try { | ||
if (relation_1_1 && !relation_1_1.done && (_c = relation_1.return)) _c.call(relation_1); | ||
finally { if (e_4) throw e_4.error; } | ||
} | ||
return false; | ||
}; | ||
/** | ||
* 매개변수로 받은 두 개의 노드로 이루어진 튜플이 존재하는지 여부를 반환합니다. | ||
* @param a 대상 노드입니다. | ||
* @param b 대상 노드입니다. | ||
*/ | ||
Relation.prototype.hasTuple = function (a, b) { | ||
var e_5, _a; | ||
try { | ||
for (var _b = __values(this.relations), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var tuple = _c.value; | ||
if (this.getMateNode(tuple, a) === b) { | ||
return true; | ||
} | ||
finally { if (e_6) throw e_6.error; } | ||
} | ||
group.delete(relation); | ||
} | ||
} | ||
catch (e_5_1) { e_5 = { error: e_5_1 }; } | ||
finally { | ||
try { | ||
if (relations_2_1 && !relations_2_1.done && (_b = relations_2.return)) _b.call(relations_2); | ||
catch (e_5_1) { e_5 = { error: e_5_1 }; } | ||
finally { | ||
try { | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
} | ||
finally { if (e_5) throw e_5.error; } | ||
} | ||
finally { if (e_5) throw e_5.error; } | ||
} | ||
group.push(newRelation); | ||
return newRelation; | ||
} | ||
exports.setRelation = setRelation; | ||
/** | ||
* 대상 노드를 포함하고 있는 릴레이션을 반환합니다. 어떤 릴레이션도 대상 노드를 가지고 있지 않다면 null을 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
function getRelation(group, node) { | ||
var e_7, _a; | ||
try { | ||
for (var group_1 = __values(group), group_1_1 = group_1.next(); !group_1_1.done; group_1_1 = group_1.next()) { | ||
var relation = group_1_1.value; | ||
if (relation.has(node)) | ||
return relation; | ||
return false; | ||
}; | ||
/** | ||
* 대상 노드와 관계를 형성하고 있는 모든 노드 목록을 배열로 반환합니다. 여러 노드를 매개변수로 전달하면, 합집합이 됩니다. | ||
* 배열에 대상 노드는 포함되지 않으니 주의하십시오. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
Relation.prototype.getRelativeNodes = function () { | ||
var e_6, _a, e_7, _b; | ||
var nodes = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
nodes[_i] = arguments[_i]; | ||
} | ||
} | ||
catch (e_7_1) { e_7 = { error: e_7_1 }; } | ||
finally { | ||
var relatives = new AdvancedArray_1.default; | ||
try { | ||
if (group_1_1 && !group_1_1.done && (_a = group_1.return)) _a.call(group_1); | ||
for (var nodes_2 = __values(nodes), nodes_2_1 = nodes_2.next(); !nodes_2_1.done; nodes_2_1 = nodes_2.next()) { | ||
var node = nodes_2_1.value; | ||
try { | ||
for (var _c = (e_7 = void 0, __values(this.getRelation(node).nodes)), _d = _c.next(); !_d.done; _d = _c.next()) { | ||
var t = _d.value; | ||
relatives.ensure(t); | ||
} | ||
} | ||
catch (e_7_1) { e_7 = { error: e_7_1 }; } | ||
finally { | ||
try { | ||
if (_d && !_d.done && (_b = _c.return)) _b.call(_c); | ||
} | ||
finally { if (e_7) throw e_7.error; } | ||
} | ||
relatives.delete(node); | ||
} | ||
} | ||
finally { if (e_7) throw e_7.error; } | ||
} | ||
return null; | ||
} | ||
exports.getRelation = getRelation; | ||
/** | ||
* 대상 노드를 모두 포함하고 있는 릴레이션을 반환합니다. 해당되는 릴레이션이 없다면 null을 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
function getRelationEvery(group) { | ||
var nodes = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
nodes[_i - 1] = arguments[_i]; | ||
} | ||
var matchedRelations = group.filter(function (relation) { | ||
catch (e_6_1) { e_6 = { error: e_6_1 }; } | ||
finally { | ||
try { | ||
if (nodes_2_1 && !nodes_2_1.done && (_a = nodes_2.return)) _a.call(nodes_2); | ||
} | ||
finally { if (e_6) throw e_6.error; } | ||
} | ||
return __spread(relatives); | ||
}; | ||
/** | ||
* 노드 간 새로운 관계를 형성합니다. 중심 노드를 기준으로 대상 노드와 관계를 형성합니다. | ||
* 형성된 결과를 새로운 릴레이션으로 만들어 반환합니다. | ||
* 가령 `setRelation('language', 'korean', 'english', 'japanese')` 메서드는 `['langauge', 'korean'], ['language', 'english'], ['language', 'japanese']` 튜플을 생성합니다. | ||
* 따라서 language 노드를 삭제할 경우 korean, english, japanese 노드들 사이의 관계성은 사라집니다. | ||
* @param target 중심 노드입니다. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
Relation.prototype.setRelation = function (target) { | ||
var e_8, _a; | ||
var nodes = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
nodes[_i - 1] = arguments[_i]; | ||
} | ||
var relation = new (Relation.bind.apply(Relation, __spread([void 0], this.relations)))(); | ||
try { | ||
for (var nodes_2 = __values(nodes), nodes_2_1 = nodes_2.next(); !nodes_2_1.done; nodes_2_1 = nodes_2.next()) { | ||
var node = nodes_2_1.value; | ||
if (!relation.has(node)) | ||
return false; | ||
for (var nodes_3 = __values(nodes), nodes_3_1 = nodes_3.next(); !nodes_3_1.done; nodes_3_1 = nodes_3.next()) { | ||
var node = nodes_3_1.value; | ||
if (relation.hasTuple(target, node)) { | ||
continue; | ||
} | ||
var tuple = relation.createTuple(target, node); | ||
relation.relations.push(tuple); | ||
} | ||
@@ -306,75 +278,149 @@ } | ||
try { | ||
if (nodes_2_1 && !nodes_2_1.done && (_a = nodes_2.return)) _a.call(nodes_2); | ||
if (nodes_3_1 && !nodes_3_1.done && (_a = nodes_3.return)) _a.call(nodes_3); | ||
} | ||
finally { if (e_8) throw e_8.error; } | ||
} | ||
return true; | ||
}); | ||
return matchedRelations.pop() || null; | ||
} | ||
exports.getRelationEvery = getRelationEvery; | ||
/** | ||
* RelationGroup 인스턴스에 담긴 모든 노드를 배열로 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @deprecated group.nodes getter를 사용하십시오. | ||
*/ | ||
function getNodes(group) { | ||
var e_9, _a; | ||
var relationNodes = new AdvancedArray_1.default; | ||
try { | ||
for (var group_2 = __values(group), group_2_1 = group_2.next(); !group_2_1.done; group_2_1 = group_2.next()) { | ||
var relation = group_2_1.value; | ||
relationNodes.push.apply(relationNodes, __spread(relation)); | ||
return relation; | ||
}; | ||
/** | ||
* 대상 노드와 관계를 맺고 있는 노드만 추려내어 새로운 릴레이션으로 만들어 반환합니다. | ||
* 여러 노드를 매개변수로 전달하면, 합집합이 됩니다. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
Relation.prototype.getRelation = function () { | ||
var e_9, _a, e_10, _b; | ||
var nodes = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
nodes[_i] = arguments[_i]; | ||
} | ||
} | ||
catch (e_9_1) { e_9 = { error: e_9_1 }; } | ||
finally { | ||
var tuples = []; | ||
try { | ||
if (group_2_1 && !group_2_1.done && (_a = group_2.return)) _a.call(group_2); | ||
for (var _c = __values(this.relations), _d = _c.next(); !_d.done; _d = _c.next()) { | ||
var tuple = _d.value; | ||
try { | ||
for (var nodes_4 = (e_10 = void 0, __values(nodes)), nodes_4_1 = nodes_4.next(); !nodes_4_1.done; nodes_4_1 = nodes_4.next()) { | ||
var node = nodes_4_1.value; | ||
if (this.isTupleHasNode(tuple, node)) | ||
tuples.push(tuple); | ||
} | ||
} | ||
catch (e_10_1) { e_10 = { error: e_10_1 }; } | ||
finally { | ||
try { | ||
if (nodes_4_1 && !nodes_4_1.done && (_b = nodes_4.return)) _b.call(nodes_4); | ||
} | ||
finally { if (e_10) throw e_10.error; } | ||
} | ||
} | ||
} | ||
finally { if (e_9) throw e_9.error; } | ||
} | ||
relationNodes.deduplication(); | ||
return __spread(relationNodes); | ||
} | ||
exports.getNodes = getNodes; | ||
/** | ||
* RelationGroup 인스턴스가 대상 노드를 포함하고 있는지 여부를 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
function hasNode(group, node) { | ||
return !!getRelation(group, node); | ||
} | ||
exports.hasNode = hasNode; | ||
/** | ||
* 릴레이션이 대상 노드를 포함하고 있다면 노드를 삭제하고, 해당 릴레이션을 반환합니다. 어떤 릴레이션도 대상 노드를 가지고 있지 않다면 null을 반환합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
function deleteNode(group, node) { | ||
var t = getRelation(group, node); | ||
if (!t) | ||
return null; | ||
else { | ||
t.delete(node); | ||
return t; | ||
} | ||
} | ||
exports.deleteNode = deleteNode; | ||
/** | ||
* 대상 노드를 포함하고 있는 릴레이션을 RelationGroup 인스턴스에서 삭제합니다. | ||
* @param group RelationGroup 인스턴스입니다. | ||
* @param node 대상 노드입니다. | ||
*/ | ||
function dropRelation(group, node) { | ||
var i = group.length; | ||
while (i--) { | ||
var relation = group[i]; | ||
if (relation.has(node)) { | ||
group.delete(relation); | ||
catch (e_9_1) { e_9 = { error: e_9_1 }; } | ||
finally { | ||
try { | ||
if (_d && !_d.done && (_a = _c.return)) _a.call(_c); | ||
} | ||
finally { if (e_9) throw e_9.error; } | ||
} | ||
} | ||
} | ||
exports.dropRelation = dropRelation; | ||
return new (Relation.bind.apply(Relation, __spread([void 0], tuples)))(); | ||
}; | ||
/** | ||
* 대상 노드를 알고 있는 모든 관계를 추려내어 새로운 릴레이션으로 만들어 반환합니다. | ||
* 여러 노드를 매개변수로 전달하면, 합집합이 됩니다. | ||
* '알고 있다'는 것은, 직접적으로 관계되어 있거나, 다른 노드의 중계로 연결되어 있는 경우를 의미합니다. | ||
* 예를 들어 A--B--C, D--E 의 형태로 노드가 관계되어 있을 경우, A와 C는 B를 경유합니다. 이 경우, A와 C는 서로를 '알고 있다'고 표현합니다. | ||
* 하지만 D는 A, B, C와 어떤 관련도 없으므로 알고 있지 못합니다. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
Relation.prototype.getLegionRelation = function () { | ||
var e_11, _a; | ||
var nodes = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
nodes[_i] = arguments[_i]; | ||
} | ||
var relation = new Relation; | ||
try { | ||
for (var nodes_5 = __values(nodes), nodes_5_1 = nodes_5.next(); !nodes_5_1.done; nodes_5_1 = nodes_5.next()) { | ||
var node = nodes_5_1.value; | ||
this.recursiveToSetTuple(node, relation); | ||
} | ||
} | ||
catch (e_11_1) { e_11 = { error: e_11_1 }; } | ||
finally { | ||
try { | ||
if (nodes_5_1 && !nodes_5_1.done && (_a = nodes_5.return)) _a.call(nodes_5); | ||
} | ||
finally { if (e_11) throw e_11.error; } | ||
} | ||
return relation; | ||
}; | ||
/** | ||
* 노드 간 형성된 관계를 제거합니다. 중심 노드를 기준으로 대상 노드와 관계를 제거합니다. | ||
* 형성된 결과를 새로운 릴레이션으로 만들어 반환합니다. | ||
* @param target 중심 노드입니다. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
Relation.prototype.deleteRelation = function (target) { | ||
var e_12, _a; | ||
var nodes = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
nodes[_i - 1] = arguments[_i]; | ||
} | ||
var relation = new (Relation.bind.apply(Relation, __spread([void 0], this.relations)))(); | ||
try { | ||
for (var nodes_6 = __values(nodes), nodes_6_1 = nodes_6.next(); !nodes_6_1.done; nodes_6_1 = nodes_6.next()) { | ||
var node = nodes_6_1.value; | ||
var i = relation.relations.length; | ||
while (i--) { | ||
var tuple = relation.relations[i]; | ||
if (relation.getMateNode(tuple, target) === node) { | ||
relation.relations.delete(tuple); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
catch (e_12_1) { e_12 = { error: e_12_1 }; } | ||
finally { | ||
try { | ||
if (nodes_6_1 && !nodes_6_1.done && (_a = nodes_6.return)) _a.call(nodes_6); | ||
} | ||
finally { if (e_12) throw e_12.error; } | ||
} | ||
return relation; | ||
}; | ||
/** | ||
* 노드를 삭제합니다. 삭제된 노드와 형성되어 있던 관계는 제거됩니다. | ||
* 형성된 결과를 새로운 릴레이션으로 만들어 반환합니다. | ||
* @param nodes 대상 노드입니다. | ||
*/ | ||
Relation.prototype.deleteNode = function () { | ||
var e_13, _a; | ||
var nodes = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
nodes[_i] = arguments[_i]; | ||
} | ||
var relation = new (Relation.bind.apply(Relation, __spread([void 0], this.relations)))(); | ||
try { | ||
for (var nodes_7 = __values(nodes), nodes_7_1 = nodes_7.next(); !nodes_7_1.done; nodes_7_1 = nodes_7.next()) { | ||
var node = nodes_7_1.value; | ||
var i = relation.relations.length; | ||
while (i--) { | ||
var tuple = relation.relations[i]; | ||
if (relation.isTupleHasNode(tuple, node)) { | ||
relation.relations.delete(tuple); | ||
} | ||
} | ||
} | ||
} | ||
catch (e_13_1) { e_13 = { error: e_13_1 }; } | ||
finally { | ||
try { | ||
if (nodes_7_1 && !nodes_7_1.done && (_a = nodes_7.return)) _a.call(nodes_7); | ||
} | ||
finally { if (e_13) throw e_13.error; } | ||
} | ||
return relation; | ||
}; | ||
return Relation; | ||
}()); | ||
exports.default = Relation; | ||
}); |
{ | ||
"name": "node-relation", | ||
"version": "1.2.0", | ||
"version": "2.0.0", | ||
"description": "Manage strings that are related to each other.", | ||
@@ -5,0 +5,0 @@ "main": "dist/NodeRelation.js", |
# node-relation | ||
This module helps you manage string, numbers, and symbols as a group. | ||
This module helps you manage string, numbers as a group. | ||
The data in the instance is immutable. Do not modify the data in the instance that invokes the method (setRelation, getRelation, getLegionRelation, deleteNode, etc.). Instead, it returns the result with a new instance. | ||
Check the code. | ||
``` | ||
import { create, setRelation, getRelation } from 'node-relation' | ||
import Relation from 'node-relation' | ||
const group = create() | ||
const relationA = new Relation().setRelation('a', 'b', 'c') | ||
console.log(relationA.nodes) | ||
setRelation(group, 'JavaScript', 'Node.JS') | ||
setRelation(group, 'Node.JS', 'ES2018') | ||
setRelation(group, 'ES2018', 'Webpack') | ||
const relationB = relationA.setRelation('b', 'd') | ||
console.log(relationB.nodes) | ||
console.log( getRelation(group, 'ES2018') ) // [ 'JavaScript', 'Node.JS', 'ES2018', 'Webpack' ] | ||
const relationC = relationB.setRelation('e', 'f') | ||
console.log(relationC.getLegionRelation('e').nodes) | ||
const relationD = relationC.setRelation('e', 'a') | ||
console.log(relationD.getLegionRelation('e').nodes) | ||
``` | ||
--- | ||
## Methods | ||
### setRelation(target: `RelationNode`, ...nodes: `RelationNode[]`): `Relation` | ||
Creates a new relationship between nodes, and returns it as a relation instance. | ||
``` | ||
const A = new Relation().setRelation('language', 'English', 'Korean', 'Japanese') | ||
const B = A.setRelation('English', 'US', 'France', 'Italy') | ||
``` | ||
### getRelation(...nodes: `RelationNode[]`): `Relation` | ||
Only the nodes that are related to the node received by the parameter are filtered and returned in a new relation instance. | ||
``` | ||
A.getRelation('language').nodes // English, Korean, Japanese | ||
B.getRelation('English').nodes // US, France, Italy | ||
``` | ||
### getLegionRelation(...nodes: `RelationNode[]`): `Relation` | ||
Only groups of nodes that are associated with the node received by the parameter. Then make and return a new relation instance. | ||
``` | ||
B.getLegionRelation('language').nodes // English, Korean, Japanese, US, France, Italy | ||
``` | ||
### deleteRelation(target: `RelationNode`, ...nodes: `RelationNode[]`): Relation | ||
Deletes the relationship between nodes and returns it as a new relation instance. | ||
``` | ||
B.deleteRelation('English', 'France') | ||
``` | ||
### deleteNode(...nodes: `RelationNode[]`): `Relation` | ||
Delete the node. If the node associated with the deleted node is isolated, it is deleted together. Returns the result with a new relation instance. | ||
``` | ||
B.deleteNode('lanugage').nodes // English, US, France, Italy | ||
``` | ||
## Try it simply | ||
``` | ||
const relation = new Relation() | ||
.setRelation('language', 'English', 'Korean', 'Japanese') | ||
.setRelation('English', 'US', 'France', 'Italy') | ||
console.log(`Languages: ${ relation.getRelativeNodes('language') }`) | ||
// Languages: English, Korean, Japanese | ||
console.log(`English country: ${ relation.getRelation('English').deleteNode('language').getRelativeNodes('English') }`) | ||
// English country: US, France, Italy | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
31338
600
63
1