diff --git a/framework/bigcommerce/customer/use-customer.tsx b/framework/bigcommerce/customer/use-customer.tsx index 3929002f7..093007824 100644 --- a/framework/bigcommerce/customer/use-customer.tsx +++ b/framework/bigcommerce/customer/use-customer.tsx @@ -1,11 +1,10 @@ -import { HookHandler } from '@commerce/utils/types' +import { SWRHook } from '@commerce/utils/types' import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' import type { Customer, CustomerData } from '../api/customers' -import type { BigcommerceProvider } from '..' -export default useCustomer as UseCustomer +export default useCustomer as UseCustomer -export const handler: HookHandler = { +export const handler: SWRHook = { fetchOptions: { url: '/api/bigcommerce/customers', method: 'GET', @@ -14,11 +13,11 @@ export const handler: HookHandler = { const data = await fetch(options) return data?.customer ?? null }, - useHook({ input, useData }) { + useHook: ({ useData }) => (input) => { return useData({ swrOptions: { revalidateOnFocus: false, - ...input.swrOptions, + ...input?.swrOptions, }, }) }, diff --git a/framework/bigcommerce/product/use-search.tsx b/framework/bigcommerce/product/use-search.tsx index 0ff767d8a..0ee135032 100644 --- a/framework/bigcommerce/product/use-search.tsx +++ b/framework/bigcommerce/product/use-search.tsx @@ -1,9 +1,8 @@ -import { HookHandler } from '@commerce/utils/types' +import { SWRHook } from '@commerce/utils/types' import useSearch, { UseSearch } from '@commerce/product/use-search' import type { SearchProductsData } from '../api/catalog/products' -import type { BigcommerceProvider } from '..' -export default useSearch as UseSearch +export default useSearch as UseSearch export type SearchProductsInput = { search?: string @@ -12,7 +11,7 @@ export type SearchProductsInput = { sort?: string } -export const handler: HookHandler< +export const handler: SWRHook< SearchProductsData, SearchProductsInput, SearchProductsInput @@ -37,7 +36,7 @@ export const handler: HookHandler< method: options.method, }) }, - useHook({ input, useData }) { + useHook: ({ useData }) => (input = {}) => { return useData({ input: [ ['search', input.search], diff --git a/framework/bigcommerce/wishlist/use-wishlist.tsx b/framework/bigcommerce/wishlist/use-wishlist.tsx index a93f0f6a4..877a857c6 100644 --- a/framework/bigcommerce/wishlist/use-wishlist.tsx +++ b/framework/bigcommerce/wishlist/use-wishlist.tsx @@ -1,13 +1,12 @@ import { useMemo } from 'react' -import { HookHandler } from '@commerce/utils/types' +import { SWRHook } from '@commerce/utils/types' import useWishlist, { UseWishlist } from '@commerce/wishlist/use-wishlist' import type { Wishlist } from '../api/wishlist' import useCustomer from '../customer/use-customer' -import type { BigcommerceProvider } from '..' -export default useWishlist as UseWishlist +export default useWishlist as UseWishlist -export const handler: HookHandler< +export const handler: SWRHook< Wishlist | null, { includeProducts?: boolean }, { customerId?: number; includeProducts: boolean }, @@ -30,16 +29,16 @@ export const handler: HookHandler< method: options.method, }) }, - useHook({ input, useData }) { + useHook: ({ useData }) => (input) => { const { data: customer } = useCustomer() const response = useData({ input: [ ['customerId', (customer as any)?.id], - ['includeProducts', input.includeProducts], + ['includeProducts', input?.includeProducts], ], swrOptions: { revalidateOnFocus: false, - ...input.swrOptions, + ...input?.swrOptions, }, }) diff --git a/framework/commerce/cart/use-cart.tsx b/framework/commerce/cart/use-cart.tsx index 6053c91d7..fbed715c8 100644 --- a/framework/commerce/cart/use-cart.tsx +++ b/framework/commerce/cart/use-cart.tsx @@ -1,8 +1,8 @@ import Cookies from 'js-cookie' -import type { Cart } from '../types' +import { useHook, useSWRHook } from '../utils/use-hook' import type { HookFetcherFn, SWRHook } from '../utils/types' +import type { Cart } from '../types' import { Provider, useCommerce } from '..' -import { useHook, useSWRHook } from '@commerce/utils/use-hook' export type FetchCartInput = { cartId?: Cart['id'] diff --git a/framework/commerce/customer/use-customer.tsx b/framework/commerce/customer/use-customer.tsx index 25112128e..5d6416a4b 100644 --- a/framework/commerce/customer/use-customer.tsx +++ b/framework/commerce/customer/use-customer.tsx @@ -1,56 +1,20 @@ +import { useHook, useSWRHook } from '../utils/use-hook' +import { SWRFetcher } from '../utils/default-fetcher' +import type { HookFetcherFn, SWRHook } from '../utils/types' import type { Customer } from '../types' -import type { - Prop, - HookFetcherFn, - UseHookInput, - UseHookResponse, -} from '../utils/types' -import defaultFetcher from '../utils/default-fetcher' -import useData from '../utils/use-data' -import { Provider, useCommerce } from '..' +import { Provider } from '..' -export type UseCustomerHandler

= Prop< - Prop, - 'useCustomer' -> +export type UseCustomer< + H extends SWRHook = SWRHook +> = ReturnType -export type UseCustomerInput

= UseHookInput< - UseCustomerHandler

-> +export const fetcher: HookFetcherFn = SWRFetcher -export type CustomerResponse

= UseHookResponse< - UseCustomerHandler

-> +const fn = (provider: Provider) => provider.customer?.useCustomer! -export type UseCustomer

= Partial< - UseCustomerInput

-> extends UseCustomerInput

- ? (input?: UseCustomerInput

) => CustomerResponse

- : (input: UseCustomerInput

) => CustomerResponse

- -export const fetcher = defaultFetcher as HookFetcherFn - -export default function useCustomer

( - input: UseCustomerInput

= {} -) { - const { providerRef, fetcherRef } = useCommerce

() - - const provider = providerRef.current - const opts = provider.customer?.useCustomer - - const fetcherFn = opts?.fetcher ?? fetcher - const useHook = opts?.useHook ?? ((ctx) => ctx.useData()) - - return useHook({ - input, - useData(ctx) { - const response = useData( - { ...opts!, fetcher: fetcherFn }, - ctx?.input ?? [], - provider.fetcher ?? fetcherRef.current, - ctx?.swrOptions ?? input.swrOptions - ) - return response - }, - }) +const useCustomer: UseCustomer = (input) => { + const hook = useHook(fn) + return useSWRHook({ fetcher, ...hook })(input) } + +export default useCustomer diff --git a/framework/commerce/index.tsx b/framework/commerce/index.tsx index 6ce2c8176..baaf65406 100644 --- a/framework/commerce/index.tsx +++ b/framework/commerce/index.tsx @@ -21,13 +21,13 @@ export type Provider = CommerceConfig & { useRemoveItem?: MutationHook } wishlist?: { - useWishlist?: HookHandler + useWishlist?: SWRHook } customer: { - useCustomer?: HookHandler + useCustomer?: SWRHook } products: { - useSearch?: HookHandler + useSearch?: SWRHook } } diff --git a/framework/commerce/product/use-search.tsx b/framework/commerce/product/use-search.tsx index 1f887f5fe..d2b782045 100644 --- a/framework/commerce/product/use-search.tsx +++ b/framework/commerce/product/use-search.tsx @@ -1,57 +1,20 @@ +import { useHook, useSWRHook } from '../utils/use-hook' +import { SWRFetcher } from '../utils/default-fetcher' +import type { HookFetcherFn, SWRHook } from '../utils/types' import type { SearchProductsData } from '../types' -import type { - Prop, - HookFetcherFn, - UseHookInput, - UseHookResponse, -} from '../utils/types' -import defaultFetcher from '../utils/default-fetcher' -import useData from '../utils/use-data' -import { Provider, useCommerce } from '..' -import { BigcommerceProvider } from '@framework' +import { Provider } from '..' -export type UseSearchHandler

= Prop< - Prop, - 'useSearch' -> +export type UseSearch< + H extends SWRHook = SWRHook +> = ReturnType -export type UseSeachInput

= UseHookInput< - UseSearchHandler

-> +export const fetcher: HookFetcherFn = SWRFetcher -export type SearchResponse

= UseHookResponse< - UseSearchHandler

-> +const fn = (provider: Provider) => provider.products?.useSearch! -export type UseSearch

= Partial< - UseSeachInput

-> extends UseSeachInput

- ? (input?: UseSeachInput

) => SearchResponse

- : (input: UseSeachInput

) => SearchResponse

- -export const fetcher = defaultFetcher as HookFetcherFn - -export default function useSearch

( - input: UseSeachInput

= {} -) { - const { providerRef, fetcherRef } = useCommerce

() - - const provider = providerRef.current - const opts = provider.products?.useSearch - - const fetcherFn = opts?.fetcher ?? fetcher - const useHook = opts?.useHook ?? ((ctx) => ctx.useData()) - - return useHook({ - input, - useData(ctx) { - const response = useData( - { ...opts!, fetcher: fetcherFn }, - ctx?.input ?? [], - provider.fetcher ?? fetcherRef.current, - ctx?.swrOptions ?? input.swrOptions - ) - return response - }, - }) +const useSearch: UseSearch = (input) => { + const hook = useHook(fn) + return useSWRHook({ fetcher, ...hook })(input) } + +export default useSearch diff --git a/framework/commerce/utils/default-fetcher.ts b/framework/commerce/utils/default-fetcher.ts index 654da2499..493a9b5f9 100644 --- a/framework/commerce/utils/default-fetcher.ts +++ b/framework/commerce/utils/default-fetcher.ts @@ -1,6 +1,6 @@ import type { HookFetcherFn } from './types' -const defaultFetcher: HookFetcherFn = ({ options, fetch }) => +export const SWRFetcher: HookFetcherFn = ({ options, fetch }) => fetch(options) export const mutationFetcher: HookFetcherFn = ({ @@ -9,4 +9,4 @@ export const mutationFetcher: HookFetcherFn = ({ fetch, }) => fetch({ ...options, body: input }) -export default defaultFetcher +export default SWRFetcher diff --git a/framework/commerce/utils/use-hook.ts b/framework/commerce/utils/use-hook.ts index 830918de5..0ee1f852e 100644 --- a/framework/commerce/utils/use-hook.ts +++ b/framework/commerce/utils/use-hook.ts @@ -1,5 +1,5 @@ import { useCallback } from 'react' -import type { Fetcher, MutationHook, PickRequired, SWRHook } from './types' +import type { MutationHook, PickRequired, SWRHook } from './types' import { Provider, useCommerce } from '..' import useData from './use-data' diff --git a/framework/commerce/wishlist/use-wishlist.tsx b/framework/commerce/wishlist/use-wishlist.tsx index dc912bc98..7a93b20b1 100644 --- a/framework/commerce/wishlist/use-wishlist.tsx +++ b/framework/commerce/wishlist/use-wishlist.tsx @@ -1,56 +1,25 @@ +import { useHook, useSWRHook } from '../utils/use-hook' +import { SWRFetcher } from '../utils/default-fetcher' +import type { HookFetcherFn, SWRHook } from '../utils/types' import type { Wishlist } from '../types' -import type { - Prop, - HookFetcherFn, - UseHookInput, - UseHookResponse, -} from '../utils/types' -import defaultFetcher from '../utils/default-fetcher' -import useData from '../utils/use-data' -import { Provider, useCommerce } from '..' +import type { Provider } from '..' -export type UseWishlistHandler

= Prop< - Prop, - 'useWishlist' -> +export type UseWishlist< + H extends SWRHook = SWRHook< + Wishlist | null, + { includeProducts?: boolean }, + { customerId?: number; includeProducts: boolean }, + { isEmpty?: boolean } + > +> = ReturnType -export type UseWishlistInput

= UseHookInput< - UseWishlistHandler

-> +export const fetcher: HookFetcherFn = SWRFetcher -export type WishlistResponse

= UseHookResponse< - UseWishlistHandler

-> +const fn = (provider: Provider) => provider.wishlist?.useWishlist! -export type UseWishlist

= Partial< - UseWishlistInput

-> extends UseWishlistInput

- ? (input?: UseWishlistInput

) => WishlistResponse

- : (input: UseWishlistInput

) => WishlistResponse

- -export const fetcher = defaultFetcher as HookFetcherFn - -export default function useWishlist

( - input: UseWishlistInput

= {} -) { - const { providerRef, fetcherRef } = useCommerce

() - - const provider = providerRef.current - const opts = provider.wishlist?.useWishlist - - const fetcherFn = opts?.fetcher ?? fetcher - const useHook = opts?.useHook ?? ((ctx) => ctx.useData()) - - return useHook({ - input, - useData(ctx) { - const response = useData( - { ...opts!, fetcher: fetcherFn }, - ctx?.input ?? [], - provider.fetcher ?? fetcherRef.current, - ctx?.swrOptions ?? input.swrOptions - ) - return response - }, - }) +const useWishlist: UseWishlist = (input) => { + const hook = useHook(fn) + return useSWRHook({ fetcher, ...hook })(input) } + +export default useWishlist