useCache.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import { type DocumentNode, type OperationVariables } from "@apollo/client";
  2. import { graphqlRequest, type CacheLifeOption, GraphqlRequestResult } from "@/lib/graphql-fetch";
  3. import { GET_FILTER_ATTRIBUTES } from "@/graphql";
  4. export interface PageCacheConfig {
  5. tags: string[];
  6. life: CacheLifeOption;
  7. }
  8. /**
  9. * Cache configuration for different pages and queries
  10. * Centralized management of cache tags and revalidation times
  11. */
  12. export const PAGE_CACHE_CONFIG: Record<string, PageCacheConfig> = {
  13. // Home page
  14. home: {
  15. tags: ["home-page"],
  16. life: "hours",
  17. },
  18. // Product pages
  19. product: {
  20. tags: ["all-products"],
  21. life: "hours",
  22. },
  23. // Category/Collection pages
  24. category: {
  25. tags: ["categories"],
  26. life: "hours",
  27. },
  28. // Static content
  29. static: {
  30. tags: ["static-content"],
  31. life: "days",
  32. },
  33. // Search results
  34. search: {
  35. tags: ["search-results"],
  36. life: "hours",
  37. },
  38. };
  39. /**
  40. * Helper to get cache config for a specific page
  41. */
  42. export function getPageCacheConfig(
  43. page: keyof typeof PAGE_CACHE_CONFIG,
  44. ): PageCacheConfig {
  45. return PAGE_CACHE_CONFIG[page];
  46. }
  47. /**
  48. * Helper to create dynamic product cache config with specific product identifier
  49. */
  50. // export function getProductCacheConfig(productId: string): PageCacheConfig {
  51. // return {
  52. // tags: ["products", `product-${productId}`],
  53. // life: "hours",
  54. // };
  55. // }
  56. export function getProductCacheConfig(productId: string): {noCache: boolean} {
  57. return {noCache: true};
  58. }
  59. /**
  60. * Helper to create dynamic category cache config with specific category identifier
  61. */
  62. export function getCategoryCacheConfig(categoryId: string): PageCacheConfig {
  63. return {
  64. tags: ["categories", `category-${categoryId}`],
  65. life: "hours",
  66. };
  67. }
  68. /**
  69. * Wrapper hook for graphqlRequest with automatic cache management
  70. * Usage: const data = await cachedGraphQLRequest('home', query, variables);
  71. */
  72. export async function cachedGraphQLRequest<
  73. TData = unknown,
  74. TVariables extends OperationVariables = OperationVariables,
  75. >(
  76. page: keyof typeof PAGE_CACHE_CONFIG,
  77. query: DocumentNode,
  78. variables?: TVariables,
  79. ): Promise<GraphqlRequestResult<TData>> {
  80. const config = getPageCacheConfig(page);
  81. return graphqlRequest<TData, TVariables>(query, variables, config);
  82. }
  83. /**
  84. * Wrapper for product-specific queries with dynamic cache tags
  85. */
  86. export async function cachedProductRequest<
  87. TData = unknown,
  88. TVariables extends OperationVariables = OperationVariables,
  89. >(
  90. productId: string,
  91. query: DocumentNode,
  92. variables?: TVariables,
  93. ): Promise<GraphqlRequestResult<TData>> {
  94. const config = getProductCacheConfig(productId);
  95. return graphqlRequest<TData, TVariables>(query, variables, config);
  96. }
  97. /**
  98. * Wrapper for category-specific queries with dynamic cache tags
  99. */
  100. export async function cachedCategoryRequest<
  101. TData = unknown,
  102. TVariables extends OperationVariables = OperationVariables,
  103. >(
  104. categoryId: string,
  105. query: DocumentNode,
  106. variables?: TVariables,
  107. ): Promise<GraphqlRequestResult<TData>> {
  108. const config = getCategoryCacheConfig(categoryId);
  109. return graphqlRequest<TData, TVariables>(query, variables, config);
  110. }
  111. /**
  112. * Fetches filter attributes (color, size, brand) for product filtering
  113. *
  114. * @returns Promise with formatted filter attributes
  115. */
  116. export async function getFilterAttributes() {
  117. const {data: filterData } = await cachedGraphQLRequest<{
  118. color: any;
  119. size: any;
  120. brand: any;
  121. }>("static", GET_FILTER_ATTRIBUTES, { locale: "en" });
  122. const attributes = [filterData?.color, filterData?.size, filterData?.brand];
  123. return attributes.filter(Boolean).map((attr) => ({
  124. id: attr.id,
  125. code: attr.code,
  126. adminName: attr.code.toUpperCase(),
  127. options: attr.options.edges.map((o: any) => ({
  128. id: o.node.id,
  129. adminName: o.node.adminName,
  130. })),
  131. }));
  132. }