UNPKG

@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
/** * @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