@pagamio/frontend-commons-lib
Version:
Pagamio library for Frontend reusable components like the form engine and table container
125 lines (124 loc) • 4.24 kB
JavaScript
/**
* @fileoverview SWR integration for the API client
*/
import useSWR, { mutate } from 'swr';
import { useApi } from './context';
// Default SWR configuration
const DEFAULT_SWR_CONFIG = {
revalidateOnFocus: false,
revalidateOnReconnect: false,
shouldRetryOnError: true,
errorRetryInterval: 10000,
// Increase to prevent new requests on same resources
dedupingInterval: 300000, // 5 minutes
revalidateIfStale: false,
revalidateOnMount: true,
// Prevent automatic polling
refreshInterval: 0,
refreshWhenHidden: false,
refreshWhenOffline: false,
// Use stale data by default to reduce server load
keepPreviousData: true,
focusThrottleInterval: 60000,
};
/**
* Creates a fetcher function using the existing ApiClient
* @template ResponseData - Expected response type
*/
const createApiFetcher = () => {
const api = useApi();
return async (key, config) => {
const url = Array.isArray(key) ? key[0] : key;
if (typeof url !== 'string') {
throw new Error('Only string keys are supported');
}
// Handle different HTTP methods
switch (config?.method) {
case 'POST':
return api.post(url, config.body ? JSON.parse(config.body.toString()) : undefined, { ...config });
case 'PUT':
return api.put(url, config.body ? JSON.parse(config.body.toString()) : undefined, { ...config });
case 'PATCH':
return api.patch(url, config.body ? JSON.parse(config.body.toString()) : undefined, {
...config,
});
case 'DELETE':
return api.delete(url, { ...config });
default:
return api.get(url, { ...config });
}
};
};
/**
* Main SWR hook that automatically inherits auth config
* @template ResponseData - Type of the expected response data
* @template ErrorData - Type of the error response (defaults to ApiErrorResponse)
*/
export function useApiSWR(endpoint, config) {
const fetcher = createApiFetcher();
const { params, skipAuth, skipRetry, skipRefresh, isProtected,
// Extract SWR-specific config
...swrConfig } = config || {};
const requestConfig = {
params,
skipAuth,
skipRetry,
skipRefresh,
isProtected,
};
const mergedConfig = {
...DEFAULT_SWR_CONFIG,
...swrConfig,
};
return useSWR(endpoint, (url) => fetcher(url, { ...requestConfig, ...config }), mergedConfig);
}
/**
* Paginated SWR hook that inherits auth config
* @template ItemType - Type of items in the paginated response
* @template ResponseType - Type of the full response (defaults to SpringBootResponse)
*/
export function usePaginatedApiSWR(endpoint, config) {
return useApiSWR(endpoint, config);
}
/**
* Mutation hook that inherits auth config
* @template ResponseData - Type of the expected response data
*/
export function useApiMutation() {
const api = useApi();
return {
post: async (endpoint, data, config) => {
const response = await api.post(endpoint, data, config);
await mutate(endpoint, response, false);
return response;
},
put: async (endpoint, data, config) => {
const response = await api.put(endpoint, data, config);
await mutate(endpoint, response, false);
return response;
},
patch: async (endpoint, data, config) => {
const response = await api.patch(endpoint, data, config);
await mutate(endpoint, response, false);
return response;
},
delete: async (endpoint, config) => {
const response = await api.delete(endpoint, config);
await mutate(endpoint, null, false);
return response;
},
};
}
/**
* Combined SWR and mutation hook
* @template ResponseData - Type of the expected response data
*/
export function useApiSWRWithMutation(endpoint, config) {
const swr = useApiSWR(endpoint, config);
const mutation = useApiMutation();
return {
...swr,
mutate: mutation,
refresh: () => mutate(endpoint),
};
}