All files useVisitorData.ts

100% Statements 19/19
100% Branches 4/4
100% Functions 6/6
100% Lines 15/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67                                                  19x 19x   19x   7x 7x 7x 7x 4x             3x         3x 1x     7x   6x         19x   19x              
import { useCallback, useContext, useState } from 'react'
import { FingerprintJsProContextInterface, FingerprintJsProContext } from './FingerprintJsProContext'
import { GetDataOptions, QueryResult, VisitorQueryContext, VisitorData, Tags } from './types'
import { IdentificationError } from './errors'
 
/**
 * Use the `useVisitorData` hook in your components to perform identification requests with the FingerprintJS API.
 *
 * @example
 * ```jsx
 * const {
 *   // Request state
 *   isLoading,
 *   // Error info
 *   error,
 *   // Visitor info
 *   data,
 *   // A method to be called to initiate request
 *   getData,
 * } = useVisitorData();
 * ```
 *
 * @group Hooks approach
 */
export function useVisitorData(): VisitorQueryContext {
  const { getVisitorData } = useContext<FingerprintJsProContextInterface>(FingerprintJsProContext)
  const [state, setState] = useState<QueryResult<VisitorData, IdentificationError>>({})
 
  const getData = useCallback<VisitorQueryContext['getData']>(
    async (tags?: Tags, linkedId?: string, options?: GetDataOptions) => {
      let result: VisitorData | null = null
      try {
        setState((state) => ({ ...state, isLoading: true }))
        result = await getVisitorData(tags, linkedId, options)
        setState((state) => ({
          ...state,
          data: result as VisitorData,
          isLoading: false,
          error: undefined,
        }))
      } catch (error) {
        setState((state) => ({
          ...state,
          data: undefined,
          error: error as IdentificationError,
        }))
        if (options?.throwOnError) {
          throw error
        }
      } finally {
        setState((state) => (state.isLoading ? { ...state, isLoading: false } : state))
      }
      return result
    },
    [getVisitorData]
  )
 
  const { isLoading, data, error } = state
 
  return {
    isLoading,
    data,
    error,
    getData,
  }
}