Ctrl K
ComunidadGuías…

src/services/chartDataService.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import type { ConsoleClient } from '~/services/consoleClient'
import colors from 'tailwindcss/colors'
import { invokeCapgoApi } from '~/services/capgoApi'
import { getCachedChartData, hasCachedChartData, setCachedChartData } from '~/services/chartDataCache'
import { formatUtcDateParam, normalizeToUtcStartOfDay } from '~/services/date'

const SKIP_COLOR = 10
const colorKeys = Object.keys(colors)

function clampToToday(date: Date): Date {
  const today = normalizeToUtcStartOfDay()
  return date > today ? today : date
}

type VersionUsageKind = 'bundle' | 'native'

export interface UseChartDataOptions {
  forceRefetch?: boolean
}

function buildCacheKey(sessionId: string, appId: string, from: Date, to: Date, kind: VersionUsageKind) {
  return `${sessionId}|${appId}|${kind}|${formatUtcDateParam(from)}|${formatUtcDateParam(to)}`
}

async function getChartCacheSessionKey(capgo: ConsoleClient): Promise<string> {
  const { data } = await capgo.auth.getClaims()
  const sessionId = data?.claims?.session_id
  if (typeof sessionId === 'string' && sessionId.length > 0)
    return sessionId
  return 'anonymous'
}

export async function useChartData(
  capgo: ConsoleClient,
  appId: string,
  from: Date,
  to: Date,
  kind: VersionUsageKind = 'bundle',
  options?: UseChartDataOptions,
) {
  const sessionKey = await getChartCacheSessionKey(capgo)
  const cacheKey = buildCacheKey(sessionKey, appId, from, to, kind)

  if (!options?.forceRefetch && hasCachedChartData(cacheKey))
    return getCachedChartData(cacheKey)

  // Clamp the 'to' date to today - we can't fetch data for future dates
  const clampedTo = clampToToday(to)
  const fromParam = formatUtcDateParam(from)
  const toParam = formatUtcDateParam(clampedTo)
  const usagePath = kind === 'native' ? 'native_usage' : 'bundle_usage'
  const { error, data } = await invokeCapgoApi(`statistics/app/${appId}/${usagePath}?from=${fromParam}&to=${toParam}`, {
    client: capgo,
    method: 'GET',
  })
  if (error)
    return null

  interface ChartDataset {
    label: string
    data: number[]
    metaCounts?: number[]
  }

  interface ChartData {
    labels: string[]
    datasets: ChartDataset[]
    latestVersion: {
      name: string
      percentage: string
    }
    activeDevices?: {
      android: number
      ios: number
      electron: number
      unknown: number
      total: number
    }
    previousPeriodActiveDevices?: {
      android: number
      ios: number
      electron: number
      unknown: number
      total: number
    }
    dailyPlatformActive?: {
      labels: string[]
      android: number[]
      ios: number[]
      electron: number[]
      unknown: number[]
      total: number[]
    }
  }

  const chartDataFromApi = data as ChartData
  const finalData = {
    labels: chartDataFromApi.labels,
    datasets: chartDataFromApi.datasets.map((dataset, i) => {
      const color = colorKeys[(i + SKIP_COLOR) % colorKeys.length]
      const metaCounts = Array.isArray(dataset.metaCounts)
        ? dataset.metaCounts.map(value => Math.max(0, Math.round(Number(value) || 0)))
        : undefined

      return {
        borderColor: colors[color as keyof typeof colors][400],
        backgroundColor: colors[color as keyof typeof colors][200],
        tension: 0.3,
        pointRadius: 2,
        pointBorderWidth: 0,
        ...dataset,
        ...(metaCounts ? { metaCountValues: metaCounts } : {}),
      }
    }),
    latestVersion: chartDataFromApi.latestVersion,
    activeDevices: chartDataFromApi.activeDevices,
    previousPeriodActiveDevices: chartDataFromApi.previousPeriodActiveDevices,
    dailyPlatformActive: chartDataFromApi.dailyPlatformActive,
  }
  setCachedChartData(cacheKey, finalData)
  return finalData
}