@zoho_apptics/apptics-js-sdk 1.0.1 → 2.0.0-beta

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 (226) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/LICENSE +13 -0
  3. package/README.md +747 -11
  4. package/dist/apptics.esm.min.js +3 -0
  5. package/dist/apptics.esm.min.js.map +1 -0
  6. package/dist/apptics.min.js +3 -0
  7. package/dist/apptics.min.js.map +1 -0
  8. package/dist/chunks/batch-BU_mTpm1.min.js +3 -0
  9. package/dist/chunks/batch-BU_mTpm1.min.js.map +1 -0
  10. package/dist/chunks/logs-Bea5zUW_.min.js +3 -0
  11. package/dist/chunks/logs-Bea5zUW_.min.js.map +1 -0
  12. package/dist/cjs/auto-init.d.ts +8 -0
  13. package/dist/cjs/auto-init.js +32 -0
  14. package/dist/cjs/core/attempts.d.ts +28 -0
  15. package/dist/cjs/core/attempts.js +113 -0
  16. package/dist/cjs/core/batch.d.ts +32 -0
  17. package/dist/cjs/core/batch.js +115 -0
  18. package/dist/cjs/core/callsite.d.ts +28 -0
  19. package/dist/cjs/core/callsite.js +93 -0
  20. package/dist/cjs/core/consent.d.ts +23 -0
  21. package/dist/cjs/core/consent.js +130 -0
  22. package/dist/cjs/core/constants.d.ts +212 -0
  23. package/dist/cjs/core/constants.js +299 -0
  24. package/dist/cjs/core/db.d.ts +40 -0
  25. package/dist/cjs/core/db.js +334 -0
  26. package/dist/cjs/core/debug.d.ts +22 -0
  27. package/dist/cjs/core/debug.js +88 -0
  28. package/dist/cjs/core/env.d.ts +28 -0
  29. package/dist/cjs/core/env.js +267 -0
  30. package/dist/cjs/core/framework-id.d.ts +1 -0
  31. package/dist/cjs/core/framework-id.js +9 -0
  32. package/dist/cjs/core/guard.d.ts +2 -0
  33. package/dist/cjs/core/guard.js +72 -0
  34. package/dist/cjs/core/hooks.d.ts +41 -0
  35. package/dist/cjs/core/hooks.js +23 -0
  36. package/dist/cjs/core/logger.d.ts +16 -0
  37. package/dist/cjs/core/logger.js +86 -0
  38. package/dist/cjs/core/state.d.ts +69 -0
  39. package/dist/cjs/core/state.js +78 -0
  40. package/dist/cjs/core/storage.d.ts +46 -0
  41. package/dist/cjs/core/storage.js +229 -0
  42. package/dist/cjs/core/transport.d.ts +83 -0
  43. package/dist/cjs/core/transport.js +441 -0
  44. package/dist/cjs/core/utils.d.ts +26 -0
  45. package/dist/cjs/core/utils.js +175 -0
  46. package/dist/cjs/core/validate.d.ts +18 -0
  47. package/dist/cjs/core/validate.js +233 -0
  48. package/dist/cjs/device/appversion.d.ts +20 -0
  49. package/dist/cjs/device/appversion.js +158 -0
  50. package/dist/cjs/device/index.d.ts +23 -0
  51. package/dist/cjs/device/index.js +372 -0
  52. package/dist/cjs/engagement/api-rules.d.ts +84 -0
  53. package/dist/cjs/engagement/api-rules.js +219 -0
  54. package/dist/cjs/engagement/auto-api.d.ts +7 -0
  55. package/dist/cjs/engagement/auto-api.js +200 -0
  56. package/dist/cjs/engagement/auto-screen.d.ts +16 -0
  57. package/dist/cjs/engagement/auto-screen.js +241 -0
  58. package/dist/cjs/engagement/defined-events.d.ts +23 -0
  59. package/dist/cjs/engagement/defined-events.js +58 -0
  60. package/dist/cjs/engagement/send.d.ts +6 -0
  61. package/dist/cjs/engagement/send.js +99 -0
  62. package/dist/cjs/engagement/session.d.ts +42 -0
  63. package/dist/cjs/engagement/session.js +327 -0
  64. package/dist/cjs/engagement/track.d.ts +56 -0
  65. package/dist/cjs/engagement/track.js +350 -0
  66. package/dist/cjs/errors/send.d.ts +6 -0
  67. package/dist/cjs/errors/send.js +73 -0
  68. package/dist/cjs/errors/track.d.ts +4 -0
  69. package/dist/cjs/errors/track.js +127 -0
  70. package/dist/cjs/feedback/controls.d.ts +31 -0
  71. package/dist/cjs/feedback/controls.js +286 -0
  72. package/dist/cjs/feedback/index.d.ts +8 -0
  73. package/dist/cjs/feedback/index.js +37 -0
  74. package/dist/cjs/feedback/logs.d.ts +40 -0
  75. package/dist/cjs/feedback/logs.js +202 -0
  76. package/dist/cjs/feedback/send.d.ts +25 -0
  77. package/dist/cjs/feedback/send.js +178 -0
  78. package/dist/cjs/feedback/template.d.ts +2 -0
  79. package/dist/cjs/feedback/template.js +162 -0
  80. package/dist/cjs/feedback/ui.d.ts +55 -0
  81. package/dist/cjs/feedback/ui.js +631 -0
  82. package/dist/cjs/heatmap/index.d.ts +16 -0
  83. package/dist/cjs/heatmap/index.js +22 -0
  84. package/dist/cjs/heatmap/send.d.ts +13 -0
  85. package/dist/cjs/heatmap/send.js +82 -0
  86. package/dist/cjs/heatmap/track.d.ts +4 -0
  87. package/dist/cjs/heatmap/track.js +377 -0
  88. package/dist/cjs/index.d.ts +68 -0
  89. package/dist/cjs/index.js +150 -0
  90. package/dist/cjs/lifecycle.d.ts +14 -0
  91. package/dist/cjs/lifecycle.js +538 -0
  92. package/dist/cjs/package.json +3 -0
  93. package/dist/cjs/remoteconfig/custom.d.ts +10 -0
  94. package/dist/cjs/remoteconfig/custom.js +78 -0
  95. package/dist/cjs/remoteconfig/evaluate.d.ts +24 -0
  96. package/dist/cjs/remoteconfig/evaluate.js +171 -0
  97. package/dist/cjs/remoteconfig/fetch.d.ts +24 -0
  98. package/dist/cjs/remoteconfig/fetch.js +214 -0
  99. package/dist/cjs/remoteconfig/index.d.ts +13 -0
  100. package/dist/cjs/remoteconfig/index.js +90 -0
  101. package/dist/cjs/remoteconfig/store.d.ts +18 -0
  102. package/dist/cjs/remoteconfig/store.js +98 -0
  103. package/dist/cjs/remotelog/gate.d.ts +11 -0
  104. package/dist/cjs/remotelog/gate.js +54 -0
  105. package/dist/cjs/remotelog/index.d.ts +25 -0
  106. package/dist/cjs/remotelog/index.js +55 -0
  107. package/dist/cjs/remotelog/logger.d.ts +28 -0
  108. package/dist/cjs/remotelog/logger.js +139 -0
  109. package/dist/cjs/remotelog/send.d.ts +13 -0
  110. package/dist/cjs/remotelog/send.js +153 -0
  111. package/dist/cjs/scheduler.d.ts +8 -0
  112. package/dist/cjs/scheduler.js +78 -0
  113. package/dist/cjs/types.d.ts +312 -0
  114. package/dist/cjs/user/index.d.ts +33 -0
  115. package/dist/cjs/user/index.js +178 -0
  116. package/dist/esm/auto-init.d.ts +8 -0
  117. package/dist/esm/auto-init.js +29 -0
  118. package/dist/esm/core/attempts.d.ts +28 -0
  119. package/dist/esm/core/attempts.js +106 -0
  120. package/dist/esm/core/batch.d.ts +32 -0
  121. package/dist/esm/core/batch.js +108 -0
  122. package/dist/esm/core/callsite.d.ts +28 -0
  123. package/dist/esm/core/callsite.js +89 -0
  124. package/dist/esm/core/consent.d.ts +23 -0
  125. package/dist/esm/core/consent.js +120 -0
  126. package/dist/esm/core/constants.d.ts +212 -0
  127. package/dist/esm/core/constants.js +277 -0
  128. package/dist/esm/core/db.d.ts +40 -0
  129. package/dist/esm/core/db.js +324 -0
  130. package/dist/esm/core/debug.d.ts +22 -0
  131. package/dist/esm/core/debug.js +81 -0
  132. package/dist/esm/core/env.d.ts +28 -0
  133. package/dist/esm/core/env.js +251 -0
  134. package/dist/esm/core/framework-id.d.ts +1 -0
  135. package/dist/esm/core/framework-id.js +7 -0
  136. package/dist/esm/core/guard.d.ts +2 -0
  137. package/dist/esm/core/guard.js +70 -0
  138. package/dist/esm/core/hooks.d.ts +41 -0
  139. package/dist/esm/core/hooks.js +21 -0
  140. package/dist/esm/core/logger.d.ts +16 -0
  141. package/dist/esm/core/logger.js +82 -0
  142. package/dist/esm/core/state.d.ts +69 -0
  143. package/dist/esm/core/state.js +73 -0
  144. package/dist/esm/core/storage.d.ts +46 -0
  145. package/dist/esm/core/storage.js +219 -0
  146. package/dist/esm/core/transport.d.ts +83 -0
  147. package/dist/esm/core/transport.js +425 -0
  148. package/dist/esm/core/utils.d.ts +26 -0
  149. package/dist/esm/core/utils.js +161 -0
  150. package/dist/esm/core/validate.d.ts +18 -0
  151. package/dist/esm/core/validate.js +226 -0
  152. package/dist/esm/device/appversion.d.ts +20 -0
  153. package/dist/esm/device/appversion.js +153 -0
  154. package/dist/esm/device/index.d.ts +23 -0
  155. package/dist/esm/device/index.js +362 -0
  156. package/dist/esm/engagement/api-rules.d.ts +84 -0
  157. package/dist/esm/engagement/api-rules.js +211 -0
  158. package/dist/esm/engagement/auto-api.d.ts +7 -0
  159. package/dist/esm/engagement/auto-api.js +198 -0
  160. package/dist/esm/engagement/auto-screen.d.ts +16 -0
  161. package/dist/esm/engagement/auto-screen.js +238 -0
  162. package/dist/esm/engagement/defined-events.d.ts +23 -0
  163. package/dist/esm/engagement/defined-events.js +55 -0
  164. package/dist/esm/engagement/send.d.ts +6 -0
  165. package/dist/esm/engagement/send.js +96 -0
  166. package/dist/esm/engagement/session.d.ts +42 -0
  167. package/dist/esm/engagement/session.js +315 -0
  168. package/dist/esm/engagement/track.d.ts +56 -0
  169. package/dist/esm/engagement/track.js +340 -0
  170. package/dist/esm/errors/send.d.ts +6 -0
  171. package/dist/esm/errors/send.js +70 -0
  172. package/dist/esm/errors/track.d.ts +4 -0
  173. package/dist/esm/errors/track.js +123 -0
  174. package/dist/esm/feedback/controls.d.ts +31 -0
  175. package/dist/esm/feedback/controls.js +280 -0
  176. package/dist/esm/feedback/index.d.ts +8 -0
  177. package/dist/esm/feedback/index.js +30 -0
  178. package/dist/esm/feedback/logs.d.ts +40 -0
  179. package/dist/esm/feedback/logs.js +188 -0
  180. package/dist/esm/feedback/send.d.ts +25 -0
  181. package/dist/esm/feedback/send.js +175 -0
  182. package/dist/esm/feedback/template.d.ts +2 -0
  183. package/dist/esm/feedback/template.js +159 -0
  184. package/dist/esm/feedback/ui.d.ts +55 -0
  185. package/dist/esm/feedback/ui.js +626 -0
  186. package/dist/esm/heatmap/index.d.ts +16 -0
  187. package/dist/esm/heatmap/index.js +17 -0
  188. package/dist/esm/heatmap/send.d.ts +13 -0
  189. package/dist/esm/heatmap/send.js +79 -0
  190. package/dist/esm/heatmap/track.d.ts +4 -0
  191. package/dist/esm/heatmap/track.js +374 -0
  192. package/dist/esm/index.d.ts +68 -0
  193. package/dist/esm/index.js +122 -0
  194. package/dist/esm/lifecycle.d.ts +14 -0
  195. package/dist/esm/lifecycle.js +534 -0
  196. package/dist/esm/package.json +3 -0
  197. package/dist/esm/remoteconfig/custom.d.ts +10 -0
  198. package/dist/esm/remoteconfig/custom.js +74 -0
  199. package/dist/esm/remoteconfig/evaluate.d.ts +24 -0
  200. package/dist/esm/remoteconfig/evaluate.js +166 -0
  201. package/dist/esm/remoteconfig/fetch.d.ts +24 -0
  202. package/dist/esm/remoteconfig/fetch.js +210 -0
  203. package/dist/esm/remoteconfig/index.d.ts +13 -0
  204. package/dist/esm/remoteconfig/index.js +85 -0
  205. package/dist/esm/remoteconfig/store.d.ts +18 -0
  206. package/dist/esm/remoteconfig/store.js +91 -0
  207. package/dist/esm/remotelog/gate.d.ts +11 -0
  208. package/dist/esm/remotelog/gate.js +48 -0
  209. package/dist/esm/remotelog/index.d.ts +25 -0
  210. package/dist/esm/remotelog/index.js +51 -0
  211. package/dist/esm/remotelog/logger.d.ts +28 -0
  212. package/dist/esm/remotelog/logger.js +136 -0
  213. package/dist/esm/remotelog/send.d.ts +13 -0
  214. package/dist/esm/remotelog/send.js +149 -0
  215. package/dist/esm/scheduler.d.ts +8 -0
  216. package/dist/esm/scheduler.js +74 -0
  217. package/dist/esm/types.d.ts +312 -0
  218. package/dist/esm/user/index.d.ts +33 -0
  219. package/dist/esm/user/index.js +170 -0
  220. package/dist/feedback.esm.min.js +3 -0
  221. package/dist/feedback.esm.min.js.map +1 -0
  222. package/dist/heatmap.esm.min.js +3 -0
  223. package/dist/heatmap.esm.min.js.map +1 -0
  224. package/dist/style.css +1 -0
  225. package/package.json +124 -7
  226. package/src/appticssdk.js +0 -3817
@@ -0,0 +1,79 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ import { _ZAP } from '../core/state.js';
3
+ import { Console, warnAlways } from '../core/logger.js';
4
+ import { cloneObject } from '../core/utils.js';
5
+ import { heatmap_transactions } from '../core/storage.js';
6
+ import { is_apptics_disabled } from '../core/env.js';
7
+ import { shouldTrackOrSendData } from '../core/consent.js';
8
+ import { defer, clearDefer, withSendLock, freshItems, awaitUnlessClosing, sendBatch } from '../core/batch.js';
9
+ import { isPermanentRefusal } from '../core/transport.js';
10
+ import { hooks } from '../core/hooks.js';
11
+
12
+ /**
13
+ * Sends queued heatmap records to heatmap/add.
14
+ *
15
+ * Shaped like the error and engagement senders, because the queue behaves the same way: records
16
+ * are stored first and sent on the flush timer, a failed send leaves them for the next one, and
17
+ * `forget` is used on page hide so the last batch survives the page going away.
18
+ *
19
+ * Gated on the server's own heatmap flag (getsdkconfig module 18), not on engagement: an app may
20
+ * want events while declining to have every click's coordinates recorded.
21
+ */
22
+ function sendHeatmapData(forget) {
23
+ if (is_apptics_disabled() || !shouldTrackOrSendData() || !_ZAP._heatmapTracking) {
24
+ return Promise.resolve();
25
+ }
26
+ if (navigator.onLine == false) {
27
+ Console.warn('sendHeatmapData: No Network'); // no i18n
28
+ return Promise.resolve();
29
+ }
30
+ if (_ZAP._sending) {
31
+ defer(sendHeatmapData);
32
+ return Promise.resolve();
33
+ }
34
+ _ZAP._sending = true;
35
+ clearDefer();
36
+ return withSendLock('heatmaps', function () {
37
+ return freshItems(heatmap_transactions, function () { return true; },
38
+ // aged by when the record happened, not when its session began: a tab left open for
39
+ // days would otherwise make every new record look older than the retention window
40
+ // and have it dropped unsent
41
+ function (item) { return (item.triggered_time || item.session_start_time); }).then(function (items) {
42
+ if (items.length == 0) {
43
+ return;
44
+ }
45
+ var data = [];
46
+ var sent = [];
47
+ cloneObject(items).forEach(function (item) {
48
+ sent.push({ ...item });
49
+ // `id` is the queue's own key, not something the endpoint declares
50
+ delete item.id;
51
+ data.push(item);
52
+ });
53
+ return awaitUnlessClosing(requestToSendHeatmaps({ data: data }, forget).then(function () {
54
+ return heatmap_transactions.remove(sent);
55
+ }, function (err) {
56
+ // the server will never accept this batch. Keeping it would block every later
57
+ // batch behind it for good, so it is dropped and said out loud
58
+ if (isPermanentRefusal(err)) {
59
+ warnAlways('apptics: the server refused these heatmap records, so they were dropped: ' + String(err && err.message)); // no i18n
60
+ return heatmap_transactions.remove(sent);
61
+ }
62
+ return Promise.reject(err);
63
+ }), forget, 'sendHeatmapData'); // no i18n
64
+ });
65
+ }).catch(function (err) {
66
+ Console.log('sendHeatmapData:' + err); // no i18n
67
+ }).then(function () {
68
+ _ZAP._sending = false;
69
+ });
70
+ }
71
+ function requestToSendHeatmaps(_payload, forget) {
72
+ var label = 'requestToSendHeatmaps'; // no i18n
73
+ return sendBatch('heatmap', label, _payload, forget); // no i18n
74
+ }
75
+ // the scheduler flushes through this, so importing the heatmap entry is what puts heatmap
76
+ // records on the flush timer at all
77
+ hooks.sendHeatmaps = sendHeatmapData;
78
+
79
+ export { requestToSendHeatmaps, sendHeatmapData };
@@ -0,0 +1,4 @@
1
+ /** Turns capture on or off. Listeners are passive, so they never delay a click or a scroll. */
2
+ export declare function enableHeatmap(status?: boolean): void;
3
+ /** Forgets what this visit recorded. reset() calls it; the cap starts again from zero. */
4
+ export declare function resetHeatmapSession(): void;
@@ -0,0 +1,374 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ import { AP_LOG_MODULE, AP_CONFIG, AP_TRACKING_STATUS } from '../core/constants.js';
3
+ import { getConfig, _ZAP } from '../core/state.js';
4
+ import { Console, logFailure } from '../core/logger.js';
5
+ import { nowMs, isEmpty, getNewUUID } from '../core/utils.js';
6
+ import { heatmap_transactions } from '../core/storage.js';
7
+ import { commitPendingSession } from '../engagement/session.js';
8
+ import { getConnectionType, getNetworkStatus, getOrientation } from '../core/env.js';
9
+ import { canTrackHeatmap, getTrackingStatus } from '../core/consent.js';
10
+ import { screenForRecord } from '../engagement/track.js';
11
+ import { hooks } from '../core/hooks.js';
12
+ import { noteDebugActivity } from '../core/debug.js';
13
+
14
+ /**
15
+ * Where people click and how far they scroll.
16
+ *
17
+ * Two shapes of record, and they behave very differently. A click is one discrete thing and is
18
+ * recorded as it happens. Scrolling fires continuously — hundreds of events for one flick of a
19
+ * wheel — so it is coalesced into one record per gesture: a burst of scrolling that ends when the
20
+ * page has been still for a moment. Recording every scroll event would swamp the queue, the
21
+ * batch and the user's bandwidth, and would say nothing a single record per gesture does not.
22
+ */
23
+ /** How long the page must be still before a scroll burst counts as one finished gesture. */
24
+ const SCROLL_IDLE_MS = 150;
25
+ /** Clicks closer than this in time and space count as one angry repetition. */
26
+ const RAGE_WINDOW_MS = 1000;
27
+ const RAGE_RADIUS_PX = 30;
28
+ const RAGE_COUNT = 3;
29
+ /** How long a click has to change something before it is called dead. */
30
+ const DEAD_CLICK_MS = 1500;
31
+ /** Longest element label we keep; enough to identify a control, short enough not to be content. */
32
+ const LABEL_MAX = 80;
33
+ /** heatMapObjectSDK caps screen, url_path and element_label at 500 characters. */
34
+ const FIELD_MAX = 500;
35
+ var installed = false;
36
+ var recorded = 0;
37
+ /** Recent clicks, for spotting a rage burst. */
38
+ var recentClicks = [];
39
+ var scrollStart = 0;
40
+ var scrollStartX = 0;
41
+ var scrollStartY = 0;
42
+ var scrollTimer = null;
43
+ /**
44
+ * Where the page was before the current gesture began.
45
+ *
46
+ * A scroll event fires *after* the position has already changed, so the first event of a burst
47
+ * reports somewhere the page has moved to, not where it started. Measuring from that loses the
48
+ * first increment of every gesture, and loses a single-event jump — an anchor link or a "back to
49
+ * top" button — completely, which is exactly the movement worth seeing on a scroll map.
50
+ */
51
+ var lastX = 0;
52
+ var lastY = 0;
53
+ /** Whether a record may still be stored, or the visit has produced enough. */
54
+ function underCap() {
55
+ var cap = getConfig('heatmap_max_per_session');
56
+ if (typeof cap !== 'number' || cap <= 0) {
57
+ cap = AP_CONFIG.heatmap_max_per_session;
58
+ }
59
+ if (recorded >= cap) {
60
+ if (recorded === cap) {
61
+ recorded++; // said once, not on every event for the rest of the visit
62
+ Console.log('apptics.heatmap: reached ' + cap + ' records for this session, pausing capture'); // no i18n
63
+ }
64
+ return false;
65
+ }
66
+ return true;
67
+ }
68
+ /** The page's full scrollable height, which is what a scroll depth is a fraction of. */
69
+ function contentHeight() {
70
+ var doc = document.documentElement;
71
+ var body = document.body;
72
+ return Math.max(doc ? doc.scrollHeight : 0, body ? body.scrollHeight : 0, doc ? doc.clientHeight : 0);
73
+ }
74
+ /**
75
+ * A 0-1 fraction, to three decimals.
76
+ *
77
+ * Clamped because the inputs can exceed each other: a page that has not laid out yet reports a
78
+ * content height of 0, and a rubber-band scroll puts the viewport bottom past the document end.
79
+ * Both produce a "fraction" far outside 0-1, which is meaningless on a heatmap.
80
+ */
81
+ function fraction(part, whole) {
82
+ if (!whole || whole <= 0) {
83
+ return 0;
84
+ }
85
+ var value = part / whole;
86
+ if (value < 0) {
87
+ value = 0;
88
+ }
89
+ if (value > 1) {
90
+ value = 1;
91
+ }
92
+ return Math.round(value * 1000) / 1000;
93
+ }
94
+ function viewportWidth() {
95
+ return window.innerWidth || (document.documentElement ? document.documentElement.clientWidth : 0) || 1;
96
+ }
97
+ /** Whether the element, or something it sits inside, is meant to be clicked. */
98
+ function clickableAncestor(node) {
99
+ var depth = 0;
100
+ while (node && depth < 10) {
101
+ var tag = node.tagName ? node.tagName.toLowerCase() : ''; // no i18n
102
+ var role = node.getAttribute ? node.getAttribute('role') : null; // no i18n
103
+ if (tag === 'a' || tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea' // no i18n
104
+ || tag === 'summary' || tag === 'label' // no i18n
105
+ || role === 'button' || role === 'link' || role === 'tab' || role === 'menuitem' // no i18n
106
+ || (node.hasAttribute && node.hasAttribute('onclick'))) { // no i18n
107
+ return node;
108
+ }
109
+ node = node.parentElement;
110
+ depth++;
111
+ }
112
+ return null;
113
+ }
114
+ /**
115
+ * A name for the element that was clicked.
116
+ *
117
+ * Attributes an author chose come first, because they are deliberate and stable. Visible text is
118
+ * the last resort and is skipped entirely when the user has opted out of PII: the text of a
119
+ * control can be a person's name, an email address or the contents of their cart.
120
+ */
121
+ function labelFor(node) {
122
+ if (!node) {
123
+ return ''; // no i18n
124
+ }
125
+ var attributes = ['data-ap-label', 'apeventaction', 'aria-label', 'name', 'id', 'title']; // no i18n
126
+ for (var i = 0; i < attributes.length; i++) {
127
+ var value = node.getAttribute ? node.getAttribute(attributes[i]) : null;
128
+ if (!isEmpty(value)) {
129
+ return String(value).slice(0, LABEL_MAX);
130
+ }
131
+ }
132
+ var tag = node.tagName ? node.tagName.toLowerCase() : 'element'; // no i18n
133
+ if (getTrackingStatus() !== AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII) {
134
+ // without consent for PII the shape of the control is all we say
135
+ var role = node.getAttribute ? node.getAttribute('role') : null; // no i18n
136
+ return isEmpty(role) ? tag : tag + '[' + role + ']'; // no i18n
137
+ }
138
+ var text = (node.textContent || '').replace(/\s+/g, ' ').trim(); // no i18n
139
+ return isEmpty(text) ? tag : text.slice(0, LABEL_MAX);
140
+ }
141
+ /**
142
+ * A stable number for the element, so the console can group every click on one control together.
143
+ * Derived from its position in the tree rather than from its text, so it survives a label change
144
+ * and carries nothing a person typed.
145
+ */
146
+ function triggeredId(node) {
147
+ if (!node) {
148
+ return 0;
149
+ }
150
+ var path = ''; // no i18n
151
+ var current = node;
152
+ var depth = 0;
153
+ while (current && depth < 12) {
154
+ var parent = current.parentElement;
155
+ var index = 0;
156
+ if (parent) {
157
+ var children = parent.children;
158
+ for (var i = 0; i < children.length; i++) {
159
+ if (children[i] === current) {
160
+ index = i;
161
+ break;
162
+ }
163
+ }
164
+ }
165
+ path = '/' + (current.tagName || '?') + ':' + index + path; // no i18n
166
+ current = parent;
167
+ depth++;
168
+ }
169
+ // FNV-1a, kept positive: a short stable number, not a cryptographic digest
170
+ var hash = 2166136261;
171
+ for (var c = 0; c < path.length; c++) {
172
+ hash ^= path.charCodeAt(c);
173
+ hash = (hash * 16777619) >>> 0;
174
+ }
175
+ return hash;
176
+ }
177
+ /** Whether this click is part of a burst of repeated clicks in the same spot. */
178
+ function isRageClick(x, y, at) {
179
+ recentClicks = recentClicks.filter(function (click) { return at - click.at <= RAGE_WINDOW_MS; });
180
+ recentClicks.push({ at: at, x: x, y: y });
181
+ var near = recentClicks.filter(function (click) {
182
+ return Math.abs(click.x - x) <= RAGE_RADIUS_PX && Math.abs(click.y - y) <= RAGE_RADIUS_PX;
183
+ });
184
+ return near.length >= RAGE_COUNT;
185
+ }
186
+ /** The fields every record carries, whatever kind it is. */
187
+ function common() {
188
+ return {
189
+ id: getNewUUID(),
190
+ session_start_time: _ZAP._current_session.starttime || nowMs(),
191
+ // without this the server has no way to order records within a session: session_start_time
192
+ // is the same for every one of them
193
+ triggered_time: nowMs(),
194
+ // the screen inScreen() or automatic screen tracking last named, or else the page, named
195
+ // as automatic tracking would name it and recorded as a screen view so engagement/add has it
196
+ screen: String(screenForRecord()).slice(0, FIELD_MAX),
197
+ url_path: String(window.location.pathname).slice(0, FIELD_MAX),
198
+ screen_width: window.screen ? window.screen.width : 0,
199
+ screen_height: window.screen ? window.screen.height : 0,
200
+ content_height: contentHeight(),
201
+ orientation: getOrientation(),
202
+ network_status: getNetworkStatus(),
203
+ edge_type: _ZAP._device_info.connectionType || getConnectionType(),
204
+ scroll_offset_x: Math.round(window.scrollX || window.pageXOffset || 0),
205
+ scroll_offset_y: Math.round(window.scrollY || window.pageYOffset || 0),
206
+ };
207
+ }
208
+ function store(record) {
209
+ recorded++;
210
+ noteDebugActivity();
211
+ // a heatmap record is worth a session in the same way an event is
212
+ commitPendingSession();
213
+ heatmap_transactions.add(record);
214
+ Console.dir(record);
215
+ }
216
+ function onPointerDown(event) {
217
+ if (!canTrackHeatmap('heatmap') || !underCap()) { // no i18n
218
+ return;
219
+ }
220
+ try {
221
+ var at = nowMs();
222
+ var target = event.target;
223
+ var clickable = clickableAncestor(target);
224
+ var named = clickable || target;
225
+ var x = Math.round(event.clientX);
226
+ var y = Math.round(event.clientY);
227
+ var height = contentHeight() || 1;
228
+ var pointerType = event.pointerType;
229
+ var record = Object.assign(common(), {
230
+ // TODO: send 'buttonclick' for a clickable target once the server accepts it. Held at
231
+ // 'default' for now while heatmap/add is still refusing payloads; `is_clickable`
232
+ // already carries the same information, so nothing is lost meanwhile.
233
+ triggered_type: 'default', // no i18n
234
+ gesture_type: 'click', // no i18n
235
+ gesture_duration: 0,
236
+ input_type: isEmpty(pointerType) ? 'mouse' : String(pointerType), // no i18n
237
+ element_label: labelFor(named),
238
+ triggered_id: triggeredId(named),
239
+ coordinate_x: x,
240
+ coordinate_y: y,
241
+ normalized_x: fraction(x, viewportWidth()),
242
+ normalized_y: fraction((window.scrollY || 0) + y, height),
243
+ velocity: 0,
244
+ is_clickable: clickable ? 1 : 0,
245
+ is_rage_click: isRageClick(x, y, at) ? 1 : 0,
246
+ is_dead_click: 0,
247
+ });
248
+ store(record);
249
+ watchForDeadClick(record, target);
250
+ }
251
+ catch (err) {
252
+ logFailure(AP_LOG_MODULE.HEATMAP, 'apptics.heatmap: click capture failed: ' + String(err)); // no i18n
253
+ }
254
+ }
255
+ /**
256
+ * A click on something that was not clickable and changed nothing is a click someone expected to
257
+ * work. Decided after the fact: the record is already stored, and is updated in place if nothing
258
+ * happened, so the click is never lost waiting to find out.
259
+ */
260
+ function watchForDeadClick(record, target) {
261
+ if (record.is_clickable === 1 || typeof MutationObserver !== 'function') { // no i18n
262
+ return;
263
+ }
264
+ var changed = false;
265
+ var url = window.location.href;
266
+ var observer = new MutationObserver(function () { changed = true; });
267
+ try {
268
+ observer.observe(document.documentElement, { childList: true, subtree: true, attributes: true });
269
+ }
270
+ catch (err) {
271
+ return;
272
+ }
273
+ setTimeout(function () {
274
+ observer.disconnect();
275
+ if (!changed && window.location.href === url) {
276
+ record.is_dead_click = 1;
277
+ heatmap_transactions.update(record);
278
+ }
279
+ }, DEAD_CLICK_MS);
280
+ }
281
+ function onScroll() {
282
+ if (!canTrackHeatmap('heatmap') || !underCap()) { // no i18n
283
+ return;
284
+ }
285
+ if (scrollTimer === null) {
286
+ scrollStart = nowMs();
287
+ scrollStartX = lastX;
288
+ scrollStartY = lastY;
289
+ }
290
+ else {
291
+ clearTimeout(scrollTimer);
292
+ }
293
+ scrollTimer = setTimeout(endScrollGesture, SCROLL_IDLE_MS);
294
+ }
295
+ /** One record for the whole burst, once the page has been still for SCROLL_IDLE_MS. */
296
+ function endScrollGesture() {
297
+ scrollTimer = null;
298
+ try {
299
+ var endX = Math.round(window.scrollX || 0);
300
+ var endY = Math.round(window.scrollY || 0);
301
+ var dx = endX - scrollStartX;
302
+ var dy = endY - scrollStartY;
303
+ lastX = endX;
304
+ lastY = endY;
305
+ if (dx === 0 && dy === 0) {
306
+ return;
307
+ }
308
+ var duration = Math.max(1, nowMs() - scrollStart);
309
+ var distance = Math.sqrt(dx * dx + dy * dy);
310
+ var direction = Math.abs(dy) >= Math.abs(dx)
311
+ ? (dy > 0 ? 'down-scroll' : 'up-scroll') // no i18n
312
+ : (dx > 0 ? 'right-scroll' : 'left-scroll'); // no i18n
313
+ var height = contentHeight() || 1;
314
+ store(Object.assign(common(), {
315
+ // the server accepts only event|default|buttonclick here; what kind of movement it
316
+ // was belongs in gesture_type. input_type is left off rather than invented: a wheel
317
+ // carries no pointer type, and the intended vocabulary has no value for "unknown"
318
+ triggered_type: 'default', // no i18n
319
+ gesture_type: direction,
320
+ gesture_duration: Math.round(duration),
321
+ element_label: '', // no i18n
322
+ triggered_id: 0,
323
+ coordinate_x: endX,
324
+ coordinate_y: endY,
325
+ normalized_x: 0,
326
+ // how far down the page the gesture left them, which is what a scroll map reads
327
+ normalized_y: fraction(endY + (window.innerHeight || 0), height),
328
+ velocity: Math.round((distance / duration) * 1000),
329
+ is_clickable: 0,
330
+ is_rage_click: 0,
331
+ is_dead_click: 0,
332
+ }));
333
+ }
334
+ catch (err) {
335
+ logFailure(AP_LOG_MODULE.HEATMAP, 'apptics.heatmap: scroll capture failed: ' + String(err)); // no i18n
336
+ }
337
+ }
338
+ /** Turns capture on or off. Listeners are passive, so they never delay a click or a scroll. */
339
+ function enableHeatmap(status) {
340
+ var wanted = typeof status === 'boolean' ? status : true; // no i18n
341
+ if (wanted === installed) {
342
+ return;
343
+ }
344
+ if (wanted) {
345
+ // where the page already is, so the first gesture is measured from here and not from 0
346
+ lastX = Math.round(window.scrollX || 0);
347
+ lastY = Math.round(window.scrollY || 0);
348
+ window.addEventListener('pointerdown', onPointerDown, { capture: true, passive: true }); // no i18n
349
+ window.addEventListener('scroll', onScroll, { capture: true, passive: true }); // no i18n
350
+ installed = true;
351
+ Console.log('apptics.heatmap: capturing clicks and scrolls'); // no i18n
352
+ return;
353
+ }
354
+ window.removeEventListener('pointerdown', onPointerDown, true); // no i18n
355
+ window.removeEventListener('scroll', onScroll, true); // no i18n
356
+ if (scrollTimer !== null) {
357
+ clearTimeout(scrollTimer);
358
+ scrollTimer = null;
359
+ }
360
+ installed = false;
361
+ Console.log('apptics.heatmap: capture stopped'); // no i18n
362
+ }
363
+ /** Forgets what this visit recorded. reset() calls it; the cap starts again from zero. */
364
+ function resetHeatmapSession() {
365
+ recorded = 0;
366
+ recentClicks = [];
367
+ lastX = 0;
368
+ lastY = 0;
369
+ }
370
+ // init() and reset() drive capture through these, so neither has to import this module
371
+ hooks.enableHeatmap = enableHeatmap;
372
+ hooks.resetHeatmap = resetHeatmapSession;
373
+
374
+ export { enableHeatmap, resetHeatmapSession };
@@ -0,0 +1,68 @@
1
+ import { AP_FEEDBACK_TYPE, AP_TRACKING_STATUS } from './core/constants.js';
2
+ import { init as initImpl, ready as readyImpl, reset as resetImpl } from './lifecycle.js';
3
+ import { enableApiTracking as enableApiTrackingImpl } from './engagement/auto-api.js';
4
+ import { DefinedEvents } from './engagement/defined-events.js';
5
+ import { ApiTrackingBuilder } from './engagement/api-rules.js';
6
+ import { enableGlobalErrorHandler as enableGlobalErrorHandlerImpl } from './errors/track.js';
7
+ import { getUser as getUserImpl, UserBuilder, users } from './user/index.js';
8
+ import { getTrackingStatus as getTrackingStatusImpl, setTrackingStatus as setTrackingStatusImpl } from './core/consent.js';
9
+ import { flush as flushImpl } from './scheduler.js';
10
+ import { addDiagnosticsInfo as addDiagnosticsInfoImpl, addFeedbackLog as addFeedbackLogImpl } from './feedback/logs.js';
11
+ import type { AppticsApi } from './types.js';
12
+ import { disableDebug as disableDebugImpl, enableDebug as enableDebugImpl } from './core/debug.js';
13
+ import { AppticsLogger } from './remotelog/logger.js';
14
+ export type { AppticsLogger as AppticsLoggerApi } from './remotelog/logger.js';
15
+ export type { AppticsApi, AppticsConfig, ErrorLike, FeedbackType, Properties, TrackingStatus, UserInfo, UserValidationResult, } from './types.js';
16
+ /** Android's Apptics: `Apptics.init(config)` starts the SDK. */
17
+ export declare const Apptics: {
18
+ /** Starts the SDK. The config object is required; the console snippet supplies it via auto-init. */
19
+ init: typeof initImpl;
20
+ };
21
+ export declare const ready: typeof readyImpl;
22
+ /** Android's AppticsEvents: `addEvent(name, group?, properties?)`, or `addEvent(DefinedEvents.X, properties?)`. */
23
+ export declare const AppticsEvents: {
24
+ addEvent: AppticsApi["AppticsEvents"]["addEvent"];
25
+ };
26
+ /** Apptics' defined events, as Android's DefinedEvents, to log with AppticsEvents.addEvent. */
27
+ export { DefinedEvents };
28
+ export type { DefinedEvent } from './engagement/defined-events.js';
29
+ /** Android's AppticsScreenTracker: inScreen(name) returns the view's id, outScreen(id) ends it. */
30
+ export declare const AppticsScreenTracker: AppticsApi['AppticsScreenTracker'];
31
+ /** Android's AppticsApiTracker: startTrackApi / endTrackApi, and configure for the rules. */
32
+ export declare const AppticsApiTracker: AppticsApi['AppticsApiTracker'];
33
+ export { ApiTrackingBuilder };
34
+ export type { ApiTrackingConfig } from './engagement/api-rules.js';
35
+ /** Turns automatic API tracking on or off; the `track_api` config flag is the usual way to set it. */
36
+ export declare const enableApiTracking: typeof enableApiTrackingImpl;
37
+ /** Reports an error the app caught, or an `error` / `unhandledrejection` event. */
38
+ export declare const AppticsTrackError: AppticsApi["AppticsTrackError"];
39
+ export declare const enableGlobalErrorHandler: typeof enableGlobalErrorHandlerImpl;
40
+ /** Registers the signed-in user; properties may be a plain object or UserBuilder.build(). */
41
+ export declare const AppticsSetUser: AppticsApi["AppticsSetUser"];
42
+ export declare const getUser: typeof getUserImpl;
43
+ export declare const setTrackingStatus: typeof setTrackingStatusImpl;
44
+ export declare const getTrackingStatus: typeof getTrackingStatusImpl;
45
+ export declare const flush: typeof flushImpl;
46
+ /** Records a line for the next feedback submission. Costs nothing until feedback is sent. */
47
+ export declare const addFeedbackLog: typeof addFeedbackLogImpl;
48
+ /** Records a diagnostics key/value, grouped under `heading`, for the next feedback submission. */
49
+ export declare const addDiagnosticsInfo: typeof addDiagnosticsInfoImpl;
50
+ /**
51
+ * Turns debug mode on; works before init(), and wins over `debug` in init().
52
+ *
53
+ * On, engagement, exception and log go to their `debug/` twins and the answers carry a request id
54
+ * and a link into the server's own logs. It switches itself off after an hour with nothing
55
+ * tracked, so a forgotten tab stops tracing on its own.
56
+ */
57
+ export declare const enableDebug: typeof enableDebugImpl;
58
+ /** Turns debug mode off; works before init(), and wins over `debug` in init(). */
59
+ export declare const disableDebug: typeof disableDebugImpl;
60
+ export declare const reset: typeof resetImpl;
61
+ /**
62
+ * Android's AppticsLogger, shown on the console's Remote Logger page. Off until
63
+ * `AppticsLogger.enable()`; then `AppticsLogger.v / d / i / w / e(tag, message, ...details)`.
64
+ */
65
+ export { AppticsLogger };
66
+ export { AP_FEEDBACK_TYPE, AP_TRACKING_STATUS, UserBuilder, users };
67
+ declare const apptics: AppticsApi;
68
+ export default apptics;
@@ -0,0 +1,122 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ import { AP_FEEDBACK_TYPE, AP_TRACKING_STATUS } from './core/constants.js';
3
+ import { guard } from './core/guard.js';
4
+ import { init, reset as reset$1, ready as ready$1 } from './lifecycle.js';
5
+ import { enableApiTracking as enableApiTracking$1 } from './engagement/auto-api.js';
6
+ import { startTrackApi, trackEvent, endTrackApiAt, outScreenAt, inScreenAt } from './engagement/track.js';
7
+ import { DefinedEvents } from './engagement/defined-events.js';
8
+ import { nowMs, getNewUUID } from './core/utils.js';
9
+ import { validateScreenName } from './core/validate.js';
10
+ import { ApiTrackingBuilder, configureApiTracking } from './engagement/api-rules.js';
11
+ import { trackError, enableGlobalErrorHandler as enableGlobalErrorHandler$1 } from './errors/track.js';
12
+ import { users, setUser, getUser as getUser$1 } from './user/index.js';
13
+ export { UserBuilder } from './user/index.js';
14
+ import { getTrackingStatus as getTrackingStatus$1, setTrackingStatus as setTrackingStatus$1 } from './core/consent.js';
15
+ import { flush as flush$1 } from './scheduler.js';
16
+ import { addDiagnosticsInfo as addDiagnosticsInfo$1, addFeedbackLog as addFeedbackLog$1 } from './feedback/logs.js';
17
+ import { scheduleAutoInit } from './auto-init.js';
18
+ import { disableDebug as disableDebug$1, enableDebug as enableDebug$1 } from './core/debug.js';
19
+ import { AppticsLogger } from './remotelog/logger.js';
20
+
21
+ /** Android's Apptics: `Apptics.init(config)` starts the SDK. */
22
+ const Apptics = {
23
+ /** Starts the SDK. The config object is required; the console snippet supplies it via auto-init. */
24
+ init: guard('Apptics.init', init), // no i18n
25
+ };
26
+ const ready = guard('ready', ready$1); // no i18n
27
+ /** Android's AppticsEvents: `addEvent(name, group?, properties?)`, or `addEvent(DefinedEvents.X, properties?)`. */
28
+ const AppticsEvents = {
29
+ addEvent: guard('AppticsEvents.addEvent', trackEvent), // no i18n
30
+ };
31
+ const inScreenGuarded = guard('AppticsScreenTracker.inScreen', inScreenAt); // no i18n
32
+ const outScreenGuarded = guard('AppticsScreenTracker.outScreen', outScreenAt); // no i18n
33
+ /** Android's AppticsScreenTracker: inScreen(name) returns the view's id, outScreen(id) ends it. */
34
+ const AppticsScreenTracker = {
35
+ /**
36
+ * Records a screen view and returns its id. The view ends at the next screen, when the page is
37
+ * hidden or its session ends, or when the id is handed to outScreen. '' for an invalid name.
38
+ */
39
+ inScreen: function (screenName, properties) {
40
+ if (!validateScreenName(screenName)) {
41
+ // inScreenAt reports it; the caller still needs an answer now
42
+ inScreenGuarded(screenName, properties, '', nowMs()); // no i18n
43
+ return ''; // no i18n
44
+ }
45
+ // the id and the start now, so both are right even when start-up is still running
46
+ var id = getNewUUID();
47
+ inScreenGuarded(screenName, properties, id, nowMs());
48
+ return id;
49
+ },
50
+ /** Ends the screen view inScreen began, before the next screen would. */
51
+ outScreen: function (id) {
52
+ outScreenGuarded(id, nowMs());
53
+ },
54
+ };
55
+ const endTrackApiGuarded = guard('AppticsApiTracker.endTrackApi', endTrackApiAt); // no i18n
56
+ /** Android's AppticsApiTracker: startTrackApi / endTrackApi, and configure for the rules. */
57
+ const AppticsApiTracker = {
58
+ /** Begins timing one call: returns the id endTrackApi takes. */
59
+ startTrackApi: guard('AppticsApiTracker.startTrackApi', startTrackApi), // no i18n
60
+ /** Finishes a call startTrackApi began and records it. */
61
+ endTrackApi: function (id, responseCode, responseMessage) {
62
+ // the end time now, not when a call made during start-up is replayed
63
+ endTrackApiGuarded(id, responseCode, responseMessage, nowMs());
64
+ },
65
+ /** The rules API tracking records by, from ApiTrackingBuilder. Works before Apptics.init(). */
66
+ configure: guard('AppticsApiTracker.configure', configureApiTracking), // no i18n
67
+ };
68
+ /** Turns automatic API tracking on or off; the `track_api` config flag is the usual way to set it. */
69
+ const enableApiTracking = guard('enableApiTracking', enableApiTracking$1); // no i18n
70
+ /** Reports an error the app caught, or an `error` / `unhandledrejection` event. */
71
+ const AppticsTrackError = guard('AppticsTrackError', trackError); // no i18n
72
+ const enableGlobalErrorHandler = guard('enableGlobalErrorHandler', enableGlobalErrorHandler$1); // no i18n
73
+ /** Registers the signed-in user; properties may be a plain object or UserBuilder.build(). */
74
+ const AppticsSetUser = guard('AppticsSetUser', setUser); // no i18n
75
+ const getUser = guard('getUser', getUser$1); // no i18n
76
+ const setTrackingStatus = guard('setTrackingStatus', setTrackingStatus$1); // no i18n
77
+ const getTrackingStatus = guard('getTrackingStatus', getTrackingStatus$1); // no i18n
78
+ const flush = guard('flush', flush$1); // no i18n
79
+ /** Records a line for the next feedback submission. Costs nothing until feedback is sent. */
80
+ const addFeedbackLog = guard('addFeedbackLog', addFeedbackLog$1); // no i18n
81
+ /** Records a diagnostics key/value, grouped under `heading`, for the next feedback submission. */
82
+ const addDiagnosticsInfo = guard('addDiagnosticsInfo', addDiagnosticsInfo$1); // no i18n
83
+ /**
84
+ * Turns debug mode on; works before init(), and wins over `debug` in init().
85
+ *
86
+ * On, engagement, exception and log go to their `debug/` twins and the answers carry a request id
87
+ * and a link into the server's own logs. It switches itself off after an hour with nothing
88
+ * tracked, so a forgotten tab stops tracing on its own.
89
+ */
90
+ const enableDebug = guard('enableDebug', enableDebug$1); // no i18n
91
+ /** Turns debug mode off; works before init(), and wins over `debug` in init(). */
92
+ const disableDebug = guard('disableDebug', disableDebug$1); // no i18n
93
+ const reset = guard('reset', reset$1); // no i18n
94
+ const apptics = {
95
+ Apptics,
96
+ AppticsEvents,
97
+ AppticsScreenTracker,
98
+ AppticsApiTracker,
99
+ AppticsLogger,
100
+ DefinedEvents,
101
+ ApiTrackingBuilder,
102
+ ready,
103
+ enableDebug,
104
+ disableDebug,
105
+ enableApiTracking,
106
+ AppticsTrackError,
107
+ enableGlobalErrorHandler,
108
+ AppticsSetUser,
109
+ getUser,
110
+ users,
111
+ setTrackingStatus,
112
+ getTrackingStatus,
113
+ flush,
114
+ addFeedbackLog,
115
+ addDiagnosticsInfo,
116
+ reset,
117
+ AP_TRACKING_STATUS,
118
+ AP_FEEDBACK_TYPE,
119
+ };
120
+ scheduleAutoInit(Apptics);
121
+
122
+ export { AP_FEEDBACK_TYPE, AP_TRACKING_STATUS, ApiTrackingBuilder, Apptics, AppticsApiTracker, AppticsEvents, AppticsLogger, AppticsScreenTracker, AppticsSetUser, AppticsTrackError, DefinedEvents, addDiagnosticsInfo, addFeedbackLog, apptics as default, disableDebug, enableApiTracking, enableDebug, enableGlobalErrorHandler, flush, getTrackingStatus, getUser, ready, reset, setTrackingStatus, users };
@@ -0,0 +1,14 @@
1
+ import type { AppticsConfig } from './types.js';
2
+ /**
3
+ * Starts the SDK. The config object is required: pass it directly, or let the console snippet
4
+ * supply it (auto-init reads window.appticssettings._defaultoptions and calls init with it).
5
+ * Returns true when the config has serviceUrl, zak, identifier and appversion and start-up has
6
+ * begun (see ready()), false when it was already running, the config is missing or incomplete, or
7
+ * there is no browser. Start-up calls app/addversion with those four, which answers with aaid, the
8
+ * portal and project ids and the rest; then device/add registers the browser, as in 1.x.
9
+ */
10
+ export declare function init(config: AppticsConfig): boolean;
11
+ /** Resolves true once start-up has finished, false if init() refused or storage is unusable. */
12
+ export declare function ready(): Promise<boolean>;
13
+ /** Clears stored identity and queues, then starts again from the snippet. */
14
+ export declare function reset(): void;