{"_id":"@adfinia/sdk-react-native","_rev":"4-596824b8bccba93a9dc3c4a2f8626449","name":"@adfinia/sdk-react-native","dist-tags":{"latest":"1.2.0"},"versions":{"1.0.0":{"name":"@adfinia/sdk-react-native","version":"1.0.0","keywords":["adfinia","analytics","events","tracking","cdp","identify","react-native","expo","push","sdk"],"author":{"name":"Infinia New Emerging Technologies","email":"engineering@adfinia.com"},"license":"MIT","_id":"@adfinia/sdk-react-native@1.0.0","maintainers":[{"name":"harshganatra93","email":"harshkganatra@gmail.com"}],"homepage":"https://github.com/Adfinia/sdk-react-native#readme","bugs":{"url":"https://github.com/Adfinia/sdk-react-native/issues"},"dist":{"shasum":"db310a74ff00b4cf00860c3d4b3d9eed58d5d045","tarball":"https://registry.npmjs.org/@adfinia/sdk-react-native/-/sdk-react-native-1.0.0.tgz","fileCount":24,"integrity":"sha512-XfGF18tSQ1CaGLcVoXNqN+JCkYOPxsWjKyXWzzohnSg7lInsGszsZyJKFMPfW2/RKFc7mB+m44eHp1f+M83hZg==","signatures":[{"sig":"MEYCIQCHTAKPx1WYBLi2bxyqiuOLO5JrIdtfSCNgFe9Zts97pwIhAJboQMm7qi3TqcTQYCuMYOW1YgUukQpMfL8//E693QD+","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":361084},"main":"./dist/index.cjs","types":"./dist/index.d.ts","module":"./dist/index.js","source":"./src/index.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs","react-native":"./dist/index.js"}},"gitHead":"f63c2d35e2a5a2766719e12c2ab4d9274db9a474","scripts":{"dev":"tsup --watch","lint":"tsc --noEmit","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"harshganatra93","email":"harshkganatra@gmail.com"},"repository":{"url":"git+https://github.com/Adfinia/sdk-react-native.git","type":"git"},"_npmVersion":"11.11.1","description":"Official Adfinia SDK for React Native / Expo - first-party event + identify ingestion and native push.","directories":{},"sideEffects":false,"_nodeVersion":"25.8.2","react-native":"./dist/index.js","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.2","vitest":"^1.6.0","typescript":"^5.4.0","@types/node":"^20.11.0","@vitest/coverage-v8":"^1.6.0"},"peerDependencies":{"react":">=18.0.0","expo-crypto":">=13.0.0","expo-device":">=6.0.0","react-native":">=0.74.0","expo-constants":">=15.0.0","expo-localization":">=15.0.0","expo-notifications":">=0.27.0","@react-native-async-storage/async-storage":">=1.21.0"},"peerDependenciesMeta":{"expo-device":{"optional":true},"expo-constants":{"optional":true},"expo-localization":{"optional":true},"expo-notifications":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk-react-native_1.0.0_1782733485656_0.9587588601980062","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@adfinia/sdk-react-native","version":"1.0.1","keywords":["adfinia","analytics","events","tracking","cdp","identify","react-native","expo","push","sdk"],"author":{"name":"Infinia New Emerging Technologies","email":"engineering@adfinia.com"},"license":"MIT","_id":"@adfinia/sdk-react-native@1.0.1","maintainers":[{"name":"harshganatra93","email":"harshkganatra@gmail.com"}],"homepage":"https://github.com/Adfinia/sdk-react-native#readme","bugs":{"url":"https://github.com/Adfinia/sdk-react-native/issues"},"dist":{"shasum":"fca9e2020bb0d537e6af21e8f08fae002863accf","tarball":"https://registry.npmjs.org/@adfinia/sdk-react-native/-/sdk-react-native-1.0.1.tgz","fileCount":24,"integrity":"sha512-ncBazoW5kS4HjXRA/r++MVPLj9oLlU0cTm7lVE6zDRe89NQWspdUIUhqWIL8LRcQjVAbnLiGRgRDzkajqlLpOA==","signatures":[{"sig":"MEYCIQCsIbeLmOehcN4HOx6G1RxN6K/W3JGX/Jb0UwU3OQIHHAIhAIx1JJzlNL9rsTI9xIIjHf24N8lNE3GEc+HKXNd3ifnt","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":361189},"main":"./dist/index.cjs","types":"./dist/index.d.ts","module":"./dist/index.js","source":"./src/index.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs","react-native":"./dist/index.js"}},"gitHead":"eaec6625c58b881815c8f9876787c08aed16f776","scripts":{"dev":"tsup --watch","lint":"tsc --noEmit","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"harshganatra93","email":"harshkganatra@gmail.com"},"repository":{"url":"git+https://github.com/Adfinia/sdk-react-native.git","type":"git"},"_npmVersion":"11.11.1","description":"Official Adfinia SDK for React Native / Expo - first-party event + identify ingestion and native push.","directories":{},"sideEffects":false,"_nodeVersion":"25.8.2","react-native":"./dist/index.js","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.2","vitest":"^1.6.0","typescript":"^5.4.0","@types/node":"^20.11.0","@vitest/coverage-v8":"^1.6.0"},"peerDependencies":{"react":">=18.0.0","expo-crypto":">=13.0.0","expo-device":">=6.0.0","react-native":">=0.74.0","expo-constants":">=15.0.0","expo-localization":">=15.0.0","expo-notifications":">=0.27.0","@react-native-async-storage/async-storage":">=1.21.0"},"peerDependenciesMeta":{"expo-device":{"optional":true},"expo-constants":{"optional":true},"expo-localization":{"optional":true},"expo-notifications":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk-react-native_1.0.1_1782735744892_0.18474687571043535","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@adfinia/sdk-react-native","version":"1.1.1","keywords":["adfinia","analytics","events","tracking","cdp","identify","react-native","expo","push","sdk"],"author":{"name":"Infinia New Emerging Technologies","email":"engineering@adfinia.com"},"license":"MIT","_id":"@adfinia/sdk-react-native@1.1.1","maintainers":[{"name":"harshganatra93","email":"harshkganatra@gmail.com"}],"homepage":"https://github.com/Adfinia/sdk-react-native#readme","bugs":{"url":"https://github.com/Adfinia/sdk-react-native/issues"},"dist":{"shasum":"fe801ea44dd983458625f11ca0ab671379bf6663","tarball":"https://registry.npmjs.org/@adfinia/sdk-react-native/-/sdk-react-native-1.1.1.tgz","fileCount":24,"integrity":"sha512-NF+scPlAZH3gVN1nDdYLfwg7wVSVfSwFkT5bsZ9uU2jKDrZ65Oj9120GyxZ/GxwnYAa+4NcxC/DxA99L8p8v7w==","signatures":[{"sig":"MEUCIBFGAR/zwoshnhM0qma7ioVSsKVoKEFioFAJapwTj0ngAiEAixhPnjTc+xLUXD/L7nvreuadgcjq1UyRCIEaKpfGU7U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":390665},"main":"./dist/index.cjs","types":"./dist/index.d.ts","module":"./dist/index.js","source":"./src/index.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs","react-native":"./dist/index.js"}},"gitHead":"05a693a89f63fba2d7434ff53504bf5d521e5992","scripts":{"dev":"tsup --watch","lint":"tsc --noEmit","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"harshganatra93","email":"harshkganatra@gmail.com"},"repository":{"url":"git+https://github.com/Adfinia/sdk-react-native.git","type":"git"},"_npmVersion":"11.11.1","description":"Official Adfinia SDK for React Native / Expo - first-party event + identify ingestion and native push.","directories":{},"sideEffects":false,"_nodeVersion":"25.8.2","react-native":"./dist/index.js","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.2","vitest":"^1.6.0","typescript":"^5.4.0","@types/node":"^20.11.0","@vitest/coverage-v8":"^1.6.0"},"peerDependencies":{"react":">=18.0.0","expo-crypto":">=13.0.0","expo-device":">=6.0.0","react-native":">=0.74.0","expo-constants":">=15.0.0","expo-localization":">=15.0.0","expo-notifications":">=0.27.0","@react-native-async-storage/async-storage":">=1.21.0"},"peerDependenciesMeta":{"expo-device":{"optional":true},"expo-constants":{"optional":true},"expo-localization":{"optional":true},"expo-notifications":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk-react-native_1.1.1_1784733115953_0.9529864683692317","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@adfinia/sdk-react-native","version":"1.2.0","description":"Official Adfinia SDK for React Native / Expo - first-party event + identify ingestion and native push.","license":"MIT","author":{"name":"Infinia New Emerging Technologies","email":"engineering@adfinia.com"},"homepage":"https://github.com/Adfinia/sdk-react-native#readme","repository":{"type":"git","url":"git+https://github.com/Adfinia/sdk-react-native.git"},"bugs":{"url":"https://github.com/Adfinia/sdk-react-native/issues"},"main":"./dist/index.cjs","module":"./dist/index.js","react-native":"./dist/index.js","types":"./dist/index.d.ts","source":"./src/index.ts","exports":{".":{"types":"./dist/index.d.ts","react-native":"./dist/index.js","import":"./dist/index.js","require":"./dist/index.cjs"}},"keywords":["adfinia","analytics","events","tracking","cdp","identify","react-native","expo","push","sdk"],"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","typecheck":"tsc --noEmit","lint":"tsc --noEmit","prepublishOnly":"npm run build && npm test"},"publishConfig":{"access":"public"},"peerDependencies":{"react":">=18.0.0","react-native":">=0.74.0","@react-native-async-storage/async-storage":">=1.21.0","expo-constants":">=15.0.0","expo-crypto":">=13.0.0","expo-device":">=6.0.0","expo-localization":">=15.0.0","expo-notifications":">=0.27.0"},"peerDependenciesMeta":{"expo-constants":{"optional":true},"expo-device":{"optional":true},"expo-localization":{"optional":true},"expo-notifications":{"optional":true}},"devDependencies":{"@types/node":"^20.11.0","@vitest/coverage-v8":"^1.6.0","tsup":"^8.0.2","typescript":"^5.4.0","vitest":"^1.6.0"},"engines":{"node":">=18"},"sideEffects":false,"gitHead":"23b6454476fa3a2072748e9f861a59597b65ff2b","_id":"@adfinia/sdk-react-native@1.2.0","_nodeVersion":"25.8.2","_npmVersion":"11.11.1","dist":{"integrity":"sha512-Rln7PGup+efv3nll1zuG47OpHld1SL8j9Q7J4eim+TDrZgunFrhcOfkIo2+uavJKLi39gQ4ZE5hg8Y58zh0FTw==","shasum":"390b363dbe7f17f9231e9b4308d9c41ba7dea7f1","tarball":"https://registry.npmjs.org/@adfinia/sdk-react-native/-/sdk-react-native-1.2.0.tgz","fileCount":25,"unpackedSize":516327,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC+EmSHpn1FsDh37xahaQfwALtLFyxc3bhIqyvb+w7u2AIhAOrfEDXDjiwkVczXbFh3tD225AK68c63KezP1Nv4also"}]},"_npmUser":{"name":"harshganatra93","email":"harshkganatra@gmail.com"},"directories":{},"maintainers":[{"name":"harshganatra93","email":"harshkganatra@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk-react-native_1.2.0_1784880397292_0.014008599622707507"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-29T11:44:45.542Z","modified":"2026-07-24T08:06:37.572Z","1.0.0":"2026-06-29T11:44:45.835Z","1.0.1":"2026-06-29T12:22:25.095Z","1.1.1":"2026-07-22T15:11:56.103Z","1.2.0":"2026-07-24T08:06:37.438Z"},"bugs":{"url":"https://github.com/Adfinia/sdk-react-native/issues"},"author":{"name":"Infinia New Emerging Technologies","email":"engineering@adfinia.com"},"license":"MIT","homepage":"https://github.com/Adfinia/sdk-react-native#readme","keywords":["adfinia","analytics","events","tracking","cdp","identify","react-native","expo","push","sdk"],"repository":{"type":"git","url":"git+https://github.com/Adfinia/sdk-react-native.git"},"description":"Official Adfinia SDK for React Native / Expo - first-party event + identify ingestion and native push.","maintainers":[{"name":"harshganatra93","email":"harshkganatra@gmail.com"}],"readme":"# @adfinia/sdk-react-native\n\nOfficial Adfinia SDK for React Native / Expo. First-party event + identify\ningestion and native push, with the same wire contract as\n[`@adfinia/sdk-web`](https://www.npmjs.com/package/@adfinia/sdk-web).\n\n- **Pure TypeScript core** - no native modules. Analytics works in Expo Go and\n  any RN runtime.\n- **Native push** - FCM (Android) / APNs (iOS) via `expo-notifications`\n  (requires a development build).\n- **Offline-durable** - events persist to AsyncStorage and retry with backoff.\n- **Zero PII by default** - device context is opt-in (`autoContext: true`).\n\n## Install\n\n```sh\nnpx expo install @adfinia/sdk-react-native \\\n  @react-native-async-storage/async-storage expo-crypto \\\n  expo-localization expo-device expo-constants\n# push only (optional):\nnpx expo install expo-notifications\n```\n\n## Quick start\n\n```ts\nimport { Adfinia } from '@adfinia/sdk-react-native'\n\n// Once, at app start. The ingest host is baked in - do not configure it.\nAdfinia.init({\n  writeKey: 'pk_live_xxx',          // your tenant write key\n  autoContext: true,                // opt in to device context\n  consent: () => userAllowedAnalytics,\n})\n\n// Identify - PredictStreet keys identity by the wallet hash (external_id).\nAdfinia.identify({\n  externalId: walletHash,\n  traits: { source: 'sdk_react_native', country: 'AE', email: 'a@example.ae' },\n})\n\n// Track product events.\nAdfinia.track('order_placed', { market_id: 'fifwc-fra-sen-2026', stake_usd: 50 })\n\n// Screens (the mobile equivalent of page views).\nAdfinia.screen('Markets')\n\n// Drain before a critical moment.\nawait Adfinia.flush()\n\n// Logout.\nAdfinia.reset()\n```\n\n## API\n\n| Method | Purpose |\n|--------|---------|\n| `init(config)` | Initialise. `writeKey` required. |\n| `identify(idOrObj, traits?)` | Attach identity (`customerId` / `externalId`) + traits. |\n| `track(event, props?, opts?)` | Record a product event. |\n| `screen(name?, props?, opts?)` | Record a screen view (primary view event on mobile). |\n| `page(name?, props?, opts?)` | Alias of `screen` for cross-SDK parity. |\n| `setConsent(channels, status)` | Write-only consent. `channels` is a single channel string or an array; `status` is `'opted_in'` or `'opted_out'`. Channels are open strings (not an enum) - the backend owns the valid-channel registry. Emits one `consent_updated` event with `channels` always an array. No read method by design. |\n| `optIn(channels)` | Shorthand for `setConsent(channels, 'opted_in')`. |\n| `optOut(channels)` | Shorthand for `setConsent(channels, 'opted_out')`. |\n| `alias(newId, prevId?)` | Merge an anonymous identity into a known one. |\n| `reset()` | Clear identity, mint a new anonymous id (logout). |\n| `flush()` | Drain the queue now. Returns a promise. |\n| `registerPush(config?)` | Register for native push (see below). |\n| `notifications.list({ status?, cursor?, limit? })` | A page of in-app notifications: `{ data, nextCursor, hasMore }`. See [In-app inbox](#in-app-inbox). |\n| `notifications.markRead(id)` / `markAllRead()` | Mark one / all read. Returns `Promise<boolean>`. |\n| `notifications.subscribe(handler, options?)` | Live subscription (SSE or long-poll). Returns `{ unsubscribe() }`. |\n| `notifications.trackOpened(n)` / `trackClicked(n)` | Emit `notification_opened` / `notification_clicked` track events. |\n\n`opts` carries a per-call `externalId` and a `context` map (caller wins on key\ncollision).\n\n### Config\n\n```ts\nAdfinia.init({\n  writeKey: string,          // required\n  debug?: boolean,           // log internals to console.debug\n  consent?: () => boolean,   // gate; false drops the call silently\n  autoContext?: boolean,     // collect device context (default false)\n  flushAt?: number,          // batch size that triggers a flush (default 50)\n  flushIntervalMs?: number,  // flush interval (default 5000)\n  maxQueueSize?: number,     // max buffered events (default 1000)\n})\n```\n\n## Native push\n\n```ts\nconst res = await Adfinia.registerPush()\nif (res.ok) {\n  // token registered with Adfinia; backend dispatches via FCM/APNs\n} else {\n  // res.reason: 'unsupported' | 'permission_denied' | 'token_failed' | ...\n}\n```\n\n`registerPush()` uses `expo-notifications` `getDevicePushTokenAsync()` to get the\n**native** device token (FCM on Android, APNs on iOS) and POSTs it to\n`/api/v1/push/register`. Requirements:\n\n1. `expo-notifications` installed.\n2. A **development build** (Expo Go cannot obtain native device tokens).\n3. FCM (`google-services.json`) configured for Android; an APNs key + the Push\n   capability for iOS.\n\nSee the SDK publishing/push runbook for the full account + credential setup.\n\n## In-app inbox\n\n`Adfinia.notifications` is a framework-agnostic data client for the in-app notification inbox. It ships **no UI** - you render the bell, list, and toasts; the SDK gives you typed notifications, a live subscription, and the open/click events.\n\n```ts\n// Page through the inbox (cursor-paginated).\nconst page = await Adfinia.notifications.list({ status: 'unread', limit: 20 })\nif (page.hasMore) {\n  const next = await Adfinia.notifications.list({ cursor: page.nextCursor! })\n}\n\n// Subscribe to live updates. On connect the handler fires once per\n// currently-unread notification (replay), then once per new one.\nconst sub = Adfinia.notifications.subscribe((n) => {\n  showToast(n) // { id, title, body, severity, deep_link?, ... }\n})\n\n// Record engagement + mark read when the user interacts.\nAdfinia.notifications.trackOpened(n)    // -> notification_opened\nawait Adfinia.notifications.markRead(n.id)\nAdfinia.notifications.trackClicked(n)   // -> notification_clicked\nawait Adfinia.notifications.markAllRead()\n\n// Tear down on logout / unmount.\nsub.unsubscribe()\n```\n\nThe `InboxNotification` shape is `{ id, contact_id, title, body, severity('info'|'success'|'warning'|'error'), dismissable, deep_link?, data?, read, created_at, read_at?, expires_at? }`.\n\n**Identity.** The inbox is keyed on the current contact - `contact_id` resolves from the active identity in the server's order (`customer_id` > `external_id` > `anonymous_id`). Call `identify(...)` first, or pass `{ contactId }` to any method.\n\n**Live transport.** React Native has no built-in `EventSource`. `subscribe()` uses a real SSE stream when an EventSource implementation is available, and otherwise **long-polls** the unread list:\n\n```ts\n// Preferred: pass an EventSource (e.g. react-native-sse) for a true stream.\nimport EventSource from 'react-native-sse'\nconst sub = Adfinia.notifications.subscribe(showToast, { eventSource: EventSource })\n\n// No EventSource? It long-polls automatically; tune the interval:\nconst sub2 = Adfinia.notifications.subscribe(showToast, { pollIntervalMs: 30_000 })\n```\n\nBoth paths replay currently-unread on connect and de-dupe delivery by id, so the transport choice is invisible to your handler. Live SSE complements native push: [`registerPush()`](#native-push) delivers **background** system notifications; the inbox stream powers the **in-app** list while the app is foregrounded.\n\n## Screen tracking\n\n```tsx\nimport { usePathname } from 'expo-router'\nimport { useAdfiniaScreenTracking } from '@adfinia/sdk-react-native'\n\nfunction RootLayout() {\n  useAdfiniaScreenTracking(usePathname())\n  // ...\n}\n```\n\n## Wire contract\n\nIdentical to `@adfinia/sdk-web`: events POST to `/api/v1/track[/batch]` and\n`/api/v1/identify[/batch]` with fields `customer_id`, `external_id`,\n`anonymous_id`, `event_name`, `properties`, `traits`, `context`, `occurred_at`;\nauth via `Authorization: Bearer <writeKey>` and `X-Adfinia-SDK-Version`. Server\nidentity resolution order: `customer_id` > `external_id` > `anonymous_id`.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}