• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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