1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.TreeQuery = void 0;
|
4 | var common_1 = require("../common");
|
5 | var TreeIdentity_1 = require("../TreeIdentity");
|
6 | var TreeQuery = (function () {
|
7 | function TreeQuery(args) {
|
8 | var _this = this;
|
9 | this.walkDown = function (visit) {
|
10 | var stopped = false;
|
11 | var walk = function (args) {
|
12 | if (!args.node || stopped) {
|
13 | return;
|
14 | }
|
15 | var _a = TreeIdentity_1.TreeIdentity.parse(args.node.id), id = _a.id, key = _a.key, namespace = _a.namespace;
|
16 | if (_this.namespace && namespace !== _this.namespace) {
|
17 | return;
|
18 | }
|
19 | var skipChildren = false;
|
20 | visit({
|
21 | id: id,
|
22 | key: key,
|
23 | namespace: namespace,
|
24 | node: args.node,
|
25 | parent: args.parent,
|
26 | index: args.index,
|
27 | level: args.depth,
|
28 | stop: function () { return (stopped = true); },
|
29 | skip: function () { return (skipChildren = true); },
|
30 | });
|
31 | if (stopped) {
|
32 | return;
|
33 | }
|
34 | var index = -1;
|
35 | if (!skipChildren) {
|
36 | for (var _i = 0, _b = TreeQuery.children(args.node, undefined, { assign: false }); _i < _b.length; _i++) {
|
37 | var child = _b[_i];
|
38 | index++;
|
39 | walk({
|
40 | node: child,
|
41 | parent: args.node,
|
42 | index: index,
|
43 | depth: args.depth + 1,
|
44 | });
|
45 | }
|
46 | }
|
47 | };
|
48 | return walk({ node: _this.root, depth: 0, index: -1 });
|
49 | };
|
50 | this.walkUp = function (startAt, visit) {
|
51 | var level = -1;
|
52 | var inner = function (startAt, visit) {
|
53 | var current = _this.findById(common_1.toNodeId(startAt));
|
54 | level++;
|
55 | if (current) {
|
56 | var stop_1 = false;
|
57 | var parentNode_1 = _this.parent(current);
|
58 | var _a = TreeIdentity_1.TreeIdentity.parse(current.id), id = _a.id, key = _a.key, namespace = _a.namespace;
|
59 | var args = {
|
60 | id: id,
|
61 | key: key,
|
62 | namespace: namespace,
|
63 | node: current,
|
64 | parent: parentNode_1,
|
65 | get index() {
|
66 | var id = current ? current.id : '';
|
67 | return !parentNode_1
|
68 | ? -1
|
69 | : (parentNode_1.children || []).findIndex(function (node) { return node.id === id; });
|
70 | },
|
71 | level: level,
|
72 | stop: function () { return (stop_1 = true); },
|
73 | };
|
74 | visit(args);
|
75 | if (!stop_1 && parentNode_1) {
|
76 | inner(args.parent, visit);
|
77 | }
|
78 | }
|
79 | };
|
80 | return inner(startAt, visit);
|
81 | };
|
82 | this.find = function (match) {
|
83 | var result;
|
84 | _this.walkDown(function (e) {
|
85 | if (match(e) === true) {
|
86 | result = e.node;
|
87 | e.stop();
|
88 | }
|
89 | });
|
90 | return result ? result : undefined;
|
91 | };
|
92 | this.findById = function (id) {
|
93 | if (!id) {
|
94 | return undefined;
|
95 | }
|
96 | else {
|
97 | var target_1 = TreeIdentity_1.TreeIdentity.parse(typeof id === 'string' ? id : id.id);
|
98 | return _this.find(function (e) {
|
99 | if (!target_1.namespace && e.key === target_1.key) {
|
100 | return true;
|
101 | }
|
102 | else {
|
103 | return e.key === target_1.key && e.namespace === target_1.namespace;
|
104 | }
|
105 | });
|
106 | }
|
107 | };
|
108 | this.parent = function (node) {
|
109 | if (!node) {
|
110 | return undefined;
|
111 | }
|
112 | if (typeof node !== 'object') {
|
113 | var id = node;
|
114 | node = _this.findById(id);
|
115 | if (!node) {
|
116 | throw new Error("Cannot find parent of '" + id + "' because that child node was not found.");
|
117 | }
|
118 | }
|
119 | var result;
|
120 | var target = node;
|
121 | _this.walkDown(function (e) {
|
122 | if (TreeQuery.hasChild(e.node, target)) {
|
123 | result = e.node;
|
124 | e.stop();
|
125 | }
|
126 | });
|
127 | return result;
|
128 | };
|
129 | this.ancestor = function (node, match) {
|
130 | var result;
|
131 | _this.walkUp(node, function (e) {
|
132 | if (match(e)) {
|
133 | result = e.node;
|
134 | e.stop();
|
135 | }
|
136 | });
|
137 | return result;
|
138 | };
|
139 | this.depth = function (node) {
|
140 | var depth = -1;
|
141 | if (!node || !_this.root) {
|
142 | return depth;
|
143 | }
|
144 | else {
|
145 | var id_1 = common_1.toNodeId(node);
|
146 | _this.walkDown(function (e) {
|
147 | if (e.node.id === id_1) {
|
148 | depth = e.level;
|
149 | e.stop();
|
150 | }
|
151 | });
|
152 | return depth;
|
153 | }
|
154 | };
|
155 | this.exists = function (input) {
|
156 | var node = typeof input === 'function' ? _this.find(input) : _this.findById(input);
|
157 | return Boolean(node);
|
158 | };
|
159 | this.root = args.root;
|
160 | this.namespace = (args.namespace || '').trim();
|
161 | }
|
162 | TreeQuery.create = function (args) {
|
163 | var input = args;
|
164 | var isQueryArgs = typeof input.root === 'object';
|
165 | var root = (isQueryArgs ? input.root : args);
|
166 | var namespace = isQueryArgs ? input.namespace || '' : '';
|
167 | return new TreeQuery({ root: root, namespace: namespace });
|
168 | };
|
169 | TreeQuery.children = function (of, fn, options) {
|
170 | if (options === void 0) { options = {}; }
|
171 | options = (typeof fn === 'object' ? fn : options) || {};
|
172 | var children = (!of ? [] : of.children || []);
|
173 | if (options.assign !== false && of && !of.children) {
|
174 | of.children = children;
|
175 | }
|
176 | if (typeof fn === 'function') {
|
177 | fn(children);
|
178 | }
|
179 | return children;
|
180 | };
|
181 | TreeQuery.hasChild = function (parent, child) {
|
182 | var nodes = TreeQuery.children(parent);
|
183 | var id = common_1.toNodeId(child);
|
184 | return nodes.some(function (node) { return node.id === id; });
|
185 | };
|
186 | TreeQuery.childAt = function (index, parent) {
|
187 | return TreeQuery.children(parent)[index];
|
188 | };
|
189 | return TreeQuery;
|
190 | }());
|
191 | exports.TreeQuery = TreeQuery;
|