Skip to content

Fix React effect-driven state synchronization - #885

Merged
Neonforge98 merged 1 commit into
developfrom
codex/react-effect-state-sync
Aug 22, 2026
Merged

Fix React effect-driven state synchronization#885
Neonforge98 merged 1 commit into
developfrom
codex/react-effect-state-sync

Conversation

@Harry19081

Copy link
Copy Markdown
Member

Problem

React state in 18 production modules was being mirrored or reset from effects. That produced post-commit render cascades, transient stale UI, and lifecycle races across workspace/session/file changes. Several real diagnostics were hidden behind broad or stale react-hooks suppressions.

Solution

  • Derive or guardedly adjust transition state during render for passport flips, poker decisions, search collapse state, status filters, app-shell hosts, subagent sessions, settings deep links, and model-palette search.
  • Move stop-button reset to component lifecycle and make modal close reset state through unmount.
  • Make workspace-memory, local-image, and git-diff async results request-keyed so obsolete completions cannot update the current surface.
  • Publish browser console/network cache snapshots through useSyncExternalStore instead of effect-mirroring the cache into local state.
  • Make the shared agent-definition atoms the tool matrix source of truth, with optimistic updates, persisted server results, and rollback.
  • Remove the affected set-state-in-effect and stale exhaustive-deps suppressions and add focused lifecycle regressions.

Potential risks

  • Several components now use React's guarded render-time state adjustment pattern; each transition is identity-guarded and covered by pure state-transition tests.
  • Browser diagnostic state now follows an external-store contract. The cache remains hook-local and bounded, and tests cover close-time invalidation plus session switching.
  • Tool-matrix writes are optimistic; failed persistence restores the prior shared definition, and both success and rollback are covered.
  • The Sync deep link remains in its atom until the Settings view has rendered the stamped request, then is cleared on the following effect.
  • Automated lifecycle checks were run, but no real Tauri/WebView UI profiling was performed in this change.

Verification

  • pnpm typecheck
  • ESLint on all 35 changed TypeScript files with --report-unused-disable-directives
  • Focused Vitest suite: 14 files, 41 tests passed
  • git diff --check
  • Repository pre-commit hooks: lint-staged, scoped TypeScript check, and circular-import stats passed

Performance guard

Area Verdict Evidence Change Verification
Background work Pass Browser polling remains visibility-aware at the existing cadence; git diff loading still uses the shared single-flight resource No timer or polling cadence added Browser and git-diff lifecycle tests
Memory bounds Pass Browser caches remain capped at 10 sessions and 500 console / 200 network rows; app-shell history is bounded by host cardinality; existing git cache remains byte/entry bounded Removed mirrored entry arrays and stale UI state Source inspection, focused tests
Scope isolation Pass Workspace, image source, browser session, git request, and settings request stamp are explicit state keys Obsolete async completions are ignored Workspace/image/browser/git regression tests
Rendering Pass Transition state is derived in the same render and effect-driven reset cascades were removed Fewer post-commit synchronization renders Targeted ESLint and state-transition tests
Cleanup Pass Modal timers are cancelled and stop/search/modal state resets through lifecycle boundaries No orphan timer or retained closed-modal state Focused lifecycle tests

Performance verdict: PASS for the affected invariants. This PR does not claim measured runtime speedups; it removes redundant render cascades without increasing background cadence or retention bounds.

@Neonforge98
Neonforge98 merged commit d3c7200 into develop Aug 22, 2026
3 checks passed
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.

2 participants