All files / src getOptionsCacheKey.ts

84% Statements 21/25
83.33% Branches 20/24
100% Functions 6/6
83.33% Lines 20/24

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      32x 9x     29x 7x       7x 7x   21x 19x   7x   7x     22x       60x 38x     22x       22x 18x     4x 4x                   20x       20x            
import { UseVisitorDataOptions } from './useVisitorData'
 
function sortObjectKeys(value: unknown, seen = new Set<object>()): unknown {
  if (Array.isArray(value)) {
    return value.map((item) => sortObjectKeys(item, seen))
  }
 
  if (value !== null && typeof value === 'object') {
    Iif (seen.has(value)) {
      throw new TypeError('Cannot serialize a circular value')
    }
 
    seen.add(value)
    const sortedValue = Object.fromEntries(
      Object.entries(value)
        .sort(([leftKey], [rightKey]) => (leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0))
        .map(([key, item]) => [key, sortObjectKeys(item, seen)])
    )
    seen.delete(value)
 
    return sortedValue
  }
 
  return value
}
 
function serializeCacheValue(value: unknown): string {
  if (value === undefined) {
    return 'undefined:'
  }
 
  Iif (value === null) {
    return 'null:'
  }
 
  if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
    return `${typeof value}:${String(value)}`
  }
 
  try {
    return `json:${JSON.stringify(sortObjectKeys(value))}`
  } catch {
    return `unserializable:${typeof value}`
  }
}
 
/**
 * Stable (cache) key for `GetOptions` object used for request deduplication and semantic equality.
 */
export function getOptionsCacheKey(options?: UseVisitorDataOptions): string {
  Iif (!options) {
    return ''
  }
 
  return JSON.stringify([
    serializeCacheValue(options.tags),
    serializeCacheValue(options.linkedId),
    serializeCacheValue(options.timeout),
  ])
}