Skip to content

Commit

Permalink
Lock the current cart so the queries do not get refreshed during load
Browse files Browse the repository at this point in the history
  • Loading branch information
paales committed Feb 16, 2024
1 parent 17ff02b commit 67c8327
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 23 deletions.
1 change: 1 addition & 0 deletions packages/magento-cart/hooks/CurrentCartId.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ query CurrentCartId {
currentCartId @client {
__typename
id
locked
}
}
1 change: 1 addition & 0 deletions packages/magento-cart/hooks/CurrentCartId.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ extend type Query {

type CurrentCartId {
id: String
locked: Boolean
}

input RegisterCartIdInput {
Expand Down
2 changes: 1 addition & 1 deletion packages/magento-cart/hooks/useAssignCurrentCartId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const CART_ID_COOKIE = 'cart'
export function writeCartId(cache: ApolloCache<object>, id: string | null = null) {
cache.writeQuery({
query: CurrentCartIdDocument,
data: { currentCartId: { __typename: 'CurrentCartId', id } },
data: { currentCartId: { __typename: 'CurrentCartId', locked: false, id } },
broadcast: true,
})
}
Expand Down
10 changes: 3 additions & 7 deletions packages/magento-cart/hooks/useCartQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,20 @@ export function useCartQuery<Q, V extends { cartId: string; [index: string]: unk
) {
const { allowUrl = true, ...queryOptions } = options
const router = useRouter()
const { currentCartId } = useCurrentCartId()
const { currentCartId, locked } = useCurrentCartId()

const urlCartId = router.query.cart_id
const usingUrl = allowUrl && typeof urlCartId === 'string'
const cartId = usingUrl ? urlCartId : currentCartId

if (usingUrl) queryOptions.fetchPolicy = 'cache-first'
if (locked) queryOptions.fetchPolicy = 'standby'

if (usingUrl && typeof queryOptions.returnPartialData === 'undefined')
queryOptions.returnPartialData = true

queryOptions.variables = { cartId, ...options?.variables } as V
queryOptions.skip = queryOptions?.skip || !cartId

const result = useQuery(document, queryOptions as QueryHookOptions<Q, V>)

return {
...result,
// error: called && !currentCartId ? noCartError : result.error,
}
return useQuery(document, queryOptions as QueryHookOptions<Q, V>)
}
6 changes: 1 addition & 5 deletions packages/magento-cart/hooks/useClearCurrentCartId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@ export function useClearCurrentCartId() {
const id = cache.readQuery({ query: CurrentCartIdDocument })?.currentCartId?.id
if (!id) return

cache.writeQuery({
query: CurrentCartIdDocument,
data: { currentCartId: { __typename: 'CurrentCartId', id: null } },
broadcast: true,
})
cache.evict({ fieldName: 'currentCartId', broadcast: true })
cookie(CART_ID_COOKIE, null)
}
}
7 changes: 6 additions & 1 deletion packages/magento-cart/hooks/useCurrentCartId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,10 @@ export function useCurrentCartId<
V extends CurrentCartIdQueryVariables,
>(options: QueryHookOptions<Q, V> = {}) {
const queryResults = useQuery<Q, V>(CurrentCartIdDocument, options)
return { currentCartId: queryResults.data?.currentCartId?.id || '', ...queryResults }

return {
currentCartId: queryResults.data?.currentCartId?.id || '',
locked: queryResults.data?.currentCartId?.locked || false,
...queryResults,
}
}
26 changes: 18 additions & 8 deletions packages/magento-cart/plugins/useSignInFormMergeCart.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,49 @@
import { useApolloClient } from '@graphcommerce/graphql'
import type { useSignInForm } from '@graphcommerce/magento-customer/hooks/useSignInForm'
import type { MethodPlugin } from '@graphcommerce/next-config'
import { useCurrentCartId, useAssignCurrentCartId } from '../hooks'
import { useAssignCurrentCartId } from '../hooks'
import { CurrentCartIdDocument } from '../hooks/CurrentCartId.gql'
import { CustomerCartDocument } from '../hooks/CustomerCart.gql'
import { UseMergeCustomerCartDocument } from '../hooks/UseMergeCustomerCart.gql'

export const func = 'useSignInForm'
export const exported = '@graphcommerce/magento-customer/hooks/useSignInForm'

const useSignInFormMergeCart: MethodPlugin<typeof useSignInForm> = (useSignInForm, options) => {
const { currentCartId } = useCurrentCartId()
const client = useApolloClient()
const assignCurrentCartId = useAssignCurrentCartId()

return useSignInForm({
...options,
onComplete: async (data, variables) => {
const currentCartId = client.cache.readQuery({ query: CurrentCartIdDocument })?.currentCartId
if (currentCartId?.id && !currentCartId.locked) {
client.cache.writeQuery({
query: CurrentCartIdDocument,
data: { currentCartId: { ...currentCartId, locked: true } },
})
}

await options.onComplete?.(data, variables)

const destinationCartId = (
await client.query({ query: CustomerCartDocument, fetchPolicy: 'network-only' })
).data.customerCart.id
const customerCart = await client.query({
query: CustomerCartDocument,
fetchPolicy: 'network-only',
})
const destinationCartId = customerCart.data.customerCart.id

// If we don't have a customer cart, we're done
// If the vistor cart is the same as the customer cart, we're done
if (!destinationCartId || currentCartId === destinationCartId) return
if (!destinationCartId || currentCartId?.id === destinationCartId) return

// Assign the customer cart as the new cart id
assignCurrentCartId(destinationCartId)

if (currentCartId) {
if (currentCartId?.id) {
await client
.mutate({
mutation: UseMergeCustomerCartDocument,
variables: { sourceCartId: currentCartId, destinationCartId },
variables: { sourceCartId: currentCartId.id, destinationCartId },
})
// We're not handling exceptions here:
// If the merge returns an error, we'll use the customer cart without merging the guest cart.
Expand Down
2 changes: 1 addition & 1 deletion packages/magento-customer/hooks/CustomerToken.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ extend type Query {
}

extend type CustomerToken {
createdAt: String
createdAt: String @deprecated(reason: "Value is not used in GraphCommerce, but still filled in.")
valid: Boolean
}

0 comments on commit 67c8327

Please sign in to comment.