1'use strict'; 2 3const { 4 ObjectDefineProperty, 5 ObjectDefineProperties, 6 ObjectSetPrototypeOf, 7} = primordials; 8 9const { 10 codes: { 11 ERR_ILLEGAL_CONSTRUCTOR, 12 ERR_MISSING_ARGS, 13 }, 14} = require('internal/errors'); 15 16const { 17 EventTarget, 18 Event, 19 kTrustEvent, 20} = require('internal/event_target'); 21 22const { now } = require('internal/perf/utils'); 23 24const { markResourceTiming } = require('internal/perf/resource_timing'); 25 26const { 27 mark, 28 measure, 29 clearMarkTimings, 30} = require('internal/perf/usertiming'); 31const { 32 clearEntriesFromBuffer, 33 filterBufferMapByNameAndType, 34 setResourceTimingBufferSize, 35 setDispatchBufferFull, 36} = require('internal/perf/observe'); 37 38const eventLoopUtilization = require('internal/perf/event_loop_utilization'); 39const nodeTiming = require('internal/perf/nodetiming'); 40const timerify = require('internal/perf/timerify'); 41const { customInspectSymbol: kInspect } = require('internal/util'); 42const { inspect } = require('util'); 43 44const { 45 getTimeOriginTimestamp, 46} = internalBinding('performance'); 47 48class Performance extends EventTarget { 49 constructor() { 50 throw new ERR_ILLEGAL_CONSTRUCTOR(); 51 } 52 53 [kInspect](depth, options) { 54 if (depth < 0) return this; 55 56 const opts = { 57 ...options, 58 depth: options.depth == null ? null : options.depth - 1, 59 }; 60 61 return `Performance ${inspect({ 62 nodeTiming: this.nodeTiming, 63 timeOrigin: this.timeOrigin, 64 }, opts)}`; 65 } 66} 67 68function toJSON() { 69 return { 70 nodeTiming: this.nodeTiming, 71 timeOrigin: this.timeOrigin, 72 eventLoopUtilization: this.eventLoopUtilization(), 73 }; 74} 75 76function clearMarks(name) { 77 if (name !== undefined) { 78 name = `${name}`; 79 } 80 clearMarkTimings(name); 81 clearEntriesFromBuffer('mark', name); 82} 83 84function clearMeasures(name) { 85 if (name !== undefined) { 86 name = `${name}`; 87 } 88 clearEntriesFromBuffer('measure', name); 89} 90 91function clearResourceTimings(name) { 92 if (name !== undefined) { 93 name = `${name}`; 94 } 95 clearEntriesFromBuffer('resource', name); 96} 97 98function getEntries() { 99 return filterBufferMapByNameAndType(); 100} 101 102function getEntriesByName(name) { 103 if (arguments.length === 0) { 104 throw new ERR_MISSING_ARGS('name'); 105 } 106 name = `${name}`; 107 return filterBufferMapByNameAndType(name, undefined); 108} 109 110function getEntriesByType(type) { 111 if (arguments.length === 0) { 112 throw new ERR_MISSING_ARGS('type'); 113 } 114 type = `${type}`; 115 return filterBufferMapByNameAndType(undefined, type); 116} 117 118class InternalPerformance extends EventTarget {} 119InternalPerformance.prototype.constructor = Performance.prototype.constructor; 120ObjectSetPrototypeOf(InternalPerformance.prototype, Performance.prototype); 121 122ObjectDefineProperties(Performance.prototype, { 123 clearMarks: { 124 __proto__: null, 125 configurable: true, 126 enumerable: false, 127 value: clearMarks, 128 }, 129 clearMeasures: { 130 __proto__: null, 131 configurable: true, 132 enumerable: false, 133 value: clearMeasures, 134 }, 135 clearResourceTimings: { 136 __proto__: null, 137 configurable: true, 138 enumerable: false, 139 value: clearResourceTimings, 140 }, 141 eventLoopUtilization: { 142 __proto__: null, 143 configurable: true, 144 enumerable: false, 145 value: eventLoopUtilization, 146 }, 147 getEntries: { 148 __proto__: null, 149 configurable: true, 150 enumerable: false, 151 value: getEntries, 152 }, 153 getEntriesByName: { 154 __proto__: null, 155 configurable: true, 156 enumerable: false, 157 value: getEntriesByName, 158 }, 159 getEntriesByType: { 160 __proto__: null, 161 configurable: true, 162 enumerable: false, 163 value: getEntriesByType, 164 }, 165 mark: { 166 __proto__: null, 167 configurable: true, 168 enumerable: false, 169 value: mark, 170 }, 171 measure: { 172 __proto__: null, 173 configurable: true, 174 enumerable: false, 175 value: measure, 176 }, 177 nodeTiming: { 178 __proto__: null, 179 configurable: true, 180 enumerable: false, 181 value: nodeTiming, 182 }, 183 // In the browser, this function is not public. However, it must be used inside fetch 184 // which is a Node.js dependency, not a internal module 185 markResourceTiming: { 186 __proto__: null, 187 configurable: true, 188 enumerable: false, 189 value: markResourceTiming, 190 }, 191 now: { 192 __proto__: null, 193 configurable: true, 194 enumerable: false, 195 value: now, 196 }, 197 setResourceTimingBufferSize: { 198 __proto__: null, 199 configurable: true, 200 enumerable: false, 201 value: setResourceTimingBufferSize, 202 }, 203 timerify: { 204 __proto__: null, 205 configurable: true, 206 enumerable: false, 207 value: timerify, 208 }, 209 timeOrigin: { 210 __proto__: null, 211 configurable: true, 212 enumerable: true, 213 get() { 214 const value = getTimeOriginTimestamp(); 215 ObjectDefineProperty(Performance.prototype, 'timeOrigin', { 216 __proto__: null, 217 value, 218 }); 219 return value; 220 }, 221 set(value) { 222 ObjectDefineProperty(Performance.prototype, 'timeOrigin', { 223 __proto__: null, 224 value, 225 }); 226 }, 227 }, 228 toJSON: { 229 __proto__: null, 230 configurable: true, 231 enumerable: true, 232 value: toJSON, 233 }, 234}); 235 236const performance = new InternalPerformance(); 237 238function dispatchBufferFull(type) { 239 const event = new Event(type, { 240 [kTrustEvent]: true, 241 }); 242 performance.dispatchEvent(event); 243} 244setDispatchBufferFull(dispatchBufferFull); 245 246module.exports = { 247 Performance, 248 performance, 249}; 250