Repository navigation
refactor: Svelte 5 best practices, avoid $effect (#47) - #52
Merged
Merged
Conversation
…fect
State that follows other state is now a writable $derived (ModuleCard's
rename, menu, page and previews), a reaction lives in its handler or a
function binding's setter (Select's onOpenChange, the site header's spin
counter), DOM work is an {@Attach} (Switch's line measurement, ModuleCard's
size tween, the setup wizard's input metering, ToolSidebar's action via
fromAction), and devicePixelRatio() subscribes on read through
createSubscriber, so Rack needs no effect to track it.
Every remaining $effect carries a `// Effect:` line saying why it is one,
and src/lib/effectGuard.test.ts fails on one that does not, across ui/ and
site/. class: directives become class arrays, except on the module panel,
whose classList the size tween writes. App.svelte loses the UTF-8 BOM that
made svelte-autofixer fail to parse it, and its mojibake comments are
repaired. AGENTS.md records the rule.
Refs #47
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.
Refactors
ui/andsite/toward Svelte 5 best practices, checked with the Svelte MCP'ssvelte-autofixer. There should be no behaviour change.Effects removed
ModuleCardreset rename/menu when edit mode ends$derived(renamingName,menuOpen) that resets whenevereditingchangesModuleCardcleared previews +menuPageon close$deriveds keyed onmenuOpen, so every close path is covered, including Popover's Escape and outside clickModuleCardsize tween{@attach tweenSize}on the panel;bind:thisfor panel and clip removedSelectonOpenChangeeffectbind:open={() => open, setOpen}plus an unmount report of "closed"Switchtext measurement{@attach measureLines}SetupWizardinput metering{@attach armMetering}on the input step's meter listRacktrackDevicePixelRatio()effectdevicePixelRatio()now usescreateSubscriber; reading it subscribesHeaderspin counterbind:scrollYsetter counts the togglesToolSidebaruse:action{@attach fromAction(...)}Effects kept, each with a
// Effect:justificationKept because no handler sees the change, and converting them would change behaviour:
Rackcontent-learn disarm andMidiLearnhide. Both write back through a$bindablethat App reads to pause MIDI dispatch. What triggers the disarm is an engine push or a host prop with no handler in the component. A plain$derivedwould keep App's flag stuck on, and would re-arm the learn when the target came back.Racklast-active-lane memory. It records history of engine pushes, because a scene recall or rig load also moves the lane. It is now a plain record rather than$state, since only a handler reads it.RackpendingSceneId. It latches the first convergence of the engine's echoes. As a$derived, an edit made after the switch settled would bring the spinner back.StrobeDisplay. It feeds the rAF loop's plain locals and wakes the loop. It also has to keep the last reference after the reading drops.GainMeter's clip hold,TunerReadout's hold/fade,Popover's open stack, andApp's theme andtone3000Verify.Guard:
ui/src/lib/effectGuard.test.tsfails on any$effectinui/srcorsite/srcwithout a// Effect:comment directly above it. It runs as part ofpnpm test.Autofixer
issues: []on every.svelte/.svelte.tsin both packages.App.svelteused to fail to parse because of a UTF-8 BOM. The BOM is gone, and the mojibake in its comments (—) is repaired.MockEngine.tshas the same mojibake and is left alone.class:directives to class arrays, with one exception: the module panel.tweenSizetogglesmodule-resizingthroughclassList, and a class array rewritesclassNamewhole whenever an entry flips, so it would strip that class mid-tween.bind:thisrefs that handlers use for focus, click or scroll;Maps that never escape into reactive state, where SvelteMap would be wrong.svelte-ignore.AGENTS.mdCode style now carries the rule: prefer$derived/ handlers / function bindings /{@attach}/createSubscriber, justify any remaining$effect, check withsvelte-autofixer, and keepclass:only whereclassListis also written.Verification
ui/:pnpm format:check,pnpm check(0 errors, 0 warnings) andpnpm testall pass: 784 tests, including the new guard, which was checked to fail on an unjustified effect.site/:pnpm --dir site checkpasses.site/src/routes/+page.sveltealready had a Prettier warning before this branch, and it is untouched here.pnpm dev(MockEngine), with no console errors:setOpenpath.Closes #47