|
1 | | -let timersArePatched = false; |
2 | | - |
3 | | -const globalSetTimeout = globalThis.setTimeout; |
4 | | -const globalClearTimeout = globalThis.clearTimeout; |
5 | | -const globalSetInterval = globalThis.setInterval; |
6 | | -const globalClearInterval = globalThis.clearInterval; |
7 | | - |
8 | | -/** @type {Map<NodeJS.Timeout|number|string, string>} */ |
9 | | -const timeoutIds = new Map(); |
10 | | -/** @type {Set<NodeJS.Timeout|number|string>} */ |
11 | | -const intervalIds = new Set(); |
12 | | - |
13 | 1 | /** |
14 | 2 | * @param {number} delay |
15 | 3 | * @returns {Promise<void>} |
16 | 4 | */ |
17 | 5 | export function sleep(delay) { |
18 | 6 | return new Promise((resolve) => { |
19 | | - globalSetTimeout(resolve, delay); |
| 7 | + setTimeout(resolve, delay); |
20 | 8 | }); |
21 | 9 | } |
22 | | - |
23 | | -export function patchTimers() { |
24 | | - if (timersArePatched) { |
25 | | - return; |
26 | | - } |
27 | | - |
28 | | - timersArePatched = true; |
29 | | - |
30 | | - timeoutIds.clear(); |
31 | | - intervalIds.clear(); |
32 | | - |
33 | | - // @ts-ignore |
34 | | - globalThis.setTimeout = (callback, delay) => { |
35 | | - // Not sure why but some tests had a residual setTimeout of one second at the end |
36 | | - // We can ignore those |
37 | | - if (isCallInsidePath('node:internal/deps/undici')) { |
38 | | - return globalSetTimeout(callback, delay); |
39 | | - } |
40 | | - |
41 | | - const id = globalSetTimeout(() => { |
42 | | - timeoutIds.delete(id); |
43 | | - return callback(); |
44 | | - }, delay); |
45 | | - timeoutIds.set(id, callback.toString()); |
46 | | - return id; |
47 | | - }; |
48 | | - |
49 | | - globalThis.clearTimeout = (id) => { |
50 | | - timeoutIds.delete(id); |
51 | | - return globalClearTimeout(id); |
52 | | - }; |
53 | | - |
54 | | - // @ts-ignore |
55 | | - globalThis.setInterval = (callback, delay) => { |
56 | | - const id = globalSetInterval(() => { |
57 | | - return callback(); |
58 | | - }, delay); |
59 | | - intervalIds.add(id); |
60 | | - return id; |
61 | | - }; |
62 | | - |
63 | | - globalThis.clearInterval = (id) => { |
64 | | - intervalIds.delete(id); |
65 | | - return globalClearInterval(id); |
66 | | - }; |
67 | | -} |
68 | | - |
69 | | -/** |
70 | | - * @param {string} path |
71 | | - * @returns {boolean} |
72 | | - */ |
73 | | -function isCallInsidePath(path) { |
74 | | - const err = new Error(); |
75 | | - const stackLines = err.stack.split('\n'); |
76 | | - return stackLines.some((line) => line.includes(path)); |
77 | | -} |
78 | | - |
79 | | -export function clearTimers() { |
80 | | - if (!timersArePatched) { |
81 | | - return; |
82 | | - } |
83 | | - |
84 | | - const timeoutsCount = timeoutIds.size; |
85 | | - const intervalsCount = intervalIds.size; |
86 | | - |
87 | | - if (timeoutsCount > 0 || intervalsCount > 0) { |
88 | | - for (const id of timeoutIds) { |
89 | | - // @ts-ignore |
90 | | - globalClearTimeout(id); |
91 | | - } |
92 | | - timeoutIds.clear(); |
93 | | - |
94 | | - for (const id of intervalIds) { |
95 | | - globalClearInterval(id); |
96 | | - } |
97 | | - intervalIds.clear(); |
98 | | - |
99 | | - throw new Error( |
100 | | - `Some timers were not cleared properly (timeouts: ${timeoutsCount} / intervals: ${intervalsCount})`, |
101 | | - ); |
102 | | - } |
103 | | -} |
104 | | - |
105 | | -export function unpatchTimers() { |
106 | | - if (!timersArePatched) { |
107 | | - return; |
108 | | - } |
109 | | - |
110 | | - timersArePatched = false; |
111 | | - |
112 | | - globalThis.setTimeout = globalSetTimeout; |
113 | | - globalThis.clearTimeout = globalClearTimeout; |
114 | | - globalThis.setInterval = globalSetInterval; |
115 | | - globalThis.clearInterval = globalClearInterval; |
116 | | -} |
0 commit comments