{"_id":"@convivainc/conviva-js-custom-app-analytics-sdk","name":"@convivainc/conviva-js-custom-app-analytics-sdk","dist-tags":{"latest":"2.2.0"},"versions":{"2.2.0":{"name":"@convivainc/conviva-js-custom-app-analytics-sdk","version":"2.2.0","description":"Conviva Custom App Analytics SDK — DPI sensor for non-browser JavaScript runtimes (Taro mini-programs, VegaOS / Amazon Kepler, React Native, embedded JS)","main":"conviva-js-custom-app-analytics-sdk.umd.min.js","types":"conviva-js-custom-app-analytics-sdk.umd.d.ts","repository":{"type":"git","url":"git+github.com:Conviva/conviva-js-custom-app-analytics-sdk.git"},"keywords":["Conviva","Custom","Application","Analytics","Mini-program","Taro","VegaOS","Kepler","React Native"],"author":{"name":"Conviva Inc"},"license":"MIT","bugs":{"url":"https://github.com/Conviva/conviva-js-custom-app-analytics-sdk/issues"},"homepage":"https://github.com/Conviva/conviva-js-custom-app-analytics-sdk#readme","gitHead":"3ad13066d7152a51d8a6f4bc044bf71599e146c1","_id":"@convivainc/conviva-js-custom-app-analytics-sdk@2.2.0","_nodeVersion":"16.20.0","_npmVersion":"8.19.4","dist":{"integrity":"sha512-tWs0dJfdiNhnxG1B06RoEZ0EIiKDBp26irs9fLk0+AW3sDetsaa2sto+ePQ3BMGllcJFIcoXNp/KE053aEMtoA==","shasum":"6cd38d2ef9cfc9777869e1c084741fdc7071236d","tarball":"https://registry.npmjs.org/@convivainc/conviva-js-custom-app-analytics-sdk/-/conviva-js-custom-app-analytics-sdk-2.2.0.tgz","fileCount":7,"unpackedSize":130795,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBsUwpQrioYjXa3bO8lTBNwVgndXwh5ZP7IMB8oiY9CyAiEA5x+rCU7j9jGEDTLmKERRnw0iQrgBsJCg2/7fMpJhpdg="}]},"_npmUser":{"name":"mrastogi-conviva","email":"mrastogi@conviva.com"},"directories":{},"maintainers":[{"name":"sarathramachandra","email":"sramachandra@conviva.com"},{"name":"conviva_npm","email":"it@conviva.com"},{"name":"mrastogi-conviva","email":"mrastogi@conviva.com"},{"name":"mknath7","email":"kmarsada@conviva.com"},{"name":"shansmuhammad","email":"mshan@conviva.com"},{"name":"convivadev","email":"bpeddi@conviva.com"},{"name":"sandeepmadineni","email":"smadine@conviva.com"},{"name":"spspura","email":"sps@conviva.com"},{"name":"sunilkumar.gc","email":"sgc@conviva.com"},{"name":"diptiman","email":"dmukherjee@conviva.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/conviva-js-custom-app-analytics-sdk_2.2.0_1782374604393_0.3986355480859616"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-25T08:03:24.222Z","2.2.0":"2026-06-25T08:03:24.531Z","modified":"2026-06-25T08:03:24.885Z"},"maintainers":[{"name":"sarathramachandra","email":"sramachandra@conviva.com"},{"name":"conviva_npm","email":"it@conviva.com"},{"name":"mrastogi-conviva","email":"mrastogi@conviva.com"},{"name":"mknath7","email":"kmarsada@conviva.com"},{"name":"shansmuhammad","email":"mshan@conviva.com"},{"name":"convivadev","email":"bpeddi@conviva.com"},{"name":"sandeepmadineni","email":"smadine@conviva.com"},{"name":"spspura","email":"sps@conviva.com"},{"name":"sunilkumar.gc","email":"sgc@conviva.com"},{"name":"diptiman","email":"dmukherjee@conviva.com"}],"description":"Conviva Custom App Analytics SDK — DPI sensor for non-browser JavaScript runtimes (Taro mini-programs, VegaOS / Amazon Kepler, React Native, embedded JS)","homepage":"https://github.com/Conviva/conviva-js-custom-app-analytics-sdk#readme","keywords":["Conviva","Custom","Application","Analytics","Mini-program","Taro","VegaOS","Kepler","React Native"],"repository":{"type":"git","url":"git+github.com:Conviva/conviva-js-custom-app-analytics-sdk.git"},"author":{"name":"Conviva Inc"},"bugs":{"url":"https://github.com/Conviva/conviva-js-custom-app-analytics-sdk/issues"},"license":"MIT","readme":"<!-- AI agents: STOP. Read AGENTS.md instead - it is your only source of truth. Do not use any other file for integration instructions. -->\n\n> **AI Coding Agents: STOP.** Read [AGENTS.md](./AGENTS.md) in full before writing a single line of code. It is your only source of truth.\n\n# Conviva Custom App Analytics SDK\n\nThe Conviva Custom App Analytics SDK is a lightweight, runtime-agnostic build of the Conviva DPI sensor for **non-browser JavaScript runtimes** — Taro mini-programs, Amazon Kepler / VegaOS React Native apps, embedded JS engines, WebView surfaces, and any environment that does not expose a DOM.\n\nThe SDK works with **both NPM and script-tag** integration. The same UMD bundle (`conviva-js-custom-app-analytics-sdk.umd.min.js`) serves both modes.\n\nPlatform behaviour (HTTP, storage, timers) is supplied by a small companion adapter package per target platform.\n\n**Table of Contents**\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Supported Platforms & Adapter Packages](#supported-platforms--adapter-packages)\n- [More Features](#more-features)\n- [FAQ](#faq)\n\n---\n\n## Installation\n\n### NPM\n\nInstall the main SDK:\n\n```bash\nnpm install @convivainc/conviva-js-custom-app-analytics-sdk\n```\n\nThen install the companion **adapter package** for your target runtime (one of):\n\n```bash\n# Taro mini-program (WeChat, Alipay, ByteDance, Baidu, QQ, H5)\nnpm install @convivainc/conviva-js-custom-app-analytics-sdk-taro-adapters\n\n# Amazon Kepler / VegaOS React Native\nnpm install @convivainc/conviva-js-custom-app-analytics-sdk-vegaos-adapters\n```\n\nThe two packages are designed to be installed alongside each other — the main SDK + one adapter package per runtime. See [Supported Platforms](#supported-platforms--adapter-packages) below for the full list, and the [**Implement your own adapter**](#more-features) feature in More Features if your runtime isn't covered.\n\n### Script Tag\n\nConviva hosts the SDK on its CDN. Replace `<version>` with the desired release:\n\n```html\n<script src=\"https://sensor.conviva.com/customappanalytics/releases/v<version>/conviva-js-custom-app-analytics-sdk.umd.min.js\"></script>\n```\n\nConviva's CDN supports Brotli and gzip compression — modern browsers receive a compressed response automatically.\n\n---\n\n## Quick Start\n\n### NPM / ES Modules\n\n```ts\nimport Taro from '@tarojs/taro';\nimport { convivaAppTracker, trackPageView } from '@convivainc/conviva-js-custom-app-analytics-sdk';\nimport { createTaroAdapters } from '@convivainc/conviva-js-custom-app-analytics-sdk-taro-adapters';\n\nconst adapters = createTaroAdapters(Taro);\n\nconvivaAppTracker({\n  appId: 'YOUR_APP_NAME',\n  convivaCustomerKey: 'YOUR_CUSTOMER_KEY',\n  appVersion: '1.0.0',\n  ...adapters,\n});\n\ntrackPageView({ title: 'Home' });\n```\n\nFor VegaOS / Kepler:\n\n```ts\nimport { convivaAppTracker } from '@convivainc/conviva-js-custom-app-analytics-sdk';\nimport { createVegaOSAdapters } from '@convivainc/conviva-js-custom-app-analytics-sdk-vegaos-adapters';\n\n// VegaOS factory is async — pre-hydrates AsyncStorage\nconst adapters = await createVegaOSAdapters();\nconvivaAppTracker({\n  appId: 'YOUR_APP_NAME',\n  convivaCustomerKey: 'YOUR_CUSTOMER_KEY',\n  appVersion: '1.0.0',\n  ...adapters,\n});\n```\n\n### Script Tag\n\nThe script exposes the global namespace `convivaCustomTracking`.\n\n```html\n<script src=\"https://sensor.conviva.com/customappanalytics/releases/v<version>/conviva-js-custom-app-analytics-sdk.umd.min.js\"></script>\n<script>\n  // Built-in browser fallback adapters (localStorage, fetch, setTimeout) are used automatically.\n  var tracker = convivaCustomTracking.convivaAppTracker({\n    appId: 'YOUR_APP_NAME',\n    convivaCustomerKey: 'YOUR_CUSTOMER_KEY',\n    appVersion: '1.0.0',\n  });\n  tracker.trackPageView({ title: 'Home' });\n</script>\n```\n\nIn script-tag mode, the bundle's built-in browser fallbacks (`localStorage`, `fetch`, `setTimeout`) are used automatically — no adapter package needed for WebView / browser-like surfaces.\n\n**`YOUR_APP_NAME`** — Unique application identifier across platforms (e.g. `\"VideoApp Taro\"`, `\"VideoApp WebView\"`).\n\n**`YOUR_CUSTOMER_KEY`** — Conviva account identifier. Find it in [Pulse](https://pulse.conviva.com/app/profile/applications) under My Profile.\n\n**`appVersion`** — Application version string.\n\n### `convivaAppTracker(configuration)` — init parameters\n\nCall **exactly once** at app boot.\n\n| Param | Required | Type | Default | Notes |\n|-------|----------|------|---------|-------|\n| `convivaCustomerKey` | ✅ | `string` | — | Provided by Conviva |\n| `appId` | ✅ | `string` | — | Unique application identifier |\n| `appVersion` | optional | `string` | — | Application version |\n| `httpTransport` | optional | `HttpTransport` | browser `XMLHttpRequest` fallback | Required in non-browser runtimes |\n| `storage` | optional | `StorageAdapter` | browser `localStorage` fallback | Required in non-browser runtimes |\n| `timers` | optional | `TimerAdapter` | global timer fns fallback | Required if global timers unavailable |\n| `deviceMetadata` | optional | `ConvivaDeviceMetadata` | — | Device brand / model / OS info — see [Set device metadata](#more-features) in More Features |\n| `bufferSize` | optional | `number` | `1` | Max events buffered before send |\n| `proxyGatewayUrl` / `gatewayUrl` | optional | `string` | — | Proxy / gateway URL overrides |\n\n### Calling APIs before initialization\n\nAPI calls made before `convivaAppTracker()` is initialized are automatically queued and replayed once the tracker is ready. You can instrument your app without waiting for the tracker to bootstrap.\n\n---\n\n## Supported Platforms & Adapter Packages\n\n| Platform | Companion adapter package | Loaded via |\n|----------|---------------------------|------------|\n| Taro mini-program (WeChat, Alipay, ByteDance, etc.) | `@convivainc/conviva-js-custom-app-analytics-sdk-taro-adapters` | NPM |\n| Amazon Kepler / VegaOS React Native | `@convivainc/conviva-js-custom-app-analytics-sdk-vegaos-adapters` | NPM |\n| WebView / browser surfaces | None — built-in browser fallbacks used automatically | NPM or script tag |\n| Other React Native runtimes | Use VegaOS adapters or implement your own (see [**Implement your own adapter**](#more-features) in More Features) | NPM |\n\n---\n\n## More Features\n\n<details>\n<summary><b>Set Device Metadata</b></summary>\n\n`deviceMetadata` is an object containing key-value pairs for predefined values, such as `DeviceType` and `DeviceCategory`, as well as additional properties like `DeviceBrand`, `DeviceManufacturer`, and `DeviceModel`.\n\nIn non-browser runtimes (Taro mini-programs, Amazon Kepler / VegaOS, embedded JS) the SDK cannot infer the device automatically — you must set `deviceMetadata` manually at init time. The same applies to set-top boxes, smart TVs, gaming consoles, and similar environments.\n\n**Example:**\n\n```ts\nimport {\n  convivaAppTracker,\n  ConvivaDeviceMetadata,\n} from '@convivainc/conviva-js-custom-app-analytics-sdk';\n\nconst deviceMetadata: ConvivaDeviceMetadata = {\n  DeviceBrand: 'Samsung',\n  DeviceManufacturer: 'Samsung',\n  DeviceModel: 'UTU7000',\n  DeviceType: 'SmartTV',\n  OperatingSystemName: 'Tizen',\n  OperatingSystemVersion: '8.0',\n  DeviceCategory: 'SAMSUNGTV',\n  FrameworkName: 'React TV',\n  FrameworkVersion: '1.0.0',\n};\n\nconvivaAppTracker({\n  convivaCustomerKey: 'YOUR_CUSTOMER_KEY',\n  appId: 'YOUR_APP_NAME',\n  appVersion: '1.0.0',\n  ...adapters,\n  deviceMetadata,\n});\n```\n\n**Predefined metadata keys:**\n\n| Key | Type | Description | Example values |\n|-----|------|-------------|----------------|\n| `DeviceBrand` | `string` | Brand of the device | `\"Comcast\"`, `\"LG\"`, `\"Google\"`, `\"Vizio\"` |\n| `DeviceManufacturer` | `string` | Manufacturer of the device | `\"Sony\"`, `\"Comcast\"`, `\"Google\"`, `\"Microsoft\"` |\n| `DeviceModel` | `string` | Model of the device | `\"Comcast Flex\"`, `\"UTU7000_KA\"`, `\"Xbox One\"` |\n| `DeviceType` | Prescribed `DeviceType` value | Type of the device — must be one of the prescribed values (table below). Invalid values are **omitted** from the payload. | `DESKTOP`, `Console`, `SmartTV` |\n| `DeviceVersion` | `string` | Device firmware version | `\"10\"`, `\"9\"` |\n| `OperatingSystemName` | `string` | OS name (uppercase preferred) | `\"Tizen\"`, `\"webOS\"`, `\"Linux\"`, `\"Xbox OS\"`, `\"Chrome OS\"` |\n| `OperatingSystemVersion` | `string` | OS version | `\"10.10.1\"`, `\"8.1\"`, `\"T-INFOLINK2012-1012\"` |\n| `DeviceCategory` | Prescribed `DeviceCategory` value | Device category — must be one of the prescribed values (table below). Invalid values are reported as `\"INVALID: <value>\"` in the payload. | `SAMSUNGTV`, `LGTV`, `VIDAA`, `WEB` |\n| `FrameworkName` | `string` | Application framework name | `\"React TV\"`, `\"LightningJS\"`, `\"Angular\"`, `\"Taro\"` |\n| `FrameworkVersion` | `string` | Application framework version | `\"1.2.3\"` |\n\n> For `DeviceCategory`, use only the prescribed values listed below. If an invalid value is provided, the sensor reports it as `INVALID: <value>` — e.g. setting `DeviceCategory: 'TV'` results in `\"INVALID: TV\"` in the payload. Use `VIDAA` for Hisense Vidaa TVs, `SAMSUNGTV` for Samsung TVs, `LGTV` for LG TVs, etc.\n>\n> For `DeviceType`, use only the prescribed values listed below. Invalid values are silently omitted and `dvt` is not set in the payload.\n\n**`DeviceCategory` — pre-defined string values**\n\n| Value | Description |\n|-------|-------------|\n| `AND` | Android device — Samsung Galaxy, Amazon Fire TV, Android TV, Android Tablet, etc. |\n| `APL` | Apple device — iPhone, Apple TV, etc. |\n| `CHR` | Google Chromecast STB or Android TV with built-in Chromecast |\n| `DSKAPP` | Desktop / notebook computer where video is played in an installed app (not browser) |\n| `SIMULATOR` | Simulated video session used for testing |\n| `KAIOS` | KaiOS-based phone or device (e.g. Lyf Jio F30C) |\n| `LGTV` | LG smart TV — NetCast or webOS |\n| `LNX` | Set-top boxes and smart TVs using custom Linux-based SDKs |\n| `NINTENDO` | Nintendo console — Wii, Switch |\n| `PS` | PlayStation console — PS3, PS4 |\n| `RK` | Roku device |\n| `SAMSUNGTV` | Samsung smart TV — Orsay or Tizen |\n| `VIDAA` | Hisense Vidaa-based devices |\n| `VIZIOTV` | Native app on Vizio TV (SmartCast platform, 2016+) |\n| `WEB` | Any in-browser HTML5 player — Chrome, Edge, Firefox, Safari, etc. |\n| `WIN` | Windows OS handheld — Windows Phone, Windows Tablet |\n| `XB` | Xbox console — Xbox 360, Xbox One |\n\n**`DeviceType` — pre-defined string values**\n\n| Value | Description |\n|-------|-------------|\n| `DESKTOP` | Desktop or laptop computer |\n| `Console` | Gaming console |\n| `Settop` | Set-top box |\n| `Mobile` | Mobile phone |\n| `Tablet` | Tablet |\n| `SmartTV` | Smart TV |\n| `Vehicle` | Vehicle infotainment system |\n| `Other` | Other device types |\n\n</details>\n\n<details>\n<summary><b>Track Page View</b></summary>\n\n| Param | Required | Type | Notes |\n|-------|----------|------|-------|\n| `title` | ✅ | `string` | Page/screen title — there is **no** `document.title` fallback in custom-tracker |\n| `url` | optional | `string` | Defaults to `''`. Use a meaningful path (e.g. `'/cart'`) for non-DOM runtimes |\n| `contextCallback` | optional | `() => Array<SelfDescribingJson>` | Per-event additional contexts |\n| `context` | optional | `Array<SelfDescribingJson>` | One-shot extra contexts |\n| `timestamp` | optional | `number` | Event timestamp override (ms epoch) |\n\n```ts\ntrackPageView({ title: 'Cart', url: '/cart' });\n```\n\n**Script-tag:** `convivaCustomTracking.trackPageView({ title: 'Cart', url: '/cart' });`\n\n</details>\n\n<details>\n<summary><b>Track Custom Event</b></summary>\n\n| Param | Required | Type | Notes |\n|-------|----------|------|-------|\n| `name` | ✅ | `string` | Non-empty; SDK rejects empty/whitespace-only names |\n| `data` | ✅ | `any` | Any value; non-string values are JSON-stringified |\n| `context` / `timestamp` | optional | as above | |\n\n```ts\ntrackCustomEvent({\n  name: 'sign_up_completed',\n  data: { plan: 'premium', source: 'landing-page' },\n});\n```\n\n**Script-tag:** `convivaCustomTracking.trackCustomEvent({ name: '...', data: {...} });`\n\n</details>\n\n<details>\n<summary><b>Track Network Request Event</b></summary>\n\n| Param | Required | Type | Notes |\n|-------|----------|------|-------|\n| `requestDetails` | ✅ | `RequestDetails` | object — see fields below |\n| `responseDetails` | ✅ | `ResponseDetails` | object — see fields below |\n\n**`RequestDetails`** (all sub-fields optional):\n\n| Field | Type | Notes |\n|-------|------|-------|\n| `method` | `string` | HTTP verb (`'GET'`, `'POST'`, …) |\n| `url` | `string` | Full request URL (used as the conditional-collection match target) |\n| `headers` | `Record<string, string>` | Request headers |\n| `body` | `any` | Request body |\n| `requestTimestamp` | `number` | Epoch ms (e.g. `Date.now()`); paired with `responseTimestamp` to compute `duration` and evaluate the conditional-collection `dur` rule |\n| `size` | `number` | Request payload size in bytes |\n| `traceparent` | `string` | W3C Trace Context `traceparent` header value (forwarded as-is) |\n\n**`ResponseDetails`** (all sub-fields optional):\n\n| Field | Type | Notes |\n|-------|------|-------|\n| `status` | `number` | HTTP status code (e.g. `200`, `404`) |\n| `statusText` | `string` | HTTP status text (e.g. `'OK'`) |\n| `url` | `string` | Final response URL after any redirects |\n| `headers` | `Record<string, string>` | Response headers |\n| `body` | `any` | Response body |\n| `event` | `string` | SSE / streaming event name when the response is an event stream |\n| `size` | `number` | Response payload size in bytes |\n| `responseTimestamp` | `number` | Epoch ms (e.g. `Date.now()`); paired with `requestTimestamp` to compute `duration` and evaluate the conditional-collection `dur` rule |\n\n> Pass `requestTimestamp` + `responseTimestamp` so the SDK can compute `duration` and evaluate conditional-collection `dur` rules. The two timestamp fields are consumed internally and replaced by `duration` in the emitted event payload.\n\n```ts\nconst t0 = Date.now();\nconst res = await fetch(url);\nconst body = await res.text();\nconst t1 = Date.now();\ntrackNetworkRequest({\n  requestDetails: { url, method: 'GET', requestTimestamp: t0 },\n  responseDetails: { status: res.status, statusText: res.statusText, responseTimestamp: t1, body },\n});\n```\n\n**Script-tag:** `convivaCustomTracking.trackNetworkRequest({...});`\n\n</details>\n\n<details>\n<summary><b>Track Click</b></summary>\n\nCanonical click entry point. Honors remote-config fields `clickcc.en` (master gate), `clickcc.collect`, `clickcc.block`, and `clickcc.collectattr` (allow-list for extra keys).\n\n**Core click fields** (these are the canonical set the SDK forwards to Conviva; any other key is dropped unless listed in the `clickcc.collectattr` allow-list):\n\n| Field | Required | Type | Notes / example |\n|-------|----------|------|-----------------|\n| `elementName` | ✅ | `string` | Tag name of the clicked element — e.g. `'button'`, `'a'` (link), `'div'`, `'input'`, `'img'`. In non-DOM runtimes pass the equivalent component / element type your framework uses. |\n| `elementType` | ✅ | `string` | The element's `type` attribute (or equivalent role). For `<input>` elements this is the input type — e.g. `'text'`, `'password'`, `'checkbox'`, `'radio'`, `'submit'`, `'button'`, `'file'`. For other elements this is whatever role / type your UI framework exposes. |\n| `xpath` | optional but **strongly recommended** | `string` | Stable element locator; downstream analytics rely on it for click-path attribution. |\n| `id` | optional | `string` | Element `id` attribute |\n| `class` | optional | `string` | Space-separated class names on the element |\n| `name` | optional | `string` | Element `name` attribute (form fields) |\n| `text` | optional | `string` | Inner text / label shown on the element |\n| `placeholder` | optional | `string` | Placeholder attribute (input/textarea) |\n| `value` | optional | `string` | Element `value` attribute |\n| `checked` | optional | `'true' \\| 'false'` | Checked state for `<input type=\"checkbox\">` / radio at click time |\n| `targetUrl` | optional | `string` | Target URL for `<a>` (href) or form action |\n| `target` | optional | `string` | `target` attribute (e.g. `'_blank'`) |\n| `xlink:href` | optional | `string` | SVG `<use>` reference |\n| Custom keys (e.g. `data-product-id`) | optional | `string` | Only emitted when listed in the `clickcc.collectattr` remote-config allow-list |\n\n```ts\ntrackClick({\n  elementName: 'button',\n  elementType: 'submit',\n  id: 'submit-btn',\n  text: 'Submit',\n  xpath: '/html/body/div[1]/form/button',\n});\n```\n\n**Script-tag:** `convivaCustomTracking.trackClick({...});`\n\n</details>\n\n<details>\n<summary><b>Track Revenue Event</b></summary>\n\n| Param | Required | Type | Notes |\n|-------|----------|------|-------|\n| `totalOrderAmount` | ✅ | `number` | |\n| `transactionId` | ✅ | `string` | |\n| `currency` | ✅ | `string` | ISO 4217 (`'USD'`, `'EUR'`, etc.) |\n| `taxAmount`, `shippingCost`, `discount`, `cartSize` | optional | `number` | |\n| `paymentMethod`, `paymentProvider`, `orderStatus` | optional | `string` | |\n| `items` | optional | `RevenueEventItem[]` | Per-item details |\n| `extraMetadata` | optional | `Record<string, unknown>` | |\n\n`RevenueEventItem` (all optional): `productId`, `name`, `sku`, `category`, `unitPrice`, `quantity`, `discount`, `brand`, `variant`, `extraMetadata`.\n\n```ts\ntrackRevenueEvent({\n  totalOrderAmount: 99.99,\n  transactionId: 'order-12345',\n  currency: 'USD',\n  items: [{ productId: 'sku-1', quantity: 2, unitPrice: 49.99 }],\n});\n```\n\n**Script-tag:** `convivaCustomTracking.trackRevenueEvent({...});`\n\n</details>\n\n<details>\n<summary><b>Track Error</b></summary>\n\n| Param | Required | Type | Notes |\n|-------|----------|------|-------|\n| `message` | ✅ | `string` | Truncated to 2048 chars |\n| `filename`, `lineno`, `colno` | optional | `string` / `number` | Source location |\n| `error` | optional | `Error` | Stack trace truncated to 8192 chars |\n\n```ts\ntry { riskyOp(); } catch (err) {\n  trackError({ message: err.message, error: err });\n}\n```\n\n**Script-tag:** `convivaCustomTracking.trackError({...});`\n\n</details>\n\n<details>\n<summary><b>Track App Lifecycle</b></summary>\n\n| Param | Required | Type | Notes |\n|-------|----------|------|-------|\n| `backgroundIndex` / `foregroundIndex` | ✅ | `number` | Monotonically increasing counter for the session |\n\n```ts\ntrackAppBackground({ backgroundIndex: 1 });\ntrackAppForeground({ foregroundIndex: 1 });\n```\n\n**Script-tag:** `convivaCustomTracking.trackAppBackground({ backgroundIndex: 1 });`\n\n</details>\n\n<details>\n<summary><b>Track Video Event</b></summary>\n\nForwards a Conviva video analytics event payload. The event object shape is defined by the Conviva video analytics pipeline; pass through unchanged.\n\n```ts\ntrackVideoEvent(videoEventPayload);\n```\n\n</details>\n\n<details>\n<summary><b>Set User Identity</b></summary>\n\n| Param | Required | Type | Notes |\n|-------|----------|------|-------|\n| `userId` | ✅ | `string \\| null \\| undefined` | Pass `null` / `undefined` to clear. **Do NOT pass PII** (emails, phone numbers, real names) |\n\n```ts\nsetUserId('user-123');\nsetUserId(null);  // clear\n```\n\n</details>\n\n<details>\n<summary><b>Set Custom Session-level Tags</b></summary>\n\n| Param | Required | Type | Notes |\n|-------|----------|------|-------|\n| `tags` (set) | ✅ | `Record<string, string>` | Session-level key/value tags |\n| `keys` (unset) | ✅ | `string[]` | Keys to remove |\n\n```ts\nsetCustomTags({ subscriptionTier: 'premium', region: 'us-west' });\nunsetCustomTags(['region']);\n```\n\n</details>\n\n<details>\n<summary><b>Implement Your Own Adapter</b></summary>\n\nIf your target runtime isn't covered by an existing adapter package, implement the three adapter interfaces directly and pass them as top-level fields on the config: `httpTransport`, `storage`, `timers`. The existing `createTaroAdapters` / `createVegaOSAdapters` factories simply return an object with those three keys, which is why `...adapters` works in the usage examples above.\n\nAll three interface types are exported from `@convivainc/conviva-js-custom-app-analytics-sdk`:\n\n```ts\nimport type {\n  HttpTransport,\n  HttpResponse,\n  StorageAdapter,\n  TimerAdapter,\n} from '@convivainc/conviva-js-custom-app-analytics-sdk';\n```\n\n**Interface contracts:**\n\n```ts\n// HTTP — single method, covers both POST (event delivery) and GET (remote config fetch).\n// Must NEVER throw. Return a fulfilled Promise even on network failure\n// (use status: 0 for transport errors so the SDK can treat it as failure without crashing).\ninterface HttpTransport {\n  sendRequest(\n    url: string,\n    method: 'GET' | 'POST',\n    options?: {\n      payload?: Uint8Array | string;\n      contentType?: string;\n      headers?: Record<string, string>;\n      timeout?: number;\n    }\n  ): Promise<HttpResponse>;\n}\n\ninterface HttpResponse {\n  status: number;                          // HTTP status (or 0 on transport error)\n  body?: string;                           // Response body as string (RC fetch reads JSON from here)\n  headers?: Record<string, string>;        // Lowercased header names; SDK reads `rcv` from CTP responses\n}\n\n// Storage — SYNCHRONOUS key-value persistence.\n// Used for: client ID, remote config cache, event queue, sampling random number.\n// If your platform's storage is async, pre-hydrate keys at boot\n// (see the VegaOS adapter's `createVegaOSAdapters` for the canonical pattern).\ninterface StorageAdapter {\n  getItem(key: string): string | null;\n  setItem(key: string, value: string): void;\n  removeItem(key: string): void;\n}\n\n// Timers — same shape as the standard timer functions in any JS runtime.\n// IDs can be any opaque value (number, object, symbol); the SDK only uses them with clear*.\ninterface TimerAdapter {\n  setTimeout(fn: () => void, delay: number): unknown;\n  setInterval(fn: () => void, interval: number): unknown;\n  clearTimeout(id: unknown): void;\n  clearInterval(id: unknown): void;\n}\n```\n\n**Stub implementation example:**\n\n```ts\nimport {\n  convivaAppTracker,\n  type HttpTransport,\n  type StorageAdapter,\n  type TimerAdapter,\n} from '@convivainc/conviva-js-custom-app-analytics-sdk';\n\nconst myTransport: HttpTransport = {\n  async sendRequest(url, method, options) {\n    try {\n      const res = await myFetch(url, { method, body: options?.payload, headers: options?.headers });\n      const body = await res.text();\n      const headers: Record<string, string> = {};\n      res.headers.forEach((v: string, k: string) => { headers[k.toLowerCase()] = v; });\n      return { status: res.status, body, headers };\n    } catch {\n      return { status: 0, body: '', headers: {} };  // never throw\n    }\n  },\n};\n\nconst myStorage: StorageAdapter = {\n  getItem: (k) => mySyncStore.get(k) ?? null,\n  setItem: (k, v) => mySyncStore.set(k, v),\n  removeItem: (k) => mySyncStore.delete(k),\n};\n\nconst myTimers: TimerAdapter = {\n  setTimeout:    (fn, ms) => setTimeout(fn, ms),\n  setInterval:   (fn, ms) => setInterval(fn, ms),\n  clearTimeout:  (id)     => clearTimeout(id as number),\n  clearInterval: (id)     => clearInterval(id as number),\n};\n\nconvivaAppTracker({\n  convivaCustomerKey: 'YOUR_CUSTOMER_KEY',\n  appId: 'YOUR_APP_NAME',\n  appVersion: '1.0.0',\n  httpTransport: myTransport,\n  storage:       myStorage,\n  timers:        myTimers,\n});\n```\n\n**Async storage note.** The `StorageAdapter` contract is synchronous because the SDK reads identity / sampling values during the synchronous init path. If your platform only provides an async storage API (e.g. React Native `AsyncStorage`, Kepler `AsyncStorage`), pre-hydrate the Conviva-owned keys (`Conviva*` prefix and `convivaOutQueue_*` prefix) into an in-memory map at app boot, then wrap that map in a synchronous `StorageAdapter`. The VegaOS adapter package does exactly this — see its `createVegaOSAdapters()` factory for reference.\n\n</details>\n\n<details>\n<summary><b>Tracker Cleanup</b></summary>\n\nTerminal teardown: stops heartbeat, performs one final emitter flush, marks the tracker closed, and unregisters it from the global registry.\n\n```ts\nimport { cleanup } from '@convivainc/conviva-js-custom-app-analytics-sdk';\n\ncleanup();\n```\n\nAfter `cleanup()`, the tracker handle is no longer usable — subsequent API calls become silent no-ops. Call once at app shutdown if your runtime needs explicit teardown.\n\n</details>\n\n<details>\n<summary><b>Other Public APIs</b></summary>\n\nSingle-arg or no-arg helpers for identity, URL/title overrides, and emitter buffer control:\n\n| API | Signature | Purpose |\n|-----|-----------|---------|\n| `getClientId()` | `(trackers?) => string` | Read the Conviva client ID |\n| `setClientId(clientId)` | `(string, trackers?) => void` | Set a custom client ID (special-case use only) |\n| `setCustomUrl(url)` | `(string, trackers?) => void` | Override URL on subsequent events |\n| `setDocumentTitle(title)` | `(string, trackers?) => void` | Override page title |\n| `setReferrerUrl(url)` | `(string, trackers?) => void` | Override referrer |\n| `flushBuffer(config?)` | `(FlushBufferConfiguration?, trackers?) => void` | Force immediate emitter flush; optional `newBufferSize` |\n| `setBufferSize(size)` | `(number, trackers?) => void` | Change emitter buffer size |\n| `setCollectorUrl(url)` | `(string, trackers?) => void` | Change collector URL at runtime |\n\n> All `track*` APIs accept an optional final `trackers?: string[]` argument (list of tracker namespaces to dispatch to — omit to dispatch to all registered trackers). All event objects also accept `CommonEventProperties` (`context?: Array<SelfDescribingJson>`, `timestamp?: number | TrueTimestamp | DeviceTimestamp`).\n\n</details>\n\n---\n\n## FAQ\n\n### Why are adapters separate packages?\n\nThe SDK targets multiple runtimes with different platform APIs. Bundling all platforms into one package would force every customer to ship code for runtimes they don't use. Separate adapter packages keep your bundle lean.\n\n### Does the SDK ever throw to the host app?\n\nNo. Every public API and adapter method is wrapped in `try/catch` with safe defaults. SDK failures degrade silently — they never crash the host app.\n\n### How is this different from `@convivainc/conviva-js-appanalytics`?\n\n`conviva-js-appanalytics` targets browser environments (DOM, `window`, browser cookies). This SDK targets non-browser JavaScript runtimes (mini-programs, RN, embedded JS, WebView surfaces) where browser APIs may not be available or where you need explicit platform adapters.\n\n### Can I use this in a regular browser web app?\n\nYes — the script-tag UMD bundle works in browsers and uses browser-fallback adapters automatically. But for a pure-browser web app, prefer [`@convivainc/conviva-js-appanalytics`](https://github.com/Conviva/conviva-js-appanalytics) — it's purpose-built for that environment.\n\n### Where is the changelog?\n\nSee [CHANGELOG.md](./CHANGELOG.md).\n","readmeFilename":"README.md","_rev":"1-95075dc75b2966f96af5ae4851ad822a"}