refactor: Implement Component Registry Architecture for Settings System#1303
Merged
kwaroran merged 12 commits intokwaroran:mainfrom Mar 6, 2026
Merged
refactor: Implement Component Registry Architecture for Settings System#1303kwaroran merged 12 commits intokwaroran:mainfrom
kwaroran merged 12 commits intokwaroran:mainfrom
Conversation
…SettingItem This introduces a type-safe and reactivity-friendly alternative to the legacy string-based bindKey/bindPath approach.
Created utils.ts for handling getter/setter safely, and isolated Header, Check, Text, and Slider UI logic into dedicated wrapper components.
Deconstructed the God Component 'SettingRenderer.svelte' into isolated wrapper components mapped by 'settingRegistry.ts'. SettingRenderer now strictly acts as a lightweight dynamic component mounter, drastically improving maintainability and extensibility for future complex UI requirements.
Removed local $state bindings that caused 'state_referenced_locally' warnings. Implemented a getter/setter proxy object pattern (valueProxy) to perfectly map Svelte two-way bindings directly to the underlying getSettingValue/setSettingValue utilities.
… effect Updated the effect that resets hidden options to use the new valueProxy pattern instead of the removed local 'value' state.
…pers - Migrate 8 input wrappers from plain JS getter/setter proxy to $state + $effect - Apply untrack() in Select/Segmented reset effects to prevent infinite loops - Fix state_referenced_locally warnings with $state(undefined) initialization - Clean up residual blank lines
- Add undefined check to skip initial state before DB sync completes - Compare localValue with DB before writing to prevent unnecessary writes - Eliminates potential infinite loop risk for reference types - All DB writes now only happen on actual user-driven value changes
…ppers - Replace $state(undefined) with $state(untrack(() => getSettingValue())) to eliminate Flash of Undefined on initial render - Introduce UNINITIALIZED Symbol in utils.ts as a sentinel value so that legitimate undefined DB values are not silently ignored - Update write-back guard from undefined check to UNINITIALIZED check across all 8 wrapper components
Add nullish coalescing assignment (??=) in setSettingValue to safely auto-create intermediate objects when writing to nested paths like 'a.b.c', preventing TypeError crashes when 'a.b' is undefined.
This was referenced Mar 7, 2026
Open
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.
PR Checklist
Summary
This PR overhauls the internal architecture of
SettingRendererby introducing a Component Registry Pattern and adopting a Svelte-5-native$state/$effectvalue binding approach. The "God Component" is deconstructed into 12 isolated wrapper components, each registered in a type-safesettingRegistry. Functional accessors (getValue/setValue) are added toSettingItemas a safer alternative to the legacy string-basedbindKey/bindPath.Related Issues
None.
Changes
Getter/Setter Type Safety (
types.ts)getValue,setValue, andonChangefunctional accessors toSettingItemas a type-safe, reactive alternative tobindKey/bindPath.labelKeyproperty toSelectOptionandSegmentOptioninterfaces for proper i18n support.Component Registry (
settingRegistry.ts)SettingType→ wrapper components.Record<SettingType, WrapperComponent>so adding a newSettingTypewithout registering a component causes a compile-time error.Deconstruction of the God Component (
SettingRenderer.svelte)if-elsebranching into a ~40-line lightweight router.{@const Component = settingRegistry[item.type]}.Isolated UI Wrappers (
src/lib/Setting/Wrappers/*).sveltefile (12 total: Check, Text, Number, Textarea, Slider, Select, Segmented, Color, Header, Button, Accordion, Custom).$state/$effectfor two-way DB binding — no plain JS getter/setter proxy.Svelte 5 Reactivity Compliance (
utils.ts)state_referenced_locallywarnings by initializing$state(undefined)and using$effectfor the initial sync.untrack()in Select/Segmented reset effects to prevent potential infinite loops.getLabel,getSettingValue,setSettingValue,checkCondition) into a dedicated module.Impact
SettingRenderer. Create a wrapper and register it — done.Record<SettingType, WrapperComponent>, andSelectOption/SegmentOptionproperly typelabelKey. Missing registrations cause compile errors.state_referenced_locally) and potential reactivity desyncs from the previous plain JS proxy approach.bindKey/bindPathsetups continue to work via the fallback path inutils.ts.Additional Notes
getValue/setValuewill follow in separate, smaller PRs.Footnotes
Modifies the behavior of prompting, requesting, or handling responses from AI models. ↩
Over 80% of the code is AI generated. ↩