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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/CHANGELOG.md +111 -5
  2. package/README.md +399 -300
  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-VYr43KcB.min.js +3 -0
  8. package/dist/chunks/lifecycle-VYr43KcB.min.js.map +1 -0
  9. package/dist/cjs/auto-init.d.ts +3 -3
  10. package/dist/cjs/auto-init.js +1 -1
  11. package/dist/cjs/core/attempts.js +1 -1
  12. package/dist/cjs/core/batch.js +2 -1
  13. package/dist/cjs/core/callsite.d.ts +6 -0
  14. package/dist/cjs/core/callsite.js +25 -3
  15. package/dist/cjs/core/consent.d.ts +5 -1
  16. package/dist/cjs/core/consent.js +8 -6
  17. package/dist/cjs/core/constants.d.ts +35 -10
  18. package/dist/cjs/core/constants.js +31 -15
  19. package/dist/cjs/core/db.d.ts +12 -4
  20. package/dist/cjs/core/db.js +167 -34
  21. package/dist/cjs/core/debug.js +1 -1
  22. package/dist/cjs/core/env.js +1 -1
  23. package/dist/cjs/core/framework-id.d.ts +1 -1
  24. package/dist/cjs/core/framework-id.js +3 -3
  25. package/dist/cjs/core/guard.d.ts +9 -0
  26. package/dist/cjs/core/guard.js +27 -13
  27. package/dist/cjs/core/hooks.d.ts +2 -4
  28. package/dist/cjs/core/hooks.js +2 -3
  29. package/dist/cjs/core/locks.d.ts +9 -0
  30. package/dist/cjs/core/locks.js +22 -0
  31. package/dist/cjs/core/logger.d.ts +3 -4
  32. package/dist/cjs/core/logger.js +4 -40
  33. package/dist/cjs/core/state.d.ts +3 -2
  34. package/dist/cjs/core/state.js +2 -2
  35. package/dist/cjs/core/storage.d.ts +20 -5
  36. package/dist/cjs/core/storage.js +115 -17
  37. package/dist/cjs/core/stylesheet.d.ts +8 -0
  38. package/dist/cjs/core/stylesheet.js +29 -0
  39. package/dist/cjs/core/transport.d.ts +2 -0
  40. package/dist/cjs/core/transport.js +19 -4
  41. package/dist/cjs/core/utils.js +1 -1
  42. package/dist/cjs/core/validate.js +2 -2
  43. package/dist/cjs/device/appversion.d.ts +1 -6
  44. package/dist/cjs/device/appversion.js +13 -1
  45. package/dist/cjs/device/index.d.ts +11 -0
  46. package/dist/cjs/device/index.js +120 -20
  47. package/dist/cjs/engagement/api-rules.d.ts +32 -67
  48. package/dist/cjs/engagement/api-rules.js +144 -157
  49. package/dist/cjs/engagement/auto-api.js +2 -2
  50. package/dist/cjs/engagement/auto-screen.d.ts +2 -0
  51. package/dist/cjs/engagement/auto-screen.js +67 -3
  52. package/dist/cjs/engagement/defined-events.js +1 -1
  53. package/dist/cjs/engagement/send.js +6 -1
  54. package/dist/cjs/engagement/session.d.ts +12 -3
  55. package/dist/cjs/engagement/session.js +161 -25
  56. package/dist/cjs/engagement/track.js +45 -20
  57. package/dist/cjs/errors/send.js +1 -1
  58. package/dist/cjs/errors/track.d.ts +1 -1
  59. package/dist/cjs/errors/track.js +46 -6
  60. package/dist/cjs/feedback/controls.d.ts +6 -0
  61. package/dist/cjs/feedback/controls.js +31 -1
  62. package/dist/cjs/feedback/index.d.ts +8 -7
  63. package/dist/cjs/feedback/index.js +32 -13
  64. package/dist/cjs/feedback/logs.d.ts +10 -5
  65. package/dist/cjs/feedback/logs.js +52 -13
  66. package/dist/cjs/feedback/quartz.d.ts +18 -0
  67. package/dist/cjs/feedback/quartz.js +105 -0
  68. package/dist/cjs/feedback/send.d.ts +3 -0
  69. package/dist/cjs/feedback/send.js +28 -3
  70. package/dist/cjs/feedback/styles.d.ts +10 -0
  71. package/dist/cjs/feedback/styles.js +8 -0
  72. package/dist/cjs/feedback/template.d.ts +1 -1
  73. package/dist/cjs/feedback/template.js +12 -12
  74. package/dist/cjs/feedback/ui.d.ts +14 -6
  75. package/dist/cjs/feedback/ui.js +126 -48
  76. package/dist/cjs/heatmap/send.js +1 -1
  77. package/dist/cjs/heatmap/track.d.ts +1 -1
  78. package/dist/cjs/heatmap/track.js +87 -16
  79. package/dist/cjs/index.d.ts +17 -63
  80. package/dist/cjs/index.js +104 -92
  81. package/dist/cjs/lifecycle.d.ts +8 -1
  82. package/dist/cjs/lifecycle.js +258 -62
  83. package/dist/cjs/remoteconfig/country.d.ts +4 -0
  84. package/dist/cjs/remoteconfig/country.js +73 -0
  85. package/dist/cjs/remoteconfig/custom.d.ts +7 -7
  86. package/dist/cjs/remoteconfig/custom.js +31 -51
  87. package/dist/cjs/remoteconfig/evaluate.d.ts +3 -3
  88. package/dist/cjs/remoteconfig/evaluate.js +56 -43
  89. package/dist/cjs/remoteconfig/fetch.d.ts +3 -3
  90. package/dist/cjs/remoteconfig/fetch.js +9 -23
  91. package/dist/cjs/remoteconfig/index.d.ts +10 -8
  92. package/dist/cjs/remoteconfig/index.js +65 -39
  93. package/dist/cjs/remoteconfig/store.js +1 -1
  94. package/dist/cjs/remoteconfig/tz-countries.d.ts +8 -0
  95. package/dist/cjs/remoteconfig/tz-countries.js +13 -0
  96. package/dist/cjs/remotelog/gate.d.ts +2 -11
  97. package/dist/cjs/remotelog/gate.js +9 -35
  98. package/dist/cjs/remotelog/index.d.ts +4 -21
  99. package/dist/cjs/remotelog/logger.d.ts +11 -17
  100. package/dist/cjs/remotelog/logger.js +30 -58
  101. package/dist/cjs/remotelog/send.js +10 -10
  102. package/dist/cjs/remotelogger/index.d.ts +12 -0
  103. package/dist/cjs/remotelogger/index.js +18 -0
  104. package/dist/cjs/scheduler.js +2 -2
  105. package/dist/cjs/types.d.ts +155 -82
  106. package/dist/cjs/user/index.js +11 -6
  107. package/dist/esm/auto-init.d.ts +3 -3
  108. package/dist/esm/auto-init.js +1 -1
  109. package/dist/esm/core/attempts.js +1 -1
  110. package/dist/esm/core/batch.js +2 -1
  111. package/dist/esm/core/callsite.d.ts +6 -0
  112. package/dist/esm/core/callsite.js +25 -4
  113. package/dist/esm/core/consent.d.ts +5 -1
  114. package/dist/esm/core/consent.js +9 -7
  115. package/dist/esm/core/constants.d.ts +35 -10
  116. package/dist/esm/core/constants.js +30 -15
  117. package/dist/esm/core/db.d.ts +12 -4
  118. package/dist/esm/core/db.js +164 -35
  119. package/dist/esm/core/debug.js +1 -1
  120. package/dist/esm/core/env.js +1 -1
  121. package/dist/esm/core/framework-id.d.ts +1 -1
  122. package/dist/esm/core/framework-id.js +3 -3
  123. package/dist/esm/core/guard.d.ts +9 -0
  124. package/dist/esm/core/guard.js +27 -14
  125. package/dist/esm/core/hooks.d.ts +2 -4
  126. package/dist/esm/core/hooks.js +2 -3
  127. package/dist/esm/core/locks.d.ts +9 -0
  128. package/dist/esm/core/locks.js +20 -0
  129. package/dist/esm/core/logger.d.ts +3 -4
  130. package/dist/esm/core/logger.js +4 -40
  131. package/dist/esm/core/state.d.ts +3 -2
  132. package/dist/esm/core/state.js +2 -2
  133. package/dist/esm/core/storage.d.ts +20 -5
  134. package/dist/esm/core/storage.js +113 -18
  135. package/dist/esm/core/stylesheet.d.ts +8 -0
  136. package/dist/esm/core/stylesheet.js +27 -0
  137. package/dist/esm/core/transport.d.ts +2 -0
  138. package/dist/esm/core/transport.js +19 -5
  139. package/dist/esm/core/utils.js +1 -1
  140. package/dist/esm/core/validate.js +2 -2
  141. package/dist/esm/device/appversion.d.ts +1 -6
  142. package/dist/esm/device/appversion.js +13 -2
  143. package/dist/esm/device/index.d.ts +11 -0
  144. package/dist/esm/device/index.js +123 -24
  145. package/dist/esm/engagement/api-rules.d.ts +32 -67
  146. package/dist/esm/engagement/api-rules.js +143 -155
  147. package/dist/esm/engagement/auto-api.js +3 -3
  148. package/dist/esm/engagement/auto-screen.d.ts +2 -0
  149. package/dist/esm/engagement/auto-screen.js +67 -4
  150. package/dist/esm/engagement/defined-events.js +1 -1
  151. package/dist/esm/engagement/send.js +6 -1
  152. package/dist/esm/engagement/session.d.ts +12 -3
  153. package/dist/esm/engagement/session.js +162 -29
  154. package/dist/esm/engagement/track.js +52 -27
  155. package/dist/esm/errors/send.js +1 -1
  156. package/dist/esm/errors/track.d.ts +1 -1
  157. package/dist/esm/errors/track.js +46 -6
  158. package/dist/esm/feedback/controls.d.ts +6 -0
  159. package/dist/esm/feedback/controls.js +31 -2
  160. package/dist/esm/feedback/index.d.ts +8 -7
  161. package/dist/esm/feedback/index.js +34 -13
  162. package/dist/esm/feedback/logs.d.ts +10 -5
  163. package/dist/esm/feedback/logs.js +54 -15
  164. package/dist/esm/feedback/quartz.d.ts +18 -0
  165. package/dist/esm/feedback/quartz.js +99 -0
  166. package/dist/esm/feedback/send.d.ts +3 -0
  167. package/dist/esm/feedback/send.js +28 -5
  168. package/dist/esm/feedback/styles.d.ts +10 -0
  169. package/dist/esm/feedback/styles.js +4 -0
  170. package/dist/esm/feedback/template.d.ts +1 -1
  171. package/dist/esm/feedback/template.js +12 -12
  172. package/dist/esm/feedback/ui.d.ts +14 -6
  173. package/dist/esm/feedback/ui.js +126 -49
  174. package/dist/esm/heatmap/send.js +1 -1
  175. package/dist/esm/heatmap/track.d.ts +1 -1
  176. package/dist/esm/heatmap/track.js +87 -16
  177. package/dist/esm/index.d.ts +17 -63
  178. package/dist/esm/index.js +108 -80
  179. package/dist/esm/lifecycle.d.ts +8 -1
  180. package/dist/esm/lifecycle.js +266 -71
  181. package/dist/esm/remoteconfig/country.d.ts +4 -0
  182. package/dist/esm/remoteconfig/country.js +70 -0
  183. package/dist/esm/remoteconfig/custom.d.ts +7 -7
  184. package/dist/esm/remoteconfig/custom.js +32 -52
  185. package/dist/esm/remoteconfig/evaluate.d.ts +3 -3
  186. package/dist/esm/remoteconfig/evaluate.js +57 -44
  187. package/dist/esm/remoteconfig/fetch.d.ts +3 -3
  188. package/dist/esm/remoteconfig/fetch.js +9 -23
  189. package/dist/esm/remoteconfig/index.d.ts +10 -8
  190. package/dist/esm/remoteconfig/index.js +66 -40
  191. package/dist/esm/remoteconfig/store.js +1 -1
  192. package/dist/esm/remoteconfig/tz-countries.d.ts +8 -0
  193. package/dist/esm/remoteconfig/tz-countries.js +11 -0
  194. package/dist/esm/remotelog/gate.d.ts +2 -11
  195. package/dist/esm/remotelog/gate.js +10 -32
  196. package/dist/esm/remotelog/index.d.ts +4 -21
  197. package/dist/esm/remotelog/logger.d.ts +11 -17
  198. package/dist/esm/remotelog/logger.js +32 -60
  199. package/dist/esm/remotelog/send.js +12 -12
  200. package/dist/esm/remotelogger/index.d.ts +12 -0
  201. package/dist/esm/remotelogger/index.js +13 -0
  202. package/dist/esm/scheduler.js +2 -2
  203. package/dist/esm/types.d.ts +155 -82
  204. package/dist/esm/user/index.js +12 -6
  205. package/dist/feedback.esm.min.js +2 -2
  206. package/dist/feedback.esm.min.js.map +1 -1
  207. package/package.json +14 -16
  208. package/dist/chunks/batch-BU_mTpm1.min.js +0 -3
  209. package/dist/chunks/batch-BU_mTpm1.min.js.map +0 -1
  210. package/dist/chunks/logs-Bea5zUW_.min.js +0 -3
  211. package/dist/chunks/logs-Bea5zUW_.min.js.map +0 -1
  212. package/dist/cjs/heatmap/index.d.ts +0 -16
  213. package/dist/cjs/heatmap/index.js +0 -22
  214. package/dist/cjs/remotelog/index.js +0 -55
  215. package/dist/esm/heatmap/index.d.ts +0 -16
  216. package/dist/esm/heatmap/index.js +0 -17
  217. package/dist/esm/remotelog/index.js +0 -51
  218. package/dist/heatmap.esm.min.js +0 -3
  219. package/dist/heatmap.esm.min.js.map +0 -1
  220. package/dist/style.css +0 -1
@@ -1,4 +1,4 @@
1
- /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
2
2
  const AP_TRACKING_STATUS = Object.freeze({
3
3
  USAGE_TRACKING_WITH_PII: 1,
4
4
  USAGE_TRACKING_WITHOUT_PII: 4,
@@ -138,8 +138,6 @@ const AP_CONFIG = Object.freeze({
138
138
  debug: false,
139
139
  track_by_default: true,
140
140
  ignore_do_not_track: false,
141
- // the SDK's own failure reports to the Remote Logger page: off unless the app passes remote_log: true
142
- remote_log: false,
143
141
  /**
144
142
  * Wrap XHR and fetch to record the app's API calls without it calling startTrackApi(). Off by
145
143
  * default: the hostnames and paths of every request an app makes is a wider grant than events
@@ -152,15 +150,16 @@ const AP_CONFIG = Object.freeze({
152
150
  */
153
151
  track_screen: true,
154
152
  /**
155
- * Print each app logger line to the browser console as well, as Android's showLogs prints to
156
- * Logcat. Off by default; console_log is the SDK's own activity, this is the app's lines.
153
+ * How automatic screen tracking names a path, as init() keeps the config's screen_routes: route
154
+ * patterns (`/users/{id}/orders`, each id recorded as a star), exact paths and regular
155
+ * expressions with a name. Tried in order; a path none matches keeps its own name.
157
156
  */
158
- show_logs: false,
157
+ screen_routes: [],
159
158
  /**
160
- * Record sessions automatically. On by default; false is Android's
161
- * automaticSessionsTrackingStatus = false: no sessions, while events and screens still are.
159
+ * The feedback form's theme: 'light', 'dark', or 'auto' to follow the visitor's system setting.
160
+ * 'auto' by default.
162
161
  */
163
- track_session: true,
162
+ feedback_theme: 'auto',
164
163
  /**
165
164
  * How long a visit must last before its session is stored, in milliseconds. A shorter visit with
166
165
  * nothing tracked in it is dropped: a bounce or a crawler is not a session. Anything tracked
@@ -206,7 +205,17 @@ const AP_CONFIG = Object.freeze({
206
205
  * What init() must be given. Everything else the SDK needs — aaid, the portal and project ids that
207
206
  * go in every url — comes back from app/addversion, which these four are enough to call.
208
207
  */
209
- const REQUIRED_CONFIG = Object.freeze(['serviceUrl', 'zak', 'identifier', 'appversion']); // no i18n
208
+ const REQUIRED_CONFIG = Object.freeze(['base_url', 'auth_key', 'app_domain', 'appversion']); // no i18n
209
+ /**
210
+ * The init() keys and the names the SDK keeps them under inside (and in app_version_info, which
211
+ * already-visited browsers have stored): base_url is the host, auth_key the `zak` header, and
212
+ * app_domain the app's identifier.
213
+ */
214
+ const CONFIG_KEYS = Object.freeze({
215
+ base_url: 'serviceUrl', // no i18n
216
+ auth_key: 'zak', // no i18n
217
+ app_domain: 'identifier', // no i18n
218
+ });
210
219
  /**
211
220
  * Paths with a `debug/` twin. The debug endpoints take the same body and answer with a request id
212
221
  * and a link to the server-side logs for that request, which is how a payload is traced end to
@@ -241,10 +250,16 @@ const RETRY_CAPABLE_PATHS = Object.freeze({
241
250
  const PATHS_WITHOUT_ORG = Object.freeze({
242
251
  addversion: true, // no i18n
243
252
  });
244
- /** Console-snippet names accepted for the canonical keys above. */
245
- const CONFIG_ALIASES = Object.freeze({
246
- serviceUrl: 'base_domain', // no i18n
247
- zak: 'token', // no i18n
253
+ /**
254
+ * Earlier names of the init() keys: 2.0.0-beta's serviceUrl, zak and identifier, and the 1.x
255
+ * console snippet's base_domain and token. Still read, with a warning naming the key to use.
256
+ */
257
+ const RETIRED_CONFIG_NAMES = Object.freeze({
258
+ serviceUrl: 'base_url', // no i18n
259
+ base_domain: 'base_url', // no i18n
260
+ zak: 'auth_key', // no i18n
261
+ token: 'auth_key', // no i18n
262
+ identifier: 'app_domain', // no i18n
248
263
  });
249
264
  // crawlers reference
250
265
  // https://developers.google.com/search/docs/advanced/crawling/overview-google-crawlers
@@ -274,4 +289,4 @@ const BLOCKED_WS = Object.freeze([
274
289
  'storebot-google', // no i18n
275
290
  ]);
276
291
 
277
- export { API_VERSIONS, AP_CONFIG, AP_CONSTANTS, AP_FEEDBACK_TYPE, AP_LOG_MODULE, AP_TRACKING_STATUS, BLOCKED_WS, CONFIG_ALIASES, CONSOLE_LOG_MAX_BODY, DEBUG_CAPABLE_PATHS, DEBUG_IDLE_MS, DEFAULT_API_PATHS, DEFAULT_INACTIVE_MINUTES, DEVICE_NAME_MAX, LOG_FILENAME_MAX, LOG_FUNCTION_MAX, PATHS_WITHOUT_ORG, REMOTE_LOG_LEVEL, REQUIRED_CONFIG, RETRY_CAPABLE_PATHS, SDK_MODULE };
292
+ export { API_VERSIONS, AP_CONFIG, AP_CONSTANTS, AP_FEEDBACK_TYPE, AP_LOG_MODULE, AP_TRACKING_STATUS, BLOCKED_WS, CONFIG_KEYS, CONSOLE_LOG_MAX_BODY, DEBUG_CAPABLE_PATHS, DEBUG_IDLE_MS, DEFAULT_API_PATHS, DEFAULT_INACTIVE_MINUTES, DEVICE_NAME_MAX, LOG_FILENAME_MAX, LOG_FUNCTION_MAX, PATHS_WITHOUT_ORG, REMOTE_LOG_LEVEL, REQUIRED_CONFIG, RETIRED_CONFIG_NAMES, RETRY_CAPABLE_PATHS, SDK_MODULE };
@@ -1,10 +1,12 @@
1
1
  import type { Dict, QueueItem } from '../types.js';
2
- export type QueueName = 'engagements' | 'errors' | 'logs' | 'consolelogs' | 'heatmaps';
2
+ export type QueueName = 'engagements' | 'errors' | 'feedbacklogs' | 'remotelogs' | 'heatmaps';
3
3
  /** One storage implementation. storage.ts talks only to this interface. */
4
4
  export interface Backend {
5
5
  readonly kind: 'indexeddb' | 'localstorage';
6
6
  loadSettings(): Promise<Dict>;
7
7
  putSetting(key: string, value: unknown): Promise<void>;
8
+ /** Removes the key itself, so it is no longer in storage at all. */
9
+ deleteSetting(key: string): Promise<void>;
8
10
  clearSettings(): Promise<void>;
9
11
  /** Items in insertion order. */
10
12
  queueAll(store: QueueName): Promise<QueueItem[]>;
@@ -16,16 +18,22 @@ export interface Backend {
16
18
  importAll?(settings: Dict, queues: Record<QueueName, QueueItem[]>): Promise<void>;
17
19
  }
18
20
  export declare const DB_NAME = "apptics";
19
- export declare const DB_VERSION = 3;
20
- /** 1.x localStorage keys; also the layout of the localStorage backend. */
21
+ export declare const DB_VERSION = 4;
22
+ /** The types a feedback entry is stored under: an addFeedbackLog() line, an addDiagnosticsInfo() entry. */
23
+ export declare const FEEDBACK_LOG = "feedbacklog";
24
+ export declare const FEEDBACK_DIAGNOSTICS = "feedbackdiagnostics";
25
+ /** A feedback entry from 1.x or 2.0.0-beta, with the type it is stored under now. */
26
+ export declare function renameFeedbackType(item: QueueItem): QueueItem;
27
+ /** 1.x localStorage keys, read once to bring 1.x data into IndexedDB (see migrateLegacy). */
21
28
  export declare const LEGACY_KEYS: Readonly<{
22
29
  readonly settings: "apptics-device-info";
23
30
  readonly engagements: "apptics-engagements-transactions";
24
31
  readonly errors: "apptics-errors-transactions";
25
32
  readonly logs: "apptics-log-transactions";
26
33
  readonly consolelogs: "apptics-consolelog-transactions";
27
- readonly heatmaps: "apptics-heatmap-transactions";
28
34
  }>;
35
+ /** The localStorage backend's layout, for a browser where IndexedDB will not open. */
36
+ export declare const LOCAL_KEYS: Readonly<Record<'settings' | QueueName, string>>;
29
37
  /** Shape guards shared by both backends and the 1.x migration. */
30
38
  export declare function asList(value: unknown): QueueItem[];
31
39
  export declare function asDict(value: unknown): Dict;
@@ -1,24 +1,71 @@
1
- /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
2
2
  import { Console } from './logger.js';
3
3
  import { nowMs } from './utils.js';
4
4
 
5
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;
6
+ // 3 added the heatmaps store. 4 renamed: each record's order key `seq` to `queue`, the logs store
7
+ // to feedbacklogs and consolelogs to remotelogs. Every upgrade keeps what is already queued.
8
+ const DB_VERSION = 4;
9
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. */
10
+ const QUEUES = ['engagements', 'errors', 'feedbacklogs', 'remotelogs', 'heatmaps']; // no i18n
11
+ /** The field, and the index on it, that keeps a queue's records in the order they were added. */
12
+ const QUEUE_KEY = 'queue'; // no i18n
13
+ /** Version 3's names, which the version 4 upgrade moves to the ones above. */
14
+ const OLD_QUEUE_KEY = 'seq'; // no i18n
15
+ const RENAMED_STORES = [['logs', 'feedbacklogs'], ['consolelogs', 'remotelogs']]; // no i18n
16
+ /** The types a feedback entry is stored under: an addFeedbackLog() line, an addDiagnosticsInfo() entry. */
17
+ const FEEDBACK_LOG = 'feedbacklog'; // no i18n
18
+ const FEEDBACK_DIAGNOSTICS = 'feedbackdiagnostics'; // no i18n
19
+ const OLD_FEEDBACK_TYPES = Object.freeze({
20
+ log: FEEDBACK_LOG, // no i18n
21
+ diagnostics: FEEDBACK_DIAGNOSTICS, // no i18n
22
+ });
23
+ /** A feedback entry from 1.x or 2.0.0-beta, with the type it is stored under now. */
24
+ function renameFeedbackType(item) {
25
+ var renamed = item && typeof item.type === 'string' ? OLD_FEEDBACK_TYPES[item.type] : undefined; // no i18n
26
+ return renamed ? { ...item, type: renamed } : item;
27
+ }
28
+ /** 1.x localStorage keys, read once to bring 1.x data into IndexedDB (see migrateLegacy). */
12
29
  const LEGACY_KEYS = Object.freeze({
13
30
  settings: 'apptics-device-info', // no i18n
14
31
  engagements: 'apptics-engagements-transactions', // no i18n
15
32
  errors: 'apptics-errors-transactions', // no i18n
16
33
  logs: 'apptics-log-transactions', // no i18n
17
34
  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
35
+ });
36
+ /** The localStorage backend's layout, for a browser where IndexedDB will not open. */
37
+ const LOCAL_KEYS = Object.freeze({
38
+ settings: LEGACY_KEYS.settings,
39
+ engagements: LEGACY_KEYS.engagements,
40
+ errors: LEGACY_KEYS.errors,
41
+ feedbacklogs: 'apptics-feedbacklog-transactions', // no i18n
42
+ remotelogs: 'apptics-remotelog-transactions', // no i18n
20
43
  heatmaps: 'apptics-heatmap-transactions', // no i18n
21
44
  });
45
+ /**
46
+ * The localStorage backend once kept these two under the 1.x keys. Moved to the new ones on first
47
+ * use, feedback types renamed on the way, unless something is already there.
48
+ */
49
+ function moveRenamedLocalKeys() {
50
+ [[LEGACY_KEYS.logs, LOCAL_KEYS.feedbacklogs], [LEGACY_KEYS.consolelogs, LOCAL_KEYS.remotelogs]].forEach(function (pair) {
51
+ try {
52
+ var from = pair[0];
53
+ var to = pair[1];
54
+ var old = localStorage.getItem(from);
55
+ if (old === null) {
56
+ return;
57
+ }
58
+ if (localStorage.getItem(to) === null) {
59
+ var items = asList(JSON.parse(old));
60
+ localStorage.setItem(to, JSON.stringify(to === LOCAL_KEYS.feedbacklogs ? items.map(renameFeedbackType) : items));
61
+ }
62
+ localStorage.removeItem(from);
63
+ }
64
+ catch (err) {
65
+ // left where it is; the next load tries again
66
+ }
67
+ });
68
+ }
22
69
  /** Shape guards shared by both backends and the 1.x migration. */
23
70
  function asList(value) {
24
71
  return Array.isArray(value) ? value : [];
@@ -46,26 +93,33 @@ function writeJSON(key, value) {
46
93
  }
47
94
  }
48
95
  function createLocalStorageBackend() {
96
+ moveRenamedLocalKeys();
49
97
  return {
50
98
  kind: 'localstorage', // no i18n
51
99
  loadSettings() {
52
- return Promise.resolve(asDict(readJSON(LEGACY_KEYS.settings)));
100
+ return Promise.resolve(asDict(readJSON(LOCAL_KEYS.settings)));
53
101
  },
54
102
  putSetting(key, value) {
55
- const all = asDict(readJSON(LEGACY_KEYS.settings));
103
+ const all = asDict(readJSON(LOCAL_KEYS.settings));
56
104
  all[key] = value;
57
- writeJSON(LEGACY_KEYS.settings, all);
105
+ writeJSON(LOCAL_KEYS.settings, all);
106
+ return Promise.resolve();
107
+ },
108
+ deleteSetting(key) {
109
+ const all = asDict(readJSON(LOCAL_KEYS.settings));
110
+ delete all[key];
111
+ writeJSON(LOCAL_KEYS.settings, all);
58
112
  return Promise.resolve();
59
113
  },
60
114
  clearSettings() {
61
- writeJSON(LEGACY_KEYS.settings, {});
115
+ writeJSON(LOCAL_KEYS.settings, {});
62
116
  return Promise.resolve();
63
117
  },
64
118
  queueAll(store) {
65
- return Promise.resolve(asList(readJSON(LEGACY_KEYS[store])));
119
+ return Promise.resolve(asList(readJSON(LOCAL_KEYS[store])));
66
120
  },
67
121
  queuePut(store, items) {
68
- const list = asList(readJSON(LEGACY_KEYS[store]));
122
+ const list = asList(readJSON(LOCAL_KEYS[store]));
69
123
  items.forEach(function (item) {
70
124
  const index = list.findIndex(function (existing) { return existing.id === item.id; });
71
125
  if (index === -1) {
@@ -75,32 +129,32 @@ function createLocalStorageBackend() {
75
129
  list[index] = item;
76
130
  }
77
131
  });
78
- writeJSON(LEGACY_KEYS[store], list);
132
+ writeJSON(LOCAL_KEYS[store], list);
79
133
  return Promise.resolve();
80
134
  },
81
135
  queueDelete(store, ids) {
82
- const remaining = asList(readJSON(LEGACY_KEYS[store])).filter(function (item) {
136
+ const remaining = asList(readJSON(LOCAL_KEYS[store])).filter(function (item) {
83
137
  return ids.indexOf(item.id) === -1;
84
138
  });
85
- writeJSON(LEGACY_KEYS[store], remaining);
139
+ writeJSON(LOCAL_KEYS[store], remaining);
86
140
  return Promise.resolve();
87
141
  },
88
142
  queueClear(store) {
89
- writeJSON(LEGACY_KEYS[store], []);
143
+ writeJSON(LOCAL_KEYS[store], []);
90
144
  return Promise.resolve();
91
145
  },
92
146
  };
93
147
  }
94
- let lastSeq = 0;
148
+ let lastQueue = 0;
95
149
  /**
96
150
  * Strictly increasing, and time-based so tabs interleave in roughly the right order.
97
151
  * Counting up from the last value rather than a counter that wraps keeps insertion order
98
152
  * even when a chatty caller adds more than a thousand items inside one millisecond.
99
153
  */
100
- function nextSeq() {
154
+ function nextQueue() {
101
155
  const base = nowMs() * 1000;
102
- lastSeq = base > lastSeq ? base : lastSeq + 1;
103
- return lastSeq;
156
+ lastQueue = base > lastQueue ? base : lastQueue + 1;
157
+ return lastQueue;
104
158
  }
105
159
  function request(req) {
106
160
  return new Promise(function (resolve, reject) {
@@ -115,7 +169,21 @@ function completed(tx) {
115
169
  tx.onabort = function () { reject(tx.error); };
116
170
  });
117
171
  }
118
- /** Puts `item` unless it exists (keepExisting) or replaces it keeping its seq. Runs inside `store`'s transaction. */
172
+ /**
173
+ * The record's `type` for an item with none of its own: heatmap records carry no type, since
174
+ * their payload is the item itself and the server takes no extra field. Never undefined.
175
+ */
176
+ const STORE_TYPES = Object.freeze({
177
+ engagements: 'engagement', // no i18n
178
+ errors: 'error', // no i18n
179
+ feedbacklogs: FEEDBACK_LOG,
180
+ remotelogs: 'remotelog', // no i18n
181
+ heatmaps: 'heatmap', // no i18n
182
+ });
183
+ function recordType(storeName, item) {
184
+ return item && typeof item.type === 'string' && item.type !== '' ? item.type : (STORE_TYPES[storeName] || storeName); // no i18n
185
+ }
186
+ /** Puts `item` unless it exists (keepExisting) or replaces it keeping its place. Runs inside `store`'s transaction. */
119
187
  function putRecord(store, item, keepExisting) {
120
188
  const id = String(item.id);
121
189
  const lookup = store.get(id);
@@ -124,7 +192,7 @@ function putRecord(store, item, keepExisting) {
124
192
  if (existing && keepExisting) {
125
193
  return;
126
194
  }
127
- store.put({ id: id, seq: existing ? existing.seq : nextSeq(), type: item.type, item: item });
195
+ store.put({ id: id, queue: existing ? existing.queue : nextQueue(), type: recordType(store.name, item), item: item });
128
196
  };
129
197
  }
130
198
  /** Our stores, as created by onupgradeneeded. */
@@ -185,15 +253,7 @@ function openOnce(factory, timeoutMs) {
185
253
  return;
186
254
  }
187
255
  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
- });
256
+ upgrade(req.result, req.transaction);
197
257
  };
198
258
  req.onsuccess = function () {
199
259
  if (settled) {
@@ -224,6 +284,70 @@ function openOnce(factory, timeoutMs) {
224
284
  };
225
285
  });
226
286
  }
287
+ /**
288
+ * Creates what is missing and moves version 3's data to version 4's names, inside the upgrade's
289
+ * own transaction: either the whole upgrade lands, or the database stays at the old version with
290
+ * everything still in it.
291
+ */
292
+ function upgrade(db, tx) {
293
+ if (!db.objectStoreNames.contains('settings')) { // no i18n
294
+ db.createObjectStore('settings'); // no i18n
295
+ }
296
+ QUEUES.forEach(function (name) {
297
+ if (!db.objectStoreNames.contains(name)) {
298
+ db.createObjectStore(name, { keyPath: 'id' }).createIndex(QUEUE_KEY, QUEUE_KEY); // no i18n
299
+ }
300
+ });
301
+ // kept stores: the order key is renamed on every record, and the index with it
302
+ QUEUES.forEach(function (name) {
303
+ const store = tx.objectStore(name);
304
+ if (!store.indexNames.contains(OLD_QUEUE_KEY)) {
305
+ return;
306
+ }
307
+ store.deleteIndex(OLD_QUEUE_KEY);
308
+ if (!store.indexNames.contains(QUEUE_KEY)) {
309
+ store.createIndex(QUEUE_KEY, QUEUE_KEY);
310
+ }
311
+ eachRecord(store, function (record, cursor) {
312
+ cursor.update(renamedRecord(record, false, name));
313
+ });
314
+ });
315
+ // renamed stores: every record moves to its new store, then the old store goes
316
+ RENAMED_STORES.forEach(function (pair) {
317
+ const from = pair[0];
318
+ const to = pair[1];
319
+ if (!db.objectStoreNames.contains(from)) {
320
+ return;
321
+ }
322
+ const source = tx.objectStore(from);
323
+ const target = tx.objectStore(to);
324
+ eachRecord(source, function (record) {
325
+ target.put(renamedRecord(record, to === 'feedbacklogs', to)); // no i18n
326
+ }, function () {
327
+ db.deleteObjectStore(from);
328
+ });
329
+ });
330
+ }
331
+ /** Calls `each` for every record of `store`, then `done`, inside the transaction `store` is in. */
332
+ function eachRecord(store, each, done) {
333
+ const req = store.openCursor();
334
+ req.onsuccess = function () {
335
+ const cursor = req.result;
336
+ if (!cursor) {
337
+ if (done)
338
+ done();
339
+ return;
340
+ }
341
+ each(cursor.value, cursor);
342
+ cursor.continue();
343
+ };
344
+ }
345
+ /** A version 3 record under version 4's names: `queue` for `seq`, and the feedback types renamed. */
346
+ function renamedRecord(record, feedback, storeName) {
347
+ const queue = typeof record[QUEUE_KEY] === 'number' ? record[QUEUE_KEY] : (typeof record[OLD_QUEUE_KEY] === 'number' ? record[OLD_QUEUE_KEY] : nextQueue()); // no i18n
348
+ const item = (feedback ? renameFeedbackType(record.item) : record.item);
349
+ return { id: String(record.id), queue: queue, type: recordType(storeName, item), item: item };
350
+ }
227
351
  function createIndexedDBBackend(db) {
228
352
  return {
229
353
  kind: 'indexeddb', // no i18n
@@ -242,13 +366,18 @@ function createIndexedDBBackend(db) {
242
366
  tx.objectStore('settings').put(value, key); // no i18n
243
367
  return completed(tx);
244
368
  },
369
+ deleteSetting(key) {
370
+ const tx = db.transaction('settings', 'readwrite'); // no i18n
371
+ tx.objectStore('settings').delete(key); // no i18n
372
+ return completed(tx);
373
+ },
245
374
  clearSettings() {
246
375
  const tx = db.transaction('settings', 'readwrite'); // no i18n
247
376
  tx.objectStore('settings').clear(); // no i18n
248
377
  return completed(tx);
249
378
  },
250
379
  queueAll(store) {
251
- const index = db.transaction(store, 'readonly').objectStore(store).index('seq'); // no i18n
380
+ const index = db.transaction(store, 'readonly').objectStore(store).index(QUEUE_KEY);
252
381
  return request(index.getAll()).then(function (records) {
253
382
  return records.map(function (record) { return record.item; });
254
383
  });
@@ -321,4 +450,4 @@ function openBackend() {
321
450
  return openIndexedDB(factory).then(createIndexedDBBackend, fallback);
322
451
  }
323
452
 
324
- export { DB_NAME, DB_VERSION, LEGACY_KEYS, asDict, asList, createIndexedDBBackend, createLocalStorageBackend, openBackend, openIndexedDB };
453
+ export { DB_NAME, DB_VERSION, FEEDBACK_DIAGNOSTICS, FEEDBACK_LOG, LEGACY_KEYS, LOCAL_KEYS, asDict, asList, createIndexedDBBackend, createLocalStorageBackend, openBackend, openIndexedDB, renameFeedbackType };
@@ -1,4 +1,4 @@
1
- /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
2
2
  import { DEBUG_IDLE_MS } from './constants.js';
3
3
  import { _ZAP } from './state.js';
4
4
  import { Console } from './logger.js';
@@ -1,4 +1,4 @@
1
- /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
2
2
  import { BLOCKED_WS } from './constants.js';
3
3
  import { includes } from './utils.js';
4
4
 
@@ -1 +1 @@
1
- export declare const FRAMEWORK_ID = 5996;
1
+ export declare const FRAMEWORK_ID = 6002;
@@ -1,7 +1,7 @@
1
- /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
2
2
  // Generated by scripts/register-version.mjs — do not edit by hand.
3
3
  // The framework id Apptics issued for this SDK, from POST /sdk/web/v1/framework/addversion
4
- // (version 2.0.0-beta, platform Browser). Regenerated on every npm pack.
5
- const FRAMEWORK_ID = 5996;
4
+ // (version 2.0.0-beta.1, platform Browser). Regenerated on every npm pack.
5
+ const FRAMEWORK_ID = 6002;
6
6
 
7
7
  export { FRAMEWORK_ID };
@@ -1,2 +1,11 @@
1
1
  /** Public calls never throw into the host app, and are buffered until start-up finishes. */
2
2
  export declare function guard<F extends (...args: any[]) => any>(name: string, fn: F): F;
3
+ /**
4
+ * Hands a public call's own `arguments` to its guarded function, exactly as they were given.
5
+ *
6
+ * guard() returns a wrapper that takes `...args`, so a browser console shows every public call as
7
+ * `(...args)`. Each public call is therefore its own function with named parameters, which is what
8
+ * the console shows, and forwards through this: `arguments` rather than the named parameters, so
9
+ * a call keeps its argument count (addEvent tells its two forms apart by it).
10
+ */
11
+ export declare function forward<F extends (...args: any[]) => any>(guarded: F, args: IArguments): ReturnType<F>;
@@ -1,4 +1,4 @@
1
- /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
2
2
  import { _ZAP } from './state.js';
3
3
  import { warnAlways, logFailure } from './logger.js';
4
4
 
@@ -8,29 +8,31 @@ import { warnAlways, logFailure } from './logger.js';
8
8
  * The two log collectors run now so an entry keeps the time it actually happened.
9
9
  */
10
10
  const RUN_BEFORE_READY = {
11
- 'Apptics.init': true, ready: true, reset: true, getUser: true, getTrackingStatus: true, sendFeedback: true,
12
- addFeedbackLog: true, addDiagnosticsInfo: true,
13
- // a switch, so it takes effect in order with the lines logged after it
14
- 'AppticsLogger.enable': true, 'AppticsLogger.disable': true, 'AppticsLogger.isEnabled': true,
11
+ 'Apptics.init': true, 'Apptics.ready': true, 'Apptics.reset': true, 'AppticsUser.getUser': true,
12
+ 'AppticsSettings.getTrackingStatus': true, 'AppticsFeedback.sendFeedback': true,
13
+ 'AppticsFeedback.addFeedbackLog': true, 'AppticsFeedback.addDiagnosticsInfo': true,
14
+ // a switch, which init() must not undo: it keeps what was set when its config has no theme
15
+ 'AppticsFeedback.setFeedbackTheme': true,
15
16
  // a switch, and a call that hands back the id endTrackApi needs: neither can wait in a queue
16
- 'AppticsApiTracker.configure': true, 'AppticsApiTracker.startTrackApi': true,
17
+ 'AppticsApi.configure': true, 'AppticsApi.startTrackApi': true,
17
18
  // these wait for ready() themselves, and a queued call would hand back undefined, not a Promise
18
19
  'AppticsRemoteConfig.fetchValue': true, 'AppticsRemoteConfig.fetchValues': true,
19
- 'AppticsRemoteConfig.setFallbackWithOfflineValue': true, 'AppticsRemoteConfig.setCustomConditionValue': true,
20
- enableDebug: true, disableDebug: true,
20
+ 'AppticsRemoteConfig.setCustomConditionValue': true,
21
+ 'Apptics.enableDebug': true, 'Apptics.disableDebug': true,
21
22
  };
22
23
  /**
23
24
  * Calls that record or send something, and so are lost when the SDK hasn't started. Calls that only
24
- * set a switch or read a value (enableDebug, AppticsLogger.enable, addFeedbackLog, getUser, …)
25
+ * set a switch or read a value (Apptics.enableDebug, AppticsLogger.enable, AppticsFeedback.addFeedbackLog,
26
+ * AppticsUser.getUser, …)
25
27
  * work without Apptics.init() and are not listed.
26
28
  */
27
29
  const NEEDS_INIT = {
28
- 'AppticsEvents.addEvent': true, 'AppticsScreenTracker.inScreen': true, 'AppticsScreenTracker.outScreen': true,
29
- 'AppticsApiTracker.endTrackApi': true, AppticsTrackError: true, AppticsSetUser: true, flush: true,
30
- AppticsLogger: true, sendFeedback: true, 'AppticsRemoteConfig.fetchValue': true,
30
+ 'AppticsEvent.addEvent': true, 'AppticsScreen.inScreen': true, 'AppticsScreen.outScreen': true,
31
+ 'AppticsApi.endTrackApi': true, 'AppticsError.trackError': true, 'AppticsUser.setUser': true,
32
+ 'Apptics.flush': true, AppticsLogger: true, 'AppticsFeedback.sendFeedback': true, 'AppticsRemoteConfig.fetchValue': true,
31
33
  'AppticsRemoteConfig.fetchValues': true,
32
34
  };
33
- /** How a call is named in a message: `AppticsEvents.addEvent` as it is, `flush` as `apptics.flush`. */
35
+ /** How a call is named in a message: every public call is named after its object, as `AppticsEvent.addEvent`. */
34
36
  function publicName(name) {
35
37
  return name.indexOf('Apptics') === 0 ? name : 'apptics.' + name; // no i18n
36
38
  }
@@ -66,5 +68,16 @@ function guard(name, fn) {
66
68
  };
67
69
  return guarded;
68
70
  }
71
+ /**
72
+ * Hands a public call's own `arguments` to its guarded function, exactly as they were given.
73
+ *
74
+ * guard() returns a wrapper that takes `...args`, so a browser console shows every public call as
75
+ * `(...args)`. Each public call is therefore its own function with named parameters, which is what
76
+ * the console shows, and forwards through this: `arguments` rather than the named parameters, so
77
+ * a call keeps its argument count (addEvent tells its two forms apart by it).
78
+ */
79
+ function forward(guarded, args) {
80
+ return guarded.apply(null, Array.prototype.slice.call(args));
81
+ }
69
82
 
70
- export { guard };
83
+ export { forward, guard };
@@ -1,4 +1,3 @@
1
- import type { CallSite } from './callsite.js';
2
1
  import type { DeviceInfo, ServerResult } from '../types.js';
3
2
  /**
4
3
  * Late-bound calls from lower modules up to the modules above them (see spec §5). device.ts and
@@ -9,7 +8,6 @@ export declare const hooks: {
9
8
  updateDevice: (deviceInfo: DeviceInfo) => Promise<ServerResult>;
10
9
  refreshDeviceInfo: () => void;
11
10
  /** Set by remotelog/index.ts. Here, not imported, so the logger doesn't depend on the sender. */
12
- remoteLog: (module: string, message: unknown, site?: CallSite) => void;
13
11
  /**
14
12
  * Set by feedback/controls.ts: the user picked in the feedback form, or null for anonymous.
15
13
  * Here so transport can read the choice without importing the modal.
@@ -24,7 +22,7 @@ export declare const hooks: {
24
22
  */
25
23
  sendHeatmaps: (forget?: boolean) => Promise<void>;
26
24
  /** Set by heatmap/track.ts, so init() and reset() can switch capture without importing it. */
27
- enableHeatmap: (status?: boolean) => void;
25
+ trackHeatmap: (status?: boolean) => void;
28
26
  /** Set by heatmap/track.ts: clears what this visit recorded, so the cap starts again. */
29
27
  resetHeatmap: () => void;
30
28
  /** Set by remoteconfig/fetch.ts, so reset() can forget the rule set without importing it. */
@@ -36,6 +34,6 @@ export declare const hooks: {
36
34
  screenTrackedByApp: () => void;
37
35
  /** Set by remoteconfig/fetch.ts: start-up has finished, so remote config fetches its values. */
38
36
  remoteConfigStarted: () => void;
39
- /** Set by remoteconfig/fetch.ts: AppticsSetUser changed who this is, so conditions on the user re-apply. */
37
+ /** Set by remoteconfig/fetch.ts: AppticsUser.setUser changed who this is, so conditions on the user re-apply. */
40
38
  remoteConfigUserChanged: () => void;
41
39
  };
@@ -1,4 +1,4 @@
1
- /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
2
2
  /**
3
3
  * Late-bound calls from lower modules up to the modules above them (see spec §5). device.ts and
4
4
  * remotelog/index.ts assign these when they are evaluated; the defaults only run if that module
@@ -7,10 +7,9 @@
7
7
  const hooks = {
8
8
  updateDevice: () => Promise.reject('apptics: device module not loaded'), // no i18n
9
9
  refreshDeviceInfo: () => { },
10
- remoteLog: () => { },
11
10
  feedbackUser: () => null,
12
11
  sendHeatmaps: () => Promise.resolve(),
13
- enableHeatmap: () => { },
12
+ trackHeatmap: () => { },
14
13
  resetHeatmap: () => { },
15
14
  resetRemoteConfig: () => { },
16
15
  screenTrackedByApp: () => { },
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Runs `run` while holding the Web Lock `name`, waiting for it if another tab of this site holds
3
+ * it. Locks are shared by every tab of an origin, which is what keeps two tabs from registering
4
+ * the same browser twice or overwriting each other's session.
5
+ *
6
+ * Without the Web Locks API (older browsers), `run` simply runs, as it did before locks were used.
7
+ * Not reentrant: `run` must not ask for the same lock again, or it waits for itself.
8
+ */
9
+ export declare function withLock<T>(name: string, run: () => Promise<T>): Promise<T>;
@@ -0,0 +1,20 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ /**
3
+ * Runs `run` while holding the Web Lock `name`, waiting for it if another tab of this site holds
4
+ * it. Locks are shared by every tab of an origin, which is what keeps two tabs from registering
5
+ * the same browser twice or overwriting each other's session.
6
+ *
7
+ * Without the Web Locks API (older browsers), `run` simply runs, as it did before locks were used.
8
+ * Not reentrant: `run` must not ask for the same lock again, or it waits for itself.
9
+ */
10
+ function withLock(name, run) {
11
+ var locks = typeof navigator !== 'undefined' ? navigator.locks : undefined; // no i18n
12
+ if (!locks || typeof locks.request !== 'function') { // no i18n
13
+ return run();
14
+ }
15
+ return locks.request('apptics-' + name, function () {
16
+ return run();
17
+ });
18
+ }
19
+
20
+ export { withLock };
@@ -8,9 +8,8 @@ export declare const Console: {
8
8
  /** Warnings the integrator must see even with debug off (e.g. missing required config). */
9
9
  export declare function warnAlways(...args: unknown[]): void;
10
10
  /**
11
- * A failure inside one of the SDK's own modules: logged to the console as usual, and sent to
12
- * console/addlog so it can be read back from the Apptics console when the SDK misbehaves in the
13
- * wild. `module` is one of AP_LOG_MODULE's values. The remote half does nothing until
14
- * the remotelog module has been loaded and its own switch allows it.
11
+ * A failure inside one of the SDK's own modules, `module` one of AP_LOG_MODULE's values: said in
12
+ * the browser console in debug mode. Nothing is sent: the Remote Logger page carries only the
13
+ * lines an app logs with AppticsLogger.
15
14
  */
16
15
  export declare function logFailure(module: string, ...args: unknown[]): void;