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