You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							107 lines
						
					
					
						
							2.2 KiB
						
					
					
				
			
		
		
	
	
							107 lines
						
					
					
						
							2.2 KiB
						
					
					
				'use strict'
 | 
						|
const archy = require('archy')
 | 
						|
 | 
						|
function TimeTree () {
 | 
						|
  this.root = null
 | 
						|
  this.tableId = new Map()
 | 
						|
  this.tableLabel = new Map()
 | 
						|
}
 | 
						|
 | 
						|
TimeTree.prototype.trackNode = function (node) {
 | 
						|
  this.tableId.set(node.id, node)
 | 
						|
  if (this.tableLabel.has(node.label)) {
 | 
						|
    this.tableLabel.get(node.label).push(node)
 | 
						|
  } else {
 | 
						|
    this.tableLabel.set(node.label, [node])
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TimeTree.prototype.untrackNode = function (node) {
 | 
						|
  this.tableId.delete(node.id)
 | 
						|
 | 
						|
  const labelNode = this.tableLabel.get(node.label)
 | 
						|
  if (labelNode.id) {
 | 
						|
    this.tableLabel.delete(node.label)
 | 
						|
    return
 | 
						|
  }
 | 
						|
  labelNode.pop()
 | 
						|
 | 
						|
  if (labelNode.length === 0) {
 | 
						|
    this.tableLabel.delete(node.label)
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TimeTree.prototype.getParent = function (parent) {
 | 
						|
  if (parent === null) {
 | 
						|
    return this.root
 | 
						|
  }
 | 
						|
 | 
						|
  const parentNode = this.tableLabel.get(parent)
 | 
						|
  if (parentNode.id) {
 | 
						|
    return parentNode
 | 
						|
  }
 | 
						|
  return parentNode[parentNode.length - 1]
 | 
						|
}
 | 
						|
 | 
						|
TimeTree.prototype.getNode = function (nodeId) {
 | 
						|
  return this.tableId.get(nodeId)
 | 
						|
}
 | 
						|
 | 
						|
TimeTree.prototype.add = function (parent, child, start) {
 | 
						|
  const isRoot = parent === null
 | 
						|
  if (isRoot) {
 | 
						|
    this.root = {
 | 
						|
      id: 'root',
 | 
						|
      label: child,
 | 
						|
      start,
 | 
						|
      nodes: []
 | 
						|
    }
 | 
						|
    this.trackNode(this.root)
 | 
						|
    return this.root.id
 | 
						|
  }
 | 
						|
 | 
						|
  const parentNode = this.getParent(parent)
 | 
						|
  const nodeId = `${child}-${Math.random()}`
 | 
						|
  const childNode = {
 | 
						|
    id: nodeId,
 | 
						|
    parent,
 | 
						|
    start,
 | 
						|
    label: child,
 | 
						|
    nodes: []
 | 
						|
  }
 | 
						|
  parentNode.nodes.push(childNode)
 | 
						|
  this.trackNode(childNode)
 | 
						|
  return nodeId
 | 
						|
}
 | 
						|
 | 
						|
TimeTree.prototype.start = function (parent, child, start) {
 | 
						|
  return this.add(parent, child, start || Date.now())
 | 
						|
}
 | 
						|
 | 
						|
TimeTree.prototype.stop = function (nodeId, stop) {
 | 
						|
  const node = this.getNode(nodeId)
 | 
						|
  if (node) {
 | 
						|
    node.stop = stop || Date.now()
 | 
						|
    node.diff = (node.stop - node.start) || 0
 | 
						|
    this.untrackNode(node)
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TimeTree.prototype.toJSON = function () {
 | 
						|
  return Object.assign({}, this.root)
 | 
						|
}
 | 
						|
 | 
						|
TimeTree.prototype.prittyPrint = function () {
 | 
						|
  const decorateText = (node) => {
 | 
						|
    node.label = `${node.label} ${node.diff} ms`
 | 
						|
    if (node.nodes.length > 0) {
 | 
						|
      node.nodes = node.nodes.map(_ => decorateText(_))
 | 
						|
    }
 | 
						|
    return node
 | 
						|
  }
 | 
						|
  const out = decorateText(this.toJSON())
 | 
						|
  return archy(out)
 | 
						|
}
 | 
						|
 | 
						|
module.exports = TimeTree
 |