@@ -16,9 +16,11 @@ const { |
16 | 16 | ObjectDefineProperties, |
17 | 17 | ObjectFreeze, |
18 | 18 | ObjectKeys, |
| 19 | + ReflectConstruct, |
19 | 20 | SafeMap, |
20 | 21 | SafeSet, |
21 | 22 | Symbol, |
| 23 | + SymbolToStringTag, |
22 | 24 | } = primordials; |
23 | 25 |
|
24 | 26 | const { |
@@ -36,12 +38,13 @@ const { |
36 | 38 | } = internalBinding('performance'); |
37 | 39 |
|
38 | 40 | const { |
39 | | - InternalPerformanceEntry, |
40 | 41 | isPerformanceEntry, |
| 42 | + createPerformanceNodeEntry, |
41 | 43 | } = require('internal/perf/performance_entry'); |
42 | 44 |
|
43 | 45 | const { |
44 | 46 | codes: { |
| 47 | + ERR_ILLEGAL_CONSTRUCTOR, |
45 | 48 | ERR_INVALID_ARG_VALUE, |
46 | 49 | ERR_INVALID_ARG_TYPE, |
47 | 50 | ERR_MISSING_ARGS, |
@@ -51,13 +54,15 @@ const { |
51 | 54 | const { |
52 | 55 | validateFunction, |
53 | 56 | validateObject, |
| 57 | + validateInternalField, |
54 | 58 | } = require('internal/validators'); |
55 | 59 |
|
56 | 60 | const { |
57 | 61 | customInspectSymbol: kInspect, |
58 | 62 | deprecate, |
59 | 63 | lazyDOMException, |
60 | 64 | kEmptyObject, |
| 65 | + kEnumerableProperty, |
61 | 66 | } = require('internal/util'); |
62 | 67 |
|
63 | 68 | const { |
@@ -68,6 +73,7 @@ const { inspect } = require('util'); |
68 | 73 |
|
69 | 74 | const { now } = require('internal/perf/utils'); |
70 | 75 |
|
| 76 | +const kBuffer = Symbol('kBuffer'); |
71 | 77 | const kDispatch = Symbol('kDispatch'); |
72 | 78 | const kMaybeBuffer = Symbol('kMaybeBuffer'); |
73 | 79 | const kDeprecatedFields = Symbol('kDeprecatedFields'); |
@@ -167,34 +173,39 @@ function maybeIncrementObserverCount(type) { |
167 | 173 | } |
168 | 174 |
|
169 | 175 | class PerformanceObserverEntryList { |
170 | | - #buffer = []; |
171 | | - |
172 | | - constructor(entries) { |
173 | | - this.#buffer = ArrayPrototypeSort(entries, (first, second) => { |
174 | | - return first.startTime - second.startTime; |
175 | | - }); |
| 176 | + constructor() { |
| 177 | + throw new ERR_ILLEGAL_CONSTRUCTOR(); |
176 | 178 | } |
177 | 179 |
|
178 | 180 | getEntries() { |
179 | | - return ArrayPrototypeSlice(this.#buffer); |
| 181 | + validateInternalField(this, kBuffer, 'PerformanceObserverEntryList'); |
| 182 | + return ArrayPrototypeSlice(this[kBuffer]); |
180 | 183 | } |
181 | 184 |
|
182 | 185 | getEntriesByType(type) { |
| 186 | + validateInternalField(this, kBuffer, 'PerformanceObserverEntryList'); |
| 187 | + if (arguments.length === 0) { |
| 188 | + throw new ERR_MISSING_ARGS('type'); |
| 189 | + } |
183 | 190 | type = `${type}`; |
184 | 191 | return ArrayPrototypeFilter( |
185 | | - this.#buffer, |
| 192 | + this[kBuffer], |
186 | 193 | (entry) => entry.entryType === type); |
187 | 194 | } |
188 | 195 |
|
189 | | - getEntriesByName(name, type) { |
| 196 | + getEntriesByName(name, type = undefined) { |
| 197 | + validateInternalField(this, kBuffer, 'PerformanceObserverEntryList'); |
| 198 | + if (arguments.length === 0) { |
| 199 | + throw new ERR_MISSING_ARGS('name'); |
| 200 | + } |
190 | 201 | name = `${name}`; |
191 | 202 | if (type != null /** not nullish */) { |
192 | 203 | return ArrayPrototypeFilter( |
193 | | - this.#buffer, |
| 204 | + this[kBuffer], |
194 | 205 | (entry) => entry.name === name && entry.entryType === type); |
195 | 206 | } |
196 | 207 | return ArrayPrototypeFilter( |
197 | | - this.#buffer, |
| 208 | + this[kBuffer], |
198 | 209 | (entry) => entry.name === name); |
199 | 210 | } |
200 | 211 |
|
@@ -206,9 +217,29 @@ class PerformanceObserverEntryList { |
206 | 217 | depth: options.depth == null ? null : options.depth - 1 |
207 | 218 | }; |
208 | 219 |
|
209 | | - return `PerformanceObserverEntryList ${inspect(this.#buffer, opts)}`; |
| 220 | + return `PerformanceObserverEntryList ${inspect(this[kBuffer], opts)}`; |
210 | 221 | } |
211 | 222 | } |
| 223 | +ObjectDefineProperties(PerformanceObserverEntryList.prototype, { |
| 224 | + getEntries: kEnumerableProperty, |
| 225 | + getEntriesByType: kEnumerableProperty, |
| 226 | + getEntriesByName: kEnumerableProperty, |
| 227 | + [SymbolToStringTag]: { |
| 228 | + __proto__: null, |
| 229 | + writable: false, |
| 230 | + enumerable: false, |
| 231 | + configurable: true, |
| 232 | + value: 'PerformanceObserverEntryList', |
| 233 | + }, |
| 234 | +}); |
| 235 | + |
| 236 | +function createPerformanceObserverEntryList(entries) { |
| 237 | + return ReflectConstruct(function PerformanceObserverEntryList() { |
| 238 | + this[kBuffer] = ArrayPrototypeSort(entries, (first, second) => { |
| 239 | + return first.startTime - second.startTime; |
| 240 | + }); |
| 241 | + }, [], PerformanceObserverEntryList); |
| 242 | +} |
212 | 243 |
|
213 | 244 | class PerformanceObserver { |
214 | 245 | #buffer = []; |
@@ -319,7 +350,7 @@ class PerformanceObserver { |
319 | 350 | } |
320 | 351 |
|
321 | 352 | [kDispatch]() { |
322 | | - this.#callback(new PerformanceObserverEntryList(this.takeRecords()), |
| 353 | + this.#callback(createPerformanceObserverEntryList(this.takeRecords()), |
323 | 354 | this); |
324 | 355 | } |
325 | 356 |
|
@@ -339,6 +370,18 @@ class PerformanceObserver { |
339 | 370 | }, opts)}`; |
340 | 371 | } |
341 | 372 | } |
| 373 | +ObjectDefineProperties(PerformanceObserver.prototype, { |
| 374 | + observe: kEnumerableProperty, |
| 375 | + disconnect: kEnumerableProperty, |
| 376 | + takeRecords: kEnumerableProperty, |
| 377 | + [SymbolToStringTag]: { |
| 378 | + __proto__: null, |
| 379 | + writable: false, |
| 380 | + enumerable: false, |
| 381 | + configurable: true, |
| 382 | + value: 'PerformanceObserver', |
| 383 | + }, |
| 384 | +}); |
342 | 385 |
|
343 | 386 | /** |
344 | 387 | * https://www.w3.org/TR/performance-timeline/#dfn-queue-a-performanceentry |
@@ -485,7 +528,7 @@ function filterBufferMapByNameAndType(name, type) { |
485 | 528 |
|
486 | 529 | function observerCallback(name, type, startTime, duration, details) { |
487 | 530 | const entry = |
488 | | - new InternalPerformanceEntry( |
| 531 | + createPerformanceNodeEntry( |
489 | 532 | name, |
490 | 533 | type, |
491 | 534 | startTime, |
@@ -542,7 +585,7 @@ function stopPerf(target, key, context = {}) { |
542 | 585 | return; |
543 | 586 | } |
544 | 587 | const startTime = ctx.startTime; |
545 | | - const entry = new InternalPerformanceEntry( |
| 588 | + const entry = createPerformanceNodeEntry( |
546 | 589 | ctx.name, |
547 | 590 | ctx.type, |
548 | 591 | startTime, |
|