@revrag-ai/embed-react-native
Version:
A powerful React Native library for integrating AI-powered voice agents into mobile applications. Features real-time voice communication, intelligent speech processing, customizable UI components, and comprehensive event handling for building conversation
306 lines • 10.8 kB
TypeScript
/**
* @file EmbedProvider.tsx
* @description Core provider component for the Embed React Native library.
*
* This provider:
* - Tracks navigation state and screen changes
* - Conditionally renders the EmbedButton based on current screen
* - Provides utilities for extracting navigation hierarchy information
* - Manages event tracking integration with the Embed system
*
* @module EmbedProvider
*/
import type { NavigationContainerRef } from '@react-navigation/native';
import React from 'react';
/**
* Props for the EmbedProvider component
* @interface EmbedProviderProps
*/
interface EmbedProviderProps {
/** Child components to render within the provider */
children: React.ReactNode;
/** Optional navigation ref for tracking navigation state */
navigationRef?: React.RefObject<NavigationContainerRef<any>>;
/**
* Optional list of screen names where the EmbedButton SHOULD be displayed.
* If provided, the button is rendered only on these screens.
* If omitted/empty, the button is shown on all screens (subject to backend config).
* @example ['Home', 'Profile']
*/
includeScreens?: string[];
/**
* Optional app version information from the host app
* Pass this to include accurate version tracking in analytics
* @example
* ```typescript
* import packageJson from './package.json';
* <EmbedProvider appVersion={packageJson.version}>
* ```
*/
appVersion: string;
}
/**
* Represents the complete hierarchical structure of the current navigation state
* @interface RouteHierarchy
*/
export interface RouteHierarchy {
/** The active/deepest screen name (leaf node in the navigation tree) */
currentScreen: string;
/** Complete navigation path (e.g., "Root > Tab > Screen") */
fullPath: string;
/** Array of route names from root to current [Level0, Level1, Level2, ...] */
allRoutes: string[];
/** Navigation depth (number of levels in the tree) */
depth: number;
/** Map of route names by level: { 0: "RootScreen", 1: "TabScreen", 2: "InnerScreen" } */
routesByLevel: Record<number, string>;
/** The immediate parent route (one level up from current) */
parentRoute?: string;
/** Parameters of the current/active route */
routeParams?: Record<string, any>;
}
/**
* Represents a node in the navigation tree structure
* @interface NavigationTreeNode
*/
export interface NavigationTreeNode {
/** Route name */
name: string;
/** Navigation level/depth (0 = root) */
level: number;
/** Route parameters, if any */
params?: Record<string, any>;
/** Child routes (nested navigators) */
children?: NavigationTreeNode[];
}
/**
* Extracts complete route hierarchy information from navigation state
*
* This function traverses the navigation state tree recursively to build
* a comprehensive hierarchy object containing the current screen, full path,
* depth, and route information at each level.
*
* @param {any} state - Navigation state from navigationRef.current?.getRootState()
* @returns {RouteHierarchy | null} Complete route hierarchy or null if state is invalid
*
* @example
* ```typescript
* const routeInfo = getRouteHierarchy(navigationRef.current?.getRootState());
* console.log(routeInfo);
* // {
* // currentScreen: "Product",
* // fullPath: "MainApp > Home > Product",
* // allRoutes: ["MainApp", "Home", "Product"],
* // depth: 3,
* // routesByLevel: { 0: "MainApp", 1: "Home", 2: "Product" },
* // parentRoute: "Home",
* // routeParams: { id: "123" }
* // }
* ```
*/
export declare const getRouteHierarchy: (state: any) => RouteHierarchy | null;
/**
* Extracts ALL available routes (both mounted and defined) from navigation state
*
* This function traverses the navigation state and returns a flat array of:
* 1. Currently MOUNTED routes (routes that are rendered in the navigation tree)
* 2. DEFINED routes (from routeNames - routes that exist but may not be rendered yet)
*
* This is particularly useful because nested navigators (like tab navigators)
* won't appear in the state until you navigate to them, but their route names
* are still defined in the navigator configuration.
*
* @param {any} state - Navigation state from navigationRef.current?.getRootState()
* @returns {string[]} Array of unique route names
*
* @example
* ```typescript
* const allRoutes = getAllRoutes(navigationRef.current?.getRootState());
* console.log(allRoutes);
* // ["Splash", "Welcome", "MainApp", "Home", "Transactions", "Profile"]
*
* // Check if a specific route is available
* const hasProfileScreen = allRoutes.includes("Profile");
* ```
*/
export declare const getAllRoutes: (state: any) => string[];
/**
* Builds a complete navigation tree structure showing all routes and their relationships
*
* This function creates a hierarchical tree structure representing the entire
* navigation state, including all routes at all levels (not just the active path).
* Useful for visualizing or debugging your navigation structure.
*
* @param {any} state - Navigation state from navigationRef.current?.getRootState()
* @returns {NavigationTreeNode[]} Array of NavigationTreeNode representing the complete tree
*
* @example
* ```typescript
* const tree = getNavigationTree(navigationRef.current?.getRootState());
* console.log(JSON.stringify(tree, null, 2));
*
* // Example output:
* // [
* // {
* // "name": "MainApp",
* // "level": 0,
* // "children": [
* // {
* // "name": "Home",
* // "level": 1,
* // "children": [
* // { "name": "HomeMain", "level": 2 },
* // { "name": "Product", "level": 2, "params": { "id": "123" } }
* // ]
* // },
* // { "name": "Profile", "level": 1 }
* // ]
* // }
* // ]
* ```
*/
export declare const getNavigationTree: (state: any) => NavigationTreeNode[];
/**
* Legacy alias for getAllRoutes()
* @deprecated Use getAllRoutes() instead
*
* Note: React Navigation limitation - nested navigator routes (like tabs inside a stack)
* only appear in the state AFTER they're mounted/rendered.
*
* @param {any} state - Navigation state
* @returns {string[]} Array of route names
*/
export declare const getAllDefinedRoutes: (state: any) => string[];
/**
* Interface for app version information
* @interface AppVersionInfo
*/
export interface AppVersionInfo {
/** App version name/string (e.g., "1.2.3") */
version: string;
/** App build number (iOS: CFBundleVersion, Android: versionCode) */
buildNumber: string;
/** Platform (iOS or Android) */
platform: string;
/** Full version string combining version and build */
fullVersion: string;
}
/**
* Track custom events with the Embed system
*
* This function provides a simple interface to send custom event data
* to the Embed analytics system. All errors are caught and handled silently
* to prevent analytics issues from affecting app functionality.
*
* @param {string} eventName - Name of the event to track
* @param {Record<string, any>} properties - Event properties/metadata (optional)
*
* @example
* ```typescript
* // Track a button click
* trackEmbedEvent('button_clicked', {
* buttonId: 'submit_form',
* screenName: 'Profile',
* });
*
* // Track a purchase
* trackEmbedEvent('purchase_completed', {
* amount: 99.99,
* currency: 'USD',
* items: ['item1', 'item2'],
* });
* ```
*/
export declare const trackEmbedEvent: (eventName: string, properties?: Record<string, any>) => void;
/**
* Track rage clicks (repeated rapid clicks indicating user frustration)
*
* Rage clicks are detected when a user clicks the same element multiple times
* in rapid succession, which can indicate frustration with unresponsive UI.
* This data helps identify problem areas in the user experience.
*
* @param {string} elementId - Unique identifier of the clicked element
* @param {string} elementType - Type of element (e.g., 'button', 'link', 'text')
* @param {{ x: number; y: number }} coordinates - Screen coordinates of the clicks
* @param {number} clickCount - Number of rapid clicks detected
*
* @example
* ```typescript
* trackRageClick('submit_button', 'button', { x: 100, y: 200 }, 5);
* ```
*/
export declare const trackRageClick: (elementId: string, elementType: string, coordinates: {
x: number;
y: number;
}, clickCount: number) => void;
/**
* Track form-related events (changes, submissions, errors)
*
* This function tracks various form interactions to help understand
* user behavior and identify potential issues in form flows.
*
* @param {string} formId - Unique identifier of the form
* @param {'form_change' | 'form_submit' | 'form_error'} eventType - Type of form event
* @param {Record<string, any>} formData - Form data/metadata (optional)
*
* @example
* ```typescript
* // Track form field change
* trackFormEvent('signup_form', 'form_change', {
* field: 'email',
* value: 'user@example.com',
* });
*
* // Track form submission
* trackFormEvent('signup_form', 'form_submit', {
* success: true,
* userId: '12345',
* });
*
* // Track form error
* trackFormEvent('signup_form', 'form_error', {
* field: 'password',
* error: 'Password too short',
* });
* ```
*/
export declare const trackFormEvent: (formId: string, eventType: "form_change" | "form_submit" | "form_error", formData?: Record<string, any>) => void;
/**
* EmbedProvider Component
*
* Core provider component that wraps your application to enable Embed functionality.
* This provider:
* - Monitors navigation state changes
* - Automatically shows/hides the EmbedButton based on current screen
* - Tracks screen views and navigation hierarchy
* - Integrates with the Embed analytics system
*
* @param {EmbedProviderProps} props - Component props
* @returns {JSX.Element} Provider component with children and conditional EmbedButton
*
* @example
* ```typescript
* import { NavigationContainer } from '@react-navigation/native';
* import { EmbedProvider } from '@revrag/embed-react-native';
* import { useRef } from 'react';
*
* function App() {
* const navigationRef = useRef<NavigationContainerRef<any>>(null);
*
* return (
* // IMPORTANT: EmbedProvider must WRAP NavigationContainer
* <EmbedProvider
* navigationRef={navigationRef}
* includeScreens={['Home', 'Profile', 'Dashboard']}
* >
* <NavigationContainer ref={navigationRef}>
* {/* Your navigation stack *\/}
* </NavigationContainer>
* </EmbedProvider>
* );
* }
* ```
*/
export declare const EmbedProvider: React.FC<EmbedProviderProps>;
export default EmbedProvider;
//# sourceMappingURL=EmbedProvider.d.ts.map