fix: call ColumnCard hooks unconditionally, enforce lint in CI#116
Merged
Conversation
ColumnCard returned its "Unknown column type" card before ~10 hooks. A column's type resolves through the plugin registry and can flip between renders, so that early return could change hook order and crash the component. Move the bail-out below every hook; the hooks above already tolerate a missing type (`paginated` optional-chains, the refresh effect guards itself). Three refs were also mutated during render, which is unsafe under concurrent rendering — a render that never commits would still have written. Sync them in effects instead; the useRef seeds cover the first frame and both consumers only dereference asynchronously. The remaining set-state-in-effect reports are suppressed with rationale rather than restructured: sticky search-open cannot be derived without auto-closing mid-type, and the other two sync from outside React. Also fix 6 unescaped entities, drop the unused MODE_LABELS in the producthunt client, and treat a leading underscore as deliberately-unused so plugin ConfigForms can keep documenting the props contract they satisfy. The tree was at 26 errors and 7 warnings because CI only ran `next build` and never invoked the lint script that already existed. Add a Lint & Test job running eslint --max-warnings=0 and vitest, split from Build so failures report without waiting on the production bundle.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
npm run lintwas reporting 26 errors and 7 warnings onmain. ESLint was already configured — CI just never ran it, so the tree drifted. This gets it to zero and wires it into CI so it stays there.The bug worth reviewing
ColumnCardreturned its "Unknown column type" card atcolumn-card.tsx:106, above ~10useMemo/useRef/useEffectcalls. A column's type resolves through the plugin registry, sotypecan flip between renders — which changes hook order and crashes the component. Moving the bail-out below the hooks clears all 14rules-of-hookserrors at once. The hooks above already tolerate a missingtype(paginatedoptional-chains; the refresh effect has its own guard).Three refs were also assigned during render. That's unsafe under concurrent rendering — a render that never commits would still have written. Now synced in effects; the
useRefseeds cover the first frame and both consumers only dereference asynchronously.Suppressed, not fixed
Three
set-state-in-effectreports are disabled with inline rationale, because a mechanical rewrite would change behavior:searchOpen || searchActivewould auto-close the row when the query is cleared mid-type, which is exactly what the existing comment rules out/shortcut routed through the store — an external signal, no render-time value to derive fromHappy to do the Suspense refactor separately if preferred.
Cosmetic
6 unescaped entities → HTML entities. Removed
MODE_LABELSfromproducthunt/client.tsx— verified dead, every other plugin references its own.Config
Added
argsIgnorePattern: "^_"tono-unused-vars. The six pluginConfigForm(_: ConfigFormProps<…>)params are deliberately unused and already say so with_— a convention gap, not six bugs.CI
New
Lint & Testjob (eslint --max-warnings=0+vitest), parallel toBuildso lint failures report without waiting on the production bundle.--max-warnings=0holds the line now that the tree is clean. Thebuildjob id is unchanged in case any required check references it.Verification
npm run lintclean · 279/279 tests pass · TypeScript +npm run buildsucceed. No behavior changes intended — the hook reordering is the only semantic change, and it strictly widens when hooks run.