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
 |