react-native-test-adx 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,16 +1,12 @@
1
1
  # react-native-adaxon
2
2
 
3
- Adaxon React Native / Expo SDK for event tracking and offer recommendations.
3
+ React Native / Expo SDK for event tracking and offer recommendations.
4
4
 
5
- The SDK talks to the MTS tracker over HTTPS. The app does not call Kafka or MySQL.
6
-
7
- ```text
8
- Mobile app → Adaxon SDK → HTTPS → MTS tracker → Kafka → MTS API → MySQL
9
- ```
5
+ **Dependencies:** `react` and `react-native` only. The SDK does not bundle AsyncStorage, NetInfo, or other storage/network libraries.
10
6
 
11
7
  ## Install
12
8
 
13
- ### Production apps
9
+ **Production**
14
10
 
15
11
  ```sh
16
12
  npm install react-native-adaxon
@@ -20,53 +16,21 @@ yarn add react-native-adaxon
20
16
  npx expo install react-native-adaxon
21
17
  ```
22
18
 
23
- ```ts
24
- import { AdaxonProvider, useAdaxon } from 'react-native-adaxon';
25
- ```
26
-
27
- ### Testing / staging apps
19
+ **Testing / staging**
28
20
 
29
21
  ```sh
30
22
  npm install react-native-test-adx
31
23
  ```
32
24
 
33
- ```ts
34
- import { AdaxonProvider, useAdaxon } from 'react-native-test-adx';
35
- ```
36
-
37
- Both packages expose the same API. Only the npm name differs.
38
-
39
- ## Quick start (React Native)
40
-
41
- Wrap the app in `AdaxonProvider`. Screens use `useAdaxon()`.
25
+ Both packages expose the same public API.
42
26
 
43
- Tracking does **not** write React state, so `logEvent` / `track` will not re-render the tree.
44
-
45
- ### Configuration
46
-
47
- The SDK owns the tracker host and API paths (`/event/tracking`, `/api/mts/recommendations`, `/click/tracking`). The app only provides credentials.
48
-
49
- | Field | Required | Default |
50
- |---|---|---|
51
- | `appId` | **Yes** | None. MTS app id (`adx_…`). |
52
- | `sdkKey` | **Yes** | None. Sent as the `x-sdk-key` header. |
53
- | `storage` | No | In-memory event queue and anonymous id. Offline events and the generated id are lost on app restart. |
54
- | `timeoutMs` | No | `10000` |
55
- | `testMode` | No | `false` (`sdk_version` gets a `-test` suffix when true) |
56
- | `externalUserId` | No | Unset |
57
-
58
- The SDK detects the device platform and collects device/app fields automatically. Do **not** pass a tracker URL — requests go to the SDK `BASE_URL`.
27
+ ## Quick start
59
28
 
60
29
  ```tsx
61
- import {
62
- AdaxonProvider,
63
- AdxEvent,
64
- useAdaxon,
65
- type RecommendationOffer,
66
- } from 'react-native-adaxon';
67
- import { Button, Text, View } from 'react-native';
68
-
69
- function App() {
30
+ import { AdaxonProvider, useAdaxon } from 'react-native-adaxon';
31
+ import { Button, Text } from 'react-native';
32
+
33
+ export default function App() {
70
34
  return (
71
35
  <AdaxonProvider
72
36
  configuration={{
@@ -81,266 +45,426 @@ function App() {
81
45
  }
82
46
 
83
47
  function HomeScreen() {
84
- const {
85
- isInitialized,
86
- logEvent,
87
- trackPurchase,
88
- trackAddToCart,
89
- loadRecommendations,
90
- showOffer,
91
- } = useAdaxon();
48
+ const { isInitialized, initializationError, logEvent } = useAdaxon();
92
49
 
93
50
  if (!isInitialized) {
94
- return <Text>Initializing…</Text>;
51
+ return <Text>{initializationError ?? 'Initializing…'}</Text>;
95
52
  }
96
53
 
97
54
  return (
98
- <View>
99
- <Button
100
- title="Custom event"
101
- onPress={() =>
102
- logEvent('level_completed', {
103
- level_number: 10,
104
- coins_used: 50,
105
- })
106
- }
107
- />
108
- <Button
109
- title="Purchase"
110
- onPress={() =>
111
- trackPurchase({
112
- order_id: 'ORD123',
113
- amount: 999,
114
- currency: 'INR',
115
- })
116
- }
117
- />
118
- <Button
119
- title="Add to cart"
120
- onPress={() =>
121
- trackAddToCart({
122
- product_id: 'P123',
123
- price: 499,
124
- currency: 'INR',
125
- })
126
- }
127
- />
128
- <Button
129
- title="Load offers"
130
- onPress={async () => {
131
- const offers: RecommendationOffer[] = await loadRecommendations(
132
- 'recommendation_view',
133
- { placement: 'home' }
134
- );
135
- if (offers[0]) {
136
- await showOffer(offers[0]);
137
- }
138
- }}
139
- />
140
- </View>
55
+ <Button
56
+ title="Track event"
57
+ onPress={() => logEvent('level_completed', { level_number: 10 })}
58
+ />
141
59
  );
142
60
  }
143
61
  ```
144
62
 
145
- Do **not** pass device or app fields. The SDK attaches `device` and `app` automatically on every event.
63
+ Tracking calls do not update React state, so `logEvent` and `track` will not re-render your app.
146
64
 
147
- ### Anonymous id
65
+ `AdaxonProvider` is required for full-screen ads (`showAd`).
148
66
 
149
- `user.anonymous_id` is generated by the SDK. It reads a unique id from React Native `NativeModules` when the host exposes one, otherwise it generates a UUID. The value is cached for the process and written to the configured `storage` adapter so the same id is reused across app launches. No third-party device-info package is required.
67
+ ## Configuration
150
68
 
151
- ### Storage
69
+ Pass `configuration` to `AdaxonProvider`, or to `Adaxon.initialize()` when not using React.
152
70
 
153
- `storage` is optional. It persists the **event queue** (offline / pending events) and the **anonymous id**. Only `appId` and `sdkKey` are required.
71
+ | Field | Required | Default | Description |
72
+ |---|---|---|---|
73
+ | `appId` | Yes | — | Your MTS app id (`adx_…`) |
74
+ | `sdkKey` | Yes | — | Sent as the `x-sdk-key` header |
75
+ | `storage` | No | In-memory | Persists offline event queue and anonymous id |
76
+ | `timeoutMs` | No | `10000` | HTTP timeout in ms |
77
+ | `testMode` | No | `false` | Sets `sdk_version` to `{version}-test` when true |
154
78
 
155
- | What you pass | What happens |
156
- |---|---|
157
- | No `storage` | The queue and anonymous id stay in memory. Tracking still works. Both are lost if the app closes. |
158
- | A storage adapter | Queued events and the anonymous id survive restart. |
79
+ Only `appId` and `sdkKey` are required. Do not pass a tracker URL — the SDK owns the host and API paths.
159
80
 
160
- The adapter is only `getItem` / `setItem` / `removeItem`. You do not implement the queue.
81
+ The SDK attaches `device`, `app`, `user.anonymous_id`, and network fields automatically. Do not pass them in event calls.
161
82
 
162
- ### Non-component boot
83
+ ### Persistent storage (optional)
163
84
 
164
- `Adaxon.initialize()` is still available if you are not inside a React tree. Prefer the provider in React Native apps.
85
+ By default the SDK uses in-memory storage. Offline events and the anonymous id are lost when the app closes.
165
86
 
166
- ```ts
167
- import { Adaxon } from 'react-native-adaxon';
87
+ Pass any object that implements `AdaxonStorageAdapter`:
168
88
 
169
- await Adaxon.initialize({
170
- appId: 'adx_your_app_id',
171
- sdkKey: 'your_sdk_key',
172
- });
89
+ ```tsx
90
+ <AdaxonProvider
91
+ configuration={{
92
+ appId: 'adx_your_app_id',
93
+ sdkKey: 'your_sdk_key',
94
+ storage: {
95
+ getItem: (key) => myKeyValueStore.get(key),
96
+ setItem: (key, value) => myKeyValueStore.set(key, value),
97
+ removeItem: (key) => myKeyValueStore.delete(key),
98
+ },
99
+ }}
100
+ >
101
+ {/* … */}
102
+ </AdaxonProvider>
103
+ ```
173
104
 
174
- await Adaxon.logEvent('level_completed', { level_number: 10 });
105
+ ---
106
+
107
+ ## Public API reference
108
+
109
+ Everything below is exported from `react-native-adaxon` / `react-native-test-adx` via `src/index.ts`.
110
+
111
+ **React apps:** use `AdaxonProvider` + `useAdaxon()`.
112
+
113
+ **Non-React apps:** use the `Adaxon` singleton (`AdaxonSdk.shared`).
114
+
115
+ ### `AdaxonProvider`
116
+
117
+ Initializes the SDK when the app mounts and mounts the interstitial overlay for ads.
118
+
119
+ ```tsx
120
+ import { AdaxonProvider } from 'react-native-adaxon';
121
+
122
+ <AdaxonProvider
123
+ configuration={{ appId: 'adx_your_app_id', sdkKey: 'your_sdk_key' }}
124
+ listener={{
125
+ onInitializationComplete: () => console.log('Adaxon ready'),
126
+ onInitializationFailed: (code, message) =>
127
+ console.warn('Adaxon init failed', code, message),
128
+ }}
129
+ >
130
+ {/* your app */}
131
+ </AdaxonProvider>
175
132
  ```
176
133
 
177
- ## API
134
+ | Prop | Required | Description |
135
+ |---|---|---|
136
+ | `configuration` | Yes | SDK credentials and optional settings |
137
+ | `listener` | No | Init success/failure callbacks |
138
+ | `children` | Yes | App content |
178
139
 
179
- | Method | What it does |
180
- |---|---|
181
- | `AdaxonProvider` | Starts the SDK once when the app mounts |
182
- | `useAdaxon()` | Hook for screens: track, recommendations, offers |
183
- | `logEvent(name, values)` | Custom or predefined event |
184
- | `trackPurchase(params)` | Sends `adx_purchase` |
185
- | `trackAddToCart(params)` | Sends `adx_add_to_cart` |
186
- | `trackLogin(params)` | Sends `adx_login` |
187
- | `trackCompleteRegistration(params)` | Sends `adx_complete_registration` |
188
- | `track` / `trackBatch` | Send immediately. `trackBatch` accepts 1–100 events |
189
- | `enqueueEvent(name, properties)` | Store an event locally; does not send yet |
190
- | `processPendingEvents()` | Send queued events in batches of up to 100 |
191
- | `loadRecommendations(eventName, properties)` | POST `/api/mts/recommendations` |
192
- | `showOffer(offer)` | Opens the offer URL and tracks `offer_opened` |
193
- | `setExternalUserId(id)` | Attaches `external_user_id` on later events |
194
-
195
- Predefined names: `AdxEvent.PURCHASE`, `AdxEvent.ADD_TO_CART`, `AdxEvent.LOGIN`, `AdxEvent.COMPLETE_REGISTRATION`.
196
-
197
- ## Event queue and batch processing
198
-
199
- `track` and `trackBatch` send immediately. Use `enqueueEvent` / `processPendingEvents` when events should wait in the local queue.
140
+ ---
200
141
 
201
- ```ts
202
- const { enqueueEvent, processPendingEvents } = useAdaxon();
142
+ ### `useAdaxon()`
143
+
144
+ Hook that returns init status and all tracking, queue, and ad methods. Must be used inside `AdaxonProvider`.
145
+
146
+ ```tsx
147
+ const adaxon = useAdaxon();
148
+ ```
149
+
150
+ #### `isInitialized`
151
+
152
+ `boolean` — `true` after the SDK initializes successfully.
153
+
154
+ ```tsx
155
+ const { isInitialized } = useAdaxon();
156
+
157
+ if (!isInitialized) {
158
+ return <Text>Loading…</Text>;
159
+ }
160
+ ```
161
+
162
+ #### `initializationError`
163
+
164
+ `string | null` — error message when initialization failed; `null` on success or while initializing.
165
+
166
+ ```tsx
167
+ const { isInitialized, initializationError } = useAdaxon();
168
+
169
+ if (!isInitialized) {
170
+ return <Text>{initializationError ?? 'Initializing…'}</Text>;
171
+ }
172
+ ```
173
+
174
+ #### `logEvent(eventName, values?, options?)`
175
+
176
+ Track a custom event. `values` are normalized to event properties.
177
+
178
+ ```tsx
179
+ const { logEvent } = useAdaxon();
180
+
181
+ await logEvent('level_completed', { level_number: 10, coins_used: 50 });
182
+ ```
183
+
184
+ Event names must match `^[a-zA-Z][a-zA-Z0-9_]*$` and be at most 100 characters.
185
+
186
+ #### `track(eventName, properties?, options?)`
187
+
188
+ Send one event immediately when online. When offline, the event is queued automatically.
189
+
190
+ ```tsx
191
+ const { track } = useAdaxon();
192
+
193
+ await track('button_clicked', { button_name: 'checkout' });
194
+ ```
195
+
196
+ #### `trackBatch(events)`
197
+
198
+ Send 1–100 events in one request when online. When offline, events are queued automatically.
199
+
200
+ ```tsx
201
+ const { trackBatch } = useAdaxon();
202
+
203
+ await trackBatch([
204
+ { eventName: 'screen_view', properties: { screen: 'home' } },
205
+ { eventName: 'screen_view', properties: { screen: 'settings' } },
206
+ ]);
207
+ ```
208
+
209
+ #### `enqueueEvent(eventName, properties?, options?)`
210
+
211
+ Store an event locally without sending it. Use `processPendingEvents()` to flush the queue.
212
+
213
+ ```tsx
214
+ const { enqueueEvent } = useAdaxon();
203
215
 
204
216
  await enqueueEvent('level_completed', { level_number: 10 });
217
+ ```
218
+
219
+ #### `processPendingEvents()`
220
+
221
+ Flush queued events in FIFO order, up to 100 per batch. Returns a `BatchProcessResult`.
222
+
223
+ ```tsx
224
+ const { processPendingEvents } = useAdaxon();
225
+
205
226
  const result = await processPendingEvents();
206
227
  // result.status: 'completed' | 'stopped' | 'already_processing'
228
+ // result.eventsProcessed, result.batchesSent, result.failedQueueIds
207
229
  ```
208
230
 
209
- How it works:
210
-
211
- ```text
212
- Persistent event queue
213
- ↓
214
- Get next ≤ 100 events (FIFO)
215
- ↓
216
- POST /event/tracking
217
- ↓
218
- Success → remove those events → next batch
219
- Failure → keep events → stop (retry later)
231
+ When the device is offline, `track`, `trackBatch`, and `logEvent` queue events automatically. When connectivity returns, pending events flush in the background. On startup, pending events also flush when the network is available.
232
+
233
+ #### `trackPurchase(params, options?)`
234
+
235
+ Track a purchase event (`AdxEvent.PURCHASE`). Maps `amount` → `adx_revenue`, `currency` → `adx_currency`, `product_id`/`content_id` → `adx_content_id`.
236
+
237
+ ```tsx
238
+ const { trackPurchase } = useAdaxon();
239
+
240
+ await trackPurchase({
241
+ order_id: 'ORD123',
242
+ amount: 999,
243
+ currency: 'INR',
244
+ product_id: 'P123',
245
+ });
220
246
  ```
221
247
 
222
- Rules:
248
+ #### `trackAddToCart(params, options?)`
223
249
 
224
- - Pending events are stored through the `storage` adapter when you pass one, so they survive app restart. If you omit `storage`, they stay in memory only.
225
- - Events are processed in creation order (FIFO).
226
- - Each request contains at most **100** events. A queue of 250 is sent as 100 + 100 + 50.
227
- - Events are removed only after the API confirms success (`success: true`). On network, HTTP, or unknown errors they stay in the queue.
228
- - Only one processor runs at a time for the same app. A second `processPendingEvents()` call returns `already_processing`.
229
- - Large queues are read 100 events at a time. The SDK does not load the whole queue into memory.
230
- - On `Adaxon.initialize()` / `AdaxonProvider` mount, pending events start flushing in the background without blocking startup when the network is available.
231
- - Pass `removeItem` on the storage adapter so successful events can be deleted. If it is omitted, the SDK writes an empty value instead.
250
+ Track an add-to-cart event (`AdxEvent.ADD_TO_CART`). Maps `price` → `adx_revenue`, `currency` → `adx_currency`, `product_id`/`content_id` → `adx_content_id`.
232
251
 
233
- ## Network loss
252
+ ```tsx
253
+ const { trackAddToCart } = useAdaxon();
234
254
 
235
- The SDK watches connectivity through the host app's NetInfo / Expo Network listener. It does **not** poll.
255
+ await trackAddToCart({
256
+ product_id: 'P123',
257
+ price: 499,
258
+ currency: 'INR',
259
+ quantity: 1,
260
+ });
261
+ ```
236
262
 
237
- - Online: `track` / `trackBatch` send immediately, same as before.
238
- - Offline: events are stored in the event queue and no API request is made.
239
- - Offline → online: the batch processor is notified once and pending events are flushed. Duplicate `ONLINE` events do not start extra processors.
240
- - `isNetworkAvailable()` reports the current state. `destroy()` (and Provider unmount) removes the network listener.
263
+ #### `trackLogin(params?, options?)`
241
264
 
242
- A missing or failing network module does not crash the app. Tracking continues as online until the device is known to be offline.
265
+ Track a login event (`AdxEvent.LOGIN`).
243
266
 
244
- Offline events use the same `storage` adapter as above. Without it, they are held in memory and are lost if the app is closed before the network returns.
267
+ ```tsx
268
+ const { trackLogin } = useAdaxon();
245
269
 
246
- ## Automatic device information
270
+ await trackLogin({ method: 'email' });
271
+ ```
247
272
 
248
- ```json
249
- {
250
- "device": {
251
- "platform": "android",
252
- "os_version": "14",
253
- "brand": "Samsung",
254
- "model": "S23",
255
- "language": "en",
256
- "timezone": "Asia/Kolkata"
257
- }
273
+ #### `trackCompleteRegistration(params?, options?)`
274
+
275
+ Track a registration event (`AdxEvent.COMPLETE_REGISTRATION`).
276
+
277
+ ```tsx
278
+ const { trackCompleteRegistration } = useAdaxon();
279
+
280
+ await trackCompleteRegistration({ method: 'google' });
281
+ ```
282
+
283
+ #### `showAd()`
284
+
285
+ Show the first eligible offer as a full-screen interstitial. Does nothing if no offer is available.
286
+
287
+ ```tsx
288
+ const { showAd } = useAdaxon();
289
+
290
+ await showAd();
291
+ ```
292
+
293
+ Requires `AdaxonProvider` for the interstitial overlay.
294
+
295
+ Interstitial behavior:
296
+
297
+ - A progress bar runs for about 8 seconds.
298
+ - The close (×) button appears after the bar completes.
299
+ - Tapping the creative opens `offer_url`.
300
+
301
+ ---
302
+
303
+ ### `Adaxon` (imperative API)
304
+
305
+ Use when React is not available. Exposes the same tracking, queue, and ad methods as `useAdaxon()`, plus lifecycle helpers.
306
+
307
+ ```ts
308
+ import { Adaxon } from 'react-native-adaxon';
309
+ ```
310
+
311
+ #### `Adaxon.initialize(configuration, listener?)`
312
+
313
+ Initialize the SDK. Required before any other call.
314
+
315
+ ```ts
316
+ await Adaxon.initialize({
317
+ appId: 'adx_your_app_id',
318
+ sdkKey: 'your_sdk_key',
319
+ testMode: false,
320
+ });
321
+ ```
322
+
323
+ #### `Adaxon.isInitialized()`
324
+
325
+ Returns whether the SDK has been initialized.
326
+
327
+ ```ts
328
+ if (Adaxon.isInitialized()) {
329
+ await Adaxon.logEvent('app_opened');
258
330
  }
259
331
  ```
260
332
 
261
- Values come from React Native `Platform` (`src/platform/reactNative.ts`). They are read **once** and cached. Missing optional fields are omitted and never block the request.
333
+ #### `Adaxon.isNetworkAvailable()`
262
334
 
263
- ## Automatic app information
335
+ Returns whether the SDK considers the device online.
264
336
 
265
- ```json
266
- {
267
- "app": {
268
- "package_name": "com.example.app",
269
- "app_version": "2.4.1",
270
- "sdk_version": "0.1.3"
271
- }
337
+ ```ts
338
+ if (Adaxon.isNetworkAvailable()) {
339
+ await Adaxon.processPendingEvents();
272
340
  }
273
341
  ```
274
342
 
275
- `package_name` and `app_version` are read from native application APIs (Android package / iOS bundle). `sdk_version` is always set by the SDK. Do **not** pass these fields in `logEvent`, `track`, or `trackBatch` — every event, including each item in a batch, receives the same `app` object automatically. Missing optional fields are omitted and never block the request.
276
-
277
- ## How the folders work
278
-
279
- ```text
280
- App screen
281
- │ useAdaxon().logEvent(...) or enqueueEvent(...) → processPendingEvents()
282
- ▼
283
- components/ + hooks/ + state/ React layer (init only)
284
- ▼
285
- AdaxonSdk.ts Public methods
286
- ▼
287
- core/AdaxonClient.ts Wires services
288
- ▼
289
- services/ Validate, build JSON, queue, batch, HTTPS
290
- ▼
291
- MTS tracker
343
+ #### `Adaxon.destroy()`
344
+
345
+ Tear down the SDK instance. `AdaxonProvider` calls this automatically on unmount.
346
+
347
+ ```ts
348
+ Adaxon.destroy();
292
349
  ```
293
350
 
294
- | Folder | Role |
351
+ #### Tracking, queue, and ads
352
+
353
+ These methods match `useAdaxon()`:
354
+
355
+ | Method | Same as |
295
356
  |---|---|
296
- | `src/index.ts` | Public exports (`Adaxon`, `AdaxonProvider`, `useAdaxon`) |
297
- | `src/AdaxonSdk.ts` | SDK facade (`initialize`, `logEvent`, queue, offers) |
298
- | `src/components/` | `AdaxonProvider` |
299
- | `src/hooks/` | `useAdaxon()` |
300
- | `src/state/` | Init status only — no event list in React state |
301
- | `src/core/` | `AdaxonClient` — connects auth, events, queue, HTTP |
302
- | `src/services/` | Auth, device, app, event build/send, batch processor, network |
303
- | `src/platform/` | Android/iOS fields. **Only `react-native` import** |
304
- | `src/config/` | Tracker host, API paths, timeouts, storage key rules |
305
- | `src/validation/` | Event name, property, and batch-size rules |
306
- | `src/storage/` | Persistent event queue |
307
- | `example/src/` | Demo app: `App.tsx`, `screens/`, `components/` |
357
+ | `Adaxon.logEvent` | `useAdaxon().logEvent` |
358
+ | `Adaxon.track` | `useAdaxon().track` |
359
+ | `Adaxon.trackBatch` | `useAdaxon().trackBatch` |
360
+ | `Adaxon.enqueueEvent` | `useAdaxon().enqueueEvent` |
361
+ | `Adaxon.processPendingEvents` | `useAdaxon().processPendingEvents` |
362
+ | `Adaxon.trackPurchase` | `useAdaxon().trackPurchase` |
363
+ | `Adaxon.trackAddToCart` | `useAdaxon().trackAddToCart` |
364
+ | `Adaxon.trackLogin` | `useAdaxon().trackLogin` |
365
+ | `Adaxon.trackCompleteRegistration` | `useAdaxon().trackCompleteRegistration` |
366
+ | `Adaxon.showAd` | `useAdaxon().showAd` |
367
+
368
+ Example without React:
369
+
370
+ ```ts
371
+ import { Adaxon } from 'react-native-adaxon';
372
+
373
+ await Adaxon.initialize({
374
+ appId: 'adx_your_app_id',
375
+ sdkKey: 'your_sdk_key',
376
+ });
308
377
 
309
- Screens belong in the **host app**, not in the SDK.
378
+ await Adaxon.logEvent('level_completed', { level_number: 10 });
379
+ await Adaxon.trackPurchase({ order_id: 'ORD123', amount: 999, currency: 'INR' });
380
+ await Adaxon.showAd();
381
+ ```
310
382
 
311
- Longer walkthrough for managers and teammates: [ARCHITECTURE.md](./ARCHITECTURE.md).
312
- Framework cost vs vanilla JS is checked by `src/__tests__/performance.framework.test.tsx`.
383
+ Prefer `AdaxonProvider` in React Native apps so init state and interstitials work correctly.
313
384
 
314
- ## Android notes
385
+ ---
315
386
 
316
- Credential `platform` in Adaxon must allow Android (`android` or `react_native`).
387
+ ### Constants
317
388
 
318
- ## Local development (this repo)
389
+ #### `AdxEvent`
319
390
 
320
- ```sh
321
- cd adaxon-sdk
322
- corepack enable
323
- yarn
324
- yarn typecheck
325
- yarn test --watchman=false
326
- yarn prepare
327
- yarn example android:emulator
391
+ Predefined event name constants.
392
+
393
+ ```ts
394
+ import { AdxEvent } from 'react-native-adaxon';
395
+
396
+ AdxEvent.PURCHASE; // 'adx_purchase'
397
+ AdxEvent.ADD_TO_CART; // 'adx_add_to_cart'
398
+ AdxEvent.LOGIN; // 'adx_login'
399
+ AdxEvent.COMPLETE_REGISTRATION; // 'adx_complete_registration'
328
400
  ```
329
401
 
330
- ## Publish to npm
402
+ #### `AdxParam`
331
403
 
332
- ```sh
333
- npm login
334
- yarn publish:test:dry # dry-run testing package
335
- yarn publish:test # publishes react-native-test-adx
336
- yarn publish:prod:dry # dry-run production package
337
- yarn publish:prod # publishes react-native-adaxon
404
+ Predefined property name constants used by commerce helpers.
405
+
406
+ ```ts
407
+ import { AdxParam } from 'react-native-adaxon';
408
+
409
+ AdxParam.REVENUE; // 'adx_revenue'
410
+ AdxParam.CURRENCY; // 'adx_currency'
411
+ AdxParam.CONTENT_ID; // 'adx_content_id'
338
412
  ```
339
413
 
340
- | Environment | Install |
414
+ ---
415
+
416
+ ### Errors
417
+
418
+ Failed SDK calls throw `AdaxonSdkError` with a `code`:
419
+
420
+ | Code | Meaning |
341
421
  |---|---|
342
- | Testing | `npm install react-native-test-adx` |
343
- | Production | `npm install react-native-adaxon` |
422
+ | `INVALID_CONFIG` | Missing or invalid SDK configuration |
423
+ | `VALIDATION_ERROR` | Invalid event name, properties, or batch |
424
+ | `AUTHENTICATION_ERROR` | Invalid SDK key |
425
+ | `HTTP_ERROR` | Server returned an error |
426
+ | `NETWORK_ERROR` | Network request failed |
427
+ | `TIMEOUT` | Request timed out |
428
+
429
+ ```tsx
430
+ import { AdaxonSdkError } from 'react-native-adaxon';
431
+
432
+ try {
433
+ await logEvent('invalid name!', {});
434
+ } catch (error) {
435
+ if (error instanceof AdaxonSdkError) {
436
+ console.warn(error.code, error.message);
437
+ }
438
+ }
439
+ ```
440
+
441
+ ---
442
+
443
+ ### Exported types
444
+
445
+ TypeScript types exported for app integration:
446
+
447
+ | Type | Use |
448
+ |---|---|
449
+ | `AdaxonStorageAdapter` | Custom persistent storage |
450
+ | `AdaxonSdkConfig` | SDK configuration shape |
451
+ | `AdaxonInitializationListener` | Init callbacks for `AdaxonProvider` / `Adaxon.initialize` |
452
+ | `TrackPurchaseParams` | Params for `trackPurchase` |
453
+ | `TrackAddToCartParams` | Params for `trackAddToCart` |
454
+ | `TrackLoginParams` | Params for `trackLogin` / `trackCompleteRegistration` |
455
+ | `EventProperties` | Event property map (`string`, `number`, `boolean`, `null`) |
456
+ | `TrackEventInput` | Single event in `trackBatch` |
457
+ | `TrackEventOptions` | Optional `eventId` / `eventTime` on track calls |
458
+ | `EventIngestionResponse` | Response from track calls |
459
+ | `BatchProcessResult` | Response from `processPendingEvents` |
460
+
461
+ ---
462
+
463
+ ## Android
464
+
465
+ Your Adaxon credential `platform` must allow Android (`android` or `react_native`).
466
+
467
+ ---
344
468
 
345
469
  ## License
346
470