@tolinku/web-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 +108 -2
- package/dist/index.d.ts +108 -2
- package/dist/index.js +206 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +206 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -84,6 +84,32 @@ await tolinku.referrals.claimReward(referral_code);
|
|
|
84
84
|
const { leaderboard } = await tolinku.referrals.leaderboard(10);
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
+
### Ecommerce
|
|
88
|
+
|
|
89
|
+
Track purchases, cart activity, and product events with built-in revenue analytics. Available on paid plans.
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
tolinku.setUserId('user_123');
|
|
93
|
+
|
|
94
|
+
// Track a product view
|
|
95
|
+
await tolinku.ecommerce.viewItem({
|
|
96
|
+
items: [{ item_id: 'sku_1', item_name: 'T-Shirt', price: 24.99 }]
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Track a purchase
|
|
100
|
+
await tolinku.ecommerce.purchase({
|
|
101
|
+
transaction_id: 'order_456',
|
|
102
|
+
revenue: 49.99,
|
|
103
|
+
currency: 'USD',
|
|
104
|
+
items: [{ item_id: 'sku_1', item_name: 'T-Shirt', price: 24.99, quantity: 2 }]
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Flush ecommerce events
|
|
108
|
+
await tolinku.ecommerce.flush();
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The SDK supports 13 event types: `viewItem`, `addToCart`, `removeFromCart`, `addToWishlist`, `viewCart`, `addPaymentInfo`, `beginCheckout`, `purchase`, `refund`, `search`, `share`, `rate`, and `spendCredits`. Cart IDs are managed automatically via `sessionStorage` and cleared after purchase.
|
|
112
|
+
|
|
87
113
|
### Deferred Deep Links
|
|
88
114
|
|
|
89
115
|
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.
|
|
@@ -175,6 +201,25 @@ tolinku.setUserId('user_123');
|
|
|
175
201
|
| `claimReward(code)` | Claim a referral reward |
|
|
176
202
|
| `leaderboard(limit?)` | Fetch the referral leaderboard |
|
|
177
203
|
|
|
204
|
+
### `tolinku.ecommerce`
|
|
205
|
+
|
|
206
|
+
| Method | Description |
|
|
207
|
+
|--------|-------------|
|
|
208
|
+
| `viewItem(params)` | Track a product view |
|
|
209
|
+
| `addToCart(params)` | Track item added to cart |
|
|
210
|
+
| `removeFromCart(params)` | Track item removed from cart |
|
|
211
|
+
| `addToWishlist(params)` | Track item added to wishlist |
|
|
212
|
+
| `viewCart()` | Track cart view |
|
|
213
|
+
| `addPaymentInfo()` | Track payment info entered |
|
|
214
|
+
| `beginCheckout(params?)` | Track checkout started |
|
|
215
|
+
| `purchase(params)` | Track a purchase |
|
|
216
|
+
| `refund(params)` | Track a refund |
|
|
217
|
+
| `search(params)` | Track a product search |
|
|
218
|
+
| `share(params)` | Track a product share |
|
|
219
|
+
| `rate(params)` | Track a product rating |
|
|
220
|
+
| `spendCredits(params)` | Track loyalty credits spent |
|
|
221
|
+
| `flush()` | Send all queued ecommerce events |
|
|
222
|
+
|
|
178
223
|
### `tolinku.deferred`
|
|
179
224
|
|
|
180
225
|
| Method | Description |
|
package/dist/index.d.mts
CHANGED
|
@@ -160,6 +160,78 @@ interface ShowMessageOptions {
|
|
|
160
160
|
onDismiss?: (messageId: string) => void;
|
|
161
161
|
onButtonPress?: (action: string, messageId: string) => void;
|
|
162
162
|
}
|
|
163
|
+
interface EcommerceItem {
|
|
164
|
+
item_id: string;
|
|
165
|
+
item_name?: string;
|
|
166
|
+
item_category?: string;
|
|
167
|
+
item_brand?: string;
|
|
168
|
+
item_variant?: string;
|
|
169
|
+
item_list_name?: string;
|
|
170
|
+
item_list_id?: string;
|
|
171
|
+
item_image_url?: string;
|
|
172
|
+
price?: number;
|
|
173
|
+
quantity?: number;
|
|
174
|
+
currency?: string;
|
|
175
|
+
coupon_code?: string;
|
|
176
|
+
discount?: number;
|
|
177
|
+
}
|
|
178
|
+
interface PurchaseParams {
|
|
179
|
+
transaction_id: string;
|
|
180
|
+
revenue: number;
|
|
181
|
+
currency: string;
|
|
182
|
+
items?: EcommerceItem[];
|
|
183
|
+
cart_id?: string;
|
|
184
|
+
coupon_code?: string;
|
|
185
|
+
discount?: number;
|
|
186
|
+
shipping?: number;
|
|
187
|
+
tax?: number;
|
|
188
|
+
}
|
|
189
|
+
interface AddToCartParams {
|
|
190
|
+
items: EcommerceItem[];
|
|
191
|
+
cart_id?: string;
|
|
192
|
+
}
|
|
193
|
+
interface RemoveFromCartParams {
|
|
194
|
+
items: EcommerceItem[];
|
|
195
|
+
cart_id?: string;
|
|
196
|
+
}
|
|
197
|
+
interface AddToWishlistParams {
|
|
198
|
+
items: EcommerceItem[];
|
|
199
|
+
}
|
|
200
|
+
interface BeginCheckoutParams {
|
|
201
|
+
revenue?: number;
|
|
202
|
+
currency?: string;
|
|
203
|
+
cart_id?: string;
|
|
204
|
+
items?: EcommerceItem[];
|
|
205
|
+
}
|
|
206
|
+
interface RefundParams {
|
|
207
|
+
transaction_id: string;
|
|
208
|
+
revenue: number;
|
|
209
|
+
currency?: string;
|
|
210
|
+
items?: EcommerceItem[];
|
|
211
|
+
}
|
|
212
|
+
interface ViewItemParams {
|
|
213
|
+
items: EcommerceItem[];
|
|
214
|
+
}
|
|
215
|
+
interface SearchParams {
|
|
216
|
+
search_term: string;
|
|
217
|
+
}
|
|
218
|
+
interface AddPaymentInfoParams {
|
|
219
|
+
cart_id?: string;
|
|
220
|
+
}
|
|
221
|
+
interface ShareParams {
|
|
222
|
+
item_id?: string;
|
|
223
|
+
url?: string;
|
|
224
|
+
method?: string;
|
|
225
|
+
}
|
|
226
|
+
interface RateParams {
|
|
227
|
+
item_id: string;
|
|
228
|
+
rating: number;
|
|
229
|
+
max_rating?: number;
|
|
230
|
+
}
|
|
231
|
+
interface SpendCreditsParams {
|
|
232
|
+
revenue: number;
|
|
233
|
+
currency: string;
|
|
234
|
+
}
|
|
163
235
|
|
|
164
236
|
declare class HttpClient {
|
|
165
237
|
private _baseUrl;
|
|
@@ -225,6 +297,38 @@ declare class Analytics {
|
|
|
225
297
|
destroy(): void;
|
|
226
298
|
}
|
|
227
299
|
|
|
300
|
+
declare class Ecommerce {
|
|
301
|
+
private client;
|
|
302
|
+
private queue;
|
|
303
|
+
private flushTimer;
|
|
304
|
+
private unloadHandler;
|
|
305
|
+
private getUserId;
|
|
306
|
+
private memoryCartId;
|
|
307
|
+
constructor(client: HttpClient, getUserId: () => string | null);
|
|
308
|
+
viewItem(params: ViewItemParams): Promise<void>;
|
|
309
|
+
addToCart(params: AddToCartParams): Promise<void>;
|
|
310
|
+
removeFromCart(params: RemoveFromCartParams): Promise<void>;
|
|
311
|
+
addToWishlist(params: AddToWishlistParams): Promise<void>;
|
|
312
|
+
viewCart(): Promise<void>;
|
|
313
|
+
addPaymentInfo(params?: AddPaymentInfoParams): Promise<void>;
|
|
314
|
+
beginCheckout(params: BeginCheckoutParams): Promise<void>;
|
|
315
|
+
purchase(params: PurchaseParams): Promise<void>;
|
|
316
|
+
refund(params: RefundParams): Promise<void>;
|
|
317
|
+
search(params: SearchParams): Promise<void>;
|
|
318
|
+
share(params: ShareParams): Promise<void>;
|
|
319
|
+
rate(params: RateParams): Promise<void>;
|
|
320
|
+
spendCredits(params: SpendCreditsParams): Promise<void>;
|
|
321
|
+
flush(): Promise<void>;
|
|
322
|
+
destroy(): void;
|
|
323
|
+
private enqueue;
|
|
324
|
+
private flushBeacon;
|
|
325
|
+
private getOrCreateCartId;
|
|
326
|
+
private getCartId;
|
|
327
|
+
private setCartId;
|
|
328
|
+
private clearCartId;
|
|
329
|
+
private generateId;
|
|
330
|
+
}
|
|
331
|
+
|
|
228
332
|
declare class Referrals {
|
|
229
333
|
private client;
|
|
230
334
|
constructor(client: HttpClient);
|
|
@@ -261,6 +365,8 @@ declare class Tolinku {
|
|
|
261
365
|
private client;
|
|
262
366
|
/** Analytics: track custom events */
|
|
263
367
|
readonly analytics: Analytics;
|
|
368
|
+
/** Ecommerce: track purchases, carts, products, revenue */
|
|
369
|
+
readonly ecommerce: Ecommerce;
|
|
264
370
|
/** Referrals: create, complete, milestone, leaderboard */
|
|
265
371
|
readonly referrals: Referrals;
|
|
266
372
|
/** Deferred deep links: claim by token or signals */
|
|
@@ -289,10 +395,10 @@ declare class Tolinku {
|
|
|
289
395
|
showMessage(options?: ShowMessageOptions): Promise<void>;
|
|
290
396
|
/** Dismiss the currently visible in-app message */
|
|
291
397
|
dismissMessage(): void;
|
|
292
|
-
/** Flush any queued analytics events immediately */
|
|
398
|
+
/** Flush any queued analytics and ecommerce events immediately */
|
|
293
399
|
flush(): Promise<void>;
|
|
294
400
|
/** Clean up all DOM elements, flush events, and cancel in-flight requests (e.g. before unmounting in SPAs) */
|
|
295
401
|
destroy(): void;
|
|
296
402
|
}
|
|
297
403
|
|
|
298
|
-
export { type BannerConfig, type BannerItem, 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 ShowBannerOptions, type ShowMessageOptions, Tolinku, type TolinkuConfig, TolinkuError, type TrackProperties };
|
|
404
|
+
export { type AddPaymentInfoParams, type AddToCartParams, type AddToWishlistParams, type BannerConfig, type BannerItem, 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 SearchParams, type ShareParams, type ShowBannerOptions, type ShowMessageOptions, type SpendCreditsParams, Tolinku, type TolinkuConfig, TolinkuError, type TrackProperties, type ViewItemParams };
|
package/dist/index.d.ts
CHANGED
|
@@ -160,6 +160,78 @@ interface ShowMessageOptions {
|
|
|
160
160
|
onDismiss?: (messageId: string) => void;
|
|
161
161
|
onButtonPress?: (action: string, messageId: string) => void;
|
|
162
162
|
}
|
|
163
|
+
interface EcommerceItem {
|
|
164
|
+
item_id: string;
|
|
165
|
+
item_name?: string;
|
|
166
|
+
item_category?: string;
|
|
167
|
+
item_brand?: string;
|
|
168
|
+
item_variant?: string;
|
|
169
|
+
item_list_name?: string;
|
|
170
|
+
item_list_id?: string;
|
|
171
|
+
item_image_url?: string;
|
|
172
|
+
price?: number;
|
|
173
|
+
quantity?: number;
|
|
174
|
+
currency?: string;
|
|
175
|
+
coupon_code?: string;
|
|
176
|
+
discount?: number;
|
|
177
|
+
}
|
|
178
|
+
interface PurchaseParams {
|
|
179
|
+
transaction_id: string;
|
|
180
|
+
revenue: number;
|
|
181
|
+
currency: string;
|
|
182
|
+
items?: EcommerceItem[];
|
|
183
|
+
cart_id?: string;
|
|
184
|
+
coupon_code?: string;
|
|
185
|
+
discount?: number;
|
|
186
|
+
shipping?: number;
|
|
187
|
+
tax?: number;
|
|
188
|
+
}
|
|
189
|
+
interface AddToCartParams {
|
|
190
|
+
items: EcommerceItem[];
|
|
191
|
+
cart_id?: string;
|
|
192
|
+
}
|
|
193
|
+
interface RemoveFromCartParams {
|
|
194
|
+
items: EcommerceItem[];
|
|
195
|
+
cart_id?: string;
|
|
196
|
+
}
|
|
197
|
+
interface AddToWishlistParams {
|
|
198
|
+
items: EcommerceItem[];
|
|
199
|
+
}
|
|
200
|
+
interface BeginCheckoutParams {
|
|
201
|
+
revenue?: number;
|
|
202
|
+
currency?: string;
|
|
203
|
+
cart_id?: string;
|
|
204
|
+
items?: EcommerceItem[];
|
|
205
|
+
}
|
|
206
|
+
interface RefundParams {
|
|
207
|
+
transaction_id: string;
|
|
208
|
+
revenue: number;
|
|
209
|
+
currency?: string;
|
|
210
|
+
items?: EcommerceItem[];
|
|
211
|
+
}
|
|
212
|
+
interface ViewItemParams {
|
|
213
|
+
items: EcommerceItem[];
|
|
214
|
+
}
|
|
215
|
+
interface SearchParams {
|
|
216
|
+
search_term: string;
|
|
217
|
+
}
|
|
218
|
+
interface AddPaymentInfoParams {
|
|
219
|
+
cart_id?: string;
|
|
220
|
+
}
|
|
221
|
+
interface ShareParams {
|
|
222
|
+
item_id?: string;
|
|
223
|
+
url?: string;
|
|
224
|
+
method?: string;
|
|
225
|
+
}
|
|
226
|
+
interface RateParams {
|
|
227
|
+
item_id: string;
|
|
228
|
+
rating: number;
|
|
229
|
+
max_rating?: number;
|
|
230
|
+
}
|
|
231
|
+
interface SpendCreditsParams {
|
|
232
|
+
revenue: number;
|
|
233
|
+
currency: string;
|
|
234
|
+
}
|
|
163
235
|
|
|
164
236
|
declare class HttpClient {
|
|
165
237
|
private _baseUrl;
|
|
@@ -225,6 +297,38 @@ declare class Analytics {
|
|
|
225
297
|
destroy(): void;
|
|
226
298
|
}
|
|
227
299
|
|
|
300
|
+
declare class Ecommerce {
|
|
301
|
+
private client;
|
|
302
|
+
private queue;
|
|
303
|
+
private flushTimer;
|
|
304
|
+
private unloadHandler;
|
|
305
|
+
private getUserId;
|
|
306
|
+
private memoryCartId;
|
|
307
|
+
constructor(client: HttpClient, getUserId: () => string | null);
|
|
308
|
+
viewItem(params: ViewItemParams): Promise<void>;
|
|
309
|
+
addToCart(params: AddToCartParams): Promise<void>;
|
|
310
|
+
removeFromCart(params: RemoveFromCartParams): Promise<void>;
|
|
311
|
+
addToWishlist(params: AddToWishlistParams): Promise<void>;
|
|
312
|
+
viewCart(): Promise<void>;
|
|
313
|
+
addPaymentInfo(params?: AddPaymentInfoParams): Promise<void>;
|
|
314
|
+
beginCheckout(params: BeginCheckoutParams): Promise<void>;
|
|
315
|
+
purchase(params: PurchaseParams): Promise<void>;
|
|
316
|
+
refund(params: RefundParams): Promise<void>;
|
|
317
|
+
search(params: SearchParams): Promise<void>;
|
|
318
|
+
share(params: ShareParams): Promise<void>;
|
|
319
|
+
rate(params: RateParams): Promise<void>;
|
|
320
|
+
spendCredits(params: SpendCreditsParams): Promise<void>;
|
|
321
|
+
flush(): Promise<void>;
|
|
322
|
+
destroy(): void;
|
|
323
|
+
private enqueue;
|
|
324
|
+
private flushBeacon;
|
|
325
|
+
private getOrCreateCartId;
|
|
326
|
+
private getCartId;
|
|
327
|
+
private setCartId;
|
|
328
|
+
private clearCartId;
|
|
329
|
+
private generateId;
|
|
330
|
+
}
|
|
331
|
+
|
|
228
332
|
declare class Referrals {
|
|
229
333
|
private client;
|
|
230
334
|
constructor(client: HttpClient);
|
|
@@ -261,6 +365,8 @@ declare class Tolinku {
|
|
|
261
365
|
private client;
|
|
262
366
|
/** Analytics: track custom events */
|
|
263
367
|
readonly analytics: Analytics;
|
|
368
|
+
/** Ecommerce: track purchases, carts, products, revenue */
|
|
369
|
+
readonly ecommerce: Ecommerce;
|
|
264
370
|
/** Referrals: create, complete, milestone, leaderboard */
|
|
265
371
|
readonly referrals: Referrals;
|
|
266
372
|
/** Deferred deep links: claim by token or signals */
|
|
@@ -289,10 +395,10 @@ declare class Tolinku {
|
|
|
289
395
|
showMessage(options?: ShowMessageOptions): Promise<void>;
|
|
290
396
|
/** Dismiss the currently visible in-app message */
|
|
291
397
|
dismissMessage(): void;
|
|
292
|
-
/** Flush any queued analytics events immediately */
|
|
398
|
+
/** Flush any queued analytics and ecommerce events immediately */
|
|
293
399
|
flush(): Promise<void>;
|
|
294
400
|
/** Clean up all DOM elements, flush events, and cancel in-flight requests (e.g. before unmounting in SPAs) */
|
|
295
401
|
destroy(): void;
|
|
296
402
|
}
|
|
297
403
|
|
|
298
|
-
export { type BannerConfig, type BannerItem, 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 ShowBannerOptions, type ShowMessageOptions, Tolinku, type TolinkuConfig, TolinkuError, type TrackProperties };
|
|
404
|
+
export { type AddPaymentInfoParams, type AddToCartParams, type AddToWishlistParams, type BannerConfig, type BannerItem, 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 SearchParams, type ShareParams, type ShowBannerOptions, type ShowMessageOptions, type SpendCreditsParams, Tolinku, type TolinkuConfig, TolinkuError, type TrackProperties, type ViewItemParams };
|
package/dist/index.js
CHANGED
|
@@ -277,6 +277,208 @@ var Analytics = class {
|
|
|
277
277
|
}
|
|
278
278
|
};
|
|
279
279
|
|
|
280
|
+
// src/ecommerce.ts
|
|
281
|
+
var BATCH_SIZE2 = 10;
|
|
282
|
+
var FLUSH_INTERVAL_MS2 = 5e3;
|
|
283
|
+
var MAX_QUEUE_SIZE2 = 500;
|
|
284
|
+
var CART_ID_KEY = "tolk_cart_id";
|
|
285
|
+
var Ecommerce = class {
|
|
286
|
+
// fallback when sessionStorage unavailable
|
|
287
|
+
constructor(client, getUserId) {
|
|
288
|
+
this.client = client;
|
|
289
|
+
this.queue = [];
|
|
290
|
+
this.flushTimer = null;
|
|
291
|
+
this.unloadHandler = null;
|
|
292
|
+
this.memoryCartId = null;
|
|
293
|
+
this.getUserId = getUserId;
|
|
294
|
+
if (typeof window !== "undefined") {
|
|
295
|
+
this.unloadHandler = () => this.flushBeacon();
|
|
296
|
+
window.addEventListener("beforeunload", this.unloadHandler);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// ─── Public methods (13 event types) ────────────────────
|
|
300
|
+
async viewItem(params) {
|
|
301
|
+
await this.enqueue({ event_type: "view_item", items: params.items });
|
|
302
|
+
}
|
|
303
|
+
async addToCart(params) {
|
|
304
|
+
const cartId = params.cart_id || this.getOrCreateCartId();
|
|
305
|
+
await this.enqueue({ event_type: "add_to_cart", items: params.items, cart_id: cartId });
|
|
306
|
+
}
|
|
307
|
+
async removeFromCart(params) {
|
|
308
|
+
await this.enqueue({ event_type: "remove_from_cart", items: params.items, cart_id: params.cart_id || this.getCartId() });
|
|
309
|
+
}
|
|
310
|
+
async addToWishlist(params) {
|
|
311
|
+
await this.enqueue({ event_type: "add_to_wishlist", items: params.items });
|
|
312
|
+
}
|
|
313
|
+
async viewCart() {
|
|
314
|
+
await this.enqueue({ event_type: "view_cart", cart_id: this.getCartId() });
|
|
315
|
+
}
|
|
316
|
+
async addPaymentInfo(params) {
|
|
317
|
+
await this.enqueue({ event_type: "add_payment_info", cart_id: params?.cart_id || this.getCartId() });
|
|
318
|
+
}
|
|
319
|
+
async beginCheckout(params) {
|
|
320
|
+
await this.enqueue({
|
|
321
|
+
event_type: "begin_checkout",
|
|
322
|
+
revenue: params.revenue,
|
|
323
|
+
currency: params.currency,
|
|
324
|
+
cart_id: params.cart_id || this.getCartId(),
|
|
325
|
+
items: params.items
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
async purchase(params) {
|
|
329
|
+
const cartId = params.cart_id || this.getCartId();
|
|
330
|
+
await this.enqueue({
|
|
331
|
+
event_type: "purchase",
|
|
332
|
+
transaction_id: params.transaction_id,
|
|
333
|
+
revenue: params.revenue,
|
|
334
|
+
currency: params.currency,
|
|
335
|
+
cart_id: cartId,
|
|
336
|
+
coupon_code: params.coupon_code,
|
|
337
|
+
discount: params.discount,
|
|
338
|
+
shipping: params.shipping,
|
|
339
|
+
tax: params.tax,
|
|
340
|
+
items: params.items
|
|
341
|
+
});
|
|
342
|
+
this.clearCartId();
|
|
343
|
+
}
|
|
344
|
+
async refund(params) {
|
|
345
|
+
await this.enqueue({
|
|
346
|
+
event_type: "refund",
|
|
347
|
+
transaction_id: params.transaction_id,
|
|
348
|
+
revenue: params.revenue,
|
|
349
|
+
currency: params.currency,
|
|
350
|
+
items: params.items
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
async search(params) {
|
|
354
|
+
await this.enqueue({ event_type: "search", properties: { search_term: params.search_term } });
|
|
355
|
+
}
|
|
356
|
+
async share(params) {
|
|
357
|
+
const props = {};
|
|
358
|
+
if (params.item_id) props.item_id = params.item_id;
|
|
359
|
+
if (params.url) props.url = params.url;
|
|
360
|
+
if (params.method) props.method = params.method;
|
|
361
|
+
await this.enqueue({ event_type: "share", properties: props });
|
|
362
|
+
}
|
|
363
|
+
async rate(params) {
|
|
364
|
+
await this.enqueue({
|
|
365
|
+
event_type: "rate",
|
|
366
|
+
properties: {
|
|
367
|
+
item_id: params.item_id,
|
|
368
|
+
rating: String(params.rating),
|
|
369
|
+
...params.max_rating != null ? { max_rating: String(params.max_rating) } : {}
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
async spendCredits(params) {
|
|
374
|
+
await this.enqueue({ event_type: "spend_credits", revenue: params.revenue, currency: params.currency });
|
|
375
|
+
}
|
|
376
|
+
// ─── Flush ─────────────────────────────────────────────
|
|
377
|
+
async flush() {
|
|
378
|
+
if (this.flushTimer) {
|
|
379
|
+
clearTimeout(this.flushTimer);
|
|
380
|
+
this.flushTimer = null;
|
|
381
|
+
}
|
|
382
|
+
if (this.queue.length === 0) return;
|
|
383
|
+
const events = this.queue.splice(0);
|
|
384
|
+
try {
|
|
385
|
+
const result = await this.client.post(
|
|
386
|
+
"/v1/api/analytics/ecommerce/batch",
|
|
387
|
+
{ events }
|
|
388
|
+
);
|
|
389
|
+
if (result.errors && result.errors.length > 0) {
|
|
390
|
+
console.warn("[TolinkuSDK] Ecommerce batch partial failure:", result.errors);
|
|
391
|
+
}
|
|
392
|
+
} catch {
|
|
393
|
+
this.queue.unshift(...events);
|
|
394
|
+
if (this.queue.length > MAX_QUEUE_SIZE2) {
|
|
395
|
+
this.queue.splice(0, this.queue.length - MAX_QUEUE_SIZE2);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
destroy() {
|
|
400
|
+
this.flushBeacon();
|
|
401
|
+
if (this.flushTimer) {
|
|
402
|
+
clearTimeout(this.flushTimer);
|
|
403
|
+
this.flushTimer = null;
|
|
404
|
+
}
|
|
405
|
+
if (typeof window !== "undefined" && this.unloadHandler) {
|
|
406
|
+
window.removeEventListener("beforeunload", this.unloadHandler);
|
|
407
|
+
this.unloadHandler = null;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
// ─── Private ───────────────────────────────────────────
|
|
411
|
+
async enqueue(event) {
|
|
412
|
+
const userId = this.getUserId();
|
|
413
|
+
if (userId) event.user_id = userId;
|
|
414
|
+
this.queue.push(event);
|
|
415
|
+
if (this.queue.length === 1 && !this.flushTimer) {
|
|
416
|
+
this.flushTimer = setTimeout(() => {
|
|
417
|
+
this.flushTimer = null;
|
|
418
|
+
this.flush();
|
|
419
|
+
}, FLUSH_INTERVAL_MS2);
|
|
420
|
+
}
|
|
421
|
+
if (this.queue.length >= BATCH_SIZE2) {
|
|
422
|
+
await this.flush();
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
flushBeacon() {
|
|
426
|
+
if (this.queue.length === 0) return;
|
|
427
|
+
const events = this.queue.splice(0);
|
|
428
|
+
const url = this.client.baseUrl + "/v1/api/analytics/ecommerce/batch";
|
|
429
|
+
const body = JSON.stringify({ events, apiKey: this.client.key });
|
|
430
|
+
if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
|
|
431
|
+
navigator.sendBeacon(url, new Blob([body], { type: "application/json" }));
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
// ─── Cart ID lifecycle ─────────────────────────────────
|
|
435
|
+
getOrCreateCartId() {
|
|
436
|
+
const existing = this.getCartId();
|
|
437
|
+
if (existing) return existing;
|
|
438
|
+
const cartId = this.generateId();
|
|
439
|
+
this.setCartId(cartId);
|
|
440
|
+
return cartId;
|
|
441
|
+
}
|
|
442
|
+
getCartId() {
|
|
443
|
+
try {
|
|
444
|
+
if (typeof sessionStorage !== "undefined") {
|
|
445
|
+
const stored = sessionStorage.getItem(CART_ID_KEY);
|
|
446
|
+
if (stored) return stored;
|
|
447
|
+
}
|
|
448
|
+
} catch {
|
|
449
|
+
}
|
|
450
|
+
return this.memoryCartId || void 0;
|
|
451
|
+
}
|
|
452
|
+
setCartId(cartId) {
|
|
453
|
+
this.memoryCartId = cartId;
|
|
454
|
+
try {
|
|
455
|
+
if (typeof sessionStorage !== "undefined") {
|
|
456
|
+
sessionStorage.setItem(CART_ID_KEY, cartId);
|
|
457
|
+
}
|
|
458
|
+
} catch {
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
clearCartId() {
|
|
462
|
+
this.memoryCartId = null;
|
|
463
|
+
try {
|
|
464
|
+
if (typeof sessionStorage !== "undefined") {
|
|
465
|
+
sessionStorage.removeItem(CART_ID_KEY);
|
|
466
|
+
}
|
|
467
|
+
} catch {
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
generateId() {
|
|
471
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
472
|
+
return crypto.randomUUID();
|
|
473
|
+
}
|
|
474
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
475
|
+
const r = Math.random() * 16 | 0;
|
|
476
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
477
|
+
return v.toString(16);
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
|
|
280
482
|
// src/referrals.ts
|
|
281
483
|
var Referrals = class {
|
|
282
484
|
constructor(client) {
|
|
@@ -857,6 +1059,7 @@ var Tolinku = class {
|
|
|
857
1059
|
}
|
|
858
1060
|
this.client = new HttpClient(resolvedConfig);
|
|
859
1061
|
this.analytics = new Analytics(this.client);
|
|
1062
|
+
this.ecommerce = new Ecommerce(this.client, () => this._userId);
|
|
860
1063
|
this.referrals = new Referrals(this.client);
|
|
861
1064
|
this.deferred = new Deferred(this.client);
|
|
862
1065
|
this.banners = new Banners(this.client);
|
|
@@ -894,13 +1097,14 @@ var Tolinku = class {
|
|
|
894
1097
|
dismissMessage() {
|
|
895
1098
|
this.messages.dismiss();
|
|
896
1099
|
}
|
|
897
|
-
/** Flush any queued analytics events immediately */
|
|
1100
|
+
/** Flush any queued analytics and ecommerce events immediately */
|
|
898
1101
|
async flush() {
|
|
899
|
-
|
|
1102
|
+
await Promise.all([this.analytics.flush(), this.ecommerce.flush()]);
|
|
900
1103
|
}
|
|
901
1104
|
/** Clean up all DOM elements, flush events, and cancel in-flight requests (e.g. before unmounting in SPAs) */
|
|
902
1105
|
destroy() {
|
|
903
1106
|
this.analytics.destroy();
|
|
1107
|
+
this.ecommerce.destroy();
|
|
904
1108
|
this.client.abort();
|
|
905
1109
|
this.banners.dismiss();
|
|
906
1110
|
this.messages.dismiss();
|