@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,25 @@
1
+ /**
2
+ * Remote logger: the SDK's own diagnostics, sent to console/addlog.
3
+ *
4
+ * This file is not the app-facing logging API — that is logger.ts, which shares this queue and
5
+ * delivery but has its own switch. This file answers "this app reports no data — what is the SDK
6
+ * actually doing on the user's machine?", so what it carries is the SDK's own failures, each
7
+ * tagged with the module that was mid-flight (Session, Screen, Event, API, Properties).
8
+ * App errors belong to exception/error, an app's remote log lines to logger.ts, and lines meant
9
+ * for a feedback report to feedback/logs.ts.
10
+ *
11
+ * This file records lines, send.ts delivers them, and gate.ts holds the switch both ask.
12
+ * Nothing here is exported to apps: the SDK writes these lines itself, through logFailure()
13
+ * in core/logger.ts.
14
+ */
15
+ import { AP_LOG_MODULE } from '../core/constants.js';
16
+ import { type CallSite } from '../core/callsite.js';
17
+ /** One of console/addlog's `module` values. */
18
+ export type LogModule = (typeof AP_LOG_MODULE)[keyof typeof AP_LOG_MODULE];
19
+ /**
20
+ * Records one line about `module` for console/addlog. Never throws and never blocks the caller:
21
+ * a diagnostics channel that breaks the flow it reports on would be worse than no channel.
22
+ */
23
+ export declare function remoteLog(module: LogModule, message: unknown, site?: CallSite): void;
24
+ export { remoteLogEnabled } from './gate.js';
25
+ export { forgetStoredLogs, sendStoredLogs } from './send.js';
@@ -0,0 +1,51 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ import '../core/constants.js';
3
+ import { NO_CALL_SITE } from '../core/callsite.js';
4
+ import { consolelog_transactions } from '../core/storage.js';
5
+ import { hooks } from '../core/hooks.js';
6
+ import { nowMs } from '../core/utils.js';
7
+ import { remoteLogEnabled } from './gate.js';
8
+ import { scheduleSend } from './send.js';
9
+ export { forgetStoredLogs, sendStoredLogs } from './send.js';
10
+
11
+ /**
12
+ * Remote logger: the SDK's own diagnostics, sent to console/addlog.
13
+ *
14
+ * This file is not the app-facing logging API — that is logger.ts, which shares this queue and
15
+ * delivery but has its own switch. This file answers "this app reports no data — what is the SDK
16
+ * actually doing on the user's machine?", so what it carries is the SDK's own failures, each
17
+ * tagged with the module that was mid-flight (Session, Screen, Event, API, Properties).
18
+ * App errors belong to exception/error, an app's remote log lines to logger.ts, and lines meant
19
+ * for a feedback report to feedback/logs.ts.
20
+ *
21
+ * This file records lines, send.ts delivers them, and gate.ts holds the switch both ask.
22
+ * Nothing here is exported to apps: the SDK writes these lines itself, through logFailure()
23
+ * in core/logger.ts.
24
+ */
25
+ /**
26
+ * Records one line about `module` for console/addlog. Never throws and never blocks the caller:
27
+ * a diagnostics channel that breaks the flow it reports on would be worse than no channel.
28
+ */
29
+ function remoteLog(module, message, site) {
30
+ try {
31
+ if (!remoteLogEnabled()) {
32
+ return;
33
+ }
34
+ var where = site || NO_CALL_SITE;
35
+ consolelog_transactions.add({
36
+ module: module,
37
+ happenedat: nowMs(),
38
+ exceptionlog: String(message),
39
+ attempt: 1,
40
+ filename: where.filename,
41
+ linenumber: where.linenumber,
42
+ });
43
+ scheduleSend();
44
+ }
45
+ catch (err) {
46
+ // never let the logger be the thing that fails
47
+ }
48
+ }
49
+ hooks.remoteLog = remoteLog;
50
+
51
+ export { remoteLog, remoteLogEnabled };
@@ -0,0 +1,28 @@
1
+ /** The level numbers log/add takes and the Remote Logger page names, in the native SDKs' order. */
2
+ export declare const LOG_LEVEL: Readonly<{
3
+ VERBOSE: 1;
4
+ DEBUG: 2;
5
+ INFO: 3;
6
+ WARN: 4;
7
+ ERROR: 5;
8
+ }>;
9
+ export interface AppticsLogger {
10
+ /** Starts recording log lines. Off until called. */
11
+ enable(): void;
12
+ /** Stops recording log lines. */
13
+ disable(): void;
14
+ /** Whether log lines are being recorded. */
15
+ isEnabled(): boolean;
16
+ /** Verbose, level 1. The tag leads the message as `[tag]`. */
17
+ v(tag: string, message: unknown, ...details: unknown[]): void;
18
+ /** Debug, level 2. */
19
+ d(tag: string, message: unknown, ...details: unknown[]): void;
20
+ /** Info, level 3. */
21
+ i(tag: string, message: unknown, ...details: unknown[]): void;
22
+ /** Warning, level 4. */
23
+ w(tag: string, message: unknown, ...details: unknown[]): void;
24
+ /** Error, level 5. */
25
+ e(tag: string, message: unknown, ...details: unknown[]): void;
26
+ }
27
+ /** Android's AppticsLogger: enable, disable, isEnabled and v / d / i / w / e(tag, message). */
28
+ export declare const AppticsLogger: AppticsLogger;
@@ -0,0 +1,136 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ import { LOG_FUNCTION_MAX } from '../core/constants.js';
3
+ import { callSite } from '../core/callsite.js';
4
+ import { consolelog_transactions } from '../core/storage.js';
5
+ import { guard } from '../core/guard.js';
6
+ import { nowMs } from '../core/utils.js';
7
+ import { getConfig } from '../core/state.js';
8
+ import { appLoggerEnabled, setAppLogger, appLogEnabled } from './gate.js';
9
+ import { scheduleSend } from './send.js';
10
+
11
+ /**
12
+ * AppticsLogger, as on Android: lines the app writes, shown on the console's Remote Logger page.
13
+ *
14
+ * AppticsLogger.enable();
15
+ * AppticsLogger.i('Checkout', 'Payment started');
16
+ * AppticsLogger.e('Checkout', 'Payment failed', err);
17
+ *
18
+ * It mirrors the native SDKs so the page reads the same whatever sent the line: off until
19
+ * enable() (AppticsLogger.enable() on Android, APLog.setShouldLog on iOS), and five levels in
20
+ * the iOS order — verbose, debug, info, warn, error — sent as 1 to 5, which is the scale the
21
+ * Remote Logger page reads back.
22
+ *
23
+ * Lines share the SDK diagnostics' queue and its log/add delivery, so they are stored before
24
+ * they are sent and survive a failed send and a reload. They are a separate switch, though:
25
+ * `remote_log: false` silences the SDK's own failures, not the app's logging.
26
+ */
27
+ /** The level numbers log/add takes and the Remote Logger page names, in the native SDKs' order. */
28
+ const LOG_LEVEL = Object.freeze({ VERBOSE: 1, DEBUG: 2, INFO: 3, WARN: 4, ERROR: 5 });
29
+ /** What a line's `function` says when the caller had no name to give (an anonymous callback). */
30
+ const ANONYMOUS_CALLER = 'App'; // no i18n
31
+ /**
32
+ * The caller's name as logSDK's `function` accepts it: safe_string refuses angle brackets and an
33
+ * empty value, and the field stops at 100 characters.
34
+ */
35
+ function functionName(site) {
36
+ var name = String(site.fn || '').replace(/<anonymous>/g, '').replace(/[<>]/g, '').trim(); // no i18n
37
+ if (name === '' || /^(Object|Module|eval)\.?$/.test(name)) {
38
+ return ANONYMOUS_CALLER;
39
+ }
40
+ return name.slice(0, LOG_FUNCTION_MAX);
41
+ }
42
+ /** One detail as text: an Error as its stack (which leads with name and message), JSON otherwise. */
43
+ function describe(value) {
44
+ if (value instanceof Error) {
45
+ var head = value.name + ': ' + value.message; // no i18n
46
+ return value.stack && value.stack.indexOf(value.message) !== -1 ? value.stack : head;
47
+ }
48
+ if (typeof value === 'string') { // no i18n
49
+ return value;
50
+ }
51
+ try {
52
+ var json = JSON.stringify(value);
53
+ return json === undefined ? String(value) : json;
54
+ }
55
+ catch (err) {
56
+ return String(value);
57
+ }
58
+ }
59
+ /**
60
+ * Stores one line. Reached through guard(), so a line logged before start-up finishes waits for
61
+ * it — which is why the time and call site are taken by the caller, not here.
62
+ */
63
+ function record(level, message, details, at, site) {
64
+ if (!appLogEnabled()) {
65
+ return;
66
+ }
67
+ var text = [message].concat(details).map(describe).join(' '); // no i18n
68
+ consolelog_transactions.add({
69
+ module: functionName(site),
70
+ level: level,
71
+ happenedat: at,
72
+ exceptionlog: text,
73
+ attempt: 1,
74
+ filename: site.filename,
75
+ linenumber: site.linenumber,
76
+ });
77
+ scheduleSend();
78
+ }
79
+ const recordLine = guard('AppticsLogger', record); // no i18n
80
+ /** The browser console method each level prints with under `show_logs`, as Logcat shows them. */
81
+ const CONSOLE_METHOD = Object.freeze({
82
+ 1: 'debug', 2: 'debug', 3: 'info', 4: 'warn', 5: 'error', // no i18n
83
+ });
84
+ /**
85
+ * `show_logs`: the line in the browser console too, as Android's showLogs prints to Logcat. For
86
+ * the developer, so it prints whether or not the remote logger is enabled or allowed to record,
87
+ * and the arguments go over untouched so the console can still expand an object or an Error.
88
+ */
89
+ function show(level, args) {
90
+ if (getConfig('show_logs') !== true) {
91
+ return;
92
+ }
93
+ var method = CONSOLE_METHOD[level] || 'log'; // no i18n
94
+ if (typeof console !== 'undefined' && typeof console[method] === 'function') { // no i18n
95
+ console[method].apply(console, args);
96
+ }
97
+ }
98
+ /**
99
+ * A level's Android-style method, `v/d/i/w/e(tag, message, ...details)`. The tag leads the
100
+ * message as `[tag]`; the function, file and line are still the caller's, as with the long names.
101
+ */
102
+ function tagged(level) {
103
+ return function (tag, message, ...details) {
104
+ try {
105
+ var label = tag === undefined || tag === null ? '' : String(tag).trim(); // no i18n
106
+ var parts = label === '' ? [message].concat(details) : ['[' + label + ']', message].concat(details); // no i18n
107
+ show(level, parts);
108
+ // skip 1: this function's own frame, so the site is the app's line that logged
109
+ recordLine(level, parts[0], parts.slice(1), nowMs(), callSite(1));
110
+ }
111
+ catch (err) {
112
+ // logging must never be the thing that breaks the app
113
+ }
114
+ };
115
+ }
116
+ /** Turns the app logger on, or off with `false`. Off by default. */
117
+ function enable(on) {
118
+ setAppLogger(on !== false);
119
+ }
120
+ /** Turns the app logger off, as AppticsLogger.disable() does; the same as enable(false). */
121
+ function disable() {
122
+ setAppLogger(false);
123
+ }
124
+ /** Android's AppticsLogger: enable, disable, isEnabled and v / d / i / w / e(tag, message). */
125
+ const AppticsLogger = {
126
+ enable: guard('AppticsLogger.enable', function () { enable(true); }), // no i18n
127
+ disable: guard('AppticsLogger.disable', disable), // no i18n
128
+ isEnabled: guard('AppticsLogger.isEnabled', appLoggerEnabled), // no i18n
129
+ v: tagged(LOG_LEVEL.VERBOSE),
130
+ d: tagged(LOG_LEVEL.DEBUG),
131
+ i: tagged(LOG_LEVEL.INFO),
132
+ w: tagged(LOG_LEVEL.WARN),
133
+ e: tagged(LOG_LEVEL.ERROR),
134
+ };
135
+
136
+ export { AppticsLogger, LOG_LEVEL };
@@ -0,0 +1,13 @@
1
+ /** Queues a pass over the stored lines, coalescing a burst into one. */
2
+ export declare function scheduleSend(): void;
3
+ /**
4
+ * Sends the stored lines as one batch. A batch the server refuses for its shape is dropped —
5
+ * retrying it could only fail the same way and would hold every later line behind it.
6
+ */
7
+ export declare function sendStoredLogs(): Promise<void>;
8
+ /**
9
+ * Sends what is stored as the page goes away, where a normal request would be cancelled.
10
+ * One keepalive request for the whole batch, which is what the endpoint now accepts. The lines
11
+ * stay stored until the server has confirmed them.
12
+ */
13
+ export declare function forgetStoredLogs(): Promise<void>;
@@ -0,0 +1,149 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ import { LOG_FUNCTION_MAX, CONSOLE_LOG_MAX_BODY, REMOTE_LOG_LEVEL, LOG_FILENAME_MAX } from '../core/constants.js';
3
+ import { _ZAP } from '../core/state.js';
4
+ import { warnAlways, Console } from '../core/logger.js';
5
+ import { nowMs, isEmpty } from '../core/utils.js';
6
+ import { consolelog_transactions } from '../core/storage.js';
7
+ import { postToApptics, apiHeaders, isPermanentRefusal, getMetaObj, postKeepalive } from '../core/transport.js';
8
+ import { remoteLogSendable } from './gate.js';
9
+
10
+ /**
11
+ * Delivery for the remote logger.
12
+ *
13
+ * v2 replaced console/addlog, which took one line per call and counted retries in an `attempt`
14
+ * param, with log/add, which takes a batch: `{ logs: [...], meta }`. A pass over the queue is now
15
+ * one request however many lines are waiting, so a burst of failures costs one call instead of
16
+ * twenty, and a line no longer has to carry its own retry bookkeeping — the batch either lands or
17
+ * stays for the next pass.
18
+ */
19
+ /**
20
+ * What the stored lines may take up, as on Android (1 MB): past it the oldest are dropped, so a
21
+ * failing SDK or a chatty app can't fill storage. Measured in size rather than in lines, since one
22
+ * line can be a 10,000-character stack and another a word.
23
+ */
24
+ const MAX_STORED_BYTES = 1024 * 1024;
25
+ /** Sends are grouped, so one broken flow that logs twice makes one pass over the queue. */
26
+ const SEND_DELAY_MS = 1000;
27
+ /** The endpoint takes a 10 MB body; a batch is capped well inside that. */
28
+ const MAX_PER_BATCH = 50;
29
+ const LABEL = 'remoteLog'; // no i18n
30
+ let sendScheduled = false;
31
+ let sending = false;
32
+ /**
33
+ * One stored line as logSDK wants it.
34
+ *
35
+ * `function` is where the module name goes — it is the only field describing *where* a line came
36
+ * from, and the template caps it at 100. `logmessage` is capped at 10000, so a long stack is
37
+ * trimmed rather than having the whole batch refused for one oversized line.
38
+ */
39
+ function entryFor(item) {
40
+ var entry = {
41
+ sessionstarttime: _ZAP._current_session.starttime || item.happenedat || nowMs(),
42
+ logtime: item.happenedat || nowMs(),
43
+ // an app's line carries the level it was logged at; the SDK's own failures carry none
44
+ level: Number(item.level) || REMOTE_LOG_LEVEL,
45
+ logmessage: String(item.exceptionlog).slice(0, CONSOLE_LOG_MAX_BODY),
46
+ function: String(item.module || 'SDK').slice(0, LOG_FUNCTION_MAX), // no i18n
47
+ // the endpoint reads linenumber with getInt(), which throws on a missing key rather than
48
+ // defaulting, so it goes out on every line - 0 where the stack gave us no frame
49
+ linenumber: Number(item.linenumber) || 0,
50
+ };
51
+ // filename is read with optString and validated against file_name, whose pattern needs at
52
+ // least one character: sending '' would have the whole batch refused, so it is left out
53
+ if (!isEmpty(item.filename)) {
54
+ entry.filename = String(item.filename).slice(0, LOG_FILENAME_MAX);
55
+ }
56
+ return entry;
57
+ }
58
+ /** The batch body: `{ logs, meta }`, where meta is metaWebSDKV2 like every other v2 payload. */
59
+ function bodyFor(items) {
60
+ return JSON.stringify({ logs: items.map(entryFor), meta: getMetaObj() }); // no i18n
61
+ }
62
+ /** Queues a pass over the stored lines, coalescing a burst into one. */
63
+ function scheduleSend() {
64
+ if (sendScheduled) {
65
+ return;
66
+ }
67
+ sendScheduled = true;
68
+ setTimeout(function () {
69
+ sendScheduled = false;
70
+ sendStoredLogs();
71
+ }, SEND_DELAY_MS);
72
+ }
73
+ /** Drops the oldest lines once the queue is over MAX_STORED_BYTES, keeping the newest that fit. */
74
+ function trim(items) {
75
+ var total = 0;
76
+ var keepFrom = items.length;
77
+ // newest first: they are the ones worth keeping
78
+ for (var i = items.length - 1; i >= 0; i--) {
79
+ total += JSON.stringify(items[i]).length;
80
+ if (total > MAX_STORED_BYTES) {
81
+ break;
82
+ }
83
+ keepFrom = i;
84
+ }
85
+ if (keepFrom === 0) {
86
+ return items;
87
+ }
88
+ consolelog_transactions.remove(items.slice(0, keepFrom));
89
+ return items.slice(keepFrom);
90
+ }
91
+ /**
92
+ * Sends the stored lines as one batch. A batch the server refuses for its shape is dropped —
93
+ * retrying it could only fail the same way and would hold every later line behind it.
94
+ */
95
+ function sendStoredLogs() {
96
+ if (sending || !remoteLogSendable() || navigator.onLine === false) {
97
+ return Promise.resolve();
98
+ }
99
+ sending = true;
100
+ return consolelog_transactions.all().then(function (stored) {
101
+ var batch = trim(stored).slice(0, MAX_PER_BATCH);
102
+ if (batch.length === 0) {
103
+ return undefined;
104
+ }
105
+ return postToApptics('consolelog', bodyFor(batch), apiHeaders(), LABEL).then(function () {
106
+ return consolelog_transactions.remove(batch);
107
+ }, function (err) {
108
+ if (isPermanentRefusal(err)) {
109
+ warnAlways('apptics: the server refused these log lines, so they were dropped: ' + String(err && err.message)); // no i18n
110
+ return consolelog_transactions.remove(batch);
111
+ }
112
+ Console.log(LABEL + ': ' + String(err)); // no i18n
113
+ return undefined;
114
+ });
115
+ }).then(function () {
116
+ sending = false;
117
+ }).catch(function () {
118
+ sending = false;
119
+ });
120
+ }
121
+ /**
122
+ * Sends what is stored as the page goes away, where a normal request would be cancelled.
123
+ * One keepalive request for the whole batch, which is what the endpoint now accepts. The lines
124
+ * stay stored until the server has confirmed them.
125
+ */
126
+ function forgetStoredLogs() {
127
+ if (!remoteLogSendable()) {
128
+ return Promise.resolve();
129
+ }
130
+ return consolelog_transactions.all().then(function (stored) {
131
+ if (stored.length === 0) {
132
+ return undefined;
133
+ }
134
+ var batch = stored.slice(0, MAX_PER_BATCH);
135
+ // removed once the server has them; lines whose answer never comes go on the next visit
136
+ postKeepalive('consolelog', bodyFor(batch), apiHeaders(), LABEL).then(function () {
137
+ return consolelog_transactions.remove(batch);
138
+ }, function (err) {
139
+ if (isPermanentRefusal(err)) {
140
+ return consolelog_transactions.remove(batch);
141
+ }
142
+ Console.log(LABEL + ': ' + String(err)); // no i18n
143
+ return undefined;
144
+ });
145
+ return undefined;
146
+ });
147
+ }
148
+
149
+ export { forgetStoredLogs, scheduleSend, sendStoredLogs };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Sends everything queued now. With `forget`, the requests are sent without waiting for a
3
+ * response (page hide), so they survive the page going away.
4
+ */
5
+ export declare function flush(forget?: boolean): Promise<void>;
6
+ /** Starts the flush and getupdates intervals once; later calls do nothing until stopTimers(). */
7
+ export declare function startTimers(): void;
8
+ export declare function stopTimers(): void;
@@ -0,0 +1,74 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ import { _ZAP, getConfig } from './core/state.js';
3
+ import { nowMs } from './core/utils.js';
4
+ import { Console } from './core/logger.js';
5
+ import { canTrack } from './core/consent.js';
6
+ import { clearDefer } from './core/batch.js';
7
+ import { sendEngagementData } from './engagement/send.js';
8
+ import { sendErrorData } from './errors/send.js';
9
+ import { hooks } from './core/hooks.js';
10
+ import { getUpdatesFromServer } from './device/index.js';
11
+ import { expireDebugIfIdle } from './core/debug.js';
12
+
13
+ /**
14
+ * Sends everything queued now. With `forget`, the requests are sent without waiting for a
15
+ * response (page hide), so they survive the page going away.
16
+ */
17
+ function flush(forget) {
18
+ if (!canTrack('flush')) { // no i18n
19
+ return Promise.resolve();
20
+ }
21
+ _ZAP._sending = false;
22
+ // one after the other: sending both at once makes the second wait for the 500 ms retry
23
+ return sendEngagementData(forget).then(function () {
24
+ return sendErrorData(forget);
25
+ }).then(function () {
26
+ // no-op unless the heatmap entry was imported, which is what sets the hook
27
+ return hooks.sendHeatmaps(forget);
28
+ });
29
+ }
30
+ var sendingInterval = null;
31
+ var getUpdatesInterval = null;
32
+ /** Starts the flush and getupdates intervals once; later calls do nothing until stopTimers(). */
33
+ function startTimers() {
34
+ if (sendingInterval === null) {
35
+ sendingInterval = setInterval(function () {
36
+ // the only tick that happens whether or not anything is being tracked, which is
37
+ // exactly the case debug mode has to expire in
38
+ expireDebugIfIdle();
39
+ Console.log('scheduleToSendDataToServer: Scheduling to send engagement data to the server after sometime'); // no i18n
40
+ // one after the other, as flush() does: run together, the second and third find the
41
+ // first still sending and are deferred, and the third's retry replaces the second's
42
+ sendEngagementData().then(function () {
43
+ return sendErrorData();
44
+ }).then(function () {
45
+ return hooks.sendHeatmaps();
46
+ });
47
+ }, getConfig('batch_flush_interval')); // no i18n
48
+ }
49
+ if (getUpdatesInterval === null) {
50
+ // the interval is the floor, not the schedule: getsdkconfig answers with next_check_after,
51
+ // and asking again before then is a call the server has already told us it will not answer
52
+ // differently. The timer still ticks so a server that sends no hint behaves as before.
53
+ getUpdatesInterval = setInterval(function () {
54
+ if (_ZAP._nextConfigCheck > 0 && nowMs() < _ZAP._nextConfigCheck) {
55
+ return;
56
+ }
57
+ Console.log('scheduleToGetUpdatesFromServer: asking the server for its config'); // no i18n
58
+ getUpdatesFromServer().catch(function (err) {
59
+ Console.log(err);
60
+ });
61
+ }, getConfig('getupdates_interval')); // no i18n
62
+ }
63
+ }
64
+ function stopTimers() {
65
+ if (sendingInterval !== null)
66
+ clearInterval(sendingInterval);
67
+ if (getUpdatesInterval !== null)
68
+ clearInterval(getUpdatesInterval);
69
+ sendingInterval = null;
70
+ getUpdatesInterval = null;
71
+ clearDefer();
72
+ }
73
+
74
+ export { flush, startTimers, stopTimers };