refactor(frontend): adopt React 19 <Context> provider shorthand#1588
Merged
Conversation
Render context objects directly as their provider instead of via the
legacy `.Provider`. 19 open + 19 close tags across 18 files; all 9
contexts are React `createContext()` objects, so every site is eligible.
Pure rewrite — `value` prop unchanged, no behavioral change.
Includes the test-wrapper sites (9 *.test.tsx) for a complete migration,
so no `.Provider` stragglers remain for the next audit to re-discover.
Codemod (handles open + close tags; \b avoids `.ProviderFoo`):
perl -i -pe 's{<(/?)([A-Z][A-Za-z0-9_]*)\.Provider\b}{<$1$2}g' <files>
Verified: tsc --noEmit clean (React 19 + @types/react 19 accept `<Ctx>`
as a provider), 4450 Vitest pass / 0 fail.
Backlog row §3a#4 (docs/reference/modernization-backlog.md §3c row #4).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (18)
📝 WalkthroughWalkthroughThis PR systematically refactors React context providers throughout the frontend to use direct context-as-component rendering with ChangesContext Provider Migration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Owner
Author
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. 🤖 Generated with Claude Code |
adamflagg
added a commit
that referenced
this pull request
May 21, 2026
Backlog row **§3 #8** (`docs/reference/modernization-backlog.md`), first slice — `types/graph.ts`. ## What it does Adds `readonly` to every field of the hand-written graph interfaces (`GraphNode`, `GraphEdge`, `GraphMetrics`, `CrossScopeEdge`, `GraphData`) and `readonly T[]` on the array fields (`nodes`, `edges`, `cross_scope_edges`, `cross_scope_nodes`). **Pure type-level — no runtime change.** ## Why `GraphData` is fetched once, cached in `GraphCacheService`, and read by ~5 graph components plus the layout worker. A stray in-place mutation (`.push`/`.sort`/field reassignment) on the shared cached instance would silently corrupt every subscriber; `readonly` turns that into a compile error. This is the clearest instance of the shared-cache bug-class in the frontend. ## Does NOT affect node movement Dragging/layout repositioning operates on Cytoscape's own `NodeSingular` model (`node.position(pos)` in `SocialNetworkGraph.tsx`, `layoutWorkerGuards.ts`), never our `GraphData`. `GraphData.layout_positions` is read-only seed data — only ever *read* in production (the lone writes are `= {}` in two test mocks). ## Verification - `npm run type-check`: **zero tsc cascade** across all 5 consumers / 42 references — the codebase already copies-before-mutating, so nothing fights `readonly`. - Graph vitest suites: 203 passed, 0 failed. - Full `lefthook run pre-push`: green. Generated type files (`pocketbase-types.ts`, `api-generated/`) deliberately skipped (hand-edits lost on regen). `app-types.ts` composites are the remaining slice of this row. ## Also (bundled doc reconciliation) Reconciles backlog §3c against git: marks #1587/#1588/#1589/#1591 shipped, retires the error-cause row (3a#5) as a false positive (0 wrap-rethrow-without-cause sites), adds Retired rows for error-cause + the `satisfies` tuple-widening trap, and corrects the `readonly` count (24 → 29). 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated modernization backlog to correct frontend execution details, clarify calibration decisions, and refine the ranked execution plan and retired items. * **Refactor** * Strengthened immutability and caching contracts for the graph data model to reduce accidental mutations and improve runtime reliability. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/adamflagg/kindred/pull/1592?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Backlog row §3a#4 (
docs/reference/modernization-backlog.md§3c row #4).What it does: Renders context objects directly as their provider —
<ThemeContext value={v}>…</ThemeContext>instead of<ThemeContext.Provider value={v}>…</ThemeContext.Provider>. 19 open + 19 close tags across 18 files.Eligibility (Rule 1): all 9 distinct contexts are React
createContext()objects (cross-referenced), so every site is eligible for the React 19 shorthand. No third-party providers in the match set.Why: React 19 idiom (the point of §3);
.Provideris the legacy form React has signaled for deprecation. Pure rewrite —valueprop unchanged, no behavioral change.Scope — includes test files: unlike the toSorted row (tests excluded to dodge Set-spread traps), this conversion is zero-risk and mechanical, so the 9
*.test.tsxwrapper sites are converted too — a complete migration leaving no.Providerstragglers for the next audit.Codemod (handles open + close;
\bavoids.ProviderFoo):Verified:
tsc --noEmitclean (React 19 +@types/react19 accept<Ctx>as a provider — the real gate) · 4450 Vitest pass / 0 fail ·lefthook run pre-pushgreen.🤖 Generated with Claude Code
Summary by CodeRabbit