fix(workspace-fs): emit from watchSingleFile only when the file changed

BR
1d ago
+106-5

What & why

Fixes #9462.

When fs.watch failed for a file, watchSingleFile polled and emitted update on every tick, so the document store reloaded the file every 2 s and could show a false external-change warning. It now keeps an ino:mtimeMs:size signature and emits only when it changes.

Left out: a same-size rewrite within one mtime tick is not reported. That only matters on coarse-mtime file systems.

How I tested it

Failing regression test that makes the file unreadable to force polling (skipped when run as root). It also checks that a real mtime change still emits. The bug was first found by checking every order of events in a small model, then reproduced against the real code.

  • packages/workspace-fs: bun run test gives 196 pass, 0 fail.
  • The unreadable-file trigger was checked on macOS only.

Checklist

  • PR title follows conventional commits (type(scope): subject)
  • bun run lint and bun run typecheck pass (CI fails on lint warnings too)
  • "Allow edits from maintainers" is checked on fork PRs
  • I have signed the CLA (the bot asks on your first PR)

Summary by cubic

Fixes watchSingleFile emitting update on every poll when fs.watch cannot be installed, preventing repeated reloads and false external-change warnings. Polling now emits only when the inode, mtime, ctime, or size changes — including permission changes and same-size rewrites that restore the mtime — while watch-driven events always emit, since a watch event is evidence of a change even when the signature is unchanged on coarse-timestamp filesystems. The polling regression tests skip Windows and root.

Summary by CodeRabbit

  • Bug Fixes
    • File watching now detects same-size rewrites even when the original modification time is restored, and detects permission changes during polling.
    • File updates are reported when a watch event occurs, even if the file’s detected signature is unchanged. Polling also handles files that cannot be watched directly.