@ccheever/exact-ibex-runtime 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/package.json +63 -0
  2. package/src/abort/AbortController.ts +23 -0
  3. package/src/abort/AbortSignal.ts +152 -0
  4. package/src/abort/index.ts +2 -0
  5. package/src/accessibility.ts +12 -0
  6. package/src/arraybuffer-detach.ts +109 -0
  7. package/src/base64/base64.ts +168 -0
  8. package/src/base64/index.ts +1 -0
  9. package/src/blob/Blob.ts +259 -0
  10. package/src/blob/File.ts +59 -0
  11. package/src/blob/FormData.ts +323 -0
  12. package/src/blob/index.ts +3 -0
  13. package/src/bootstrap.ts +1946 -0
  14. package/src/broadcast/BroadcastChannel.ts +280 -0
  15. package/src/broadcast/index.ts +5 -0
  16. package/src/cache/Cache.ts +349 -0
  17. package/src/cache/CacheStorage.ts +89 -0
  18. package/src/cache/index.ts +27 -0
  19. package/src/camera/index.ts +6202 -0
  20. package/src/camera/processor.worker.ts +194 -0
  21. package/src/camera/scene.ts +195 -0
  22. package/src/clipboard/Clipboard.ts +129 -0
  23. package/src/clipboard/ClipboardItem.ts +97 -0
  24. package/src/clipboard/index.ts +6 -0
  25. package/src/clone/index.ts +1 -0
  26. package/src/clone/structuredClone.ts +389 -0
  27. package/src/clone/transferableSymbols.ts +2 -0
  28. package/src/compression/CompressionStream.ts +146 -0
  29. package/src/compression/DecompressionStream.ts +342 -0
  30. package/src/compression/index.ts +4 -0
  31. package/src/console/Console.ts +341 -0
  32. package/src/console/index.ts +2 -0
  33. package/src/core/accessibility-state.ts +263 -0
  34. package/src/core/accessibility.ts +184 -0
  35. package/src/core/agent-state.ts +37 -0
  36. package/src/core/diagnostics-logs.ts +144 -0
  37. package/src/core/host-call-bridge.ts +16 -0
  38. package/src/core/i18n-helpers.ts +189 -0
  39. package/src/core/locale-state.ts +253 -0
  40. package/src/core/locale.ts +95 -0
  41. package/src/crypto/Crypto.ts +2743 -0
  42. package/src/crypto/index.ts +1 -0
  43. package/src/diagnostics/logs.ts +7 -0
  44. package/src/encoding/TextDecoder.ts +1181 -0
  45. package/src/encoding/TextDecoderStream.ts +58 -0
  46. package/src/encoding/TextEncoder.ts +180 -0
  47. package/src/encoding/TextEncoderStream.ts +39 -0
  48. package/src/encoding/index.ts +8 -0
  49. package/src/events/CloseEvent.ts +91 -0
  50. package/src/events/DOMException.ts +409 -0
  51. package/src/events/ErrorEvent.ts +39 -0
  52. package/src/events/Event.ts +151 -0
  53. package/src/events/EventTarget.ts +280 -0
  54. package/src/events/FocusEvent.ts +27 -0
  55. package/src/events/KeyboardEvent.ts +46 -0
  56. package/src/events/MessageEvent.ts +61 -0
  57. package/src/events/ProgressEvent.ts +33 -0
  58. package/src/events/PromiseRejectionEvent.ts +31 -0
  59. package/src/events/index.ts +52 -0
  60. package/src/eventsource/EventSource.ts +371 -0
  61. package/src/eventsource/index.ts +2 -0
  62. package/src/fetch/Headers.ts +642 -0
  63. package/src/fetch/Request.ts +760 -0
  64. package/src/fetch/Response.ts +543 -0
  65. package/src/fetch/body.ts +1256 -0
  66. package/src/fetch/cookie-jar.ts +566 -0
  67. package/src/fetch/demo.ts +207 -0
  68. package/src/fetch/errors.ts +101 -0
  69. package/src/fetch/fetch.ts +2610 -0
  70. package/src/fetch/index.ts +101 -0
  71. package/src/fetch/native-bridge.ts +65 -0
  72. package/src/fetch/types.ts +258 -0
  73. package/src/filereader/FileReader.ts +236 -0
  74. package/src/filereader/index.ts +1 -0
  75. package/src/fs/Dirent.ts +39 -0
  76. package/src/fs/ExactFile.ts +450 -0
  77. package/src/fs/Stats.ts +80 -0
  78. package/src/fs/index.ts +944 -0
  79. package/src/fs/promises.ts +386 -0
  80. package/src/fs/shared.ts +328 -0
  81. package/src/http-server/index.js +697 -0
  82. package/src/http-server/index.ts +27 -0
  83. package/src/identity.generated.ts +14 -0
  84. package/src/index.ts +283 -0
  85. package/src/indexeddb/IDBCursor.ts +188 -0
  86. package/src/indexeddb/IDBDatabase.ts +343 -0
  87. package/src/indexeddb/IDBFactory.ts +269 -0
  88. package/src/indexeddb/IDBIndex.ts +194 -0
  89. package/src/indexeddb/IDBKeyRange.ts +109 -0
  90. package/src/indexeddb/IDBObjectStore.ts +468 -0
  91. package/src/indexeddb/IDBRequest.ts +163 -0
  92. package/src/indexeddb/IDBTransaction.ts +207 -0
  93. package/src/indexeddb/index.ts +34 -0
  94. package/src/indexeddb/utils.ts +52 -0
  95. package/src/inspect/index.ts +1 -0
  96. package/src/inspect/inspect.ts +465 -0
  97. package/src/internal/detect.ts +104 -0
  98. package/src/locale.ts +10 -0
  99. package/src/location/index.ts +1059 -0
  100. package/src/locks/LockManager.ts +460 -0
  101. package/src/locks/index.ts +12 -0
  102. package/src/media/VideoFrame.ts +58 -0
  103. package/src/messaging/MessageChannel.ts +31 -0
  104. package/src/messaging/MessagePort.ts +180 -0
  105. package/src/messaging/index.ts +2 -0
  106. package/src/messaging.ts +247 -0
  107. package/src/native/NativeModules.ts +354 -0
  108. package/src/native/index.ts +1 -0
  109. package/src/navigator/Navigator.ts +351 -0
  110. package/src/navigator/index.ts +1 -0
  111. package/src/node/Buffer.ts +1786 -0
  112. package/src/node/index.ts +4 -0
  113. package/src/node/path.ts +495 -0
  114. package/src/node/process.ts +2528 -0
  115. package/src/performance/Performance.ts +532 -0
  116. package/src/performance/index.ts +21 -0
  117. package/src/polyfills/array.ts +236 -0
  118. package/src/polyfills/arraybuffer.ts +172 -0
  119. package/src/polyfills/groupby.ts +85 -0
  120. package/src/polyfills/index.ts +85 -0
  121. package/src/polyfills/intl.ts +1956 -0
  122. package/src/polyfills/iterator.ts +479 -0
  123. package/src/polyfills/promise.ts +37 -0
  124. package/src/polyfills/set.ts +245 -0
  125. package/src/polyfills/string.ts +85 -0
  126. package/src/polyfills/typedarray.ts +110 -0
  127. package/src/promise-rejection-tracking.ts +464 -0
  128. package/src/react-native/index.ts +388 -0
  129. package/src/runtime-entry.ts +55 -0
  130. package/src/scheduling/AnimationFrame.ts +105 -0
  131. package/src/scheduling/IdleCallback.ts +167 -0
  132. package/src/scheduling/index.ts +13 -0
  133. package/src/security/Capabilities.ts +1146 -0
  134. package/src/security/Permissions.ts +392 -0
  135. package/src/security/capability-bits.generated.ts +63 -0
  136. package/src/security/index.ts +16 -0
  137. package/src/sqlite/Database.ts +456 -0
  138. package/src/sqlite/Statement.ts +206 -0
  139. package/src/sqlite/constants.ts +79 -0
  140. package/src/sqlite/errors.ts +25 -0
  141. package/src/sqlite/index.ts +34 -0
  142. package/src/sqlite/module.js +438 -0
  143. package/src/storage/Storage.ts +291 -0
  144. package/src/storage/StorageManager.ts +91 -0
  145. package/src/storage/index.ts +3 -0
  146. package/src/stream-compat.ts +47 -0
  147. package/src/streams/ReadableStream.ts +4131 -0
  148. package/src/streams/TransformStream.ts +375 -0
  149. package/src/streams/WritableStream.ts +866 -0
  150. package/src/streams/index.ts +41 -0
  151. package/src/timers/Timers.ts +296 -0
  152. package/src/timers/index.ts +11 -0
  153. package/src/url/URL.ts +656 -0
  154. package/src/url/URLPattern.ts +850 -0
  155. package/src/url/URLSearchParams.ts +244 -0
  156. package/src/url/index.ts +9 -0
  157. package/src/websocket/WebSocket.ts +770 -0
  158. package/src/websocket/WebSocketError.ts +52 -0
  159. package/src/websocket/WebSocketStream.ts +628 -0
  160. package/src/websocket/index.ts +7 -0
  161. package/src/window/index.ts +872 -0
@@ -0,0 +1,532 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * Performance - Web Standard Performance API Implementation
4
+ *
5
+ * @see https://www.w3.org/TR/hr-time/
6
+ * @see https://www.w3.org/TR/user-timing/
7
+ */
8
+
9
+ import { EventTarget } from "../events/EventTarget";
10
+
11
+ export interface PerformanceMarkOptions {
12
+ detail?: any;
13
+ startTime?: number;
14
+ }
15
+
16
+ export interface PerformanceMeasureOptions {
17
+ detail?: any;
18
+ start?: string | number;
19
+ duration?: number;
20
+ end?: string | number;
21
+ }
22
+
23
+ export interface PerformanceEntryInit {
24
+ name: string;
25
+ entryType: string;
26
+ startTime: number;
27
+ duration: number;
28
+ }
29
+
30
+ export class PerformanceEntry {
31
+ readonly name: string;
32
+ readonly entryType: string;
33
+ readonly startTime: number;
34
+ readonly duration: number;
35
+
36
+ constructor(init: PerformanceEntryInit) {
37
+ this.name = init.name;
38
+ this.entryType = init.entryType;
39
+ this.startTime = init.startTime;
40
+ this.duration = init.duration;
41
+ }
42
+
43
+ toJSON(): object {
44
+ return {
45
+ name: this.name,
46
+ entryType: this.entryType,
47
+ startTime: this.startTime,
48
+ duration: this.duration,
49
+ };
50
+ }
51
+ }
52
+
53
+ export class PerformanceMark extends PerformanceEntry {
54
+ readonly detail: any;
55
+
56
+ constructor(name: string, options?: PerformanceMarkOptions) {
57
+ super({
58
+ name,
59
+ entryType: "mark",
60
+ startTime: options?.startTime ?? performance?.now?.() ?? Date.now(),
61
+ duration: 0,
62
+ });
63
+ this.detail = options?.detail;
64
+ }
65
+ }
66
+
67
+ export class PerformanceMeasure extends PerformanceEntry {
68
+ readonly detail: any;
69
+
70
+ constructor(
71
+ name: string,
72
+ startTime: number,
73
+ duration: number,
74
+ detail?: any
75
+ ) {
76
+ super({
77
+ name,
78
+ entryType: "measure",
79
+ startTime,
80
+ duration,
81
+ });
82
+ this.detail = detail;
83
+ }
84
+ }
85
+
86
+ // Native module for high-resolution timing
87
+ export interface PerformanceModule {
88
+ now(): number;
89
+ timeOrigin: number;
90
+ }
91
+
92
+ let nativeModule: PerformanceModule | null = null;
93
+
94
+ export function setNativePerformanceModule(module: PerformanceModule): void {
95
+ nativeModule = module;
96
+ }
97
+
98
+ // Fallback using Date.now() with offset
99
+ const fallbackTimeOrigin = Date.now();
100
+ const fallbackModule: PerformanceModule = {
101
+ now: () => Date.now() - fallbackTimeOrigin,
102
+ timeOrigin: fallbackTimeOrigin,
103
+ };
104
+
105
+ function getModule(): PerformanceModule {
106
+ return nativeModule ?? fallbackModule;
107
+ }
108
+
109
+ export class Performance {
110
+ private _marks: Map<string, PerformanceMark[]> = new Map();
111
+ private _measures: Map<string, PerformanceMeasure[]> = new Map();
112
+ private _entries: PerformanceEntry[] = [];
113
+
114
+ /**
115
+ * Time origin (when the runtime started)
116
+ */
117
+ get timeOrigin(): number {
118
+ return getModule().timeOrigin;
119
+ }
120
+
121
+ /**
122
+ * Current high-resolution timestamp in milliseconds
123
+ */
124
+ now(): number {
125
+ return getModule().now();
126
+ }
127
+
128
+ /**
129
+ * Create a performance mark
130
+ */
131
+ mark(markName: string, markOptions?: PerformanceMarkOptions): PerformanceMark {
132
+ const mark = new PerformanceMark(markName, {
133
+ ...markOptions,
134
+ startTime: markOptions?.startTime ?? this.now(),
135
+ });
136
+
137
+ let marks = this._marks.get(markName);
138
+ if (!marks) {
139
+ marks = [];
140
+ this._marks.set(markName, marks);
141
+ }
142
+ marks.push(mark);
143
+ this._entries.push(mark);
144
+
145
+ return mark;
146
+ }
147
+
148
+ /**
149
+ * Create a performance measure between two marks or times
150
+ */
151
+ measure(
152
+ measureName: string,
153
+ startOrMeasureOptions?: string | PerformanceMeasureOptions,
154
+ endMark?: string
155
+ ): PerformanceMeasure {
156
+ let startTime: number;
157
+ let endTime: number;
158
+ let detail: any;
159
+
160
+ if (typeof startOrMeasureOptions === "string" || startOrMeasureOptions === undefined) {
161
+ // Legacy signature: measure(name, startMark?, endMark?)
162
+ const startMarkName = startOrMeasureOptions;
163
+
164
+ if (startMarkName) {
165
+ const startMarks = this._marks.get(startMarkName);
166
+ if (!startMarks || startMarks.length === 0) {
167
+ throw new DOMException(
168
+ `Failed to execute 'measure': The mark '${startMarkName}' does not exist.`,
169
+ "SyntaxError"
170
+ );
171
+ }
172
+ startTime = startMarks[startMarks.length - 1].startTime;
173
+ } else {
174
+ startTime = 0;
175
+ }
176
+
177
+ if (endMark) {
178
+ const endMarks = this._marks.get(endMark);
179
+ if (!endMarks || endMarks.length === 0) {
180
+ throw new DOMException(
181
+ `Failed to execute 'measure': The mark '${endMark}' does not exist.`,
182
+ "SyntaxError"
183
+ );
184
+ }
185
+ endTime = endMarks[endMarks.length - 1].startTime;
186
+ } else {
187
+ endTime = this.now();
188
+ }
189
+ } else {
190
+ // Modern signature: measure(name, options)
191
+ const options = startOrMeasureOptions;
192
+ detail = options.detail;
193
+
194
+ if (options.start !== undefined) {
195
+ if (typeof options.start === "string") {
196
+ const startMarks = this._marks.get(options.start);
197
+ if (!startMarks || startMarks.length === 0) {
198
+ throw new DOMException(
199
+ `Failed to execute 'measure': The mark '${options.start}' does not exist.`,
200
+ "SyntaxError"
201
+ );
202
+ }
203
+ startTime = startMarks[startMarks.length - 1].startTime;
204
+ } else {
205
+ startTime = options.start;
206
+ }
207
+ } else {
208
+ startTime = 0;
209
+ }
210
+
211
+ if (options.end !== undefined) {
212
+ if (typeof options.end === "string") {
213
+ const endMarks = this._marks.get(options.end);
214
+ if (!endMarks || endMarks.length === 0) {
215
+ throw new DOMException(
216
+ `Failed to execute 'measure': The mark '${options.end}' does not exist.`,
217
+ "SyntaxError"
218
+ );
219
+ }
220
+ endTime = endMarks[endMarks.length - 1].startTime;
221
+ } else {
222
+ endTime = options.end;
223
+ }
224
+ } else if (options.duration !== undefined) {
225
+ endTime = startTime + options.duration;
226
+ } else {
227
+ endTime = this.now();
228
+ }
229
+ }
230
+
231
+ const duration = endTime - startTime;
232
+ const measure = new PerformanceMeasure(measureName, startTime, duration, detail);
233
+
234
+ let measures = this._measures.get(measureName);
235
+ if (!measures) {
236
+ measures = [];
237
+ this._measures.set(measureName, measures);
238
+ }
239
+ measures.push(measure);
240
+ this._entries.push(measure);
241
+
242
+ return measure;
243
+ }
244
+
245
+ /**
246
+ * Clear marks by name (or all marks if no name given)
247
+ */
248
+ clearMarks(markName?: string): void {
249
+ if (markName) {
250
+ this._marks.delete(markName);
251
+ this._entries = this._entries.filter(
252
+ (e) => !(e.entryType === "mark" && e.name === markName)
253
+ );
254
+ } else {
255
+ this._marks.clear();
256
+ this._entries = this._entries.filter((e) => e.entryType !== "mark");
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Clear measures by name (or all measures if no name given)
262
+ */
263
+ clearMeasures(measureName?: string): void {
264
+ if (measureName) {
265
+ this._measures.delete(measureName);
266
+ this._entries = this._entries.filter(
267
+ (e) => !(e.entryType === "measure" && e.name === measureName)
268
+ );
269
+ } else {
270
+ this._measures.clear();
271
+ this._entries = this._entries.filter((e) => e.entryType !== "measure");
272
+ }
273
+ }
274
+
275
+ /**
276
+ * Get all entries
277
+ */
278
+ getEntries(): PerformanceEntry[] {
279
+ return [...this._entries].sort((a, b) => a.startTime - b.startTime);
280
+ }
281
+
282
+ /**
283
+ * Get entries by name
284
+ */
285
+ getEntriesByName(name: string, type?: string): PerformanceEntry[] {
286
+ return this._entries
287
+ .filter((e) => e.name === name && (!type || e.entryType === type))
288
+ .sort((a, b) => a.startTime - b.startTime);
289
+ }
290
+
291
+ /**
292
+ * Get entries by type
293
+ */
294
+ getEntriesByType(type: string): PerformanceEntry[] {
295
+ return this._entries
296
+ .filter((e) => e.entryType === type)
297
+ .sort((a, b) => a.startTime - b.startTime);
298
+ }
299
+
300
+ // Resource timing (stubs for compatibility)
301
+ clearResourceTimings(): void {
302
+ // No-op in Exact (no resource timing)
303
+ }
304
+
305
+ setResourceTimingBufferSize(_maxSize: number): void {
306
+ // No-op in Exact
307
+ }
308
+
309
+ toJSON(): object {
310
+ return {
311
+ timeOrigin: this.timeOrigin,
312
+ };
313
+ }
314
+ }
315
+
316
+ // Mix in EventTarget methods on Performance.prototype so that
317
+ // `performance instanceof EventTarget` is true and addEventListener/
318
+ // dispatchEvent work correctly (per spec, Performance extends EventTarget).
319
+ // We do this as a mixin instead of class inheritance because Babel's
320
+ // ES5 transpilation of `class Performance extends EventTarget` doesn't
321
+ // properly set up the prototype chain when compiled to an IIFE for Hermes.
322
+ Object.setPrototypeOf(Performance.prototype, EventTarget.prototype);
323
+
324
+ // Create singleton
325
+ export const performance = new Performance();
326
+ // Initialize the EventTarget internal state on the singleton.
327
+ // We can't use EventTarget.call(performance) because Babel's _classCallCheck
328
+ // prevents calling a class constructor without `new`. Instead, directly
329
+ // initialize the internal _listeners Map that EventTarget expects.
330
+ (performance as any)._listeners = new Map();
331
+
332
+ // =============================================================================
333
+ // PerformanceObserver
334
+ // =============================================================================
335
+
336
+ export interface PerformanceObserverInit {
337
+ entryTypes?: string[];
338
+ type?: string;
339
+ buffered?: boolean;
340
+ }
341
+
342
+ export interface PerformanceObserverCallbackOptions {
343
+ droppedEntriesCount?: number;
344
+ }
345
+
346
+ export type PerformanceObserverCallback = (
347
+ entries: PerformanceObserverEntryList,
348
+ observer: PerformanceObserver,
349
+ options?: PerformanceObserverCallbackOptions
350
+ ) => void;
351
+
352
+ export class PerformanceObserverEntryList {
353
+ private _entries: PerformanceEntry[];
354
+
355
+ constructor(entries: PerformanceEntry[]) {
356
+ this._entries = entries;
357
+ }
358
+
359
+ getEntries(): PerformanceEntry[] {
360
+ return [...this._entries].sort((a, b) => a.startTime - b.startTime);
361
+ }
362
+
363
+ getEntriesByName(name: string, type?: string): PerformanceEntry[] {
364
+ return this._entries
365
+ .filter((e) => e.name === name && (!type || e.entryType === type))
366
+ .sort((a, b) => a.startTime - b.startTime);
367
+ }
368
+
369
+ getEntriesByType(type: string): PerformanceEntry[] {
370
+ return this._entries
371
+ .filter((e) => e.entryType === type)
372
+ .sort((a, b) => a.startTime - b.startTime);
373
+ }
374
+ }
375
+
376
+ // Store active observers
377
+ const observers = new Set<PerformanceObserver>();
378
+
379
+ /**
380
+ * PerformanceObserver enables observing performance timeline entries.
381
+ */
382
+ export class PerformanceObserver {
383
+ private _callback: PerformanceObserverCallback;
384
+ private _entryTypes: Set<string> = new Set();
385
+ private _buffer: PerformanceEntry[] = [];
386
+ private _isObserving = false;
387
+ private _scheduled = false;
388
+
389
+ /**
390
+ * Supported entry types.
391
+ */
392
+ static get supportedEntryTypes(): readonly string[] {
393
+ return Object.freeze(['mark', 'measure']);
394
+ }
395
+
396
+ constructor(callback: PerformanceObserverCallback) {
397
+ if (typeof callback !== 'function') {
398
+ throw new TypeError('Callback must be a function');
399
+ }
400
+ this._callback = callback;
401
+ }
402
+
403
+ /**
404
+ * Start observing performance entries.
405
+ */
406
+ observe(options: PerformanceObserverInit): void {
407
+ if (!options.entryTypes && !options.type) {
408
+ throw new TypeError('Either entryTypes or type must be specified');
409
+ }
410
+
411
+ if (options.entryTypes && options.type) {
412
+ throw new TypeError('Cannot specify both entryTypes and type');
413
+ }
414
+
415
+ this._entryTypes.clear();
416
+
417
+ if (options.entryTypes) {
418
+ for (let i = 0; i < options.entryTypes.length; i++) {
419
+ const type = options.entryTypes[i];
420
+ if (PerformanceObserver.supportedEntryTypes.includes(type)) {
421
+ this._entryTypes.add(type);
422
+ }
423
+ }
424
+ } else if (options.type) {
425
+ if (PerformanceObserver.supportedEntryTypes.includes(options.type)) {
426
+ this._entryTypes.add(options.type);
427
+ }
428
+ }
429
+
430
+ if (this._entryTypes.size === 0) {
431
+ // Per spec: if no supported entry types remain, silently return
432
+ return;
433
+ }
434
+
435
+ // If buffered, only works with single `type` API (not `entryTypes`)
436
+ if (options.buffered && options.type) {
437
+ const existingEntries: PerformanceEntry[] = [];
438
+ const timelineEntries = performance.getEntries();
439
+ for (let i = 0; i < timelineEntries.length; i++) {
440
+ const entry = timelineEntries[i];
441
+ if (this._entryTypes.has(entry.entryType)) {
442
+ existingEntries.push(entry);
443
+ }
444
+ }
445
+ if (existingEntries.length > 0) {
446
+ this._buffer.push(...existingEntries);
447
+ this._scheduleCallback();
448
+ }
449
+ }
450
+
451
+ this._isObserving = true;
452
+ observers.add(this);
453
+ }
454
+
455
+ /**
456
+ * Stop observing.
457
+ */
458
+ disconnect(): void {
459
+ this._isObserving = false;
460
+ this._buffer = [];
461
+ observers.delete(this);
462
+ }
463
+
464
+ /**
465
+ * Get buffered entries and clear the buffer.
466
+ */
467
+ takeRecords(): PerformanceEntry[] {
468
+ const entries = [...this._buffer];
469
+ this._buffer = [];
470
+ return entries;
471
+ }
472
+
473
+ /**
474
+ * Internal: Called when a new entry is added.
475
+ */
476
+ _notify(entry: PerformanceEntry): void {
477
+ if (!this._isObserving) return;
478
+ if (!this._entryTypes.has(entry.entryType)) return;
479
+
480
+ this._buffer.push(entry);
481
+ this._scheduleCallback();
482
+ }
483
+
484
+ private _scheduleCallback(): void {
485
+ if (this._scheduled) return;
486
+ this._scheduled = true;
487
+ const observer = this;
488
+
489
+ queueMicrotask(function() {
490
+ observer._scheduled = false;
491
+ if (observer._buffer.length === 0) return;
492
+
493
+ const entries = observer.takeRecords();
494
+ const list = new PerformanceObserverEntryList(entries);
495
+
496
+ try {
497
+ observer._callback(list, observer);
498
+ } catch (e) {
499
+ console.error('PerformanceObserver callback error:', e);
500
+ }
501
+ });
502
+ }
503
+ }
504
+
505
+ /**
506
+ * Notify all observers of a new entry.
507
+ * Called internally when marks/measures are created.
508
+ */
509
+ export function notifyObservers(entry: PerformanceEntry): void {
510
+ for (const observer of observers) {
511
+ observer._notify(entry);
512
+ }
513
+ }
514
+
515
+ // Patch Performance to notify observers
516
+ const originalMark = Performance.prototype.mark;
517
+ Performance.prototype.mark = function(markName: string, markOptions?: PerformanceMarkOptions): PerformanceMark {
518
+ const mark = originalMark.call(this, markName, markOptions);
519
+ notifyObservers(mark);
520
+ return mark;
521
+ };
522
+
523
+ const originalMeasure = Performance.prototype.measure;
524
+ Performance.prototype.measure = function(
525
+ measureName: string,
526
+ startOrMeasureOptions?: string | PerformanceMeasureOptions,
527
+ endMark?: string
528
+ ): PerformanceMeasure {
529
+ const measure = originalMeasure.call(this, measureName, startOrMeasureOptions, endMark);
530
+ notifyObservers(measure);
531
+ return measure;
532
+ };
@@ -0,0 +1,21 @@
1
+ export {
2
+ Performance,
3
+ PerformanceEntry,
4
+ PerformanceMark,
5
+ PerformanceMeasure,
6
+ PerformanceObserver,
7
+ PerformanceObserverEntryList,
8
+ performance,
9
+ setNativePerformanceModule,
10
+ notifyObservers,
11
+ } from "./Performance";
12
+
13
+ export type {
14
+ PerformanceModule,
15
+ PerformanceMarkOptions,
16
+ PerformanceMeasureOptions,
17
+ PerformanceEntryInit,
18
+ PerformanceObserverInit,
19
+ PerformanceObserverCallback,
20
+ PerformanceObserverCallbackOptions,
21
+ } from "./Performance";