import { CountMinSketchOptions, JsBloomOptions } from '@getkoala/edge-api-client' import type { Profile } from '../analytics/collector' import { Context } from '../analytics/event-context' import type { Event } from '../analytics/event-queue' import { PageView } from '../analytics/page/page-tracker' import { post, sendBeacon } from './fetch' async function postJson(path: string, body: object) { return post(path, body).then((res) => { if (!res.ok) { throw new Error(`${res.status} ${res.statusText}`) } const contentType = res.headers.get('content-type') if (contentType?.includes('application/json')) { return res.json() } return res.text() }) } export interface AccountScore { fit_grade: number fit_grade_letter: 'A' | 'B' | 'C' | 'D' | 'F' intent_grade: number intent_score_level: 'Very High' | 'High' | 'Medium' | 'Low' | 'None' overall_grade: number } export interface QualificationResult { account_score?: AccountScore } export type AnonymousProfile = { c?: CountMinSketchOptions b?: JsBloomOptions } export interface Qualification { profile_id: string qualification: QualificationResult a?: AnonymousProfile } export type Identify = { context: Context type: 'identify' traits?: Record sent_at?: string } /** * Qualify a profile and get the results. * This is ideal for when you need to know the * score before finishing an async operation. */ export async function qualify(project: string, profile: Profile): Promise { if (!profile.user.id) { throw new Error('missing profile id') } const result = await postJson(`/web/projects/${project}/profiles`, { profile_id: profile.user.id, email: profile.email, traits: profile.traits }) return { ...result, qualification: result.q } } export function collectIdentify(project: string, profile: Profile, identify: Identify) { return sendBeacon(`/web/projects/${project}/batch`, { profile_id: profile.user.id, email: profile.email, traits: profile.traits, identifies: [identify] }) } export function collectEvents(project: string, profile_id: string, events: Event[] = []) { if (events.length === 0) { return } return sendBeacon(`/web/projects/${project}/batch`, { profile_id, events }) } export function collectPages(project: string, profile_id: string, page_views: PageView[] = []) { if (page_views.length === 0) return return sendBeacon(`/web/projects/${project}/batch`, { profile_id, page_views }) }