* Attempt refresh, respecting pause conditions.
(options?: {
bypassPause?: boolean;
bypassHidden?: boolean;
bypassMinInterval?: boolean;
trigger?: RefreshTrigger;
})
| 239 | * Attempt refresh, respecting pause conditions. |
| 240 | */ |
| 241 | private tryRefresh(options?: { |
| 242 | bypassPause?: boolean; |
| 243 | bypassHidden?: boolean; |
| 244 | bypassMinInterval?: boolean; |
| 245 | trigger?: RefreshTrigger; |
| 246 | }): void { |
| 247 | if (this.disposed) return; |
| 248 | |
| 249 | const trigger = options?.trigger ?? this.pendingTrigger ?? "scheduled"; |
| 250 | const bypassHidden = (options?.bypassHidden ?? false) || trigger === "manual"; |
| 251 | const bypassPause = (options?.bypassPause ?? false) || trigger === "manual"; |
| 252 | const bypassMinInterval = (options?.bypassMinInterval ?? false) || trigger === "manual"; |
| 253 | |
| 254 | // Hidden → queue for visibility (unless bypassed) |
| 255 | if (!bypassHidden && typeof document !== "undefined" && document.hidden) { |
| 256 | this.pendingBecauseHidden = true; |
| 257 | this.updatePendingTrigger(trigger); |
| 258 | return; |
| 259 | } |
| 260 | |
| 261 | // Custom pause (e.g., user interacting) → queue for unpause |
| 262 | // Bypassed for manual refresh (user explicitly requested) |
| 263 | if (!bypassPause && this.isPaused?.()) { |
| 264 | this.pendingBecausePaused = true; |
| 265 | this.updatePendingTrigger(trigger); |
| 266 | return; |
| 267 | } |
| 268 | |
| 269 | // In-flight → queue for completion |
| 270 | if (this.inFlight) { |
| 271 | this.pendingBecauseInFlight = true; |
| 272 | this.updatePendingTrigger(trigger); |
| 273 | return; |
| 274 | } |
| 275 | |
| 276 | // Hard guard: enforce minimum interval between refresh starts. |
| 277 | // Rather than dropping the request, schedule it for the earliest allowed time. |
| 278 | // Bypassed for manual refresh (user/component explicitly requested). |
| 279 | if (!bypassMinInterval && this.lastRefreshStartMs > 0) { |
| 280 | const now = Date.now(); |
| 281 | const elapsed = now - this.lastRefreshStartMs; |
| 282 | if (elapsed < MIN_REFRESH_INTERVAL_MS) { |
| 283 | this.updatePendingTrigger(trigger); |
| 284 | |
| 285 | if (this.cooldownTimer) { |
| 286 | this.debug("cooldown timer running, coalescing"); |
| 287 | return; |
| 288 | } |
| 289 | |
| 290 | const delayMs = MIN_REFRESH_INTERVAL_MS - elapsed; |
| 291 | const t = this.pendingTrigger ?? trigger; |
| 292 | this.debug(`cooldown: delaying ${delayMs}ms (${t})`); |
| 293 | |
| 294 | this.cooldownTimer = setTimeout(() => { |
| 295 | this.cooldownTimer = null; |
| 296 | const cooldownTrigger = this.pendingTrigger ?? t; |
| 297 | this.pendingTrigger = null; |
| 298 | this.tryRefresh({ trigger: cooldownTrigger }); |
no test coverage detected