@shopify/shop-minis-react 0.3.4 → 0.4.1

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 (185) hide show
  1. package/dist/_virtual/index3.js +2 -5
  2. package/dist/_virtual/index3.js.map +1 -1
  3. package/dist/_virtual/index4.js +5 -2
  4. package/dist/_virtual/index4.js.map +1 -1
  5. package/dist/components/MinisContainer.js +11 -10
  6. package/dist/components/MinisContainer.js.map +1 -1
  7. package/dist/hooks/content/useContent.js +12 -18
  8. package/dist/hooks/content/useContent.js.map +1 -1
  9. package/dist/hooks/product/useCuratedProducts.js +9 -11
  10. package/dist/hooks/product/useCuratedProducts.js.map +1 -1
  11. package/dist/hooks/product/usePopularProducts.js +9 -11
  12. package/dist/hooks/product/usePopularProducts.js.map +1 -1
  13. package/dist/hooks/product/useProduct.js +11 -17
  14. package/dist/hooks/product/useProduct.js.map +1 -1
  15. package/dist/hooks/product/useProductList.js +10 -21
  16. package/dist/hooks/product/useProductList.js.map +1 -1
  17. package/dist/hooks/product/useProductLists.js +11 -13
  18. package/dist/hooks/product/useProductLists.js.map +1 -1
  19. package/dist/hooks/product/useProductMedia.js +12 -18
  20. package/dist/hooks/product/useProductMedia.js.map +1 -1
  21. package/dist/hooks/product/useProductSearch.js +34 -27
  22. package/dist/hooks/product/useProductSearch.js.map +1 -1
  23. package/dist/hooks/product/useProductVariants.js +11 -14
  24. package/dist/hooks/product/useProductVariants.js.map +1 -1
  25. package/dist/hooks/product/useProducts.js +12 -11
  26. package/dist/hooks/product/useProducts.js.map +1 -1
  27. package/dist/hooks/product/useRecommendedProducts.js +11 -13
  28. package/dist/hooks/product/useRecommendedProducts.js.map +1 -1
  29. package/dist/hooks/shop/useRecommendedShops.js +11 -13
  30. package/dist/hooks/shop/useRecommendedShops.js.map +1 -1
  31. package/dist/hooks/shop/useShop.js +12 -11
  32. package/dist/hooks/shop/useShop.js.map +1 -1
  33. package/dist/hooks/user/useBuyerAttributes.js +8 -10
  34. package/dist/hooks/user/useBuyerAttributes.js.map +1 -1
  35. package/dist/hooks/user/useCurrentUser.js +7 -9
  36. package/dist/hooks/user/useCurrentUser.js.map +1 -1
  37. package/dist/hooks/user/useFollowedShops.js +11 -14
  38. package/dist/hooks/user/useFollowedShops.js.map +1 -1
  39. package/dist/hooks/user/useOrders.js +7 -9
  40. package/dist/hooks/user/useOrders.js.map +1 -1
  41. package/dist/hooks/user/useRecentProducts.js +11 -13
  42. package/dist/hooks/user/useRecentProducts.js.map +1 -1
  43. package/dist/hooks/user/useRecentShops.js +10 -13
  44. package/dist/hooks/user/useRecentShops.js.map +1 -1
  45. package/dist/hooks/user/useSavedProducts.js +10 -13
  46. package/dist/hooks/user/useSavedProducts.js.map +1 -1
  47. package/dist/hooks/util/useImagePicker.js +13 -6
  48. package/dist/hooks/util/useImagePicker.js.map +1 -1
  49. package/dist/internal/reactQuery/MinisQueryProvider.js +11 -0
  50. package/dist/internal/reactQuery/MinisQueryProvider.js.map +1 -0
  51. package/dist/internal/reactQuery/queryClient.js +33 -0
  52. package/dist/internal/reactQuery/queryClient.js.map +1 -0
  53. package/dist/internal/reactQuery/useShopActionInfiniteQuery.js +52 -0
  54. package/dist/internal/reactQuery/useShopActionInfiniteQuery.js.map +1 -0
  55. package/dist/internal/reactQuery/useShopActionQuery.js +37 -0
  56. package/dist/internal/reactQuery/useShopActionQuery.js.map +1 -0
  57. package/dist/internal/utils/resizeImage.js +61 -0
  58. package/dist/internal/utils/resizeImage.js.map +1 -0
  59. package/dist/providers/ImagePickerProvider.js +123 -102
  60. package/dist/providers/ImagePickerProvider.js.map +1 -1
  61. 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
  62. 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
  63. 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
  64. 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
  65. 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
  66. 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
  67. 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
  68. 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
  69. 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
  70. 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
  71. 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
  72. 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
  73. 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
  74. 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
  75. 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
  76. 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
  77. 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
  78. 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
  79. 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
  80. 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
  81. 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
  82. 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
  83. 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
  84. 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
  85. 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
  86. 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
  87. 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
  88. 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
  89. 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
  90. 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
  91. 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
  92. 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
  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/IsRestoringProvider.js +7 -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/IsRestoringProvider.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/QueryClientProvider.js +17 -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/QueryClientProvider.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/QueryErrorResetBoundary.js +19 -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/QueryErrorResetBoundary.js.map +1 -0
  99. 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
  100. 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
  101. 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
  102. 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
  103. 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
  104. 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
  105. 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
  106. 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
  107. 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
  108. 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
  109. package/dist/shop-minis-react/node_modules/.pnpm/querystringify@2.2.0/node_modules/querystringify/index.js +1 -1
  110. package/dist/shop-minis-react/node_modules/.pnpm/video.js@8.23.3/node_modules/video.js/dist/video.es.js +1 -1
  111. package/package.json +2 -7
  112. package/src/components/MinisContainer.tsx +6 -3
  113. package/src/hooks/content/useContent.ts +6 -17
  114. package/src/hooks/product/useCuratedProducts.ts +4 -6
  115. package/src/hooks/product/usePopularProducts.ts +4 -6
  116. package/src/hooks/product/useProduct.ts +6 -17
  117. package/src/hooks/product/useProductList.ts +4 -19
  118. package/src/hooks/product/useProductLists.ts +4 -6
  119. package/src/hooks/product/useProductMedia.ts +6 -17
  120. package/src/hooks/product/useProductSearch.ts +19 -15
  121. package/src/hooks/product/useProductVariants.ts +5 -13
  122. package/src/hooks/product/useProducts.ts +8 -12
  123. package/src/hooks/product/useRecommendedProducts.ts +4 -6
  124. package/src/hooks/shop/useRecommendedShops.ts +4 -6
  125. package/src/hooks/shop/useShop.ts +8 -12
  126. package/src/hooks/user/useBuyerAttributes.ts +4 -6
  127. package/src/hooks/user/useCurrentUser.ts +4 -6
  128. package/src/hooks/user/useFollowedShops.ts +5 -13
  129. package/src/hooks/user/useOrders.ts +4 -6
  130. package/src/hooks/user/useRecentProducts.ts +4 -6
  131. package/src/hooks/user/useRecentShops.ts +5 -13
  132. package/src/hooks/user/useSavedProducts.ts +5 -13
  133. package/src/hooks/util/useImagePicker.test.tsx +193 -0
  134. package/src/hooks/util/useImagePicker.ts +24 -5
  135. package/src/internal/reactQuery/MinisQueryProvider.test.tsx +38 -0
  136. package/src/internal/reactQuery/MinisQueryProvider.tsx +16 -0
  137. package/src/internal/reactQuery/index.ts +8 -0
  138. package/src/internal/reactQuery/queryClient.test.tsx +91 -0
  139. package/src/internal/reactQuery/queryClient.ts +43 -0
  140. package/src/internal/reactQuery/useShopActionInfiniteQuery.test.tsx +357 -0
  141. package/src/internal/reactQuery/useShopActionInfiniteQuery.ts +129 -0
  142. package/src/internal/reactQuery/useShopActionQuery.test.tsx +184 -0
  143. package/src/internal/reactQuery/useShopActionQuery.ts +74 -0
  144. package/src/internal/utils/resizeImage.test.ts +314 -0
  145. package/src/internal/utils/resizeImage.ts +108 -0
  146. package/src/providers/ImagePickerProvider.test.tsx +32 -1
  147. package/src/providers/ImagePickerProvider.tsx +108 -65
  148. package/dist/internal/useShopActionsDataFetching.js +0 -79
  149. package/dist/internal/useShopActionsDataFetching.js.map +0 -1
  150. package/dist/internal/useShopActionsPaginatedDataFetching.js +0 -96
  151. package/dist/internal/useShopActionsPaginatedDataFetching.js.map +0 -1
  152. package/src/hooks/product/useProductSearch.test.ts +0 -470
  153. package/src/internal/useShopActionsDataFetching.test.ts +0 -465
  154. package/src/internal/useShopActionsDataFetching.ts +0 -150
  155. package/src/internal/useShopActionsPaginatedDataFetching.ts +0 -188
  156. package/src/stories/Accordion.stories.tsx +0 -124
  157. package/src/stories/AddToCart.stories.tsx +0 -251
  158. package/src/stories/Alert.stories.tsx +0 -38
  159. package/src/stories/AlertDialog.stories.tsx +0 -48
  160. package/src/stories/Avatar.stories.tsx +0 -29
  161. package/src/stories/Badge.stories.tsx +0 -46
  162. package/src/stories/Button.stories.tsx +0 -81
  163. package/src/stories/Card.stories.tsx +0 -40
  164. package/src/stories/Checkbox.stories.tsx +0 -44
  165. package/src/stories/FavoriteButton.stories.tsx +0 -58
  166. package/src/stories/IconButton.stories.tsx +0 -68
  167. package/src/stories/ImageContentWrapper.stories.tsx +0 -65
  168. package/src/stories/Input.stories.tsx +0 -44
  169. package/src/stories/Label.stories.tsx +0 -19
  170. package/src/stories/List.stories.tsx +0 -64
  171. package/src/stories/MerchantCard.stories.tsx +0 -127
  172. package/src/stories/ProductCard.stories.tsx +0 -92
  173. package/src/stories/ProductLink.stories.tsx +0 -46
  174. package/src/stories/ProductVariantPrice.stories.tsx +0 -70
  175. package/src/stories/Progress.stories.tsx +0 -30
  176. package/src/stories/PullToRefreshList.stories.tsx +0 -122
  177. package/src/stories/QuantitySelector.stories.tsx +0 -78
  178. package/src/stories/RadioGroup.stories.tsx +0 -51
  179. package/src/stories/Search.stories.tsx +0 -37
  180. package/src/stories/Select.stories.tsx +0 -85
  181. package/src/stories/Skeleton.stories.tsx +0 -19
  182. package/src/stories/TextInput.stories.tsx +0 -26
  183. package/src/stories/Toaster.stories.tsx +0 -46
  184. package/src/stories/Touchable.stories.tsx +0 -40
  185. package/src/stories/VideoPlayer.stories.tsx +0 -129
@@ -0,0 +1,52 @@
1
+ import { useMemo as P, useCallback as o } from "react";
2
+ import { useInfiniteQuery as x } from "../../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";
3
+ import { useShopMinisQueryClient as N } from "./queryClient.js";
4
+ function M(i, s, f, u) {
5
+ const { skip: c = !1 } = u ?? {}, l = N(), {
6
+ data: a,
7
+ fetchNextPage: r,
8
+ hasNextPage: g,
9
+ isLoading: p,
10
+ error: d,
11
+ refetch: n
12
+ } = x(
13
+ {
14
+ queryKey: i,
15
+ queryFn: async ({ pageParam: e }) => {
16
+ const t = await s({
17
+ ...f,
18
+ after: e
19
+ });
20
+ if (!t.ok)
21
+ throw t.error;
22
+ return t.data;
23
+ },
24
+ getNextPageParam: (e) => e.pageInfo.hasNextPage ? e.pageInfo.endCursor : void 0,
25
+ initialPageParam: void 0,
26
+ enabled: !c
27
+ // Caching disabled by default (handled by Apollo)
28
+ // fetchPolicy param is passed through to the action (Apollo layer)
29
+ },
30
+ l
31
+ ), h = P(() => {
32
+ if (!a?.pages || a.pages.length === 0) return null;
33
+ const e = a.pages[0].data;
34
+ return e == null ? null : Array.isArray(e) ? a.pages.flatMap((t) => t.data) : e;
35
+ }, [a?.pages]), y = o(async () => {
36
+ await r();
37
+ }, [r]), m = o(async () => {
38
+ await n();
39
+ }, [n]);
40
+ return {
41
+ data: h,
42
+ loading: p,
43
+ error: d,
44
+ hasNextPage: g ?? !1,
45
+ fetchMore: y,
46
+ refetch: m
47
+ };
48
+ }
49
+ export {
50
+ M as useShopActionInfiniteQuery
51
+ };
52
+ //# sourceMappingURL=useShopActionInfiniteQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useShopActionInfiniteQuery.js","sources":["../../../src/internal/reactQuery/useShopActionInfiniteQuery.ts"],"sourcesContent":["import {useCallback, useMemo} from 'react'\n\nimport {ShopActionResult} from '@shopify/shop-minis-platform/actions'\nimport {useInfiniteQuery} from '@tanstack/react-query'\n\nimport {DataHookFetchPolicy} from '../../types'\n\nimport {useShopMinisQueryClient} from './queryClient'\n\n/**\n * Helper to use React Query with Shop Actions (paginated)\n * Replaces useShopActionsPaginatedDataFetching\n *\n * @example\n * ```ts\n * // Example: Fetching saved products\n * const { getSavedProducts } = useShopActions()\n * const { data, loading, error, hasNextPage, fetchMore, refetch } =\n * useShopActionInfiniteQuery(\n * ['savedProducts', { includeSensitive }], // Query key\n * getSavedProducts, // Shop Action\n * { includeSensitive }, // Params (excludes 'after')\n * { skip: false } // Options\n * )\n * // data will be flattened array of products from all pages\n * ```\n */\nexport function useShopActionInfiniteQuery<\n TData,\n TParams extends {after?: string; fetchPolicy?: DataHookFetchPolicy},\n>(\n queryKey: unknown[],\n action: (params: TParams) => Promise<\n ShopActionResult<{\n data: TData\n pageInfo: {hasNextPage: boolean; endCursor: string | null}\n }>\n >,\n params: Omit<TParams, 'after'>,\n options?: {\n skip?: boolean\n }\n) {\n const {skip = false} = options ?? {}\n\n // Always use our SDK's QueryClient for isolation\n const queryClient = useShopMinisQueryClient()\n\n interface PageData {\n data: TData\n pageInfo: {hasNextPage: boolean; endCursor: string | null}\n }\n\n const {\n data,\n fetchNextPage,\n hasNextPage,\n isLoading,\n error,\n refetch: reactQueryRefetch,\n } = useInfiniteQuery<\n PageData,\n Error,\n {pages: PageData[]},\n unknown[],\n string | undefined\n >(\n {\n queryKey,\n queryFn: async ({pageParam}: {pageParam: string | undefined}) => {\n const result = await action({\n ...params,\n after: pageParam,\n } as TParams)\n\n if (!result.ok) {\n throw result.error\n }\n\n return result.data\n },\n getNextPageParam: (lastPage: PageData) =>\n lastPage.pageInfo.hasNextPage ? lastPage.pageInfo.endCursor : undefined,\n initialPageParam: undefined as string | undefined,\n enabled: !skip,\n // Caching disabled by default (handled by Apollo)\n // fetchPolicy param is passed through to the action (Apollo layer)\n },\n queryClient\n )\n\n // Flatten paginated data\n // For paginated queries, we expect TData to be an array type\n // Each page.data is an array that we concatenate together\n const flattenedData = useMemo(() => {\n if (!data?.pages || data.pages.length === 0) return null\n\n // If first page data is null/undefined, return null\n const firstPageData = data.pages[0].data\n if (firstPageData === null || firstPageData === undefined) return null\n\n // If data is array type, flatten all pages\n if (Array.isArray(firstPageData)) {\n return data.pages.flatMap((page: PageData) => page.data as any) as TData\n }\n\n // If data is not an array, just return the first page's data\n // (Though in practice, all Shop Minis paginated queries return arrays)\n return firstPageData as TData\n }, [data?.pages])\n\n // Wrap React Query functions to match expected API\n const fetchMore = useCallback(async () => {\n await fetchNextPage()\n }, [fetchNextPage])\n\n const refetch = useCallback(async () => {\n await reactQueryRefetch()\n }, [reactQueryRefetch])\n\n return {\n data: flattenedData,\n loading: isLoading,\n error: error as Error | null,\n hasNextPage: hasNextPage ?? false,\n fetchMore,\n refetch,\n }\n}\n"],"names":["useShopActionInfiniteQuery","queryKey","action","params","options","skip","queryClient","useShopMinisQueryClient","data","fetchNextPage","hasNextPage","isLoading","error","reactQueryRefetch","useInfiniteQuery","pageParam","result","lastPage","flattenedData","useMemo","firstPageData","page","fetchMore","useCallback","refetch"],"mappings":";;;AA2BO,SAASA,EAIdC,GACAC,GAMAC,GACAC,GAGA;AACA,QAAM,EAAC,MAAAC,IAAO,GAAK,IAAID,KAAW,CAAC,GAG7BE,IAAcC,EAAwB,GAOtC;AAAA,IACJ,MAAAC;AAAA,IACA,eAAAC;AAAA,IACA,aAAAC;AAAA,IACA,WAAAC;AAAA,IACA,OAAAC;AAAA,IACA,SAASC;AAAA,EAAA,IACPC;AAAA,IAOF;AAAA,MACE,UAAAb;AAAA,MACA,SAAS,OAAO,EAAC,WAAAc,QAAgD;AACzD,cAAAC,IAAS,MAAMd,EAAO;AAAA,UAC1B,GAAGC;AAAA,UACH,OAAOY;AAAA,QAAA,CACG;AAER,YAAA,CAACC,EAAO;AACV,gBAAMA,EAAO;AAGf,eAAOA,EAAO;AAAA,MAChB;AAAA,MACA,kBAAkB,CAACC,MACjBA,EAAS,SAAS,cAAcA,EAAS,SAAS,YAAY;AAAA,MAChE,kBAAkB;AAAA,MAClB,SAAS,CAACZ;AAAA;AAAA;AAAA,IAGZ;AAAA,IACAC;AAAA,EACF,GAKMY,IAAgBC,EAAQ,MAAM;AAClC,QAAI,CAACX,GAAM,SAASA,EAAK,MAAM,WAAW,EAAU,QAAA;AAGpD,UAAMY,IAAgBZ,EAAK,MAAM,CAAC,EAAE;AACpC,WAAIY,KAAkB,OAA4C,OAG9D,MAAM,QAAQA,CAAa,IACtBZ,EAAK,MAAM,QAAQ,CAACa,MAAmBA,EAAK,IAAW,IAKzDD;AAAA,EAAA,GACN,CAACZ,GAAM,KAAK,CAAC,GAGVc,IAAYC,EAAY,YAAY;AACxC,UAAMd,EAAc;AAAA,EAAA,GACnB,CAACA,CAAa,CAAC,GAEZe,IAAUD,EAAY,YAAY;AACtC,UAAMV,EAAkB;AAAA,EAAA,GACvB,CAACA,CAAiB,CAAC;AAEf,SAAA;AAAA,IACL,MAAMK;AAAA,IACN,SAASP;AAAA,IACT,OAAAC;AAAA,IACA,aAAaF,KAAe;AAAA,IAC5B,WAAAY;AAAA,IACA,SAAAE;AAAA,EACF;AACF;"}
@@ -0,0 +1,37 @@
1
+ import { useCallback as y } from "react";
2
+ import { useQuery as d } from "../../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";
3
+ import { useShopMinisQueryClient as p } from "./queryClient.js";
4
+ function k(t, o, a, n) {
5
+ const { skip: i = !1 } = n ?? {}, s = p(), {
6
+ data: u,
7
+ error: c,
8
+ isLoading: l,
9
+ refetch: r
10
+ } = d(
11
+ {
12
+ queryKey: t,
13
+ queryFn: async () => {
14
+ const e = await o(a);
15
+ if (!e.ok)
16
+ throw e.error;
17
+ return e.data.data;
18
+ },
19
+ enabled: !i
20
+ // Caching disabled by default (handled by Apollo)
21
+ // fetchPolicy param is passed through to the action (Apollo layer)
22
+ },
23
+ s
24
+ ), f = y(async () => {
25
+ await r();
26
+ }, [r]);
27
+ return {
28
+ data: u ?? null,
29
+ loading: l,
30
+ error: c,
31
+ refetch: f
32
+ };
33
+ }
34
+ export {
35
+ k as useShopActionQuery
36
+ };
37
+ //# sourceMappingURL=useShopActionQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useShopActionQuery.js","sources":["../../../src/internal/reactQuery/useShopActionQuery.ts"],"sourcesContent":["import {useCallback} from 'react'\n\nimport {ShopActionResult} from '@shopify/shop-minis-platform/actions'\nimport {useQuery} from '@tanstack/react-query'\n\nimport {DataHookFetchPolicy} from '../../types'\n\nimport {useShopMinisQueryClient} from './queryClient'\n\n/**\n * Helper to use React Query with Shop Actions (non-paginated)\n * Replaces useShopActionsDataFetching\n *\n * @example\n * ```ts\n * const { data, loading, error, refetch } = useShopActionQuery(\n * ['product', id],\n * getProduct,\n * { id },\n * { skip: false }\n * )\n * ```\n */\nexport function useShopActionQuery<\n TData,\n TParams extends {fetchPolicy?: DataHookFetchPolicy},\n>(\n queryKey: unknown[],\n action: (params: TParams) => Promise<ShopActionResult<{data: TData}>>,\n params: TParams,\n options?: {\n skip?: boolean\n }\n) {\n const {skip = false} = options ?? {}\n\n // Always use our SDK's QueryClient for isolation\n const queryClient = useShopMinisQueryClient()\n\n const {\n data,\n error,\n isLoading,\n refetch: reactQueryRefetch,\n } = useQuery(\n {\n queryKey,\n queryFn: async () => {\n const result = await action(params)\n\n if (!result.ok) {\n throw result.error\n }\n\n return result.data.data\n },\n enabled: !skip,\n // Caching disabled by default (handled by Apollo)\n // fetchPolicy param is passed through to the action (Apollo layer)\n },\n queryClient\n )\n\n const refetch = useCallback(async () => {\n await reactQueryRefetch()\n }, [reactQueryRefetch])\n\n return {\n data: data ?? null,\n loading: isLoading,\n error: error as Error | null,\n refetch,\n }\n}\n"],"names":["useShopActionQuery","queryKey","action","params","options","skip","queryClient","useShopMinisQueryClient","data","error","isLoading","reactQueryRefetch","useQuery","result","refetch","useCallback"],"mappings":";;;AAuBO,SAASA,EAIdC,GACAC,GACAC,GACAC,GAGA;AACA,QAAM,EAAC,MAAAC,IAAO,GAAK,IAAID,KAAW,CAAC,GAG7BE,IAAcC,EAAwB,GAEtC;AAAA,IACJ,MAAAC;AAAA,IACA,OAAAC;AAAA,IACA,WAAAC;AAAA,IACA,SAASC;AAAA,EAAA,IACPC;AAAA,IACF;AAAA,MACE,UAAAX;AAAA,MACA,SAAS,YAAY;AACb,cAAAY,IAAS,MAAMX,EAAOC,CAAM;AAE9B,YAAA,CAACU,EAAO;AACV,gBAAMA,EAAO;AAGf,eAAOA,EAAO,KAAK;AAAA,MACrB;AAAA,MACA,SAAS,CAACR;AAAA;AAAA;AAAA,IAGZ;AAAA,IACAC;AAAA,EACF,GAEMQ,IAAUC,EAAY,YAAY;AACtC,UAAMJ,EAAkB;AAAA,EAAA,GACvB,CAACA,CAAiB,CAAC;AAEf,SAAA;AAAA,IACL,MAAMH,KAAQ;AAAA,IACd,SAASE;AAAA,IACT,OAAAD;AAAA,IACA,SAAAK;AAAA,EACF;AACF;"}
@@ -0,0 +1,61 @@
1
+ const z = {
2
+ low: {
3
+ size: 1080,
4
+ compression: 0.7
5
+ },
6
+ medium: {
7
+ size: 1600,
8
+ compression: 0.85
9
+ },
10
+ high: {
11
+ size: 2048,
12
+ compression: 0.92
13
+ }
14
+ };
15
+ function f({
16
+ file: s,
17
+ quality: g,
18
+ customQuality: r
19
+ }) {
20
+ if (g === "original")
21
+ return Promise.resolve(s);
22
+ const c = z[g], d = r ? {
23
+ size: r.size ?? c.size,
24
+ compression: r.compression ?? c.compression
25
+ } : c, i = d.size;
26
+ return new Promise((h, a) => {
27
+ const t = new Image(), m = URL.createObjectURL(s);
28
+ t.onerror = () => {
29
+ URL.revokeObjectURL(m), a(new Error("Failed to load image"));
30
+ }, t.onload = () => {
31
+ URL.revokeObjectURL(m);
32
+ const n = document.createElement("canvas");
33
+ let e = t.width, o = t.height;
34
+ e > o ? e > i && (o *= i / e, e = i) : o > i && (e *= i / o, o = i), n.width = e, n.height = o;
35
+ const l = n.getContext("2d");
36
+ if (!l) {
37
+ a(new Error("Failed to get canvas context"));
38
+ return;
39
+ }
40
+ l.drawImage(t, 0, 0, e, o), n.toBlob(
41
+ (w) => {
42
+ if (!w) {
43
+ a(new Error("Failed to create blob"));
44
+ return;
45
+ }
46
+ const p = new File([w], s.name, {
47
+ type: "image/jpeg",
48
+ lastModified: Date.now()
49
+ });
50
+ h(p);
51
+ },
52
+ "image/jpeg",
53
+ d.compression
54
+ );
55
+ }, t.src = m;
56
+ });
57
+ }
58
+ export {
59
+ f as resizeImage
60
+ };
61
+ //# sourceMappingURL=resizeImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resizeImage.js","sources":["../../../src/internal/utils/resizeImage.ts"],"sourcesContent":["import type {\n ImageQuality,\n CustomImageQuality,\n} from '../../providers/ImagePickerProvider'\n\ninterface ResizeSettings {\n size: number\n compression: number\n}\n\nexport interface ResizeImageParams {\n file: File\n quality: ImageQuality\n customQuality?: CustomImageQuality\n}\n\nconst QUALITY_SETTINGS: {\n [key in Exclude<ImageQuality, 'original'>]: ResizeSettings\n} = {\n low: {\n size: 1080,\n compression: 0.7,\n },\n medium: {\n size: 1600,\n compression: 0.85,\n },\n high: {\n size: 2048,\n compression: 0.92,\n },\n} as const\n\nexport function resizeImage({\n file,\n quality,\n customQuality,\n}: ResizeImageParams): Promise<File> {\n if (quality === 'original') {\n return Promise.resolve(file)\n }\n\n const defaultSettings = QUALITY_SETTINGS[quality]\n const settings: ResizeSettings = customQuality\n ? {\n size: customQuality.size ?? defaultSettings.size,\n compression: customQuality.compression ?? defaultSettings.compression,\n }\n : defaultSettings\n const maxSize = settings.size\n\n return new Promise((resolve, reject) => {\n const img = new Image()\n const url = URL.createObjectURL(file)\n\n img.onerror = () => {\n URL.revokeObjectURL(url)\n reject(new Error('Failed to load image'))\n }\n\n img.onload = () => {\n URL.revokeObjectURL(url)\n\n const canvas = document.createElement('canvas')\n let width = img.width\n let height = img.height\n\n // Resize image dimensions maintaining aspect ratio\n if (width > height) {\n if (width > maxSize) {\n height *= maxSize / width\n width = maxSize\n }\n } else if (height > maxSize) {\n width *= maxSize / height\n height = maxSize\n }\n\n canvas.width = width\n canvas.height = height\n\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n reject(new Error('Failed to get canvas context'))\n return\n }\n ctx.drawImage(img, 0, 0, width, height)\n\n canvas.toBlob(\n blob => {\n if (!blob) {\n reject(new Error('Failed to create blob'))\n return\n }\n const resizedFile = new File([blob], file.name, {\n type: 'image/jpeg',\n lastModified: Date.now(),\n })\n resolve(resizedFile)\n },\n 'image/jpeg',\n settings.compression\n )\n }\n\n img.src = url\n })\n}\n"],"names":["QUALITY_SETTINGS","resizeImage","file","quality","customQuality","defaultSettings","settings","maxSize","resolve","reject","img","url","canvas","width","height","ctx","blob","resizedFile"],"mappings":"AAgBA,MAAMA,IAEF;AAAA,EACF,KAAK;AAAA,IACH,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EAAA;AAEjB;AAEO,SAASC,EAAY;AAAA,EAC1B,MAAAC;AAAA,EACA,SAAAC;AAAA,EACA,eAAAC;AACF,GAAqC;AACnC,MAAID,MAAY;AACP,WAAA,QAAQ,QAAQD,CAAI;AAGvB,QAAAG,IAAkBL,EAAiBG,CAAO,GAC1CG,IAA2BF,IAC7B;AAAA,IACE,MAAMA,EAAc,QAAQC,EAAgB;AAAA,IAC5C,aAAaD,EAAc,eAAeC,EAAgB;AAAA,EAAA,IAE5DA,GACEE,IAAUD,EAAS;AAEzB,SAAO,IAAI,QAAQ,CAACE,GAASC,MAAW;AAChC,UAAAC,IAAM,IAAI,MAAM,GAChBC,IAAM,IAAI,gBAAgBT,CAAI;AAEpC,IAAAQ,EAAI,UAAU,MAAM;AAClB,UAAI,gBAAgBC,CAAG,GAChBF,EAAA,IAAI,MAAM,sBAAsB,CAAC;AAAA,IAC1C,GAEAC,EAAI,SAAS,MAAM;AACjB,UAAI,gBAAgBC,CAAG;AAEjB,YAAAC,IAAS,SAAS,cAAc,QAAQ;AAC9C,UAAIC,IAAQH,EAAI,OACZI,IAASJ,EAAI;AAGjB,MAAIG,IAAQC,IACND,IAAQN,MACVO,KAAUP,IAAUM,GACZA,IAAAN,KAEDO,IAASP,MAClBM,KAASN,IAAUO,GACVA,IAAAP,IAGXK,EAAO,QAAQC,GACfD,EAAO,SAASE;AAEV,YAAAC,IAAMH,EAAO,WAAW,IAAI;AAClC,UAAI,CAACG,GAAK;AACD,QAAAN,EAAA,IAAI,MAAM,8BAA8B,CAAC;AAChD;AAAA,MAAA;AAEF,MAAAM,EAAI,UAAUL,GAAK,GAAG,GAAGG,GAAOC,CAAM,GAE/BF,EAAA;AAAA,QACL,CAAQI,MAAA;AACN,cAAI,CAACA,GAAM;AACF,YAAAP,EAAA,IAAI,MAAM,uBAAuB,CAAC;AACzC;AAAA,UAAA;AAEF,gBAAMQ,IAAc,IAAI,KAAK,CAACD,CAAI,GAAGd,EAAK,MAAM;AAAA,YAC9C,MAAM;AAAA,YACN,cAAc,KAAK,IAAI;AAAA,UAAA,CACxB;AACD,UAAAM,EAAQS,CAAW;AAAA,QACrB;AAAA,QACA;AAAA,QACAX,EAAS;AAAA,MACX;AAAA,IACF,GAEAI,EAAI,MAAMC;AAAA,EAAA,CACX;AACH;"}
@@ -1,167 +1,188 @@
1
- import { jsxs as x, jsx as h } from "react/jsx-runtime";
2
- import { useRef as p, useCallback as d, useEffect as I, useMemo as V, createContext as b, useContext as A } from "react";
3
- import { useRequestPermissions as L } from "../hooks/util/useRequestPermissions.js";
4
- import { useReportInteraction as M } from "../internal/useReportInteraction.js";
5
- const R = b(null);
6
- function F() {
7
- const g = A(R);
8
- if (!g)
1
+ import { jsxs as q, jsx as w } from "react/jsx-runtime";
2
+ import { useRef as o, useCallback as y, useEffect as A, useMemo as z, createContext as L, useContext as M } from "react";
3
+ import { useRequestPermissions as F } from "../hooks/util/useRequestPermissions.js";
4
+ import { useReportInteraction as G } from "../internal/useReportInteraction.js";
5
+ import { resizeImage as H } from "../internal/utils/resizeImage.js";
6
+ const V = L(null);
7
+ function B() {
8
+ const C = M(V);
9
+ if (!C)
9
10
  throw new Error(
10
11
  "useImagePickerContext must be used within an ImagePickerProvider"
11
12
  );
12
- return g;
13
+ return C;
13
14
  }
14
- function N({ children: g }) {
15
- const k = p(null), _ = p(null), E = p(null), t = p(null), e = p(null), f = p(null), n = p(null), { requestPermission: y } = L(), { reportInteraction: r } = M(), a = d(() => {
16
- if (f.current) {
17
- const { input: c, handler: i } = f.current;
18
- c.removeEventListener("cancel", i), f.current = null;
15
+ function D({ children: C }) {
16
+ const E = o(null), P = o(null), R = o(null), n = o(null), e = o(null), g = o(null), t = o(null), h = o("medium"), k = o(void 0), { requestPermission: v } = F(), { reportInteraction: r } = G(), u = y(() => {
17
+ if (g.current) {
18
+ const { input: c, handler: l } = g.current;
19
+ c.removeEventListener("cancel", l), g.current = null;
19
20
  }
20
- }, []), m = d(() => {
21
+ }, []), d = y(() => {
21
22
  if (e.current) {
22
23
  const c = new Error(
23
24
  "New file picker opened before previous completed"
24
25
  );
25
- n.current === "gallery" ? r({
26
+ t.current === "gallery" ? r({
26
27
  interactionType: "image_picker_error",
27
28
  interactionValue: c.message
28
- }) : n.current === "camera" && r({
29
+ }) : t.current === "camera" && r({
29
30
  interactionType: "camera_error",
30
31
  interactionValue: c.message
31
- }), e.current(c), t.current = null, e.current = null, n.current = null;
32
+ }), e.current(c), n.current = null, e.current = null, t.current = null, h.current = "medium", k.current = void 0;
32
33
  }
33
- }, [r]), C = d(
34
- (c) => {
35
- const i = c.target.files?.[0];
36
- i && t.current && (n.current === "gallery" ? r({
37
- interactionType: "image_picker_success"
38
- }) : n.current === "camera" && r({
39
- interactionType: "camera_success"
40
- }), t.current(i), t.current = null, e.current = null, n.current = null, a()), c.target.value = "";
34
+ }, [r]), _ = y(
35
+ async (c) => {
36
+ const { target: l } = c, p = l.files?.[0];
37
+ if (p && n.current) {
38
+ try {
39
+ const s = await H({
40
+ file: p,
41
+ quality: h.current,
42
+ customQuality: k.current
43
+ });
44
+ t.current === "gallery" ? r({
45
+ interactionType: "image_picker_success"
46
+ }) : t.current === "camera" && r({
47
+ interactionType: "camera_success"
48
+ }), n.current(s);
49
+ } catch (s) {
50
+ console.warn("Image resize failed, using original:", s), n.current && n.current(p);
51
+ }
52
+ n.current = null, e.current = null, t.current = null, u();
53
+ }
54
+ l.value = "";
41
55
  },
42
- [a, r]
43
- ), P = d(() => new Promise((c, i) => {
44
- m(), a(), t.current = c, e.current = i, n.current = "gallery";
45
- const u = k.current;
46
- if (!u) {
47
- const o = new Error("Gallery input not found");
48
- r({
49
- interactionType: "image_picker_error",
50
- interactionValue: o.message
51
- }), i(o), t.current = null, e.current = null, n.current = null;
52
- return;
53
- }
54
- const s = () => {
55
- if (e.current) {
56
- const o = new Error("User cancelled file selection");
56
+ [u, r]
57
+ ), I = y(
58
+ ({ quality: c = "medium", customQuality: l } = {}) => new Promise((p, s) => {
59
+ d(), u(), h.current = c, k.current = l, n.current = p, e.current = s, t.current = "gallery";
60
+ const i = E.current;
61
+ if (!i) {
62
+ const m = new Error("Gallery input not found");
57
63
  r({
58
64
  interactionType: "image_picker_error",
59
- interactionValue: o.message
60
- }), e.current(o), t.current = null, e.current = null, n.current = null;
65
+ interactionValue: m.message
66
+ }), s(m), n.current = null, e.current = null, t.current = null;
67
+ return;
61
68
  }
62
- a();
63
- };
64
- u.addEventListener("cancel", s), f.current = { input: u, handler: s }, r({
65
- interactionType: "image_picker_open"
66
- }), y({ permission: "CAMERA" }).then(() => {
67
- u.click();
68
- }).catch(() => {
69
- u.click();
70
- });
71
- }), [
72
- m,
73
- a,
74
- y,
75
- r
76
- ]), v = d(
77
- (c = "back") => new Promise((i, u) => {
78
- m(), a(), t.current = i, e.current = u, n.current = "camera";
79
- const s = c === "front" ? _.current : E.current;
80
- if (!s) {
81
- const l = new Error("Camera input not found");
69
+ const f = () => {
70
+ if (e.current) {
71
+ const m = new Error("User cancelled file selection");
72
+ r({
73
+ interactionType: "image_picker_error",
74
+ interactionValue: m.message
75
+ }), e.current(m), n.current = null, e.current = null, t.current = null;
76
+ }
77
+ u();
78
+ };
79
+ i.addEventListener("cancel", f), g.current = { input: i, handler: f }, r({
80
+ interactionType: "image_picker_open"
81
+ }), v({ permission: "CAMERA" }).then(() => {
82
+ i.click();
83
+ }).catch(() => {
84
+ i.click();
85
+ });
86
+ }),
87
+ [
88
+ d,
89
+ u,
90
+ v,
91
+ r
92
+ ]
93
+ ), T = y(
94
+ ({
95
+ cameraFacing: c = "back",
96
+ quality: l = "medium",
97
+ customQuality: p
98
+ } = {}) => new Promise((s, i) => {
99
+ d(), u(), h.current = l, k.current = p, n.current = s, e.current = i, t.current = "camera";
100
+ const f = c === "front" ? P.current : R.current;
101
+ if (!f) {
102
+ const a = new Error("Camera input not found");
82
103
  r({
83
104
  interactionType: "camera_error",
84
- interactionValue: l.message
85
- }), u(l), t.current = null, e.current = null, n.current = null;
105
+ interactionValue: a.message
106
+ }), i(a), n.current = null, e.current = null, t.current = null;
86
107
  return;
87
108
  }
88
- const o = () => {
109
+ const m = () => {
89
110
  if (e.current) {
90
- const l = new Error("User cancelled camera");
111
+ const a = new Error("User cancelled camera");
91
112
  r({
92
113
  interactionType: "camera_error",
93
- interactionValue: l.message
94
- }), e.current(l), t.current = null, e.current = null, n.current = null;
114
+ interactionValue: a.message
115
+ }), e.current(a), n.current = null, e.current = null, t.current = null;
95
116
  }
96
- a();
117
+ u();
97
118
  };
98
- s.addEventListener("cancel", o), f.current = { input: s, handler: o }, r({
119
+ f.addEventListener("cancel", m), g.current = { input: f, handler: m }, r({
99
120
  interactionType: "camera_open"
100
- }), y({ permission: "CAMERA" }).then(({ granted: l }) => {
101
- if (l)
102
- s.click();
121
+ }), v({ permission: "CAMERA" }).then(({ granted: a }) => {
122
+ if (a)
123
+ f.click();
103
124
  else {
104
- const w = new Error("Camera permission not granted");
125
+ const x = new Error("Camera permission not granted");
105
126
  r({
106
127
  interactionType: "camera_error",
107
- interactionValue: w.message
108
- }), u(w), t.current = null, e.current = null, n.current = null;
128
+ interactionValue: x.message
129
+ }), i(x), n.current = null, e.current = null, t.current = null;
109
130
  }
110
131
  }).catch(() => {
111
- const l = new Error("Camera permission not granted");
112
- u(l), t.current = null, e.current = null, n.current = null;
132
+ const a = new Error("Camera permission not granted");
133
+ i(a), n.current = null, e.current = null, t.current = null;
113
134
  });
114
135
  }),
115
136
  [
116
- m,
117
- a,
118
- y,
137
+ d,
138
+ u,
139
+ v,
119
140
  r
120
141
  ]
121
142
  );
122
- I(() => () => {
123
- m(), a();
124
- }, [m, a]);
125
- const T = V(
143
+ A(() => () => {
144
+ d(), u();
145
+ }, [d, u]);
146
+ const b = z(
126
147
  () => ({
127
- openCamera: v,
128
- openGallery: P
148
+ openCamera: T,
149
+ openGallery: I
129
150
  }),
130
- [v, P]
151
+ [T, I]
131
152
  );
132
- return /* @__PURE__ */ x(R.Provider, { value: T, children: [
133
- g,
134
- /* @__PURE__ */ h(
153
+ return /* @__PURE__ */ q(V.Provider, { value: b, children: [
154
+ C,
155
+ /* @__PURE__ */ w(
135
156
  "input",
136
157
  {
137
- ref: k,
158
+ ref: E,
138
159
  type: "file",
139
160
  accept: "image/*",
140
- onChange: C,
161
+ onChange: _,
141
162
  style: { display: "none" },
142
163
  "aria-hidden": "true"
143
164
  }
144
165
  ),
145
- /* @__PURE__ */ h(
166
+ /* @__PURE__ */ w(
146
167
  "input",
147
168
  {
148
- ref: _,
169
+ ref: P,
149
170
  type: "file",
150
171
  accept: "image/*",
151
172
  capture: "user",
152
- onChange: C,
173
+ onChange: _,
153
174
  style: { display: "none" },
154
175
  "aria-hidden": "true"
155
176
  }
156
177
  ),
157
- /* @__PURE__ */ h(
178
+ /* @__PURE__ */ w(
158
179
  "input",
159
180
  {
160
- ref: E,
181
+ ref: R,
161
182
  type: "file",
162
183
  accept: "image/*",
163
184
  capture: "environment",
164
- onChange: C,
185
+ onChange: _,
165
186
  style: { display: "none" },
166
187
  "aria-hidden": "true"
167
188
  }
@@ -169,7 +190,7 @@ function N({ children: g }) {
169
190
  ] });
170
191
  }
171
192
  export {
172
- N as ImagePickerProvider,
173
- F as useImagePickerContext
193
+ D as ImagePickerProvider,
194
+ B as useImagePickerContext
174
195
  };
175
196
  //# sourceMappingURL=ImagePickerProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImagePickerProvider.js","sources":["../../src/providers/ImagePickerProvider.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n useRef,\n useCallback,\n useEffect,\n useMemo,\n} from 'react'\n\nimport {useRequestPermissions} from '../hooks/util/useRequestPermissions'\nimport {useReportInteraction} from '../internal/useReportInteraction'\n\nexport type CameraFacing = 'front' | 'back'\n\ninterface ImagePickerContextValue {\n openCamera: (cameraFacing?: CameraFacing) => Promise<File>\n openGallery: () => Promise<File>\n}\n\nconst ImagePickerContext = createContext<ImagePickerContextValue | null>(null)\n\nexport function useImagePickerContext() {\n const context = useContext(ImagePickerContext)\n if (!context) {\n throw new Error(\n 'useImagePickerContext must be used within an ImagePickerProvider'\n )\n }\n return context\n}\n\ninterface ImagePickerProviderProps {\n children: React.ReactNode\n}\n\nexport function ImagePickerProvider({children}: ImagePickerProviderProps) {\n const galleryInputRef = useRef<HTMLInputElement>(null)\n const frontCameraInputRef = useRef<HTMLInputElement>(null)\n const backCameraInputRef = useRef<HTMLInputElement>(null)\n const resolveRef = useRef<((file: File) => void) | null>(null)\n const rejectRef = useRef<((reason: Error) => void) | null>(null)\n const activeCancelHandlerRef = useRef<{\n input: HTMLInputElement\n handler: () => void\n } | null>(null)\n const activeOperationRef = useRef<'gallery' | 'camera' | null>(null)\n\n const {requestPermission} = useRequestPermissions()\n const {reportInteraction} = useReportInteraction()\n\n const cleanupCancelHandler = useCallback(() => {\n if (activeCancelHandlerRef.current) {\n const {input, handler} = activeCancelHandlerRef.current\n input.removeEventListener('cancel', handler)\n activeCancelHandlerRef.current = null\n }\n }, [])\n\n const rejectPendingPromise = useCallback(() => {\n if (rejectRef.current) {\n const error = new Error(\n 'New file picker opened before previous completed'\n )\n if (activeOperationRef.current === 'gallery') {\n reportInteraction({\n interactionType: 'image_picker_error',\n interactionValue: error.message,\n })\n } else if (activeOperationRef.current === 'camera') {\n reportInteraction({\n interactionType: 'camera_error',\n interactionValue: error.message,\n })\n }\n\n rejectRef.current(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n }\n }, [reportInteraction])\n\n const handleFileChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0]\n\n if (file && resolveRef.current) {\n // Report success based on the active operation\n if (activeOperationRef.current === 'gallery') {\n reportInteraction({\n interactionType: 'image_picker_success',\n })\n } else if (activeOperationRef.current === 'camera') {\n reportInteraction({\n interactionType: 'camera_success',\n })\n }\n\n resolveRef.current(file)\n\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n\n cleanupCancelHandler()\n }\n\n event.target.value = ''\n },\n [cleanupCancelHandler, reportInteraction]\n )\n\n const openGallery = useCallback(() => {\n return new Promise<File>((resolve, reject) => {\n rejectPendingPromise()\n cleanupCancelHandler()\n\n resolveRef.current = resolve\n rejectRef.current = reject\n activeOperationRef.current = 'gallery'\n\n const input = galleryInputRef.current\n\n if (!input) {\n const error = new Error('Gallery input not found')\n reportInteraction({\n interactionType: 'image_picker_error',\n interactionValue: error.message,\n })\n reject(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n return\n }\n\n const handleCancel = () => {\n if (rejectRef.current) {\n const error = new Error('User cancelled file selection')\n reportInteraction({\n interactionType: 'image_picker_error',\n interactionValue: error.message,\n })\n rejectRef.current(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n }\n cleanupCancelHandler()\n }\n\n input.addEventListener('cancel', handleCancel)\n activeCancelHandlerRef.current = {input, handler: handleCancel}\n\n reportInteraction({\n interactionType: 'image_picker_open',\n })\n\n requestPermission({permission: 'CAMERA'})\n .then(() => {\n // This will show both Camera and Gallery\n input.click()\n })\n .catch(() => {\n // Show only Gallery\n input.click()\n })\n })\n }, [\n rejectPendingPromise,\n cleanupCancelHandler,\n requestPermission,\n reportInteraction,\n ])\n\n const openCamera = useCallback(\n (cameraFacing: CameraFacing = 'back') => {\n return new Promise<File>((resolve, reject) => {\n rejectPendingPromise()\n cleanupCancelHandler()\n\n resolveRef.current = resolve\n rejectRef.current = reject\n activeOperationRef.current = 'camera'\n\n const input =\n cameraFacing === 'front'\n ? frontCameraInputRef.current\n : backCameraInputRef.current\n\n if (!input) {\n const error = new Error('Camera input not found')\n reportInteraction({\n interactionType: 'camera_error',\n interactionValue: error.message,\n })\n reject(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n return\n }\n\n const handleCancel = () => {\n if (rejectRef.current) {\n const error = new Error('User cancelled camera')\n reportInteraction({\n interactionType: 'camera_error',\n interactionValue: error.message,\n })\n rejectRef.current(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n }\n cleanupCancelHandler()\n }\n\n input.addEventListener('cancel', handleCancel)\n activeCancelHandlerRef.current = {input, handler: handleCancel}\n\n reportInteraction({\n interactionType: 'camera_open',\n })\n\n requestPermission({permission: 'CAMERA'})\n .then(({granted}) => {\n if (granted) {\n input.click()\n } else {\n const error = new Error('Camera permission not granted')\n reportInteraction({\n interactionType: 'camera_error',\n interactionValue: error.message,\n })\n reject(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n }\n })\n .catch(() => {\n const error = new Error('Camera permission not granted')\n reject(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n })\n })\n },\n [\n rejectPendingPromise,\n cleanupCancelHandler,\n requestPermission,\n reportInteraction,\n ]\n )\n\n useEffect(() => {\n return () => {\n rejectPendingPromise()\n cleanupCancelHandler()\n }\n }, [rejectPendingPromise, cleanupCancelHandler])\n\n const contextValue: ImagePickerContextValue = useMemo(\n () => ({\n openCamera,\n openGallery,\n }),\n [openCamera, openGallery]\n )\n\n return (\n <ImagePickerContext.Provider value={contextValue}>\n {children}\n <input\n ref={galleryInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileChange}\n style={{display: 'none'}}\n aria-hidden=\"true\"\n />\n <input\n ref={frontCameraInputRef}\n type=\"file\"\n accept=\"image/*\"\n capture=\"user\"\n onChange={handleFileChange}\n style={{display: 'none'}}\n aria-hidden=\"true\"\n />\n <input\n ref={backCameraInputRef}\n type=\"file\"\n accept=\"image/*\"\n capture=\"environment\"\n onChange={handleFileChange}\n style={{display: 'none'}}\n aria-hidden=\"true\"\n />\n </ImagePickerContext.Provider>\n )\n}\n"],"names":["ImagePickerContext","createContext","useImagePickerContext","context","useContext","ImagePickerProvider","children","galleryInputRef","useRef","frontCameraInputRef","backCameraInputRef","resolveRef","rejectRef","activeCancelHandlerRef","activeOperationRef","requestPermission","useRequestPermissions","reportInteraction","useReportInteraction","cleanupCancelHandler","useCallback","input","handler","rejectPendingPromise","error","handleFileChange","event","file","openGallery","resolve","reject","handleCancel","openCamera","cameraFacing","granted","useEffect","contextValue","useMemo","jsxs","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"ImagePickerProvider.js","sources":["../../src/providers/ImagePickerProvider.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n useRef,\n useCallback,\n useEffect,\n useMemo,\n} from 'react'\n\nimport {useRequestPermissions} from '../hooks/util/useRequestPermissions'\nimport {useReportInteraction} from '../internal/useReportInteraction'\nimport {resizeImage} from '../internal/utils/resizeImage'\n\nexport type ImageQuality = 'low' | 'medium' | 'high' | 'original'\nexport type CameraFacing = 'front' | 'back'\nexport interface CustomImageQuality {\n size?: number\n compression?: number\n}\n\nexport interface OpenCameraParams {\n cameraFacing?: CameraFacing\n quality?: ImageQuality\n customQuality?: CustomImageQuality\n}\n\nexport interface OpenGalleryParams {\n quality?: ImageQuality\n customQuality?: CustomImageQuality\n}\n\ninterface ImagePickerContextValue {\n openCamera: (params?: OpenCameraParams) => Promise<File>\n openGallery: (params?: OpenGalleryParams) => Promise<File>\n}\n\nconst ImagePickerContext = createContext<ImagePickerContextValue | null>(null)\n\nexport function useImagePickerContext() {\n const context = useContext(ImagePickerContext)\n if (!context) {\n throw new Error(\n 'useImagePickerContext must be used within an ImagePickerProvider'\n )\n }\n return context\n}\n\ninterface ImagePickerProviderProps {\n children: React.ReactNode\n}\n\nexport function ImagePickerProvider({children}: ImagePickerProviderProps) {\n const galleryInputRef = useRef<HTMLInputElement>(null)\n const frontCameraInputRef = useRef<HTMLInputElement>(null)\n const backCameraInputRef = useRef<HTMLInputElement>(null)\n const resolveRef = useRef<((file: File) => void) | null>(null)\n const rejectRef = useRef<((reason: Error) => void) | null>(null)\n const activeCancelHandlerRef = useRef<{\n input: HTMLInputElement\n handler: () => void\n } | null>(null)\n const activeOperationRef = useRef<'gallery' | 'camera' | null>(null)\n const qualityRef = useRef<ImageQuality>('medium')\n const customQualityRef = useRef<CustomImageQuality>(undefined)\n const {requestPermission} = useRequestPermissions()\n const {reportInteraction} = useReportInteraction()\n\n const cleanupCancelHandler = useCallback(() => {\n if (activeCancelHandlerRef.current) {\n const {input, handler} = activeCancelHandlerRef.current\n input.removeEventListener('cancel', handler)\n activeCancelHandlerRef.current = null\n }\n }, [])\n\n const rejectPendingPromise = useCallback(() => {\n if (rejectRef.current) {\n const error = new Error(\n 'New file picker opened before previous completed'\n )\n if (activeOperationRef.current === 'gallery') {\n reportInteraction({\n interactionType: 'image_picker_error',\n interactionValue: error.message,\n })\n } else if (activeOperationRef.current === 'camera') {\n reportInteraction({\n interactionType: 'camera_error',\n interactionValue: error.message,\n })\n }\n\n rejectRef.current(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n qualityRef.current = 'medium'\n customQualityRef.current = undefined\n }\n }, [reportInteraction])\n\n const handleFileChange = useCallback(\n async (event: React.ChangeEvent<HTMLInputElement>) => {\n const {target} = event\n const file = target.files?.[0]\n\n if (file && resolveRef.current) {\n try {\n const resizedFile = await resizeImage({\n file,\n quality: qualityRef.current,\n customQuality: customQualityRef.current,\n })\n\n if (activeOperationRef.current === 'gallery') {\n reportInteraction({\n interactionType: 'image_picker_success',\n })\n } else if (activeOperationRef.current === 'camera') {\n reportInteraction({\n interactionType: 'camera_success',\n })\n }\n\n resolveRef.current(resizedFile)\n } catch (error) {\n console.warn('Image resize failed, using original:', error)\n if (resolveRef.current) {\n resolveRef.current(file)\n }\n }\n\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n\n cleanupCancelHandler()\n }\n\n target.value = ''\n },\n [cleanupCancelHandler, reportInteraction]\n )\n\n const openGallery = useCallback(\n ({quality = 'medium', customQuality}: OpenGalleryParams = {}) => {\n return new Promise<File>((resolve, reject) => {\n rejectPendingPromise()\n cleanupCancelHandler()\n\n qualityRef.current = quality\n customQualityRef.current = customQuality\n resolveRef.current = resolve\n rejectRef.current = reject\n activeOperationRef.current = 'gallery'\n const input = galleryInputRef.current\n\n if (!input) {\n const error = new Error('Gallery input not found')\n reportInteraction({\n interactionType: 'image_picker_error',\n interactionValue: error.message,\n })\n reject(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n return\n }\n\n const handleCancel = () => {\n if (rejectRef.current) {\n const error = new Error('User cancelled file selection')\n reportInteraction({\n interactionType: 'image_picker_error',\n interactionValue: error.message,\n })\n rejectRef.current(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n }\n cleanupCancelHandler()\n }\n\n input.addEventListener('cancel', handleCancel)\n activeCancelHandlerRef.current = {input, handler: handleCancel}\n\n reportInteraction({\n interactionType: 'image_picker_open',\n })\n\n requestPermission({permission: 'CAMERA'})\n .then(() => {\n // This will show both Camera and Gallery\n input.click()\n })\n .catch(() => {\n // Show only Gallery\n input.click()\n })\n })\n },\n [\n rejectPendingPromise,\n cleanupCancelHandler,\n requestPermission,\n reportInteraction,\n ]\n )\n\n const openCamera = useCallback(\n ({\n cameraFacing = 'back',\n quality = 'medium',\n customQuality,\n }: OpenCameraParams = {}) => {\n return new Promise<File>((resolve, reject) => {\n rejectPendingPromise()\n cleanupCancelHandler()\n\n qualityRef.current = quality\n customQualityRef.current = customQuality\n resolveRef.current = resolve\n rejectRef.current = reject\n activeOperationRef.current = 'camera'\n\n const input =\n cameraFacing === 'front'\n ? frontCameraInputRef.current\n : backCameraInputRef.current\n\n if (!input) {\n const error = new Error('Camera input not found')\n reportInteraction({\n interactionType: 'camera_error',\n interactionValue: error.message,\n })\n reject(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n return\n }\n\n const handleCancel = () => {\n if (rejectRef.current) {\n const error = new Error('User cancelled camera')\n reportInteraction({\n interactionType: 'camera_error',\n interactionValue: error.message,\n })\n rejectRef.current(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n }\n cleanupCancelHandler()\n }\n\n input.addEventListener('cancel', handleCancel)\n activeCancelHandlerRef.current = {input, handler: handleCancel}\n\n reportInteraction({\n interactionType: 'camera_open',\n })\n\n requestPermission({permission: 'CAMERA'})\n .then(({granted}) => {\n if (granted) {\n input.click()\n } else {\n const error = new Error('Camera permission not granted')\n reportInteraction({\n interactionType: 'camera_error',\n interactionValue: error.message,\n })\n reject(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n }\n })\n .catch(() => {\n const error = new Error('Camera permission not granted')\n reject(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n })\n })\n },\n [\n rejectPendingPromise,\n cleanupCancelHandler,\n requestPermission,\n reportInteraction,\n ]\n )\n\n useEffect(() => {\n return () => {\n rejectPendingPromise()\n cleanupCancelHandler()\n }\n }, [rejectPendingPromise, cleanupCancelHandler])\n\n const contextValue: ImagePickerContextValue = useMemo(\n () => ({\n openCamera,\n openGallery,\n }),\n [openCamera, openGallery]\n )\n\n return (\n <ImagePickerContext.Provider value={contextValue}>\n {children}\n <input\n ref={galleryInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileChange}\n style={{display: 'none'}}\n aria-hidden=\"true\"\n />\n <input\n ref={frontCameraInputRef}\n type=\"file\"\n accept=\"image/*\"\n capture=\"user\"\n onChange={handleFileChange}\n style={{display: 'none'}}\n aria-hidden=\"true\"\n />\n <input\n ref={backCameraInputRef}\n type=\"file\"\n accept=\"image/*\"\n capture=\"environment\"\n onChange={handleFileChange}\n style={{display: 'none'}}\n aria-hidden=\"true\"\n />\n </ImagePickerContext.Provider>\n )\n}\n"],"names":["ImagePickerContext","createContext","useImagePickerContext","context","useContext","ImagePickerProvider","children","galleryInputRef","useRef","frontCameraInputRef","backCameraInputRef","resolveRef","rejectRef","activeCancelHandlerRef","activeOperationRef","qualityRef","customQualityRef","requestPermission","useRequestPermissions","reportInteraction","useReportInteraction","cleanupCancelHandler","useCallback","input","handler","rejectPendingPromise","error","handleFileChange","event","target","file","resizedFile","resizeImage","openGallery","quality","customQuality","resolve","reject","handleCancel","openCamera","cameraFacing","granted","useEffect","contextValue","useMemo","jsxs","jsx"],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { Subscribable as i } from "./subscribable.js";
2
+ import { isServer as t } from "./utils.js";
3
+ var n = class extends i {
4
+ #e;
5
+ #s;
6
+ #i;
7
+ constructor() {
8
+ super(), this.#i = (s) => {
9
+ if (!t && window.addEventListener) {
10
+ const e = () => s();
11
+ return window.addEventListener("visibilitychange", e, !1), () => {
12
+ window.removeEventListener("visibilitychange", e);
13
+ };
14
+ }
15
+ };
16
+ }
17
+ onSubscribe() {
18
+ this.#s || this.setEventListener(this.#i);
19
+ }
20
+ onUnsubscribe() {
21
+ this.hasListeners() || (this.#s?.(), this.#s = void 0);
22
+ }
23
+ setEventListener(s) {
24
+ this.#i = s, this.#s?.(), this.#s = s((e) => {
25
+ typeof e == "boolean" ? this.setFocused(e) : this.onFocus();
26
+ });
27
+ }
28
+ setFocused(s) {
29
+ this.#e !== s && (this.#e = s, this.onFocus());
30
+ }
31
+ onFocus() {
32
+ const s = this.isFocused();
33
+ this.listeners.forEach((e) => {
34
+ e(s);
35
+ });
36
+ }
37
+ isFocused() {
38
+ return typeof this.#e == "boolean" ? this.#e : globalThis.document?.visibilityState !== "hidden";
39
+ }
40
+ }, h = new n();
41
+ export {
42
+ n as FocusManager,
43
+ h as focusManager
44
+ };
45
+ //# sourceMappingURL=focusManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focusManager.js","sources":["../../../../../../../../../../node_modules/.pnpm/@tanstack+query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/focusManager.js"],"sourcesContent":["// src/focusManager.ts\nimport { Subscribable } from \"./subscribable.js\";\nimport { isServer } from \"./utils.js\";\nvar FocusManager = class extends Subscribable {\n #focused;\n #cleanup;\n #setup;\n constructor() {\n super();\n this.#setup = (onFocus) => {\n if (!isServer && window.addEventListener) {\n const listener = () => onFocus();\n window.addEventListener(\"visibilitychange\", listener, false);\n return () => {\n window.removeEventListener(\"visibilitychange\", listener);\n };\n }\n return;\n };\n }\n onSubscribe() {\n if (!this.#cleanup) {\n this.setEventListener(this.#setup);\n }\n }\n onUnsubscribe() {\n if (!this.hasListeners()) {\n this.#cleanup?.();\n this.#cleanup = void 0;\n }\n }\n setEventListener(setup) {\n this.#setup = setup;\n this.#cleanup?.();\n this.#cleanup = setup((focused) => {\n if (typeof focused === \"boolean\") {\n this.setFocused(focused);\n } else {\n this.onFocus();\n }\n });\n }\n setFocused(focused) {\n const changed = this.#focused !== focused;\n if (changed) {\n this.#focused = focused;\n this.onFocus();\n }\n }\n onFocus() {\n const isFocused = this.isFocused();\n this.listeners.forEach((listener) => {\n listener(isFocused);\n });\n }\n isFocused() {\n if (typeof this.#focused === \"boolean\") {\n return this.#focused;\n }\n return globalThis.document?.visibilityState !== \"hidden\";\n }\n};\nvar focusManager = new FocusManager();\nexport {\n FocusManager,\n focusManager\n};\n//# sourceMappingURL=focusManager.js.map"],"names":["FocusManager","Subscribable","#focused","#cleanup","#setup","onFocus","isServer","listener","setup","focused","isFocused","focusManager"],"mappings":";;AAGG,IAACA,IAAe,cAAcC,EAAa;AAAA,EAC5CC;AAAA,EACAC;AAAA,EACAC;AAAA,EACA,cAAc;AACZ,UAAO,GACP,KAAKA,KAAS,CAACC,MAAY;AACzB,UAAI,CAACC,KAAY,OAAO,kBAAkB;AACxC,cAAMC,IAAW,MAAMF,EAAS;AAChC,sBAAO,iBAAiB,oBAAoBE,GAAU,EAAK,GACpD,MAAM;AACX,iBAAO,oBAAoB,oBAAoBA,CAAQ;AAAA,QACxD;AAAA,MACT;AAAA,IAEK;AAAA,EACL;AAAA,EACE,cAAc;AACZ,IAAK,KAAKJ,MACR,KAAK,iBAAiB,KAAKC,EAAM;AAAA,EAEvC;AAAA,EACE,gBAAgB;AACd,IAAK,KAAK,mBACR,KAAKD,KAAY,GACjB,KAAKA,KAAW;AAAA,EAEtB;AAAA,EACE,iBAAiBK,GAAO;AACtB,SAAKJ,KAASI,GACd,KAAKL,KAAY,GACjB,KAAKA,KAAWK,EAAM,CAACC,MAAY;AACjC,MAAI,OAAOA,KAAY,YACrB,KAAK,WAAWA,CAAO,IAEvB,KAAK,QAAS;AAAA,IAEtB,CAAK;AAAA,EACL;AAAA,EACE,WAAWA,GAAS;AAElB,IADgB,KAAKP,OAAaO,MAEhC,KAAKP,KAAWO,GAChB,KAAK,QAAS;AAAA,EAEpB;AAAA,EACE,UAAU;AACR,UAAMC,IAAY,KAAK,UAAW;AAClC,SAAK,UAAU,QAAQ,CAACH,MAAa;AACnC,MAAAA,EAASG,CAAS;AAAA,IACxB,CAAK;AAAA,EACL;AAAA,EACE,YAAY;AACV,WAAI,OAAO,KAAKR,MAAa,YACpB,KAAKA,KAEP,WAAW,UAAU,oBAAoB;AAAA,EACpD;AACA,GACIS,IAAe,IAAIX,EAAY;","x_google_ignoreList":[0]}