@zoho_apptics/apptics-js-sdk 2.0.0-beta.1 → 2.0.0-beta.2

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.
Files changed (183) hide show
  1. package/CHANGELOG.md +80 -16
  2. package/README.md +187 -100
  3. package/dist/apptics.esm.min.js +2 -2
  4. package/dist/apptics.esm.min.js.map +1 -1
  5. package/dist/apptics.min.js +2 -2
  6. package/dist/apptics.min.js.map +1 -1
  7. package/dist/chunks/lifecycle-C6m1W7jo.min.js +3 -0
  8. package/dist/chunks/lifecycle-C6m1W7jo.min.js.map +1 -0
  9. package/dist/chunks/send-CgUO82ne.min.js +3 -0
  10. package/dist/chunks/send-CgUO82ne.min.js.map +1 -0
  11. package/dist/cjs/core/attempts.js +1 -1
  12. package/dist/cjs/core/batch.js +1 -2
  13. package/dist/cjs/core/consent.d.ts +13 -3
  14. package/dist/cjs/core/consent.js +24 -10
  15. package/dist/cjs/core/constants.d.ts +22 -17
  16. package/dist/cjs/core/constants.js +22 -19
  17. package/dist/cjs/core/db.js +1 -1
  18. package/dist/cjs/core/debug.js +1 -1
  19. package/dist/cjs/core/env.d.ts +0 -3
  20. package/dist/cjs/core/env.js +1 -9
  21. package/dist/cjs/core/framework-id.d.ts +1 -1
  22. package/dist/cjs/core/framework-id.js +3 -3
  23. package/dist/cjs/core/guard.js +1 -1
  24. package/dist/cjs/core/hooks.d.ts +5 -0
  25. package/dist/cjs/core/hooks.js +2 -1
  26. package/dist/cjs/core/locks.js +1 -1
  27. package/dist/cjs/core/logger.js +1 -1
  28. package/dist/cjs/core/state.d.ts +6 -4
  29. package/dist/cjs/core/state.js +2 -4
  30. package/dist/cjs/core/storage.js +1 -4
  31. package/dist/cjs/core/stylesheet.js +1 -1
  32. package/dist/cjs/core/transport.js +13 -16
  33. package/dist/cjs/core/utils.js +1 -1
  34. package/dist/cjs/core/validate.js +1 -1
  35. package/dist/cjs/device/appversion.d.ts +10 -1
  36. package/dist/cjs/device/appversion.js +26 -3
  37. package/dist/cjs/device/index.d.ts +17 -2
  38. package/dist/cjs/device/index.js +195 -27
  39. package/dist/cjs/engagement/api-rules.js +1 -1
  40. package/dist/cjs/engagement/auto-api.js +1 -1
  41. package/dist/cjs/engagement/auto-screen.js +1 -1
  42. package/dist/cjs/engagement/defined-events.js +1 -1
  43. package/dist/cjs/engagement/send.js +7 -3
  44. package/dist/cjs/engagement/session.d.ts +17 -0
  45. package/dist/cjs/engagement/session.js +95 -4
  46. package/dist/cjs/engagement/track.d.ts +4 -4
  47. package/dist/cjs/engagement/track.js +15 -12
  48. package/dist/cjs/errors/send.js +2 -2
  49. package/dist/cjs/errors/track.d.ts +2 -1
  50. package/dist/cjs/errors/track.js +6 -4
  51. package/dist/cjs/feedback/controls.d.ts +6 -0
  52. package/dist/cjs/feedback/controls.js +74 -25
  53. package/dist/cjs/feedback/index.js +1 -1
  54. package/dist/cjs/feedback/logs.d.ts +3 -6
  55. package/dist/cjs/feedback/logs.js +8 -18
  56. package/dist/cjs/feedback/quartz.js +1 -1
  57. package/dist/cjs/feedback/send.d.ts +2 -2
  58. package/dist/cjs/feedback/send.js +4 -27
  59. package/dist/cjs/feedback/styles.js +2 -2
  60. package/dist/cjs/feedback/template.d.ts +1 -1
  61. package/dist/cjs/feedback/template.js +9 -1
  62. package/dist/cjs/feedback/ui.d.ts +7 -0
  63. package/dist/cjs/feedback/ui.js +160 -25
  64. package/dist/cjs/heatmap/send.d.ts +2 -0
  65. package/dist/cjs/heatmap/send.js +3 -5
  66. package/dist/cjs/heatmap/track.js +1 -1
  67. package/dist/cjs/index.d.ts +1 -2
  68. package/dist/cjs/index.js +54 -17
  69. package/dist/cjs/lifecycle.d.ts +13 -2
  70. package/dist/cjs/lifecycle.js +122 -54
  71. package/dist/cjs/remoteconfig/country.js +1 -1
  72. package/dist/cjs/remoteconfig/custom.js +1 -1
  73. package/dist/cjs/remoteconfig/evaluate.js +1 -1
  74. package/dist/cjs/remoteconfig/fetch.d.ts +17 -10
  75. package/dist/cjs/remoteconfig/fetch.js +126 -31
  76. package/dist/cjs/remoteconfig/index.d.ts +13 -4
  77. package/dist/cjs/remoteconfig/index.js +36 -20
  78. package/dist/cjs/remoteconfig/store.d.ts +15 -7
  79. package/dist/cjs/remoteconfig/store.js +68 -35
  80. package/dist/cjs/remoteconfig/tz-countries.js +1 -1
  81. package/dist/cjs/{core → remotelog}/callsite.d.ts +5 -4
  82. package/dist/cjs/{core → remotelog}/callsite.js +6 -5
  83. package/dist/cjs/remotelog/gate.js +1 -1
  84. package/dist/cjs/remotelog/logger.js +2 -2
  85. package/dist/cjs/remotelog/send.js +2 -2
  86. package/dist/cjs/remotelogger/index.js +1 -1
  87. package/dist/cjs/scheduler.d.ts +3 -1
  88. package/dist/cjs/scheduler.js +24 -21
  89. package/dist/cjs/types.d.ts +61 -16
  90. package/dist/cjs/user/index.js +6 -2
  91. package/dist/esm/core/attempts.js +1 -1
  92. package/dist/esm/core/batch.js +1 -2
  93. package/dist/esm/core/consent.d.ts +13 -3
  94. package/dist/esm/core/consent.js +24 -11
  95. package/dist/esm/core/constants.d.ts +22 -17
  96. package/dist/esm/core/constants.js +22 -19
  97. package/dist/esm/core/db.js +1 -1
  98. package/dist/esm/core/debug.js +1 -1
  99. package/dist/esm/core/env.d.ts +0 -3
  100. package/dist/esm/core/env.js +2 -9
  101. package/dist/esm/core/framework-id.d.ts +1 -1
  102. package/dist/esm/core/framework-id.js +3 -3
  103. package/dist/esm/core/guard.js +1 -1
  104. package/dist/esm/core/hooks.d.ts +5 -0
  105. package/dist/esm/core/hooks.js +2 -1
  106. package/dist/esm/core/locks.js +1 -1
  107. package/dist/esm/core/logger.js +1 -1
  108. package/dist/esm/core/state.d.ts +6 -4
  109. package/dist/esm/core/state.js +2 -4
  110. package/dist/esm/core/storage.js +1 -4
  111. package/dist/esm/core/stylesheet.js +1 -1
  112. package/dist/esm/core/transport.js +13 -16
  113. package/dist/esm/core/utils.js +1 -1
  114. package/dist/esm/core/validate.js +1 -1
  115. package/dist/esm/device/appversion.d.ts +10 -1
  116. package/dist/esm/device/appversion.js +26 -4
  117. package/dist/esm/device/index.d.ts +17 -2
  118. package/dist/esm/device/index.js +195 -30
  119. package/dist/esm/engagement/api-rules.js +1 -1
  120. package/dist/esm/engagement/auto-api.js +1 -1
  121. package/dist/esm/engagement/auto-screen.js +1 -1
  122. package/dist/esm/engagement/defined-events.js +1 -1
  123. package/dist/esm/engagement/send.js +7 -3
  124. package/dist/esm/engagement/session.d.ts +17 -0
  125. package/dist/esm/engagement/session.js +93 -5
  126. package/dist/esm/engagement/track.d.ts +4 -4
  127. package/dist/esm/engagement/track.js +16 -13
  128. package/dist/esm/errors/send.js +2 -2
  129. package/dist/esm/errors/track.d.ts +2 -1
  130. package/dist/esm/errors/track.js +6 -4
  131. package/dist/esm/feedback/controls.d.ts +6 -0
  132. package/dist/esm/feedback/controls.js +74 -26
  133. package/dist/esm/feedback/index.js +1 -1
  134. package/dist/esm/feedback/logs.d.ts +3 -6
  135. package/dist/esm/feedback/logs.js +8 -18
  136. package/dist/esm/feedback/quartz.js +1 -1
  137. package/dist/esm/feedback/send.d.ts +2 -2
  138. package/dist/esm/feedback/send.js +6 -29
  139. package/dist/esm/feedback/styles.js +2 -2
  140. package/dist/esm/feedback/template.d.ts +1 -1
  141. package/dist/esm/feedback/template.js +9 -1
  142. package/dist/esm/feedback/ui.d.ts +7 -0
  143. package/dist/esm/feedback/ui.js +161 -26
  144. package/dist/esm/heatmap/send.d.ts +2 -0
  145. package/dist/esm/heatmap/send.js +3 -5
  146. package/dist/esm/heatmap/track.js +1 -1
  147. package/dist/esm/index.d.ts +1 -2
  148. package/dist/esm/index.js +57 -20
  149. package/dist/esm/lifecycle.d.ts +13 -2
  150. package/dist/esm/lifecycle.js +126 -60
  151. package/dist/esm/remoteconfig/country.js +1 -1
  152. package/dist/esm/remoteconfig/custom.js +1 -1
  153. package/dist/esm/remoteconfig/evaluate.js +1 -1
  154. package/dist/esm/remoteconfig/fetch.d.ts +17 -10
  155. package/dist/esm/remoteconfig/fetch.js +127 -32
  156. package/dist/esm/remoteconfig/index.d.ts +13 -4
  157. package/dist/esm/remoteconfig/index.js +36 -20
  158. package/dist/esm/remoteconfig/store.d.ts +15 -7
  159. package/dist/esm/remoteconfig/store.js +68 -36
  160. package/dist/esm/remoteconfig/tz-countries.js +1 -1
  161. package/dist/esm/{core → remotelog}/callsite.d.ts +5 -4
  162. package/dist/esm/{core → remotelog}/callsite.js +6 -5
  163. package/dist/esm/remotelog/gate.js +1 -1
  164. package/dist/esm/remotelog/logger.js +2 -2
  165. package/dist/esm/remotelog/send.js +2 -2
  166. package/dist/esm/remotelogger/index.js +1 -1
  167. package/dist/esm/scheduler.d.ts +3 -1
  168. package/dist/esm/scheduler.js +25 -23
  169. package/dist/esm/types.d.ts +61 -16
  170. package/dist/esm/user/index.js +7 -3
  171. package/dist/feedback.esm.min.js +2 -2
  172. package/dist/feedback.esm.min.js.map +1 -1
  173. package/dist/remoteconfig.esm.min.js +3 -0
  174. package/dist/remoteconfig.esm.min.js.map +1 -0
  175. package/dist/remotelogger.esm.min.js +3 -0
  176. package/dist/remotelogger.esm.min.js.map +1 -0
  177. package/package.json +3 -2
  178. package/dist/chunks/lifecycle-VYr43KcB.min.js +0 -3
  179. package/dist/chunks/lifecycle-VYr43KcB.min.js.map +0 -1
  180. package/dist/cjs/auto-init.d.ts +0 -8
  181. package/dist/cjs/auto-init.js +0 -32
  182. package/dist/esm/auto-init.d.ts +0 -8
  183. package/dist/esm/auto-init.js +0 -29
package/dist/cjs/index.js CHANGED
@@ -1,10 +1,11 @@
1
- /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
2
2
  'use strict';
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
6
  var constants = require('./core/constants.js');
7
7
  var guard = require('./core/guard.js');
8
+ var logger = require('./core/logger.js');
8
9
  var lifecycle = require('./lifecycle.js');
9
10
  var autoApi = require('./engagement/auto-api.js');
10
11
  var track = require('./engagement/track.js');
@@ -17,17 +18,22 @@ var index = require('./user/index.js');
17
18
  var consent = require('./core/consent.js');
18
19
  var scheduler = require('./scheduler.js');
19
20
  var track$2 = require('./heatmap/track.js');
20
- require('./heatmap/send.js');
21
- var autoInit = require('./auto-init.js');
21
+ var send = require('./heatmap/send.js');
22
+ var hooks = require('./core/hooks.js');
22
23
  var debug = require('./core/debug.js');
23
24
 
25
+ // flush() and the flush timer send heatmap records through this hook. Set here, from a named
26
+ // import, rather than by heatmap/send.ts on being imported: the package's sideEffects list names
27
+ // only the CDN bundle, so a bundler drops a bare `import './heatmap/send.js'`, and with it every
28
+ // heatmap send, while capture carries on filling the queue
29
+ hooks.hooks.sendHeatmaps = send.sendHeatmapData;
24
30
  /*
25
31
  * Every public call below is a function of its own, with the parameter names the console shows
26
32
  * on hover, forwarding to its guard()ed implementation (see forward).
27
33
  */
28
34
  const initGuarded = guard.guard('Apptics.init', lifecycle.init); // no i18n
29
35
  const readyGuarded = guard.guard('Apptics.ready', lifecycle.ready); // no i18n
30
- const flushGuarded = guard.guard('Apptics.flush', scheduler.flush); // no i18n
36
+ const flushGuarded = guard.guard('Apptics.flush', scheduler.calledFlush); // no i18n
31
37
  const resetGuarded = guard.guard('Apptics.reset', lifecycle.reset); // no i18n
32
38
  /**
33
39
  * Debug mode, on or off; works before init(), and wins over `debug` in init(). On, engagement,
@@ -37,13 +43,23 @@ const resetGuarded = guard.guard('Apptics.reset', lifecycle.reset); // no i18n
37
43
  */
38
44
  const enableDebugGuarded = guard.guard('Apptics.enableDebug', debug.enableDebug); // no i18n
39
45
  const disableDebugGuarded = guard.guard('Apptics.disableDebug', debug.disableDebug); // no i18n
46
+ /** The renamed calls already warned about: once per page each, not once per call. */
47
+ var warnedRenamed = {};
48
+ /** An earlier name of a call still works, with a console warning naming the call to use. */
49
+ function renamed(old, current) {
50
+ if (warnedRenamed[old]) {
51
+ return;
52
+ }
53
+ warnedRenamed[old] = true;
54
+ logger.warnAlways(old + ' is now ' + current + '; rename it in your code'); // no i18n
55
+ }
40
56
  /** Android's Apptics: starting the SDK, and what applies to all of it. */
41
57
  const Apptics = {
42
- /** Starts the SDK. The config object is required; the console snippet supplies it via auto-init. */
58
+ /** Starts the SDK with the app's config object, which is required. */
43
59
  init: function init(config) { return guard.forward(initGuarded, arguments); },
44
60
  /** Resolves true once the SDK is running, false if it can't start. */
45
61
  ready: function ready() { return guard.forward(readyGuarded, arguments); },
46
- /** Sends stored engagements, errors and heatmap records now. */
62
+ /** Sends stored engagements, errors and heatmap records now; at most once every 15 seconds. */
47
63
  flush: function flush() { return guard.forward(flushGuarded, arguments); },
48
64
  /** Clears stored identity, queued data and remote config values, then starts again. */
49
65
  reset: function reset() { return guard.forward(resetGuarded, arguments); },
@@ -51,19 +67,23 @@ const Apptics = {
51
67
  disableDebug: function disableDebug() { return guard.forward(disableDebugGuarded, arguments); },
52
68
  };
53
69
  /**
54
- * Android's AppticsEvents: `addEvent(name, group?, properties?)`, or
70
+ * Android's AppticsEvents: `addEvent(name, group, properties?)`, or
55
71
  * `addEvent(AppticsEvent.DefinedEvents.X, properties?)`.
56
72
  */
57
73
  const addEventGuarded = guard.guard('AppticsEvent.addEvent', track.trackEvent); // no i18n
74
+ const setClickTrackingGuarded = guard.guard('AppticsEvent.setClickTracking', lifecycle.setClickTracking); // no i18n
58
75
  const AppticsEvent = {
59
76
  /** Apptics' defined events, as Android's DefinedEvents, to log with addEvent. */
60
77
  DefinedEvents: definedEvents.DefinedEvents,
61
78
  addEvent: function addEvent(eventName, groupName, properties) {
62
79
  return guard.forward(addEventGuarded, arguments);
63
80
  },
81
+ /** Turns click tracking from markup (apeventaction) on or off; the `track_click` config flag sets it at start-up. */
82
+ setClickTracking: function setClickTracking(enabled) { return guard.forward(setClickTrackingGuarded, arguments); },
64
83
  };
65
84
  const inScreenGuarded = guard.guard('AppticsScreen.inScreen', track.inScreenAt); // no i18n
66
85
  const outScreenGuarded = guard.guard('AppticsScreen.outScreen', track.outScreenAt); // no i18n
86
+ const setScreenTrackingGuarded = guard.guard('AppticsScreen.setScreenTracking', lifecycle.setScreenTracking); // no i18n
67
87
  /** Android's AppticsScreenTracker: inScreen(name) returns the view's id, outScreen(id) ends it. */
68
88
  const AppticsScreen = {
69
89
  /**
@@ -85,11 +105,13 @@ const AppticsScreen = {
85
105
  outScreen: function outScreen(id) {
86
106
  outScreenGuarded(id, utils.nowMs());
87
107
  },
108
+ /** Turns automatic screen tracking on or off; the `track_screen` config flag sets it at start-up. */
109
+ setScreenTracking: function setScreenTracking(enabled) { return guard.forward(setScreenTrackingGuarded, arguments); },
88
110
  };
89
111
  const endTrackApiGuarded = guard.guard('AppticsApi.endTrackApi', track.endTrackApiAt); // no i18n
90
112
  const startTrackApiGuarded = guard.guard('AppticsApi.startTrackApi', track.startTrackApi); // no i18n
91
113
  const configureGuarded = guard.guard('AppticsApi.configure', apiRules.configureApiTracking); // no i18n
92
- const enableApiTrackingGuarded = guard.guard('AppticsApi.enableApiTracking', autoApi.enableApiTracking); // no i18n
114
+ const setApiTrackingGuarded = guard.guard('AppticsApi.setApiTracking', autoApi.enableApiTracking); // no i18n
93
115
  /** Android's AppticsApiTracker: startTrackApi / endTrackApi, and configure for the rules. */
94
116
  const AppticsApi = {
95
117
  /** Begins timing one call: returns the id endTrackApi takes. */
@@ -103,17 +125,27 @@ const AppticsApi = {
103
125
  ApiTrackingBuilder: apiRules.ApiTrackingBuilder,
104
126
  /** The rules API tracking records by, from ApiTrackingBuilder. Works before Apptics.init(). */
105
127
  configure: function configure(config) { return guard.forward(configureGuarded, arguments); },
106
- /** Turns automatic API tracking on or off; the `track_api` config flag is the usual way to set it. */
107
- enableApiTracking: function enableApiTracking(enabled) { return guard.forward(enableApiTrackingGuarded, arguments); },
128
+ /** Turns automatic API tracking on or off; the `track_api` config flag sets it at start-up. */
129
+ setApiTracking: function setApiTracking(enabled) { return guard.forward(setApiTrackingGuarded, arguments); },
130
+ /** @deprecated the earlier name of setApiTracking, which it calls, with a warning */
131
+ enableApiTracking: function enableApiTracking(enabled) {
132
+ renamed('AppticsApi.enableApiTracking', 'AppticsApi.setApiTracking'); // no i18n
133
+ return guard.forward(setApiTrackingGuarded, arguments);
134
+ },
108
135
  };
109
136
  const trackErrorGuarded = guard.guard('AppticsError.trackError', track$1.trackError); // no i18n
110
- const trackGlobalErrorHandlerGuarded = guard.guard('AppticsError.trackGlobalErrorHandler', track$1.trackGlobalErrorHandler); // no i18n
137
+ const setErrorTrackingGuarded = guard.guard('AppticsError.setErrorTracking', track$1.setErrorTracking); // no i18n
111
138
  /** Errors: the ones the app caught, and the switch for the uncaught ones tracked on their own. */
112
139
  const AppticsError = {
113
140
  /** Reports an error the app caught, or an `error` / `unhandledrejection` event. */
114
141
  trackError: function trackError(error, properties) { return guard.forward(trackErrorGuarded, arguments); },
115
- /** Turns the automatic tracking of uncaught errors and unhandled rejections on or off. */
116
- trackGlobalErrorHandler: function trackGlobalErrorHandler(enabled) { return guard.forward(trackGlobalErrorHandlerGuarded, arguments); },
142
+ /** Turns the automatic tracking of uncaught errors and unhandled rejections on or off; the `track_error` config flag sets it at start-up. */
143
+ setErrorTracking: function setErrorTracking(enabled) { return guard.forward(setErrorTrackingGuarded, arguments); },
144
+ /** @deprecated the earlier name of setErrorTracking, which it calls, with a warning */
145
+ trackGlobalErrorHandler: function trackGlobalErrorHandler(enabled) {
146
+ renamed('AppticsError.trackGlobalErrorHandler', 'AppticsError.setErrorTracking'); // no i18n
147
+ return guard.forward(setErrorTrackingGuarded, arguments);
148
+ },
117
149
  };
118
150
  const setUserGuarded = guard.guard('AppticsUser.setUser', index.setUser); // no i18n
119
151
  const getUserGuarded = guard.guard('AppticsUser.getUser', index.getUser); // no i18n
@@ -125,10 +157,16 @@ const AppticsUser = {
125
157
  getUser: function getUser() { return guard.forward(getUserGuarded, arguments); },
126
158
  UserBuilder: index.UserBuilder,
127
159
  };
128
- const trackHeatmapGuarded = guard.guard('AppticsHeatmap.trackHeatmap', track$2.trackHeatmap); // no i18n
129
- /** Heatmap capture: AppticsHeatmap.trackHeatmap() starts or stops recording clicks and scrolls. */
160
+ const setHeatmapTrackingGuarded = guard.guard('AppticsHeatmap.setHeatmapTracking', track$2.trackHeatmap); // no i18n
161
+ /** Heatmap capture: AppticsHeatmap.setHeatmapTracking() starts or stops recording clicks and scrolls. */
130
162
  const AppticsHeatmap = {
131
- trackHeatmap: function trackHeatmap(on) { return guard.forward(trackHeatmapGuarded, arguments); },
163
+ /** Starts or stops recording clicks and scrolls; the `track_heatmap` config flag sets it at start-up. */
164
+ setHeatmapTracking: function setHeatmapTracking(enabled) { return guard.forward(setHeatmapTrackingGuarded, arguments); },
165
+ /** @deprecated the earlier name of setHeatmapTracking, which it calls, with a warning */
166
+ trackHeatmap: function trackHeatmap(on) {
167
+ renamed('AppticsHeatmap.trackHeatmap', 'AppticsHeatmap.setHeatmapTracking'); // no i18n
168
+ return guard.forward(setHeatmapTrackingGuarded, arguments);
169
+ },
132
170
  };
133
171
  const setTrackingStatusGuarded = guard.guard('AppticsSettings.setTrackingStatus', consent.setTrackingStatus); // no i18n
134
172
  const getTrackingStatusGuarded = guard.guard('AppticsSettings.getTrackingStatus', consent.getTrackingStatus); // no i18n
@@ -149,7 +187,6 @@ const apptics = {
149
187
  AppticsSettings,
150
188
  AppticsHeatmap,
151
189
  };
152
- autoInit.scheduleAutoInit(Apptics);
153
190
 
154
191
  exports.Apptics = Apptics;
155
192
  exports.AppticsApi = AppticsApi;
@@ -1,8 +1,7 @@
1
1
  import { type ScreenRouteRule } from './core/constants.js';
2
2
  import type { AppticsConfig } from './types.js';
3
3
  /**
4
- * Starts the SDK. The config object is required: pass it directly, or let the console snippet
5
- * supply it (auto-init reads window.appticssettings._defaultoptions and calls init with it).
4
+ * Starts the SDK. The config object is required: the SDK starts only when the app calls this.
6
5
  * Returns true when the config has base_url, auth_key, app_domain and appversion and start-up has
7
6
  * begun (see ready()), false when it was already running, the config is missing or incomplete, or
8
7
  * there is no browser. Start-up calls app/addversion with those four, which answers with aaid, the
@@ -19,3 +18,15 @@ export declare function screenRouteRules(routes: unknown): ScreenRouteRule[];
19
18
  export declare function ready(): Promise<boolean>;
20
19
  /** Clears stored identity and queues, then starts again from the snippet. */
21
20
  export declare function reset(): void;
21
+ /**
22
+ * AppticsEvent.setClickTracking: click tracking from markup on or off, as the `track_click`
23
+ * config sets it. The listener stays; it checks the switch on every click.
24
+ */
25
+ export declare function setClickTracking(enabled?: boolean): void;
26
+ /**
27
+ * AppticsScreen.setScreenTracking: automatic screen tracking on or off, as the `track_screen`
28
+ * config sets it. Applied now once the SDK is running; before that it is only noted, and start()
29
+ * switches tracking to it. Like the other switches, the next init() (a reset() too) goes back to
30
+ * what its config says.
31
+ */
32
+ export declare function setScreenTracking(enabled?: boolean): void;
@@ -1,4 +1,4 @@
1
- /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
2
2
  'use strict';
3
3
 
4
4
  var constants = require('./core/constants.js');
@@ -116,10 +116,15 @@ var previousAppVersion = ''; // no i18n
116
116
  /**
117
117
  * Data stored for another app on this origin is discarded before anything else reads it,
118
118
  * including the stored app/addversion answer that would otherwise hand out that app's ids.
119
+ *
120
+ * Another app is a different base_url, app_domain or auth_key from the ones the stored data was
121
+ * registered with. Everything goes, the queues included, and start-up runs as on a first visit:
122
+ * app/addversion, device/add and the rest. Resolves once the store is empty.
119
123
  */
120
124
  function discardOtherAppData(settings) {
121
- // which app it is, and which version, are in app_version_info (serviceUrl, identifier and
122
- // appversion): no keys of their own. 2.0.0-beta's appkey and appversion are read this once
125
+ // which app it is, and which version, are in app_version_info (serviceUrl, identifier, a
126
+ // fingerprint of zak, and appversion): no keys of their own. 2.0.0-beta's appkey and
127
+ // appversion are read this once
123
128
  var info = storage.user_defaults.item('app_version_info') || {}; // no i18n
124
129
  var stored = !utils.isEmpty(info.serviceUrl) && !utils.isEmpty(info.identifier)
125
130
  ? appKey(info)
@@ -127,11 +132,17 @@ function discardOtherAppData(settings) {
127
132
  previousAppVersion = String((!utils.isEmpty(info.appversion) ? info.appversion : storage.user_defaults.item('appversion')) || ''); // no i18n
128
133
  storage.user_defaults.add('appkey', undefined); // no i18n
129
134
  storage.user_defaults.add('appversion', undefined); // no i18n
130
- if (!utils.isEmpty(stored) && stored !== appKey(settings)) {
131
- logger.Console.log('init: stored data belongs to another app, resetting'); // no i18n
132
- clearStorage();
133
- previousAppVersion = ''; // no i18n
134
- }
135
+ var otherApp = !utils.isEmpty(stored) && stored !== appKey(settings);
136
+ // a build that kept no fingerprint cannot tell: hasAppVersion() registers again, and records one
137
+ var otherKey = !utils.isEmpty(info.zakhash) && info.zakhash !== appversion.keyFingerprint(settings.zak);
138
+ if (!otherApp && !otherKey) {
139
+ return Promise.resolve();
140
+ }
141
+ logger.Console.log('init: stored data was registered with another ' + (otherApp ? 'base_url or app_domain' : 'auth_key') + ', clearing it and starting as a first visit'); // no i18n
142
+ previousAppVersion = ''; // no i18n
143
+ // the remote config values read from the store, which is about to go
144
+ hooks.hooks.resetRemoteConfig();
145
+ return clearStorage();
135
146
  }
136
147
  /**
137
148
  * Timing an app may tune in init(). Each has a range: a value outside it is ignored with a
@@ -175,15 +186,20 @@ function applyIntervals(config) {
175
186
  }
176
187
  }
177
188
  }
189
+ /** Everything the SDK stores: settings, ids and every queue. Resolves once it is all gone. */
178
190
  function clearStorage() {
179
191
  attempts.clearAttempts();
180
192
  storage.user_defaults.clear();
181
- storage.engagement_transactions.clear();
182
- storage.error_transactions.clear();
193
+ return Promise.all([
194
+ storage.engagement_transactions, storage.error_transactions, storage.heatmap_transactions, storage.remotelog_transactions, storage.feedbacklog_transactions,
195
+ ].map(function (queue) {
196
+ return queue.clear();
197
+ })).then(function () {
198
+ return undefined;
199
+ });
183
200
  }
184
201
  /**
185
- * Starts the SDK. The config object is required: pass it directly, or let the console snippet
186
- * supply it (auto-init reads window.appticssettings._defaultoptions and calls init with it).
202
+ * Starts the SDK. The config object is required: the SDK starts only when the app calls this.
187
203
  * Returns true when the config has base_url, auth_key, app_domain and appversion and start-up has
188
204
  * begun (see ready()), false when it was already running, the config is missing or incomplete, or
189
205
  * there is no browser. Start-up calls app/addversion with those four, which answers with aaid, the
@@ -281,6 +297,10 @@ function init(config) {
281
297
  // screen view can be stored
282
298
  state._ZAP._config.track_screen = typeof config.track_screen === 'boolean' ? config.track_screen : constants.AP_CONFIG.track_screen; // no i18n
283
299
  state._ZAP._config.screen_routes = screenRouteRules(config.screen_routes);
300
+ // uncaught errors and tagged clicks, on unless the config says false: the listeners check
301
+ // these as each error or click happens
302
+ state._ZAP._config.track_error = typeof config.track_error === 'boolean' ? config.track_error : constants.AP_CONFIG.track_error; // no i18n
303
+ state._ZAP._config.track_click = typeof config.track_click === 'boolean' ? config.track_click : constants.AP_CONFIG.track_click; // no i18n
284
304
  // a theme in the config wins; without one, what AppticsFeedback.setFeedbackTheme set stays
285
305
  if (config.feedback_theme === 'light' || config.feedback_theme === 'dark' || config.feedback_theme === 'auto') { // no i18n
286
306
  state._ZAP._config.feedback_theme = config.feedback_theme;
@@ -302,39 +322,11 @@ function init(config) {
302
322
  state._ZAP._pending = [];
303
323
  return false;
304
324
  }
305
- discardOtherAppData(state._ZAP._defaultoptions);
306
- // app/addversion is the first call and everything waits on it: it is what turns the four
307
- // values init() was given into aaid, the portal and project ids every url carries, and
308
- // appreleaseversionid, which metaWebSDKV2 refuses a payload without
309
- return appversion.registerAppVersion().then(function (registered) {
325
+ return discardOtherAppData(state._ZAP._defaultoptions).then(function () {
310
326
  if (myGeneration !== generation) {
311
327
  return false;
312
328
  }
313
- if (!registered && appversion.appVersionFailedForNetwork()) {
314
- // a first visit with no network: start once it is back, keeping what the app
315
- // tracks until then queued, rather than giving up for the rest of the page
316
- logger.warnAlways('Apptics.init: offline, so app/addversion is tried again when the browser is back online; calls made until then are kept'); // no i18n
317
- return registerWhenOnline(myGeneration).then(function (ok) {
318
- if (myGeneration !== generation) {
319
- return false;
320
- }
321
- if (!ok) {
322
- state._ZAP._initialised = false;
323
- state._ZAP._token = ''; // no i18n
324
- state._ZAP._pending = [];
325
- return false;
326
- }
327
- return start(config, myGeneration);
328
- });
329
- }
330
- if (!registered) {
331
- logger.warnAlways('Apptics.init: app/addversion did not return the app ids, not starting'); // no i18n
332
- state._ZAP._initialised = false;
333
- state._ZAP._token = ''; // no i18n
334
- state._ZAP._pending = [];
335
- return false;
336
- }
337
- return start(config, myGeneration);
329
+ return startUp(config, myGeneration);
338
330
  });
339
331
  }).catch(function (err) {
340
332
  logger.Console.error('Apptics.init: start-up failed', err); // no i18n
@@ -342,6 +334,42 @@ function init(config) {
342
334
  });
343
335
  return true;
344
336
  }
337
+ /** Start-up from app/addversion on, once the store holds only this app's data. */
338
+ function startUp(config, myGeneration) {
339
+ // app/addversion is the first call and everything waits on it: it is what turns the four
340
+ // values init() was given into aaid, the portal and project ids every url carries, and
341
+ // appreleaseversionid, which metaWebSDKV2 refuses a payload without
342
+ return appversion.registerAppVersion().then(function (registered) {
343
+ if (myGeneration !== generation) {
344
+ return false;
345
+ }
346
+ if (!registered && appversion.appVersionFailedForNetwork()) {
347
+ // a first visit with no network: start once it is back, keeping what the app
348
+ // tracks until then queued, rather than giving up for the rest of the page
349
+ logger.warnAlways('Apptics.init: offline, so app/addversion is tried again when the browser is back online; calls made until then are kept'); // no i18n
350
+ return registerWhenOnline(myGeneration).then(function (ok) {
351
+ if (myGeneration !== generation) {
352
+ return false;
353
+ }
354
+ if (!ok) {
355
+ state._ZAP._initialised = false;
356
+ state._ZAP._token = ''; // no i18n
357
+ state._ZAP._pending = [];
358
+ return false;
359
+ }
360
+ return start(config, myGeneration);
361
+ });
362
+ }
363
+ if (!registered) {
364
+ logger.warnAlways('Apptics.init: app/addversion did not return the app ids, not starting'); // no i18n
365
+ state._ZAP._initialised = false;
366
+ state._ZAP._token = ''; // no i18n
367
+ state._ZAP._pending = [];
368
+ return false;
369
+ }
370
+ return start(config, myGeneration);
371
+ });
372
+ }
345
373
  /** How often a start-up waiting on the network tries app/addversion again, besides on `online`. */
346
374
  const OFFLINE_RETRY_MS = 60 * 1000;
347
375
  /**
@@ -448,6 +476,8 @@ function start(config, myGeneration) {
448
476
  state._ZAP._token = String(state._ZAP._defaultoptions.aaid);
449
477
  // last known server settings (getupdates) apply before anything is tracked
450
478
  index.restoreServerSettings();
479
+ // the user this browser was tracking as, before getsdkconfig is asked: it carries their ids
480
+ index$1.getUserInfo();
451
481
  // a new release of the app, against the version the stored data was for (see
452
482
  // discardOtherAppData): a first visit has none, and is no change
453
483
  var appVersionChanged = previousAppVersion !== '' && previousAppVersion != state._ZAP._defaultoptions.appversion; // no i18n
@@ -466,9 +496,11 @@ function start(config, myGeneration) {
466
496
  }
467
497
  /** The rest of start-up, once the device is set up. */
468
498
  function startTracking(appVersionChanged, myGeneration) {
469
- // no getsdkconfig here, straight after app/addversion: it is asked for once device/add has
470
- // succeeded (registerDeviceWithApptics), then every getupdates_interval. A returning visit
471
- // starts from the settings saved by the last one (restoreServerSettings, in start())
499
+ // getsdkconfig, once per page load and then at each answer's next_check_after. A first visit
500
+ // asked as soon as device/add succeeded (registerDeviceWithApptics) and this does nothing; a
501
+ // returning visit, whose device is registered, asks now, after app/addversion. Until it
502
+ // answers, the settings saved by the last visit apply (restoreServerSettings, in start())
503
+ index.startServerSettingChecks();
472
504
  if (appVersionChanged) {
473
505
  state._ZAP._device_info.appversionid = ''; // no i18n
474
506
  index.updateDeviceWithApptics(state._ZAP._device_info).then(function (result) {
@@ -483,7 +515,6 @@ function startTracking(appVersionChanged, myGeneration) {
483
515
  state._ZAP._device_info.connectionType = env.getConnectionType();
484
516
  attachListeners();
485
517
  state._ZAP._properties.orientation = env.getOrientation();
486
- index$1.getUserInfo();
487
518
  return session.checkAndUpdateSession().then(function () {
488
519
  if (myGeneration !== generation) {
489
520
  return false;
@@ -518,6 +549,7 @@ function startTracking(appVersionChanged, myGeneration) {
518
549
  function reset() {
519
550
  generation++;
520
551
  scheduler.stopTimers();
552
+ session.resetInactivity();
521
553
  // the wrappers come off with everything else; the init() below puts them back if the config
522
554
  // asked for them, so a reset that has no config to restore leaves XHR and fetch untouched
523
555
  autoApi.enableApiTracking(false);
@@ -548,6 +580,26 @@ function reset() {
548
580
  function isActive() {
549
581
  return state._ZAP._ready;
550
582
  }
583
+ /**
584
+ * AppticsEvent.setClickTracking: click tracking from markup on or off, as the `track_click`
585
+ * config sets it. The listener stays; it checks the switch on every click.
586
+ */
587
+ function setClickTracking(enabled) {
588
+ state._ZAP._config.track_click = typeof enabled === 'boolean' ? enabled : true; // no i18n
589
+ logger.Console.log('click tracking: ' + (state._ZAP._config.track_click ? 'on' : 'off')); // no i18n
590
+ }
591
+ /**
592
+ * AppticsScreen.setScreenTracking: automatic screen tracking on or off, as the `track_screen`
593
+ * config sets it. Applied now once the SDK is running; before that it is only noted, and start()
594
+ * switches tracking to it. Like the other switches, the next init() (a reset() too) goes back to
595
+ * what its config says.
596
+ */
597
+ function setScreenTracking(enabled) {
598
+ state._ZAP._config.track_screen = typeof enabled === 'boolean' ? enabled : true; // no i18n
599
+ if (isActive()) {
600
+ autoScreen.enableScreenTracking(state._ZAP._config.track_screen);
601
+ }
602
+ }
551
603
  /**
552
604
  * A click-tracking attribute, in either spelling: `apeventaction`, or `data-apeventaction`, which
553
605
  * is valid HTML and what React and TypeScript accept without declaring the attribute.
@@ -563,7 +615,7 @@ function trackingSelector(name) {
563
615
  // Declarative click tracking: <el apeventaction="name" apeventprops='{"k":"v"}'> inside <el apgroupaction="group">,
564
616
  // or the same attributes with a data- prefix
565
617
  function onDocumentClick(event) {
566
- if (!window.appticsReadyStatus || !isActive()) {
618
+ if (!window.appticsReadyStatus || !isActive() || !state._ZAP._config.track_click) {
567
619
  return;
568
620
  }
569
621
  var start = event.target;
@@ -579,7 +631,8 @@ function onDocumentClick(event) {
579
631
  }
580
632
  var eventName = trackingAttribute(targetElem, 'apeventaction') || ''; // no i18n
581
633
  var groupElem = targetElem.closest(trackingSelector('apgroupaction')); // no i18n
582
- var groupName = (groupElem && trackingAttribute(groupElem, 'apgroupaction')) || constants.AP_CONFIG.default_group_name; // no i18n
634
+ // no apgroupaction around it: trackEvent refuses it and says the group is missing
635
+ var groupName = (groupElem && trackingAttribute(groupElem, 'apgroupaction')) || undefined; // no i18n
583
636
  var eventProps = {};
584
637
  var rawProps = trackingAttribute(targetElem, 'apeventprops'); // no i18n
585
638
  if (!utils.isEmpty(rawProps)) {
@@ -603,10 +656,18 @@ function onDocumentClick(event) {
603
656
  function onPageHidden() {
604
657
  if (!isActive())
605
658
  return;
659
+ // the moment the user left: the session ends at it if they are not back within inactiveduration
660
+ session.markTabInactive(sendEndedSession);
606
661
  session.updateScreenWithEndtime();
607
662
  scheduler.flush(true);
608
663
  logger.Console.log('page hidden: closing the open screen and flushing'); // no i18n
609
664
  }
665
+ /** A session that inactivity ended while the tab was away: sent now, not when the user returns. */
666
+ function sendEndedSession() {
667
+ if (!isActive())
668
+ return;
669
+ scheduler.flush();
670
+ }
610
671
  /**
611
672
  * The tab is closing, or the page is being replaced or frozen into the back/forward cache.
612
673
  * The session ends here, and everything queued goes out by keepalive, since a normal
@@ -638,14 +699,18 @@ function attachListeners() {
638
699
  window.addEventListener('blur', function () {
639
700
  if (!isActive())
640
701
  return;
702
+ // focus moving into an iframe on the page blurs the window too, and the user is still here
703
+ if (document.activeElement && document.activeElement.tagName === 'IFRAME')
704
+ return; // no i18n
641
705
  logger.Console.log('Window lost focus, user switched to another window or application'); // no i18n
642
- session.updateLastActiveTimeOfSession();
706
+ session.markTabInactive(sendEndedSession);
643
707
  });
644
708
  // Track when the window gains focus (user switches back to the window)
645
709
  window.addEventListener('focus', function () {
646
710
  if (!isActive())
647
711
  return;
648
712
  logger.Console.log('Window regained focus, user switched back to the window'); // no i18n
713
+ session.markTabActive();
649
714
  session.checkAndUpdateSession();
650
715
  scheduler.startTimers();
651
716
  });
@@ -656,6 +721,7 @@ function attachListeners() {
656
721
  if (!isActive() || !event.persisted)
657
722
  return;
658
723
  logger.Console.log('restored from the back/forward cache: starting a new session'); // no i18n
724
+ session.markTabActive();
659
725
  // the screen the page was left on starts a new view, in the new session
660
726
  session.checkAndUpdateSession().then(track.resumeScreen);
661
727
  scheduler.startTimers();
@@ -667,12 +733,12 @@ function attachListeners() {
667
733
  onPageHidden();
668
734
  return;
669
735
  }
670
- // back in view: the server's tracking flags may have changed while we were away
671
- logger.Console.log('page visible: refreshing the server settings'); // no i18n
736
+ // back in view. getsdkconfig is not asked here: only at its next_check_after, on a tab's
737
+ // first page load, and when a user is registered or getupdates reports a change
738
+ session.markTabActive();
672
739
  // hiding ended the screen view; the screen the user is back on starts a new one, after the
673
740
  // session is settled so the view belongs to the right one
674
741
  session.checkAndUpdateSession().then(track.resumeScreen);
675
- index.refreshServerSettings();
676
742
  });
677
743
  // if we are running in cordova use ondeviceready otherwise onload
678
744
  window.addEventListener(window.cordova ? 'deviceready' : 'load', function () {
@@ -706,7 +772,7 @@ function attachListeners() {
706
772
  });
707
773
  }
708
774
  window.addEventListener('unhandledrejection', function (event) {
709
- if (isActive() && state._ZAP._isGlobalErrorTracking) {
775
+ if (isActive() && state._ZAP._config.track_error) {
710
776
  track$1.trackError(event);
711
777
  }
712
778
  });
@@ -714,7 +780,7 @@ function attachListeners() {
714
780
  // element, and it does not bubble, so a bubbling listener never hears of it. One listener
715
781
  // hears both kinds, the window's own errors included, so none is counted twice
716
782
  window.addEventListener('error', function (event) {
717
- if (!isActive() || !state._ZAP._isGlobalErrorTracking) {
783
+ if (!isActive() || !state._ZAP._config.track_error) {
718
784
  return;
719
785
  }
720
786
  var target = event.target;
@@ -732,3 +798,5 @@ exports.init = init;
732
798
  exports.ready = ready;
733
799
  exports.reset = reset;
734
800
  exports.screenRouteRules = screenRouteRules;
801
+ exports.setClickTracking = setClickTracking;
802
+ exports.setScreenTracking = setScreenTracking;
@@ -1,4 +1,4 @@
1
- /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
2
2
  'use strict';
3
3
 
4
4
  var state = require('../core/state.js');
@@ -1,4 +1,4 @@
1
- /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
2
2
  'use strict';
3
3
 
4
4
  var storage = require('../core/storage.js');
@@ -1,4 +1,4 @@
1
- /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
2
2
  'use strict';
3
3
 
4
4
  var logger = require('../core/logger.js');
@@ -1,24 +1,31 @@
1
1
  /**
2
- * Asks for the rule set, if anything has changed since the last one.
2
+ * Asks for the rule set: the whole of it with flagtime 0 on the first fetch of a page load, then
3
+ * only what changed since the last answered request, which is merged into what is stored.
3
4
  *
4
- * Resolves with the parameters as they stand afterwards, whether or not the answer carried a new
5
- * rule set — an answer with no `remoteconfig` block means nothing has changed, which is the
6
- * normal case and not a failure.
5
+ * Resolves with the answer, whether or not it carried a rule set — a later answer with no
6
+ * `remoteconfig` block means nothing has changed, which is the normal case and not a failure.
7
7
  *
8
- * A second caller joins the first rather than making another request.
8
+ * With `whole`, a cold fetch: flagtime 0 whatever this page has fetched already, and the answer
9
+ * replaces the stored set as the first fetch of a page load does.
10
+ *
11
+ * A second caller joins the first rather than making another request. A cold fetch joins one
12
+ * only when it asked with flagtime 0 too, and otherwise asks once it has answered.
9
13
  */
10
- export declare function fetchRemoteConfig(): Promise<Record<string, unknown>>;
14
+ export declare function fetchRemoteConfig(whole?: boolean): Promise<Record<string, unknown>>;
11
15
  /**
12
16
  * reset(): forgets the rule set, its values and what the server last reported, and disowns a
13
17
  * request still in flight, whose answer would otherwise put the old rule set back.
14
18
  */
15
19
  export declare function resetRemoteConfig(): void;
16
20
  /**
17
- * Makes sure the values are this page's own: from a fetch that just succeeded, or one within
18
- * CACHE_MS. Resolves true when they are, false when the fetch failed or could not be made — the
19
- * caller then decides whether stored values will do. Never rejects.
21
+ * Makes sure the values are this page's own: from a fetch on this page that succeeded, kept up to
22
+ * date by the polling after it. With `coldFetch`, a fetch with flagtime 0 now, whatever this page
23
+ * already has, whose answer replaces what is stored: at most COLD_LIMIT a minute, and one past
24
+ * that answers from what this page has. Resolves true when they are, false when the
25
+ * fetch failed or could not be made — the caller then decides whether stored values will do.
26
+ * Never rejects.
20
27
  *
21
28
  * Waits for start-up and for the device to be registered, which a first visit is still doing
22
29
  * when ready() resolves: getupdates is refused without the device ids.
23
30
  */
24
- export declare function obtain(): Promise<boolean>;
31
+ export declare function obtain(coldFetch?: boolean): Promise<boolean>;