0.1.0 • Published 11 months ago

@instalog.dev/expo v0.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
11 months ago

Instalog Expo

An Expo module wrapper for the Instalog analytics and logging SDK, making it easy to integrate Instalog into your Expo applications.

Installation

npm install @instalog.dev/expo

Expo Config Plugin

This package auto-installs necessary native dependencies for Expo projects.

Android Configuration

For Android, make sure to add the Instalog Feedback Activity to your AndroidManifest.xml:

<activity
  android:name="dev.instalog.mobile.feedback.InstalogFeedbackActivity"
  android:label="Instalog"
  android:theme="@style/Theme.Instalog" />

This should be placed inside the <application> tags of your manifest file.

Usage

Initialization

Initialize the Instalog SDK at the beginning of your app:

import { Instalog } from '@instalog.dev/expo';

// Initialize with default settings
await Instalog.initialize('YOUR_API_KEY');

// Or with custom options
await Instalog.initialize('YOUR_API_KEY', {
  isLogEnabled: true,
  isCrashEnabled: true,
  isFeedbackEnabled: true,
  isLoggerEnabled: false, // Debug logging
  autoCaptureCrashes: true, // Automatically capture unhandled JS errors
  errorGrouping: {
    enabled: true,
    flushIntervalMs: 30000, // 30 seconds
    errorThreshold: 5,
    timeWindowMs: 60000, // 1 minute
    flushOnBackground: true,
    requireNetwork: true,
    maxErrorsPerGroup: 10,
    dynamicFlushInterval: true,
  }
});

// Identify your user after initialization
await Instalog.identifyUser("user123");

User Identification

Identify your users to track their activity across sessions:

await Instalog.identifyUser('user123');

Event Logging

Track user actions and events in your app:

await Instalog.logEvent('button_clicked', {
  button_name: 'submit',
  screen: 'login',
});

Feedback Collection

Show a feedback modal to collect user feedback:

await Instalog.showFeedbackModal();

Crash Reporting

Crash reporting is automatically enabled after initialization. The SDK can automatically capture unhandled JavaScript errors when autoCaptureCrashes is enabled (default).

You can also manually report crashes:

try {
  // Your code that might throw an exception
} catch (error) {
  await Instalog.sendCrash('Error name', error.stack || error.toString());
}

For more structured error reporting, you can use the formatErrorReport helper:

try {
  // Your code that might throw an exception
} catch (error) {
  const formattedError = Instalog.formatErrorReport(error, errorInfo);
  await Instalog.sendCrash('Caught Error', formattedError);
}

For testing, you can simulate a crash:

await Instalog.simulateCrash();

Global Error Handling

The SDK automatically sets up global error handling when initialized with autoCaptureCrashes: true (default). This captures unhandled JavaScript errors and reports them to Instalog.

You can test this functionality with:

// This will trigger the global error handler
setTimeout(() => {
  throw new Error("Test Global Error");
}, 0);

API Reference

Instalog.initialize(key: string, options?: InstalogOptions): Promise<boolean>

Initializes the SDK with your API key and optional configuration.

Options:

OptionTypeDefaultDescription
isLogEnabledbooleanfalseEnable event logging
isLoggerEnabledbooleanfalseEnable debug logging
isCrashEnabledbooleanfalseEnable crash reporting
isFeedbackEnabledbooleanfalseEnable feedback collection
autoCaptureCrashesbooleantrueAutomatically capture unhandled JS errors
errorGroupingobject(see below)Configure how errors are grouped and reported

Error Grouping Options:

OptionTypeDefaultDescription
enabledbooleantrueEnable error grouping
flushIntervalMsnumber30000Interval to flush error groups (ms)
errorThresholdnumber5Number of errors to trigger flush
timeWindowMsnumber60000Time window for grouping errors (ms)
flushOnBackgroundbooleantrueFlush errors when app goes to background
requireNetworkbooleantrueOnly flush when network is available
maxErrorsPerGroupnumber10Max errors to store per group
dynamicFlushIntervalbooleantrueAdjust flush interval based on error volume

Instalog.identifyUser(userId: string): Promise<boolean>

Identifies the current user.

Instalog.logEvent(event: string, params?: Record<string, any>): Promise<boolean>

Logs an event with optional parameters.

Instalog.showFeedbackModal(): Promise<boolean>

Shows the feedback collection modal.

Instalog.sendCrash(error: string, stack: string): Promise<boolean>

Manually sends a crash report.

Instalog.formatErrorReport(error: Error, errorInfo?: any): string

Formats an error into a structured report for sending.

Instalog.simulateCrash(): Promise<boolean>

Simulates a crash for testing.

Example Application

import { Instalog } from "@instalog.dev/expo";
import React, { useState, useEffect } from "react";
import { StyleSheet, Text, View, TouchableOpacity, SafeAreaView } from "react-native";

export default function App() {
  const apiKey = "YOUR_API_KEY";

  useEffect(() => {
    const initialize = async () => {
      await Instalog.initialize(apiKey, {
        isLogEnabled: true,
        isCrashEnabled: true,
        isFeedbackEnabled: true,
        isLoggerEnabled: true,
      });
      await Instalog.identifyUser("expo_test_user");
    };
    initialize();
  }, []);

  const handleSendEvent = async () => {
    await Instalog.logEvent("button_clicked", {
      timestamp: new Date().toISOString(),
      screen: "demo_screen",
    });
  };

  const handleShowFeedback = async () => {
    await Instalog.showFeedbackModal();
  };

  const handleSimulateCrash = async () => {
    await Instalog.simulateCrash();
  };

  const handleTestGlobalError = () => {
    setTimeout(() => {
      throw new Error("Test Global Error");
    }, 0);
  };

  const handleManualErrorReport = async () => {
    await Instalog.sendCrash(
      "Manual Test Error",
      "This is a stack trace for a manually reported error\nLine 1\nLine 2\nLine 3"
    );
  };

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.buttonContainer}>
        <TouchableOpacity
          style={styles.button}
          onPress={handleSendEvent}
        >
          <Text style={styles.buttonText}>Send Event</Text>
        </TouchableOpacity>
        
        <TouchableOpacity
          style={styles.button}
          onPress={handleShowFeedback}
        >
          <Text style={styles.buttonText}>Show Feedback</Text>
        </TouchableOpacity>
        
        <TouchableOpacity
          style={styles.button}
          onPress={handleSimulateCrash}
        >
          <Text style={styles.buttonText}>Simulate Crash</Text>
        </TouchableOpacity>
        
        <TouchableOpacity
          style={styles.button}
          onPress={handleTestGlobalError}
        >
          <Text style={styles.buttonText}>Test Global Error</Text>
        </TouchableOpacity>
        
        <TouchableOpacity
          style={styles.button}
          onPress={handleManualErrorReport}
        >
          <Text style={styles.buttonText}>Manual Error Report</Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    backgroundColor: "#fff",
  },
  buttonContainer: {
    alignItems: "center",
  },
  button: {
    backgroundColor: "#8860E6",
    padding: 15,
    borderRadius: 8,
    marginVertical: 10,
    width: 200,
    alignItems: "center",
  },
  buttonText: {
    color: "#fff",
    fontWeight: "bold",
  },
});

License

MIT