Poll until `predicate` returns true or `timeoutMs` elapses.
(
predicate: () => T | null | undefined | false,
opts: { timeoutMs?: number; intervalMs?: number; label?: string } = {},
)
| 300 | |
| 301 | /** Poll until `predicate` returns true or `timeoutMs` elapses. */ |
| 302 | async waitFor<T>( |
| 303 | predicate: () => T | null | undefined | false, |
| 304 | opts: { timeoutMs?: number; intervalMs?: number; label?: string } = {}, |
| 305 | ): Promise<T> { |
| 306 | // Default bumped from 10s → 60s for CI. waitFor is called by tests |
| 307 | // to poll for DB rows / queued ops to appear; on CI shared runners |
| 308 | // there can be material latency between an event firing and the |
| 309 | // SQLite row being visible. Individual tests can still pass a |
| 310 | // smaller timeoutMs. |
| 311 | const timeoutMs = opts.timeoutMs ?? 60_000; |
| 312 | const intervalMs = opts.intervalMs ?? 100; |
| 313 | const deadline = Date.now() + timeoutMs; |
| 314 | while (Date.now() < deadline) { |
| 315 | const value = predicate(); |
| 316 | if (value) return value as T; |
| 317 | await Bun.sleep(intervalMs); |
| 318 | } |
| 319 | throw new Error( |
| 320 | `waitFor timed out after ${timeoutMs}ms${opts.label ? ` (${opts.label})` : ""}`, |
| 321 | ); |
| 322 | } |
| 323 | |
| 324 | /** |
| 325 | * Count compartments for a session. Returns 0 if the table is empty or missing. |
no outgoing calls