@applicaster/zapp-react-native-utils
Version:
Applicaster Zapp React Native utilities package
124 lines (102 loc) • 3.42 kB
text/typescript
/* 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;
}