(options?: { readonly immediate?: boolean })
| 2243 | }; |
| 2244 | |
| 2245 | const scheduleFlush = (options?: { readonly immediate?: boolean }): void => { |
| 2246 | if (disposed) return; |
| 2247 | if (flushScheduled && !options?.immediate) return; |
| 2248 | |
| 2249 | // Cancel any previous schedule so we coalesce to exactly one pending flush. |
| 2250 | if (flushRafId !== null) { |
| 2251 | cancelAnimationFrame(flushRafId); |
| 2252 | flushRafId = null; |
| 2253 | } |
| 2254 | if (flushTimeoutId !== null) { |
| 2255 | clearTimeout(flushTimeoutId); |
| 2256 | flushTimeoutId = null; |
| 2257 | } |
| 2258 | |
| 2259 | flushScheduled = true; |
| 2260 | |
| 2261 | flushRafId = requestAnimationFrame(() => { |
| 2262 | flushRafId = null; |
| 2263 | if (disposed) { |
| 2264 | cancelScheduledFlush(); |
| 2265 | return; |
| 2266 | } |
| 2267 | // rAF fired first: cancel the fallback timeout. |
| 2268 | if (flushTimeoutId !== null) { |
| 2269 | clearTimeout(flushTimeoutId); |
| 2270 | flushTimeoutId = null; |
| 2271 | } |
| 2272 | flushScheduled = false; |
| 2273 | executeFlush(); |
| 2274 | }); |
| 2275 | |
| 2276 | // Fallback: ensure we flush even if rAF is delayed (high-frequency streams > 60Hz). |
| 2277 | flushTimeoutId = (typeof self !== 'undefined' ? self : window).setTimeout(() => { |
| 2278 | if (disposed) { |
| 2279 | cancelScheduledFlush(); |
| 2280 | return; |
| 2281 | } |
| 2282 | if (!flushScheduled) return; |
| 2283 | |
| 2284 | if (flushRafId !== null) { |
| 2285 | cancelAnimationFrame(flushRafId); |
| 2286 | flushRafId = null; |
| 2287 | } |
| 2288 | flushScheduled = false; |
| 2289 | flushTimeoutId = null; |
| 2290 | executeFlush(); |
| 2291 | }, 16); |
| 2292 | }; |
| 2293 | |
| 2294 | const scheduleZoomResample = (): void => { |
| 2295 | if (disposed) return; |
no test coverage detected