52 lines
1.6 KiB
TypeScript
52 lines
1.6 KiB
TypeScript
|
|
import { queryClient } from '$shared/api/queryClient';
|
||
|
|
import {
|
||
|
|
QueryObserver,
|
||
|
|
type QueryObserverResult,
|
||
|
|
type QueryOptions,
|
||
|
|
} from '@tanstack/query-core';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Abstract base class for reactive Svelte 5 stores backed by TanStack Query.
|
||
|
|
*
|
||
|
|
* Provides a unified way to use TanStack Query observers within Svelte 5 classes
|
||
|
|
* using runes for reactivity. Handles subscription lifecycle automatically.
|
||
|
|
*
|
||
|
|
* @template TData - The type of data returned by the query.
|
||
|
|
* @template TError - The type of error that can be thrown.
|
||
|
|
*/
|
||
|
|
export abstract class BaseQueryStore<TData, TError = Error> {
|
||
|
|
#result = $state<QueryObserverResult<TData, TError>>({} as QueryObserverResult<TData, TError>);
|
||
|
|
#observer: QueryObserver<TData, TError>;
|
||
|
|
#unsubscribe: () => void;
|
||
|
|
|
||
|
|
constructor(options: QueryOptions<TData, TError, any, any, any>) {
|
||
|
|
this.#observer = new QueryObserver(queryClient, options);
|
||
|
|
this.#unsubscribe = this.#observer.subscribe(result => {
|
||
|
|
this.#result = result;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Current query result (reactive)
|
||
|
|
*/
|
||
|
|
protected get result(): QueryObserverResult<TData, TError> {
|
||
|
|
return this.#result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Updates observer options dynamically.
|
||
|
|
* Use this when query parameters or dependencies change.
|
||
|
|
*/
|
||
|
|
protected updateOptions(options: QueryOptions<TData, TError, any, any, any>): void {
|
||
|
|
this.#observer.setOptions(options);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Cleans up the observer subscription.
|
||
|
|
* Should be called when the store is no longer needed.
|
||
|
|
*/
|
||
|
|
destroy(): void {
|
||
|
|
this.#unsubscribe();
|
||
|
|
}
|
||
|
|
}
|