@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,464 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * Promise Rejection Tracking
4
+ *
5
+ * Provides `unhandledrejection` and `rejectionhandled` event dispatch on globalThis.
6
+ *
7
+ * Strategy:
8
+ * 1. If the native bridge exposes `__exactOnUnhandledRejection`, use it directly.
9
+ * 2. Otherwise, install a userland polyfill that:
10
+ * a. Wraps `Promise.prototype.then` to track which promises have rejection handlers.
11
+ * b. Uses a Map to track unhandled rejections.
12
+ * c. Uses `queueMicrotask` to defer detection until after synchronous handler attachment.
13
+ * d. Dispatches `unhandledrejection` on globalThis when a rejection is unhandled.
14
+ * e. Dispatches `rejectionhandled` when a previously-unhandled rejection gets a handler.
15
+ *
16
+ * @see https://html.spec.whatwg.org/multipage/webappapis.html#unhandled-promise-rejections
17
+ */
18
+
19
+ import { EventTarget } from "./events/EventTarget";
20
+ import { PromiseRejectionEvent } from "./events/PromiseRejectionEvent";
21
+
22
+ /**
23
+ * Map of currently-unhandled rejections: Promise -> reason.
24
+ * Exposed for testing purposes.
25
+ */
26
+ const _unhandledRejections: Map<Promise<any>, any> = new Map();
27
+
28
+ /**
29
+ * Internal EventTarget used to dispatch promise rejection events.
30
+ * We always use our own EventTarget instance to ensure compatibility with
31
+ * our custom Event classes (avoids issues with native EventTarget implementations
32
+ * in environments like Bun/Node that reject non-native Event subclasses).
33
+ */
34
+ let _eventTarget: EventTarget | null = null;
35
+
36
+ /**
37
+ * Whether globalThis.addEventListener has been wrapped to intercept
38
+ * unhandledrejection/rejectionhandled listeners.
39
+ */
40
+ let _globalListenersInstalled = false;
41
+
42
+ /**
43
+ * Promise rejection event types that we intercept.
44
+ */
45
+ const REJECTION_EVENT_TYPES = new Set(['unhandledrejection', 'rejectionhandled']);
46
+ const trailingDataErrorSymbol = Symbol.for("__exact.decompression.trailing-data-error");
47
+ const _synchronouslyHandledPromises = new WeakSet<Promise<any>>();
48
+ let _nativeHandledTrackingInstalled = false;
49
+
50
+ /**
51
+ * Get or create the internal EventTarget for promise rejection events.
52
+ */
53
+ function getEventTarget(): EventTarget {
54
+ if (_eventTarget) return _eventTarget;
55
+ _eventTarget = new EventTarget();
56
+ return _eventTarget;
57
+ }
58
+
59
+ /**
60
+ * Install interception of addEventListener/removeEventListener on globalThis
61
+ * so that listeners for 'unhandledrejection' and 'rejectionhandled' are
62
+ * forwarded to our internal EventTarget.
63
+ */
64
+ function installGlobalListenerForwarding(): void {
65
+ if (_globalListenersInstalled) return;
66
+ _globalListenersInstalled = true;
67
+
68
+ const g = globalThis as any;
69
+ const et = getEventTarget();
70
+
71
+ const origAddEventListener = g.addEventListener;
72
+ const origRemoveEventListener = g.removeEventListener;
73
+
74
+ if (typeof origAddEventListener === 'function') {
75
+ // Wrap existing addEventListener to intercept rejection events
76
+ g.addEventListener = function wrappedAddEventListener(
77
+ type: string,
78
+ callback: any,
79
+ options?: any
80
+ ): void {
81
+ if (REJECTION_EVENT_TYPES.has(type)) {
82
+ et.addEventListener(type, callback, options);
83
+ } else {
84
+ origAddEventListener.call(this, type, callback, options);
85
+ }
86
+ };
87
+ } else {
88
+ // No existing addEventListener, install ours directly
89
+ g.addEventListener = et.addEventListener.bind(et);
90
+ }
91
+
92
+ if (typeof origRemoveEventListener === 'function') {
93
+ g.removeEventListener = function wrappedRemoveEventListener(
94
+ type: string,
95
+ callback: any,
96
+ options?: any
97
+ ): void {
98
+ if (REJECTION_EVENT_TYPES.has(type)) {
99
+ et.removeEventListener(type, callback, options);
100
+ } else {
101
+ origRemoveEventListener.call(this, type, callback, options);
102
+ }
103
+ };
104
+ } else {
105
+ g.removeEventListener = et.removeEventListener.bind(et);
106
+ }
107
+
108
+ if (typeof g.dispatchEvent !== 'function') {
109
+ g.dispatchEvent = et.dispatchEvent.bind(et);
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Track a promise rejection. Called when a promise is rejected without a handler.
115
+ * After a microtask, if no handler has been attached, dispatches `unhandledrejection`.
116
+ */
117
+ export function trackPromiseRejection(promise: Promise<any>, reason: any): void {
118
+ if (_synchronouslyHandledPromises.has(promise)) {
119
+ return;
120
+ }
121
+
122
+ const suppressUnhandledRejection = (globalThis as any).__exactShouldSuppressUnhandledRejection;
123
+ if (typeof suppressUnhandledRejection === "function") {
124
+ try {
125
+ if (suppressUnhandledRejection(reason, promise)) {
126
+ return;
127
+ }
128
+ } catch (_) {}
129
+ }
130
+
131
+ if (reason && reason[trailingDataErrorSymbol]) {
132
+ return;
133
+ }
134
+
135
+ _unhandledRejections.set(promise, reason);
136
+
137
+ // Defer the check to after the current microtask queue drains,
138
+ // giving synchronous .catch() calls a chance to attach.
139
+ queueMicrotask(() => {
140
+ if (!_unhandledRejections.has(promise)) {
141
+ // Handler was attached synchronously -- nothing to report
142
+ return;
143
+ }
144
+
145
+ const target = getEventTarget();
146
+ const event = new PromiseRejectionEvent('unhandledrejection', {
147
+ promise,
148
+ reason,
149
+ cancelable: true,
150
+ });
151
+
152
+ const notPrevented = target.dispatchEvent(event);
153
+
154
+ if (notPrevented) {
155
+ // Default behavior: log the unhandled rejection to console
156
+ // (browsers typically report to console unless preventDefault is called)
157
+ console.error('Unhandled promise rejection:', reason);
158
+ }
159
+ });
160
+ }
161
+
162
+ function installNativeHandledPromiseTracking(OriginalPromise: PromiseConstructor): void {
163
+ if (_nativeHandledTrackingInstalled) return;
164
+ _nativeHandledTrackingInstalled = true;
165
+
166
+ const originalThen = OriginalPromise.prototype.then;
167
+ const originalCatch = OriginalPromise.prototype.catch;
168
+ const originalFinally = OriginalPromise.prototype.finally;
169
+
170
+ function markHandled(promise: Promise<any>): void {
171
+ _synchronouslyHandledPromises.add(promise);
172
+ if (_unhandledRejections.has(promise)) {
173
+ trackPromiseRejectionHandled(promise);
174
+ }
175
+ }
176
+
177
+ OriginalPromise.prototype.then = function wrappedThen(
178
+ onFulfilled?: any,
179
+ onRejected?: any
180
+ ): Promise<any> {
181
+ if (this && (typeof this === 'object' || typeof this === 'function')) {
182
+ markHandled(this as Promise<any>);
183
+ }
184
+ return originalThen.call(this, onFulfilled, onRejected);
185
+ };
186
+
187
+ OriginalPromise.prototype.catch = function wrappedCatch(
188
+ onRejected?: any
189
+ ): Promise<any> {
190
+ if (typeof onRejected === 'function' && this && (typeof this === 'object' || typeof this === 'function')) {
191
+ markHandled(this as Promise<any>);
192
+ }
193
+ return originalCatch.call(this, onRejected);
194
+ };
195
+
196
+ if (typeof originalFinally === 'function') {
197
+ OriginalPromise.prototype.finally = function wrappedFinally(
198
+ onFinally?: any
199
+ ): Promise<any> {
200
+ if (this && (typeof this === 'object' || typeof this === 'function')) {
201
+ markHandled(this as Promise<any>);
202
+ }
203
+ return originalFinally.call(this, onFinally);
204
+ };
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Track that a previously-unhandled promise rejection has been handled.
210
+ * Dispatches `rejectionhandled` on globalThis.
211
+ */
212
+ export function trackPromiseRejectionHandled(promise: Promise<any>): void {
213
+ const reason = _unhandledRejections.get(promise);
214
+ if (!_unhandledRejections.has(promise)) {
215
+ return;
216
+ }
217
+
218
+ _unhandledRejections.delete(promise);
219
+
220
+ // Dispatch rejectionhandled asynchronously (per spec, fires in a later task)
221
+ queueMicrotask(() => {
222
+ const target = getEventTarget();
223
+ const event = new PromiseRejectionEvent('rejectionhandled', {
224
+ promise,
225
+ reason,
226
+ cancelable: false,
227
+ });
228
+
229
+ target.dispatchEvent(event);
230
+ });
231
+ }
232
+
233
+ /**
234
+ * Install promise rejection tracking on the global Promise.
235
+ *
236
+ * This wraps Promise.prototype.then to intercept rejection handler attachment
237
+ * and hooks into the Promise constructor to detect unhandled rejections.
238
+ */
239
+ export function installPromiseRejectionTracking(): void {
240
+ const g = globalThis as any;
241
+
242
+ // Set up event listener forwarding on globalThis
243
+ installGlobalListenerForwarding();
244
+
245
+ const OriginalPromise = g.Promise;
246
+
247
+ // If native bridge provides promise rejection hooks, use those
248
+ if (typeof g.__exactOnUnhandledRejection === 'function') {
249
+ installNativeHandledPromiseTracking(OriginalPromise);
250
+ g.__exactOnUnhandledRejection((promise: Promise<any>, reason: any) => {
251
+ trackPromiseRejection(promise, reason);
252
+ });
253
+ if (typeof g.__exactOnRejectionHandled === 'function') {
254
+ g.__exactOnRejectionHandled((promise: Promise<any>) => {
255
+ trackPromiseRejectionHandled(promise);
256
+ });
257
+ }
258
+ return;
259
+ }
260
+
261
+ // Polyfill approach: wrap Promise.prototype.then to detect handler attachment
262
+ // and wrap the Promise constructor to detect rejections without handlers.
263
+ const originalThen = OriginalPromise.prototype.then;
264
+ const originalCatch = OriginalPromise.prototype.catch;
265
+
266
+ // WeakSet to track promises that have had rejection handlers attached
267
+ const _handledPromises = new WeakSet<Promise<any>>();
268
+ // WeakSet to track promises that have been reported as rejected
269
+ const _rejectedPromises = new WeakSet<Promise<any>>();
270
+ // WeakMap to map child promises back to parent for handler tracking
271
+ const _promiseParents = new WeakMap<Promise<any>, Promise<any>>();
272
+
273
+ /**
274
+ * Mark a promise (and its ancestor chain) as handled.
275
+ */
276
+ function markHandled(promise: Promise<any>): void {
277
+ let current: unknown = promise;
278
+ while (current && (typeof current === 'object' || typeof current === 'function')) {
279
+ if (_handledPromises.has(current)) break;
280
+ _handledPromises.add(current);
281
+
282
+ // If this promise was in the unhandled set, dispatch rejectionhandled
283
+ if (_rejectedPromises.has(current)) {
284
+ _rejectedPromises.delete(current);
285
+ trackPromiseRejectionHandled(current);
286
+ }
287
+
288
+ current = _promiseParents.get(current);
289
+ }
290
+ }
291
+
292
+ /**
293
+ * Wrapped .then() that tracks rejection handler attachment.
294
+ */
295
+ OriginalPromise.prototype.then = function wrappedThen(
296
+ onFulfilled?: any,
297
+ onRejected?: any
298
+ ): Promise<any> {
299
+ const child = originalThen.call(this, onFulfilled, onRejected);
300
+
301
+ // Track the parent-child relationship
302
+ if (child && (typeof child === 'object' || typeof child === 'function')) {
303
+ _promiseParents.set(child, this);
304
+ }
305
+
306
+ // If a rejection handler is provided, mark the promise as handled
307
+ if (typeof onRejected === 'function' && this && (typeof this === 'object' || typeof this === 'function')) {
308
+ markHandled(this);
309
+ }
310
+
311
+ return child;
312
+ };
313
+
314
+ /**
315
+ * Wrapped .catch() that tracks rejection handler attachment.
316
+ */
317
+ OriginalPromise.prototype.catch = function wrappedCatch(
318
+ onRejected?: any
319
+ ): Promise<any> {
320
+ const child = originalCatch.call(this, onRejected);
321
+
322
+ // Track the parent-child relationship
323
+ if (child && (typeof child === 'object' || typeof child === 'function')) {
324
+ _promiseParents.set(child, this);
325
+ }
326
+
327
+ // A .catch() always provides a rejection handler
328
+ if (typeof onRejected === 'function' && this && (typeof this === 'object' || typeof this === 'function')) {
329
+ markHandled(this);
330
+ }
331
+
332
+ return child;
333
+ };
334
+
335
+ // Preserve .finally if it exists
336
+ const originalFinally = OriginalPromise.prototype.finally;
337
+ if (originalFinally) {
338
+ OriginalPromise.prototype.finally = function wrappedFinally(
339
+ onFinally?: any
340
+ ): Promise<any> {
341
+ const child = originalFinally.call(this, onFinally);
342
+ if (child && (typeof child === 'object' || typeof child === 'function')) {
343
+ _promiseParents.set(child, this);
344
+ }
345
+ return child;
346
+ };
347
+ }
348
+
349
+ /**
350
+ * Create a wrapper around Promise.reject to detect immediate rejections.
351
+ */
352
+ const originalReject = OriginalPromise.reject;
353
+ OriginalPromise.reject = function wrappedReject(reason?: any): Promise<any> {
354
+ const promise = originalReject.call(this, reason);
355
+ if (promise && (typeof promise === 'object' || typeof promise === 'function')) {
356
+ _rejectedPromises.add(promise);
357
+ }
358
+
359
+ // Schedule a microtask to check if a handler was attached
360
+ queueMicrotask(() => {
361
+ if (promise && (typeof promise === 'object' || typeof promise === 'function') && !_handledPromises.has(promise)) {
362
+ trackPromiseRejection(promise, reason);
363
+ }
364
+ });
365
+
366
+ return promise;
367
+ };
368
+
369
+ /**
370
+ * Wrap the Promise constructor to detect rejections in executor functions.
371
+ */
372
+ const ExactPromise = function ExactPromise(
373
+ this: any,
374
+ executor: (
375
+ resolve: (value?: any) => void,
376
+ reject: (reason?: any) => void
377
+ ) => void
378
+ ): Promise<any> {
379
+ let promiseRef: Promise<any> | null = null;
380
+ let pendingReject: any = null;
381
+
382
+ const wrappedExecutor = (
383
+ resolve: (value?: any) => void,
384
+ reject: (reason?: any) => void
385
+ ) => {
386
+ const wrappedReject = (reason?: any) => {
387
+ if (promiseRef && (typeof promiseRef === 'object' || typeof promiseRef === 'function')) {
388
+ _rejectedPromises.add(promiseRef);
389
+ queueMicrotask(() => {
390
+ if (!_handledPromises.has(promiseRef as any)) {
391
+ trackPromiseRejection(promiseRef as any, reason);
392
+ }
393
+ });
394
+ } else {
395
+ pendingReject = reason;
396
+ }
397
+
398
+ return reject(reason);
399
+ };
400
+
401
+ return executor(resolve, wrappedReject);
402
+ };
403
+
404
+ const promise = new OriginalPromise(wrappedExecutor);
405
+ promiseRef = promise;
406
+ if (pendingReject !== null) {
407
+ const reason = pendingReject;
408
+ pendingReject = null;
409
+ _rejectedPromises.add(promiseRef);
410
+ queueMicrotask(() => {
411
+ if (!_handledPromises.has(promiseRef as any)) {
412
+ trackPromiseRejection(promiseRef as any, reason);
413
+ }
414
+ });
415
+ }
416
+
417
+ return promise;
418
+ } as any;
419
+
420
+ // Copy static methods and properties
421
+ const bindStatic = (name: string): void => {
422
+ const value = (OriginalPromise as any)[name];
423
+ if (typeof value === 'function') {
424
+ ExactPromise[name] = value.bind(OriginalPromise);
425
+ }
426
+ };
427
+
428
+ bindStatic('resolve');
429
+ ExactPromise.reject = OriginalPromise.reject; // Already wrapped above
430
+ bindStatic('all');
431
+ bindStatic('allSettled');
432
+ bindStatic('race');
433
+ bindStatic('any');
434
+ bindStatic('withResolvers');
435
+ ExactPromise.prototype = OriginalPromise.prototype;
436
+ ExactPromise[Symbol.species] = OriginalPromise;
437
+
438
+ // Make instanceof checks work
439
+ Object.defineProperty(ExactPromise, Symbol.hasInstance, {
440
+ value: (instance: any) => instance instanceof OriginalPromise,
441
+ });
442
+
443
+ // Install as the global Promise
444
+ g.Promise = ExactPromise;
445
+
446
+ // Store original for internal use
447
+ g.__OriginalPromise = OriginalPromise;
448
+ }
449
+
450
+ /**
451
+ * Get the current set of unhandled rejections (for testing).
452
+ */
453
+ export function getUnhandledRejections(): Map<Promise<any>, any> {
454
+ return _unhandledRejections;
455
+ }
456
+
457
+ /**
458
+ * Reset tracking state (for testing).
459
+ */
460
+ export function resetPromiseRejectionTracking(): void {
461
+ _unhandledRejections.clear();
462
+ _eventTarget = null;
463
+ _globalListenersInstalled = false;
464
+ }