TanStack Query Strategy
Relevant source files
The following files were used as context for generating this wiki page:
The TanStack Query Strategy within the beverage-utils library provides a standardized, cross-framework approach for fetching, caching, and processing beverage classification data. It leverages TanStack Query to manage asynchronous state across React, Vue, and Angular applications, ensuring that beverage labels and categories are consistently available and efficiently cached.
The strategy focuses on retrieving a BeverageClassification object from the CellarNode API and transforming it into a flattened LabelMap. This map allows for fast, unambiguous lookups using composite keys, solving the issue of duplicate subtype IDs across different beverage categories.
Sources: README.md:14-17, README.md:104-106
Core Query Configuration
The implementation across all supported frameworks relies on a shared query configuration pattern. This pattern defines how the data is fetched and how long it remains valid in the cache.
Query Options and Fetching
Each framework adapter exports a beverageLabelMapOptions function. This function returns a configuration object compatible with TanStack Query's queryOptions API.
| Option | Value | Description |
|---|---|---|
queryKey | ["beverage-classifications"] | The unique identifier for the query in the cache. |
queryFn | async fetch | Fetches data from /api/v1/classifications/beverage-types. |
staleTime | Infinity | Data never expires because classifications change rarely. |
Sources: src/react/use-beverage-label-map.ts:7-21, src/vue/use-beverage-label-map.ts:7-21, src/angular/beverage-label-map.service.ts:7-21
Data Transformation Logic
The query function does not just return the raw JSON from the API. It passes the jsonData property to the buildLabelMap utility. This utility iterates through categories and subtypes to create a lookup table with three types of keys:
- Category ID: e.g.,
"wine"->"Still Wine" - Subtype ID: e.g.,
"red"->"Red Wine"(last-write-wins) - Composite Key: e.g.,
"wine:red"->"Red Wine"(unambiguous)
Sources: src/label-map.ts:5-15, README.md:36-41
The following diagram illustrates the data flow from the API to the framework-specific hooks:
The diagram shows the sequence from the initial API request to the delivery of the transformed LabelMap to UI components.
Sources: src/react/use-beverage-label-map.ts:13-18, src/label-map.ts:7-14
Framework-Specific Adapters
The library provides specialized wrappers for React, Vue, and Angular to integrate the TanStack Query strategy into their respective reactivity systems.
React Implementation
In React, the strategy is exposed via the useBeverageLabelMap hook. This hook calls useQuery using the options generated by beverageLabelMapOptions.
export function useBeverageLabelMap(apiBaseUrl: string) {
return useQuery(beverageLabelMapOptions(apiBaseUrl));
}
Sources: src/react/use-beverage-label-map.ts:23-25
Vue Implementation
The Vue adapter uses the @tanstack/vue-query package to provide a similar composable.
export function useBeverageLabelMap(apiBaseUrl: string) {
return useQuery(beverageLabelMapOptions(apiBaseUrl));
}
Sources: src/vue/use-beverage-label-map.ts:23-25
Angular Implementation
For Angular, the library uses @tanstack/angular-query-experimental. It provides an injectBeverageLabelMap function that uses Angular's dependency injection context.
export function injectBeverageLabelMap(apiBaseUrl: string) {
return injectQuery(() => beverageLabelMapOptions(apiBaseUrl));
}
Sources: src/angular/beverage-label-map.service.ts:23-25
Data Structures
The strategy relies on specific TypeScript interfaces to ensure type safety during the fetch and transformation process.
Beverage Classification Schema
The API returns a structure defined by the BeverageClassification interface.
This diagram represents the hierarchical structure of the classification data received from the API.
Sources: src/types.ts:1-15
LabelMap Type
The final result of the query is a LabelMap, which is a flat dictionary for rapid lookup.
export type LabelMap = Record<string, string>;
Sources: src/label-map.ts:3
Error Handling and State
The fetch operation includes basic error handling to manage API failures. If the response from the CellarNode API is not "ok" (status outside 200-299), the query function throws an error: "Failed to fetch beverage classifications". This error is then captured by TanStack Query's internal state management, allowing components to react to loading or error states via the hook's returned properties.
Sources: src/react/use-beverage-label-map.ts:16, src/vue/use-beverage-label-map.ts:16, src/angular/beverage-label-map.service.ts:16
Summary
The TanStack Query Strategy in beverage-utils centralizes the logic for managing beverage classification data. By combining staleTime: Infinity with a custom transformation utility (buildLabelMap), it provides a high-performance, type-safe, and unambiguous lookup system available across all major modern web frameworks.