refactor(GetFonts): consolidate filtersStore wiring into bindings

Move the filtersStore → filterManager.setGroups $effect.root out of
manager.svelte.ts into bindings.svelte.ts so all cross-store reactive
wiring for the feature lives in one place. manager.svelte.ts now only
constructs and exports the singleton.
This commit is contained in:
Ilia Mashkov
2026-05-24 15:08:54 +03:00
parent e60309af78
commit 33d3429060
2 changed files with 29 additions and 29 deletions
@@ -13,9 +13,34 @@ import { fontStore } from '$entities/Font';
import { untrack } from 'svelte'; import { untrack } from 'svelte';
import { mapManagerToParams } from '../../lib/mapper/mapManagerToParams'; import { mapManagerToParams } from '../../lib/mapper/mapManagerToParams';
import { sortStore } from '../store/sortStore.svelte'; import { sortStore } from '../store/sortStore.svelte';
import { filtersStore } from './filters.svelte';
import { filterManager } from './manager.svelte'; import { filterManager } from './manager.svelte';
$effect.root(() => { $effect.root(() => {
/**
* Populate filterManager groups when backend filter metadata resolves.
* filtersStore is async; until it loads, filterManager has empty groups
* and the UI renders nothing for them.
*/
$effect(() => {
const dynamicFilters = filtersStore.filters;
if (dynamicFilters.length > 0) {
filterManager.setGroups(
dynamicFilters.map(filter => ({
id: filter.id,
label: filter.name,
properties: filter.options.sort((a, b) => b.count - a.count).map(opt => ({
id: opt.id,
name: opt.name,
value: opt.value,
selected: false,
})),
})),
);
}
});
/** /**
* Mirror filter selections + debounced search query into fontStore params. * Mirror filter selections + debounced search query into fontStore params.
* untrack the write so fontStore's internal $state reads don't feed back * untrack the write so fontStore's internal $state reads don't feed back
@@ -1,39 +1,14 @@
/** /**
* Filter manager singleton * Filter manager singleton.
* *
* Creates filterManager with empty groups initially, then reactively * Constructed with empty groups; the filtersStore → filterManager wiring
* populates groups when filtersStore loads data from backend. * lives in `./bindings.svelte` and populates groups once the backend
* filter metadata arrives.
*/ */
import { createFilterManager } from '../../lib/filterManager/filterManager.svelte'; import { createFilterManager } from '../../lib/filterManager/filterManager.svelte';
import { filtersStore } from './filters.svelte';
export const filterManager = createFilterManager({ export const filterManager = createFilterManager({
queryValue: '', queryValue: '',
groups: [], groups: [],
}); });
/**
* Reactively sync backend filter metadata into filterManager groups.
* When filtersStore.filters resolves, setGroups replaces the empty groups.
*/
$effect.root(() => {
$effect(() => {
const dynamicFilters = filtersStore.filters;
if (dynamicFilters.length > 0) {
filterManager.setGroups(
dynamicFilters.map(filter => ({
id: filter.id,
label: filter.name,
properties: filter.options.sort((a, b) => b.count - a.count).map(opt => ({
id: opt.id,
name: opt.name,
value: opt.value,
selected: false,
})),
})),
);
}
});
});