npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

uengage-sales-funnel

v1.0.11

Published

React Native funnel tracking SDK (internal)

Readme

uengage-sales-funnel

A lightweight event tracking SDK for React Native apps, used to send predefined sales funnel events to the Uengage sales funnel backend.

  • 📦 Built for React Native >=0.68.3
  • ⚛️ React 17 compatible
  • 💾 Uses @react-native-community/async-storage for persistent visitor_id
  • 📡 Batches events and flushes periodically + when app goes to background
  • 🕒 All timestamps are captured in IST (Asia/Kolkata)

1. Installation

Peer dependencies

Your React Native app must already have:

"dependencies": {
  "react": "17.0.2",
  "react-native": "0.68.3",
  "@react-native-community/async-storage": "^1.12.1"
}

Install the SDK

npm install uengage-sales-funnel
# or
yarn add uengage-sales-funnel

2. Quick Start

Initialize the tracker once (usually at app startup) and then call trackEvent wherever you need.

// App.tsx
import React, { useEffect } from "react";
import { View, Text } from "react-native";
import {
  initTracker,
  trackEvent
} from "uengage-sales-funnel";

const App = () => {
  useEffect(() => {
    initTracker({
      // apiUrl is optional – defaults to Uengage production endpoint
      batchSize: 10,
      flushInterval: 5000,
      platform: "application",
      tenantToken: "<TENANT_TOKEN_FROM_BACKEND>"
    });

    // Example funnel event
    trackEvent("visit");
  }, []);

  return (
    <View>
      <Text>Hello Funnel Tracker</Text>
    </View>
  );
};

export default App;

3. Configuration

initTracker(config)

Call once at app startup (e.g. in App.tsx or in your root provider file).

initTracker({
  batchSize?: number;      // optional - default: 10
  flushInterval?: number;  // optional - ms, default: 5000 (5s)
  platform?: string;       // optional - default: "application"
  tenantToken: string | null; // required in production
});

Example

initTracker({
  batchSize: 20,
  flushInterval: 7000,
  platform: "android",
  tenantToken: "tenant_abc_123"
});

Note: If tenantToken is missing, the SDK will log a warning but still try to send events.


4. Tracking Events

Supported event names

The SDK is currently built around a fixed set of funnel events:

type Events =
  | "visit"
  | "send_otp"
  | "login_success"
  | "location_selected"
  | "location_popup"
  | "product_viewed"
  | "add_to_cart"
  | "remove_from_cart"
  | "add_payment_info"
  | "conversion";

trackEvent(eventName, options?)

Tracks a single event and pushes it into a local queue.

When the queue size reaches batchSize or when the flush interval fires, events are sent in a batch to your backend.

trackEvent(
  eventName: Events, // one of the supported values above
  options?: {
    userId?: string | null;
    metadata?: Record<string, any>;
  }
): Promise<void>

Basic example

trackEvent("visit");

With userId and metadata

trackEvent("product_viewed", {
  userId: "user_123",
  metadata: {
    productId: "PROD-9876",
    name: "Paneer Tikka Pizza",
    price: 299,
    currency: "INR"
  }
});

Conversion example

trackEvent("conversion", {
  userId: "user_123",
  metadata: {
    orderId: "ORD-1122",
    amount: 499,
    paymentMethod: "UPI"
  }
});

5. How events are structured

Each event sent to the backend looks like:

{
  "event": "product_viewed",
  "visitor_id": "v_xxxxx",               // stored in AsyncStorage
  "user_id": "user_123",                 // from options.userId
  "url": null,                           // not applicable in React Native
  "captured_at": "2025-11-17 12:34:56",  // IST (Asia/Kolkata)
  "platform": "application",             // from config.platform
  "system": "android",                   // Platform.OS
  "metadata": { /* custom data */ }
}

The full request body sent to the server:

{
  "tenantToken": "tenant_abc_123",
  "events": [ /* array of event objects */ ]
}

6. Visitor ID

The SDK generates a persistent visitor_id and stores it using @react-native-community/async-storage.

  • Key: uengage_visitor_id
  • Format: "v_" + random + timestamp

You can access it if needed:

getVisitorId()

import { getVisitorId } from "uengage-sales-funnel";

const visitorId = await getVisitorId();
console.log("Visitor ID:", visitorId);

7. Flushing events

Events are flushed automatically when:

  1. The in-memory queue length reaches batchSize
  2. The flush timer ticks (flushInterval in ms)
  3. The app goes to background (AppState changes from active to background/inactive)

You can also trigger manual flush:

flushEvents()

import { flushEvents } from "uengage-sales-funnel";

await flushEvents();

8. Shutdown / cleanup (optional)

If you need to clean up listeners and timers (e.g. during tests):

shutdownTracker()

import { shutdownTracker } from "uengage-sales-funnel";

shutdownTracker();

This:

  • Clears the internal interval timer
  • Unsubscribes from AppState changes

9. TypeScript support

The SDK is written in TypeScript and ships type declarations.

You get full typings out of the box:

import {
  initTracker,
  trackEvent,
  flushEvents,
  getVisitorId,
  shutdownTracker,
  type TrackerConfig,
  type TrackEventOptions
} from "uengage-sales-funnel";

Example of using TrackerConfig in your own abstraction:

import type { TrackerConfig } from "uengage-sales-funnel";

const config: Partial<TrackerConfig> = {
  tenantToken: "tenant_abc_123"
};

10. Notes & Gotchas

  • Call initTracker before trackEvent If you forget, the SDK will log a warning and ignore the event.

  • Predefined event set eventName must be one of: visit, send_otp, login_success, location_selected, location_popup, product_viewed, add_to_cart, remove_from_cart, add_payment_info, conversion.

  • No window.location This is React Native, so url is always null. If you want to track screens, pass them in metadata:

    trackEvent("visit", {
      metadata: {
        screen: "HomeScreen"
      }
    });
  • Time zone is IST (Asia/Kolkata) captured_at is formatted as YYYY-MM-DD HH:mm:ss in IST internally using a custom date helper.

  • Offline handling Currently, events are queued in memory and retried on flush failure by re-adding them to the queue. For full offline durability, additional storage logic can be added in a future version.


11. Example: Screen tracking helper

Here’s a small example you can add in your app (not part of the SDK) using the existing visit event:

// trackerHelpers.ts
import { trackEvent } from "uengage-sales-funnel";

export function trackScreenVisit(screenName: string, userId?: string) {
  return trackEvent("visit", {
    userId,
    metadata: { screen: screenName }
  });
}

And use with React Navigation:

// Somewhere in your navigation container
trackScreenVisit("HomeScreen", currentUserId);