@journium/js 1.1.0 → 1.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 +49 -5
- package/dist/JourniumAnalytics.d.ts +0 -1
- package/dist/JourniumAnalytics.d.ts.map +1 -1
- package/dist/JourniumClient.d.ts +9 -1
- package/dist/JourniumClient.d.ts.map +1 -1
- package/dist/PageviewTracker.d.ts +3 -2
- package/dist/PageviewTracker.d.ts.map +1 -1
- package/dist/cdn.d.ts +40 -0
- package/dist/cdn.d.ts.map +1 -0
- package/dist/index.cjs +135 -135
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +13 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +136 -135
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +136 -136
- package/dist/index.umd.js.map +1 -1
- package/dist/journium.js +1892 -0
- package/dist/journium.js.map +1 -0
- package/dist/journium.min.js +2 -0
- package/dist/journium.min.js.map +1 -0
- package/package.json +10 -5
package/dist/index.umd.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
2
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
3
|
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.journium = {}));
|
|
5
5
|
})(this, (function (exports) { 'use strict';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -452,9 +452,9 @@
|
|
|
452
452
|
'Content-Type': 'application/json',
|
|
453
453
|
},
|
|
454
454
|
});
|
|
455
|
-
if (!response.ok) {
|
|
456
|
-
|
|
457
|
-
}
|
|
455
|
+
// if (!response.ok) {
|
|
456
|
+
// throw new Error(`Options fetch failed: ${response.status} ${response.statusText}`);
|
|
457
|
+
// }
|
|
458
458
|
const data = await response.json();
|
|
459
459
|
return data;
|
|
460
460
|
}
|
|
@@ -707,20 +707,19 @@
|
|
|
707
707
|
this.queue = [];
|
|
708
708
|
this.stagedEvents = [];
|
|
709
709
|
this.flushTimer = null;
|
|
710
|
+
this.remoteOptionsRefreshTimer = null;
|
|
711
|
+
this.isRefreshing = false;
|
|
712
|
+
this.lastRemoteOptions = null;
|
|
710
713
|
this.initializationComplete = false;
|
|
711
714
|
this.initializationFailed = false;
|
|
712
|
-
this.disabled = false;
|
|
713
715
|
this.optionsChangeCallbacks = new Set();
|
|
714
|
-
// Validate required configuration
|
|
716
|
+
// Validate required configuration
|
|
715
717
|
if (!config.publishableKey || config.publishableKey.trim() === '') {
|
|
716
|
-
|
|
718
|
+
// Reject initialization with clear error
|
|
719
|
+
const errorMsg = 'Journium: publishableKey is required but not provided or is empty. SDK cannot be initialized.';
|
|
717
720
|
Logger.setDebug(true);
|
|
718
|
-
Logger.error(
|
|
719
|
-
|
|
720
|
-
this.config = { publishableKey: '', apiHost: 'https://events.journium.app' };
|
|
721
|
-
this.effectiveOptions = { debug: true };
|
|
722
|
-
this.optionsStorageKey = 'jrnm_invalid_options';
|
|
723
|
-
return;
|
|
721
|
+
Logger.error(errorMsg);
|
|
722
|
+
throw new Error(errorMsg);
|
|
724
723
|
}
|
|
725
724
|
// Set default apiHost if not provided
|
|
726
725
|
this.config = {
|
|
@@ -764,62 +763,24 @@
|
|
|
764
763
|
}
|
|
765
764
|
}
|
|
766
765
|
async initializeAsync() {
|
|
767
|
-
var _a;
|
|
768
766
|
try {
|
|
769
767
|
Logger.log('Journium: Starting initialization - fetching fresh remote config...');
|
|
770
|
-
// Step 1: Try to fetch fresh remote config with timeout and retry
|
|
771
768
|
const remoteOptions = await this.fetchRemoteOptionsWithRetry();
|
|
772
|
-
if (remoteOptions) {
|
|
773
|
-
|
|
774
|
-
this.
|
|
775
|
-
|
|
776
|
-
if (this.config.options) {
|
|
777
|
-
this.effectiveOptions = mergeOptions(this.config.options, remoteOptions);
|
|
778
|
-
Logger.log('Journium: Using fresh remote config merged with local options:', this.effectiveOptions);
|
|
779
|
-
}
|
|
780
|
-
else {
|
|
781
|
-
this.effectiveOptions = remoteOptions;
|
|
782
|
-
Logger.log('Journium: Using fresh remote config:', this.effectiveOptions);
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
else {
|
|
786
|
-
// Step 4: Fallback to cached config if fresh fetch failed
|
|
787
|
-
const cachedRemoteOptions = this.loadCachedOptions();
|
|
788
|
-
if (cachedRemoteOptions) {
|
|
789
|
-
if (this.config.options) {
|
|
790
|
-
this.effectiveOptions = mergeOptions(this.config.options, cachedRemoteOptions);
|
|
791
|
-
Logger.log('Journium: Fresh config failed, using cached remote config merged with local options:', this.effectiveOptions);
|
|
792
|
-
}
|
|
793
|
-
else {
|
|
794
|
-
this.effectiveOptions = cachedRemoteOptions;
|
|
795
|
-
Logger.log('Journium: Fresh config failed, using cached remote config:', this.effectiveOptions);
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
else {
|
|
799
|
-
// Step 5: No remote config and no cached config - initialization fails
|
|
800
|
-
Logger.error('Journium: Initialization failed - no remote config available and no cached config found');
|
|
801
|
-
this.initializationFailed = true;
|
|
802
|
-
this.initializationComplete = false;
|
|
803
|
-
return;
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
// Step 6: Update identity manager session timeout if provided
|
|
807
|
-
if (this.effectiveOptions.sessionTimeout) {
|
|
808
|
-
this.identityManager.updateSessionTimeout(this.effectiveOptions.sessionTimeout);
|
|
769
|
+
if (!remoteOptions) {
|
|
770
|
+
Logger.error('Journium: Initialization failed - no remote config available');
|
|
771
|
+
this.initializationFailed = true;
|
|
772
|
+
return;
|
|
809
773
|
}
|
|
810
|
-
|
|
811
|
-
Logger.
|
|
812
|
-
// Step 8: Mark initialization as complete
|
|
774
|
+
this.applyRemoteOptions(remoteOptions);
|
|
775
|
+
Logger.log('Journium: Effective options after init:', this.effectiveOptions);
|
|
813
776
|
this.initializationComplete = true;
|
|
814
777
|
this.initializationFailed = false;
|
|
815
|
-
// Step 9: Process any staged events
|
|
816
778
|
this.processStagedEvents();
|
|
817
|
-
// Step 10: Start flush timer
|
|
818
779
|
if (this.effectiveOptions.flushInterval && this.effectiveOptions.flushInterval > 0) {
|
|
819
780
|
this.startFlushTimer();
|
|
820
781
|
}
|
|
821
|
-
|
|
822
|
-
|
|
782
|
+
this.startRemoteOptionsRefreshTimer();
|
|
783
|
+
Logger.log('Journium: Initialization complete');
|
|
823
784
|
this.notifyOptionsChange();
|
|
824
785
|
}
|
|
825
786
|
catch (error) {
|
|
@@ -841,11 +802,15 @@
|
|
|
841
802
|
// Race fetch against timeout
|
|
842
803
|
const fetchPromise = fetchRemoteOptions(this.config.apiHost, this.config.publishableKey);
|
|
843
804
|
const remoteOptionsResponse = await Promise.race([fetchPromise, timeoutPromise]);
|
|
844
|
-
if (remoteOptionsResponse && remoteOptionsResponse.success) {
|
|
805
|
+
if (remoteOptionsResponse && remoteOptionsResponse.status === 'success') {
|
|
845
806
|
Logger.log('Journium: Successfully fetched fresh remote config:', remoteOptionsResponse.config);
|
|
846
|
-
return remoteOptionsResponse.config;
|
|
807
|
+
return remoteOptionsResponse.config || null;
|
|
847
808
|
}
|
|
848
|
-
else {
|
|
809
|
+
else if (remoteOptionsResponse && remoteOptionsResponse.status === 'error' && remoteOptionsResponse.errorCode === 'J_ERR_TENANT_NOT_FOUND') {
|
|
810
|
+
Logger.error('Journium: Invalid publishableKey is being used.');
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
{
|
|
849
814
|
throw new Error('Remote config fetch unsuccessful');
|
|
850
815
|
}
|
|
851
816
|
}
|
|
@@ -886,35 +851,21 @@
|
|
|
886
851
|
processStagedEvents() {
|
|
887
852
|
if (this.stagedEvents.length === 0)
|
|
888
853
|
return;
|
|
854
|
+
if (this.ingestionPaused) {
|
|
855
|
+
Logger.warn(`Journium: Ingestion is paused — discarding ${this.stagedEvents.length} staged events`);
|
|
856
|
+
this.stagedEvents = [];
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
889
859
|
Logger.log(`Journium: Processing ${this.stagedEvents.length} staged events`);
|
|
890
|
-
// Move staged events to main queue, adding identity properties now
|
|
891
|
-
const identity = this.identityManager.getIdentity();
|
|
892
|
-
const userAgentInfo = this.identityManager.getUserAgentInfo();
|
|
893
860
|
for (const stagedEvent of this.stagedEvents) {
|
|
894
|
-
|
|
895
|
-
const eventWithIdentity = {
|
|
861
|
+
this.queue.push({
|
|
896
862
|
...stagedEvent,
|
|
897
|
-
properties:
|
|
898
|
-
|
|
899
|
-
distinct_id: identity === null || identity === void 0 ? void 0 : identity.distinct_id,
|
|
900
|
-
$session_id: identity === null || identity === void 0 ? void 0 : identity.$session_id,
|
|
901
|
-
$is_identified: (identity === null || identity === void 0 ? void 0 : identity.$user_state) === 'identified',
|
|
902
|
-
$current_url: typeof window !== 'undefined' ? window.location.href : '',
|
|
903
|
-
$pathname: typeof window !== 'undefined' ? window.location.pathname : '',
|
|
904
|
-
...userAgentInfo,
|
|
905
|
-
$lib_version: '0.1.0', // TODO: Get from package.json
|
|
906
|
-
$platform: 'web',
|
|
907
|
-
...stagedEvent.properties, // Original properties override system properties
|
|
908
|
-
},
|
|
909
|
-
};
|
|
910
|
-
this.queue.push(eventWithIdentity);
|
|
863
|
+
properties: this.buildIdentityProperties(stagedEvent.properties),
|
|
864
|
+
});
|
|
911
865
|
}
|
|
912
|
-
// Clear staged events
|
|
913
866
|
this.stagedEvents = [];
|
|
914
867
|
Logger.log('Journium: Staged events processed and moved to main queue');
|
|
915
|
-
// Check if we should flush immediately
|
|
916
868
|
if (this.queue.length >= this.effectiveOptions.flushAt) {
|
|
917
|
-
// console.log('1 Journium: Flushing events...'+JSON.stringify(this.effectiveOptions));
|
|
918
869
|
this.flush();
|
|
919
870
|
}
|
|
920
871
|
}
|
|
@@ -922,12 +873,88 @@
|
|
|
922
873
|
if (this.flushTimer) {
|
|
923
874
|
clearInterval(this.flushTimer);
|
|
924
875
|
}
|
|
925
|
-
// Use universal setInterval (works in both browser and Node.js)
|
|
926
876
|
this.flushTimer = setInterval(() => {
|
|
927
|
-
// console.log('2 Journium: Flushing events...'+JSON.stringify(this.effectiveOptions));
|
|
928
877
|
this.flush();
|
|
929
878
|
}, this.effectiveOptions.flushInterval);
|
|
930
879
|
}
|
|
880
|
+
startRemoteOptionsRefreshTimer() {
|
|
881
|
+
// Clear any existing timer to prevent duplicate intervals
|
|
882
|
+
if (this.remoteOptionsRefreshTimer) {
|
|
883
|
+
clearInterval(this.remoteOptionsRefreshTimer);
|
|
884
|
+
this.remoteOptionsRefreshTimer = null;
|
|
885
|
+
}
|
|
886
|
+
this.remoteOptionsRefreshTimer = setInterval(() => {
|
|
887
|
+
this.refreshRemoteOptions();
|
|
888
|
+
}, JourniumClient.REMOTE_OPTIONS_REFRESH_INTERVAL);
|
|
889
|
+
Logger.log(`Journium: Scheduling remote options refresh every ${JourniumClient.REMOTE_OPTIONS_REFRESH_INTERVAL}ms`);
|
|
890
|
+
}
|
|
891
|
+
async refreshRemoteOptions() {
|
|
892
|
+
if (this.isRefreshing) {
|
|
893
|
+
Logger.log('Journium: Remote options refresh already in progress, skipping');
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
this.isRefreshing = true;
|
|
897
|
+
Logger.log('Journium: Periodic remote options refresh triggered');
|
|
898
|
+
try {
|
|
899
|
+
const remoteOptions = await this.fetchRemoteOptionsWithRetry();
|
|
900
|
+
if (!remoteOptions) {
|
|
901
|
+
Logger.warn('Journium: Periodic remote options refresh failed, keeping current options');
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
const prevRemoteSnapshot = JSON.stringify(this.lastRemoteOptions);
|
|
905
|
+
const prevFlushInterval = this.effectiveOptions.flushInterval;
|
|
906
|
+
this.applyRemoteOptions(remoteOptions);
|
|
907
|
+
if (prevRemoteSnapshot === JSON.stringify(this.lastRemoteOptions)) {
|
|
908
|
+
Logger.log('Journium: Remote options unchanged after refresh, no update needed');
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
Logger.log('Journium: Remote options updated after refresh:', this.effectiveOptions);
|
|
912
|
+
if (this.effectiveOptions.flushInterval !== prevFlushInterval) {
|
|
913
|
+
if (this.effectiveOptions.flushInterval && this.effectiveOptions.flushInterval > 0) {
|
|
914
|
+
this.startFlushTimer();
|
|
915
|
+
}
|
|
916
|
+
else if (this.flushTimer) {
|
|
917
|
+
clearInterval(this.flushTimer);
|
|
918
|
+
this.flushTimer = null;
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
this.notifyOptionsChange();
|
|
922
|
+
}
|
|
923
|
+
catch (error) {
|
|
924
|
+
Logger.error('Journium: Periodic remote options refresh encountered an error:', error);
|
|
925
|
+
}
|
|
926
|
+
finally {
|
|
927
|
+
this.isRefreshing = false;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
applyRemoteOptions(remoteOptions) {
|
|
931
|
+
var _a;
|
|
932
|
+
this.lastRemoteOptions = remoteOptions;
|
|
933
|
+
this.effectiveOptions = this.config.options
|
|
934
|
+
? mergeOptions(this.config.options, remoteOptions)
|
|
935
|
+
: remoteOptions;
|
|
936
|
+
this.saveCachedOptions(remoteOptions);
|
|
937
|
+
if (this.effectiveOptions.sessionTimeout) {
|
|
938
|
+
this.identityManager.updateSessionTimeout(this.effectiveOptions.sessionTimeout);
|
|
939
|
+
}
|
|
940
|
+
Logger.setDebug((_a = this.effectiveOptions.debug) !== null && _a !== void 0 ? _a : false);
|
|
941
|
+
}
|
|
942
|
+
buildIdentityProperties(userProperties = {}) {
|
|
943
|
+
const identity = this.identityManager.getIdentity();
|
|
944
|
+
const userAgentInfo = this.identityManager.getUserAgentInfo();
|
|
945
|
+
return {
|
|
946
|
+
$device_id: identity === null || identity === void 0 ? void 0 : identity.$device_id,
|
|
947
|
+
distinct_id: identity === null || identity === void 0 ? void 0 : identity.distinct_id,
|
|
948
|
+
$session_id: identity === null || identity === void 0 ? void 0 : identity.$session_id,
|
|
949
|
+
$is_identified: (identity === null || identity === void 0 ? void 0 : identity.$user_state) === 'identified',
|
|
950
|
+
$current_url: typeof window !== 'undefined' ? window.location.href : '',
|
|
951
|
+
$pathname: typeof window !== 'undefined' ? window.location.pathname : '',
|
|
952
|
+
...userAgentInfo,
|
|
953
|
+
$lib_version: '0.1.0', // TODO: Get from package.json
|
|
954
|
+
$platform: 'web',
|
|
955
|
+
...userProperties,
|
|
956
|
+
};
|
|
957
|
+
}
|
|
931
958
|
async sendEvents(events) {
|
|
932
959
|
if (!events.length)
|
|
933
960
|
return;
|
|
@@ -953,11 +980,6 @@
|
|
|
953
980
|
}
|
|
954
981
|
}
|
|
955
982
|
identify(distinctId, attributes = {}) {
|
|
956
|
-
// Don't identify if SDK is not properly configured or disabled
|
|
957
|
-
if (this.disabled || !this.config || !this.config.publishableKey) {
|
|
958
|
-
Logger.warn('Journium: identify() call rejected - SDK not ready or disabled');
|
|
959
|
-
return;
|
|
960
|
-
}
|
|
961
983
|
// Don't identify if initialization failed
|
|
962
984
|
if (this.initializationFailed) {
|
|
963
985
|
Logger.warn('Journium: identify() call rejected - initialization failed');
|
|
@@ -974,11 +996,6 @@
|
|
|
974
996
|
Logger.log('Journium: User identified', { distinctId, attributes, previousDistinctId });
|
|
975
997
|
}
|
|
976
998
|
reset() {
|
|
977
|
-
// Don't reset if SDK is not properly configured or disabled
|
|
978
|
-
if (this.disabled || !this.config || !this.config.publishableKey) {
|
|
979
|
-
Logger.warn('Journium: reset() call rejected - SDK not ready or disabled');
|
|
980
|
-
return;
|
|
981
|
-
}
|
|
982
999
|
// Don't reset if initialization failed
|
|
983
1000
|
if (this.initializationFailed) {
|
|
984
1001
|
Logger.warn('Journium: reset() call rejected - initialization failed');
|
|
@@ -989,11 +1006,6 @@
|
|
|
989
1006
|
Logger.log('Journium: User identity reset');
|
|
990
1007
|
}
|
|
991
1008
|
track(event, properties = {}) {
|
|
992
|
-
// Don't track if SDK is not properly configured or disabled
|
|
993
|
-
if (this.disabled || !this.config || !this.config.publishableKey) {
|
|
994
|
-
Logger.warn('Journium: track() call rejected - SDK not ready or disabled');
|
|
995
|
-
return;
|
|
996
|
-
}
|
|
997
1009
|
// Create minimal event without identity properties (will be added later if staging)
|
|
998
1010
|
const journiumEvent = {
|
|
999
1011
|
uuid: generateUuidv7(),
|
|
@@ -1002,9 +1014,7 @@
|
|
|
1002
1014
|
event,
|
|
1003
1015
|
properties: { ...properties }, // Only user properties for now
|
|
1004
1016
|
};
|
|
1005
|
-
// Stage events during initialization, add to queue after initialization
|
|
1006
1017
|
if (!this.initializationComplete) {
|
|
1007
|
-
// If initialization failed, reject events
|
|
1008
1018
|
if (this.initializationFailed) {
|
|
1009
1019
|
Logger.warn('Journium: track() call rejected - initialization failed');
|
|
1010
1020
|
return;
|
|
@@ -1013,42 +1023,21 @@
|
|
|
1013
1023
|
Logger.log('Journium: Event staged during initialization', journiumEvent);
|
|
1014
1024
|
return;
|
|
1015
1025
|
}
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
Logger.warn('Journium: track() call rejected - initialization failed');
|
|
1026
|
+
if (this.ingestionPaused) {
|
|
1027
|
+
Logger.warn('Journium: Ingestion is paused — event dropped:', journiumEvent.event);
|
|
1019
1028
|
return;
|
|
1020
1029
|
}
|
|
1021
|
-
// Add identity properties for immediate events (after initialization)
|
|
1022
|
-
const identity = this.identityManager.getIdentity();
|
|
1023
|
-
const userAgentInfo = this.identityManager.getUserAgentInfo();
|
|
1024
1030
|
const eventWithIdentity = {
|
|
1025
1031
|
...journiumEvent,
|
|
1026
|
-
properties:
|
|
1027
|
-
$device_id: identity === null || identity === void 0 ? void 0 : identity.$device_id,
|
|
1028
|
-
distinct_id: identity === null || identity === void 0 ? void 0 : identity.distinct_id,
|
|
1029
|
-
$session_id: identity === null || identity === void 0 ? void 0 : identity.$session_id,
|
|
1030
|
-
$is_identified: (identity === null || identity === void 0 ? void 0 : identity.$user_state) === 'identified',
|
|
1031
|
-
$current_url: typeof window !== 'undefined' ? window.location.href : '',
|
|
1032
|
-
$pathname: typeof window !== 'undefined' ? window.location.pathname : '',
|
|
1033
|
-
...userAgentInfo,
|
|
1034
|
-
$lib_version: '0.1.0', // TODO: Get from package.json
|
|
1035
|
-
$platform: 'web',
|
|
1036
|
-
...properties, // User-provided properties override system properties
|
|
1037
|
-
},
|
|
1032
|
+
properties: this.buildIdentityProperties(properties),
|
|
1038
1033
|
};
|
|
1039
1034
|
this.queue.push(eventWithIdentity);
|
|
1040
1035
|
Logger.log('Journium: Event tracked', eventWithIdentity);
|
|
1041
|
-
// Only flush if we have effective options (after initialization)
|
|
1042
1036
|
if (this.effectiveOptions.flushAt && this.queue.length >= this.effectiveOptions.flushAt) {
|
|
1043
|
-
// console.log('3 Journium: Flushing events...'+JSON.stringify(this.effectiveOptions));
|
|
1044
1037
|
this.flush();
|
|
1045
1038
|
}
|
|
1046
1039
|
}
|
|
1047
1040
|
async flush() {
|
|
1048
|
-
// Don't flush if SDK is not properly configured
|
|
1049
|
-
if (!this.config || !this.config.publishableKey) {
|
|
1050
|
-
return;
|
|
1051
|
-
}
|
|
1052
1041
|
// Don't flush if initialization failed
|
|
1053
1042
|
if (this.initializationFailed) {
|
|
1054
1043
|
Logger.warn('Journium: flush() call rejected - initialization failed');
|
|
@@ -1071,12 +1060,20 @@
|
|
|
1071
1060
|
clearInterval(this.flushTimer);
|
|
1072
1061
|
this.flushTimer = null;
|
|
1073
1062
|
}
|
|
1063
|
+
if (this.remoteOptionsRefreshTimer) {
|
|
1064
|
+
clearInterval(this.remoteOptionsRefreshTimer);
|
|
1065
|
+
this.remoteOptionsRefreshTimer = null;
|
|
1066
|
+
}
|
|
1074
1067
|
this.flush();
|
|
1075
1068
|
}
|
|
1076
1069
|
getEffectiveOptions() {
|
|
1077
1070
|
return this.effectiveOptions;
|
|
1078
1071
|
}
|
|
1072
|
+
get ingestionPaused() {
|
|
1073
|
+
return this.effectiveOptions['ingestionPaused'] === true;
|
|
1074
|
+
}
|
|
1079
1075
|
}
|
|
1076
|
+
JourniumClient.REMOTE_OPTIONS_REFRESH_INTERVAL = 15 * 60 * 1000; // 15 minutes
|
|
1080
1077
|
|
|
1081
1078
|
class PageviewTracker {
|
|
1082
1079
|
constructor(client) {
|
|
@@ -1103,10 +1100,13 @@
|
|
|
1103
1100
|
}
|
|
1104
1101
|
/**
|
|
1105
1102
|
* Start automatic autocapture for pageviews
|
|
1106
|
-
* @
|
|
1103
|
+
* @param captureInitialPageview - whether to fire a $pageview immediately on start (default: true).
|
|
1104
|
+
* Pass false when restarting after a remote options update to avoid a spurious pageview.
|
|
1107
1105
|
*/
|
|
1108
|
-
startAutoPageviewTracking() {
|
|
1109
|
-
|
|
1106
|
+
startAutoPageviewTracking(captureInitialPageview = true) {
|
|
1107
|
+
if (captureInitialPageview) {
|
|
1108
|
+
this.capturePageview();
|
|
1109
|
+
}
|
|
1110
1110
|
if (typeof window !== 'undefined') {
|
|
1111
1111
|
// Store original methods for cleanup
|
|
1112
1112
|
this.originalPushState = window.history.pushState;
|
|
@@ -1625,21 +1625,22 @@
|
|
|
1625
1625
|
* Handle effective options change (e.g., when remote options are fetched)
|
|
1626
1626
|
*/
|
|
1627
1627
|
handleOptionsChange(effectiveOptions) {
|
|
1628
|
-
//
|
|
1628
|
+
// If autocapture was never started before, this is the initial options application
|
|
1629
|
+
// (async init completed) — treat it like a page load and capture a pageview.
|
|
1630
|
+
// If it was already started, this is a periodic remote options update — only
|
|
1631
|
+
// re-register listeners without emitting a spurious pageview.
|
|
1632
|
+
const isFirstStart = !this.autocaptureStarted;
|
|
1629
1633
|
if (this.autocaptureStarted) {
|
|
1630
1634
|
this.pageviewTracker.stopAutocapture();
|
|
1631
1635
|
this.autocaptureTracker.stop();
|
|
1632
1636
|
this.autocaptureStarted = false;
|
|
1633
1637
|
}
|
|
1634
|
-
// Evaluate if autocapture should be enabled with new options
|
|
1635
1638
|
const autoTrackPageviews = effectiveOptions.autoTrackPageviews !== false;
|
|
1636
1639
|
const autocaptureEnabled = effectiveOptions.autocapture !== false;
|
|
1637
|
-
// Update autocapture tracker options
|
|
1638
1640
|
const autocaptureOptions = this.resolveAutocaptureOptions(effectiveOptions.autocapture);
|
|
1639
1641
|
this.autocaptureTracker.updateOptions(autocaptureOptions);
|
|
1640
|
-
// Start autocapture based on new options (even if it wasn't started before)
|
|
1641
1642
|
if (autoTrackPageviews) {
|
|
1642
|
-
this.pageviewTracker.startAutoPageviewTracking();
|
|
1643
|
+
this.pageviewTracker.startAutoPageviewTracking(isFirstStart);
|
|
1643
1644
|
}
|
|
1644
1645
|
if (autocaptureEnabled) {
|
|
1645
1646
|
this.autocaptureTracker.start();
|
|
@@ -1673,7 +1674,6 @@
|
|
|
1673
1674
|
|
|
1674
1675
|
exports.AutocaptureTracker = AutocaptureTracker;
|
|
1675
1676
|
exports.BrowserIdentityManager = BrowserIdentityManager;
|
|
1676
|
-
exports.JourniumAnalytics = JourniumAnalytics;
|
|
1677
1677
|
exports.JourniumClient = JourniumClient;
|
|
1678
1678
|
exports.Logger = Logger;
|
|
1679
1679
|
exports.PageviewTracker = PageviewTracker;
|