refactor(fontCatalogStore): single source of truth for query params
On initial load, two separate $effects in bindings.svelte.ts — one for filters, one for sort — each issued its own setOptions with a different queryKey on the first flush, producing an orphaned `/fonts?limit=50&offset=0` request immediately followed by the real `/fonts?limit=50&sort=popularity&offset=0`. Hardcoding the default sort on the singleton would have papered over the symptom while leaving the sortStore default and the catalog-store default coupled by hand. Make bindings the sole emitter of query params: - features/.../bindings: merge filter + sort effects into one. The effect reads both stores, builds the merged param object, and issues a single setParams. No more interleaved setOptions on mount. - entities/.../fontCatalogStore: gate the observer with `enabled: false` on construction. The first setParams flips `#enabled` on and triggers exactly one fetch with the correct queryKey. Removes the need for a hardcoded default sort on the singleton. - isEmpty is also gated on `#enabled` so the brief pre-config window doesn't render "no results" before bindings configures the query. - The constructor seeds #result from observer.getCurrentResult() because subscribe may not fire synchronously when the observer is disabled.
This commit is contained in:
@@ -42,20 +42,19 @@ $effect.root(() => {
|
||||
});
|
||||
|
||||
/**
|
||||
* Mirror filter selections + debounced search query into fontCatalogStore params.
|
||||
* Mirror filter selections + debounced search query + sort into fontCatalogStore params.
|
||||
*
|
||||
* Filters and sort are merged into one setParams call to avoid a startup race:
|
||||
* two separate effects each issued setOptions with a different queryKey on the
|
||||
* first flush, producing an orphaned `?limit=50&offset=0` fetch immediately
|
||||
* followed by the real `?limit=50&sort=popularity&offset=0` fetch.
|
||||
*
|
||||
* untrack the write so fontCatalogStore's internal $state reads don't feed back
|
||||
* into this effect's dependency graph.
|
||||
*/
|
||||
$effect(() => {
|
||||
const params = mapAppliedFiltersToParams(appliedFilterStore);
|
||||
untrack(() => fontCatalogStore.setParams(params));
|
||||
});
|
||||
|
||||
/**
|
||||
* Mirror sort selection into fontCatalogStore.
|
||||
*/
|
||||
$effect(() => {
|
||||
const apiSort = sortStore.apiValue;
|
||||
untrack(() => fontCatalogStore.setSort(apiSort));
|
||||
const sort = sortStore.apiValue;
|
||||
untrack(() => fontCatalogStore.setParams({ ...params, sort }));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user