@journium/js 1.1.1 → 1.2.1
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/JourniumAnalytics.d.ts.map +1 -1
- package/dist/JourniumClient.d.ts +9 -0
- 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/index.cjs +136 -111
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +12 -2
- package/dist/index.mjs +136 -111
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +136 -111
- package/dist/index.umd.js.map +1 -1
- package/dist/journium.js +136 -111
- package/dist/journium.js.map +1 -1
- package/dist/journium.min.js +1 -1
- package/dist/journium.min.js.map +1 -1
- package/package.json +4 -4
package/dist/index.umd.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
/**
|
|
8
8
|
* uuidv7: A JavaScript implementation of UUID version 7
|
|
9
9
|
*
|
|
10
|
-
* Copyright 2021-
|
|
10
|
+
* Copyright 2021-2025 LiosK
|
|
11
11
|
*
|
|
12
12
|
* @license Apache-2.0
|
|
13
13
|
* @packageDocumentation
|
|
@@ -236,7 +236,10 @@
|
|
|
236
236
|
* number generator should be cryptographically strong and securely seeded.
|
|
237
237
|
*/
|
|
238
238
|
constructor(randomNumberGenerator) {
|
|
239
|
-
|
|
239
|
+
/**
|
|
240
|
+
* Biased by one to distinguish zero (uninitialized) and zero (UNIX epoch).
|
|
241
|
+
*/
|
|
242
|
+
this.timestamp_biased = 0;
|
|
240
243
|
this.counter = 0;
|
|
241
244
|
this.random = randomNumberGenerator !== null && randomNumberGenerator !== void 0 ? randomNumberGenerator : getDefaultRandom();
|
|
242
245
|
}
|
|
@@ -282,13 +285,13 @@
|
|
|
282
285
|
*
|
|
283
286
|
* @param rollbackAllowance - The amount of `unixTsMs` rollback that is
|
|
284
287
|
* considered significant. A suggested value is `10_000` (milliseconds).
|
|
285
|
-
* @throws RangeError if `unixTsMs` is not a 48-bit
|
|
288
|
+
* @throws RangeError if `unixTsMs` is not a 48-bit unsigned integer.
|
|
286
289
|
*/
|
|
287
290
|
generateOrResetCore(unixTsMs, rollbackAllowance) {
|
|
288
291
|
let value = this.generateOrAbortCore(unixTsMs, rollbackAllowance);
|
|
289
292
|
if (value === undefined) {
|
|
290
293
|
// reset state and resume
|
|
291
|
-
this.
|
|
294
|
+
this.timestamp_biased = 0;
|
|
292
295
|
value = this.generateOrAbortCore(unixTsMs, rollbackAllowance);
|
|
293
296
|
}
|
|
294
297
|
return value;
|
|
@@ -302,28 +305,29 @@
|
|
|
302
305
|
*
|
|
303
306
|
* @param rollbackAllowance - The amount of `unixTsMs` rollback that is
|
|
304
307
|
* considered significant. A suggested value is `10_000` (milliseconds).
|
|
305
|
-
* @throws RangeError if `unixTsMs` is not a 48-bit
|
|
308
|
+
* @throws RangeError if `unixTsMs` is not a 48-bit unsigned integer.
|
|
306
309
|
*/
|
|
307
310
|
generateOrAbortCore(unixTsMs, rollbackAllowance) {
|
|
308
311
|
const MAX_COUNTER = 4398046511103;
|
|
309
312
|
if (!Number.isInteger(unixTsMs) ||
|
|
310
|
-
unixTsMs <
|
|
313
|
+
unixTsMs < 0 ||
|
|
311
314
|
unixTsMs > 281474976710655) {
|
|
312
|
-
throw new RangeError("`unixTsMs` must be a 48-bit
|
|
315
|
+
throw new RangeError("`unixTsMs` must be a 48-bit unsigned integer");
|
|
313
316
|
}
|
|
314
317
|
else if (rollbackAllowance < 0 || rollbackAllowance > 281474976710655) {
|
|
315
318
|
throw new RangeError("`rollbackAllowance` out of reasonable range");
|
|
316
319
|
}
|
|
317
|
-
|
|
318
|
-
|
|
320
|
+
unixTsMs++;
|
|
321
|
+
if (unixTsMs > this.timestamp_biased) {
|
|
322
|
+
this.timestamp_biased = unixTsMs;
|
|
319
323
|
this.resetCounter();
|
|
320
324
|
}
|
|
321
|
-
else if (unixTsMs + rollbackAllowance >= this.
|
|
325
|
+
else if (unixTsMs + rollbackAllowance >= this.timestamp_biased) {
|
|
322
326
|
// go on with previous timestamp if new one is not much smaller
|
|
323
327
|
this.counter++;
|
|
324
328
|
if (this.counter > MAX_COUNTER) {
|
|
325
329
|
// increment timestamp at counter overflow
|
|
326
|
-
this.
|
|
330
|
+
this.timestamp_biased++;
|
|
327
331
|
this.resetCounter();
|
|
328
332
|
}
|
|
329
333
|
}
|
|
@@ -331,7 +335,7 @@
|
|
|
331
335
|
// abort if clock went backwards to unbearable extent
|
|
332
336
|
return undefined;
|
|
333
337
|
}
|
|
334
|
-
return UUID.fromFieldsV7(this.
|
|
338
|
+
return UUID.fromFieldsV7(this.timestamp_biased - 1, Math.trunc(this.counter / 2 ** 30), this.counter & (2 ** 30 - 1), this.random.nextUint32());
|
|
335
339
|
}
|
|
336
340
|
/** Initializes the counter at a 42-bit random integer. */
|
|
337
341
|
resetCounter() {
|
|
@@ -707,6 +711,9 @@
|
|
|
707
711
|
this.queue = [];
|
|
708
712
|
this.stagedEvents = [];
|
|
709
713
|
this.flushTimer = null;
|
|
714
|
+
this.remoteOptionsRefreshTimer = null;
|
|
715
|
+
this.isRefreshing = false;
|
|
716
|
+
this.lastRemoteOptions = null;
|
|
710
717
|
this.initializationComplete = false;
|
|
711
718
|
this.initializationFailed = false;
|
|
712
719
|
this.optionsChangeCallbacks = new Set();
|
|
@@ -760,61 +767,24 @@
|
|
|
760
767
|
}
|
|
761
768
|
}
|
|
762
769
|
async initializeAsync() {
|
|
763
|
-
var _a;
|
|
764
770
|
try {
|
|
765
771
|
Logger.log('Journium: Starting initialization - fetching fresh remote config...');
|
|
766
|
-
// Step 1: Try to fetch fresh remote config with timeout and retry
|
|
767
772
|
const remoteOptions = await this.fetchRemoteOptionsWithRetry();
|
|
768
|
-
if (remoteOptions) {
|
|
769
|
-
|
|
770
|
-
this.
|
|
771
|
-
|
|
772
|
-
if (this.config.options) {
|
|
773
|
-
this.effectiveOptions = mergeOptions(this.config.options, remoteOptions);
|
|
774
|
-
Logger.log('Journium: Using fresh remote config merged with local options:', this.effectiveOptions);
|
|
775
|
-
}
|
|
776
|
-
else {
|
|
777
|
-
this.effectiveOptions = remoteOptions;
|
|
778
|
-
Logger.log('Journium: Using fresh remote config:', this.effectiveOptions);
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
else {
|
|
782
|
-
// Step 4: Fallback to cached config if fresh fetch failed
|
|
783
|
-
/* const cachedRemoteOptions = this.loadCachedOptions();
|
|
784
|
-
|
|
785
|
-
if (cachedRemoteOptions) {
|
|
786
|
-
if (this.config.options) {
|
|
787
|
-
this.effectiveOptions = mergeOptions(this.config.options, cachedRemoteOptions);
|
|
788
|
-
Logger.log('Journium: Fresh config failed, using cached remote config merged with local options:', this.effectiveOptions);
|
|
789
|
-
} else {
|
|
790
|
-
this.effectiveOptions = cachedRemoteOptions;
|
|
791
|
-
Logger.log('Journium: Fresh config failed, using cached remote config:', this.effectiveOptions);
|
|
792
|
-
}
|
|
793
|
-
} else {
|
|
794
|
-
// Step 5: No remote config and no cached config - initialization fails
|
|
795
|
-
Logger.error('Journium: Initialization failed - no remote config available and no cached config found');
|
|
796
|
-
this.initializationFailed = true;
|
|
797
|
-
this.initializationComplete = false;
|
|
798
|
-
return;
|
|
799
|
-
} */
|
|
800
|
-
}
|
|
801
|
-
// Step 6: Update identity manager session timeout if provided
|
|
802
|
-
if (this.effectiveOptions.sessionTimeout) {
|
|
803
|
-
this.identityManager.updateSessionTimeout(this.effectiveOptions.sessionTimeout);
|
|
773
|
+
if (!remoteOptions) {
|
|
774
|
+
Logger.error('Journium: Initialization failed - no remote config available');
|
|
775
|
+
this.initializationFailed = true;
|
|
776
|
+
return;
|
|
804
777
|
}
|
|
805
|
-
|
|
806
|
-
Logger.
|
|
807
|
-
// Step 8: Mark initialization as complete
|
|
778
|
+
this.applyRemoteOptions(remoteOptions);
|
|
779
|
+
Logger.log('Journium: Effective options after init:', this.effectiveOptions);
|
|
808
780
|
this.initializationComplete = true;
|
|
809
781
|
this.initializationFailed = false;
|
|
810
|
-
// Step 9: Process any staged events
|
|
811
782
|
this.processStagedEvents();
|
|
812
|
-
// Step 10: Start flush timer
|
|
813
783
|
if (this.effectiveOptions.flushInterval && this.effectiveOptions.flushInterval > 0) {
|
|
814
784
|
this.startFlushTimer();
|
|
815
785
|
}
|
|
816
|
-
|
|
817
|
-
|
|
786
|
+
this.startRemoteOptionsRefreshTimer();
|
|
787
|
+
Logger.log('Journium: Initialization complete');
|
|
818
788
|
this.notifyOptionsChange();
|
|
819
789
|
}
|
|
820
790
|
catch (error) {
|
|
@@ -885,35 +855,21 @@
|
|
|
885
855
|
processStagedEvents() {
|
|
886
856
|
if (this.stagedEvents.length === 0)
|
|
887
857
|
return;
|
|
858
|
+
if (this.ingestionPaused) {
|
|
859
|
+
Logger.warn(`Journium: Ingestion is paused — discarding ${this.stagedEvents.length} staged events`);
|
|
860
|
+
this.stagedEvents = [];
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
888
863
|
Logger.log(`Journium: Processing ${this.stagedEvents.length} staged events`);
|
|
889
|
-
// Move staged events to main queue, adding identity properties now
|
|
890
|
-
const identity = this.identityManager.getIdentity();
|
|
891
|
-
const userAgentInfo = this.identityManager.getUserAgentInfo();
|
|
892
864
|
for (const stagedEvent of this.stagedEvents) {
|
|
893
|
-
|
|
894
|
-
const eventWithIdentity = {
|
|
865
|
+
this.queue.push({
|
|
895
866
|
...stagedEvent,
|
|
896
|
-
properties:
|
|
897
|
-
|
|
898
|
-
distinct_id: identity === null || identity === void 0 ? void 0 : identity.distinct_id,
|
|
899
|
-
$session_id: identity === null || identity === void 0 ? void 0 : identity.$session_id,
|
|
900
|
-
$is_identified: (identity === null || identity === void 0 ? void 0 : identity.$user_state) === 'identified',
|
|
901
|
-
$current_url: typeof window !== 'undefined' ? window.location.href : '',
|
|
902
|
-
$pathname: typeof window !== 'undefined' ? window.location.pathname : '',
|
|
903
|
-
...userAgentInfo,
|
|
904
|
-
$lib_version: '0.1.0', // TODO: Get from package.json
|
|
905
|
-
$platform: 'web',
|
|
906
|
-
...stagedEvent.properties, // Original properties override system properties
|
|
907
|
-
},
|
|
908
|
-
};
|
|
909
|
-
this.queue.push(eventWithIdentity);
|
|
867
|
+
properties: this.buildIdentityProperties(stagedEvent.properties),
|
|
868
|
+
});
|
|
910
869
|
}
|
|
911
|
-
// Clear staged events
|
|
912
870
|
this.stagedEvents = [];
|
|
913
871
|
Logger.log('Journium: Staged events processed and moved to main queue');
|
|
914
|
-
// Check if we should flush immediately
|
|
915
872
|
if (this.queue.length >= this.effectiveOptions.flushAt) {
|
|
916
|
-
// console.log('1 Journium: Flushing events...'+JSON.stringify(this.effectiveOptions));
|
|
917
873
|
this.flush();
|
|
918
874
|
}
|
|
919
875
|
}
|
|
@@ -921,12 +877,88 @@
|
|
|
921
877
|
if (this.flushTimer) {
|
|
922
878
|
clearInterval(this.flushTimer);
|
|
923
879
|
}
|
|
924
|
-
// Use universal setInterval (works in both browser and Node.js)
|
|
925
880
|
this.flushTimer = setInterval(() => {
|
|
926
|
-
// console.log('2 Journium: Flushing events...'+JSON.stringify(this.effectiveOptions));
|
|
927
881
|
this.flush();
|
|
928
882
|
}, this.effectiveOptions.flushInterval);
|
|
929
883
|
}
|
|
884
|
+
startRemoteOptionsRefreshTimer() {
|
|
885
|
+
// Clear any existing timer to prevent duplicate intervals
|
|
886
|
+
if (this.remoteOptionsRefreshTimer) {
|
|
887
|
+
clearInterval(this.remoteOptionsRefreshTimer);
|
|
888
|
+
this.remoteOptionsRefreshTimer = null;
|
|
889
|
+
}
|
|
890
|
+
this.remoteOptionsRefreshTimer = setInterval(() => {
|
|
891
|
+
this.refreshRemoteOptions();
|
|
892
|
+
}, JourniumClient.REMOTE_OPTIONS_REFRESH_INTERVAL);
|
|
893
|
+
Logger.log(`Journium: Scheduling remote options refresh every ${JourniumClient.REMOTE_OPTIONS_REFRESH_INTERVAL}ms`);
|
|
894
|
+
}
|
|
895
|
+
async refreshRemoteOptions() {
|
|
896
|
+
if (this.isRefreshing) {
|
|
897
|
+
Logger.log('Journium: Remote options refresh already in progress, skipping');
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
900
|
+
this.isRefreshing = true;
|
|
901
|
+
Logger.log('Journium: Periodic remote options refresh triggered');
|
|
902
|
+
try {
|
|
903
|
+
const remoteOptions = await this.fetchRemoteOptionsWithRetry();
|
|
904
|
+
if (!remoteOptions) {
|
|
905
|
+
Logger.warn('Journium: Periodic remote options refresh failed, keeping current options');
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
const prevRemoteSnapshot = JSON.stringify(this.lastRemoteOptions);
|
|
909
|
+
const prevFlushInterval = this.effectiveOptions.flushInterval;
|
|
910
|
+
this.applyRemoteOptions(remoteOptions);
|
|
911
|
+
if (prevRemoteSnapshot === JSON.stringify(this.lastRemoteOptions)) {
|
|
912
|
+
Logger.log('Journium: Remote options unchanged after refresh, no update needed');
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
Logger.log('Journium: Remote options updated after refresh:', this.effectiveOptions);
|
|
916
|
+
if (this.effectiveOptions.flushInterval !== prevFlushInterval) {
|
|
917
|
+
if (this.effectiveOptions.flushInterval && this.effectiveOptions.flushInterval > 0) {
|
|
918
|
+
this.startFlushTimer();
|
|
919
|
+
}
|
|
920
|
+
else if (this.flushTimer) {
|
|
921
|
+
clearInterval(this.flushTimer);
|
|
922
|
+
this.flushTimer = null;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
this.notifyOptionsChange();
|
|
926
|
+
}
|
|
927
|
+
catch (error) {
|
|
928
|
+
Logger.error('Journium: Periodic remote options refresh encountered an error:', error);
|
|
929
|
+
}
|
|
930
|
+
finally {
|
|
931
|
+
this.isRefreshing = false;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
applyRemoteOptions(remoteOptions) {
|
|
935
|
+
var _a;
|
|
936
|
+
this.lastRemoteOptions = remoteOptions;
|
|
937
|
+
this.effectiveOptions = this.config.options
|
|
938
|
+
? mergeOptions(this.config.options, remoteOptions)
|
|
939
|
+
: remoteOptions;
|
|
940
|
+
this.saveCachedOptions(remoteOptions);
|
|
941
|
+
if (this.effectiveOptions.sessionTimeout) {
|
|
942
|
+
this.identityManager.updateSessionTimeout(this.effectiveOptions.sessionTimeout);
|
|
943
|
+
}
|
|
944
|
+
Logger.setDebug((_a = this.effectiveOptions.debug) !== null && _a !== void 0 ? _a : false);
|
|
945
|
+
}
|
|
946
|
+
buildIdentityProperties(userProperties = {}) {
|
|
947
|
+
const identity = this.identityManager.getIdentity();
|
|
948
|
+
const userAgentInfo = this.identityManager.getUserAgentInfo();
|
|
949
|
+
return {
|
|
950
|
+
$device_id: identity === null || identity === void 0 ? void 0 : identity.$device_id,
|
|
951
|
+
distinct_id: identity === null || identity === void 0 ? void 0 : identity.distinct_id,
|
|
952
|
+
$session_id: identity === null || identity === void 0 ? void 0 : identity.$session_id,
|
|
953
|
+
$is_identified: (identity === null || identity === void 0 ? void 0 : identity.$user_state) === 'identified',
|
|
954
|
+
$current_url: typeof window !== 'undefined' ? window.location.href : '',
|
|
955
|
+
$pathname: typeof window !== 'undefined' ? window.location.pathname : '',
|
|
956
|
+
...userAgentInfo,
|
|
957
|
+
$lib_version: '0.1.0', // TODO: Get from package.json
|
|
958
|
+
$platform: 'web',
|
|
959
|
+
...userProperties,
|
|
960
|
+
};
|
|
961
|
+
}
|
|
930
962
|
async sendEvents(events) {
|
|
931
963
|
if (!events.length)
|
|
932
964
|
return;
|
|
@@ -986,9 +1018,7 @@
|
|
|
986
1018
|
event,
|
|
987
1019
|
properties: { ...properties }, // Only user properties for now
|
|
988
1020
|
};
|
|
989
|
-
// Stage events during initialization, add to queue after initialization
|
|
990
1021
|
if (!this.initializationComplete) {
|
|
991
|
-
// If initialization failed, reject events
|
|
992
1022
|
if (this.initializationFailed) {
|
|
993
1023
|
Logger.warn('Journium: track() call rejected - initialization failed');
|
|
994
1024
|
return;
|
|
@@ -997,34 +1027,17 @@
|
|
|
997
1027
|
Logger.log('Journium: Event staged during initialization', journiumEvent);
|
|
998
1028
|
return;
|
|
999
1029
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
Logger.warn('Journium: track() call rejected - initialization failed');
|
|
1030
|
+
if (this.ingestionPaused) {
|
|
1031
|
+
Logger.warn('Journium: Ingestion is paused — event dropped:', journiumEvent.event);
|
|
1003
1032
|
return;
|
|
1004
1033
|
}
|
|
1005
|
-
// Add identity properties for immediate events (after initialization)
|
|
1006
|
-
const identity = this.identityManager.getIdentity();
|
|
1007
|
-
const userAgentInfo = this.identityManager.getUserAgentInfo();
|
|
1008
1034
|
const eventWithIdentity = {
|
|
1009
1035
|
...journiumEvent,
|
|
1010
|
-
properties:
|
|
1011
|
-
$device_id: identity === null || identity === void 0 ? void 0 : identity.$device_id,
|
|
1012
|
-
distinct_id: identity === null || identity === void 0 ? void 0 : identity.distinct_id,
|
|
1013
|
-
$session_id: identity === null || identity === void 0 ? void 0 : identity.$session_id,
|
|
1014
|
-
$is_identified: (identity === null || identity === void 0 ? void 0 : identity.$user_state) === 'identified',
|
|
1015
|
-
$current_url: typeof window !== 'undefined' ? window.location.href : '',
|
|
1016
|
-
$pathname: typeof window !== 'undefined' ? window.location.pathname : '',
|
|
1017
|
-
...userAgentInfo,
|
|
1018
|
-
$lib_version: '0.1.0', // TODO: Get from package.json
|
|
1019
|
-
$platform: 'web',
|
|
1020
|
-
...properties, // User-provided properties override system properties
|
|
1021
|
-
},
|
|
1036
|
+
properties: this.buildIdentityProperties(properties),
|
|
1022
1037
|
};
|
|
1023
1038
|
this.queue.push(eventWithIdentity);
|
|
1024
1039
|
Logger.log('Journium: Event tracked', eventWithIdentity);
|
|
1025
|
-
// Only flush if we have effective options (after initialization)
|
|
1026
1040
|
if (this.effectiveOptions.flushAt && this.queue.length >= this.effectiveOptions.flushAt) {
|
|
1027
|
-
// console.log('3 Journium: Flushing events...'+JSON.stringify(this.effectiveOptions));
|
|
1028
1041
|
this.flush();
|
|
1029
1042
|
}
|
|
1030
1043
|
}
|
|
@@ -1051,12 +1064,20 @@
|
|
|
1051
1064
|
clearInterval(this.flushTimer);
|
|
1052
1065
|
this.flushTimer = null;
|
|
1053
1066
|
}
|
|
1067
|
+
if (this.remoteOptionsRefreshTimer) {
|
|
1068
|
+
clearInterval(this.remoteOptionsRefreshTimer);
|
|
1069
|
+
this.remoteOptionsRefreshTimer = null;
|
|
1070
|
+
}
|
|
1054
1071
|
this.flush();
|
|
1055
1072
|
}
|
|
1056
1073
|
getEffectiveOptions() {
|
|
1057
1074
|
return this.effectiveOptions;
|
|
1058
1075
|
}
|
|
1076
|
+
get ingestionPaused() {
|
|
1077
|
+
return this.effectiveOptions['ingestionPaused'] === true;
|
|
1078
|
+
}
|
|
1059
1079
|
}
|
|
1080
|
+
JourniumClient.REMOTE_OPTIONS_REFRESH_INTERVAL = 15 * 60 * 1000; // 15 minutes
|
|
1060
1081
|
|
|
1061
1082
|
class PageviewTracker {
|
|
1062
1083
|
constructor(client) {
|
|
@@ -1083,10 +1104,13 @@
|
|
|
1083
1104
|
}
|
|
1084
1105
|
/**
|
|
1085
1106
|
* Start automatic autocapture for pageviews
|
|
1086
|
-
* @
|
|
1107
|
+
* @param captureInitialPageview - whether to fire a $pageview immediately on start (default: true).
|
|
1108
|
+
* Pass false when restarting after a remote options update to avoid a spurious pageview.
|
|
1087
1109
|
*/
|
|
1088
|
-
startAutoPageviewTracking() {
|
|
1089
|
-
|
|
1110
|
+
startAutoPageviewTracking(captureInitialPageview = true) {
|
|
1111
|
+
if (captureInitialPageview) {
|
|
1112
|
+
this.capturePageview();
|
|
1113
|
+
}
|
|
1090
1114
|
if (typeof window !== 'undefined') {
|
|
1091
1115
|
// Store original methods for cleanup
|
|
1092
1116
|
this.originalPushState = window.history.pushState;
|
|
@@ -1605,21 +1629,22 @@
|
|
|
1605
1629
|
* Handle effective options change (e.g., when remote options are fetched)
|
|
1606
1630
|
*/
|
|
1607
1631
|
handleOptionsChange(effectiveOptions) {
|
|
1608
|
-
//
|
|
1632
|
+
// If autocapture was never started before, this is the initial options application
|
|
1633
|
+
// (async init completed) — treat it like a page load and capture a pageview.
|
|
1634
|
+
// If it was already started, this is a periodic remote options update — only
|
|
1635
|
+
// re-register listeners without emitting a spurious pageview.
|
|
1636
|
+
const isFirstStart = !this.autocaptureStarted;
|
|
1609
1637
|
if (this.autocaptureStarted) {
|
|
1610
1638
|
this.pageviewTracker.stopAutocapture();
|
|
1611
1639
|
this.autocaptureTracker.stop();
|
|
1612
1640
|
this.autocaptureStarted = false;
|
|
1613
1641
|
}
|
|
1614
|
-
// Evaluate if autocapture should be enabled with new options
|
|
1615
1642
|
const autoTrackPageviews = effectiveOptions.autoTrackPageviews !== false;
|
|
1616
1643
|
const autocaptureEnabled = effectiveOptions.autocapture !== false;
|
|
1617
|
-
// Update autocapture tracker options
|
|
1618
1644
|
const autocaptureOptions = this.resolveAutocaptureOptions(effectiveOptions.autocapture);
|
|
1619
1645
|
this.autocaptureTracker.updateOptions(autocaptureOptions);
|
|
1620
|
-
// Start autocapture based on new options (even if it wasn't started before)
|
|
1621
1646
|
if (autoTrackPageviews) {
|
|
1622
|
-
this.pageviewTracker.startAutoPageviewTracking();
|
|
1647
|
+
this.pageviewTracker.startAutoPageviewTracking(isFirstStart);
|
|
1623
1648
|
}
|
|
1624
1649
|
if (autocaptureEnabled) {
|
|
1625
1650
|
this.autocaptureTracker.start();
|