Commit c305c91
committed
perf(hooks): use primitive fingerprint for ensure-draft-when-empty effect
Audit pass on the same class of bug fixed in b0b41a6 found a second
hook subscribing to the entire `appState` and using it as an effect
dep: `useEnsureDraftWhenEmpty` had `[appState, ...]` in its dep
array. Lower severity than the worktree-include case because the
inner Tauri call (`agentChatCreatePane`) is guarded by an
`inFlightSpawnRef`, so the effect didn't actually fan out into
duplicate IPC calls. But the effect BODY still re-ran on every
backend tick (many per second under the 5 s git poll + agent
streaming), walking workspace surface trees and doing pane-tree
checks for nothing.
Replaced the `appState` subscription with a primitive string
fingerprint built from the four fields the effect actually
depends on:
`${active_workspace_id}|${hasPane}|${project_root}`
The selector returns a primitive string so React/Zustand bail on
identity equality. The effect body now only runs when one of those
three fields actually changes — i.e. when the user activates a
different workspace, or panes are added/removed on the active
surface, or `project_root` flips.
Inside the effect, the live `appState` is read via
`useAppStore.getState()` at fire time so we can still walk surfaces
to pick the Home-draft-vs-pane-spawn branch.
Added a regression test (`use-ensure-draft-when-empty.test.tsx`)
that simulates a backend tick changing only `git_branch` on the
active workspace (the most frequent backend mutation under the 5 s
git poll). The hook must NOT fire `agentChatCreatePane` a second
time across the rerender. Now 17 tests in this file (up from 16),
1686/1686 frontend tests pass.
Tests verified:
- npx tsc --noEmit: clean
- npx vitest run: 1686/1686 pass1 parent b0b41a6 commit c305c91
2 files changed
Lines changed: 106 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
348 | 348 | | |
349 | 349 | | |
350 | 350 | | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
351 | 413 | | |
352 | 414 | | |
353 | 415 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
8 | 36 | | |
9 | 37 | | |
10 | 38 | | |
| |||
28 | 56 | | |
29 | 57 | | |
30 | 58 | | |
31 | | - | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
32 | 66 | | |
33 | 67 | | |
34 | 68 | | |
| |||
44 | 78 | | |
45 | 79 | | |
46 | 80 | | |
47 | | - | |
| 81 | + | |
48 | 82 | | |
49 | 83 | | |
50 | 84 | | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
51 | 92 | | |
52 | 93 | | |
53 | 94 | | |
| |||
86 | 127 | | |
87 | 128 | | |
88 | 129 | | |
89 | | - | |
| 130 | + | |
90 | 131 | | |
91 | 132 | | |
92 | 133 | | |
| |||
0 commit comments