mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Refactor TreeNode.js & TreeNode.test.js to TypeScript (#58540)
This commit is contained in:
@@ -135,10 +135,13 @@ export default function transformTraceData(data: TraceResponse | undefined): Tra
|
||||
|
||||
// Eslint complains about number type not needed but then TS complains it is implicitly any.
|
||||
// eslint-disable-next-line @typescript-eslint/no-inferrable-types
|
||||
tree.walk((spanID: string, node: TreeNode, depth: number = 0) => {
|
||||
tree.walk((spanID: string | number | undefined, node: TreeNode, depth: number = 0) => {
|
||||
if (spanID === '__root__') {
|
||||
return;
|
||||
}
|
||||
if (typeof spanID !== 'string') {
|
||||
return;
|
||||
}
|
||||
const span = spanMap.get(spanID) as TraceSpan;
|
||||
if (!span) {
|
||||
return;
|
||||
|
@@ -280,7 +280,7 @@ it('walk() should iterate over every item and compute the right deep on each nod
|
||||
const nodeB0 = new TreeNode('B0');
|
||||
const nodeB1 = new TreeNode('B1');
|
||||
const nodeC3 = new TreeNode('C3');
|
||||
const depthMap = { A: 0, B0: 1, B1: 1, C0: 2, C1: 2, C2: 2, C3: 2, D: 3 };
|
||||
const depthMap: { [key: string]: number } = { A: 0, B0: 1, B1: 1, C0: 2, C1: 2, C2: 2, C3: 2, D: 3 };
|
||||
nodeA.addChild(nodeB0);
|
||||
nodeA.addChild(nodeB0);
|
||||
nodeA.addChild(nodeB1);
|
||||
@@ -289,5 +289,9 @@ it('walk() should iterate over every item and compute the right deep on each nod
|
||||
nodeB1.addChild('C2');
|
||||
nodeB1.addChild(nodeC3);
|
||||
nodeC3.addChild('D');
|
||||
nodeA.walk((value, node, depth) => expect(depth).toBe(depthMap[value]));
|
||||
nodeA.walk((value, _, depth) => {
|
||||
if (typeof value === 'string') {
|
||||
expect(depth).toBe(depthMap[value]);
|
||||
}
|
||||
});
|
||||
});
|
@@ -12,26 +12,32 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
type SearchFn = (value: string | number | undefined, node: TreeNode, depth?: number) => boolean;
|
||||
|
||||
export default class TreeNode {
|
||||
static iterFunction(fn, depth = 0) {
|
||||
return (node) => fn(node.value, node, depth);
|
||||
value: string | number | undefined;
|
||||
children: TreeNode[];
|
||||
|
||||
static iterFunction(fn: SearchFn, depth = 0) {
|
||||
return (node: TreeNode) => fn(node.value, node, depth);
|
||||
}
|
||||
|
||||
static searchFunction(search) {
|
||||
static searchFunction(search: TreeNode | number | SearchFn) {
|
||||
if (typeof search === 'function') {
|
||||
return search;
|
||||
}
|
||||
|
||||
return (value, node) => (search instanceof TreeNode ? node === search : value === search);
|
||||
return (value: string | number | undefined, node: TreeNode) =>
|
||||
search instanceof TreeNode ? node === search : value === search;
|
||||
}
|
||||
|
||||
constructor(value, children = []) {
|
||||
constructor(value?: string | number, children: TreeNode[] = []) {
|
||||
this.value = value;
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
get depth() {
|
||||
return this.children.reduce((depth, child) => Math.max(child.depth + 1, depth), 1);
|
||||
get depth(): number {
|
||||
return this.children?.reduce((depth: number, child: { depth: number }) => Math.max(child.depth + 1, depth), 1);
|
||||
}
|
||||
|
||||
get size() {
|
||||
@@ -40,12 +46,12 @@ export default class TreeNode {
|
||||
return i;
|
||||
}
|
||||
|
||||
addChild(child) {
|
||||
this.children.push(child instanceof TreeNode ? child : new TreeNode(child));
|
||||
addChild(child: string | number | TreeNode) {
|
||||
this.children?.push(child instanceof TreeNode ? child : new TreeNode(child));
|
||||
return this;
|
||||
}
|
||||
|
||||
find(search) {
|
||||
find(search: TreeNode | number | SearchFn): TreeNode | null {
|
||||
const searchFn = TreeNode.iterFunction(TreeNode.searchFunction(search));
|
||||
if (searchFn(this)) {
|
||||
return this;
|
||||
@@ -59,10 +65,10 @@ export default class TreeNode {
|
||||
return null;
|
||||
}
|
||||
|
||||
getPath(search) {
|
||||
getPath(search: TreeNode) {
|
||||
const searchFn = TreeNode.iterFunction(TreeNode.searchFunction(search));
|
||||
|
||||
const findPath = (currentNode, currentPath) => {
|
||||
const findPath = (currentNode: TreeNode, currentPath: TreeNode[]): TreeNode[] | null => {
|
||||
// skip if we already found the result
|
||||
const attempt = currentPath.concat([currentNode]);
|
||||
// base case: return the array when there is a match
|
||||
@@ -82,18 +88,21 @@ export default class TreeNode {
|
||||
return findPath(this, []);
|
||||
}
|
||||
|
||||
walk(fn, depth = 0) {
|
||||
const nodeStack = [];
|
||||
walk(fn: (value: string | number | undefined, node: TreeNode, depth?: number) => void, depth = 0) {
|
||||
const nodeStack: Array<{ node: TreeNode; depth?: number }> = [];
|
||||
let actualDepth = depth;
|
||||
nodeStack.push({ node: this, depth: actualDepth });
|
||||
while (nodeStack.length) {
|
||||
const { node, depth: nodeDepth } = nodeStack.pop();
|
||||
fn(node.value, node, nodeDepth);
|
||||
actualDepth = nodeDepth + 1;
|
||||
let i = node.children.length - 1;
|
||||
while (i >= 0) {
|
||||
nodeStack.push({ node: node.children[i], depth: actualDepth });
|
||||
i--;
|
||||
const popped = nodeStack.pop();
|
||||
if (popped) {
|
||||
const { node, depth: nodeDepth } = popped;
|
||||
fn(node.value, node, nodeDepth);
|
||||
actualDepth = (nodeDepth || 0) + 1;
|
||||
let i = node.children.length - 1;
|
||||
while (i >= 0) {
|
||||
nodeStack.push({ node: node.children[i], depth: actualDepth });
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user