@splitsoftware/splitio-commons 1.4.2-rc.4 → 1.5.1-rc.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/CHANGES.txt CHANGED
@@ -1,7 +1,11 @@
1
- 1.4.2 (June XX, 2022)
2
- - Added `sync.enabled` property to SDK configuration to allow synchronize splits and segments only once.
3
- - Updated telemetry to submit data even if user consent is not granted.
4
- - Updated submitters logic, to avoid duplicating the post of impressions to Split cloud when the SDK is destroyed while performing its periodic post of impressions.
1
+ 1.6.0 (July 7, 2022)
2
+ - Added `autoRequire` configuration option to the Google Analytics to Split integration (See https://help.split.io/hc/en-us/articles/360040838752#set-up-with-gtm-and-gtag.js).
3
+ - Updated browser listener to push remaining impressions and events on 'visibilitychange' and 'pagehide' DOM events, instead of 'unload', which is not reliable in mobile and modern Web browsers (See https://developer.chrome.com/blog/page-lifecycle-api/#legacy-lifecycle-apis-to-avoid).
4
+
5
+ 1.5.0 (June 29, 2022)
6
+ - Added a new config option to control the tasks that listen or poll for updates on feature flags and segments, via the new config sync.enabled . Running online Split will always pull the most recent updates upon initialization, this only affects updates fetching on a running instance. Useful when a consistent session experience is a must or to save resources when updates are not being used.
7
+ - Updated telemetry logic to track the anonymous config for user consent flag set to declined or unknown.
8
+ - Updated submitters logic, to avoid duplicating the post of impressions to Split cloud when the SDK is destroyed while its periodic post of impressions is running.
5
9
 
6
10
  1.4.1 (June 13, 2022)
7
11
  - Bugfixing - Updated submitters logic, to avoid dropping impressions and events that are being tracked while POST request is pending.
@@ -10,23 +10,24 @@ var logNameMapper = 'ga-to-split:mapper';
10
10
  /**
11
11
  * Provides a plugin to use with analytics.js, accounting for the possibility
12
12
  * that the global command queue has been renamed or not yet defined.
13
- * @param {string} pluginName The plugin name identifier.
14
- * @param {Function} pluginConstructor The plugin constructor function.
13
+ * @param window Reference to global object.
14
+ * @param pluginName The plugin name identifier.
15
+ * @param pluginConstructor The plugin constructor function.
16
+ * @param log Logger instance.
17
+ * @param autoRequire If true, log error when auto-require script is not detected
15
18
  */
16
- function providePlugin(pluginName, pluginConstructor) {
19
+ function providePlugin(window, pluginName, pluginConstructor, log, autoRequire) {
17
20
  // get reference to global command queue. Init it if not defined yet.
18
- // @ts-expect-error
19
21
  var gaAlias = window.GoogleAnalyticsObject || 'ga';
20
22
  window[gaAlias] = window[gaAlias] || function () {
21
- var args = [];
22
- for (var _i = 0; _i < arguments.length; _i++) {
23
- args[_i] = arguments[_i];
24
- }
25
- (window[gaAlias].q = window[gaAlias].q || []).push(args);
23
+ (window[gaAlias].q = window[gaAlias].q || []).push(arguments);
26
24
  };
27
25
  // provides the plugin for use with analytics.js.
28
- // @ts-expect-error
29
26
  window[gaAlias]('provide', pluginName, pluginConstructor);
27
+ if (autoRequire && (!window[gaAlias].q || window[gaAlias].q.push === [].push)) {
28
+ // Expecting spy on ga.q push method but not found
29
+ log.error(logPrefix + 'integration is configured to autorequire the splitTracker plugin, but the necessary script does not seem to have run.');
30
+ }
30
31
  }
31
32
  // Default mapping: object used for building the default mapper from hits to Split events
32
33
  var defaultMapping = {
@@ -246,6 +247,6 @@ function GaToSplit(sdkOptions, params) {
246
247
  return SplitTracker;
247
248
  }());
248
249
  // Register the plugin, even if config is invalid, since, if not provided, it will block `ga` command queue.
249
- providePlugin('splitTracker', SplitTracker);
250
+ providePlugin(window, 'splitTracker', SplitTracker, log, sdkOptions.autoRequire);
250
251
  }
251
252
  exports.GaToSplit = GaToSplit;
@@ -10,7 +10,7 @@ var consent_1 = require("../consent");
10
10
  var telemetrySubmitter_1 = require("../sync/submitters/telemetrySubmitter");
11
11
  var VISIBILITYCHANGE_EVENT = 'visibilitychange';
12
12
  var PAGEHIDE_EVENT = 'pagehide';
13
- var UNLOAD_DOM_EVENT = 'unload';
13
+ var UNLOAD_EVENT = 'unload';
14
14
  var EVENT_NAME = 'for unload page event.';
15
15
  /**
16
16
  * We'll listen for events over the window object.
@@ -31,15 +31,17 @@ var BrowserSignalListener = /** @class */ (function () {
31
31
  * Called when SplitFactory is initialized, it adds event listeners to close streaming and flush impressions and events.
32
32
  */
33
33
  BrowserSignalListener.prototype.start = function () {
34
- if (typeof window !== 'undefined' && window.addEventListener) {
35
- this.settings.log.debug(constants_2.CLEANUP_REGISTERING, [EVENT_NAME]);
34
+ this.settings.log.debug(constants_2.CLEANUP_REGISTERING, [EVENT_NAME]);
35
+ if (typeof document !== 'undefined' && document.addEventListener) {
36
36
  // Flush data whenever the page is hidden or unloaded.
37
- window.addEventListener(VISIBILITYCHANGE_EVENT, this.flushDataIfHidden);
37
+ document.addEventListener(VISIBILITYCHANGE_EVENT, this.flushDataIfHidden);
38
+ }
39
+ if (typeof window !== 'undefined' && window.addEventListener) {
38
40
  // Some browsers like Safari does not fire the `visibilitychange` event when the page is being unloaded. So we also flush data in the `pagehide` event.
39
41
  // If both events are triggered, the last one will find the storage empty, so no duplicated data will be submitted.
40
42
  window.addEventListener(PAGEHIDE_EVENT, this.flushData);
41
43
  // Stop streaming on 'unload' event. Used instead of 'beforeunload', because 'unload' is not a cancelable event, so no other listeners can stop the event from occurring.
42
- window.addEventListener(UNLOAD_DOM_EVENT, this.stopSync);
44
+ window.addEventListener(UNLOAD_EVENT, this.stopSync);
43
45
  }
44
46
  };
45
47
  /**
@@ -47,11 +49,13 @@ var BrowserSignalListener = /** @class */ (function () {
47
49
  * Called when client is destroyed, it removes event listeners.
48
50
  */
49
51
  BrowserSignalListener.prototype.stop = function () {
52
+ this.settings.log.debug(constants_2.CLEANUP_DEREGISTERING, [EVENT_NAME]);
53
+ if (typeof document !== 'undefined' && document.removeEventListener) {
54
+ document.removeEventListener(VISIBILITYCHANGE_EVENT, this.flushDataIfHidden);
55
+ }
50
56
  if (typeof window !== 'undefined' && window.removeEventListener) {
51
- this.settings.log.debug(constants_2.CLEANUP_DEREGISTERING, [EVENT_NAME]);
52
- window.removeEventListener(VISIBILITYCHANGE_EVENT, this.flushDataIfHidden);
53
57
  window.removeEventListener(PAGEHIDE_EVENT, this.flushData);
54
- window.removeEventListener(UNLOAD_DOM_EVENT, this.stopSync);
58
+ window.removeEventListener(UNLOAD_EVENT, this.stopSync);
55
59
  }
56
60
  };
57
61
  BrowserSignalListener.prototype.stopSync = function () {
@@ -61,7 +65,7 @@ var BrowserSignalListener = /** @class */ (function () {
61
65
  };
62
66
  /**
63
67
  * flushData method.
64
- * Called when unload event is triggered. It flushed remaining impressions and events to the backend,
68
+ * Called when pagehide event is triggered. It flushed remaining impressions and events to the backend,
65
69
  * using beacon API if possible, or falling back to regular post transport.
66
70
  */
67
71
  BrowserSignalListener.prototype.flushData = function () {
@@ -87,7 +91,8 @@ var BrowserSignalListener = /** @class */ (function () {
87
91
  }
88
92
  };
89
93
  BrowserSignalListener.prototype.flushDataIfHidden = function () {
90
- if (typeof document !== 'undefined' && document.visibilityState === 'hidden')
94
+ // Precondition: document defined
95
+ if (document.visibilityState === 'hidden')
91
96
  this.flushData(); // On a 'visibilitychange' event, flush data if state is hidden
92
97
  };
93
98
  BrowserSignalListener.prototype._flushData = function (url, cache, postService, fromCacheToPayload, extraMetadata) {
@@ -7,23 +7,24 @@ var logNameMapper = 'ga-to-split:mapper';
7
7
  /**
8
8
  * Provides a plugin to use with analytics.js, accounting for the possibility
9
9
  * that the global command queue has been renamed or not yet defined.
10
- * @param {string} pluginName The plugin name identifier.
11
- * @param {Function} pluginConstructor The plugin constructor function.
10
+ * @param window Reference to global object.
11
+ * @param pluginName The plugin name identifier.
12
+ * @param pluginConstructor The plugin constructor function.
13
+ * @param log Logger instance.
14
+ * @param autoRequire If true, log error when auto-require script is not detected
12
15
  */
13
- function providePlugin(pluginName, pluginConstructor) {
16
+ function providePlugin(window, pluginName, pluginConstructor, log, autoRequire) {
14
17
  // get reference to global command queue. Init it if not defined yet.
15
- // @ts-expect-error
16
18
  var gaAlias = window.GoogleAnalyticsObject || 'ga';
17
19
  window[gaAlias] = window[gaAlias] || function () {
18
- var args = [];
19
- for (var _i = 0; _i < arguments.length; _i++) {
20
- args[_i] = arguments[_i];
21
- }
22
- (window[gaAlias].q = window[gaAlias].q || []).push(args);
20
+ (window[gaAlias].q = window[gaAlias].q || []).push(arguments);
23
21
  };
24
22
  // provides the plugin for use with analytics.js.
25
- // @ts-expect-error
26
23
  window[gaAlias]('provide', pluginName, pluginConstructor);
24
+ if (autoRequire && (!window[gaAlias].q || window[gaAlias].q.push === [].push)) {
25
+ // Expecting spy on ga.q push method but not found
26
+ log.error(logPrefix + 'integration is configured to autorequire the splitTracker plugin, but the necessary script does not seem to have run.');
27
+ }
27
28
  }
28
29
  // Default mapping: object used for building the default mapper from hits to Split events
29
30
  var defaultMapping = {
@@ -240,5 +241,5 @@ export function GaToSplit(sdkOptions, params) {
240
241
  return SplitTracker;
241
242
  }());
242
243
  // Register the plugin, even if config is invalid, since, if not provided, it will block `ga` command queue.
243
- providePlugin('splitTracker', SplitTracker);
244
+ providePlugin(window, 'splitTracker', SplitTracker, log, sdkOptions.autoRequire);
244
245
  }
@@ -7,7 +7,7 @@ import { isConsentGranted } from '../consent';
7
7
  import { telemetryCacheStatsAdapter } from '../sync/submitters/telemetrySubmitter';
8
8
  var VISIBILITYCHANGE_EVENT = 'visibilitychange';
9
9
  var PAGEHIDE_EVENT = 'pagehide';
10
- var UNLOAD_DOM_EVENT = 'unload';
10
+ var UNLOAD_EVENT = 'unload';
11
11
  var EVENT_NAME = 'for unload page event.';
12
12
  /**
13
13
  * We'll listen for events over the window object.
@@ -28,15 +28,17 @@ var BrowserSignalListener = /** @class */ (function () {
28
28
  * Called when SplitFactory is initialized, it adds event listeners to close streaming and flush impressions and events.
29
29
  */
30
30
  BrowserSignalListener.prototype.start = function () {
31
- if (typeof window !== 'undefined' && window.addEventListener) {
32
- this.settings.log.debug(CLEANUP_REGISTERING, [EVENT_NAME]);
31
+ this.settings.log.debug(CLEANUP_REGISTERING, [EVENT_NAME]);
32
+ if (typeof document !== 'undefined' && document.addEventListener) {
33
33
  // Flush data whenever the page is hidden or unloaded.
34
- window.addEventListener(VISIBILITYCHANGE_EVENT, this.flushDataIfHidden);
34
+ document.addEventListener(VISIBILITYCHANGE_EVENT, this.flushDataIfHidden);
35
+ }
36
+ if (typeof window !== 'undefined' && window.addEventListener) {
35
37
  // Some browsers like Safari does not fire the `visibilitychange` event when the page is being unloaded. So we also flush data in the `pagehide` event.
36
38
  // If both events are triggered, the last one will find the storage empty, so no duplicated data will be submitted.
37
39
  window.addEventListener(PAGEHIDE_EVENT, this.flushData);
38
40
  // Stop streaming on 'unload' event. Used instead of 'beforeunload', because 'unload' is not a cancelable event, so no other listeners can stop the event from occurring.
39
- window.addEventListener(UNLOAD_DOM_EVENT, this.stopSync);
41
+ window.addEventListener(UNLOAD_EVENT, this.stopSync);
40
42
  }
41
43
  };
42
44
  /**
@@ -44,11 +46,13 @@ var BrowserSignalListener = /** @class */ (function () {
44
46
  * Called when client is destroyed, it removes event listeners.
45
47
  */
46
48
  BrowserSignalListener.prototype.stop = function () {
49
+ this.settings.log.debug(CLEANUP_DEREGISTERING, [EVENT_NAME]);
50
+ if (typeof document !== 'undefined' && document.removeEventListener) {
51
+ document.removeEventListener(VISIBILITYCHANGE_EVENT, this.flushDataIfHidden);
52
+ }
47
53
  if (typeof window !== 'undefined' && window.removeEventListener) {
48
- this.settings.log.debug(CLEANUP_DEREGISTERING, [EVENT_NAME]);
49
- window.removeEventListener(VISIBILITYCHANGE_EVENT, this.flushDataIfHidden);
50
54
  window.removeEventListener(PAGEHIDE_EVENT, this.flushData);
51
- window.removeEventListener(UNLOAD_DOM_EVENT, this.stopSync);
55
+ window.removeEventListener(UNLOAD_EVENT, this.stopSync);
52
56
  }
53
57
  };
54
58
  BrowserSignalListener.prototype.stopSync = function () {
@@ -58,7 +62,7 @@ var BrowserSignalListener = /** @class */ (function () {
58
62
  };
59
63
  /**
60
64
  * flushData method.
61
- * Called when unload event is triggered. It flushed remaining impressions and events to the backend,
65
+ * Called when pagehide event is triggered. It flushed remaining impressions and events to the backend,
62
66
  * using beacon API if possible, or falling back to regular post transport.
63
67
  */
64
68
  BrowserSignalListener.prototype.flushData = function () {
@@ -84,7 +88,8 @@ var BrowserSignalListener = /** @class */ (function () {
84
88
  }
85
89
  };
86
90
  BrowserSignalListener.prototype.flushDataIfHidden = function () {
87
- if (typeof document !== 'undefined' && document.visibilityState === 'hidden')
91
+ // Precondition: document defined
92
+ if (document.visibilityState === 'hidden')
88
93
  this.flushData(); // On a 'visibilitychange' event, flush data if state is hidden
89
94
  };
90
95
  BrowserSignalListener.prototype._flushData = function (url, cache, postService, fromCacheToPayload, extraMetadata) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splitsoftware/splitio-commons",
3
- "version": "1.4.2-rc.4",
3
+ "version": "1.5.1-rc.0",
4
4
  "description": "Split Javascript SDK common components",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",
@@ -19,20 +19,26 @@ const logNameMapper = 'ga-to-split:mapper';
19
19
  /**
20
20
  * Provides a plugin to use with analytics.js, accounting for the possibility
21
21
  * that the global command queue has been renamed or not yet defined.
22
- * @param {string} pluginName The plugin name identifier.
23
- * @param {Function} pluginConstructor The plugin constructor function.
22
+ * @param window Reference to global object.
23
+ * @param pluginName The plugin name identifier.
24
+ * @param pluginConstructor The plugin constructor function.
25
+ * @param log Logger instance.
26
+ * @param autoRequire If true, log error when auto-require script is not detected
24
27
  */
25
- function providePlugin(pluginName: string, pluginConstructor: Function) {
28
+ function providePlugin(window: any, pluginName: string, pluginConstructor: Function, log: ILogger, autoRequire?: boolean) {
26
29
  // get reference to global command queue. Init it if not defined yet.
27
- // @ts-expect-error
28
30
  const gaAlias = window.GoogleAnalyticsObject || 'ga';
29
- window[gaAlias] = window[gaAlias] || function (...args: any[]) { // @ts-expect-error
30
- (window[gaAlias].q = window[gaAlias].q || []).push(args);
31
+ window[gaAlias] = window[gaAlias] || function () {
32
+ (window[gaAlias].q = window[gaAlias].q || []).push(arguments);
31
33
  };
32
34
 
33
35
  // provides the plugin for use with analytics.js.
34
- // @ts-expect-error
35
36
  window[gaAlias]('provide', pluginName, pluginConstructor);
37
+
38
+ if (autoRequire && (!window[gaAlias].q || window[gaAlias].q.push === [].push)) {
39
+ // Expecting spy on ga.q push method but not found
40
+ log.error(logPrefix + 'integration is configured to autorequire the splitTracker plugin, but the necessary script does not seem to have run.');
41
+ }
36
42
  }
37
43
 
38
44
  // Default mapping: object used for building the default mapper from hits to Split events
@@ -284,5 +290,5 @@ export function GaToSplit(sdkOptions: GoogleAnalyticsToSplitOptions, params: IIn
284
290
  }
285
291
 
286
292
  // Register the plugin, even if config is invalid, since, if not provided, it will block `ga` command queue.
287
- providePlugin('splitTracker', SplitTracker);
293
+ providePlugin(window, 'splitTracker', SplitTracker, log, sdkOptions.autoRequire);
288
294
  }
@@ -0,0 +1,33 @@
1
+ /* eslint-disable no-undef */
2
+ /**
3
+ * Auto-require script to use with GoogleAnalyticsToSplit integration
4
+ */
5
+ (function (i, r, s) {
6
+ i[s] = i[s] || r;
7
+ i[r] = i[r] || function () { i[r].q.push(arguments); };
8
+ i[r].q = i[r].q || [];
9
+
10
+ var ts = {}; // Tracker names
11
+ function name(arg) { return typeof arg === 'object' && typeof arg.name === 'string' && arg.name; }
12
+
13
+ function processCommand(v) { // Queue a `require` command if v is a `create` command
14
+ if (v && v[0] === 'create') {
15
+ var t = name(v[1]) || name(v[2]) || name(v[3]) || (typeof v[3] === 'string' ? v[3] : undefined); // Get tracker name
16
+
17
+ if (!ts[t]) {
18
+ ts[t] = true;
19
+ i[r]((t ? t + '.' : '') + 'require', 'splitTracker'); // Auto-require
20
+ }
21
+ }
22
+ }
23
+
24
+ i[r].q.forEach(processCommand); // Process already queued commands
25
+
26
+ var o = i[r].q.push;
27
+ i[r].q.push = function (v) { // Spy new queued commands
28
+ var result = o.apply(this, arguments);
29
+ processCommand(v);
30
+ return result;
31
+ };
32
+
33
+ })(window, 'ga', 'GoogleAnalyticsObject');
@@ -53,13 +53,24 @@ export interface GoogleAnalyticsToSplitOptions {
53
53
  * If not provided, events are sent using the key and traffic type provided at SDK config
54
54
  */
55
55
  identities?: Identity[],
56
+ /**
57
+ * Optional flag to log an error if the `auto-require` script is not detected.
58
+ * The auto-require script automatically requires the `splitTracker` plugin for created trackers,
59
+ * and should be placed right after your Google Analytics, Google Tag Manager or gtag.js script tag.
60
+ *
61
+ * @see {@link https://help.split.io/hc/en-us/articles/360040838752#set-up-with-gtm-and-gtag.js}
62
+ *
63
+ * @property {boolean} autoRequire
64
+ * @default false
65
+ */
66
+ autoRequire?: boolean,
56
67
  }
57
68
 
58
69
  /**
59
70
  * Enable 'Google Analytics to Split' integration, to track Google Analytics hits as Split events.
60
71
  * Used by the browser variant of the isomorphic JS SDK.
61
72
  *
62
- * @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#google-analytics-to-split}
73
+ * @see {@link https://help.split.io/hc/en-us/articles/360040838752#google-analytics-to-split}
63
74
  */
64
75
  export interface IGoogleAnalyticsToSplitConfig extends GoogleAnalyticsToSplitOptions {
65
76
  type: 'GOOGLE_ANALYTICS_TO_SPLIT'
@@ -129,7 +140,7 @@ export interface SplitToGoogleAnalyticsOptions {
129
140
  * Enable 'Split to Google Analytics' integration, to track Split impressions and events as Google Analytics hits.
130
141
  * Used by the browser variant of the isomorphic JS SDK.
131
142
  *
132
- * @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#split-to-google-analytics}
143
+ * @see {@link https://help.split.io/hc/en-us/articles/360040838752#split-to-google-analytics}
133
144
  */
134
145
  export interface ISplitToGoogleAnalyticsConfig extends SplitToGoogleAnalyticsOptions {
135
146
  type: 'SPLIT_TO_GOOGLE_ANALYTICS'
@@ -16,7 +16,7 @@ import { telemetryCacheStatsAdapter } from '../sync/submitters/telemetrySubmitte
16
16
 
17
17
  const VISIBILITYCHANGE_EVENT = 'visibilitychange';
18
18
  const PAGEHIDE_EVENT = 'pagehide';
19
- const UNLOAD_DOM_EVENT = 'unload';
19
+ const UNLOAD_EVENT = 'unload';
20
20
  const EVENT_NAME = 'for unload page event.';
21
21
 
22
22
  /**
@@ -43,16 +43,17 @@ export class BrowserSignalListener implements ISignalListener {
43
43
  * Called when SplitFactory is initialized, it adds event listeners to close streaming and flush impressions and events.
44
44
  */
45
45
  start() {
46
- if (typeof window !== 'undefined' && window.addEventListener) {
47
- this.settings.log.debug(CLEANUP_REGISTERING, [EVENT_NAME]);
48
-
46
+ this.settings.log.debug(CLEANUP_REGISTERING, [EVENT_NAME]);
47
+ if (typeof document !== 'undefined' && document.addEventListener) {
49
48
  // Flush data whenever the page is hidden or unloaded.
50
- window.addEventListener(VISIBILITYCHANGE_EVENT, this.flushDataIfHidden);
49
+ document.addEventListener(VISIBILITYCHANGE_EVENT, this.flushDataIfHidden);
50
+ }
51
+ if (typeof window !== 'undefined' && window.addEventListener) {
51
52
  // Some browsers like Safari does not fire the `visibilitychange` event when the page is being unloaded. So we also flush data in the `pagehide` event.
52
53
  // If both events are triggered, the last one will find the storage empty, so no duplicated data will be submitted.
53
54
  window.addEventListener(PAGEHIDE_EVENT, this.flushData);
54
55
  // Stop streaming on 'unload' event. Used instead of 'beforeunload', because 'unload' is not a cancelable event, so no other listeners can stop the event from occurring.
55
- window.addEventListener(UNLOAD_DOM_EVENT, this.stopSync);
56
+ window.addEventListener(UNLOAD_EVENT, this.stopSync);
56
57
  }
57
58
  }
58
59
 
@@ -61,11 +62,13 @@ export class BrowserSignalListener implements ISignalListener {
61
62
  * Called when client is destroyed, it removes event listeners.
62
63
  */
63
64
  stop() {
65
+ this.settings.log.debug(CLEANUP_DEREGISTERING, [EVENT_NAME]);
66
+ if (typeof document !== 'undefined' && document.removeEventListener) {
67
+ document.removeEventListener(VISIBILITYCHANGE_EVENT, this.flushDataIfHidden);
68
+ }
64
69
  if (typeof window !== 'undefined' && window.removeEventListener) {
65
- this.settings.log.debug(CLEANUP_DEREGISTERING, [EVENT_NAME]);
66
- window.removeEventListener(VISIBILITYCHANGE_EVENT, this.flushDataIfHidden);
67
70
  window.removeEventListener(PAGEHIDE_EVENT, this.flushData);
68
- window.removeEventListener(UNLOAD_DOM_EVENT, this.stopSync);
71
+ window.removeEventListener(UNLOAD_EVENT, this.stopSync);
69
72
  }
70
73
  }
71
74
 
@@ -76,7 +79,7 @@ export class BrowserSignalListener implements ISignalListener {
76
79
 
77
80
  /**
78
81
  * flushData method.
79
- * Called when unload event is triggered. It flushed remaining impressions and events to the backend,
82
+ * Called when pagehide event is triggered. It flushed remaining impressions and events to the backend,
80
83
  * using beacon API if possible, or falling back to regular post transport.
81
84
  */
82
85
  flushData() {
@@ -104,7 +107,8 @@ export class BrowserSignalListener implements ISignalListener {
104
107
  }
105
108
 
106
109
  flushDataIfHidden() {
107
- if (typeof document !== 'undefined' && document.visibilityState === 'hidden') this.flushData(); // On a 'visibilitychange' event, flush data if state is hidden
110
+ // Precondition: document defined
111
+ if (document.visibilityState === 'hidden') this.flushData(); // On a 'visibilitychange' event, flush data if state is hidden
108
112
  }
109
113
 
110
114
  private _flushData<T>(url: string, cache: IRecorderCacheProducerSync<T>, postService: (body: string) => Promise<IResponse>, fromCacheToPayload?: (cacheData: T) => any, extraMetadata?: {}) {
@@ -52,12 +52,23 @@ export interface GoogleAnalyticsToSplitOptions {
52
52
  * If not provided, events are sent using the key and traffic type provided at SDK config
53
53
  */
54
54
  identities?: Identity[];
55
+ /**
56
+ * Optional flag to log an error if the `auto-require` script is not detected.
57
+ * The auto-require script automatically requires the `splitTracker` plugin for created trackers,
58
+ * and should be placed right after your Google Analytics, Google Tag Manager or gtag.js script tag.
59
+ *
60
+ * @see {@link https://help.split.io/hc/en-us/articles/360040838752#set-up-with-gtm-and-gtag.js}
61
+ *
62
+ * @property {boolean} autoRequire
63
+ * @default false
64
+ */
65
+ autoRequire?: boolean;
55
66
  }
56
67
  /**
57
68
  * Enable 'Google Analytics to Split' integration, to track Google Analytics hits as Split events.
58
69
  * Used by the browser variant of the isomorphic JS SDK.
59
70
  *
60
- * @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#google-analytics-to-split}
71
+ * @see {@link https://help.split.io/hc/en-us/articles/360040838752#google-analytics-to-split}
61
72
  */
62
73
  export interface IGoogleAnalyticsToSplitConfig extends GoogleAnalyticsToSplitOptions {
63
74
  type: 'GOOGLE_ANALYTICS_TO_SPLIT';
@@ -125,7 +136,7 @@ export interface SplitToGoogleAnalyticsOptions {
125
136
  * Enable 'Split to Google Analytics' integration, to track Split impressions and events as Google Analytics hits.
126
137
  * Used by the browser variant of the isomorphic JS SDK.
127
138
  *
128
- * @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#split-to-google-analytics}
139
+ * @see {@link https://help.split.io/hc/en-us/articles/360040838752#split-to-google-analytics}
129
140
  */
130
141
  export interface ISplitToGoogleAnalyticsConfig extends SplitToGoogleAnalyticsOptions {
131
142
  type: 'SPLIT_TO_GOOGLE_ANALYTICS';
@@ -26,7 +26,7 @@ export declare class BrowserSignalListener implements ISignalListener {
26
26
  stopSync(): void;
27
27
  /**
28
28
  * flushData method.
29
- * Called when unload event is triggered. It flushed remaining impressions and events to the backend,
29
+ * Called when pagehide event is triggered. It flushed remaining impressions and events to the backend,
30
30
  * using beacon API if possible, or falling back to regular post transport.
31
31
  */
32
32
  flushData(): void;
@@ -0,0 +1,3 @@
1
+ export declare const FETCH_BACKOFF_BASE = 10000;
2
+ export declare const FETCH_BACKOFF_MAX_WAIT = 60000;
3
+ export declare const FETCH_BACKOFF_MAX_RETRIES = 10;