@shopify/shop-minis-react 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/dist/components/MinisContainer.js +11 -10
  2. package/dist/components/MinisContainer.js.map +1 -1
  3. package/dist/hooks/content/useContent.js +12 -18
  4. package/dist/hooks/content/useContent.js.map +1 -1
  5. package/dist/hooks/product/useCuratedProducts.js +9 -11
  6. package/dist/hooks/product/useCuratedProducts.js.map +1 -1
  7. package/dist/hooks/product/usePopularProducts.js +9 -11
  8. package/dist/hooks/product/usePopularProducts.js.map +1 -1
  9. package/dist/hooks/product/useProduct.js +11 -17
  10. package/dist/hooks/product/useProduct.js.map +1 -1
  11. package/dist/hooks/product/useProductList.js +10 -21
  12. package/dist/hooks/product/useProductList.js.map +1 -1
  13. package/dist/hooks/product/useProductLists.js +11 -13
  14. package/dist/hooks/product/useProductLists.js.map +1 -1
  15. package/dist/hooks/product/useProductMedia.js +12 -18
  16. package/dist/hooks/product/useProductMedia.js.map +1 -1
  17. package/dist/hooks/product/useProductSearch.js +34 -27
  18. package/dist/hooks/product/useProductSearch.js.map +1 -1
  19. package/dist/hooks/product/useProductVariants.js +11 -14
  20. package/dist/hooks/product/useProductVariants.js.map +1 -1
  21. package/dist/hooks/product/useProducts.js +12 -11
  22. package/dist/hooks/product/useProducts.js.map +1 -1
  23. package/dist/hooks/product/useRecommendedProducts.js +11 -13
  24. package/dist/hooks/product/useRecommendedProducts.js.map +1 -1
  25. package/dist/hooks/shop/useRecommendedShops.js +11 -13
  26. package/dist/hooks/shop/useRecommendedShops.js.map +1 -1
  27. package/dist/hooks/shop/useShop.js +12 -11
  28. package/dist/hooks/shop/useShop.js.map +1 -1
  29. package/dist/hooks/user/useBuyerAttributes.js +8 -10
  30. package/dist/hooks/user/useBuyerAttributes.js.map +1 -1
  31. package/dist/hooks/user/useCurrentUser.js +7 -9
  32. package/dist/hooks/user/useCurrentUser.js.map +1 -1
  33. package/dist/hooks/user/useFollowedShops.js +11 -14
  34. package/dist/hooks/user/useFollowedShops.js.map +1 -1
  35. package/dist/hooks/user/useOrders.js +7 -9
  36. package/dist/hooks/user/useOrders.js.map +1 -1
  37. package/dist/hooks/user/useRecentProducts.js +11 -13
  38. package/dist/hooks/user/useRecentProducts.js.map +1 -1
  39. package/dist/hooks/user/useRecentShops.js +10 -13
  40. package/dist/hooks/user/useRecentShops.js.map +1 -1
  41. package/dist/hooks/user/useSavedProducts.js +10 -13
  42. package/dist/hooks/user/useSavedProducts.js.map +1 -1
  43. package/dist/internal/reactQuery/MinisQueryProvider.js +11 -0
  44. package/dist/internal/reactQuery/MinisQueryProvider.js.map +1 -0
  45. package/dist/internal/reactQuery/queryClient.js +33 -0
  46. package/dist/internal/reactQuery/queryClient.js.map +1 -0
  47. package/dist/internal/reactQuery/useShopActionInfiniteQuery.js +52 -0
  48. package/dist/internal/reactQuery/useShopActionInfiniteQuery.js.map +1 -0
  49. package/dist/internal/reactQuery/useShopActionQuery.js +37 -0
  50. package/dist/internal/reactQuery/useShopActionQuery.js.map +1 -0
  51. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/focusManager.js +45 -0
  52. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/focusManager.js.map +1 -0
  53. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/infiniteQueryBehavior.js +89 -0
  54. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/infiniteQueryBehavior.js.map +1 -0
  55. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/infiniteQueryObserver.js +55 -0
  56. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/infiniteQueryObserver.js.map +1 -0
  57. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/mutation.js +198 -0
  58. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/mutation.js.map +1 -0
  59. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/mutationCache.js +99 -0
  60. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/mutationCache.js.map +1 -0
  61. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/notifyManager.js +67 -0
  62. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/notifyManager.js.map +1 -0
  63. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/onlineManager.js +39 -0
  64. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/onlineManager.js.map +1 -0
  65. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/query.js +299 -0
  66. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/query.js.map +1 -0
  67. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryCache.js +80 -0
  68. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryCache.js.map +1 -0
  69. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryClient.js +215 -0
  70. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryClient.js.map +1 -0
  71. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryObserver.js +300 -0
  72. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryObserver.js.map +1 -0
  73. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/removable.js +25 -0
  74. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/removable.js.map +1 -0
  75. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/retryer.js +76 -0
  76. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/retryer.js.map +1 -0
  77. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/subscribable.js +21 -0
  78. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/subscribable.js.map +1 -0
  79. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/thenable.js +26 -0
  80. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/thenable.js.map +1 -0
  81. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/utils.js +176 -0
  82. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/utils.js.map +1 -0
  83. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/IsRestoringProvider.js +7 -0
  84. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/IsRestoringProvider.js.map +1 -0
  85. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js +17 -0
  86. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js.map +1 -0
  87. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/QueryErrorResetBoundary.js +19 -0
  88. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/QueryErrorResetBoundary.js.map +1 -0
  89. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/errorBoundaryUtils.js +21 -0
  90. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/errorBoundaryUtils.js.map +1 -0
  91. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/suspense.js +18 -0
  92. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/suspense.js.map +1 -0
  93. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useBaseQuery.js +64 -0
  94. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useBaseQuery.js.map +1 -0
  95. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useInfiniteQuery.js +13 -0
  96. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useInfiniteQuery.js.map +1 -0
  97. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useQuery.js +9 -0
  98. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useQuery.js.map +1 -0
  99. package/package.json +2 -7
  100. package/src/components/MinisContainer.tsx +6 -3
  101. package/src/hooks/content/useContent.ts +6 -17
  102. package/src/hooks/product/useCuratedProducts.ts +4 -6
  103. package/src/hooks/product/usePopularProducts.ts +4 -6
  104. package/src/hooks/product/useProduct.ts +6 -17
  105. package/src/hooks/product/useProductList.ts +4 -19
  106. package/src/hooks/product/useProductLists.ts +4 -6
  107. package/src/hooks/product/useProductMedia.ts +6 -17
  108. package/src/hooks/product/useProductSearch.ts +19 -15
  109. package/src/hooks/product/useProductVariants.ts +5 -13
  110. package/src/hooks/product/useProducts.ts +8 -12
  111. package/src/hooks/product/useRecommendedProducts.ts +4 -6
  112. package/src/hooks/shop/useRecommendedShops.ts +4 -6
  113. package/src/hooks/shop/useShop.ts +8 -12
  114. package/src/hooks/user/useBuyerAttributes.ts +4 -6
  115. package/src/hooks/user/useCurrentUser.ts +4 -6
  116. package/src/hooks/user/useFollowedShops.ts +5 -13
  117. package/src/hooks/user/useOrders.ts +4 -6
  118. package/src/hooks/user/useRecentProducts.ts +4 -6
  119. package/src/hooks/user/useRecentShops.ts +5 -13
  120. package/src/hooks/user/useSavedProducts.ts +5 -13
  121. package/src/internal/reactQuery/MinisQueryProvider.test.tsx +38 -0
  122. package/src/internal/reactQuery/MinisQueryProvider.tsx +16 -0
  123. package/src/internal/reactQuery/index.ts +8 -0
  124. package/src/internal/reactQuery/queryClient.test.tsx +91 -0
  125. package/src/internal/reactQuery/queryClient.ts +43 -0
  126. package/src/internal/reactQuery/useShopActionInfiniteQuery.test.tsx +357 -0
  127. package/src/internal/reactQuery/useShopActionInfiniteQuery.ts +129 -0
  128. package/src/internal/reactQuery/useShopActionQuery.test.tsx +184 -0
  129. package/src/internal/reactQuery/useShopActionQuery.ts +74 -0
  130. package/dist/internal/useShopActionsDataFetching.js +0 -79
  131. package/dist/internal/useShopActionsDataFetching.js.map +0 -1
  132. package/dist/internal/useShopActionsPaginatedDataFetching.js +0 -96
  133. package/dist/internal/useShopActionsPaginatedDataFetching.js.map +0 -1
  134. package/src/hooks/product/useProductSearch.test.ts +0 -470
  135. package/src/internal/useShopActionsDataFetching.test.ts +0 -465
  136. package/src/internal/useShopActionsDataFetching.ts +0 -150
  137. package/src/internal/useShopActionsPaginatedDataFetching.ts +0 -188
  138. package/src/stories/Accordion.stories.tsx +0 -124
  139. package/src/stories/AddToCart.stories.tsx +0 -251
  140. package/src/stories/Alert.stories.tsx +0 -38
  141. package/src/stories/AlertDialog.stories.tsx +0 -48
  142. package/src/stories/Avatar.stories.tsx +0 -29
  143. package/src/stories/Badge.stories.tsx +0 -46
  144. package/src/stories/Button.stories.tsx +0 -81
  145. package/src/stories/Card.stories.tsx +0 -40
  146. package/src/stories/Checkbox.stories.tsx +0 -44
  147. package/src/stories/FavoriteButton.stories.tsx +0 -58
  148. package/src/stories/IconButton.stories.tsx +0 -68
  149. package/src/stories/ImageContentWrapper.stories.tsx +0 -65
  150. package/src/stories/Input.stories.tsx +0 -44
  151. package/src/stories/Label.stories.tsx +0 -19
  152. package/src/stories/List.stories.tsx +0 -64
  153. package/src/stories/MerchantCard.stories.tsx +0 -127
  154. package/src/stories/ProductCard.stories.tsx +0 -92
  155. package/src/stories/ProductLink.stories.tsx +0 -46
  156. package/src/stories/ProductVariantPrice.stories.tsx +0 -70
  157. package/src/stories/Progress.stories.tsx +0 -30
  158. package/src/stories/PullToRefreshList.stories.tsx +0 -122
  159. package/src/stories/QuantitySelector.stories.tsx +0 -78
  160. package/src/stories/RadioGroup.stories.tsx +0 -51
  161. package/src/stories/Search.stories.tsx +0 -37
  162. package/src/stories/Select.stories.tsx +0 -85
  163. package/src/stories/Skeleton.stories.tsx +0 -19
  164. package/src/stories/TextInput.stories.tsx +0 -26
  165. package/src/stories/Toaster.stories.tsx +0 -46
  166. package/src/stories/Touchable.stories.tsx +0 -40
  167. package/src/stories/VideoPlayer.stories.tsx +0 -129
@@ -0,0 +1,129 @@
1
+ import {useCallback, useMemo} from 'react'
2
+
3
+ import {ShopActionResult} from '@shopify/shop-minis-platform/actions'
4
+ import {useInfiniteQuery} from '@tanstack/react-query'
5
+
6
+ import {DataHookFetchPolicy} from '../../types'
7
+
8
+ import {useShopMinisQueryClient} from './queryClient'
9
+
10
+ /**
11
+ * Helper to use React Query with Shop Actions (paginated)
12
+ * Replaces useShopActionsPaginatedDataFetching
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * // Example: Fetching saved products
17
+ * const { getSavedProducts } = useShopActions()
18
+ * const { data, loading, error, hasNextPage, fetchMore, refetch } =
19
+ * useShopActionInfiniteQuery(
20
+ * ['savedProducts', { includeSensitive }], // Query key
21
+ * getSavedProducts, // Shop Action
22
+ * { includeSensitive }, // Params (excludes 'after')
23
+ * { skip: false } // Options
24
+ * )
25
+ * // data will be flattened array of products from all pages
26
+ * ```
27
+ */
28
+ export function useShopActionInfiniteQuery<
29
+ TData,
30
+ TParams extends {after?: string; fetchPolicy?: DataHookFetchPolicy},
31
+ >(
32
+ queryKey: unknown[],
33
+ action: (params: TParams) => Promise<
34
+ ShopActionResult<{
35
+ data: TData
36
+ pageInfo: {hasNextPage: boolean; endCursor: string | null}
37
+ }>
38
+ >,
39
+ params: Omit<TParams, 'after'>,
40
+ options?: {
41
+ skip?: boolean
42
+ }
43
+ ) {
44
+ const {skip = false} = options ?? {}
45
+
46
+ // Always use our SDK's QueryClient for isolation
47
+ const queryClient = useShopMinisQueryClient()
48
+
49
+ interface PageData {
50
+ data: TData
51
+ pageInfo: {hasNextPage: boolean; endCursor: string | null}
52
+ }
53
+
54
+ const {
55
+ data,
56
+ fetchNextPage,
57
+ hasNextPage,
58
+ isLoading,
59
+ error,
60
+ refetch: reactQueryRefetch,
61
+ } = useInfiniteQuery<
62
+ PageData,
63
+ Error,
64
+ {pages: PageData[]},
65
+ unknown[],
66
+ string | undefined
67
+ >(
68
+ {
69
+ queryKey,
70
+ queryFn: async ({pageParam}: {pageParam: string | undefined}) => {
71
+ const result = await action({
72
+ ...params,
73
+ after: pageParam,
74
+ } as TParams)
75
+
76
+ if (!result.ok) {
77
+ throw result.error
78
+ }
79
+
80
+ return result.data
81
+ },
82
+ getNextPageParam: (lastPage: PageData) =>
83
+ lastPage.pageInfo.hasNextPage ? lastPage.pageInfo.endCursor : undefined,
84
+ initialPageParam: undefined as string | undefined,
85
+ enabled: !skip,
86
+ // Caching disabled by default (handled by Apollo)
87
+ // fetchPolicy param is passed through to the action (Apollo layer)
88
+ },
89
+ queryClient
90
+ )
91
+
92
+ // Flatten paginated data
93
+ // For paginated queries, we expect TData to be an array type
94
+ // Each page.data is an array that we concatenate together
95
+ const flattenedData = useMemo(() => {
96
+ if (!data?.pages || data.pages.length === 0) return null
97
+
98
+ // If first page data is null/undefined, return null
99
+ const firstPageData = data.pages[0].data
100
+ if (firstPageData === null || firstPageData === undefined) return null
101
+
102
+ // If data is array type, flatten all pages
103
+ if (Array.isArray(firstPageData)) {
104
+ return data.pages.flatMap((page: PageData) => page.data as any) as TData
105
+ }
106
+
107
+ // If data is not an array, just return the first page's data
108
+ // (Though in practice, all Shop Minis paginated queries return arrays)
109
+ return firstPageData as TData
110
+ }, [data?.pages])
111
+
112
+ // Wrap React Query functions to match expected API
113
+ const fetchMore = useCallback(async () => {
114
+ await fetchNextPage()
115
+ }, [fetchNextPage])
116
+
117
+ const refetch = useCallback(async () => {
118
+ await reactQueryRefetch()
119
+ }, [reactQueryRefetch])
120
+
121
+ return {
122
+ data: flattenedData,
123
+ loading: isLoading,
124
+ error: error as Error | null,
125
+ hasNextPage: hasNextPage ?? false,
126
+ fetchMore,
127
+ refetch,
128
+ }
129
+ }
@@ -0,0 +1,184 @@
1
+ import React from 'react'
2
+
3
+ import {renderHook, waitFor} from '@testing-library/react'
4
+ import {describe, expect, it, vi} from 'vitest'
5
+
6
+ import {MinisQueryProvider} from './MinisQueryProvider'
7
+ import {useShopActionQuery} from './useShopActionQuery'
8
+
9
+ describe('useShopActionQuery', () => {
10
+ const wrapper = ({children}: {children: React.ReactNode}) => (
11
+ <MinisQueryProvider>{children}</MinisQueryProvider>
12
+ )
13
+
14
+ describe('Successful Data Fetching', () => {
15
+ it('fetches and returns data', async () => {
16
+ const mockAction = vi.fn().mockResolvedValue({
17
+ ok: true,
18
+ data: {data: {id: '1', name: 'Test Product'}},
19
+ })
20
+
21
+ const {result} = renderHook(
22
+ () => useShopActionQuery(['test-1'], mockAction, {}),
23
+ {wrapper}
24
+ )
25
+
26
+ await waitFor(() => {
27
+ expect(result.current.loading).toBe(false)
28
+ })
29
+
30
+ expect(result.current.data).toEqual({id: '1', name: 'Test Product'})
31
+ expect(result.current.error).toBeNull()
32
+ expect(mockAction).toHaveBeenCalledWith({})
33
+ })
34
+
35
+ it('returns null when data is undefined', async () => {
36
+ const mockAction = vi.fn().mockResolvedValue({
37
+ ok: true,
38
+ data: {data: undefined},
39
+ })
40
+
41
+ const {result} = renderHook(
42
+ () => useShopActionQuery(['test-undefined'], mockAction, {}),
43
+ {wrapper}
44
+ )
45
+
46
+ await waitFor(() => {
47
+ expect(result.current.loading).toBe(false)
48
+ })
49
+
50
+ expect(result.current.data).toBeNull()
51
+ })
52
+ })
53
+
54
+ describe('Error Handling', () => {
55
+ it('handles action errors (ok: false)', async () => {
56
+ const mockAction = vi.fn().mockRejectedValue(new Error('API Error'))
57
+
58
+ const {result} = renderHook(
59
+ () => useShopActionQuery(['test-action-error'], mockAction, {}),
60
+ {wrapper}
61
+ )
62
+
63
+ // Wait for loading to complete (after retries)
64
+ await waitFor(
65
+ () => {
66
+ expect(result.current.loading).toBe(false)
67
+ },
68
+ {timeout: 3000}
69
+ )
70
+
71
+ expect(result.current.data).toBeNull()
72
+ expect(result.current.error).toBeInstanceOf(Error)
73
+ expect(result.current.error?.message).toBe('API Error')
74
+ })
75
+ })
76
+
77
+ describe('Skip Parameter', () => {
78
+ it('does not fetch when skip is true', async () => {
79
+ const mockAction = vi.fn()
80
+
81
+ renderHook(
82
+ () => useShopActionQuery(['test-skip'], mockAction, {}, {skip: true}),
83
+ {wrapper}
84
+ )
85
+
86
+ // Wait a bit to ensure no fetch happens
87
+ await new Promise(resolve => setTimeout(resolve, 100))
88
+
89
+ expect(mockAction).not.toHaveBeenCalled()
90
+ })
91
+
92
+ it('fetches when skip is false', async () => {
93
+ const mockAction = vi.fn().mockResolvedValue({
94
+ ok: true,
95
+ data: {data: 'skip-false-data'},
96
+ })
97
+
98
+ const {result} = renderHook(
99
+ () =>
100
+ useShopActionQuery(
101
+ ['test-noskip-query'],
102
+ mockAction,
103
+ {},
104
+ {skip: false}
105
+ ),
106
+ {wrapper}
107
+ )
108
+
109
+ await waitFor(() => {
110
+ expect(result.current.data).toBe('skip-false-data')
111
+ })
112
+
113
+ expect(mockAction).toHaveBeenCalled()
114
+ })
115
+ })
116
+
117
+ describe('API Contract', () => {
118
+ it('returns expected shape', async () => {
119
+ const mockAction = vi.fn().mockResolvedValue({
120
+ ok: true,
121
+ data: {data: 'contract-test'},
122
+ })
123
+
124
+ const {result} = renderHook(
125
+ () => useShopActionQuery(['test-contract'], mockAction, {}),
126
+ {wrapper}
127
+ )
128
+
129
+ await waitFor(() => {
130
+ expect(result.current.loading).toBe(false)
131
+ })
132
+
133
+ // Verify all expected properties exist
134
+ expect(result.current).toHaveProperty('data')
135
+ expect(result.current).toHaveProperty('loading')
136
+ expect(result.current).toHaveProperty('error')
137
+ expect(result.current).toHaveProperty('refetch')
138
+
139
+ // Verify types
140
+ expect(typeof result.current.loading).toBe('boolean')
141
+ expect(typeof result.current.refetch).toBe('function')
142
+ })
143
+ })
144
+
145
+ describe('fetchPolicy Parameter', () => {
146
+ it('passes fetchPolicy to action', async () => {
147
+ const mockAction = vi.fn().mockResolvedValue({
148
+ ok: true,
149
+ data: {data: 'test'},
150
+ })
151
+
152
+ renderHook(
153
+ () =>
154
+ useShopActionQuery(['test-network-only'], mockAction, {
155
+ fetchPolicy: 'network-only',
156
+ }),
157
+ {wrapper}
158
+ )
159
+
160
+ await waitFor(() => {
161
+ expect(mockAction).toHaveBeenCalledWith({fetchPolicy: 'network-only'})
162
+ })
163
+ })
164
+
165
+ it('passes cache-first fetchPolicy to action', async () => {
166
+ const mockAction = vi.fn().mockResolvedValue({
167
+ ok: true,
168
+ data: {data: 'test'},
169
+ })
170
+
171
+ renderHook(
172
+ () =>
173
+ useShopActionQuery(['test-cache-first'], mockAction, {
174
+ fetchPolicy: 'cache-first',
175
+ }),
176
+ {wrapper}
177
+ )
178
+
179
+ await waitFor(() => {
180
+ expect(mockAction).toHaveBeenCalledWith({fetchPolicy: 'cache-first'})
181
+ })
182
+ })
183
+ })
184
+ })
@@ -0,0 +1,74 @@
1
+ import {useCallback} from 'react'
2
+
3
+ import {ShopActionResult} from '@shopify/shop-minis-platform/actions'
4
+ import {useQuery} from '@tanstack/react-query'
5
+
6
+ import {DataHookFetchPolicy} from '../../types'
7
+
8
+ import {useShopMinisQueryClient} from './queryClient'
9
+
10
+ /**
11
+ * Helper to use React Query with Shop Actions (non-paginated)
12
+ * Replaces useShopActionsDataFetching
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const { data, loading, error, refetch } = useShopActionQuery(
17
+ * ['product', id],
18
+ * getProduct,
19
+ * { id },
20
+ * { skip: false }
21
+ * )
22
+ * ```
23
+ */
24
+ export function useShopActionQuery<
25
+ TData,
26
+ TParams extends {fetchPolicy?: DataHookFetchPolicy},
27
+ >(
28
+ queryKey: unknown[],
29
+ action: (params: TParams) => Promise<ShopActionResult<{data: TData}>>,
30
+ params: TParams,
31
+ options?: {
32
+ skip?: boolean
33
+ }
34
+ ) {
35
+ const {skip = false} = options ?? {}
36
+
37
+ // Always use our SDK's QueryClient for isolation
38
+ const queryClient = useShopMinisQueryClient()
39
+
40
+ const {
41
+ data,
42
+ error,
43
+ isLoading,
44
+ refetch: reactQueryRefetch,
45
+ } = useQuery(
46
+ {
47
+ queryKey,
48
+ queryFn: async () => {
49
+ const result = await action(params)
50
+
51
+ if (!result.ok) {
52
+ throw result.error
53
+ }
54
+
55
+ return result.data.data
56
+ },
57
+ enabled: !skip,
58
+ // Caching disabled by default (handled by Apollo)
59
+ // fetchPolicy param is passed through to the action (Apollo layer)
60
+ },
61
+ queryClient
62
+ )
63
+
64
+ const refetch = useCallback(async () => {
65
+ await reactQueryRefetch()
66
+ }, [reactQueryRefetch])
67
+
68
+ return {
69
+ data: data ?? null,
70
+ loading: isLoading,
71
+ error: error as Error | null,
72
+ refetch,
73
+ }
74
+ }
@@ -1,79 +0,0 @@
1
- import { useState as b, useCallback as u, useMemo as v, useEffect as M } from "react";
2
- import { MiniError as P, formatError as V } from "../utils/errors.js";
3
- const A = (c, d, f) => {
4
- const [n, l] = b({
5
- data: null,
6
- loading: !0,
7
- error: null
8
- }), h = f?.skip === !0, { validator: g, hook: t } = f, w = u(
9
- (s) => {
10
- try {
11
- return g?.(s), null;
12
- } catch (e) {
13
- return e instanceof Error ? e : new P({
14
- hook: t,
15
- message: "Validation failed"
16
- });
17
- }
18
- },
19
- [g, t]
20
- ), y = v(() => d, [JSON.stringify(d)]), a = u(
21
- async (s, {
22
- setLoading: e = !0,
23
- setError: p = !0,
24
- resetOnError: E = !0,
25
- throwOnError: O = !0
26
- } = {}) => {
27
- let m = null, i = null;
28
- l((r) => ({
29
- ...r,
30
- loading: e ? !0 : r.loading
31
- }));
32
- try {
33
- const r = await c({ ...y, ...s });
34
- if (r.ok)
35
- i = w(r.data.data), l((S) => ({
36
- ...S,
37
- data: r.data.data,
38
- loading: !1,
39
- error: i ?? null
40
- }));
41
- else
42
- throw r.error;
43
- } catch (r) {
44
- m = V({ hook: t }, r);
45
- }
46
- const o = i || m;
47
- if (o && (p || E) && l((r) => ({
48
- data: E ? null : r.data,
49
- loading: !1,
50
- error: o
51
- })), o && O)
52
- throw o;
53
- },
54
- [c, y, t, w]
55
- ), k = u(async () => {
56
- await a({ fetchPolicy: "network-only" }, {
57
- setLoading: !1,
58
- resetOnError: !1,
59
- throwOnError: !0
60
- });
61
- }, [a]);
62
- return M(() => {
63
- h || a(
64
- {},
65
- {
66
- throwOnError: !1
67
- }
68
- );
69
- }, [a, h]), {
70
- data: n.data,
71
- loading: n.loading,
72
- error: n.error,
73
- refetch: k
74
- };
75
- };
76
- export {
77
- A as useShopActionsDataFetching
78
- };
79
- //# sourceMappingURL=useShopActionsDataFetching.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useShopActionsDataFetching.js","sources":["../../src/internal/useShopActionsDataFetching.ts"],"sourcesContent":["import {useCallback, useEffect, useMemo, useState} from 'react'\n\nimport {ShopActionResult} from '@shopify/shop-minis-platform/actions'\n\nimport {DataHookFetchPolicy, DataHookReturnsBase} from '../types'\nimport {formatError, MiniError} from '../utils/errors'\n\nexport interface ShopActionsDataFetchingResult<R> extends DataHookReturnsBase {\n data: R | null\n}\n\nexport const useShopActionsDataFetching = <\n S = unknown,\n P extends {fetchPolicy?: DataHookFetchPolicy} = {\n fetchPolicy?: DataHookFetchPolicy\n },\n>(\n action: (params: P) => Promise<ShopActionResult<{data: S}>>,\n params: P,\n options: {\n skip?: boolean\n hook?: string\n validator?: (data: S) => void\n }\n): ShopActionsDataFetchingResult<S> => {\n const [state, setState] = useState<{\n data: S | null\n loading: boolean\n error: Error | null\n }>({\n data: null,\n loading: true,\n error: null,\n })\n\n const skip = options?.skip === true\n const {validator, hook} = options\n const runValidator = useCallback(\n (dataToValidate: S) => {\n try {\n validator?.(dataToValidate)\n return null\n } catch (err) {\n if (err instanceof Error) return err\n\n return new MiniError({\n hook,\n message: 'Validation failed',\n })\n }\n },\n [validator, hook]\n )\n\n // Params object is recreated on every render, so we need to memoize it.\n // We don't know what's inside the params object, but we can stringify it.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const stableParams = useMemo(() => params, [JSON.stringify(params)])\n\n // There's a lot of complexity here because each type of fetch has different side effects if we are trying to\n // stay close to how Apollo client works. eg:\n // - Initial fetch: set loading, set error, set data, reset on error (don't throw)\n // - change params fetch: set loading, set error, set data, reset on error (don't throw)\n // - refetch fetch: don't set loading, set error, update data, leave data as is was on error (also throw)\n // - fetchMore fetch: don't set loading, don't set error, update data, leave data as is was on error (also throw)\n const fetch = useCallback(\n async (\n extraParams?: Partial<P>,\n {\n setLoading = true,\n setError = true,\n resetOnError = true,\n throwOnError = true,\n }: {\n setLoading?: boolean\n setError?: boolean\n resetOnError?: boolean\n throwOnError?: boolean\n } = {}\n ) => {\n let queryError: Error | null = null\n let validationError: Error | null = null\n\n setState(curState => ({\n ...curState,\n loading: setLoading ? true : curState.loading,\n }))\n\n try {\n const result = await action({...stableParams, ...extraParams})\n\n if (result.ok) {\n validationError = runValidator(result.data.data)\n\n setState(curState => ({\n ...curState,\n data: result.data.data,\n loading: false,\n error: validationError ?? null,\n }))\n } else {\n throw result.error\n }\n } catch (err) {\n queryError = formatError({hook}, err)\n }\n\n const error = validationError || queryError\n\n if (error && (setError || resetOnError)) {\n setState(curState => ({\n data: resetOnError ? null : curState.data,\n loading: false,\n error,\n }))\n }\n\n if (error && throwOnError) {\n throw error\n }\n },\n [action, stableParams, hook, runValidator]\n )\n\n const refetch = useCallback(async () => {\n await fetch({fetchPolicy: 'network-only'} as Partial<P>, {\n setLoading: false,\n resetOnError: false,\n throwOnError: true,\n })\n }, [fetch])\n\n useEffect(() => {\n if (skip) return\n\n fetch(\n {},\n {\n throwOnError: false,\n }\n )\n }, [fetch, skip])\n\n return {\n data: state.data,\n loading: state.loading,\n error: state.error,\n refetch,\n }\n}\n"],"names":["useShopActionsDataFetching","action","params","options","state","setState","useState","skip","validator","hook","runValidator","useCallback","dataToValidate","err","MiniError","stableParams","useMemo","fetch","extraParams","setLoading","setError","resetOnError","throwOnError","queryError","validationError","curState","result","formatError","error","refetch","useEffect"],"mappings":";;AAWO,MAAMA,IAA6B,CAMxCC,GACAC,GACAC,MAKqC;AACrC,QAAM,CAACC,GAAOC,CAAQ,IAAIC,EAIvB;AAAA,IACD,MAAM;AAAA,IACN,SAAS;AAAA,IACT,OAAO;AAAA,EAAA,CACR,GAEKC,IAAOJ,GAAS,SAAS,IACzB,EAAC,WAAAK,GAAW,MAAAC,EAAA,IAAQN,GACpBO,IAAeC;AAAA,IACnB,CAACC,MAAsB;AACjB,UAAA;AACF,eAAAJ,IAAYI,CAAc,GACnB;AAAA,eACAC,GAAK;AACR,eAAAA,aAAe,QAAcA,IAE1B,IAAIC,EAAU;AAAA,UACnB,MAAAL;AAAA,UACA,SAAS;AAAA,QAAA,CACV;AAAA,MAAA;AAAA,IAEL;AAAA,IACA,CAACD,GAAWC,CAAI;AAAA,EAClB,GAKMM,IAAeC,EAAQ,MAAMd,GAAQ,CAAC,KAAK,UAAUA,CAAM,CAAC,CAAC,GAQ7De,IAAQN;AAAA,IACZ,OACEO,GACA;AAAA,MACE,YAAAC,IAAa;AAAA,MACb,UAAAC,IAAW;AAAA,MACX,cAAAC,IAAe;AAAA,MACf,cAAAC,IAAe;AAAA,IACjB,IAKI,OACD;AACH,UAAIC,IAA2B,MAC3BC,IAAgC;AAEpC,MAAAnB,EAAS,CAAaoB,OAAA;AAAA,QACpB,GAAGA;AAAA,QACH,SAASN,IAAa,KAAOM,EAAS;AAAA,MAAA,EACtC;AAEE,UAAA;AACI,cAAAC,IAAS,MAAMzB,EAAO,EAAC,GAAGc,GAAc,GAAGG,GAAY;AAE7D,YAAIQ,EAAO;AACS,UAAAF,IAAAd,EAAagB,EAAO,KAAK,IAAI,GAE/CrB,EAAS,CAAaoB,OAAA;AAAA,YACpB,GAAGA;AAAA,YACH,MAAMC,EAAO,KAAK;AAAA,YAClB,SAAS;AAAA,YACT,OAAOF,KAAmB;AAAA,UAAA,EAC1B;AAAA;AAEF,gBAAME,EAAO;AAAA,eAERb,GAAK;AACZ,QAAAU,IAAaI,EAAY,EAAC,MAAAlB,EAAI,GAAGI,CAAG;AAAA,MAAA;AAGtC,YAAMe,IAAQJ,KAAmBD;AAUjC,UARIK,MAAUR,KAAYC,MACxBhB,EAAS,CAAaoB,OAAA;AAAA,QACpB,MAAMJ,IAAe,OAAOI,EAAS;AAAA,QACrC,SAAS;AAAA,QACT,OAAAG;AAAA,MAAA,EACA,GAGAA,KAASN;AACL,cAAAM;AAAA,IAEV;AAAA,IACA,CAAC3B,GAAQc,GAAcN,GAAMC,CAAY;AAAA,EAC3C,GAEMmB,IAAUlB,EAAY,YAAY;AACtC,UAAMM,EAAM,EAAC,aAAa,kBAA+B;AAAA,MACvD,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,cAAc;AAAA,IAAA,CACf;AAAA,EAAA,GACA,CAACA,CAAK,CAAC;AAEV,SAAAa,EAAU,MAAM;AACd,IAAIvB,KAEJU;AAAA,MACE,CAAC;AAAA,MACD;AAAA,QACE,cAAc;AAAA,MAAA;AAAA,IAElB;AAAA,EAAA,GACC,CAACA,GAAOV,CAAI,CAAC,GAET;AAAA,IACL,MAAMH,EAAM;AAAA,IACZ,SAASA,EAAM;AAAA,IACf,OAAOA,EAAM;AAAA,IACb,SAAAyB;AAAA,EACF;AACF;"}
@@ -1,96 +0,0 @@
1
- import { useState as A, useCallback as l, useMemo as O, useEffect as D } from "react";
2
- import { MiniError as M, formatError as b } from "../utils/errors.js";
3
- const V = (g, c, h) => {
4
- const [r, f] = A({
5
- data: null,
6
- pageInfo: { hasNextPage: !1, endCursor: null },
7
- loading: !1,
8
- error: null
9
- }), p = h?.skip === !0, { validator: y, hook: t } = h, w = l(
10
- (d) => {
11
- try {
12
- return y?.(d), null;
13
- } catch (o) {
14
- return o instanceof Error ? o : new M({
15
- hook: t,
16
- message: "Validation failed"
17
- });
18
- }
19
- },
20
- [y, t]
21
- ), I = O(() => c, [JSON.stringify(c)]), e = l(
22
- async (d, {
23
- setLoading: o = !0,
24
- setError: N = !0,
25
- resetOnError: i = !0,
26
- throwOnError: k = !0,
27
- appendData: C = !1
28
- } = {}) => {
29
- let E = null, u = null;
30
- f((a) => ({
31
- ...a,
32
- loading: o ? !0 : a.loading
33
- }));
34
- try {
35
- const a = await g({ ...I, ...d });
36
- if (a.ok)
37
- u = w(a.data.data), f((s) => {
38
- let P = a.data.data;
39
- return C && s.data && Array.isArray(s.data) && Array.isArray(a.data.data) && (P = [...s.data, ...a.data.data]), {
40
- ...s,
41
- data: P,
42
- pageInfo: a.data.pageInfo,
43
- loading: !1,
44
- error: u ?? null
45
- };
46
- });
47
- else
48
- throw a.error;
49
- } catch (a) {
50
- console.log("caught 1", a), E = b({ hook: t }, a);
51
- }
52
- const n = u || E;
53
- if (n && (N || i) && f((a) => ({
54
- data: i ? null : a.data,
55
- pageInfo: i ? { hasNextPage: !1, endCursor: null } : a.pageInfo,
56
- loading: !1,
57
- error: n
58
- })), n && k)
59
- throw n;
60
- },
61
- [g, I, t, w]
62
- ), m = l(async () => {
63
- await e({ fetchPolicy: "network-only" }, {
64
- setLoading: !1,
65
- resetOnError: !1,
66
- throwOnError: !0
67
- });
68
- }, [e]), x = l(async () => {
69
- !r.pageInfo.hasNextPage || !r.pageInfo.endCursor || await e({ after: r.pageInfo.endCursor }, {
70
- setLoading: !1,
71
- setError: !1,
72
- resetOnError: !1,
73
- throwOnError: !0,
74
- appendData: !0
75
- });
76
- }, [r.pageInfo.hasNextPage, r.pageInfo.endCursor, e]);
77
- return D(() => {
78
- p || e(
79
- {},
80
- {
81
- throwOnError: !1
82
- }
83
- );
84
- }, [e, p]), {
85
- data: r.data,
86
- loading: r.loading,
87
- error: r.error,
88
- hasNextPage: r.pageInfo.hasNextPage,
89
- refetch: m,
90
- fetchMore: x
91
- };
92
- };
93
- export {
94
- V as useShopActionsPaginatedDataFetching
95
- };
96
- //# sourceMappingURL=useShopActionsPaginatedDataFetching.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useShopActionsPaginatedDataFetching.js","sources":["../../src/internal/useShopActionsPaginatedDataFetching.ts"],"sourcesContent":["import {useCallback, useEffect, useMemo, useState} from 'react'\n\nimport {ShopAction, PaginationInfo} from '@shopify/shop-minis-platform/actions'\n\nimport {DataHookFetchPolicy, PaginatedDataHookReturnsBase} from '../types'\nimport {formatError, MiniError} from '../utils/errors'\n\nexport interface ShopActionsDataFetchingResult<S>\n extends PaginatedDataHookReturnsBase {\n data: S | null\n}\n\nexport const useShopActionsPaginatedDataFetching = <\n S = unknown,\n P extends {after?: string; fetchPolicy?: DataHookFetchPolicy} = {\n after?: undefined\n fetchPolicy?: DataHookFetchPolicy\n },\n>(\n action: ShopAction<P, {data: S; pageInfo: PaginationInfo}>,\n params: P,\n options: {\n skip?: boolean\n hook?: string\n validator?: (data: S) => void\n }\n): ShopActionsDataFetchingResult<S> => {\n const [state, setState] = useState<{\n data: S | null\n pageInfo: PaginationInfo\n loading: boolean\n error: Error | null\n }>({\n data: null,\n pageInfo: {hasNextPage: false, endCursor: null},\n loading: false,\n error: null,\n })\n\n const skip = options?.skip === true\n const {validator, hook} = options\n const runValidator = useCallback(\n (dataToValidate: S): Error | null => {\n try {\n validator?.(dataToValidate)\n return null\n } catch (err) {\n if (err instanceof Error) return err\n\n return new MiniError({\n hook,\n message: 'Validation failed',\n })\n }\n },\n [validator, hook]\n )\n\n // Params object is recreated on every render, so we need to memoize it.\n // We don't know what's inside the params object, but we can stringify it.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const stableParams = useMemo(() => params, [JSON.stringify(params)])\n\n // There's a lot of complexity here because each type of fetch has different side effects if we are trying to\n // stay close to how Apollo client works. eg:\n // - Initial fetch: set loading, set error, set data, reset on error (don't throw)\n // - change params fetch: set loading, set error, set data, reset on error (don't throw)\n // - refetch fetch: don't set loading, set error, update data, leave data as is was on error (also throw)\n // - fetchMore fetch: don't set loading, don't set error, update data, leave data as is was on error (also throw)\n const fetch = useCallback(\n async (\n extraParams?: Partial<P>,\n {\n setLoading = true,\n setError = true,\n resetOnError = true,\n throwOnError = true,\n appendData = false,\n }: {\n setLoading?: boolean\n setError?: boolean\n resetOnError?: boolean\n throwOnError?: boolean\n appendData?: boolean\n } = {}\n ) => {\n let queryError: Error | null = null\n let validationError: Error | null = null\n\n setState(curState => ({\n ...curState,\n loading: setLoading ? true : curState.loading,\n }))\n\n try {\n const result = await action({...stableParams, ...extraParams})\n\n if (result.ok) {\n validationError = runValidator(result.data.data)\n\n setState(curState => {\n let newData = result.data.data\n\n if (\n appendData &&\n curState.data &&\n Array.isArray(curState.data) &&\n Array.isArray(result.data.data)\n ) {\n newData = [...curState.data, ...result.data.data] as S\n }\n\n return {\n ...curState,\n data: newData,\n pageInfo: result.data.pageInfo,\n loading: false,\n error: validationError ?? null,\n }\n })\n } else {\n throw result.error\n }\n } catch (err) {\n console.log('caught 1', err)\n queryError = formatError({hook}, err)\n }\n\n const error = validationError || queryError\n\n if (error && (setError || resetOnError)) {\n setState(curState => ({\n data: resetOnError ? null : curState.data,\n pageInfo: resetOnError\n ? {hasNextPage: false, endCursor: null}\n : curState.pageInfo,\n loading: false,\n error,\n }))\n }\n\n if (error && throwOnError) {\n throw error\n }\n },\n [action, stableParams, hook, runValidator]\n )\n\n const refetch = useCallback(async () => {\n await fetch({fetchPolicy: 'network-only'} as Partial<P>, {\n setLoading: false,\n resetOnError: false,\n throwOnError: true,\n })\n }, [fetch])\n\n const fetchMore = useCallback(async () => {\n if (!state.pageInfo.hasNextPage || !state.pageInfo.endCursor) return\n\n await fetch({after: state.pageInfo.endCursor} as Partial<P>, {\n setLoading: false,\n setError: false,\n resetOnError: false,\n throwOnError: true,\n appendData: true,\n })\n }, [state.pageInfo.hasNextPage, state.pageInfo.endCursor, fetch])\n\n useEffect(() => {\n if (skip) return\n\n fetch(\n {},\n {\n throwOnError: false,\n }\n )\n }, [fetch, skip])\n\n return {\n data: state.data,\n loading: state.loading,\n error: state.error,\n hasNextPage: state.pageInfo.hasNextPage,\n refetch,\n fetchMore,\n }\n}\n"],"names":["useShopActionsPaginatedDataFetching","action","params","options","state","setState","useState","skip","validator","hook","runValidator","useCallback","dataToValidate","err","MiniError","stableParams","useMemo","fetch","extraParams","setLoading","setError","resetOnError","throwOnError","appendData","queryError","validationError","curState","result","newData","formatError","error","refetch","fetchMore","useEffect"],"mappings":";;AAYO,MAAMA,IAAsC,CAOjDC,GACAC,GACAC,MAKqC;AACrC,QAAM,CAACC,GAAOC,CAAQ,IAAIC,EAKvB;AAAA,IACD,MAAM;AAAA,IACN,UAAU,EAAC,aAAa,IAAO,WAAW,KAAI;AAAA,IAC9C,SAAS;AAAA,IACT,OAAO;AAAA,EAAA,CACR,GAEKC,IAAOJ,GAAS,SAAS,IACzB,EAAC,WAAAK,GAAW,MAAAC,EAAA,IAAQN,GACpBO,IAAeC;AAAA,IACnB,CAACC,MAAoC;AAC/B,UAAA;AACF,eAAAJ,IAAYI,CAAc,GACnB;AAAA,eACAC,GAAK;AACR,eAAAA,aAAe,QAAcA,IAE1B,IAAIC,EAAU;AAAA,UACnB,MAAAL;AAAA,UACA,SAAS;AAAA,QAAA,CACV;AAAA,MAAA;AAAA,IAEL;AAAA,IACA,CAACD,GAAWC,CAAI;AAAA,EAClB,GAKMM,IAAeC,EAAQ,MAAMd,GAAQ,CAAC,KAAK,UAAUA,CAAM,CAAC,CAAC,GAQ7De,IAAQN;AAAA,IACZ,OACEO,GACA;AAAA,MACE,YAAAC,IAAa;AAAA,MACb,UAAAC,IAAW;AAAA,MACX,cAAAC,IAAe;AAAA,MACf,cAAAC,IAAe;AAAA,MACf,YAAAC,IAAa;AAAA,IACf,IAMI,OACD;AACH,UAAIC,IAA2B,MAC3BC,IAAgC;AAEpC,MAAApB,EAAS,CAAaqB,OAAA;AAAA,QACpB,GAAGA;AAAA,QACH,SAASP,IAAa,KAAOO,EAAS;AAAA,MAAA,EACtC;AAEE,UAAA;AACI,cAAAC,IAAS,MAAM1B,EAAO,EAAC,GAAGc,GAAc,GAAGG,GAAY;AAE7D,YAAIS,EAAO;AACS,UAAAF,IAAAf,EAAaiB,EAAO,KAAK,IAAI,GAE/CtB,EAAS,CAAYqB,MAAA;AACf,gBAAAE,IAAUD,EAAO,KAAK;AAE1B,mBACEJ,KACAG,EAAS,QACT,MAAM,QAAQA,EAAS,IAAI,KAC3B,MAAM,QAAQC,EAAO,KAAK,IAAI,MAE9BC,IAAU,CAAC,GAAGF,EAAS,MAAM,GAAGC,EAAO,KAAK,IAAI,IAG3C;AAAA,cACL,GAAGD;AAAA,cACH,MAAME;AAAA,cACN,UAAUD,EAAO,KAAK;AAAA,cACtB,SAAS;AAAA,cACT,OAAOF,KAAmB;AAAA,YAC5B;AAAA,UAAA,CACD;AAAA;AAED,gBAAME,EAAO;AAAA,eAERd,GAAK;AACJ,gBAAA,IAAI,YAAYA,CAAG,GAC3BW,IAAaK,EAAY,EAAC,MAAApB,EAAI,GAAGI,CAAG;AAAA,MAAA;AAGtC,YAAMiB,IAAQL,KAAmBD;AAajC,UAXIM,MAAUV,KAAYC,MACxBhB,EAAS,CAAaqB,OAAA;AAAA,QACpB,MAAML,IAAe,OAAOK,EAAS;AAAA,QACrC,UAAUL,IACN,EAAC,aAAa,IAAO,WAAW,KAAA,IAChCK,EAAS;AAAA,QACb,SAAS;AAAA,QACT,OAAAI;AAAA,MAAA,EACA,GAGAA,KAASR;AACL,cAAAQ;AAAA,IAEV;AAAA,IACA,CAAC7B,GAAQc,GAAcN,GAAMC,CAAY;AAAA,EAC3C,GAEMqB,IAAUpB,EAAY,YAAY;AACtC,UAAMM,EAAM,EAAC,aAAa,kBAA+B;AAAA,MACvD,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,cAAc;AAAA,IAAA,CACf;AAAA,EAAA,GACA,CAACA,CAAK,CAAC,GAEJe,IAAYrB,EAAY,YAAY;AACxC,IAAI,CAACP,EAAM,SAAS,eAAe,CAACA,EAAM,SAAS,aAEnD,MAAMa,EAAM,EAAC,OAAOb,EAAM,SAAS,aAA0B;AAAA,MAC3D,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,cAAc;AAAA,MACd,cAAc;AAAA,MACd,YAAY;AAAA,IAAA,CACb;AAAA,EAAA,GACA,CAACA,EAAM,SAAS,aAAaA,EAAM,SAAS,WAAWa,CAAK,CAAC;AAEhE,SAAAgB,EAAU,MAAM;AACd,IAAI1B,KAEJU;AAAA,MACE,CAAC;AAAA,MACD;AAAA,QACE,cAAc;AAAA,MAAA;AAAA,IAElB;AAAA,EAAA,GACC,CAACA,GAAOV,CAAI,CAAC,GAET;AAAA,IACL,MAAMH,EAAM;AAAA,IACZ,SAASA,EAAM;AAAA,IACf,OAAOA,EAAM;AAAA,IACb,aAAaA,EAAM,SAAS;AAAA,IAC5B,SAAA2B;AAAA,IACA,WAAAC;AAAA,EACF;AACF;"}