Skip to content

refactor(web): replace controller prop drilling with svelte context - #80

Merged
andykais merged 3 commits into
mainfrom
cursor/replace-controller-god-object-with-context-f3ba
Oct 14, 2026
Merged

andykais merged 3 commits into
mainfrom
cursor/replace-controller-god-object-with-context-f3ba

Conversation

@andykais-ai

@andykais-ai andykais-ai commented Jul 15, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • implements a $lib/contexts module built on svelte's createContext; consumers use import * as contexts from '$lib/contexts/index.ts' with contexts.controller.set(...) at the page root and contexts.controller.get<T>() in descendants
  • improves the browse and tags routes by setting the route controller in component context instead of passing a controller prop through every child
  • removes all controller prop drilling (18+ static prop passes across the browse tree, plus the tags routes)
  • drops the unused controller prop from MediaDetailEntry and a leftover debug console.log in SearchLink
  • bumps svelte 5.39.8 -> 5.56.4, since createContext was added in svelte 5.40
  • rebased onto current main

Vision Testing

  • deno task --cwd packages/web build succeeds
  • svelte-check reports 132 errors on both main and this branch with an identical per-file breakdown (0 introduced). The newer svelte adds state_referenced_locally warnings on props, including in files this PR doesn't touch (Sidebar.svelte, Tag.svelte)
  • manually verified against a seeded database: browse grid, media details sidebar, tag autocomplete, advanced filters toggle, tags table, and tag detail page all work with the controller sourced from context; no console errors

Media details sidebar
Advanced filters panel
Tag detail page

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

@andykais andykais left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also rebase this branch against main

Comment on lines +4 to +7
import { get_controller } from '$lib/contexts/controller.ts'

let {controller, height = $bindable()}: {controller: BrowseController, height: number} = $props()
let {height = $bindable()}: {height: number} = $props()
const controller = get_controller<BrowseController>()

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like this replaced with this pattern:

Suggested change
import { get_controller } from '$lib/contexts/controller.ts'
let {controller, height = $bindable()}: {controller: BrowseController, height: number} = $props()
let {height = $bindable()}: {height: number} = $props()
const controller = get_controller<BrowseController>()
import * as contexts from '$lib/contexts/index.ts'
let {height = $bindable()}: {height: number} = $props()
const controller = contexts.controller.get<BrowseController>()

cursoragent and others added 3 commits October 14, 2026 03:26
Co-authored-by: andykais-claude <andykais-claude@users.noreply.github.com>
Introduce a typed $lib/contexts/controller helper built on svelte's
createContext, and set the route controller in each page's context
(browse, tags, tags/[slug]). Descendant components now read the
controller via get_controller() instead of receiving it as a prop,
removing all controller prop drilling. MediaDetailEntry drops its
unused controller prop entirely.

Co-authored-by: andykais-claude <andykais-claude@users.noreply.github.com>
…pace

Consumers now import `* as contexts from '$lib/contexts/index.ts'` and call
`contexts.controller.get<T>()` / `contexts.controller.set(...)`.

Co-authored-by: andykais-ai <andykais-ai@users.noreply.github.com>
@cursor
cursor Bot force-pushed the cursor/replace-controller-god-object-with-context-f3ba branch from 3909dd5 to 665666c Compare October 14, 2026 03:27
@andykais
andykais marked this pull request as ready for review October 14, 2026 03:31
@andykais
andykais merged commit d317721 into main Oct 14, 2026
8 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.

3 participants