Skip to content

Conversation

devin-ai-integration[bot]
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Oct 13, 2025

Fixes #10944

When using custom builds with file watching, if multiple files changed simultaneously (e.g., via git operations or editor auto-saves), the build would trigger multiple times concurrently. This PR fixes the issue by debouncing the custom build trigger with a 50ms delay.

Changes

  1. Enhanced the debounce utility (packages/wrangler/src/utils/debounce.ts) to support generic function signatures with parameters:

    • Previously only supported () => void functions
    • Now supports any function signature via TypeScript generics
    • Maintains full backward compatibility with existing uses
    • Uses any[] with eslint-disable (necessary for TypeScript contravariance)
  2. Applied debounce to custom build watcher (packages/wrangler/src/api/startDevWorker/BundlerController.ts):

    • Wraps the #runCustomBuild callback with debounced version
    • Uses 50ms delay (consistent with pages/dev.ts pattern)
    • Prevents concurrent builds when multiple files change rapidly
    • Preserves filePath parameter for logging

Review Focus

  • Verify the generic type signature is correct and maintains backward compatibility
  • Confirm 50ms is an appropriate debounce delay
  • Check that filePath is correctly passed through to #runCustomBuild

Link to Devin run: https://app.devin.ai/sessions/0923b0d7ecc441d29357b877d08d1d63
Requested by: @smacleod


  • Tests
    • Tests included
    • Tests not necessary because: This is a simple debounce application following existing patterns in the codebase (e.g., pages/dev.ts); the logic correctness is straightforward and can be verified through code review
  • Public documentation
    • Cloudflare docs PR(s):
    • Documentation not necessary because: Internal implementation fix with no user-facing API changes
  • Wrangler V3 Backport
    • Wrangler PR:
    • Not necessary because:

- Improve debounce utility to support generic function signatures with parameters
- Apply debounce to custom build watcher with 50ms delay to prevent concurrent builds
- Fixes #10944

Co-Authored-By: [email protected] <[email protected]>
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link

changeset-bot bot commented Oct 13, 2025

🦋 Changeset detected

Latest commit: 5e714a8

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

pkg-pr-new bot commented Oct 13, 2025

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@10955

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@10955

miniflare

npm i https://pkg.pr.new/miniflare@10955

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@10955

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@10955

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@10955

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@10955

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@10955

wrangler

npm i https://pkg.pr.new/wrangler@10955

commit: 5e714a8

* function was invoked.
*/
export function debounce(fn: () => void, delayMs = 100) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't use any. Try unknown?

Copy link
Contributor Author

Thanks for the suggestion! I tried using unknown[] but it breaks the build due to TypeScript's contravariance rules.

When a type parameter appears in a function parameter position (contravariant), TypeScript's subtyping rules are reversed. With T extends (...args: unknown[]) => void, the constraint requires that the function's parameters be contravariant with unknown[]. However, unknown in a contravariant position is actually the most restrictive type (not the most permissive), so (...args: unknown[]) => void is not compatible with specific function signatures like (event: string, filePath: string) => void.

The build error we get is:

error TS2345: Argument of type '(_event: string, filePath: string) => undefined' is not assignable to parameter of type '(...args: unknown[]) => void'.
  Types of parameters '_event' and 'args' are incompatible.
    Type 'unknown' is not assignable to type 'string'.

Using any[] here is the correct approach for generic utilities that need to preserve exact function signatures while remaining type-safe through Parameters<T>. I've added a detailed comment explaining this.

For reference: TypeScript Handbook on Contravariance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

Prevent custom builds from executing concurrenctly

1 participant