CosmWasm / ts-codegen

Convert your CosmWasm smart contracts into dev-friendly TypeScript classes so you can focus on shipping code.
https://cosmology.zone/products/ts-codegen
Apache License 2.0
116 stars 29 forks source link

Optionally generate query keys factory for the useQueries #56

Closed adairrr closed 2 years ago

adairrr commented 2 years ago

This PR allows the user to specify queryKeys option for the react-query generation so that the following (truncated) will be generated:

export const cw3FlexMultisigQueryKeys = {
  contract: [
    {
      contract: 'cw3FlexMultisig',
    },
  ] as const,
  address: (contractAddress: string) =>
    [{ ...cw3FlexMultisigQueryKeys.contract[0], address: contractAddress }] as const,
...
  proposal: (contractAddress: string, args?: Record<string, unknown>) =>
    [
      { ...cw3FlexMultisigQueryKeys.address(contractAddress)[0], method: 'proposal', args },
    ] as const,
// we use the underscore method here on purpose for clarity
  listProposals: (contractAddress: string, args?: Record<string, unknown>) =>
    [
      { ...cw3FlexMultisigQueryKeys.address(contractAddress)[0], method: 'list_proposals', args },
    ] as const,
...
}
export function useCw3FlexMultisigProposalQuery({
  client,
  args,
  options,
}: Cw3FlexMultisigProposalQuery) {
  return useQuery<ProposalResponse, Error, ProposalResponse>(
-     ['cw3FlexMultisigListVoters', client?.contractAddress, JSON.stringify(args)],
+    cw3FlexMultisigQueryKeys.proposal(client.contractAddress, args),
    () =>
      client
        ? client.proposal({
            proposalId: args.proposalId,
          })
        : Promise.reject(new Error('Invalid client')),
    { ...options, enabled: !!client && (options?.enabled != undefined ? options.enabled : true) }
  )
}

Please see https://tkdodo.eu/blog/effective-react-query-keys

This allows the following:

// remove everything related to any of these contracts
queryClient.removeQueries([{ contract: 'cw3FlexMultisig' }])
queryClient.removeQueries(cw3FlexMultisigQueryKeys.contract)

// reset all the queries for this specific contract address
queryClient.resetQueries([{ contract: 'cw3FlexMultisig', address: 'juno1ua2ak7ucrjc5vfzlzeyaw9shrpr2srqggquanqmztfv2fzqvyfhsu2pnzj' }])
queryClient.resetQueries(cw3FlexMultisigQueryKeys.address('juno...u2pnzj'))

// invalidate all queries for this specific query method
queryClient.invalidateQueries([{ contract: 'cw3FlexMultisig' , address: 'juno1ua2...hsu2pnzj', method: 'list_voters'
}}])
queryClient.invalidateQueries(cw3FlexMultisigQueryKeys.listVoters('juno1....u2pnzj'))

(https://tanstack.com/query/v4/docs/reference/QueryClient#queryclientsetquerydata) AND allows for use of setting query data if fetched outside of react query, so that fewer network calls have to be duplicated:

queryClient.setQueryData(cw3FlexMultisigQueryKeys.listVoters('juno1....u2pnzj'), [{ addr: 'juno...xx', weight: 1}])

Note that it is updated for the optionalClient to accept an undefined contract address :2

Also note that it removes the strongly typed (string | undefined)[]) and leaves it to inference.`