Fix #529: commits stack overflow #541

Merged
crueber merged 1 commit from fix/issue-529 into main 2026-09-14 21:50:21 +00:00
Owner

Fixes #529: the Commits tab page-2 (?skip=) window called useData(...) INSIDE a createEffect body, nesting its inner effect scope and growing the effect graph without bound (Maximum call stack size exceeded), then hanging on loading history... (failed entries carry only entry.error, never a value).

  • web/src/pages/Commits.jsx: hook hoisted to component scope with a reactive key (DocTabs precedent, commits:none sentinel); failed windows render an inline role=alert error with invalidate() retry; h() serves getFirst() whenever no window is keyed (page-1 identical); repo-wide sweep: zero data-hook-in-effect call sites remain.
  • web/test/unit/commits-page-529.test.js: 8 new tests (structure pins + headless failure/retry semantics via prefetchData).
  • docs/go/12_web_ui.md: law-12 decision entry.
  • No backend/SDK change; no new deps.
  • node --test web/test/unit/*.test.js: 1231 total / 1230 pass / 1 fail — the 1 failure is the ambient live-server smoke subtest (smoke.test.js needs a live Go server; the standing :8080 answers /setup 403, untouched by this change); new file 8/8 green; vite build green. Browser proof open (shared-daemon loopback guard).
Fixes #529: the Commits tab page-2 (?skip=) window called useData(...) INSIDE a createEffect body, nesting its inner effect scope and growing the effect graph without bound (Maximum call stack size exceeded), then hanging on loading history... (failed entries carry only entry.error, never a value). - web/src/pages/Commits.jsx: hook hoisted to component scope with a reactive key (DocTabs precedent, commits:none sentinel); failed windows render an inline role=alert error with invalidate() retry; h() serves getFirst() whenever no window is keyed (page-1 identical); repo-wide sweep: zero data-hook-in-effect call sites remain. - web/test/unit/commits-page-529.test.js: 8 new tests (structure pins + headless failure/retry semantics via prefetchData). - docs/go/12_web_ui.md: law-12 decision entry. - No backend/SDK change; no new deps. - node --test web/test/unit/*.test.js: 1231 total / 1230 pass / 1 fail — the 1 failure is the ambient live-server smoke subtest (smoke.test.js needs a live Go server; the standing :8080 answers /setup 403, untouched by this change); new file 8/8 green; vite build green. Browser proof open (shared-daemon loopback guard).
The ?skip=/?path= window instantiated useData inside a createEffect body;
useData opens its own createEffect, so the nested scope grew the effect
graph without bound (Maximum call stack size exceeded) and the page hung
on loading history... (failed entries carry only entry.error, never a
value). Hoist to component scope with a reactive key (DocTabs pattern,
commits:none sentinel); failed windows render an inline role=alert error
with invalidate() retry. Page-1 path unchanged. Docs: 12_web_ui.md
Decisions. Tests: web/test/unit/commits-page-529.test.js (8 tests).
Sign in to join this conversation.
No description provided.