refactor(filters): mount-scope store bindings and fix effect-update loop
Replace the side-effect-on-import $effect.root in bindings with an explicit startFilterBindings() started from an AppBindings provider in onMount, so the filters/sort -> font-catalog bridge has a lifecycle tied to the app tree and a returned cleanup. bindings now consumes getFontCatalog(). Fix the effect-update loop this surfaced: setGroups populated the reactive groups array in place via `groups.length = 0; groups.push(...)`. push reads the array's length signal, so the populating effect both read and wrote groups.length each run and re-triggered itself forever (effect_update_depth_exceeded). setGroups now reassigns the array (groups is `let`), which does not read length. Extract mapFilterMetadataToGroups to own the metadata -> group-config mapping, including sorting a copy of options (the source is TanStack-cached data; an in-place sort corrupts the cache and writes into the effect's read dependency).
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
Component: AppBindings
|
||||
Provider that starts app-wide store bindings (filters → sort → font catalog)
|
||||
for its subtree. Mount-scoped so the bindings' lifetime tracks the app tree.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { startFilterBindings } from '$features/FilterAndSortFonts';
|
||||
import { onMount } from 'svelte';
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* Content snippet
|
||||
*/
|
||||
children?: Snippet;
|
||||
}
|
||||
|
||||
let { children }: Props = $props();
|
||||
|
||||
// startFilterBindings returns its $effect.root cleanup; onMount runs it on unmount.
|
||||
onMount(() => startFilterBindings());
|
||||
</script>
|
||||
|
||||
{@render children?.()}
|
||||
Reference in New Issue
Block a user