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 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | 37x 37x 37x 37x 37x 13x 13x 13x 13x 13x 12x 12x 1x 1x 1x 37x 16x 6x 37x 2x 37x 34x | import { FingerprintContext, FingerprintContextInterface, VisitorQueryResult } from './fingerprint-context'
import { useCallback, useContext, useEffect, useMemo, useState } from 'react'
import deepEquals from 'fast-deep-equal'
import { toError } from './utils/to-error'
import { assertIsTruthy } from './utils/assert-is-truthy'
import { GetOptions, GetResult } from '@fingerprint/agent'
export interface UseVisitorDataConfig {
/**
* Determines whether the `getData()` method will be called immediately after the hook mounts or not
*/
immediate: boolean
}
export type UseVisitorDataOptions = GetOptions & UseVisitorDataConfig
export type UseVisitorDataReturn = VisitorQueryResult & {
/**
* Performs identification request to server and returns visitors data.
* */
getData: (getDataOptions?: GetOptions) => Promise<GetResult>
}
/**
* @example
* ```js
* const {
* // Request state
* data,
* isLoading,
* error,
* // A method to be called manually when the `immediate` field in the config is set to `false`:
* getData,
* } = useVisitorData({ extended: true, immediate: false });
* ```
* Use the `useVisitorData` hook in your components to perform identification requests with the Fingerprint API. The returned object contains information about loading status, errors, and visitor.
*
* @param {UseVisitorDataOptions} options for the `agent.get()` request and for hook
*/
export function useVisitorData(
{ immediate, ...getOptions }: UseVisitorDataOptions = { immediate: true }
): UseVisitorDataReturn {
assertIsTruthy(getOptions, 'getOptions')
const { getVisitorData } = useContext<FingerprintContextInterface>(FingerprintContext)
const [currentGetOptions, setCurrentGetOptions] = useState(getOptions)
const [queryState, setQueryState] = useState<VisitorQueryResult>({
isLoading: immediate,
data: undefined,
isFetched: false,
error: undefined,
})
const getData = useCallback<UseVisitorDataReturn['getData']>(
async (params = {}) => {
assertIsTruthy(params, 'getDataParams')
try {
setQueryState({
isLoading: true,
isFetched: false,
data: undefined,
error: undefined,
})
const getDataOptions: GetOptions = {
...currentGetOptions,
...params,
}
const result = await getVisitorData(getDataOptions)
setQueryState({
isLoading: false,
isFetched: true,
data: result,
error: undefined,
})
return result
} catch (unknownError) {
const error = toError(unknownError)
setQueryState({
isLoading: false,
isFetched: false,
data: undefined,
error,
})
throw error
}
},
[currentGetOptions, getVisitorData]
)
useEffect(() => {
if (immediate) {
getData().catch((error) => {
console.error(`Failed to fetch visitor data on mount: ${error}`)
})
}
}, [immediate, getData])
if (!Object.is(currentGetOptions, getOptions) && !deepEquals(currentGetOptions, getOptions)) {
setCurrentGetOptions(getOptions)
}
return useMemo(
() => ({
...queryState,
getData,
}),
[queryState, getData]
)
}
|