@zoho_apptics/apptics-js-sdk 1.0.2 → 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 -1
@@ -0,0 +1,324 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ import { Console } from './logger.js';
3
+ import { nowMs } from './utils.js';
4
+
5
+ const DB_NAME = 'apptics'; // no i18n
6
+ // 3 added the heatmaps store. The upgrade only creates stores that are missing, so an existing
7
+ // database keeps everything already queued in it.
8
+ const DB_VERSION = 3;
9
+ const OPEN_TIMEOUT_MS = 3000;
10
+ const QUEUES = ['engagements', 'errors', 'logs', 'consolelogs', 'heatmaps']; // no i18n
11
+ /** 1.x localStorage keys; also the layout of the localStorage backend. */
12
+ const LEGACY_KEYS = Object.freeze({
13
+ settings: 'apptics-device-info', // no i18n
14
+ engagements: 'apptics-engagements-transactions', // no i18n
15
+ errors: 'apptics-errors-transactions', // no i18n
16
+ logs: 'apptics-log-transactions', // no i18n
17
+ consolelogs: 'apptics-consolelog-transactions', // no i18n
18
+ // not a 1.x key: heatmaps did not exist then. It is here because this map is also the
19
+ // localStorage backend's layout, so the store needs a name there too
20
+ heatmaps: 'apptics-heatmap-transactions', // no i18n
21
+ });
22
+ /** Shape guards shared by both backends and the 1.x migration. */
23
+ function asList(value) {
24
+ return Array.isArray(value) ? value : [];
25
+ }
26
+ function asDict(value) {
27
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
28
+ }
29
+ /* ---------------- localStorage backend ---------------- */
30
+ function readJSON(key) {
31
+ try {
32
+ const raw = localStorage.getItem(key);
33
+ return raw === null || raw === '' ? null : JSON.parse(raw); // no i18n
34
+ }
35
+ catch (err) {
36
+ Console.warn('apptics: could not read ' + key + ', treating it as empty'); // no i18n
37
+ return null;
38
+ }
39
+ }
40
+ function writeJSON(key, value) {
41
+ try {
42
+ localStorage.setItem(key, JSON.stringify(value));
43
+ }
44
+ catch (err) {
45
+ Console.warn('apptics: could not write ' + key + ': ' + String(err)); // no i18n
46
+ }
47
+ }
48
+ function createLocalStorageBackend() {
49
+ return {
50
+ kind: 'localstorage', // no i18n
51
+ loadSettings() {
52
+ return Promise.resolve(asDict(readJSON(LEGACY_KEYS.settings)));
53
+ },
54
+ putSetting(key, value) {
55
+ const all = asDict(readJSON(LEGACY_KEYS.settings));
56
+ all[key] = value;
57
+ writeJSON(LEGACY_KEYS.settings, all);
58
+ return Promise.resolve();
59
+ },
60
+ clearSettings() {
61
+ writeJSON(LEGACY_KEYS.settings, {});
62
+ return Promise.resolve();
63
+ },
64
+ queueAll(store) {
65
+ return Promise.resolve(asList(readJSON(LEGACY_KEYS[store])));
66
+ },
67
+ queuePut(store, items) {
68
+ const list = asList(readJSON(LEGACY_KEYS[store]));
69
+ items.forEach(function (item) {
70
+ const index = list.findIndex(function (existing) { return existing.id === item.id; });
71
+ if (index === -1) {
72
+ list.push(item);
73
+ }
74
+ else {
75
+ list[index] = item;
76
+ }
77
+ });
78
+ writeJSON(LEGACY_KEYS[store], list);
79
+ return Promise.resolve();
80
+ },
81
+ queueDelete(store, ids) {
82
+ const remaining = asList(readJSON(LEGACY_KEYS[store])).filter(function (item) {
83
+ return ids.indexOf(item.id) === -1;
84
+ });
85
+ writeJSON(LEGACY_KEYS[store], remaining);
86
+ return Promise.resolve();
87
+ },
88
+ queueClear(store) {
89
+ writeJSON(LEGACY_KEYS[store], []);
90
+ return Promise.resolve();
91
+ },
92
+ };
93
+ }
94
+ let lastSeq = 0;
95
+ /**
96
+ * Strictly increasing, and time-based so tabs interleave in roughly the right order.
97
+ * Counting up from the last value rather than a counter that wraps keeps insertion order
98
+ * even when a chatty caller adds more than a thousand items inside one millisecond.
99
+ */
100
+ function nextSeq() {
101
+ const base = nowMs() * 1000;
102
+ lastSeq = base > lastSeq ? base : lastSeq + 1;
103
+ return lastSeq;
104
+ }
105
+ function request(req) {
106
+ return new Promise(function (resolve, reject) {
107
+ req.onsuccess = function () { resolve(req.result); };
108
+ req.onerror = function () { reject(req.error); };
109
+ });
110
+ }
111
+ function completed(tx) {
112
+ return new Promise(function (resolve, reject) {
113
+ tx.oncomplete = function () { resolve(); };
114
+ tx.onerror = function () { reject(tx.error); };
115
+ tx.onabort = function () { reject(tx.error); };
116
+ });
117
+ }
118
+ /** Puts `item` unless it exists (keepExisting) or replaces it keeping its seq. Runs inside `store`'s transaction. */
119
+ function putRecord(store, item, keepExisting) {
120
+ const id = String(item.id);
121
+ const lookup = store.get(id);
122
+ lookup.onsuccess = function () {
123
+ const existing = lookup.result;
124
+ if (existing && keepExisting) {
125
+ return;
126
+ }
127
+ store.put({ id: id, seq: existing ? existing.seq : nextSeq(), type: item.type, item: item });
128
+ };
129
+ }
130
+ /** Our stores, as created by onupgradeneeded. */
131
+ function hasAllStores(db) {
132
+ return db.objectStoreNames.contains('settings') && QUEUES.every(function (name) {
133
+ return db.objectStoreNames.contains(name);
134
+ });
135
+ }
136
+ function deleteDatabase(factory) {
137
+ return new Promise(function (resolve) {
138
+ var req = factory.deleteDatabase(DB_NAME);
139
+ req.onsuccess = function () { resolve(); };
140
+ req.onerror = function () { resolve(); };
141
+ req.onblocked = function () { resolve(); };
142
+ });
143
+ }
144
+ /**
145
+ * Opens the database, and repairs it once if something else created an "apptics" database
146
+ * without our stores (then onupgradeneeded never fires and every read would fail).
147
+ */
148
+ function openIndexedDB(factory = indexedDB, timeoutMs = OPEN_TIMEOUT_MS) {
149
+ return openOnce(factory, timeoutMs).then(function (db) {
150
+ if (hasAllStores(db)) {
151
+ return db;
152
+ }
153
+ Console.warn('apptics: the "' + DB_NAME + '" database is missing its stores, recreating it'); // no i18n
154
+ db.close();
155
+ return deleteDatabase(factory).then(function () {
156
+ return openOnce(factory, timeoutMs);
157
+ }).then(function (fresh) {
158
+ if (!hasAllStores(fresh)) {
159
+ fresh.close();
160
+ throw new Error('indexedDB: stores could not be created'); // no i18n
161
+ }
162
+ return fresh;
163
+ });
164
+ });
165
+ }
166
+ function openOnce(factory, timeoutMs) {
167
+ return new Promise(function (resolve, reject) {
168
+ let settled = false;
169
+ const fail = function (reason) {
170
+ if (!settled) {
171
+ settled = true;
172
+ clearTimeout(timer);
173
+ reject(reason);
174
+ }
175
+ };
176
+ const timer = setTimeout(function () {
177
+ fail(new Error('indexedDB open timed out')); // no i18n
178
+ }, timeoutMs);
179
+ let req;
180
+ try {
181
+ req = factory.open(DB_NAME, DB_VERSION);
182
+ }
183
+ catch (err) {
184
+ fail(err);
185
+ return;
186
+ }
187
+ req.onupgradeneeded = function () {
188
+ const db = req.result;
189
+ if (!db.objectStoreNames.contains('settings')) { // no i18n
190
+ db.createObjectStore('settings'); // no i18n
191
+ }
192
+ QUEUES.forEach(function (name) {
193
+ if (!db.objectStoreNames.contains(name)) {
194
+ db.createObjectStore(name, { keyPath: 'id' }).createIndex('seq', 'seq'); // no i18n
195
+ }
196
+ });
197
+ };
198
+ req.onsuccess = function () {
199
+ if (settled) {
200
+ req.result.close(); // we already gave up (timeout or blocked)
201
+ return;
202
+ }
203
+ settled = true;
204
+ clearTimeout(timer);
205
+ // Another tab running a newer build needs to upgrade the schema, and cannot while this
206
+ // connection is open. Letting go is the only cooperative answer: holding on blocks that
207
+ // tab's upgrade until this one is closed, and it spends the whole time with no storage.
208
+ // This tab keeps working from memory and picks the new schema up on its next load.
209
+ req.result.onversionchange = function () {
210
+ Console.warn('apptics: another tab is upgrading the database, closing this connection'); // no i18n
211
+ req.result.close();
212
+ };
213
+ resolve(req.result);
214
+ };
215
+ req.onerror = function () {
216
+ fail(req.error);
217
+ };
218
+ req.onblocked = function () {
219
+ // Another tab is holding an older version open. A build that sets onversionchange
220
+ // (above) lets go by itself, so this resolves on its own in a moment; the open is left
221
+ // to run until the timeout rather than abandoned, because giving up here would mean
222
+ // running with no storage for the rest of the visit.
223
+ Console.warn('apptics: waiting for another tab to release the database'); // no i18n
224
+ };
225
+ });
226
+ }
227
+ function createIndexedDBBackend(db) {
228
+ return {
229
+ kind: 'indexeddb', // no i18n
230
+ loadSettings() {
231
+ const store = db.transaction('settings', 'readonly').objectStore('settings'); // no i18n
232
+ return Promise.all([request(store.getAllKeys()), request(store.getAll())]).then(function ([keys, values]) {
233
+ const out = {};
234
+ keys.forEach(function (key, i) {
235
+ out[String(key)] = values[i];
236
+ });
237
+ return out;
238
+ });
239
+ },
240
+ putSetting(key, value) {
241
+ const tx = db.transaction('settings', 'readwrite'); // no i18n
242
+ tx.objectStore('settings').put(value, key); // no i18n
243
+ return completed(tx);
244
+ },
245
+ clearSettings() {
246
+ const tx = db.transaction('settings', 'readwrite'); // no i18n
247
+ tx.objectStore('settings').clear(); // no i18n
248
+ return completed(tx);
249
+ },
250
+ queueAll(store) {
251
+ const index = db.transaction(store, 'readonly').objectStore(store).index('seq'); // no i18n
252
+ return request(index.getAll()).then(function (records) {
253
+ return records.map(function (record) { return record.item; });
254
+ });
255
+ },
256
+ queuePut(store, items) {
257
+ const tx = db.transaction(store, 'readwrite'); // no i18n
258
+ const objectStore = tx.objectStore(store);
259
+ items.forEach(function (item) { putRecord(objectStore, item, false); });
260
+ return completed(tx);
261
+ },
262
+ queueDelete(store, ids) {
263
+ const tx = db.transaction(store, 'readwrite'); // no i18n
264
+ const objectStore = tx.objectStore(store);
265
+ ids.forEach(function (id) { objectStore.delete(id); });
266
+ return completed(tx);
267
+ },
268
+ queueClear(store) {
269
+ const tx = db.transaction(store, 'readwrite'); // no i18n
270
+ tx.objectStore(store).clear();
271
+ return completed(tx);
272
+ },
273
+ importAll(settings, queues) {
274
+ // scope derived from QUEUES, not repeated: the loop below opens every one of them,
275
+ // and a store left out of the scope throws NotFoundError the moment it is reached
276
+ const tx = db.transaction(['settings'].concat(QUEUES), 'readwrite'); // no i18n
277
+ const settingsStore = tx.objectStore('settings'); // no i18n
278
+ Object.keys(settings).forEach(function (key) {
279
+ const lookup = settingsStore.get(key);
280
+ lookup.onsuccess = function () {
281
+ if (lookup.result === undefined) {
282
+ settingsStore.put(settings[key], key);
283
+ }
284
+ };
285
+ });
286
+ QUEUES.forEach(function (name) {
287
+ const objectStore = tx.objectStore(name);
288
+ queues[name].forEach(function (item) { putRecord(objectStore, item, true); });
289
+ });
290
+ return completed(tx);
291
+ },
292
+ };
293
+ }
294
+ function localStorageUsable() {
295
+ try {
296
+ const probe = '__apptics_probe__'; // no i18n
297
+ localStorage.setItem(probe, '1');
298
+ localStorage.removeItem(probe);
299
+ return true;
300
+ }
301
+ catch (err) {
302
+ return false;
303
+ }
304
+ }
305
+ /** IndexedDB when it opens, otherwise localStorage, otherwise null. Never rejects. */
306
+ function openBackend() {
307
+ const fallback = function (reason) {
308
+ Console.warn('apptics: IndexedDB unavailable (' + String(reason) + '), using localStorage'); // no i18n
309
+ return localStorageUsable() ? createLocalStorageBackend() : null;
310
+ };
311
+ let factory;
312
+ try {
313
+ factory = typeof indexedDB !== 'undefined' ? indexedDB : undefined; // no i18n
314
+ }
315
+ catch (err) {
316
+ factory = undefined; // access can throw in sandboxed frames
317
+ }
318
+ if (!factory) {
319
+ return Promise.resolve(fallback('not supported')); // no i18n
320
+ }
321
+ return openIndexedDB(factory).then(createIndexedDBBackend, fallback);
322
+ }
323
+
324
+ export { DB_NAME, DB_VERSION, LEGACY_KEYS, asDict, asList, createIndexedDBBackend, createLocalStorageBackend, openBackend, openIndexedDB };
@@ -0,0 +1,22 @@
1
+ /** Whether debug mode is on right now, idle hour included. */
2
+ export declare function debugEnabled(): boolean;
3
+ /**
4
+ * Pushes the idle hour out. Called wherever something is actually tracked, which is the only
5
+ * evidence the SDK has that a person is still looking — there is no event for "watching".
6
+ */
7
+ export declare function noteDebugActivity(): void;
8
+ /**
9
+ * Turns debug mode off if its hour has run out. Called from the flush timer, which ticks whether
10
+ * or not anything is happening — a check that only ran on the way into a request would never
11
+ * fire, because an idle SDK makes no requests.
12
+ */
13
+ export declare function expireDebugIfIdle(): void;
14
+ /**
15
+ * Turns debug mode on, at any time: before init(), during start-up or while the SDK runs. The
16
+ * choice holds over `debug` in init() for the rest of the page's life.
17
+ */
18
+ export declare function enableDebug(): void;
19
+ /** Turns debug mode off, at any time, with the same hold over `debug` as enableDebug(). */
20
+ export declare function disableDebug(): void;
21
+ /** What init() applies for `debug`: the config's value, unless the app has already chosen. */
22
+ export declare function applyDebugConfig(configured: boolean): void;
@@ -0,0 +1,81 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ import { DEBUG_IDLE_MS } from './constants.js';
3
+ import { _ZAP } from './state.js';
4
+ import { Console } from './logger.js';
5
+ import { nowMs } from './utils.js';
6
+
7
+ /**
8
+ * The switch for debug mode, and the hour that closes it.
9
+ *
10
+ * Debug mode is not free on either side: every engagement, exception and log call goes to its
11
+ * `debug/` twin instead of the ordinary endpoint, which makes the server keep a traceable
12
+ * record of the request. That is worth it while someone is watching, and pure
13
+ * cost once they have walked away — and walking away is the normal way a debugging session ends,
14
+ * not a deliberate switch-off. So the SDK closes it: an hour with nothing tracked turns debug
15
+ * back off by itself, and anything tracked pushes that hour out again.
16
+ *
17
+ * It lives in core because every send asks it: `debug: true` in init(), or enableDebug(), is
18
+ * enough to turn the twins on, and that alone must expire.
19
+ */
20
+ /** Whether debug mode is on right now, idle hour included. */
21
+ function debugEnabled() {
22
+ return _ZAP._config.debug_api === true && !debugIdle();
23
+ }
24
+ /** True once the idle hour has run out on a debug session nobody is watching. */
25
+ function debugIdle() {
26
+ return _ZAP._debugUntil > 0 && nowMs() > _ZAP._debugUntil;
27
+ }
28
+ /**
29
+ * Pushes the idle hour out. Called wherever something is actually tracked, which is the only
30
+ * evidence the SDK has that a person is still looking — there is no event for "watching".
31
+ */
32
+ function noteDebugActivity() {
33
+ if (_ZAP._config.debug_api !== true) {
34
+ return;
35
+ }
36
+ _ZAP._debugUntil = nowMs() + DEBUG_IDLE_MS;
37
+ }
38
+ /**
39
+ * Turns debug mode off if its hour has run out. Called from the flush timer, which ticks whether
40
+ * or not anything is happening — a check that only ran on the way into a request would never
41
+ * fire, because an idle SDK makes no requests.
42
+ */
43
+ function expireDebugIfIdle() {
44
+ if (!debugIdle()) {
45
+ return;
46
+ }
47
+ Console.log('apptics: debug mode has been idle for an hour, switching it off'); // no i18n
48
+ setDebug(false);
49
+ }
50
+ /**
51
+ * The app's own choice, from enableDebug() or disableDebug(). It wins over `debug` in init(),
52
+ * so debug mode can be switched on or off with one call, before init() runs or while the SDK is
53
+ * running, and an init() or reset() that comes after doesn't switch it back. null until the app
54
+ * has chosen.
55
+ */
56
+ var chosen = null;
57
+ /** Turning it on starts the idle hour; turning it off clears it, so the next on gets a whole hour. */
58
+ function setDebug(on) {
59
+ _ZAP._config.debug_api = on;
60
+ _ZAP._debugUntil = on ? nowMs() + DEBUG_IDLE_MS : 0;
61
+ Console.log('apptics: debug mode ' + (on ? 'on' : 'off')); // no i18n
62
+ }
63
+ /**
64
+ * Turns debug mode on, at any time: before init(), during start-up or while the SDK runs. The
65
+ * choice holds over `debug` in init() for the rest of the page's life.
66
+ */
67
+ function enableDebug() {
68
+ chosen = true;
69
+ setDebug(true);
70
+ }
71
+ /** Turns debug mode off, at any time, with the same hold over `debug` as enableDebug(). */
72
+ function disableDebug() {
73
+ chosen = false;
74
+ setDebug(false);
75
+ }
76
+ /** What init() applies for `debug`: the config's value, unless the app has already chosen. */
77
+ function applyDebugConfig(configured) {
78
+ setDebug(chosen !== null ? chosen : configured);
79
+ }
80
+
81
+ export { applyDebugConfig, debugEnabled, disableDebug, enableDebug, expireDebugIfIdle, noteDebugActivity };
@@ -0,0 +1,28 @@
1
+ import type { AppticsConfig } from '../types.js';
2
+ export declare function isBlockedWS(ua: string): boolean;
3
+ /** Device RAM as the API wants it ("4 GB"). Chromium only; empty elsewhere. */
4
+ export declare function getRam(): string;
5
+ export declare function getConnectionType(): string;
6
+ export declare function getNetworkStatus(): number;
7
+ /**
8
+ * The battery as a whole percentage, or null where the browser will not say.
9
+ *
10
+ * feedbackWebSDK types `battery` as an int and the console shows it next to a report, which is
11
+ * what makes "it died while I was filling this in" legible. The Battery Status API is behind a
12
+ * promise and is absent in Firefox and Safari entirely, so this answers null rather than 0 -
13
+ * a real 0% and "no answer" are different things, and only one of them belongs in a report.
14
+ */
15
+ export declare function getBatteryPercent(): Promise<number | null>;
16
+ export declare function getOrientation(): number;
17
+ export declare function getDevice(): string;
18
+ export declare function getOS(): string;
19
+ export declare function getBrowser(): string;
20
+ export declare function getBrowserVersion(): number | string;
21
+ export declare function getReferringURL(): string;
22
+ export declare function getTimeZone(): string;
23
+ /** True for crawlers and non-browser environments; the SDK does nothing for them. */
24
+ export declare function is_apptics_disabled(): boolean;
25
+ /** Pure DNT check (no side effects). consent.hasDoNotTrackEnabled() applies NO_TRACKING. */
26
+ export declare function isDntOn(): boolean;
27
+ /** The console snippet's config (window.appticssettings._defaultoptions), if the page defines one. */
28
+ export declare function getSnippetOptions(): AppticsConfig | undefined;