Loading workspace insights... Statistics interval
7 days30 daysLatest CI Pipeline Executions
dc22f7e3 fix(core): collect trickling watcher bursts fully on daemon force-flush (#36391)
## Current Behavior
When the daemon serves a project graph, it first force-flushes the
native watcher (`force_flush_pending`) so buffered file events are not
missed. The flush handler waits `FORCE_FLUSH_GRACE` (10ms Linux / 50ms
macOS) for **at most one** in-flight event, then only drains events that
have *already* reached the channel. A burst whose events are delivered
with small gaps — routine when the notify thread competes for CPU on a
loaded CI machine — is cut mid-stream: trailing writes are missing from
the snapshot, the daemon concludes “no files changed”, and it serves a
**stale project graph**.
Observed failure mode (e2e-webpack, `it should support building
libraries and apps when buildLibsFromSource is false`, on the CI run for
#36387): the test writes an import into `main.ts` and immediately runs
`nx build`. The stale graph had no app→lib edge, so `dependsOn:
['^build']` scheduled **one** task instead of two — `my-pkg:build` never
ran and the run-one banner assertions failed. The test passes locally on
the same commit; the race needs delivery latency, which is why it only
shows under CI load.
The new regression test demonstrates the cut: on the old code, a 5-file
trickling burst flushed as just `[t0.txt]`.
## Expected Behavior
Force-flush waits for event delivery to go **quiet** before
snapshotting: every received event restarts the `FORCE_FLUSH_GRACE`
silence window, bounded by a new `FORCE_FLUSH_MAX` (250ms — safely under
the 500ms reply timeout, past which the JS side would treat the late
reply as “no changes”). The idle path is unchanged: an empty channel
still times out after a single grace window, so daemon graph requests
get no extra latency when nothing is being delivered.
| time | event | Before | After |
|------|-------|--------|-------|
| 0ms | write t0 | | |
| ~5ms | flush starts; t0 already in accumulator | window = 10ms |
`burst_in_progress=true` → window = 50ms |
| ~15ms | 10ms elapsed, no new event | **timeout → break, snapshot
`{t0}`** | still waiting (50ms window) |
| 20ms | t1 arrives | — | ingest, restart 50ms |
| 40/60/80ms | t2, t3, t4 arrive | — | each ingested, window restarts |
| ~130ms | 50ms silence after t4 | — | **break → snapshot `{t0..t4}`** |
Validation:
- New `force_flush_pending_captures_trickling_burst` test fails on the
old handler, passes with the fix (stable across repeated runs)
- Full `nx` Rust lib suite: 520 passed
- Existing `concurrent_force_flush_pending_callers_do_not_time_out` and
`force_flush_pending_captures_in_flight_writes` still green
## Related Issue(s)
None filed — root cause of a flaky `e2e-ci--src/webpack.test.ts` failure
first seen on the CI run for #36387 (a dep-only version bump that cannot
affect task scheduling, which is what prompted the investigation).
<!-- polygraph-session-start -->
---
[View session information
↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/Migrate-5-repos-to-nx-23.2.0-beta.0-0c64a1ed)
<!-- polygraph-session-end -->
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com> af78b8d2 fix(core): stop ratatui cursor queries from racing the TUI event stream (#36318)
## Current Behavior
Since the ratatui 0.30 bump, running tasks in the inline TUI
intermittently logs `ERROR insert_before failed - method may not exist
on this terminal type`, typically noticed when swapping to inline mode.
Root cause: ratatui-core **0.1.2** (a semver-compatible patch that
arrived via a later `Cargo.lock` refresh, not the 0.30 bump commit
itself) added a cursor-position snapshot to `Terminal::clear()`:
```rust
pub fn clear(&mut self) -> Result<(), B::Error> {
let original_cursor = self.backend.get_cursor_position()?; // new in 0.1.2
self.clear_viewport()?;
self.backend.set_cursor_position(original_cursor)?;
...
```
`insert_before` (the inline scrollback path) calls `clear()` on every
insert, so every scrollback flush now writes `ESC[6n` and reads the
reply from terminal input — while crossterm's `EventStream` owns
terminal input. When the query loses that race it times out (~2s) and
`insert_before` returns `Err`. This is the same query/event-stream
conflict the TUI already works around with `draw_without_autoresize` and
by stopping the event stream around mode switches; ratatui-core 0.1.2
re-introduced it from inside the render path where we can't stop the
stream.
(Enabling ratatui's `scrolling-regions` feature was considered and
rejected: with our full-height inline viewport it pushes lines to
scrollback via `CSI S` in a 1-row DECSTBM region, which xterm.js/VSCode
drops instead of saving to scrollback.)
## Expected Behavior
No cursor-position query can ever run on the TUI render path. The
crossterm backend is wrapped in `CursorCachingBackend`, whose
`get_cursor_position` answers from the last position set through the
backend instead of touching the terminal. This is sound because the TUI
keeps the cursor hidden and positions it absolutely, and the inline
viewport is full-height, so ratatui's inline viewport math yields the
same result regardless of the reported position. This also structurally
covers other ratatui internals that query the cursor (e.g. fullscreen
`autoresize` → `resize` → `clear()` on terminal resize).
The error log for a failed scrollback insert now includes the actual
`io::Error` instead of the speculative "method may not exist on this
terminal type" message.
Validation: `cargo test -p nx --lib` passes (477 tests, includes a new
unit test for the cached-cursor behavior); `cargo check`/`clippy`
introduce no new warnings.
## Related Issue(s)
Fixes NXC-4597 af78b8d2 fix(core): stop ratatui cursor queries from racing the TUI event stream (#36318)
## Current Behavior
Since the ratatui 0.30 bump, running tasks in the inline TUI
intermittently logs `ERROR insert_before failed - method may not exist
on this terminal type`, typically noticed when swapping to inline mode.
Root cause: ratatui-core **0.1.2** (a semver-compatible patch that
arrived via a later `Cargo.lock` refresh, not the 0.30 bump commit
itself) added a cursor-position snapshot to `Terminal::clear()`:
```rust
pub fn clear(&mut self) -> Result<(), B::Error> {
let original_cursor = self.backend.get_cursor_position()?; // new in 0.1.2
self.clear_viewport()?;
self.backend.set_cursor_position(original_cursor)?;
...
```
`insert_before` (the inline scrollback path) calls `clear()` on every
insert, so every scrollback flush now writes `ESC[6n` and reads the
reply from terminal input — while crossterm's `EventStream` owns
terminal input. When the query loses that race it times out (~2s) and
`insert_before` returns `Err`. This is the same query/event-stream
conflict the TUI already works around with `draw_without_autoresize` and
by stopping the event stream around mode switches; ratatui-core 0.1.2
re-introduced it from inside the render path where we can't stop the
stream.
(Enabling ratatui's `scrolling-regions` feature was considered and
rejected: with our full-height inline viewport it pushes lines to
scrollback via `CSI S` in a 1-row DECSTBM region, which xterm.js/VSCode
drops instead of saving to scrollback.)
## Expected Behavior
No cursor-position query can ever run on the TUI render path. The
crossterm backend is wrapped in `CursorCachingBackend`, whose
`get_cursor_position` answers from the last position set through the
backend instead of touching the terminal. This is sound because the TUI
keeps the cursor hidden and positions it absolutely, and the inline
viewport is full-height, so ratatui's inline viewport math yields the
same result regardless of the reported position. This also structurally
covers other ratatui internals that query the cursor (e.g. fullscreen
`autoresize` → `resize` → `clear()` on terminal resize).
The error log for a failed scrollback insert now includes the actual
`io::Error` instead of the speculative "method may not exist on this
terminal type" message.
Validation: `cargo test -p nx --lib` passes (477 tests, includes a new
unit test for the cached-cursor behavior); `cargo check`/`clippy`
introduce no new warnings.
## Related Issue(s)
Fixes NXC-4597 af78b8d2 fix(core): stop ratatui cursor queries from racing the TUI event stream (#36318)
## Current Behavior
Since the ratatui 0.30 bump, running tasks in the inline TUI
intermittently logs `ERROR insert_before failed - method may not exist
on this terminal type`, typically noticed when swapping to inline mode.
Root cause: ratatui-core **0.1.2** (a semver-compatible patch that
arrived via a later `Cargo.lock` refresh, not the 0.30 bump commit
itself) added a cursor-position snapshot to `Terminal::clear()`:
```rust
pub fn clear(&mut self) -> Result<(), B::Error> {
let original_cursor = self.backend.get_cursor_position()?; // new in 0.1.2
self.clear_viewport()?;
self.backend.set_cursor_position(original_cursor)?;
...
```
`insert_before` (the inline scrollback path) calls `clear()` on every
insert, so every scrollback flush now writes `ESC[6n` and reads the
reply from terminal input — while crossterm's `EventStream` owns
terminal input. When the query loses that race it times out (~2s) and
`insert_before` returns `Err`. This is the same query/event-stream
conflict the TUI already works around with `draw_without_autoresize` and
by stopping the event stream around mode switches; ratatui-core 0.1.2
re-introduced it from inside the render path where we can't stop the
stream.
(Enabling ratatui's `scrolling-regions` feature was considered and
rejected: with our full-height inline viewport it pushes lines to
scrollback via `CSI S` in a 1-row DECSTBM region, which xterm.js/VSCode
drops instead of saving to scrollback.)
## Expected Behavior
No cursor-position query can ever run on the TUI render path. The
crossterm backend is wrapped in `CursorCachingBackend`, whose
`get_cursor_position` answers from the last position set through the
backend instead of touching the terminal. This is sound because the TUI
keeps the cursor hidden and positions it absolutely, and the inline
viewport is full-height, so ratatui's inline viewport math yields the
same result regardless of the reported position. This also structurally
covers other ratatui internals that query the cursor (e.g. fullscreen
`autoresize` → `resize` → `clear()` on terminal resize).
The error log for a failed scrollback insert now includes the actual
`io::Error` instead of the speculative "method may not exist on this
terminal type" message.
Validation: `cargo test -p nx --lib` passes (477 tests, includes a new
unit test for the cached-cursor behavior); `cargo check`/`clippy`
introduce no new warnings.
## Related Issue(s)
Fixes NXC-4597 71436fbe feat(repo): add react + vite + vitest + playwright example (#35921)
## Current Behavior
There's no React example in the repo that dogfoods the local `@nx/vite`
/ `@nx/react` / `@nx/playwright` / `@nx/eslint` packages end-to-end.
Separately, the global `test` targetDefault applied jest-only options to
**every** `test` target — including `@nx/vitest` ones:
`--detectOpenHandles`, `--forceExit`, and
`NODE_OPTIONS=--experimental-vm-modules`. vitest rejects those jest
flags (`CACError: Unknown option '--detectOpenHandles'`), so every
vitest project had to carry a per-project `test` override to strip them.
## Expected Behavior
This PR has two commits:
**`chore(repo)`: scope test target defaults by plugin (jest vs vitest)**
- Scope the jest flags to `@nx/jest/plugin` targets, and add a
`@nx/vitest`-scoped default that supplies just `--passWithNoTests`.
- Vitest `test` targets now resolve correct args with no per-project
override, so the redundant overrides are removed from
`@nx/angular-rspack` and `@nx/angular-rspack-compiler` (their tests
still pass — 25 and 80 specs respectively; the only real dependency,
`^build-native`, comes from the targetDefault).
- Consolidate the `@nx/vite/plugin` and `@nx/vitest` plugin declarations
(drop the dead `angular-rspack*` vite include).
**`feat(react)`: add react + vite + vitest + playwright example**
- Add `examples/react/basic` — a React app built with **Vite**,
unit-tested with **Vitest**, e2e-tested with **Playwright**, and linted
with **ESLint** — all linked to the local workspace packages via
`workspace:*`, so it dogfoods the in-repo builds.
- Targets verified: `build`, `test` (2 specs), `pw-e2e` (chromium, 1
spec), `lint`, `typecheck`. Workspace `nx sync:check` clean.
## Related Issue(s)
Tracked in NXC-4540 (linked via branch name).
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: FrozenPandaz <FrozenPandaz@users.noreply.github.com> af78b8d2 fix(core): stop ratatui cursor queries from racing the TUI event stream (#36318)
## Current Behavior
Since the ratatui 0.30 bump, running tasks in the inline TUI
intermittently logs `ERROR insert_before failed - method may not exist
on this terminal type`, typically noticed when swapping to inline mode.
Root cause: ratatui-core **0.1.2** (a semver-compatible patch that
arrived via a later `Cargo.lock` refresh, not the 0.30 bump commit
itself) added a cursor-position snapshot to `Terminal::clear()`:
```rust
pub fn clear(&mut self) -> Result<(), B::Error> {
let original_cursor = self.backend.get_cursor_position()?; // new in 0.1.2
self.clear_viewport()?;
self.backend.set_cursor_position(original_cursor)?;
...
```
`insert_before` (the inline scrollback path) calls `clear()` on every
insert, so every scrollback flush now writes `ESC[6n` and reads the
reply from terminal input — while crossterm's `EventStream` owns
terminal input. When the query loses that race it times out (~2s) and
`insert_before` returns `Err`. This is the same query/event-stream
conflict the TUI already works around with `draw_without_autoresize` and
by stopping the event stream around mode switches; ratatui-core 0.1.2
re-introduced it from inside the render path where we can't stop the
stream.
(Enabling ratatui's `scrolling-regions` feature was considered and
rejected: with our full-height inline viewport it pushes lines to
scrollback via `CSI S` in a 1-row DECSTBM region, which xterm.js/VSCode
drops instead of saving to scrollback.)
## Expected Behavior
No cursor-position query can ever run on the TUI render path. The
crossterm backend is wrapped in `CursorCachingBackend`, whose
`get_cursor_position` answers from the last position set through the
backend instead of touching the terminal. This is sound because the TUI
keeps the cursor hidden and positions it absolutely, and the inline
viewport is full-height, so ratatui's inline viewport math yields the
same result regardless of the reported position. This also structurally
covers other ratatui internals that query the cursor (e.g. fullscreen
`autoresize` → `resize` → `clear()` on terminal resize).
The error log for a failed scrollback insert now includes the actual
`io::Error` instead of the speculative "method may not exist on this
terminal type" message.
Validation: `cargo test -p nx --lib` passes (477 tests, includes a new
unit test for the cached-cursor behavior); `cargo check`/`clippy`
introduce no new warnings.
## Related Issue(s)
Fixes NXC-4597