Skip to content

feat(core): add TreeSitterClient.idle() to await pending work#881

Open
edlsh wants to merge 2 commits intoanomalyco:mainfrom
edlsh:feat/tree-sitter-idle
Open

feat(core): add TreeSitterClient.idle() to await pending work#881
edlsh wants to merge 2 commits intoanomalyco:mainfrom
edlsh:feat/tree-sitter-idle

Conversation

@edlsh
Copy link
Copy Markdown
Contributor

@edlsh edlsh commented Mar 27, 2026

Summary

Add TreeSitterClient.idle() — a method that returns a Promise resolving when all pending tree-sitter operations complete. This eliminates flaky CI tests that relied on arbitrary setTimeout/Bun.sleep delays to wait for async highlighting.

Changes

packages/core/src/lib/tree-sitter/client.ts

  • Add idle() public method with tracked-work counting (beginTrackedWork()/finish() callback pattern)
  • Track per-buffer response queues (pendingBufferResponses) and reset-debounce work (pendingResetDebounces)
  • Clean up all tracked work on destroy()

packages/core/src/lib/tree-sitter/parser.worker.ts

  • Always send HIGHLIGHT_RESPONSE even when highlights array is empty. Previously, HANDLE_EDITS and RESET_BUFFER sent no message when highlights were empty with no warning/error, which would cause idle() to hang indefinitely on blank or comment-only content.

packages/core/src/lib/tree-sitter/client.test.ts

  • Add tests for idle(): resolves immediately when nothing pending, and waits for queued buffer updates

packages/core/src/renderables/Code.test.ts

  • Un-skip flaky CI test, replace setTimeout with deterministic idle() + highlightingDone + renderOnce()

packages/core/src/renderables/__tests__/LineNumberRenderable.test.ts

  • Un-skip flaky CI test, replace Bun.sleep with idle() + highlightingDone + renderOnce()

Testing

All 124 affected tests pass locally (42 tree-sitter client + 82 renderable tests).

Add an idle() method that returns a Promise resolving when all pending
tree-sitter operations (buffer creates, updates, resets, parser preloads,
etc.) complete. This replaces arbitrary setTimeout/Bun.sleep waits in
tests with a deterministic state-based approach.

The implementation tracks outstanding work via a pendingWorkCount counter
with beginTrackedWork()/finish callbacks, per-buffer response queues,
and reset-debounce tracking. All tracked work is cleaned up on destroy().

Also fix the worker to always send HIGHLIGHT_RESPONSE even when highlights
are empty, preventing idle() from hanging on blank/comment-only content.

Un-skip two previously flaky CI tests that now use idle() instead of
timing-dependent sleeps.
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