@tolinku/react-native-sdk 0.1.0 → 0.2.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.
- package/README.md +45 -0
- package/dist/index.d.mts +112 -2
- package/dist/index.d.ts +112 -2
- package/dist/index.js +227 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +227 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,6 +105,32 @@ await Tolinku.referrals.claimReward(referral_code);
|
|
|
105
105
|
const { leaderboard } = await Tolinku.referrals.leaderboard(10);
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
+
### Ecommerce
|
|
109
|
+
|
|
110
|
+
Track purchases, cart activity, and product events with built-in revenue analytics. Available on paid plans.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
Tolinku.setUserId('user_123');
|
|
114
|
+
|
|
115
|
+
// Track a product view
|
|
116
|
+
await Tolinku.ecommerce.viewItem({
|
|
117
|
+
items: [{ item_id: 'sku_1', item_name: 'T-Shirt', price: 24.99 }]
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Track a purchase
|
|
121
|
+
await Tolinku.ecommerce.purchase({
|
|
122
|
+
transaction_id: 'order_456',
|
|
123
|
+
revenue: 49.99,
|
|
124
|
+
currency: 'USD',
|
|
125
|
+
items: [{ item_id: 'sku_1', item_name: 'T-Shirt', price: 24.99, quantity: 2 }]
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Flush ecommerce events
|
|
129
|
+
await Tolinku.ecommerce.flush();
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The SDK supports 13 event types covering the full shopping journey. Cart IDs are managed automatically via `AsyncStorage` and cleared after purchase. Events auto-flush when the app enters the background.
|
|
133
|
+
|
|
108
134
|
### Deferred Deep Links
|
|
109
135
|
|
|
110
136
|
Recover deep link context for users who installed your app after clicking a link. Deferred deep linking lets you route users to specific content even when the app was not installed at the time of the click.
|
|
@@ -201,6 +227,25 @@ await Tolinku.destroy();
|
|
|
201
227
|
| `claimReward(code)` | Claim a referral reward |
|
|
202
228
|
| `leaderboard(limit?)` | Fetch the referral leaderboard |
|
|
203
229
|
|
|
230
|
+
### `Tolinku.ecommerce`
|
|
231
|
+
|
|
232
|
+
| Method | Description |
|
|
233
|
+
|--------|-------------|
|
|
234
|
+
| `viewItem(params)` | Track a product view |
|
|
235
|
+
| `addToCart(params)` | Track item added to cart |
|
|
236
|
+
| `removeFromCart(params)` | Track item removed from cart |
|
|
237
|
+
| `addToWishlist(params)` | Track item added to wishlist |
|
|
238
|
+
| `viewCart()` | Track cart view |
|
|
239
|
+
| `addPaymentInfo()` | Track payment info entered |
|
|
240
|
+
| `beginCheckout(params?)` | Track checkout started |
|
|
241
|
+
| `purchase(params)` | Track a purchase |
|
|
242
|
+
| `refund(params)` | Track a refund |
|
|
243
|
+
| `search(params)` | Track a product search |
|
|
244
|
+
| `share(params)` | Track a product share |
|
|
245
|
+
| `rate(params)` | Track a product rating |
|
|
246
|
+
| `spendCredits(params)` | Track loyalty credits spent |
|
|
247
|
+
| `flush()` | Send all queued ecommerce events |
|
|
248
|
+
|
|
204
249
|
### `Tolinku.deferred`
|
|
205
250
|
|
|
206
251
|
| Method | Description |
|
package/dist/index.d.mts
CHANGED
|
@@ -146,6 +146,78 @@ interface ShowMessageOptions {
|
|
|
146
146
|
onDismiss?: (messageId: string) => void;
|
|
147
147
|
onButtonPress?: (action: string, messageId: string) => void;
|
|
148
148
|
}
|
|
149
|
+
interface EcommerceItem {
|
|
150
|
+
item_id: string;
|
|
151
|
+
item_name?: string;
|
|
152
|
+
item_category?: string;
|
|
153
|
+
item_brand?: string;
|
|
154
|
+
item_variant?: string;
|
|
155
|
+
item_list_name?: string;
|
|
156
|
+
item_list_id?: string;
|
|
157
|
+
item_image_url?: string;
|
|
158
|
+
price?: number;
|
|
159
|
+
quantity?: number;
|
|
160
|
+
currency?: string;
|
|
161
|
+
coupon_code?: string;
|
|
162
|
+
discount?: number;
|
|
163
|
+
}
|
|
164
|
+
interface PurchaseParams {
|
|
165
|
+
transaction_id: string;
|
|
166
|
+
revenue: number;
|
|
167
|
+
currency: string;
|
|
168
|
+
items?: EcommerceItem[];
|
|
169
|
+
cart_id?: string;
|
|
170
|
+
coupon_code?: string;
|
|
171
|
+
discount?: number;
|
|
172
|
+
shipping?: number;
|
|
173
|
+
tax?: number;
|
|
174
|
+
}
|
|
175
|
+
interface AddToCartParams {
|
|
176
|
+
items: EcommerceItem[];
|
|
177
|
+
cart_id?: string;
|
|
178
|
+
}
|
|
179
|
+
interface RemoveFromCartParams {
|
|
180
|
+
items: EcommerceItem[];
|
|
181
|
+
cart_id?: string;
|
|
182
|
+
}
|
|
183
|
+
interface AddToWishlistParams {
|
|
184
|
+
items: EcommerceItem[];
|
|
185
|
+
}
|
|
186
|
+
interface BeginCheckoutParams {
|
|
187
|
+
revenue?: number;
|
|
188
|
+
currency?: string;
|
|
189
|
+
cart_id?: string;
|
|
190
|
+
items?: EcommerceItem[];
|
|
191
|
+
}
|
|
192
|
+
interface RefundParams {
|
|
193
|
+
transaction_id: string;
|
|
194
|
+
revenue: number;
|
|
195
|
+
currency?: string;
|
|
196
|
+
items?: EcommerceItem[];
|
|
197
|
+
}
|
|
198
|
+
interface ViewItemParams {
|
|
199
|
+
items: EcommerceItem[];
|
|
200
|
+
}
|
|
201
|
+
interface SearchParams {
|
|
202
|
+
search_term: string;
|
|
203
|
+
}
|
|
204
|
+
interface AddPaymentInfoParams {
|
|
205
|
+
cart_id?: string;
|
|
206
|
+
}
|
|
207
|
+
interface ShareParams {
|
|
208
|
+
item_id?: string;
|
|
209
|
+
url?: string;
|
|
210
|
+
method?: string;
|
|
211
|
+
}
|
|
212
|
+
interface RateParams {
|
|
213
|
+
item_id: string;
|
|
214
|
+
rating: number;
|
|
215
|
+
max_rating?: number;
|
|
216
|
+
}
|
|
217
|
+
interface SpendCreditsParams {
|
|
218
|
+
revenue: number;
|
|
219
|
+
currency: string;
|
|
220
|
+
}
|
|
149
221
|
|
|
150
222
|
declare class HttpClient {
|
|
151
223
|
private baseUrl;
|
|
@@ -185,6 +257,41 @@ declare class TolinkuError extends Error {
|
|
|
185
257
|
constructor(message: string, status: number, code?: string);
|
|
186
258
|
}
|
|
187
259
|
|
|
260
|
+
declare class Ecommerce {
|
|
261
|
+
private client;
|
|
262
|
+
private queue;
|
|
263
|
+
private flushTimer;
|
|
264
|
+
private appStateSubscription;
|
|
265
|
+
private isFlushing;
|
|
266
|
+
private getUserId;
|
|
267
|
+
private memoryCartId;
|
|
268
|
+
constructor(client: HttpClient, getUserId: () => string | null);
|
|
269
|
+
viewItem(params: ViewItemParams): Promise<void>;
|
|
270
|
+
addToCart(params: AddToCartParams): Promise<void>;
|
|
271
|
+
removeFromCart(params: RemoveFromCartParams): Promise<void>;
|
|
272
|
+
addToWishlist(params: AddToWishlistParams): Promise<void>;
|
|
273
|
+
viewCart(): Promise<void>;
|
|
274
|
+
addPaymentInfo(params?: AddPaymentInfoParams): Promise<void>;
|
|
275
|
+
beginCheckout(params: BeginCheckoutParams): Promise<void>;
|
|
276
|
+
purchase(params: PurchaseParams): Promise<void>;
|
|
277
|
+
refund(params: RefundParams): Promise<void>;
|
|
278
|
+
search(params: SearchParams): Promise<void>;
|
|
279
|
+
share(params: ShareParams): Promise<void>;
|
|
280
|
+
rate(params: RateParams): Promise<void>;
|
|
281
|
+
spendCredits(params: SpendCreditsParams): Promise<void>;
|
|
282
|
+
flush(): Promise<void>;
|
|
283
|
+
destroy(): Promise<void>;
|
|
284
|
+
private enqueue;
|
|
285
|
+
private handleAppStateChange;
|
|
286
|
+
private startFlushTimer;
|
|
287
|
+
private cancelFlushTimer;
|
|
288
|
+
private getOrCreateCartId;
|
|
289
|
+
private getCartId;
|
|
290
|
+
private setCartId;
|
|
291
|
+
private clearCartId;
|
|
292
|
+
private generateId;
|
|
293
|
+
}
|
|
294
|
+
|
|
188
295
|
declare class Referrals {
|
|
189
296
|
private client;
|
|
190
297
|
constructor(client: HttpClient);
|
|
@@ -230,6 +337,7 @@ declare class Tolinku {
|
|
|
230
337
|
static readonly VERSION = "0.1.0";
|
|
231
338
|
private static client;
|
|
232
339
|
private static analyticsInstance;
|
|
340
|
+
private static ecommerceInstance;
|
|
233
341
|
private static referralsInstance;
|
|
234
342
|
private static deferredInstance;
|
|
235
343
|
private static _initialized;
|
|
@@ -259,9 +367,11 @@ declare class Tolinku {
|
|
|
259
367
|
*/
|
|
260
368
|
static track(eventType: string, properties?: TrackProperties): Promise<void>;
|
|
261
369
|
/**
|
|
262
|
-
* Immediately flush all queued analytics events to the server.
|
|
370
|
+
* Immediately flush all queued analytics and ecommerce events to the server.
|
|
263
371
|
*/
|
|
264
372
|
static flush(): Promise<void>;
|
|
373
|
+
/** Ecommerce: track purchases, carts, products, revenue */
|
|
374
|
+
static get ecommerce(): Ecommerce;
|
|
265
375
|
/** Referrals: create, complete, milestone, leaderboard, claimReward */
|
|
266
376
|
static get referrals(): Referrals;
|
|
267
377
|
/** Deferred deep links: claimByToken, claimBySignals */
|
|
@@ -303,4 +413,4 @@ declare function TolinkuMessages({ trigger, triggerValue, onDismiss, onButtonPre
|
|
|
303
413
|
*/
|
|
304
414
|
declare function isSafeUrl(url: string): boolean;
|
|
305
415
|
|
|
306
|
-
export { type ClaimBySignalsOptions, type CompleteReferralOptions, type CompleteReferralResult, type CreateReferralOptions, type CreateReferralResult, type DeferredLink, type LeaderboardEntry, type Message, type MessageComponent, type MessageContent, type MilestoneOptions, type MilestoneResult, type ReferralInfo, type ResolvedTolinkuConfig, type ShowMessageOptions, Tolinku, type TolinkuConfig, TolinkuError, TolinkuMessages, type TrackProperties, isSafeUrl };
|
|
416
|
+
export { type AddPaymentInfoParams, type AddToCartParams, type AddToWishlistParams, type BeginCheckoutParams, type ClaimBySignalsOptions, type CompleteReferralOptions, type CompleteReferralResult, type CreateReferralOptions, type CreateReferralResult, type DeferredLink, type EcommerceItem, type LeaderboardEntry, type Message, type MessageComponent, type MessageContent, type MilestoneOptions, type MilestoneResult, type PurchaseParams, type RateParams, type ReferralInfo, type RefundParams, type RemoveFromCartParams, type ResolvedTolinkuConfig, type SearchParams, type ShareParams, type ShowMessageOptions, type SpendCreditsParams, Tolinku, type TolinkuConfig, TolinkuError, TolinkuMessages, type TrackProperties, type ViewItemParams, isSafeUrl };
|
package/dist/index.d.ts
CHANGED
|
@@ -146,6 +146,78 @@ interface ShowMessageOptions {
|
|
|
146
146
|
onDismiss?: (messageId: string) => void;
|
|
147
147
|
onButtonPress?: (action: string, messageId: string) => void;
|
|
148
148
|
}
|
|
149
|
+
interface EcommerceItem {
|
|
150
|
+
item_id: string;
|
|
151
|
+
item_name?: string;
|
|
152
|
+
item_category?: string;
|
|
153
|
+
item_brand?: string;
|
|
154
|
+
item_variant?: string;
|
|
155
|
+
item_list_name?: string;
|
|
156
|
+
item_list_id?: string;
|
|
157
|
+
item_image_url?: string;
|
|
158
|
+
price?: number;
|
|
159
|
+
quantity?: number;
|
|
160
|
+
currency?: string;
|
|
161
|
+
coupon_code?: string;
|
|
162
|
+
discount?: number;
|
|
163
|
+
}
|
|
164
|
+
interface PurchaseParams {
|
|
165
|
+
transaction_id: string;
|
|
166
|
+
revenue: number;
|
|
167
|
+
currency: string;
|
|
168
|
+
items?: EcommerceItem[];
|
|
169
|
+
cart_id?: string;
|
|
170
|
+
coupon_code?: string;
|
|
171
|
+
discount?: number;
|
|
172
|
+
shipping?: number;
|
|
173
|
+
tax?: number;
|
|
174
|
+
}
|
|
175
|
+
interface AddToCartParams {
|
|
176
|
+
items: EcommerceItem[];
|
|
177
|
+
cart_id?: string;
|
|
178
|
+
}
|
|
179
|
+
interface RemoveFromCartParams {
|
|
180
|
+
items: EcommerceItem[];
|
|
181
|
+
cart_id?: string;
|
|
182
|
+
}
|
|
183
|
+
interface AddToWishlistParams {
|
|
184
|
+
items: EcommerceItem[];
|
|
185
|
+
}
|
|
186
|
+
interface BeginCheckoutParams {
|
|
187
|
+
revenue?: number;
|
|
188
|
+
currency?: string;
|
|
189
|
+
cart_id?: string;
|
|
190
|
+
items?: EcommerceItem[];
|
|
191
|
+
}
|
|
192
|
+
interface RefundParams {
|
|
193
|
+
transaction_id: string;
|
|
194
|
+
revenue: number;
|
|
195
|
+
currency?: string;
|
|
196
|
+
items?: EcommerceItem[];
|
|
197
|
+
}
|
|
198
|
+
interface ViewItemParams {
|
|
199
|
+
items: EcommerceItem[];
|
|
200
|
+
}
|
|
201
|
+
interface SearchParams {
|
|
202
|
+
search_term: string;
|
|
203
|
+
}
|
|
204
|
+
interface AddPaymentInfoParams {
|
|
205
|
+
cart_id?: string;
|
|
206
|
+
}
|
|
207
|
+
interface ShareParams {
|
|
208
|
+
item_id?: string;
|
|
209
|
+
url?: string;
|
|
210
|
+
method?: string;
|
|
211
|
+
}
|
|
212
|
+
interface RateParams {
|
|
213
|
+
item_id: string;
|
|
214
|
+
rating: number;
|
|
215
|
+
max_rating?: number;
|
|
216
|
+
}
|
|
217
|
+
interface SpendCreditsParams {
|
|
218
|
+
revenue: number;
|
|
219
|
+
currency: string;
|
|
220
|
+
}
|
|
149
221
|
|
|
150
222
|
declare class HttpClient {
|
|
151
223
|
private baseUrl;
|
|
@@ -185,6 +257,41 @@ declare class TolinkuError extends Error {
|
|
|
185
257
|
constructor(message: string, status: number, code?: string);
|
|
186
258
|
}
|
|
187
259
|
|
|
260
|
+
declare class Ecommerce {
|
|
261
|
+
private client;
|
|
262
|
+
private queue;
|
|
263
|
+
private flushTimer;
|
|
264
|
+
private appStateSubscription;
|
|
265
|
+
private isFlushing;
|
|
266
|
+
private getUserId;
|
|
267
|
+
private memoryCartId;
|
|
268
|
+
constructor(client: HttpClient, getUserId: () => string | null);
|
|
269
|
+
viewItem(params: ViewItemParams): Promise<void>;
|
|
270
|
+
addToCart(params: AddToCartParams): Promise<void>;
|
|
271
|
+
removeFromCart(params: RemoveFromCartParams): Promise<void>;
|
|
272
|
+
addToWishlist(params: AddToWishlistParams): Promise<void>;
|
|
273
|
+
viewCart(): Promise<void>;
|
|
274
|
+
addPaymentInfo(params?: AddPaymentInfoParams): Promise<void>;
|
|
275
|
+
beginCheckout(params: BeginCheckoutParams): Promise<void>;
|
|
276
|
+
purchase(params: PurchaseParams): Promise<void>;
|
|
277
|
+
refund(params: RefundParams): Promise<void>;
|
|
278
|
+
search(params: SearchParams): Promise<void>;
|
|
279
|
+
share(params: ShareParams): Promise<void>;
|
|
280
|
+
rate(params: RateParams): Promise<void>;
|
|
281
|
+
spendCredits(params: SpendCreditsParams): Promise<void>;
|
|
282
|
+
flush(): Promise<void>;
|
|
283
|
+
destroy(): Promise<void>;
|
|
284
|
+
private enqueue;
|
|
285
|
+
private handleAppStateChange;
|
|
286
|
+
private startFlushTimer;
|
|
287
|
+
private cancelFlushTimer;
|
|
288
|
+
private getOrCreateCartId;
|
|
289
|
+
private getCartId;
|
|
290
|
+
private setCartId;
|
|
291
|
+
private clearCartId;
|
|
292
|
+
private generateId;
|
|
293
|
+
}
|
|
294
|
+
|
|
188
295
|
declare class Referrals {
|
|
189
296
|
private client;
|
|
190
297
|
constructor(client: HttpClient);
|
|
@@ -230,6 +337,7 @@ declare class Tolinku {
|
|
|
230
337
|
static readonly VERSION = "0.1.0";
|
|
231
338
|
private static client;
|
|
232
339
|
private static analyticsInstance;
|
|
340
|
+
private static ecommerceInstance;
|
|
233
341
|
private static referralsInstance;
|
|
234
342
|
private static deferredInstance;
|
|
235
343
|
private static _initialized;
|
|
@@ -259,9 +367,11 @@ declare class Tolinku {
|
|
|
259
367
|
*/
|
|
260
368
|
static track(eventType: string, properties?: TrackProperties): Promise<void>;
|
|
261
369
|
/**
|
|
262
|
-
* Immediately flush all queued analytics events to the server.
|
|
370
|
+
* Immediately flush all queued analytics and ecommerce events to the server.
|
|
263
371
|
*/
|
|
264
372
|
static flush(): Promise<void>;
|
|
373
|
+
/** Ecommerce: track purchases, carts, products, revenue */
|
|
374
|
+
static get ecommerce(): Ecommerce;
|
|
265
375
|
/** Referrals: create, complete, milestone, leaderboard, claimReward */
|
|
266
376
|
static get referrals(): Referrals;
|
|
267
377
|
/** Deferred deep links: claimByToken, claimBySignals */
|
|
@@ -303,4 +413,4 @@ declare function TolinkuMessages({ trigger, triggerValue, onDismiss, onButtonPre
|
|
|
303
413
|
*/
|
|
304
414
|
declare function isSafeUrl(url: string): boolean;
|
|
305
415
|
|
|
306
|
-
export { type ClaimBySignalsOptions, type CompleteReferralOptions, type CompleteReferralResult, type CreateReferralOptions, type CreateReferralResult, type DeferredLink, type LeaderboardEntry, type Message, type MessageComponent, type MessageContent, type MilestoneOptions, type MilestoneResult, type ReferralInfo, type ResolvedTolinkuConfig, type ShowMessageOptions, Tolinku, type TolinkuConfig, TolinkuError, TolinkuMessages, type TrackProperties, isSafeUrl };
|
|
416
|
+
export { type AddPaymentInfoParams, type AddToCartParams, type AddToWishlistParams, type BeginCheckoutParams, type ClaimBySignalsOptions, type CompleteReferralOptions, type CompleteReferralResult, type CreateReferralOptions, type CreateReferralResult, type DeferredLink, type EcommerceItem, type LeaderboardEntry, type Message, type MessageComponent, type MessageContent, type MilestoneOptions, type MilestoneResult, type PurchaseParams, type RateParams, type ReferralInfo, type RefundParams, type RemoveFromCartParams, type ResolvedTolinkuConfig, type SearchParams, type ShareParams, type ShowMessageOptions, type SpendCreditsParams, Tolinku, type TolinkuConfig, TolinkuError, TolinkuMessages, type TrackProperties, type ViewItemParams, isSafeUrl };
|
package/dist/index.js
CHANGED
|
@@ -353,6 +353,215 @@ var Analytics = class {
|
|
|
353
353
|
}
|
|
354
354
|
}
|
|
355
355
|
};
|
|
356
|
+
var BATCH_SIZE2 = 10;
|
|
357
|
+
var FLUSH_INTERVAL_MS2 = 5e3;
|
|
358
|
+
var MAX_QUEUE_SIZE2 = 500;
|
|
359
|
+
var CART_ID_STORAGE_KEY = "tolinku_ecom_cart_id";
|
|
360
|
+
var Ecommerce = class {
|
|
361
|
+
constructor(client, getUserId) {
|
|
362
|
+
this.queue = [];
|
|
363
|
+
this.flushTimer = null;
|
|
364
|
+
this.appStateSubscription = null;
|
|
365
|
+
this.isFlushing = false;
|
|
366
|
+
this.memoryCartId = null;
|
|
367
|
+
this.handleAppStateChange = (state) => {
|
|
368
|
+
if (state === "background" || state === "inactive") {
|
|
369
|
+
this.flush().catch(() => {
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
this.client = client;
|
|
374
|
+
this.getUserId = getUserId;
|
|
375
|
+
this.appStateSubscription = reactNative.AppState.addEventListener(
|
|
376
|
+
"change",
|
|
377
|
+
this.handleAppStateChange
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
// ─── Public methods (13 event types) ────────────────────
|
|
381
|
+
async viewItem(params) {
|
|
382
|
+
await this.enqueue({ event_type: "view_item", items: params.items });
|
|
383
|
+
}
|
|
384
|
+
async addToCart(params) {
|
|
385
|
+
const cartId = params.cart_id || await this.getOrCreateCartId();
|
|
386
|
+
await this.enqueue({ event_type: "add_to_cart", items: params.items, cart_id: cartId });
|
|
387
|
+
}
|
|
388
|
+
async removeFromCart(params) {
|
|
389
|
+
const cartId = params.cart_id || await this.getCartId();
|
|
390
|
+
await this.enqueue({ event_type: "remove_from_cart", items: params.items, cart_id: cartId });
|
|
391
|
+
}
|
|
392
|
+
async addToWishlist(params) {
|
|
393
|
+
await this.enqueue({ event_type: "add_to_wishlist", items: params.items });
|
|
394
|
+
}
|
|
395
|
+
async viewCart() {
|
|
396
|
+
const cartId = await this.getCartId();
|
|
397
|
+
await this.enqueue({ event_type: "view_cart", cart_id: cartId });
|
|
398
|
+
}
|
|
399
|
+
async addPaymentInfo(params) {
|
|
400
|
+
const cartId = params?.cart_id || await this.getCartId();
|
|
401
|
+
await this.enqueue({ event_type: "add_payment_info", cart_id: cartId });
|
|
402
|
+
}
|
|
403
|
+
async beginCheckout(params) {
|
|
404
|
+
const cartId = params.cart_id || await this.getCartId();
|
|
405
|
+
await this.enqueue({
|
|
406
|
+
event_type: "begin_checkout",
|
|
407
|
+
revenue: params.revenue,
|
|
408
|
+
currency: params.currency,
|
|
409
|
+
cart_id: cartId,
|
|
410
|
+
items: params.items
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
async purchase(params) {
|
|
414
|
+
const cartId = params.cart_id || await this.getCartId();
|
|
415
|
+
await this.enqueue({
|
|
416
|
+
event_type: "purchase",
|
|
417
|
+
transaction_id: params.transaction_id,
|
|
418
|
+
revenue: params.revenue,
|
|
419
|
+
currency: params.currency,
|
|
420
|
+
cart_id: cartId,
|
|
421
|
+
coupon_code: params.coupon_code,
|
|
422
|
+
discount: params.discount,
|
|
423
|
+
shipping: params.shipping,
|
|
424
|
+
tax: params.tax,
|
|
425
|
+
items: params.items
|
|
426
|
+
});
|
|
427
|
+
await this.clearCartId();
|
|
428
|
+
}
|
|
429
|
+
async refund(params) {
|
|
430
|
+
await this.enqueue({
|
|
431
|
+
event_type: "refund",
|
|
432
|
+
transaction_id: params.transaction_id,
|
|
433
|
+
revenue: params.revenue,
|
|
434
|
+
currency: params.currency,
|
|
435
|
+
items: params.items
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
async search(params) {
|
|
439
|
+
await this.enqueue({ event_type: "search", properties: { search_term: params.search_term } });
|
|
440
|
+
}
|
|
441
|
+
async share(params) {
|
|
442
|
+
const props = {};
|
|
443
|
+
if (params.item_id) props.item_id = params.item_id;
|
|
444
|
+
if (params.url) props.url = params.url;
|
|
445
|
+
if (params.method) props.method = params.method;
|
|
446
|
+
await this.enqueue({ event_type: "share", properties: props });
|
|
447
|
+
}
|
|
448
|
+
async rate(params) {
|
|
449
|
+
await this.enqueue({
|
|
450
|
+
event_type: "rate",
|
|
451
|
+
properties: {
|
|
452
|
+
item_id: params.item_id,
|
|
453
|
+
rating: String(params.rating),
|
|
454
|
+
...params.max_rating != null ? { max_rating: String(params.max_rating) } : {}
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
async spendCredits(params) {
|
|
459
|
+
await this.enqueue({ event_type: "spend_credits", revenue: params.revenue, currency: params.currency });
|
|
460
|
+
}
|
|
461
|
+
// ─── Flush ─────────────────────────────────────────────
|
|
462
|
+
async flush() {
|
|
463
|
+
if (this.queue.length === 0 || this.isFlushing) return;
|
|
464
|
+
this.isFlushing = true;
|
|
465
|
+
const events = this.queue.splice(0);
|
|
466
|
+
this.cancelFlushTimer();
|
|
467
|
+
try {
|
|
468
|
+
debugLog(`Flushing ${events.length} ecommerce event(s)`);
|
|
469
|
+
const result = await this.client.post(
|
|
470
|
+
"/v1/api/analytics/ecommerce/batch",
|
|
471
|
+
{ events }
|
|
472
|
+
);
|
|
473
|
+
if (result.errors && result.errors.length > 0) {
|
|
474
|
+
debugWarn(`Ecommerce batch partial failure: ${result.errors.join(", ")}`);
|
|
475
|
+
}
|
|
476
|
+
} catch (err) {
|
|
477
|
+
debugWarn(`Failed to flush ecommerce events: ${err.message}`);
|
|
478
|
+
const spaceLeft = MAX_QUEUE_SIZE2 - this.queue.length;
|
|
479
|
+
if (spaceLeft > 0) {
|
|
480
|
+
this.queue.unshift(...events.slice(0, spaceLeft));
|
|
481
|
+
}
|
|
482
|
+
} finally {
|
|
483
|
+
this.isFlushing = false;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
async destroy() {
|
|
487
|
+
this.cancelFlushTimer();
|
|
488
|
+
this.appStateSubscription?.remove();
|
|
489
|
+
this.appStateSubscription = null;
|
|
490
|
+
try {
|
|
491
|
+
await this.flush();
|
|
492
|
+
} catch {
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
// ─── Private ───────────────────────────────────────────
|
|
496
|
+
async enqueue(event) {
|
|
497
|
+
const userId = this.getUserId();
|
|
498
|
+
if (userId) event.user_id = userId;
|
|
499
|
+
if (this.queue.length >= MAX_QUEUE_SIZE2) {
|
|
500
|
+
debugWarn(`Ecommerce queue full (${MAX_QUEUE_SIZE2}). Dropping oldest event.`);
|
|
501
|
+
this.queue.shift();
|
|
502
|
+
}
|
|
503
|
+
this.queue.push(event);
|
|
504
|
+
if (this.queue.length >= BATCH_SIZE2) {
|
|
505
|
+
await this.flush();
|
|
506
|
+
} else if (this.queue.length === 1) {
|
|
507
|
+
this.startFlushTimer();
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
startFlushTimer() {
|
|
511
|
+
this.cancelFlushTimer();
|
|
512
|
+
this.flushTimer = setTimeout(() => {
|
|
513
|
+
this.flush().catch((err) => {
|
|
514
|
+
debugWarn(`Ecommerce timer flush failed: ${err.message}`);
|
|
515
|
+
});
|
|
516
|
+
}, FLUSH_INTERVAL_MS2);
|
|
517
|
+
}
|
|
518
|
+
cancelFlushTimer() {
|
|
519
|
+
if (this.flushTimer !== null) {
|
|
520
|
+
clearTimeout(this.flushTimer);
|
|
521
|
+
this.flushTimer = null;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
// ─── Cart ID lifecycle (AsyncStorage + memory fallback) ─
|
|
525
|
+
async getOrCreateCartId() {
|
|
526
|
+
const existing = await this.getCartId();
|
|
527
|
+
if (existing) return existing;
|
|
528
|
+
const cartId = this.generateId();
|
|
529
|
+
await this.setCartId(cartId);
|
|
530
|
+
return cartId;
|
|
531
|
+
}
|
|
532
|
+
async getCartId() {
|
|
533
|
+
try {
|
|
534
|
+
const stored = await AsyncStorage__default.default.getItem(CART_ID_STORAGE_KEY);
|
|
535
|
+
if (stored) return stored;
|
|
536
|
+
} catch {
|
|
537
|
+
}
|
|
538
|
+
return this.memoryCartId || void 0;
|
|
539
|
+
}
|
|
540
|
+
async setCartId(cartId) {
|
|
541
|
+
this.memoryCartId = cartId;
|
|
542
|
+
try {
|
|
543
|
+
await AsyncStorage__default.default.setItem(CART_ID_STORAGE_KEY, cartId);
|
|
544
|
+
} catch {
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
async clearCartId() {
|
|
548
|
+
this.memoryCartId = null;
|
|
549
|
+
try {
|
|
550
|
+
await AsyncStorage__default.default.removeItem(CART_ID_STORAGE_KEY);
|
|
551
|
+
} catch {
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
generateId() {
|
|
555
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
556
|
+
return crypto.randomUUID();
|
|
557
|
+
}
|
|
558
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
559
|
+
const r = Math.random() * 16 | 0;
|
|
560
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
561
|
+
return v.toString(16);
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
};
|
|
356
565
|
|
|
357
566
|
// src/referrals.ts
|
|
358
567
|
var Referrals = class {
|
|
@@ -568,6 +777,7 @@ var _Tolinku = class _Tolinku {
|
|
|
568
777
|
setStorageNamespace(config.apiKey);
|
|
569
778
|
_Tolinku.client = new HttpClient(resolvedConfig);
|
|
570
779
|
_Tolinku.analyticsInstance = new Analytics(_Tolinku.client);
|
|
780
|
+
_Tolinku.ecommerceInstance = new Ecommerce(_Tolinku.client, () => _Tolinku._userId);
|
|
571
781
|
_Tolinku.referralsInstance = new Referrals(_Tolinku.client);
|
|
572
782
|
_Tolinku.deferredInstance = new Deferred(_Tolinku.client);
|
|
573
783
|
_Tolinku._initialized = true;
|
|
@@ -608,13 +818,23 @@ var _Tolinku = class _Tolinku {
|
|
|
608
818
|
return _Tolinku.analyticsInstance.track(eventType, mergedProps);
|
|
609
819
|
}
|
|
610
820
|
/**
|
|
611
|
-
* Immediately flush all queued analytics events to the server.
|
|
821
|
+
* Immediately flush all queued analytics and ecommerce events to the server.
|
|
612
822
|
*/
|
|
613
823
|
static async flush() {
|
|
614
824
|
if (!_Tolinku.analyticsInstance) {
|
|
615
825
|
throw new Error("Tolinku: SDK not initialized. Call Tolinku.init() first.");
|
|
616
826
|
}
|
|
617
|
-
|
|
827
|
+
await Promise.all([
|
|
828
|
+
_Tolinku.analyticsInstance.flush(),
|
|
829
|
+
_Tolinku.ecommerceInstance?.flush()
|
|
830
|
+
]);
|
|
831
|
+
}
|
|
832
|
+
/** Ecommerce: track purchases, carts, products, revenue */
|
|
833
|
+
static get ecommerce() {
|
|
834
|
+
if (!_Tolinku.ecommerceInstance) {
|
|
835
|
+
throw new Error("Tolinku: SDK not initialized. Call Tolinku.init() first.");
|
|
836
|
+
}
|
|
837
|
+
return _Tolinku.ecommerceInstance;
|
|
618
838
|
}
|
|
619
839
|
/** Referrals: create, complete, milestone, leaderboard, claimReward */
|
|
620
840
|
static get referrals() {
|
|
@@ -641,12 +861,16 @@ var _Tolinku = class _Tolinku {
|
|
|
641
861
|
if (_Tolinku.analyticsInstance) {
|
|
642
862
|
await _Tolinku.analyticsInstance.destroy();
|
|
643
863
|
}
|
|
864
|
+
if (_Tolinku.ecommerceInstance) {
|
|
865
|
+
await _Tolinku.ecommerceInstance.destroy();
|
|
866
|
+
}
|
|
644
867
|
if (_Tolinku.client) {
|
|
645
868
|
_Tolinku.client.abort();
|
|
646
869
|
}
|
|
647
870
|
resetStorageNamespace();
|
|
648
871
|
_Tolinku.client = null;
|
|
649
872
|
_Tolinku.analyticsInstance = null;
|
|
873
|
+
_Tolinku.ecommerceInstance = null;
|
|
650
874
|
_Tolinku.referralsInstance = null;
|
|
651
875
|
_Tolinku.deferredInstance = null;
|
|
652
876
|
_Tolinku._initialized = false;
|
|
@@ -657,6 +881,7 @@ var _Tolinku = class _Tolinku {
|
|
|
657
881
|
_Tolinku.VERSION = SDK_VERSION;
|
|
658
882
|
_Tolinku.client = null;
|
|
659
883
|
_Tolinku.analyticsInstance = null;
|
|
884
|
+
_Tolinku.ecommerceInstance = null;
|
|
660
885
|
_Tolinku.referralsInstance = null;
|
|
661
886
|
_Tolinku.deferredInstance = null;
|
|
662
887
|
_Tolinku._initialized = false;
|