com-tapp-so-sdk 0.1.6 → 1.1.0

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.
@@ -17,10 +17,12 @@ Pod::Spec.new do |s|
17
17
  s.platforms = { :ios => min_ios_version_supported }
18
18
  s.source = { :git => "https://www.tapp.so/.git", :tag => "#{s.version}" }
19
19
 
20
- # Conditionally include source files.
21
- # In legacy mode (RCT_NEW_ARCH_ENABLED != '1') exclude files in the generated folder.
20
+ # Keep architecture behavior explicit:
21
+ # - New Arch: generated specs are compiled by ReactCodegen, so exclude local generated files.
22
+ # - Legacy: generated files are not used.
22
23
  if ENV['RCT_NEW_ARCH_ENABLED'] == '1'
23
24
  s.source_files = "ios/**/*.{h,m,mm,cpp}"
25
+ s.exclude_files = "ios/generated/**/*"
24
26
  else
25
27
  s.source_files = Dir.glob("ios/**/*.{h,m,mm,cpp}").reject { |path| path.include?("generated") }
26
28
  end
@@ -46,6 +48,8 @@ Pod::Spec.new do |s|
46
48
  s.dependency "ReactCommon/turbomodule/core"
47
49
  end
48
50
  end
51
+ # TODO: pin Tapp version when it is updated
49
52
  s.dependency "Tapp"
53
+ # s.dependency "Tapp", "1.1.13"
50
54
  s.dependency "Tapp-Networking"
51
55
  end
package/LICENSE CHANGED
@@ -1,20 +1,9 @@
1
- MIT License
1
+ Copyright (c) 2025 Tapp.so
2
2
 
3
- Copyright (c) 2025 tapp.so
4
- Permission is hereby granted, free of charge, to any person obtaining a copy
5
- of this software and associated documentation files (the "Software"), to deal
6
- in the Software without restriction, including without limitation the rights
7
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- copies of the Software, and to permit persons to whom the Software is
9
- furnished to do so, subject to the following conditions:
3
+ Use of Tapp platform features requires an active Tapp.so account and valid API credentials from https://tapp.so.
10
4
 
11
- The above copyright notice and this permission notice shall be included in all
12
- copies or substantial portions of the Software.
5
+ Unauthorized access to Tapp services, credentials, or private backend endpoints is prohibited.
13
6
 
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- SOFTWARE.
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8
+
9
+ For licensing or commercial inquiries, contact: support@tapp.so
package/README.md CHANGED
@@ -1,263 +1,384 @@
1
- # Tapp React Native SDK
1
+ # com-tapp-so-sdk
2
2
 
3
- The official React Native SDK for [Tapp](https://www.tapp.so/) the growth and attribution platform for modern apps.
3
+ `com-tapp-so-sdk` provides the official React Native integration for Tapp, giving iOS and Android apps a single JS/TS API for SDK initialization, deep-link attribution, tracked URL generation, and event reporting.
4
4
 
5
- ![npm version](https://img.shields.io/npm/v/com-tapp-so-sdk)
6
- ![license](https://img.shields.io/npm/l/com-tapp-so-sdk)
7
- ![platform](https://img.shields.io/badge/platform-ios%20%7C%20android-lightgrey)
5
+ Use this package to decide whether incoming links should be processed by Tapp, retrieve resolved link payloads, and subscribe to deferred-link callbacks from the native SDKs.
8
6
 
9
- ## Overview
7
+ ## Prerequisites
10
8
 
11
- The Tapp React Native SDK allows you to integrate Tapp's powerful attribution and event tracking into your iOS and Android applications. With this SDK, you can:
12
-
13
- - **Track Events**: Monitor user actions like purchases, registrations, and custom interactions.
14
- - **Deep Linking**: Handle deferred deep links to attribute installs and route users to specific content.
15
- - **Affiliate Integration**: Generate dynamic tracking URLs for influencers and partners.
16
- - **Cross-Platform Support**: Seamlessly unified API for both iOS and Android.
17
-
18
- ## Features
19
-
20
- - 🚀 **Easy Initialization**: Single configuration step for both platforms.
21
- - 📊 **Event Tracking**: 40+ predefined event types plus support for custom events.
22
- - 🔗 **Deep Linking**: Robust support for direct and deferred deep linking.
23
- - 🌐 **Affiliate URL Generation**: Create tracking links programmatically.
24
- - ⚡ **TurboModules Support**: Ready for React Native's New Architecture.
25
-
26
- ## Requirements
27
-
28
- - **React Native**: >= 0.70.0
29
- - **iOS**: 13.0+
30
- - **Android**: 5.0+ (API Level 21+)
31
- - **TypeScript**: 5.0+ (recommended)
9
+ - React Native `>=0.70.0`
10
+ - Tapp credentials for your app:
11
+ - `authToken`
12
+ - `tappToken`
13
+ - Android app with `minSdk 24` and `compileSdk 34+`
14
+ - iOS app with deployment target `13.0+`
32
15
 
33
16
  ## Installation
34
17
 
35
- 1. Install the package using `yarn` or `npm`:
18
+ ### 1) Add dependency
36
19
 
37
- ```sh
20
+ ```bash
38
21
  yarn add com-tapp-so-sdk
39
22
  # or
40
23
  npm install com-tapp-so-sdk
41
24
  ```
42
25
 
43
- 2. **iOS Only**: Install CocoaPods dependencies.
26
+ ### 2) Android setup (required)
44
27
 
45
- ```sh
46
- cd ios && pod install
28
+ This SDK depends on Tapp Android artifacts published through JitPack.
29
+
30
+ Add JitPack to your Android repositories:
31
+
32
+ ```gradle
33
+ // android/settings.gradle (or project-level repositories)
34
+ dependencyResolutionManagement {
35
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
36
+ repositories {
37
+ google()
38
+ mavenCentral()
39
+ maven { url 'https://jitpack.io' }
40
+ }
41
+ }
47
42
  ```
48
43
 
49
- 3. **Android**: No extra steps required (auto-linked).
44
+ Ensure your Android app build config is compatible:
50
45
 
51
- ## Configuration
46
+ ```gradle
47
+ // android/app/build.gradle
48
+ android {
49
+ compileSdkVersion 34
52
50
 
53
- To start using the SDK, you need to initialize it with your unique **App Token** and **Auth Token** from the [Tapp Dashboard](https://dashboard.tapp.so).
51
+ defaultConfig {
52
+ minSdkVersion 24
53
+ }
54
54
 
55
- It is recommended to initialize the SDK early in your app's lifecycle, such as in your root App component `useEffect`.
55
+ compileOptions {
56
+ sourceCompatibility JavaVersion.VERSION_1_8
57
+ targetCompatibility JavaVersion.VERSION_1_8
58
+ }
56
59
 
57
- ```tsx
58
- import React, { useEffect } from 'react';
59
- import { start } from 'com-tapp-so-sdk';
60
+ kotlinOptions {
61
+ jvmTarget = '1.8'
62
+ }
63
+ }
64
+ ```
60
65
 
61
- const App = () => {
62
- useEffect(() => {
63
- start({
64
- authToken: 'YOUR_AUTH_TOKEN',
65
- tappToken: 'YOUR_TAPP_TOKEN',
66
- env: 'SANDBOX', // or 'PRODUCTION'
67
- });
68
- }, []);
66
+ ### 3) iOS setup
69
67
 
70
- return <YourAppContent />;
71
- };
68
+ Set iOS deployment target to `13.0+`:
69
+
70
+ ```ruby
71
+ # ios/Podfile
72
+ platform :ios, '13.0'
72
73
  ```
73
74
 
74
- > **Note**: Use `env: 'SANDBOX'` for development/testing and change to `'PRODUCTION'` for App Store/Play Store builds.
75
+ Install and refresh pods:
75
76
 
76
- ## Usage
77
+ ```bash
78
+ cd ios
79
+ pod repo update
80
+ pod install
81
+ ```
77
82
 
78
- ### 1. Tracking Events
83
+ ## Deep Link Setup
79
84
 
80
- Track standard or custom events to measure user engagement and campaign performance.
85
+ To enable incoming link handling, complete both setup tracks:
81
86
 
82
- **Standard Event:**
87
+ 1. Configure your app in the Tapp dashboard.
88
+ 2. Enable Universal Links / App Links in your native project.
83
89
 
84
- ```tsx
85
- import { handleTappEvent, EventAction } from 'com-tapp-so-sdk';
86
-
87
- // Track a "Purchase" event
88
- await handleTappEvent({
89
- eventAction: EventAction.TAPP_PURCHASE,
90
- metadata: {
91
- price: 29.99,
92
- currency: 'USD',
93
- product_id: 'prod_123',
94
- success: true,
95
- },
96
- });
90
+ **Note:** After your application is configured in the Tapp dashboard, Tapp manages the association files required for verification: `apple-app-site-association` (iOS) and `assetlinks.json` (Android). You do not host these files yourself.
91
+
92
+ ### 1. Configure your application in the Tapp dashboard
93
+
94
+ General fields:
95
+
96
+ - Application Name
97
+ - Android App Identifier
98
+ - iOS Bundle Identifier
99
+ - Apple App Store ID
100
+
101
+ When Android deep linking is enabled:
102
+
103
+ - Enable Android Deep Linking
104
+ - SHA-256 Certificate Fingerprint
105
+ - Android App Scheme
106
+
107
+ When iOS universal linking is enabled:
108
+
109
+ - Enable iOS Universal Linking
110
+ - App ID Prefix
111
+ - iOS App Scheme
112
+
113
+ These values must match your real app configuration:
114
+
115
+ - **Android App Identifier** -> Android application ID (for example `com.example.app`)
116
+ - **SHA-256 Certificate Fingerprint** -> signing certificate fingerprint used for the distributed build
117
+ - **Android App Scheme** -> custom scheme configured in your Android manifest (if used)
118
+ - **iOS Bundle Identifier** -> bundle identifier configured in Xcode
119
+ - **Apple App Store ID** -> published App Store app ID, when applicable
120
+ - **App ID Prefix** -> Apple Team ID / App ID prefix used with Associated Domains
121
+ - **iOS App Scheme** -> URL Types scheme configured in Xcode (if used)
122
+
123
+ ### 2. Enable iOS Universal Links
124
+
125
+ In Xcode, open your app target and enable **Associated Domains**.
126
+
127
+ Add your Tapp-managed link domain:
128
+
129
+ ```text
130
+ applinks:your-tapp-link-domain.com
97
131
  ```
98
132
 
99
- **Custom Event:**
133
+ Ensure your iOS Bundle Identifier and App ID Prefix match dashboard values.
100
134
 
101
- ```tsx
102
- // Track a custom event with a specific name
103
- await handleTappEvent({
104
- eventAction: EventAction.CUSTOM,
105
- customValue: 'my_custom_action',
106
- metadata: {
107
- level_achieved: 5,
108
- score: 1200,
109
- },
110
- });
135
+ If custom URL schemes are part of your flow, ensure iOS App Scheme matches URL Types.
136
+
137
+ For reliable Universal Link validation, test on a physical device.
138
+
139
+ After dashboard setup, Tapp serves the required `apple-app-site-association` file for your configured link domain.
140
+
141
+ ### 3. Enable Android App Links
142
+
143
+ Add an intent filter to the receiving activity (usually the launcher activity) in `android/app/src/main/AndroidManifest.xml`:
144
+
145
+ ```xml
146
+ <intent-filter android:autoVerify="true">
147
+ <action android:name="android.intent.action.VIEW" />
148
+ <category android:name="android.intent.category.DEFAULT" />
149
+ <category android:name="android.intent.category.BROWSABLE" />
150
+
151
+ <data
152
+ android:scheme="https"
153
+ android:host="your-tapp-link-domain.com" />
154
+ </intent-filter>
111
155
  ```
112
156
 
113
- ### 2. Deep Linking & Attribution
157
+ If needed, restrict matching using attributes such as `android:pathPrefix`.
158
+
159
+ Ensure these values align with dashboard configuration:
114
160
 
115
- Retrieve attribution data when your app is opened via a Tapp link.
161
+ - Android App Identifier matches your Android application ID
162
+ - SHA-256 Certificate Fingerprint matches the certificate used to sign your app
163
+ - Android App Scheme matches manifest URL-scheme configuration (if used)
116
164
 
117
- **Fetch Deferred Link Data (First Launch):**
165
+ After dashboard setup, Tapp serves `assetlinks.json` for your configured link domain.
166
+
167
+ ### 4. Use the SDK link APIs
168
+
169
+ Use `shouldProcess` before resolving incoming links, then fetch link data when applicable:
118
170
 
119
171
  ```tsx
120
- import { fetchOriginLinkData } from 'com-tapp-so-sdk';
121
-
122
- const checkAttribution = async () => {
123
- const result = await fetchOriginLinkData();
124
-
125
- if (!result.error) {
126
- console.log('Attribution Data:', result.data);
127
- console.log('Campaign:', result.data?.campaign);
128
- console.log('Is First Session:', result.isFirstSession);
129
- } else {
130
- // Note: This is NOT a fatal error, just means no attribution data was found or config is empty
131
- console.log('Attribution Info:', result.message);
172
+ import { fetchLinkData, fetchOriginLinkData, shouldProcess } from 'com-tapp-so-sdk';
173
+
174
+ async function handleIncomingLink(incomingUrl: string) {
175
+ if (await shouldProcess(incomingUrl)) {
176
+ const data = await fetchLinkData(incomingUrl);
177
+ console.log('Resolved link data:', data);
132
178
  }
133
- };
179
+
180
+ const originData = await fetchOriginLinkData();
181
+ console.log('Origin link data:', originData);
182
+ }
134
183
  ```
135
184
 
136
- **Handling Deep Links (Runtime):**
185
+ ### Integration Checklist
186
+
187
+ - [ ] Add package dependency
188
+ - [ ] Add JitPack to Android repositories
189
+ - [ ] Confirm Android `minSdk 24` and `compileSdk 34+`
190
+ - [ ] Confirm iOS deployment target `13.0+`
191
+ - [ ] Configure dashboard application identifiers and link fields
192
+ - [ ] Enable iOS Associated Domains and Android App Links
193
+ - [ ] Initialize SDK once during app startup
194
+ - [ ] Run smoke checks from **Verify Integration**
195
+
196
+ ## Minimal Integration
197
+
198
+ Use this as a minimum working startup flow.
137
199
 
138
200
  ```tsx
139
- import { Linking } from 'react-native';
140
- import { fetchLinkData, shouldProcess } from 'com-tapp-so-sdk';
141
-
142
- // In your deep link handler
143
- const handleUrl = async (url: string) => {
144
- // shouldProcess is async to support both architectures safely
145
- const canProcess = await shouldProcess(url);
146
-
147
- if (canProcess) {
148
- const linkData = await fetchLinkData(url);
149
- if (!linkData.error) {
150
- console.log('Tapp Deep Link Data:', linkData);
151
- console.log('Target Content:', linkData.tappUrl);
152
- }
153
- } else {
154
- // Handle standard deep link
155
- }
156
- };
201
+ import { useEffect } from 'react';
202
+ import { start } from 'com-tapp-so-sdk';
157
203
 
158
- // Listen for incoming links
159
- Linking.addEventListener('url', ({ url }) => handleUrl(url));
204
+ export default function App() {
205
+ useEffect(() => {
206
+ start({
207
+ authToken: 'YOUR_AUTH_TOKEN',
208
+ env: 'SANDBOX',
209
+ tappToken: 'YOUR_TAPP_TOKEN',
210
+ });
211
+ }, []);
212
+
213
+ return null;
214
+ }
160
215
  ```
161
216
 
162
- ### 3. Generate Affiliate URLs
217
+ ## Verify Integration
163
218
 
164
- Create shareable tracking links for your users (e.g., "Invite a Friend").
219
+ After `start(...)`, run a short smoke test:
165
220
 
166
221
  ```tsx
167
- import { url } from 'com-tapp-so-sdk';
168
-
169
- const generateInviteLink = async () => {
170
- try {
171
- const inviteLink = await url(
172
- 'user_123', // Influencer/User ID
173
- 'summer_promo', // Ad Group (optional)
174
- 'banner_v1', // Creative (optional)
175
- { source: 'app_share' } // Custom Data (optional)
176
- );
177
- console.log('Share this link:', inviteLink);
178
- } catch (error) {
179
- console.error('Failed to generate link:', error);
180
- }
181
- };
222
+ import { fetchOriginLinkData, shouldProcess } from 'com-tapp-so-sdk';
223
+
224
+ async function verifyTappSdk() {
225
+ const shouldHandle = await shouldProcess('https://example.com');
226
+ const origin = await fetchOriginLinkData();
227
+
228
+ console.log('shouldProcess(example):', shouldHandle);
229
+ console.log('origin link data:', origin);
230
+ }
182
231
  ```
183
232
 
184
- ## API Reference
233
+ Expected results:
185
234
 
186
- ### `start(config: InitConfig): void`
235
+ - `shouldProcess(...)` returns `true` or `false` without throwing
236
+ - `fetchOriginLinkData()` resolves without throwing
187
237
 
188
- Initializes the SDK.
238
+ ## Recommended App Bootstrap Pattern
189
239
 
190
- - `authToken`: Your API authentication token.
191
- - `tappToken`: Your unique App token.
192
- - `env`: `'PRODUCTION'` | `'SANDBOX'`.
240
+ Use this pattern for production-friendly startup: initialize once, attach listeners once, optionally process a cold-start link, and expose loading/ready/error state.
193
241
 
194
- ### `handleTappEvent(event: TappEventType): Promise<string>`
242
+ ```tsx
243
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
244
+ import {
245
+ addDeferredLinkListener,
246
+ addDidFailResolvingURLListener,
247
+ fetchLinkData,
248
+ shouldProcess,
249
+ start,
250
+ } from 'com-tapp-so-sdk';
251
+
252
+ type BootstrapState = 'idle' | 'loading' | 'ready' | 'error';
253
+
254
+ export function useTappBootstrap(initialLink?: string) {
255
+ const [state, setState] = useState<BootstrapState>('idle');
256
+ const [lastError, setLastError] = useState<unknown>(null);
257
+ const startedRef = useRef(false);
258
+
259
+ const initialize = useCallback(async () => {
260
+ if (startedRef.current) {
261
+ setState('ready');
262
+ return;
263
+ }
195
264
 
196
- Tracks a user event.
265
+ setState('loading');
266
+ try {
267
+ start({
268
+ authToken: 'YOUR_AUTH_TOKEN',
269
+ env: 'PRODUCTION',
270
+ tappToken: 'YOUR_TAPP_TOKEN',
271
+ });
272
+
273
+ const deferredSub = addDeferredLinkListener((event) => {
274
+ console.log('Deferred link:', event);
275
+ });
276
+
277
+ const failSub = addDidFailResolvingURLListener((event) => {
278
+ console.log('Deferred-link resolve failed:', event);
279
+ });
280
+
281
+ if (initialLink && (await shouldProcess(initialLink))) {
282
+ const data = await fetchLinkData(initialLink);
283
+ console.log('Cold-start link data:', data);
284
+ }
285
+
286
+ startedRef.current = true;
287
+ setState('ready');
288
+
289
+ return () => {
290
+ deferredSub.remove();
291
+ failSub.remove();
292
+ };
293
+ } catch (err) {
294
+ setLastError(err);
295
+ setState('error');
296
+ throw err;
297
+ }
298
+ }, [initialLink]);
197
299
 
198
- - `eventAction`: One of `EventAction` enums (e.g., `TAPP_LOGIN`, `TAPP_PURCHASE`).
199
- - `customValue`: String identifier for `EventAction.CUSTOM`.
200
- - `metadata`: Object `{ [key: string]: string | number | boolean }`.
300
+ useEffect(() => {
301
+ let cleanup: (() => void) | void;
302
+ initialize().then((c) => {
303
+ cleanup = c;
304
+ });
201
305
 
202
- ### `fetchOriginLinkData(): Promise<TappLinkDataResponse>`
306
+ return () => {
307
+ if (cleanup) cleanup();
308
+ };
309
+ }, [initialize]);
203
310
 
204
- Fetches attribution data for the current installation/session (deferred deep linking).
311
+ return useMemo(() => ({ state, lastError }), [state, lastError]);
312
+ }
313
+ ```
205
314
 
206
- **Response (`TappLinkDataResponse`):**
207
- - `error`: `boolean` — Indicates if the SDK encountered an issue (e.g. network error).
208
- - `message`: `string | null` — Error description or info message.
209
- - `tappUrl`: `string | null` — The deep link URL.
210
- - `attrTappUrl`: `string | null` — The attributed URL.
211
- - `influencer`: `string | null` — The influencer associated with the link.
212
- - `data`: `{ [key: string]: string }` — Custom link data (never null, empty object if none).
213
- - `isFirstSession`: `boolean` — `true` if this is the first app launch.
315
+ ### Where to use this pattern
214
316
 
215
- ### `fetchLinkData(deepLink: string): Promise<TappLinkDataResponse>`
317
+ Use this bootstrap hook in your app root (the first mounted screen/component after app startup), so Tapp initialization and listener attachment happen immediately.
216
318
 
217
- Resolves link data for a specific URL string (used for direct deep linking).
319
+ ```tsx
320
+ import { Text, View } from 'react-native';
321
+ import { useTappBootstrap } from './useTappBootstrap';
218
322
 
219
- **Returns**: Same response shape as `fetchOriginLinkData`.
323
+ export default function App() {
324
+ const { state, lastError } = useTappBootstrap();
220
325
 
221
- ### `shouldProcess(deepLink: string): Promise<boolean>`
326
+ if (state === 'loading' || state === 'idle') {
327
+ return <Text>Initializing...</Text>;
328
+ }
222
329
 
223
- Checks if the provided URL should be processed by the Tapp SDK.
224
- Returns `true` if it matches Tapp domains/schemes, `false` otherwise.
330
+ if (state === 'error') {
331
+ return <Text>{String(lastError)}</Text>;
332
+ }
225
333
 
226
- ### `url(influencer: string, adGroup?: string, creative?: string, data?: object): Promise<string>`
334
+ return (
335
+ <View>
336
+ <Text>App Ready</Text>
337
+ </View>
338
+ );
339
+ }
340
+ ```
227
341
 
228
- Generates a tracking URL for the specified parameters.
342
+ ## Public API Summary
229
343
 
230
- ## SDK Guarantees
344
+ - `start(config)` initializes the SDK
345
+ - `url(influencer, adGroup?, creative?, data?)` generates a tracking URL
346
+ - `handleTappEvent(event)` reports predefined or custom events
347
+ - `shouldProcess(deepLink)` checks if a link should be handled by Tapp
348
+ - `fetchLinkData(deepLink)` resolves attribution payload for an incoming link
349
+ - `fetchOriginLinkData()` returns deferred/origin attribution payload
350
+ - `addDeferredLinkListener(listener)` subscribes to deferred deep link events
351
+ - `addDidFailResolvingURLListener(listener)` subscribes to resolve-failure events
231
352
 
232
- - **No Throw on Attribution**: `fetchOriginLinkData` and `fetchLinkData` do **not** reject (throw) for standard SDK states (e.g., empty config, no attribution, network error). They resolve an object with `error: true` and a `message`. You should check `response.error` instead of using `try/catch`.
233
- - **Cross-Platform Consistency**: The response shapes for attribution data are identical on iOS and Android.
234
- - **Null Safety**: Optional string fields (`tappUrl`, `influencer`) are returned as `null` (not `undefined` or empty strings) when no value is present, allowing for strict type checking.
353
+ ## Debug Simulation Notes
235
354
 
236
- ## Architecture Notes
355
+ - `simulateTestEvent()` is intentionally disabled and kept only for backward compatibility.
356
+ - `simulateDeferredLink(...)` and `simulateFailResolving(...)` are debug helpers and should never be used in production logic.
237
357
 
238
- ### React Native New Architecture (Fabric/TurboModules)
358
+ ## Troubleshooting
239
359
 
240
- This SDK is fully compatible with React Native's New Architecture.
241
- - **Android**: Supports TurboModules via C++ bindings.
242
- - **iOS**: Fully implemented in Objective-C++ / Swift with TurboModule support enabled.
360
+ ### iOS build fails
243
361
 
244
- No additional configuration is required; the SDK automatically detects the architecture enabled in your project.
362
+ - Confirm deployment target is `13.0+`
363
+ - Reinstall pods:
245
364
 
246
- ## Troubleshooting
365
+ ```bash
366
+ cd ios
367
+ rm -rf Pods Podfile.lock
368
+ pod install
369
+ ```
370
+
371
+ ### Android cannot resolve Tapp dependencies
247
372
 
248
- **iOS: Build Failures ("Swift compiler error" or "module not found")**
249
- - Ensure your iOS deployment target is 13.0 or higher.
250
- - Try cleaning pods: `cd ios && rm -rf Pods Podfile.lock && pod install`.
251
- - Ensure you open the `.xcworkspace` file, not the `.xcodeproj`.
373
+ - Confirm `maven { url 'https://jitpack.io' }` exists in app-level dependency repositories
374
+ - Sync Gradle and rebuild
252
375
 
253
- **Android: "SDK not initialized"**
254
- - Ensure `start()` is called immediately upon app launch.
255
- - Check that your `tappToken` matches the package name defined in the Tapp Dashboard.
376
+ ### Events or attribution data do not appear
256
377
 
257
- **Events not showing in Dashboard**
258
- - Check if `env` is set to `'SANDBOX'` while looking at live data (or vice versa).
259
- - Verify internet connectivity on the device/simulator.
378
+ - Ensure `start(...)` runs once during app startup
379
+ - Verify dashboard credentials (`authToken`, `tappToken`, env)
380
+ - Verify deep link domain and app identifiers are consistent between dashboard and app
260
381
 
261
382
  ## License
262
383
 
263
- MIT License. See [LICENSE](LICENSE) for details.
384
+ See [LICENSE](./LICENSE) for full licensing and usage terms.
@@ -11,6 +11,7 @@ import com.example.tapp.services.network.RequestModels
11
11
  import com.example.tapp.utils.Logger
12
12
  import com.example.tapp.utils.TappConfiguration
13
13
  import com.facebook.react.bridge.Arguments
14
+ import com.facebook.react.bridge.LifecycleEventListener
14
15
  import com.facebook.react.bridge.Promise
15
16
  import com.facebook.react.bridge.ReactApplicationContext
16
17
  import com.facebook.react.bridge.ReactContextBaseJavaModule
@@ -18,6 +19,7 @@ import com.facebook.react.bridge.ReactMethod
18
19
  import com.facebook.react.bridge.ReadableMap
19
20
  import com.facebook.react.bridge.ReadableType
20
21
  import com.facebook.react.bridge.WritableMap
22
+ import com.facebook.react.common.LifecycleState
21
23
  import com.facebook.react.module.annotations.ReactModule
22
24
  import com.facebook.react.modules.core.DeviceEventManagerModule
23
25
  import com.facebook.react.turbomodule.core.interfaces.TurboModule
@@ -29,26 +31,57 @@ import java.util.concurrent.ConcurrentLinkedQueue
29
31
 
30
32
  @ReactModule(name = ComTappSoSdkModule.NAME)
31
33
  class ComTappSoSdkModule(reactContext: ReactApplicationContext) :
32
- ReactContextBaseJavaModule(reactContext), TurboModule{
34
+ ReactContextBaseJavaModule(reactContext), TurboModule, LifecycleEventListener {
33
35
 
34
36
  companion object {
35
37
  const val NAME = "ComTappSoSdk"
36
38
  private const val FLUSH_RETRY_INTERVAL_MS = 100L
37
- private const val FLUSH_RETRY_MAX_DURATION_MS = 2000L
38
39
  }
39
40
 
40
41
  private lateinit var tapp: Tapp
41
42
  private var listenerCount = 0
42
43
  private val eventQueue = ConcurrentLinkedQueue<Pair<String, WritableMap?>>()
43
44
  private val mainHandler = Handler(Looper.getMainLooper())
44
- private var flushRetryStartTime: Long = 0
45
45
  private var isFlushRetryScheduled = false
46
+ private var isHostResumed = false
46
47
 
47
48
  init {
48
49
  Logger.logInfo("[$NAME] IS_NEW_ARCHITECTURE_ENABLED: ${BuildConfig.IS_NEW_ARCHITECTURE_ENABLED}")
49
50
  }
50
51
  override fun getName(): String = NAME
51
52
 
53
+ override fun initialize() {
54
+ super.initialize()
55
+ reactApplicationContext.addLifecycleEventListener(this)
56
+ isHostResumed = reactApplicationContext.lifecycleState == LifecycleState.RESUMED
57
+ }
58
+
59
+ override fun invalidate() {
60
+ reactApplicationContext.removeLifecycleEventListener(this)
61
+ mainHandler.removeCallbacksAndMessages(null)
62
+ eventQueue.clear()
63
+ listenerCount = 0
64
+ isFlushRetryScheduled = false
65
+ isHostResumed = false
66
+ super.invalidate()
67
+ }
68
+
69
+ override fun onHostResume() {
70
+ isHostResumed = true
71
+ if (listenerCount > 0) {
72
+ flushEvents()
73
+ scheduleFlushRetry()
74
+ }
75
+ }
76
+
77
+ override fun onHostPause() {
78
+ isHostResumed = false
79
+ }
80
+
81
+ override fun onHostDestroy() {
82
+ isHostResumed = false
83
+ }
84
+
52
85
  // Required by NativeEventEmitter
53
86
  @ReactMethod
54
87
  fun addListener(eventName: String) {
@@ -60,8 +93,9 @@ class ComTappSoSdkModule(reactContext: ReactApplicationContext) :
60
93
 
61
94
  // Required by NativeEventEmitter
62
95
  @ReactMethod
63
- fun removeListeners(count: Int) {
64
- listenerCount -= count
96
+ fun removeListeners(count: Double) {
97
+ // RN passes JS numbers as Double in Turbo host functions.
98
+ listenerCount -= count.toInt()
65
99
  if (listenerCount < 0) {
66
100
  listenerCount = 0
67
101
  }
@@ -86,26 +120,23 @@ class ComTappSoSdkModule(reactContext: ReactApplicationContext) :
86
120
  }
87
121
 
88
122
  /**
89
- * Schedule flush retries every 100ms for up to 2 seconds.
90
- * This ensures buffered events are flushed even if React wasn't active initially.
123
+ * Schedule flush retries every 100ms while host is resumed and listeners exist.
124
+ * This keeps buffered events reliable across cold starts and React activation delays.
91
125
  */
92
126
  private fun scheduleFlushRetry() {
93
127
  if (isFlushRetryScheduled) return
94
128
  if (eventQueue.isEmpty()) return
95
129
 
96
130
  isFlushRetryScheduled = true
97
- flushRetryStartTime = System.currentTimeMillis()
98
131
 
99
132
  mainHandler.postDelayed(object : Runnable {
100
133
  override fun run() {
101
- val elapsed = System.currentTimeMillis() - flushRetryStartTime
102
-
103
134
  if (eventQueue.isEmpty() || listenerCount == 0) {
104
135
  isFlushRetryScheduled = false
105
136
  return
106
137
  }
107
138
 
108
- if (elapsed > FLUSH_RETRY_MAX_DURATION_MS) {
139
+ if (!isHostResumed) {
109
140
  isFlushRetryScheduled = false
110
141
  return
111
142
  }
@@ -126,6 +157,13 @@ class ComTappSoSdkModule(reactContext: ReactApplicationContext) :
126
157
  // If we have listeners and the React context is active, emit immediately
127
158
  if (listenerCount > 0 && isReactActive()) {
128
159
  mainHandler.post {
160
+ // Drain older queued events first to preserve order and avoid stuck buffered state.
161
+ while (listenerCount > 0 && isReactActive() && !eventQueue.isEmpty()) {
162
+ val event = eventQueue.poll()
163
+ if (event != null) {
164
+ emitNow(event.first, event.second)
165
+ }
166
+ }
129
167
  emitNow(eventName, params)
130
168
  }
131
169
  } else {
@@ -376,12 +414,22 @@ class ComTappSoSdkModule(reactContext: ReactApplicationContext) :
376
414
  }
377
415
  } else {
378
416
  withContext(Dispatchers.Main) {
379
- promise?.reject("NO_RESPONSE", "No link data response")
417
+ promise?.resolve(
418
+ createLinkDataErrorMap(
419
+ message = "No link data response",
420
+ deepLink = deepLink
421
+ )
422
+ )
380
423
  }
381
424
  }
382
425
  } catch (e: Exception) {
383
426
  withContext(Dispatchers.Main) {
384
- promise?.reject("FETCH_LINK_DATA_ERROR", e.message ?: "An unexpected error occurred")
427
+ promise?.resolve(
428
+ createLinkDataErrorMap(
429
+ message = e.message ?: "An unexpected error occurred",
430
+ deepLink = deepLink
431
+ )
432
+ )
385
433
  }
386
434
  }
387
435
  }
@@ -417,12 +465,14 @@ class ComTappSoSdkModule(reactContext: ReactApplicationContext) :
417
465
  }
418
466
  } else {
419
467
  withContext(Dispatchers.Main) {
420
- promise?.reject("NO_DATA", "No link data returned")
468
+ promise?.resolve(createLinkDataErrorMap(message = "No link data returned"))
421
469
  }
422
470
  }
423
471
  } catch (e: Exception) {
424
472
  withContext(Dispatchers.Main) {
425
- promise?.reject("FETCH_ORIGINAL_LINK_DATA_ERROR", e.message ?: "An unexpected error occurred", e)
473
+ promise?.resolve(
474
+ createLinkDataErrorMap(message = e.message ?: "An unexpected error occurred")
475
+ )
426
476
  }
427
477
  }
428
478
  }
@@ -433,6 +483,74 @@ class ComTappSoSdkModule(reactContext: ReactApplicationContext) :
433
483
  tapp.simulateTestEvent()
434
484
  }
435
485
 
486
+ // DEBUG-only: Simulate a deferred link event for listener verification
487
+ @ReactMethod
488
+ fun simulateDeferredLink(payload: ReadableMap?) {
489
+ if (!BuildConfig.DEBUG) {
490
+ Log.w(NAME, "simulateDeferredLink is only available in DEBUG builds")
491
+ return
492
+ }
493
+
494
+ val safePayload = payload
495
+ val tappUrl = safePayload?.getString("tappUrl") ?: "tapp://simulated"
496
+ val attrTappUrl = safePayload?.getString("attrTappUrl") ?: "tapp://simulated/attributed"
497
+ val influencer = safePayload?.getString("influencer") ?: "test_influencer"
498
+ val isFirstSession = if (
499
+ safePayload?.hasKey("isFirstSession") == true && !safePayload.isNull("isFirstSession")
500
+ ) {
501
+ safePayload.getBoolean("isFirstSession")
502
+ } else {
503
+ true
504
+ }
505
+
506
+ val dataMap = Arguments.createMap()
507
+ if (safePayload?.hasKey("data") == true && !safePayload.isNull("data")) {
508
+ val rawData = safePayload.getMap("data")
509
+ if (rawData != null) {
510
+ val iterator = rawData.keySetIterator()
511
+ while (iterator.hasNextKey()) {
512
+ val key = iterator.nextKey()
513
+ when (rawData.getType(key)) {
514
+ ReadableType.String -> dataMap.putString(key, rawData.getString(key))
515
+ ReadableType.Number -> dataMap.putString(key, rawData.getDouble(key).toString())
516
+ ReadableType.Boolean -> dataMap.putString(key, rawData.getBoolean(key).toString())
517
+ ReadableType.Null -> dataMap.putString(key, null)
518
+ ReadableType.Map, ReadableType.Array -> {
519
+ Log.w(NAME, "simulateDeferredLink dropped nested data key: $key")
520
+ }
521
+ }
522
+ }
523
+ }
524
+ }
525
+
526
+ val result: WritableMap = Arguments.createMap().apply {
527
+ putBoolean("error", false)
528
+ putString("message", null)
529
+ putString("tappUrl", tappUrl)
530
+ putString("attrTappUrl", attrTappUrl)
531
+ putString("influencer", influencer)
532
+ putBoolean("isFirstSession", isFirstSession)
533
+ putString("deepLink", tappUrl)
534
+ putMap("data", dataMap)
535
+ }
536
+ emitOrBuffer("onDeferredLinkReceived", result)
537
+ }
538
+
539
+ // DEBUG-only: Simulate a fail resolving URL event for listener verification
540
+ @ReactMethod
541
+ fun simulateFailResolving(url: String?, errorMessage: String?) {
542
+ if (!BuildConfig.DEBUG) {
543
+ Log.w(NAME, "simulateFailResolving is only available in DEBUG builds")
544
+ return
545
+ }
546
+
547
+ val result: WritableMap = Arguments.createMap().apply {
548
+ putString("url", url ?: "tapp://unknown")
549
+ putString("error", errorMessage ?: "Simulated error for testing")
550
+ }
551
+ emitOrBuffer("onDidFailResolvingURL", result)
552
+ }
553
+
436
554
  private fun didFailResolvingURL(response: RequestModels.FailResolvingUrlResponse) {
437
555
  val map: WritableMap = Arguments.createMap().apply {
438
556
  putString("url", response.url)
@@ -444,7 +562,6 @@ class ComTappSoSdkModule(reactContext: ReactApplicationContext) :
444
562
 
445
563
 
446
564
  // --- helper methods for emitting deferred link events ---
447
- //TODO::ADD LINK DATA ON RETURN
448
565
  private fun sendDeferredLinkEvent(response: RequestModels.TappLinkDataResponse) {
449
566
  val map: WritableMap = Arguments.createMap().apply {
450
567
  putBoolean("error", response.error)
@@ -485,4 +602,19 @@ class ComTappSoSdkModule(reactContext: ReactApplicationContext) :
485
602
  map.putMap("data", dataMap)
486
603
  return map
487
604
  }
605
+
606
+ private fun createLinkDataErrorMap(message: String, deepLink: String? = null): WritableMap {
607
+ val map = Arguments.createMap()
608
+ map.putBoolean("error", true)
609
+ map.putString("message", message)
610
+ map.putString("tappUrl", null)
611
+ map.putString("attrTappUrl", null)
612
+ map.putString("influencer", null)
613
+ map.putBoolean("isFirstSession", false)
614
+ if (deepLink != null) {
615
+ map.putString("deepLink", deepLink)
616
+ }
617
+ map.putMap("data", Arguments.createMap())
618
+ return map
619
+ }
488
620
  }
@@ -1 +1 @@
1
- {"version":3,"names":["EventAction"],"sourceRoot":"../../src","sources":["Types.ts"],"mappings":";;AAWA,WAAYA,WAAW,0BAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW,4BAyCT;EAAA,OAzCFA,WAAW;AAAA","ignoreList":[]}
1
+ {"version":3,"names":["EventAction"],"sourceRoot":"../../src","sources":["Types.ts"],"mappings":";;AAUA,WAAYA,WAAW,0BAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW,4BAyCT;EAAA,OAzCFA,WAAW;AAAA","ignoreList":[]}
@@ -8,6 +8,27 @@ import { EventAction } from './Types';
8
8
  const unsupportedPlatformMessage = methodName => {
9
9
  console.log(`[${Platform.OS}] Method "${methodName}" is not supported.`);
10
10
  };
11
+ const getErrorCode = error => {
12
+ if (error && typeof error === 'object' && 'code' in error) {
13
+ const code = error.code;
14
+ if (typeof code === 'string') {
15
+ return code;
16
+ }
17
+ }
18
+ return undefined;
19
+ };
20
+ const getErrorMessage = (error, fallback = 'An unexpected error occurred') => {
21
+ if (error instanceof Error && error.message) {
22
+ return error.message;
23
+ }
24
+ if (error && typeof error === 'object' && 'message' in error) {
25
+ const message = error.message;
26
+ if (typeof message === 'string' && message.length > 0) {
27
+ return message;
28
+ }
29
+ }
30
+ return fallback;
31
+ };
11
32
  export function start(config) {
12
33
  if (Platform.OS === 'web') {
13
34
  unsupportedPlatformMessage('start');
@@ -42,7 +63,22 @@ export function fetchLinkData(deepLink) {
42
63
  if (Platform.OS === 'web') {
43
64
  unsupportedPlatformMessage('fetchLinkData');
44
65
  }
45
- return ComTappSoSdk.fetchLinkData(deepLink);
66
+ return ComTappSoSdk.fetchLinkData(deepLink).catch(error => {
67
+ // Keep programmer-input errors explicit while normalizing runtime/sdk failures.
68
+ if (getErrorCode(error) === 'INVALID_URL') {
69
+ return Promise.reject(error);
70
+ }
71
+ return {
72
+ error: true,
73
+ message: getErrorMessage(error),
74
+ tappUrl: undefined,
75
+ attrTappUrl: undefined,
76
+ influencer: undefined,
77
+ data: {},
78
+ isFirstSession: false,
79
+ deepLink
80
+ };
81
+ });
46
82
  }
47
83
  export function shouldProcess(deepLink) {
48
84
  if (Platform.OS === 'web') {
@@ -54,30 +90,38 @@ export function fetchOriginLinkData() {
54
90
  if (Platform.OS === 'web') {
55
91
  unsupportedPlatformMessage('fetchOriginLinkData');
56
92
  }
57
- return ComTappSoSdk.fetchOriginLinkData();
93
+ return ComTappSoSdk.fetchOriginLinkData().catch(error => {
94
+ return {
95
+ error: true,
96
+ message: getErrorMessage(error),
97
+ tappUrl: undefined,
98
+ attrTappUrl: undefined,
99
+ influencer: undefined,
100
+ data: {},
101
+ isFirstSession: false
102
+ };
103
+ });
58
104
  }
59
105
  export function simulateTestEvent() {
60
- if (Platform.OS === 'web' || Platform.OS === 'ios') {
61
- unsupportedPlatformMessage('simulateTestEvent');
62
- }
63
- return ComTappSoSdk.simulateTestEvent();
106
+ // Kept for backward compatibility, but intentionally disabled.
107
+ unsupportedPlatformMessage('simulateTestEvent');
64
108
  }
65
109
 
66
- // DEBUG-only: Simulate a deferred link event for iOS testing
67
- // Only works in DEBUG builds on iOS
110
+ // DEBUG-only: Simulate a deferred link event for iOS/Android testing
111
+ // Only works in DEBUG builds on native platforms
68
112
  export function simulateDeferredLink(payload) {
69
- if (Platform.OS !== 'ios') {
70
- console.log('[simulateDeferredLink] Only supported on iOS');
113
+ if (Platform.OS !== 'ios' && Platform.OS !== 'android') {
114
+ console.log('[simulateDeferredLink] Only supported on iOS/Android');
71
115
  return;
72
116
  }
73
117
  ComTappSoSdk.simulateDeferredLink(payload || {});
74
118
  }
75
119
 
76
- // DEBUG-only: Simulate a fail resolving URL event for iOS testing
77
- // Only works in DEBUG builds on iOS
120
+ // DEBUG-only: Simulate a fail resolving URL event for iOS/Android testing
121
+ // Only works in DEBUG builds on native platforms
78
122
  export function simulateFailResolving(url, error) {
79
- if (Platform.OS !== 'ios') {
80
- console.log('[simulateFailResolving] Only supported on iOS');
123
+ if (Platform.OS !== 'ios' && Platform.OS !== 'android') {
124
+ console.log('[simulateFailResolving] Only supported on iOS/Android');
81
125
  return;
82
126
  }
83
127
  ComTappSoSdk.simulateFailResolving(url, error);
@@ -1 +1 @@
1
- {"version":3,"names":["ComTappSoSdk","Platform","NativeModules","EventAction","unsupportedPlatformMessage","methodName","console","log","OS","start","config","TappEventEmitter","authToken","env","tappToken","url","influencer","adGroup","creative","data","handleTappEvent","event","value","customValue","eventAction","CUSTOM","undefined","metadata","fetchLinkData","deepLink","shouldProcess","fetchOriginLinkData","simulateTestEvent","simulateDeferredLink","payload","simulateFailResolving","error"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,YAAY,MAAM,sBAAsB;AAC/C,SAASC,QAAQ,EAAEC,aAAa,QAAQ,cAAc;AACtD,SACEC,WAAW,QAIN,SAAS;;AAEhB;AACA,MAAMC,0BAA0B,GAAIC,UAAkB,IAAK;EACzDC,OAAO,CAACC,GAAG,CAAC,IAAIN,QAAQ,CAACO,EAAE,aAAaH,UAAU,qBAAqB,CAAC;AAC1E,CAAC;AAED,OAAO,SAASI,KAAKA,CAACC,MAAkB,EAAQ;EAC9C,IAAIT,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBJ,0BAA0B,CAAC,OAAO,CAAC;EACrC;EACA;EACA,IAAIH,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzB,MAAM;MAAEG;IAAiB,CAAC,GAAGT,aAAa;IAC1C,IAAIS,gBAAgB,EAAE;MACpB;IAAA;EAEJ;EACAX,YAAY,CAACS,KAAK,CAACC,MAAM,CAACE,SAAS,EAAEF,MAAM,CAACG,GAAG,EAAEH,MAAM,CAACI,SAAS,CAAC;AACpE;AAEA,OAAO,SAASC,GAAGA,CACjBC,UAAkB,EAClBC,OAAgB,EAChBC,QAAiB,EACjBC,IAAgC,EACf;EACjB,IAAIlB,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBJ,0BAA0B,CAAC,KAAK,CAAC;EACnC;EACA,OAAOJ,YAAY,CAACe,GAAG,CAACC,UAAU,EAAEC,OAAO,EAAEC,QAAQ,EAAEC,IAAI,CAAC;AAC9D;AAEA,OAAO,SAASC,eAAeA,CAACC,KAAoB,EAAmB;EACrE,IAAIpB,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBJ,0BAA0B,CAAC,iBAAiB,CAAC;EAC/C;EAEA,MAAMkB,KAAK,GAAGD,KAAK,CAACE,WAAW,IAAI,4BAA4B;EAC/D,MAAMA,WAAW,GACfF,KAAK,CAACG,WAAW,KAAKrB,WAAW,CAACsB,MAAM,GAAGH,KAAK,GAAGI,SAAS;EAE9D,MAAMC,QAAQ,GAAGN,KAAK,CAACM,QAAQ;EAE/B,OAAO3B,YAAY,CAACoB,eAAe,CACjCC,KAAK,CAACG,WAAW,EACjBD,WAAW,EACXI,QACF,CAAC;AACH;AAEA,OAAO,SAASC,aAAaA,CAACC,QAAgB,EAAiC;EAC7E,IAAI5B,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBJ,0BAA0B,CAAC,eAAe,CAAC;EAC7C;EACA,OAAOJ,YAAY,CAAC4B,aAAa,CAACC,QAAQ,CAAC;AAC7C;AAEA,OAAO,SAASC,aAAaA,CAACD,QAAgB,EAAoB;EAChE,IAAI5B,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBJ,0BAA0B,CAAC,eAAe,CAAC;EAC7C;EACA,OAAOJ,YAAY,CAAC8B,aAAa,CAACD,QAAQ,CAAC;AAC7C;AAEA,OAAO,SAASE,mBAAmBA,CAAA,EAAkC;EACnE,IAAI9B,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBJ,0BAA0B,CAAC,qBAAqB,CAAC;EACnD;EACA,OAAOJ,YAAY,CAAC+B,mBAAmB,CAAC,CAAC;AAC3C;AAEA,OAAO,SAASC,iBAAiBA,CAAA,EAAS;EACxC,IAAI/B,QAAQ,CAACO,EAAE,KAAK,KAAK,IAAIP,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IAClDJ,0BAA0B,CAAC,mBAAmB,CAAC;EACjD;EACA,OAAOJ,YAAY,CAACgC,iBAAiB,CAAC,CAAC;AACzC;;AAEA;AACA;AACA,OAAO,SAASC,oBAAoBA,CAACC,OAMpC,EAAQ;EACP,IAAIjC,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBF,OAAO,CAACC,GAAG,CAAC,8CAA8C,CAAC;IAC3D;EACF;EACAP,YAAY,CAACiC,oBAAoB,CAACC,OAAO,IAAI,CAAC,CAAC,CAAC;AAClD;;AAEA;AACA;AACA,OAAO,SAASC,qBAAqBA,CAACpB,GAAW,EAAEqB,KAAa,EAAQ;EACtE,IAAInC,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBF,OAAO,CAACC,GAAG,CAAC,+CAA+C,CAAC;IAC5D;EACF;EACAP,YAAY,CAACmC,qBAAqB,CAACpB,GAAG,EAAEqB,KAAK,CAAC;AAChD;AAEA,cAAc,SAAS;AACvB,cAAc,UAAU","ignoreList":[]}
1
+ {"version":3,"names":["ComTappSoSdk","Platform","NativeModules","EventAction","unsupportedPlatformMessage","methodName","console","log","OS","getErrorCode","error","code","undefined","getErrorMessage","fallback","Error","message","length","start","config","TappEventEmitter","authToken","env","tappToken","url","influencer","adGroup","creative","data","handleTappEvent","event","value","customValue","eventAction","CUSTOM","metadata","fetchLinkData","deepLink","catch","Promise","reject","tappUrl","attrTappUrl","isFirstSession","shouldProcess","fetchOriginLinkData","simulateTestEvent","simulateDeferredLink","payload","simulateFailResolving"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,YAAY,MAAM,sBAAsB;AAC/C,SAASC,QAAQ,EAAEC,aAAa,QAAQ,cAAc;AACtD,SACEC,WAAW,QAIN,SAAS;;AAEhB;AACA,MAAMC,0BAA0B,GAAIC,UAAkB,IAAK;EACzDC,OAAO,CAACC,GAAG,CAAC,IAAIN,QAAQ,CAACO,EAAE,aAAaH,UAAU,qBAAqB,CAAC;AAC1E,CAAC;AAED,MAAMI,YAAY,GAAIC,KAAc,IAAyB;EAC3D,IAAIA,KAAK,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAIA,KAAK,EAAE;IACzD,MAAMC,IAAI,GAAID,KAAK,CAAwBC,IAAI;IAC/C,IAAI,OAAOA,IAAI,KAAK,QAAQ,EAAE;MAC5B,OAAOA,IAAI;IACb;EACF;EACA,OAAOC,SAAS;AAClB,CAAC;AAED,MAAMC,eAAe,GAAGA,CACtBH,KAAc,EACdI,QAAgB,GAAG,8BAA8B,KACtC;EACX,IAAIJ,KAAK,YAAYK,KAAK,IAAIL,KAAK,CAACM,OAAO,EAAE;IAC3C,OAAON,KAAK,CAACM,OAAO;EACtB;EACA,IAAIN,KAAK,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI,SAAS,IAAIA,KAAK,EAAE;IAC5D,MAAMM,OAAO,GAAIN,KAAK,CAA2BM,OAAO;IACxD,IAAI,OAAOA,OAAO,KAAK,QAAQ,IAAIA,OAAO,CAACC,MAAM,GAAG,CAAC,EAAE;MACrD,OAAOD,OAAO;IAChB;EACF;EACA,OAAOF,QAAQ;AACjB,CAAC;AAED,OAAO,SAASI,KAAKA,CAACC,MAAkB,EAAQ;EAC9C,IAAIlB,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBJ,0BAA0B,CAAC,OAAO,CAAC;EACrC;EACA;EACA,IAAIH,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzB,MAAM;MAAEY;IAAiB,CAAC,GAAGlB,aAAa;IAC1C,IAAIkB,gBAAgB,EAAE;MACpB;IAAA;EAEJ;EACApB,YAAY,CAACkB,KAAK,CAACC,MAAM,CAACE,SAAS,EAAEF,MAAM,CAACG,GAAG,EAAEH,MAAM,CAACI,SAAS,CAAC;AACpE;AAEA,OAAO,SAASC,GAAGA,CACjBC,UAAkB,EAClBC,OAAgB,EAChBC,QAAiB,EACjBC,IAAgC,EACf;EACjB,IAAI3B,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBJ,0BAA0B,CAAC,KAAK,CAAC;EACnC;EACA,OAAOJ,YAAY,CAACwB,GAAG,CAACC,UAAU,EAAEC,OAAO,EAAEC,QAAQ,EAAEC,IAAI,CAAC;AAC9D;AAEA,OAAO,SAASC,eAAeA,CAACC,KAAoB,EAAmB;EACrE,IAAI7B,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBJ,0BAA0B,CAAC,iBAAiB,CAAC;EAC/C;EAEA,MAAM2B,KAAK,GAAGD,KAAK,CAACE,WAAW,IAAI,4BAA4B;EAC/D,MAAMA,WAAW,GACfF,KAAK,CAACG,WAAW,KAAK9B,WAAW,CAAC+B,MAAM,GAAGH,KAAK,GAAGnB,SAAS;EAE9D,MAAMuB,QAAQ,GAAGL,KAAK,CAACK,QAAQ;EAE/B,OAAOnC,YAAY,CAAC6B,eAAe,CACjCC,KAAK,CAACG,WAAW,EACjBD,WAAW,EACXG,QACF,CAAC;AACH;AAEA,OAAO,SAASC,aAAaA,CAACC,QAAgB,EAAiC;EAC7E,IAAIpC,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBJ,0BAA0B,CAAC,eAAe,CAAC;EAC7C;EACA,OAAOJ,YAAY,CAACoC,aAAa,CAACC,QAAQ,CAAC,CAACC,KAAK,CAAE5B,KAAc,IAAK;IACpE;IACA,IAAID,YAAY,CAACC,KAAK,CAAC,KAAK,aAAa,EAAE;MACzC,OAAO6B,OAAO,CAACC,MAAM,CAAC9B,KAAK,CAAC;IAC9B;IAEA,OAAO;MACLA,KAAK,EAAE,IAAI;MACXM,OAAO,EAAEH,eAAe,CAACH,KAAK,CAAC;MAC/B+B,OAAO,EAAE7B,SAAS;MAClB8B,WAAW,EAAE9B,SAAS;MACtBa,UAAU,EAAEb,SAAS;MACrBgB,IAAI,EAAE,CAAC,CAAC;MACRe,cAAc,EAAE,KAAK;MACrBN;IACF,CAAC;EACH,CAAC,CAAC;AACJ;AAEA,OAAO,SAASO,aAAaA,CAACP,QAAgB,EAAoB;EAChE,IAAIpC,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBJ,0BAA0B,CAAC,eAAe,CAAC;EAC7C;EACA,OAAOJ,YAAY,CAAC4C,aAAa,CAACP,QAAQ,CAAC;AAC7C;AAEA,OAAO,SAASQ,mBAAmBA,CAAA,EAAkC;EACnE,IAAI5C,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzBJ,0BAA0B,CAAC,qBAAqB,CAAC;EACnD;EACA,OAAOJ,YAAY,CAAC6C,mBAAmB,CAAC,CAAC,CAACP,KAAK,CAAE5B,KAAc,IAAK;IAClE,OAAO;MACLA,KAAK,EAAE,IAAI;MACXM,OAAO,EAAEH,eAAe,CAACH,KAAK,CAAC;MAC/B+B,OAAO,EAAE7B,SAAS;MAClB8B,WAAW,EAAE9B,SAAS;MACtBa,UAAU,EAAEb,SAAS;MACrBgB,IAAI,EAAE,CAAC,CAAC;MACRe,cAAc,EAAE;IAClB,CAAC;EACH,CAAC,CAAC;AACJ;AAEA,OAAO,SAASG,iBAAiBA,CAAA,EAAS;EACxC;EACA1C,0BAA0B,CAAC,mBAAmB,CAAC;AACjD;;AAEA;AACA;AACA,OAAO,SAAS2C,oBAAoBA,CAACC,OAMpC,EAAQ;EACP,IAAI/C,QAAQ,CAACO,EAAE,KAAK,KAAK,IAAIP,QAAQ,CAACO,EAAE,KAAK,SAAS,EAAE;IACtDF,OAAO,CAACC,GAAG,CAAC,sDAAsD,CAAC;IACnE;EACF;EACAP,YAAY,CAAC+C,oBAAoB,CAACC,OAAO,IAAI,CAAC,CAAC,CAAC;AAClD;;AAEA;AACA;AACA,OAAO,SAASC,qBAAqBA,CAACzB,GAAW,EAAEd,KAAa,EAAQ;EACtE,IAAIT,QAAQ,CAACO,EAAE,KAAK,KAAK,IAAIP,QAAQ,CAACO,EAAE,KAAK,SAAS,EAAE;IACtDF,OAAO,CAACC,GAAG,CAAC,uDAAuD,CAAC;IACpE;EACF;EACAP,YAAY,CAACiD,qBAAqB,CAACzB,GAAG,EAAEd,KAAK,CAAC;AAChD;AAEA,cAAc,SAAS;AACvB,cAAc,UAAU","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"Types.d.ts","sourceRoot":"","sources":["../../../src/Types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Types.d.ts","sourceRoot":"","sources":["../../../src/Types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,eAAe,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,SAAS,CAAC;AAEvD,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,aAAa,CAAC;AAE3E,oBAAY,WAAW;IACrB,qBAAqB,IAAI;IACzB,gBAAgB,IAAI;IACpB,oBAAoB,IAAI;IACxB,0BAA0B,IAAI;IAC9B,YAAY,IAAI;IAChB,sBAAsB,IAAI;IAC1B,WAAW,IAAI;IACf,kBAAkB,IAAI;IACtB,sBAAsB,IAAI;IAC1B,kBAAkB,KAAK;IACvB,aAAa,KAAK;IAClB,aAAa,KAAK;IAClB,WAAW,KAAK;IAChB,gBAAgB,KAAK;IACrB,uBAAuB,KAAK;IAC5B,cAAc,KAAK;IACnB,iBAAiB,KAAK;IACtB,iBAAiB,KAAK;IACtB,kBAAkB,KAAK;IACvB,eAAe,KAAK;IACpB,kBAAkB,KAAK;IACvB,iBAAiB,KAAK;IACtB,gBAAgB,KAAK;IACrB,eAAe,KAAK;IACpB,oBAAoB,KAAK;IACzB,mBAAmB,KAAK;IACxB,kBAAkB,KAAK;IACvB,mBAAmB,KAAK;IACxB,UAAU,KAAK;IACf,SAAS,KAAK;IACd,kBAAkB,KAAK;IACvB,uBAAuB,KAAK;IAC5B,sBAAsB,KAAK;IAC3B,0BAA0B,KAAK;IAC/B,gBAAgB,KAAK;IACrB,mBAAmB,KAAK;IACxB,eAAe,KAAK;IACpB,mBAAmB,KAAK;IACxB,mBAAmB,KAAK;IACxB,sBAAsB,KAAK;IAC3B,MAAM,IAAI;CACX;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAC1D,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAE7D,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AACF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC1C,aAAa,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC1C,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC/C,iBAAiB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,6BAA6B,GAAG;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAAG,CAAC,MAAM,EAAE;IAC3D,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,KAAK,IAAI,CAAC;AACX,MAAM,WAAW,oBAAoB;IACnC,sBAAsB,CAAC,gBAAgB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrE,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAC1B,MAAM,SAAS,CAAC;AAOjB,wBAAgB,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAY9C;AAED,wBAAgB,GAAG,CACjB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAC/B,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBrE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAK7E;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAKhE;AAED,wBAAgB,mBAAmB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAKnE;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC;AAID,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,IAAI,CAMP;AAID,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAMtE;AAED,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAC1B,MAAM,SAAS,CAAC;AAiCjB,wBAAgB,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAY9C;AAED,wBAAgB,GAAG,CACjB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAC/B,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBrE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAqB7E;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAKhE;AAED,wBAAgB,mBAAmB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAenE;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAID,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,IAAI,CAMP;AAID,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAMtE;AAED,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com-tapp-so-sdk",
3
- "version": "0.1.6",
3
+ "version": "1.1.0",
4
4
  "description": "react native tapp sdk",
5
5
  "sideEffects": false,
6
6
  "engines": {
@@ -55,7 +55,7 @@
55
55
  "url": "git+https://github.com/tapp-so/Tapp-RN"
56
56
  },
57
57
  "author": "nick@tapp.so <nick@tapp.so> (https://www.tapp.so/)",
58
- "license": "MIT",
58
+ "license": "SEE LICENSE IN LICENSE",
59
59
  "bugs": {
60
60
  "url": "https://github.com/tapp-so/Tapp-RN/issues"
61
61
  },
package/src/Types.ts CHANGED
@@ -2,7 +2,6 @@ export type InitConfig = {
2
2
  authToken: string;
3
3
  env: EnvironmentType;
4
4
  tappToken: string;
5
- //affiliate: AffiliateType;
6
5
  };
7
6
 
8
7
  export type EnvironmentType = 'PRODUCTION' | 'SANDBOX';
package/src/index.tsx CHANGED
@@ -12,6 +12,32 @@ const unsupportedPlatformMessage = (methodName: string) => {
12
12
  console.log(`[${Platform.OS}] Method "${methodName}" is not supported.`);
13
13
  };
14
14
 
15
+ const getErrorCode = (error: unknown): string | undefined => {
16
+ if (error && typeof error === 'object' && 'code' in error) {
17
+ const code = (error as { code?: unknown }).code;
18
+ if (typeof code === 'string') {
19
+ return code;
20
+ }
21
+ }
22
+ return undefined;
23
+ };
24
+
25
+ const getErrorMessage = (
26
+ error: unknown,
27
+ fallback: string = 'An unexpected error occurred'
28
+ ): string => {
29
+ if (error instanceof Error && error.message) {
30
+ return error.message;
31
+ }
32
+ if (error && typeof error === 'object' && 'message' in error) {
33
+ const message = (error as { message?: unknown }).message;
34
+ if (typeof message === 'string' && message.length > 0) {
35
+ return message;
36
+ }
37
+ }
38
+ return fallback;
39
+ };
40
+
15
41
  export function start(config: InitConfig): void {
16
42
  if (Platform.OS === 'web') {
17
43
  unsupportedPlatformMessage('start');
@@ -60,7 +86,23 @@ export function fetchLinkData(deepLink: string): Promise<TappLinkDataResponse> {
60
86
  if (Platform.OS === 'web') {
61
87
  unsupportedPlatformMessage('fetchLinkData');
62
88
  }
63
- return ComTappSoSdk.fetchLinkData(deepLink);
89
+ return ComTappSoSdk.fetchLinkData(deepLink).catch((error: unknown) => {
90
+ // Keep programmer-input errors explicit while normalizing runtime/sdk failures.
91
+ if (getErrorCode(error) === 'INVALID_URL') {
92
+ return Promise.reject(error);
93
+ }
94
+
95
+ return {
96
+ error: true,
97
+ message: getErrorMessage(error),
98
+ tappUrl: undefined,
99
+ attrTappUrl: undefined,
100
+ influencer: undefined,
101
+ data: {},
102
+ isFirstSession: false,
103
+ deepLink,
104
+ };
105
+ });
64
106
  }
65
107
 
66
108
  export function shouldProcess(deepLink: string): Promise<boolean> {
@@ -74,18 +116,26 @@ export function fetchOriginLinkData(): Promise<TappLinkDataResponse> {
74
116
  if (Platform.OS === 'web') {
75
117
  unsupportedPlatformMessage('fetchOriginLinkData');
76
118
  }
77
- return ComTappSoSdk.fetchOriginLinkData();
119
+ return ComTappSoSdk.fetchOriginLinkData().catch((error: unknown) => {
120
+ return {
121
+ error: true,
122
+ message: getErrorMessage(error),
123
+ tappUrl: undefined,
124
+ attrTappUrl: undefined,
125
+ influencer: undefined,
126
+ data: {},
127
+ isFirstSession: false,
128
+ };
129
+ });
78
130
  }
79
131
 
80
132
  export function simulateTestEvent(): void {
81
- if (Platform.OS === 'web' || Platform.OS === 'ios') {
82
- unsupportedPlatformMessage('simulateTestEvent');
83
- }
84
- return ComTappSoSdk.simulateTestEvent();
133
+ // Kept for backward compatibility, but intentionally disabled.
134
+ unsupportedPlatformMessage('simulateTestEvent');
85
135
  }
86
136
 
87
- // DEBUG-only: Simulate a deferred link event for iOS testing
88
- // Only works in DEBUG builds on iOS
137
+ // DEBUG-only: Simulate a deferred link event for iOS/Android testing
138
+ // Only works in DEBUG builds on native platforms
89
139
  export function simulateDeferredLink(payload?: {
90
140
  tappUrl?: string;
91
141
  attrTappUrl?: string;
@@ -93,18 +143,18 @@ export function simulateDeferredLink(payload?: {
93
143
  data?: { [key: string]: string };
94
144
  isFirstSession?: boolean;
95
145
  }): void {
96
- if (Platform.OS !== 'ios') {
97
- console.log('[simulateDeferredLink] Only supported on iOS');
146
+ if (Platform.OS !== 'ios' && Platform.OS !== 'android') {
147
+ console.log('[simulateDeferredLink] Only supported on iOS/Android');
98
148
  return;
99
149
  }
100
150
  ComTappSoSdk.simulateDeferredLink(payload || {});
101
151
  }
102
152
 
103
- // DEBUG-only: Simulate a fail resolving URL event for iOS testing
104
- // Only works in DEBUG builds on iOS
153
+ // DEBUG-only: Simulate a fail resolving URL event for iOS/Android testing
154
+ // Only works in DEBUG builds on native platforms
105
155
  export function simulateFailResolving(url: string, error: string): void {
106
- if (Platform.OS !== 'ios') {
107
- console.log('[simulateFailResolving] Only supported on iOS');
156
+ if (Platform.OS !== 'ios' && Platform.OS !== 'android') {
157
+ console.log('[simulateFailResolving] Only supported on iOS/Android');
108
158
  return;
109
159
  }
110
160
  ComTappSoSdk.simulateFailResolving(url, error);