UNPKG

@applicaster/zapp-react-native-utils

Version:

Applicaster Zapp React Native utilities package

124 lines (102 loc) 3.42 kB
/* eslint-disable @typescript-eslint/no-use-before-define */ import * as R from "ramda"; import { NativeModules } from "react-native"; import { ANALYTICS_CORE_EVENTS } from "@applicaster/zapp-react-native-utils/analyticsUtils/events"; import { analyticsUtilsLogger } from "./logger"; const { AnalyticsBridge } = NativeModules; const startTime = {}; const endTime = {}; /** * this function will return true if the Analytics Bridge native module is missing. this * allows to skip execution and prevent a crash if this happens */ function guardAgainstUndefinedBridge() { if (!AnalyticsBridge) { analyticsUtilsLogger.warning({ message: "Analytics Bridge is missing - no event will be sent", }); return true; } return false; } /** * Post to application for event type and additional params * * @param eventName Analytic event name * @param payload Additonal parameters that will be passed with event */ export function postAnalyticEvent(eventName: string, payload = {}) { if (isValidAnalyticsData(eventName, payload)) { if (guardAgainstUndefinedBridge()) { return; } AnalyticsBridge.postEvent(eventName, payload); } } export function providePlugins(plugins, configs, callback) { if (guardAgainstUndefinedBridge()) { return; } AnalyticsBridge.setPlugins(plugins, configs, callback); } /** * Notify application that timed event was started for event type and additional params. * * @param eventName Analytic event name * @param payload Additonal parameters that will be passed with event */ export function startAnalyticsTimedEvent(eventName: string, payload: object) { if (isValidAnalyticsData(eventName, payload)) { if (guardAgainstUndefinedBridge()) { return; } startTime[eventName] = new Date(); } } /** * Notify application that timed event was finished for event type and additional params. * * @param eventName Analytic event name * @param payload Additonal parameters that will be passed with event */ export function endAnalyticsTimedEvent(eventName: string, payload: object) { if (isValidAnalyticsData(eventName, payload)) { if (guardAgainstUndefinedBridge()) { return; } if (!startTime[eventName]) { analyticsUtilsLogger.error({ message: `Mismatch in start/endAnalyticsTimedEvent ${eventName}`, }); } endTime[eventName] = new Date(); const toSeconds = (ms) => ms / 1000; const duration = startTime[eventName] ? toSeconds(endTime[eventName] - startTime[eventName]) : "N/A"; const updatedPayload = { duration, ...payload, }; AnalyticsBridge.postEvent( ANALYTICS_CORE_EVENTS.TIME_ON_SCREEN, updatedPayload ); startTime[eventName] = null; endTime[eventName] = null; } } /** * Checks if analytics data to pass wass passsed expected values * * @param eventName Analytic event name * @param payload Additonal parameters that will be passed with event * * @returns {boolean} True in case if parameters suitable for manager to send, otherwise false */ export function isValidAnalyticsData(eventName: string, payload: any = null) { const eventExist = R.is(String, eventName); // we allow payload to be null, but we're leveraging here the fact that typeof null === "object" const payloadObjectOrNil = typeof payload === "object"; return eventExist && payloadObjectOrNil; }