@clianta/sdk 1.7.1 → 1.7.3
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/dist/angular.cjs.js +54 -48
- package/dist/angular.cjs.js.map +1 -1
- package/dist/angular.d.ts +12 -9
- package/dist/angular.esm.js +54 -48
- package/dist/angular.esm.js.map +1 -1
- package/dist/clianta.cjs.js +1238 -48
- package/dist/clianta.cjs.js.map +1 -1
- package/dist/clianta.esm.js +1238 -49
- package/dist/clianta.esm.js.map +1 -1
- package/dist/clianta.umd.js +1238 -48
- package/dist/clianta.umd.js.map +1 -1
- package/dist/clianta.umd.min.js +2 -2
- package/dist/clianta.umd.min.js.map +1 -1
- package/dist/index.d.ts +832 -12
- package/dist/react.cjs.js +54 -48
- package/dist/react.cjs.js.map +1 -1
- package/dist/react.d.ts +12 -9
- package/dist/react.esm.js +54 -48
- package/dist/react.esm.js.map +1 -1
- package/dist/svelte.cjs.js +54 -48
- package/dist/svelte.cjs.js.map +1 -1
- package/dist/svelte.d.ts +12 -9
- package/dist/svelte.esm.js +54 -48
- package/dist/svelte.esm.js.map +1 -1
- package/dist/vue.cjs.js +54 -48
- package/dist/vue.cjs.js.map +1 -1
- package/dist/vue.d.ts +12 -9
- package/dist/vue.esm.js +54 -48
- package/dist/vue.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/vue.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Clianta SDK v1.7.
|
|
2
|
+
* Clianta SDK v1.7.3
|
|
3
3
|
* (c) 2026 Clianta
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -13,7 +13,7 @@ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentS
|
|
|
13
13
|
* @see SDK_VERSION in core/config.ts
|
|
14
14
|
*/
|
|
15
15
|
/** SDK Version */
|
|
16
|
-
const SDK_VERSION = '1.7.
|
|
16
|
+
const SDK_VERSION = '1.7.2';
|
|
17
17
|
/** Default API endpoint — reads from env or falls back to localhost */
|
|
18
18
|
const getDefaultApiEndpoint = () => {
|
|
19
19
|
// Next.js (process.env)
|
|
@@ -224,8 +224,9 @@ class Transport {
|
|
|
224
224
|
/**
|
|
225
225
|
* Send identify request.
|
|
226
226
|
* Returns contactId from the server response so the Tracker can store it.
|
|
227
|
+
* Retries on 5xx with exponential backoff (same policy as sendEvents).
|
|
227
228
|
*/
|
|
228
|
-
async sendIdentify(data) {
|
|
229
|
+
async sendIdentify(data, attempt = 1) {
|
|
229
230
|
const url = `${this.config.apiEndpoint}/api/public/track/identify`;
|
|
230
231
|
try {
|
|
231
232
|
const response = await this.fetchWithTimeout(url, {
|
|
@@ -243,16 +244,26 @@ class Transport {
|
|
|
243
244
|
contactId: body.contactId ?? undefined,
|
|
244
245
|
};
|
|
245
246
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
247
|
+
// Server error — retry with exponential backoff
|
|
248
|
+
if (response.status >= 500 && attempt < this.config.maxRetries) {
|
|
249
|
+
const backoff = this.config.retryDelay * Math.pow(2, attempt - 1);
|
|
250
|
+
logger.warn(`Identify server error (${response.status}), retrying in ${backoff}ms...`);
|
|
251
|
+
await this.delay(backoff);
|
|
252
|
+
return this.sendIdentify(data, attempt + 1);
|
|
251
253
|
}
|
|
254
|
+
logger.error(`Identify failed with status ${response.status}:`, body.message);
|
|
252
255
|
return { success: false, status: response.status };
|
|
253
256
|
}
|
|
254
257
|
catch (error) {
|
|
255
|
-
|
|
258
|
+
// Network error — retry if still online
|
|
259
|
+
const isOnline = typeof navigator === 'undefined' || navigator.onLine;
|
|
260
|
+
if (isOnline && attempt < this.config.maxRetries) {
|
|
261
|
+
const backoff = this.config.retryDelay * Math.pow(2, attempt - 1);
|
|
262
|
+
logger.warn(`Identify network error, retrying in ${backoff}ms (${attempt}/${this.config.maxRetries})...`);
|
|
263
|
+
await this.delay(backoff);
|
|
264
|
+
return this.sendIdentify(data, attempt + 1);
|
|
265
|
+
}
|
|
266
|
+
logger.error('Identify request failed after retries:', error);
|
|
256
267
|
return { success: false, error: error };
|
|
257
268
|
}
|
|
258
269
|
}
|
|
@@ -570,9 +581,6 @@ function resetIds(useCookies = false) {
|
|
|
570
581
|
// Ignore
|
|
571
582
|
}
|
|
572
583
|
}
|
|
573
|
-
// ============================================
|
|
574
|
-
// URL UTILITIES
|
|
575
|
-
// ============================================
|
|
576
584
|
/**
|
|
577
585
|
* Extract UTM parameters from URL
|
|
578
586
|
*/
|
|
@@ -729,8 +737,9 @@ class EventQueue {
|
|
|
729
737
|
flushInterval: config.flushInterval ?? 5000,
|
|
730
738
|
maxQueueSize: config.maxQueueSize ?? MAX_QUEUE_SIZE,
|
|
731
739
|
storageKey: config.storageKey ?? STORAGE_KEYS.EVENT_QUEUE,
|
|
740
|
+
persistMode: config.persistMode ?? 'session',
|
|
732
741
|
};
|
|
733
|
-
this.persistMode = config.persistMode
|
|
742
|
+
this.persistMode = this.config.persistMode;
|
|
734
743
|
this.isOnline = typeof navigator === 'undefined' || navigator.onLine;
|
|
735
744
|
// Restore persisted queue
|
|
736
745
|
this.restoreQueue();
|
|
@@ -794,9 +803,11 @@ class EventQueue {
|
|
|
794
803
|
// Send to backend
|
|
795
804
|
const result = await this.transport.sendEvents(events);
|
|
796
805
|
if (!result.success) {
|
|
797
|
-
// Re-queue events on failure (at the front)
|
|
806
|
+
// Re-queue events on failure (at the front), capped at maxQueueSize
|
|
798
807
|
logger.warn('Flush failed, re-queuing events');
|
|
799
|
-
this.queue.
|
|
808
|
+
const availableSpace = this.config.maxQueueSize - this.queue.length;
|
|
809
|
+
const eventsToRequeue = events.slice(0, Math.max(0, availableSpace));
|
|
810
|
+
this.queue.unshift(...eventsToRequeue);
|
|
800
811
|
this.persistQueue(this.queue);
|
|
801
812
|
}
|
|
802
813
|
else {
|
|
@@ -1243,7 +1254,7 @@ class FormsPlugin extends BasePlugin {
|
|
|
1243
1254
|
if (this.trackedForms.has(form))
|
|
1244
1255
|
return;
|
|
1245
1256
|
this.trackedForms.add(form);
|
|
1246
|
-
const formId = form.id || form.name || `form-${Math.random().toString(36).
|
|
1257
|
+
const formId = form.id || form.name || `form-${Math.random().toString(36).substring(2, 11)}`;
|
|
1247
1258
|
// Track form view
|
|
1248
1259
|
this.track('form_view', 'Form Viewed', {
|
|
1249
1260
|
formId,
|
|
@@ -1887,27 +1898,22 @@ class PopupFormsPlugin extends BasePlugin {
|
|
|
1887
1898
|
super.destroy();
|
|
1888
1899
|
}
|
|
1889
1900
|
loadShownForms() {
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1901
|
+
const stored = getLocalStorage('clianta_shown_forms');
|
|
1902
|
+
if (stored) {
|
|
1903
|
+
try {
|
|
1893
1904
|
const data = JSON.parse(stored);
|
|
1894
1905
|
this.shownForms = new Set(data.forms || []);
|
|
1895
1906
|
}
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1907
|
+
catch {
|
|
1908
|
+
// Ignore parse errors
|
|
1909
|
+
}
|
|
1899
1910
|
}
|
|
1900
1911
|
}
|
|
1901
1912
|
saveShownForms() {
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
}));
|
|
1907
|
-
}
|
|
1908
|
-
catch (e) {
|
|
1909
|
-
// Ignore storage errors
|
|
1910
|
-
}
|
|
1913
|
+
setLocalStorage('clianta_shown_forms', JSON.stringify({
|
|
1914
|
+
forms: Array.from(this.shownForms),
|
|
1915
|
+
timestamp: Date.now(),
|
|
1916
|
+
}));
|
|
1911
1917
|
}
|
|
1912
1918
|
async fetchForms() {
|
|
1913
1919
|
if (!this.tracker)
|
|
@@ -1926,7 +1932,7 @@ class PopupFormsPlugin extends BasePlugin {
|
|
|
1926
1932
|
}
|
|
1927
1933
|
}
|
|
1928
1934
|
catch (error) {
|
|
1929
|
-
|
|
1935
|
+
logger.error('Failed to fetch popup forms:', error);
|
|
1930
1936
|
}
|
|
1931
1937
|
}
|
|
1932
1938
|
shouldShowForm(form) {
|
|
@@ -1937,7 +1943,7 @@ class PopupFormsPlugin extends BasePlugin {
|
|
|
1937
1943
|
}
|
|
1938
1944
|
else if (form.showFrequency === 'once_per_session') {
|
|
1939
1945
|
const sessionKey = `clianta_form_${form._id}_shown`;
|
|
1940
|
-
if (
|
|
1946
|
+
if (getSessionStorage(sessionKey))
|
|
1941
1947
|
return false;
|
|
1942
1948
|
}
|
|
1943
1949
|
return true;
|
|
@@ -2009,7 +2015,7 @@ class PopupFormsPlugin extends BasePlugin {
|
|
|
2009
2015
|
// Mark as shown
|
|
2010
2016
|
this.shownForms.add(form._id);
|
|
2011
2017
|
this.saveShownForms();
|
|
2012
|
-
|
|
2018
|
+
setSessionStorage(`clianta_form_${form._id}_shown`, 'true');
|
|
2013
2019
|
// Track view
|
|
2014
2020
|
await this.trackFormView(form._id);
|
|
2015
2021
|
// Render form
|
|
@@ -2325,17 +2331,17 @@ class PopupFormsPlugin extends BasePlugin {
|
|
|
2325
2331
|
const redirect = new URL(form.redirectUrl, window.location.origin);
|
|
2326
2332
|
const isSameOrigin = redirect.origin === window.location.origin;
|
|
2327
2333
|
const isSafeProtocol = redirect.protocol === 'https:' || redirect.protocol === 'http:';
|
|
2328
|
-
if (isSameOrigin
|
|
2334
|
+
if (isSameOrigin && isSafeProtocol) {
|
|
2329
2335
|
setTimeout(() => {
|
|
2330
2336
|
window.location.href = redirect.href;
|
|
2331
2337
|
}, 1500);
|
|
2332
2338
|
}
|
|
2333
2339
|
else {
|
|
2334
|
-
|
|
2340
|
+
logger.warn('Blocked unsafe redirect URL:', form.redirectUrl);
|
|
2335
2341
|
}
|
|
2336
2342
|
}
|
|
2337
2343
|
catch {
|
|
2338
|
-
|
|
2344
|
+
logger.warn('Invalid redirect URL:', form.redirectUrl);
|
|
2339
2345
|
}
|
|
2340
2346
|
}
|
|
2341
2347
|
// Close after delay
|
|
@@ -2348,7 +2354,7 @@ class PopupFormsPlugin extends BasePlugin {
|
|
|
2348
2354
|
}
|
|
2349
2355
|
}
|
|
2350
2356
|
catch (error) {
|
|
2351
|
-
|
|
2357
|
+
logger.error('Form submit error:', error);
|
|
2352
2358
|
if (submitBtn) {
|
|
2353
2359
|
submitBtn.disabled = false;
|
|
2354
2360
|
submitBtn.textContent = form.submitButtonText || 'Subscribe';
|
|
@@ -2419,7 +2425,7 @@ const STORAGE_KEY_PATTERNS = [
|
|
|
2419
2425
|
'token', 'jwt', 'auth', 'user', 'session', 'credential', 'account',
|
|
2420
2426
|
];
|
|
2421
2427
|
/** JWT/user object fields containing email */
|
|
2422
|
-
const EMAIL_CLAIMS = ['email', '
|
|
2428
|
+
const EMAIL_CLAIMS = ['email', 'preferred_username', 'user_email', 'mail', 'emailAddress', 'e_mail'];
|
|
2423
2429
|
/** Full name fields */
|
|
2424
2430
|
const NAME_CLAIMS = ['name', 'full_name', 'display_name', 'displayName'];
|
|
2425
2431
|
/** First name fields */
|
|
@@ -3363,6 +3369,7 @@ class Tracker {
|
|
|
3363
3369
|
this.queue = new EventQueue(this.transport, {
|
|
3364
3370
|
batchSize: this.config.batchSize,
|
|
3365
3371
|
flushInterval: this.config.flushInterval,
|
|
3372
|
+
persistMode: this.config.persistMode,
|
|
3366
3373
|
});
|
|
3367
3374
|
// Get or create visitor and session IDs based on mode
|
|
3368
3375
|
this.visitorId = this.createVisitorId();
|
|
@@ -3479,10 +3486,13 @@ class Tracker {
|
|
|
3479
3486
|
logger.warn('SDK not initialized, event dropped');
|
|
3480
3487
|
return;
|
|
3481
3488
|
}
|
|
3489
|
+
const utmParams = getUTMParams();
|
|
3482
3490
|
const event = {
|
|
3483
3491
|
workspaceId: this.workspaceId,
|
|
3484
3492
|
visitorId: this.visitorId,
|
|
3485
3493
|
sessionId: this.sessionId,
|
|
3494
|
+
contactId: this.contactId ?? undefined,
|
|
3495
|
+
groupId: this.groupId ?? undefined,
|
|
3486
3496
|
eventType: eventType,
|
|
3487
3497
|
eventName,
|
|
3488
3498
|
url: typeof window !== 'undefined' ? window.location.href : '',
|
|
@@ -3493,18 +3503,14 @@ class Tracker {
|
|
|
3493
3503
|
websiteDomain: typeof window !== 'undefined' ? window.location.hostname : undefined,
|
|
3494
3504
|
},
|
|
3495
3505
|
device: getDeviceInfo(),
|
|
3496
|
-
|
|
3506
|
+
utmSource: utmParams.utmSource,
|
|
3507
|
+
utmMedium: utmParams.utmMedium,
|
|
3508
|
+
utmCampaign: utmParams.utmCampaign,
|
|
3509
|
+
utmTerm: utmParams.utmTerm,
|
|
3510
|
+
utmContent: utmParams.utmContent,
|
|
3497
3511
|
timestamp: new Date().toISOString(),
|
|
3498
3512
|
sdkVersion: SDK_VERSION,
|
|
3499
3513
|
};
|
|
3500
|
-
// Attach contactId if known (from a prior identify() call)
|
|
3501
|
-
if (this.contactId) {
|
|
3502
|
-
event.contactId = this.contactId;
|
|
3503
|
-
}
|
|
3504
|
-
// Attach groupId if known (from a prior group() call)
|
|
3505
|
-
if (this.groupId) {
|
|
3506
|
-
event.groupId = this.groupId;
|
|
3507
|
-
}
|
|
3508
3514
|
// Validate event against registered schema (debug mode only)
|
|
3509
3515
|
this.validateEventSchema(eventType, properties);
|
|
3510
3516
|
// Check consent before tracking
|