fix/filtration #20
@@ -9,7 +9,6 @@ import type { UnifiedFont } from '../types';
|
|||||||
|
|
||||||
/** */
|
/** */
|
||||||
export abstract class BaseFontStore<TParams extends Record<string, any>> {
|
export abstract class BaseFontStore<TParams extends Record<string, any>> {
|
||||||
// params = $state<TParams>({} as TParams);
|
|
||||||
cleanup: () => void;
|
cleanup: () => void;
|
||||||
|
|
||||||
#bindings = $state<(() => Partial<TParams>)[]>([]);
|
#bindings = $state<(() => Partial<TParams>)[]>([]);
|
||||||
@@ -18,9 +17,11 @@ export abstract class BaseFontStore<TParams extends Record<string, any>> {
|
|||||||
params = $derived.by(() => {
|
params = $derived.by(() => {
|
||||||
let merged = { ...this.#internalParams };
|
let merged = { ...this.#internalParams };
|
||||||
|
|
||||||
|
// Loop through every "Cable" plugged into the store
|
||||||
// Loop through every "Cable" plugged into the store
|
// Loop through every "Cable" plugged into the store
|
||||||
for (const getter of this.#bindings) {
|
for (const getter of this.#bindings) {
|
||||||
merged = { ...merged, ...getter() };
|
const bindingResult = getter();
|
||||||
|
merged = { ...merged, ...bindingResult };
|
||||||
}
|
}
|
||||||
|
|
||||||
return merged as TParams;
|
return merged as TParams;
|
||||||
@@ -54,7 +55,7 @@ export abstract class BaseFontStore<TParams extends Record<string, any>> {
|
|||||||
protected abstract getQueryKey(params: TParams): QueryKey;
|
protected abstract getQueryKey(params: TParams): QueryKey;
|
||||||
protected abstract fetchFn(params: TParams): Promise<UnifiedFont[]>;
|
protected abstract fetchFn(params: TParams): Promise<UnifiedFont[]>;
|
||||||
|
|
||||||
private getOptions(params = this.params): QueryObserverOptions<UnifiedFont[], Error> {
|
protected getOptions(params = this.params): QueryObserverOptions<UnifiedFont[], Error> {
|
||||||
return {
|
return {
|
||||||
queryKey: this.getQueryKey(params),
|
queryKey: this.getQueryKey(params),
|
||||||
queryFn: () => this.fetchFn(params),
|
queryFn: () => this.fetchFn(params),
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* - Provider-specific shortcuts for common operations
|
* - Provider-specific shortcuts for common operations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { QueryObserverOptions } from '@tanstack/query-core';
|
||||||
import type { ProxyFontsParams } from '../../api';
|
import type { ProxyFontsParams } from '../../api';
|
||||||
import { fetchProxyFonts } from '../../api';
|
import { fetchProxyFonts } from '../../api';
|
||||||
import type { UnifiedFont } from '../types';
|
import type { UnifiedFont } from '../types';
|
||||||
@@ -121,6 +122,19 @@ export class UnifiedFontStore extends BaseFontStore<ProxyFontsParams> {
|
|||||||
this.#previousFilterParams = filterParams;
|
this.#previousFilterParams = filterParams;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Effect: Sync state from Query result (Handles Cache Hits)
|
||||||
|
$effect(() => {
|
||||||
|
const data = this.result.data;
|
||||||
|
const offset = this.params.offset || 0;
|
||||||
|
|
||||||
|
// When we have data and we are at the start (offset 0),
|
||||||
|
// we must ensure accumulatedFonts matches the fresh (or cached) data.
|
||||||
|
// This fixes the issue where cache hits skip fetchFn side-effects.
|
||||||
|
if (offset === 0 && data && data.length > 0) {
|
||||||
|
this.#accumulatedFonts = data;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,15 +159,26 @@ export class UnifiedFontStore extends BaseFontStore<ProxyFontsParams> {
|
|||||||
protected getQueryKey(params: ProxyFontsParams) {
|
protected getQueryKey(params: ProxyFontsParams) {
|
||||||
// Normalize params to treat empty arrays/strings as undefined
|
// Normalize params to treat empty arrays/strings as undefined
|
||||||
const normalized = Object.entries(params).reduce((acc, [key, value]) => {
|
const normalized = Object.entries(params).reduce((acc, [key, value]) => {
|
||||||
if (value === '' || (Array.isArray(value) && value.length === 0)) {
|
if (value === '' || value === undefined || (Array.isArray(value) && value.length === 0)) {
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
return { ...acc, [key]: value };
|
return { ...acc, [key]: value };
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
|
// Return a consistent key
|
||||||
return ['unifiedFonts', normalized] as const;
|
return ['unifiedFonts', normalized] as const;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected getOptions(params = this.params): QueryObserverOptions<UnifiedFont[], Error> {
|
||||||
|
const hasFilters = !!(params.q || params.provider || params.category || params.subset);
|
||||||
|
return {
|
||||||
|
queryKey: this.getQueryKey(params),
|
||||||
|
queryFn: () => this.fetchFn(params),
|
||||||
|
staleTime: hasFilters ? 0 : 5 * 60 * 1000,
|
||||||
|
gcTime: 10 * 60 * 1000,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch function that calls the proxy API
|
* Fetch function that calls the proxy API
|
||||||
* Returns the full response including pagination metadata
|
* Returns the full response including pagination metadata
|
||||||
@@ -187,11 +212,10 @@ export class UnifiedFontStore extends BaseFontStore<ProxyFontsParams> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Accumulate fonts for infinite scroll
|
// Accumulate fonts for infinite scroll
|
||||||
if (params.offset === 0) {
|
// Note: For offset === 0, we rely on the $effect above to handle the reset/init
|
||||||
// Reset when starting from beginning (new search/filter)
|
// This prevents race conditions and double-setting.
|
||||||
this.#accumulatedFonts = response.fonts;
|
if (params.offset !== 0) {
|
||||||
} else {
|
// Append new fonts to existing ones only for pagination
|
||||||
// Append new fonts to existing ones
|
|
||||||
this.#accumulatedFonts = [...this.#accumulatedFonts, ...response.fonts];
|
this.#accumulatedFonts = [...this.#accumulatedFonts, ...response.fonts];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user