import frappe from 'frappe'; import { cloneDeep } from 'lodash'; import { getCounts, getDeviceId, getInstanceId, getLocale } from './helpers'; import { Noun, Telemetry, Verb } from './types'; class TelemetryManager { #started = false; #telemetryObject: Partial = {}; start() { this.#telemetryObject.locale ||= getLocale(); this.#telemetryObject.deviceId ||= getDeviceId(); this.#telemetryObject.instanceId ||= getInstanceId(); this.#telemetryObject.openTime ||= new Date().valueOf(); this.#telemetryObject.timeline ??= []; this.#telemetryObject.errors ??= {}; this.#started = true; } log(verb: Verb, noun: Noun, more?: Record) { if (!this.#started) { this.start(); } const time = new Date().valueOf(); if (this.#telemetryObject.timeline === undefined) { this.#telemetryObject.timeline = []; } this.#telemetryObject.timeline.push({ time, verb, noun, more }); } error(name: string) { if (this.#telemetryObject.errors === undefined) { this.#telemetryObject.errors = {}; } this.#telemetryObject.errors[name] ??= 0; this.#telemetryObject.errors[name] += 1; } async stop() { // Will set ids if not set. this.start(); //@ts-ignore this.#telemetryObject.version = frappe.store.appVersion ?? ''; this.#telemetryObject.counts = await getCounts(); this.#telemetryObject.closeTime = new Date().valueOf(); } get telemetryObject(): Readonly> { return cloneDeep(this.#telemetryObject); } } export default new TelemetryManager();