@journium/js 1.0.5 → 1.0.7
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/AutocaptureTracker.d.ts +4 -0
- package/dist/AutocaptureTracker.d.ts.map +1 -1
- package/dist/JourniumAnalytics.d.ts +12 -3
- package/dist/JourniumAnalytics.d.ts.map +1 -1
- package/dist/JourniumClient.d.ts +6 -0
- package/dist/JourniumClient.d.ts.map +1 -1
- package/dist/index.cjs +168 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +21 -3
- package/dist/index.mjs +168 -62
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +168 -61
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
package/dist/index.umd.js
CHANGED
|
@@ -671,14 +671,47 @@
|
|
|
671
671
|
}
|
|
672
672
|
}
|
|
673
673
|
|
|
674
|
+
class Logger {
|
|
675
|
+
static setDebug(enabled) {
|
|
676
|
+
this.isDebugEnabled = enabled;
|
|
677
|
+
}
|
|
678
|
+
static isDebug() {
|
|
679
|
+
return this.isDebugEnabled;
|
|
680
|
+
}
|
|
681
|
+
static log(...args) {
|
|
682
|
+
if (this.isDebugEnabled) {
|
|
683
|
+
console.log(...args);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
static warn(...args) {
|
|
687
|
+
if (this.isDebugEnabled) {
|
|
688
|
+
console.warn(...args);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
static error(...args) {
|
|
692
|
+
if (this.isDebugEnabled) {
|
|
693
|
+
console.error(...args);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
static info(...args) {
|
|
697
|
+
if (this.isDebugEnabled) {
|
|
698
|
+
console.info(...args);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
Logger.isDebugEnabled = false;
|
|
703
|
+
|
|
674
704
|
class JourniumClient {
|
|
675
705
|
constructor(config) {
|
|
706
|
+
var _a;
|
|
676
707
|
this.queue = [];
|
|
677
708
|
this.flushTimer = null;
|
|
678
709
|
this.initialized = false;
|
|
710
|
+
this.optionsChangeCallbacks = new Set();
|
|
679
711
|
// Validate required configuration
|
|
680
712
|
if (!config.publishableKey) {
|
|
681
|
-
|
|
713
|
+
Logger.setDebug(true);
|
|
714
|
+
Logger.error('Journium: publishableKey is required but not provided. SDK will not function.');
|
|
682
715
|
return;
|
|
683
716
|
}
|
|
684
717
|
// Set default apiHost if not provided
|
|
@@ -700,6 +733,8 @@
|
|
|
700
733
|
if (this.config.options) {
|
|
701
734
|
this.effectiveOptions = mergeOptions(defaultOptions, this.config.options);
|
|
702
735
|
}
|
|
736
|
+
// Initialize Logger with debug setting
|
|
737
|
+
Logger.setDebug((_a = this.effectiveOptions.debug) !== null && _a !== void 0 ? _a : false);
|
|
703
738
|
// Initialize identity manager
|
|
704
739
|
this.identityManager = new BrowserIdentityManager(this.effectiveOptions.sessionTimeout, this.config.publishableKey);
|
|
705
740
|
// Initialize synchronously with cached config, fetch fresh config in background
|
|
@@ -707,7 +742,6 @@
|
|
|
707
742
|
this.fetchRemoteOptionsAsync();
|
|
708
743
|
}
|
|
709
744
|
loadCachedOptions() {
|
|
710
|
-
var _a;
|
|
711
745
|
if (typeof window === 'undefined' || !window.localStorage) {
|
|
712
746
|
return null;
|
|
713
747
|
}
|
|
@@ -716,14 +750,11 @@
|
|
|
716
750
|
return cached ? JSON.parse(cached) : null;
|
|
717
751
|
}
|
|
718
752
|
catch (error) {
|
|
719
|
-
|
|
720
|
-
console.warn('Journium: Failed to load cached config:', error);
|
|
721
|
-
}
|
|
753
|
+
Logger.warn('Journium: Failed to load cached config:', error);
|
|
722
754
|
return null;
|
|
723
755
|
}
|
|
724
756
|
}
|
|
725
757
|
saveCachedOptions(options) {
|
|
726
|
-
var _a;
|
|
727
758
|
if (typeof window === 'undefined' || !window.localStorage) {
|
|
728
759
|
return;
|
|
729
760
|
}
|
|
@@ -731,30 +762,34 @@
|
|
|
731
762
|
window.localStorage.setItem(this.optionsStorageKey, JSON.stringify(options));
|
|
732
763
|
}
|
|
733
764
|
catch (error) {
|
|
734
|
-
|
|
735
|
-
console.warn('Journium: Failed to save config to cache:', error);
|
|
736
|
-
}
|
|
765
|
+
Logger.warn('Journium: Failed to save config to cache:', error);
|
|
737
766
|
}
|
|
738
767
|
}
|
|
739
768
|
initializeSync() {
|
|
740
769
|
// Step 1: Load cached remote options from localStorage (synchronous)
|
|
741
770
|
const cachedRemoteOptions = this.loadCachedOptions();
|
|
742
|
-
// Step 2:
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
if (this.
|
|
746
|
-
|
|
771
|
+
// Step 2: Merge cached remote options with local options (if cached options exist)
|
|
772
|
+
// Local options take precedence over cached remote options
|
|
773
|
+
if (cachedRemoteOptions) {
|
|
774
|
+
if (this.config.options) {
|
|
775
|
+
// Merge: local options override cached remote options
|
|
776
|
+
this.effectiveOptions = mergeOptions(cachedRemoteOptions, this.config.options);
|
|
777
|
+
Logger.log('Journium: Using cached remote options merged with local options:', this.effectiveOptions);
|
|
778
|
+
}
|
|
779
|
+
else {
|
|
780
|
+
// No local options, use cached remote options as-is
|
|
781
|
+
this.effectiveOptions = cachedRemoteOptions;
|
|
782
|
+
Logger.log('Journium: Using cached remote options:', cachedRemoteOptions);
|
|
747
783
|
}
|
|
748
784
|
}
|
|
785
|
+
// If no cached options, effectiveOptions already has defaults merged with local options from constructor
|
|
749
786
|
// Step 3: Mark as initialized immediately - no need to wait for remote fetch
|
|
750
787
|
this.initialized = true;
|
|
751
788
|
// Step 4: Start flush timer immediately
|
|
752
789
|
if (this.effectiveOptions.flushInterval && this.effectiveOptions.flushInterval > 0) {
|
|
753
790
|
this.startFlushTimer();
|
|
754
791
|
}
|
|
755
|
-
|
|
756
|
-
console.log('Journium: Client initialized with effective options:', this.effectiveOptions);
|
|
757
|
-
}
|
|
792
|
+
Logger.log('Journium: Client initialized with effective options:', this.effectiveOptions);
|
|
758
793
|
}
|
|
759
794
|
async fetchRemoteOptionsAsync() {
|
|
760
795
|
// Fetch fresh config in background
|
|
@@ -763,10 +798,9 @@
|
|
|
763
798
|
}
|
|
764
799
|
}
|
|
765
800
|
async fetchAndCacheRemoteOptions() {
|
|
801
|
+
var _a;
|
|
766
802
|
try {
|
|
767
|
-
|
|
768
|
-
console.log('Journium: Fetching remote configuration in background...');
|
|
769
|
-
}
|
|
803
|
+
Logger.log('Journium: Fetching remote configuration in background...');
|
|
770
804
|
const remoteOptionsResponse = await fetchRemoteOptions(this.config.apiHost, this.config.publishableKey);
|
|
771
805
|
if (remoteOptionsResponse && remoteOptionsResponse.success) {
|
|
772
806
|
// Save remote config to cache for next session
|
|
@@ -784,18 +818,38 @@
|
|
|
784
818
|
if (this.effectiveOptions.sessionTimeout) {
|
|
785
819
|
this.identityManager.updateSessionTimeout(this.effectiveOptions.sessionTimeout);
|
|
786
820
|
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
821
|
+
Logger.log('Journium: Background remote options applied:', remoteOptionsResponse.config);
|
|
822
|
+
Logger.log('Journium: New effective options:', this.effectiveOptions);
|
|
823
|
+
// Update Logger debug setting with new options
|
|
824
|
+
Logger.setDebug((_a = this.effectiveOptions.debug) !== null && _a !== void 0 ? _a : false);
|
|
825
|
+
// Notify all registered callbacks about the options change
|
|
826
|
+
this.notifyOptionsChange();
|
|
791
827
|
}
|
|
792
828
|
}
|
|
793
829
|
catch (error) {
|
|
794
|
-
|
|
795
|
-
console.warn('Journium: Background remote options fetch failed:', error);
|
|
796
|
-
}
|
|
830
|
+
Logger.warn('Journium: Background remote options fetch failed:', error);
|
|
797
831
|
}
|
|
798
832
|
}
|
|
833
|
+
/**
|
|
834
|
+
* Register a callback to be notified when effective options change (e.g., when remote options are fetched)
|
|
835
|
+
*/
|
|
836
|
+
onOptionsChange(callback) {
|
|
837
|
+
this.optionsChangeCallbacks.add(callback);
|
|
838
|
+
// Return unsubscribe function
|
|
839
|
+
return () => {
|
|
840
|
+
this.optionsChangeCallbacks.delete(callback);
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
notifyOptionsChange() {
|
|
844
|
+
this.optionsChangeCallbacks.forEach(callback => {
|
|
845
|
+
try {
|
|
846
|
+
callback(this.effectiveOptions);
|
|
847
|
+
}
|
|
848
|
+
catch (error) {
|
|
849
|
+
Logger.warn('Journium: Error in options change callback:', error);
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
}
|
|
799
853
|
startFlushTimer() {
|
|
800
854
|
if (this.flushTimer) {
|
|
801
855
|
clearInterval(this.flushTimer);
|
|
@@ -822,24 +876,17 @@
|
|
|
822
876
|
if (!response.ok) {
|
|
823
877
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
824
878
|
}
|
|
825
|
-
|
|
826
|
-
console.log('Journium: Successfully sent events', events);
|
|
827
|
-
}
|
|
879
|
+
Logger.log('Journium: Successfully sent events', events);
|
|
828
880
|
}
|
|
829
881
|
catch (error) {
|
|
830
|
-
|
|
831
|
-
console.error('Journium: Failed to send events', error);
|
|
832
|
-
}
|
|
882
|
+
Logger.error('Journium: Failed to send events', error);
|
|
833
883
|
throw error;
|
|
834
884
|
}
|
|
835
885
|
}
|
|
836
886
|
identify(distinctId, attributes = {}) {
|
|
837
|
-
var _a;
|
|
838
887
|
// Don't identify if SDK is not properly configured
|
|
839
888
|
if (!this.config || !this.config.publishableKey || !this.initialized) {
|
|
840
|
-
|
|
841
|
-
console.warn('Journium: identify() call rejected - SDK not ready');
|
|
842
|
-
}
|
|
889
|
+
Logger.warn('Journium: identify() call rejected - SDK not ready');
|
|
843
890
|
return;
|
|
844
891
|
}
|
|
845
892
|
// Call identify on identity manager to get previous distinct ID
|
|
@@ -850,32 +897,22 @@
|
|
|
850
897
|
$anon_distinct_id: previousDistinctId,
|
|
851
898
|
};
|
|
852
899
|
this.track('$identify', identifyProperties);
|
|
853
|
-
|
|
854
|
-
console.log('Journium: User identified', { distinctId, attributes, previousDistinctId });
|
|
855
|
-
}
|
|
900
|
+
Logger.log('Journium: User identified', { distinctId, attributes, previousDistinctId });
|
|
856
901
|
}
|
|
857
902
|
reset() {
|
|
858
|
-
var _a;
|
|
859
903
|
// Don't reset if SDK is not properly configured
|
|
860
904
|
if (!this.config || !this.config.publishableKey || !this.initialized) {
|
|
861
|
-
|
|
862
|
-
console.warn('Journium: reset() call rejected - SDK not ready');
|
|
863
|
-
}
|
|
905
|
+
Logger.warn('Journium: reset() call rejected - SDK not ready');
|
|
864
906
|
return;
|
|
865
907
|
}
|
|
866
908
|
// Reset identity in identity manager
|
|
867
909
|
this.identityManager.reset();
|
|
868
|
-
|
|
869
|
-
console.log('Journium: User identity reset');
|
|
870
|
-
}
|
|
910
|
+
Logger.log('Journium: User identity reset');
|
|
871
911
|
}
|
|
872
912
|
track(event, properties = {}) {
|
|
873
|
-
var _a;
|
|
874
913
|
// Don't track if SDK is not properly configured
|
|
875
914
|
if (!this.config || !this.config.publishableKey || !this.initialized) {
|
|
876
|
-
|
|
877
|
-
console.warn('Journium: track() call rejected - SDK not ready');
|
|
878
|
-
}
|
|
915
|
+
Logger.warn('Journium: track() call rejected - SDK not ready');
|
|
879
916
|
return;
|
|
880
917
|
}
|
|
881
918
|
const identity = this.identityManager.getIdentity();
|
|
@@ -901,9 +938,7 @@
|
|
|
901
938
|
properties: eventProperties,
|
|
902
939
|
};
|
|
903
940
|
this.queue.push(journiumEvent);
|
|
904
|
-
|
|
905
|
-
console.log('Journium: Event tracked', journiumEvent);
|
|
906
|
-
}
|
|
941
|
+
Logger.log('Journium: Event tracked', journiumEvent);
|
|
907
942
|
if (this.queue.length >= this.effectiveOptions.flushAt) {
|
|
908
943
|
this.flush();
|
|
909
944
|
}
|
|
@@ -1026,6 +1061,31 @@
|
|
|
1026
1061
|
...options,
|
|
1027
1062
|
};
|
|
1028
1063
|
}
|
|
1064
|
+
/**
|
|
1065
|
+
* Update autocapture options and restart if currently active
|
|
1066
|
+
*/
|
|
1067
|
+
updateOptions(options) {
|
|
1068
|
+
const wasActive = this.isActive;
|
|
1069
|
+
// Stop if currently active
|
|
1070
|
+
if (wasActive) {
|
|
1071
|
+
this.stop();
|
|
1072
|
+
}
|
|
1073
|
+
// Update options
|
|
1074
|
+
this.options = {
|
|
1075
|
+
captureClicks: true,
|
|
1076
|
+
captureFormSubmits: true,
|
|
1077
|
+
captureFormChanges: true,
|
|
1078
|
+
captureTextSelection: false,
|
|
1079
|
+
ignoreClasses: ['journium-ignore'],
|
|
1080
|
+
ignoreElements: ['script', 'style', 'noscript'],
|
|
1081
|
+
captureContentText: true,
|
|
1082
|
+
...options,
|
|
1083
|
+
};
|
|
1084
|
+
// Restart if it was active before
|
|
1085
|
+
if (wasActive) {
|
|
1086
|
+
this.start();
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1029
1089
|
start() {
|
|
1030
1090
|
if (!isBrowser() || this.isActive) {
|
|
1031
1091
|
return;
|
|
@@ -1355,14 +1415,19 @@
|
|
|
1355
1415
|
|
|
1356
1416
|
class JourniumAnalytics {
|
|
1357
1417
|
constructor(config) {
|
|
1358
|
-
|
|
1418
|
+
this.autocaptureStarted = false;
|
|
1359
1419
|
this.config = config;
|
|
1360
1420
|
this.client = new JourniumClient(config);
|
|
1361
1421
|
this.pageviewTracker = new PageviewTracker(this.client);
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1422
|
+
// Initialize autocapture tracker with effective options (may include cached remote options)
|
|
1423
|
+
// This ensures we use the correct initial state even if cached remote options exist
|
|
1424
|
+
const initialEffectiveOptions = this.client.getEffectiveOptions();
|
|
1425
|
+
const initialAutocaptureOptions = this.resolveAutocaptureOptions(initialEffectiveOptions.autocapture);
|
|
1426
|
+
this.autocaptureTracker = new AutocaptureTracker(this.client, initialAutocaptureOptions);
|
|
1427
|
+
// Listen for options changes (e.g., when fresh remote options are fetched)
|
|
1428
|
+
this.unsubscribeOptionsChange = this.client.onOptionsChange((effectiveOptions) => {
|
|
1429
|
+
this.handleOptionsChange(effectiveOptions);
|
|
1430
|
+
});
|
|
1366
1431
|
}
|
|
1367
1432
|
resolveAutocaptureOptions(autocapture) {
|
|
1368
1433
|
if (autocapture === false) {
|
|
@@ -1391,19 +1456,51 @@
|
|
|
1391
1456
|
this.pageviewTracker.capturePageview(properties);
|
|
1392
1457
|
}
|
|
1393
1458
|
startAutocapture() {
|
|
1394
|
-
//
|
|
1459
|
+
// Always check effective options (which may include remote options)
|
|
1395
1460
|
const effectiveOptions = this.client.getEffectiveOptions();
|
|
1396
1461
|
const autoTrackPageviews = effectiveOptions.autoTrackPageviews !== false;
|
|
1462
|
+
const autocaptureEnabled = effectiveOptions.autocapture !== false;
|
|
1463
|
+
// Update autocapture tracker options if they've changed
|
|
1464
|
+
const autocaptureOptions = this.resolveAutocaptureOptions(effectiveOptions.autocapture);
|
|
1465
|
+
this.autocaptureTracker.updateOptions(autocaptureOptions);
|
|
1397
1466
|
if (autoTrackPageviews) {
|
|
1398
1467
|
this.pageviewTracker.startAutocapture();
|
|
1399
1468
|
}
|
|
1400
|
-
if (
|
|
1469
|
+
if (autocaptureEnabled) {
|
|
1401
1470
|
this.autocaptureTracker.start();
|
|
1402
1471
|
}
|
|
1472
|
+
this.autocaptureStarted = true;
|
|
1403
1473
|
}
|
|
1404
1474
|
stopAutocapture() {
|
|
1405
1475
|
this.pageviewTracker.stopAutocapture();
|
|
1406
1476
|
this.autocaptureTracker.stop();
|
|
1477
|
+
this.autocaptureStarted = false;
|
|
1478
|
+
}
|
|
1479
|
+
/**
|
|
1480
|
+
* Handle effective options change (e.g., when remote options are fetched)
|
|
1481
|
+
*/
|
|
1482
|
+
handleOptionsChange(effectiveOptions) {
|
|
1483
|
+
// If autocapture was already started, re-evaluate with new options
|
|
1484
|
+
if (this.autocaptureStarted) {
|
|
1485
|
+
// Stop current autocapture
|
|
1486
|
+
this.pageviewTracker.stopAutocapture();
|
|
1487
|
+
this.autocaptureTracker.stop();
|
|
1488
|
+
this.autocaptureStarted = false;
|
|
1489
|
+
// Re-evaluate if autocapture should be enabled with new options
|
|
1490
|
+
const autoTrackPageviews = effectiveOptions.autoTrackPageviews !== false;
|
|
1491
|
+
const autocaptureEnabled = effectiveOptions.autocapture !== false;
|
|
1492
|
+
// Update autocapture tracker options
|
|
1493
|
+
const autocaptureOptions = this.resolveAutocaptureOptions(effectiveOptions.autocapture);
|
|
1494
|
+
this.autocaptureTracker.updateOptions(autocaptureOptions);
|
|
1495
|
+
// Restart only if still enabled
|
|
1496
|
+
if (autoTrackPageviews) {
|
|
1497
|
+
this.pageviewTracker.startAutocapture();
|
|
1498
|
+
}
|
|
1499
|
+
if (autocaptureEnabled) {
|
|
1500
|
+
this.autocaptureTracker.start();
|
|
1501
|
+
}
|
|
1502
|
+
this.autocaptureStarted = autoTrackPageviews || autocaptureEnabled;
|
|
1503
|
+
}
|
|
1407
1504
|
}
|
|
1408
1505
|
async flush() {
|
|
1409
1506
|
return this.client.flush();
|
|
@@ -1411,9 +1508,18 @@
|
|
|
1411
1508
|
getEffectiveOptions() {
|
|
1412
1509
|
return this.client.getEffectiveOptions();
|
|
1413
1510
|
}
|
|
1511
|
+
/**
|
|
1512
|
+
* Register a callback to be notified when effective options change
|
|
1513
|
+
*/
|
|
1514
|
+
onOptionsChange(callback) {
|
|
1515
|
+
return this.client.onOptionsChange(callback);
|
|
1516
|
+
}
|
|
1414
1517
|
destroy() {
|
|
1415
1518
|
this.pageviewTracker.stopAutocapture();
|
|
1416
1519
|
this.autocaptureTracker.stop();
|
|
1520
|
+
if (this.unsubscribeOptionsChange) {
|
|
1521
|
+
this.unsubscribeOptionsChange();
|
|
1522
|
+
}
|
|
1417
1523
|
this.client.destroy();
|
|
1418
1524
|
}
|
|
1419
1525
|
}
|
|
@@ -1425,6 +1531,7 @@
|
|
|
1425
1531
|
exports.BrowserIdentityManager = BrowserIdentityManager;
|
|
1426
1532
|
exports.JourniumAnalytics = JourniumAnalytics;
|
|
1427
1533
|
exports.JourniumClient = JourniumClient;
|
|
1534
|
+
exports.Logger = Logger;
|
|
1428
1535
|
exports.PageviewTracker = PageviewTracker;
|
|
1429
1536
|
exports.fetchRemoteOptions = fetchRemoteOptions;
|
|
1430
1537
|
exports.generateId = generateId;
|