Skip to content

Use standard Window interface for idle callbacks#227

Open
ysdede wants to merge 1 commit intomasterfrom
fix-idle-callbacks-5515221070947143723
Open

Use standard Window interface for idle callbacks#227
ysdede wants to merge 1 commit intomasterfrom
fix-idle-callbacks-5515221070947143723

Conversation

@ysdede
Copy link
Copy Markdown
Owner

@ysdede ysdede commented Mar 22, 2026

🎯 What: Extended the global Window interface to include proper TypeScript definitions for requestIdleCallback and cancelIdleCallback instead of casting window to any.
💡 Why: Reduces unsafe any usages and correctly utilizes native browser APIs, improving type safety and readability.
Verification: Ran test suite and production build step.
Result: Safe typing applied to idle callbacks.


PR created automatically by Jules for task 5515221070947143723 started by @ysdede

Summary by Sourcery

Strengthen typing around browser idle callbacks and remove unsafe window casts.

Enhancements:

  • Extend the global Window interface with typed requestIdleCallback and cancelIdleCallback definitions.
  • Replace any-casted window idle callback usage in the WASM warmup scheduling logic with the now-typed Window methods.

@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 22, 2026

Warning

Rate limit exceeded

@ysdede has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 25 minutes and 5 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d3e750f7-f76f-40d6-a5fe-587de60230fa

📥 Commits

Reviewing files that changed from the base of the PR and between 474dbe6 and a3e6570.

📒 Files selected for processing (2)
  • src/App.tsx
  • src/vite-env.d.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-idle-callbacks-5515221070947143723

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review
Copy link
Copy Markdown

ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan

Review Summary by Qodo

Add proper TypeScript types for idle callback APIs

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Added TypeScript definitions for requestIdleCallback and cancelIdleCallback to Window
  interface
• Removed unsafe any type casts in idle callback usage
• Improved type safety for browser idle scheduling APIs
Diagram
flowchart LR
  A["vite-env.d.ts<br/>Window interface"] -- "defines types" --> B["requestIdleCallback<br/>cancelIdleCallback"]
  B -- "used by" --> C["App.tsx<br/>Idle callback handlers"]
  C -- "removes" --> D["any type casts"]
Loading

Grey Divider

File Changes

1. src/vite-env.d.ts ✨ Enhancement +11/-0

Define Window interface for idle callbacks

• Added Window interface extension with requestIdleCallback method signature
• Added cancelIdleCallback method signature to Window interface
• Defined proper TypeScript types for idle callback deadline object and options parameter

src/vite-env.d.ts


2. src/App.tsx 🐞 Bug fix +2/-2

Remove any casts from idle callback usage

• Removed (window as any) cast from cancelIdleCallback call
• Removed (window as any) cast from requestIdleCallback call
• Leverages new Window interface definitions for type safety

src/App.tsx


Grey Divider

Qodo Logo

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the application's type safety and code clarity by introducing explicit TypeScript definitions for the requestIdleCallback and cancelIdleCallback methods on the global Window interface. This change allows for direct, type-checked calls to these browser APIs, removing previous any type assertions and improving maintainability.

Highlights

  • Type Safety Improvement: Eliminated (window as any) type assertions for requestIdleCallback and cancelIdleCallback by providing proper TypeScript definitions.
  • Native API Utilization: Ensured correct and type-safe usage of native browser requestIdleCallback and cancelIdleCallback APIs.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review bot commented Mar 22, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 📐 Spec deviations (0)

Grey Divider


Action required

1. Idle callbacks typed required 🐞 Bug ✓ Correctness
Description
src/vite-env.d.ts makes requestIdleCallback/cancelIdleCallback mandatory on Window, even
though the app treats them as optional at runtime (feature-detects before calling). This weakens
type safety by allowing other call sites to call these APIs without checks and still compile,
potentially crashing at runtime in environments that don’t implement them.
Code

src/vite-env.d.ts[R8-17]

+interface Window {
+  requestIdleCallback(
+    callback: (deadline: {
+      readonly didTimeout: boolean;
+      timeRemaining(): number;
+    }) => void,
+    options?: { timeout: number }
+  ): number;
+  cancelIdleCallback(handle: number): void;
+}
Evidence
The new global Window augmentation declares both methods as always present, but App.tsx still
performs explicit runtime feature detection ('requestIdleCallback' in window /
'cancelIdleCallback' in window) before calling them, demonstrating they are not guaranteed to
exist at runtime. With the new required typings, TypeScript will no longer help enforce those checks
anywhere else in the codebase.

src/vite-env.d.ts[8-17]
src/App.tsx[486-526]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`Window.requestIdleCallback` and `Window.cancelIdleCallback` are declared as required in `src/vite-env.d.ts`, but the runtime code still feature-detects them. This makes the type system claim the APIs always exist and can let other call sites compile without guards, risking runtime `TypeError` in non-supporting environments.

## Issue Context
The current warmup logic already uses feature detection before calling idle callbacks.

## Fix Focus Areas
- Make the augmented properties optional (e.g., `requestIdleCallback?: ...`, `cancelIdleCallback?: ...`) to reflect runtime variability.
- Update call sites to narrow with `typeof window.requestIdleCallback === &#x27;function&#x27;` / `typeof window.cancelIdleCallback === &#x27;function&#x27;` (or keep existing guards and use non-null assertion after narrowing).

### Target locations
- src/vite-env.d.ts[8-17]
- src/App.tsx[486-526]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Timeout option too strict 🐞 Bug ⚙ Maintainability
Description
The added requestIdleCallback typing requires timeout whenever an options object is provided
(options?: { timeout: number }). This is stricter than the API behavior and will reject valid
usage like requestIdleCallback(cb, {}) or options objects with timeout omitted.
Code

src/vite-env.d.ts[R9-15]

+  requestIdleCallback(
+    callback: (deadline: {
+      readonly didTimeout: boolean;
+      timeRemaining(): number;
+    }) => void,
+    options?: { timeout: number }
+  ): number;
Evidence
The PR’s ambient type explicitly requires timeout inside the options object. This is an
unnecessary restriction that will cause TS errors for otherwise valid call patterns; the only
current call site happens to pass { timeout: 2500 }, so the issue is latent but real for future
usage.

src/vite-env.d.ts[9-15]
src/App.tsx[518-525]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The ambient type for `requestIdleCallback` currently requires `timeout` whenever `options` is supplied. This is overly strict and will reject valid usages.

## Issue Context
Current code passes `{ timeout: 2500 }`, but the typing should match the broader API contract.

## Fix Focus Areas
- Change `options?: { timeout: number }` to `options?: { timeout?: number }`.
- (Optional) Consider using standard DOM type names if available (`IdleRequestOptions`, `IdleDeadline`, `IdleRequestCallback`) or define compatible local ambient types.

### Target locations
- src/vite-env.d.ts[9-15]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • Since you already guard usage with 'requestIdleCallback' in window, consider marking requestIdleCallback and cancelIdleCallback as optional on the Window interface to better reflect that they may not exist in all environments.
  • The options parameter for requestIdleCallback should likely use timeout?: number rather than timeout: number to match the browser API, which treats timeout as optional.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Since you already guard usage with `'requestIdleCallback' in window`, consider marking `requestIdleCallback` and `cancelIdleCallback` as optional on the `Window` interface to better reflect that they may not exist in all environments.
- The `options` parameter for `requestIdleCallback` should likely use `timeout?: number` rather than `timeout: number` to match the browser API, which treats `timeout` as optional.

## Individual Comments

### Comment 1
<location path="src/vite-env.d.ts" line_range="9-15" />
<code_context>
+      readonly didTimeout: boolean;
+      timeRemaining(): number;
+    }) => void,
+    options?: { timeout: number }
+  ): number;
+  cancelIdleCallback(handle: number): void;
</code_context>
<issue_to_address>
**suggestion:** Align the `timeout` option shape with the standard `IdleRequestOptions` to avoid unnecessary type friction.

The DOM `requestIdleCallback` uses `IdleRequestOptions` with an optional `timeout?: number`, but this overload makes `timeout` required whenever `options` is passed, which is stricter than the platform API and rejects valid calls like `requestIdleCallback(cb, {})`. Please make `timeout` optional (e.g., `options?: { timeout?: number }` or reuse `IdleRequestOptions`) to keep the signature compatible with the standard.

```suggestion
  requestIdleCallback(
    callback: (deadline: {
      readonly didTimeout: boolean;
      timeRemaining(): number;
    }) => void,
    options?: IdleRequestOptions
  ): number;
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +9 to +15
requestIdleCallback(
callback: (deadline: {
readonly didTimeout: boolean;
timeRemaining(): number;
}) => void,
options?: { timeout: number }
): number;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Align the timeout option shape with the standard IdleRequestOptions to avoid unnecessary type friction.

The DOM requestIdleCallback uses IdleRequestOptions with an optional timeout?: number, but this overload makes timeout required whenever options is passed, which is stricter than the platform API and rejects valid calls like requestIdleCallback(cb, {}). Please make timeout optional (e.g., options?: { timeout?: number } or reuse IdleRequestOptions) to keep the signature compatible with the standard.

Suggested change
requestIdleCallback(
callback: (deadline: {
readonly didTimeout: boolean;
timeRemaining(): number;
}) => void,
options?: { timeout: number }
): number;
requestIdleCallback(
callback: (deadline: {
readonly didTimeout: boolean;
timeRemaining(): number;
}) => void,
options?: IdleRequestOptions
): number;

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request correctly extends the global Window interface to include TypeScript definitions for requestIdleCallback and cancelIdleCallback, which successfully removes the need for any type assertions. The implementation is sound. I have added one suggestion in src/vite-env.d.ts to further improve the type definitions by using a declare global block and creating a separate IdleDeadline interface, which enhances clarity and aligns with best practices for global type augmentation.

Comment on lines +8 to +17
interface Window {
requestIdleCallback(
callback: (deadline: {
readonly didTimeout: boolean;
timeRemaining(): number;
}) => void,
options?: { timeout: number }
): number;
cancelIdleCallback(handle: number): void;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To improve type safety and adhere to best practices for global type augmentation, it's better to wrap this in declare global. Additionally, defining IdleDeadline as a separate interface improves readability and reusability.

Suggested change
interface Window {
requestIdleCallback(
callback: (deadline: {
readonly didTimeout: boolean;
timeRemaining(): number;
}) => void,
options?: { timeout: number }
): number;
cancelIdleCallback(handle: number): void;
}
declare global {
interface IdleDeadline {
readonly didTimeout: boolean;
timeRemaining(): number;
}
interface Window {
requestIdleCallback(
callback: (deadline: IdleDeadline) => void,
options?: { timeout: number }
): number;
cancelIdleCallback(handle: number): void;
}
}

Comment on lines +8 to +17
interface Window {
requestIdleCallback(
callback: (deadline: {
readonly didTimeout: boolean;
timeRemaining(): number;
}) => void,
options?: { timeout: number }
): number;
cancelIdleCallback(handle: number): void;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Idle callbacks typed required 🐞 Bug ✓ Correctness

src/vite-env.d.ts makes requestIdleCallback/cancelIdleCallback mandatory on Window, even
though the app treats them as optional at runtime (feature-detects before calling). This weakens
type safety by allowing other call sites to call these APIs without checks and still compile,
potentially crashing at runtime in environments that don’t implement them.
Agent Prompt
## Issue description
`Window.requestIdleCallback` and `Window.cancelIdleCallback` are declared as required in `src/vite-env.d.ts`, but the runtime code still feature-detects them. This makes the type system claim the APIs always exist and can let other call sites compile without guards, risking runtime `TypeError` in non-supporting environments.

## Issue Context
The current warmup logic already uses feature detection before calling idle callbacks.

## Fix Focus Areas
- Make the augmented properties optional (e.g., `requestIdleCallback?: ...`, `cancelIdleCallback?: ...`) to reflect runtime variability.
- Update call sites to narrow with `typeof window.requestIdleCallback === 'function'` / `typeof window.cancelIdleCallback === 'function'` (or keep existing guards and use non-null assertion after narrowing).

### Target locations
- src/vite-env.d.ts[8-17]
- src/App.tsx[486-526]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@ysdede ysdede changed the title 🧹 Use standard Window interface for idle callbacks Use standard Window interface for idle callbacks Mar 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant