@zoho_apptics/apptics-js-sdk 1.0.2 → 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.
- package/CHANGELOG.md +193 -0
- package/LICENSE +13 -0
- package/README.md +846 -11
- package/dist/apptics.esm.min.js +3 -0
- package/dist/apptics.esm.min.js.map +1 -0
- package/dist/apptics.min.js +3 -0
- package/dist/apptics.min.js.map +1 -0
- package/dist/chunks/lifecycle-VYr43KcB.min.js +3 -0
- package/dist/chunks/lifecycle-VYr43KcB.min.js.map +1 -0
- package/dist/cjs/auto-init.d.ts +8 -0
- package/dist/cjs/auto-init.js +32 -0
- package/dist/cjs/core/attempts.d.ts +28 -0
- package/dist/cjs/core/attempts.js +113 -0
- package/dist/cjs/core/batch.d.ts +32 -0
- package/dist/cjs/core/batch.js +116 -0
- package/dist/cjs/core/callsite.d.ts +34 -0
- package/dist/cjs/core/callsite.js +115 -0
- package/dist/cjs/core/consent.d.ts +27 -0
- package/dist/cjs/core/consent.js +132 -0
- package/dist/cjs/core/constants.d.ts +237 -0
- package/dist/cjs/core/constants.js +315 -0
- package/dist/cjs/core/db.d.ts +48 -0
- package/dist/cjs/core/db.js +467 -0
- package/dist/cjs/core/debug.d.ts +22 -0
- package/dist/cjs/core/debug.js +88 -0
- package/dist/cjs/core/env.d.ts +28 -0
- package/dist/cjs/core/env.js +267 -0
- package/dist/cjs/core/framework-id.d.ts +1 -0
- package/dist/cjs/core/framework-id.js +9 -0
- package/dist/cjs/core/guard.d.ts +11 -0
- package/dist/cjs/core/guard.js +86 -0
- package/dist/cjs/core/hooks.d.ts +39 -0
- package/dist/cjs/core/hooks.js +22 -0
- package/dist/cjs/core/locks.d.ts +9 -0
- package/dist/cjs/core/locks.js +22 -0
- package/dist/cjs/core/logger.d.ts +15 -0
- package/dist/cjs/core/logger.js +50 -0
- package/dist/cjs/core/state.d.ts +70 -0
- package/dist/cjs/core/state.js +78 -0
- package/dist/cjs/core/storage.d.ts +61 -0
- package/dist/cjs/core/storage.js +327 -0
- package/dist/cjs/core/stylesheet.d.ts +8 -0
- package/dist/cjs/core/stylesheet.js +29 -0
- package/dist/cjs/core/transport.d.ts +85 -0
- package/dist/cjs/core/transport.js +456 -0
- package/dist/cjs/core/utils.d.ts +26 -0
- package/dist/cjs/core/utils.js +175 -0
- package/dist/cjs/core/validate.d.ts +18 -0
- package/dist/cjs/core/validate.js +233 -0
- package/dist/cjs/device/appversion.d.ts +15 -0
- package/dist/cjs/device/appversion.js +170 -0
- package/dist/cjs/device/index.d.ts +34 -0
- package/dist/cjs/device/index.js +472 -0
- package/dist/cjs/engagement/api-rules.d.ts +49 -0
- package/dist/cjs/engagement/api-rules.js +206 -0
- package/dist/cjs/engagement/auto-api.d.ts +7 -0
- package/dist/cjs/engagement/auto-api.js +200 -0
- package/dist/cjs/engagement/auto-screen.d.ts +18 -0
- package/dist/cjs/engagement/auto-screen.js +305 -0
- package/dist/cjs/engagement/defined-events.d.ts +23 -0
- package/dist/cjs/engagement/defined-events.js +58 -0
- package/dist/cjs/engagement/send.d.ts +6 -0
- package/dist/cjs/engagement/send.js +104 -0
- package/dist/cjs/engagement/session.d.ts +51 -0
- package/dist/cjs/engagement/session.js +463 -0
- package/dist/cjs/engagement/track.d.ts +56 -0
- package/dist/cjs/engagement/track.js +375 -0
- package/dist/cjs/errors/send.d.ts +6 -0
- package/dist/cjs/errors/send.js +73 -0
- package/dist/cjs/errors/track.d.ts +4 -0
- package/dist/cjs/errors/track.js +167 -0
- package/dist/cjs/feedback/controls.d.ts +37 -0
- package/dist/cjs/feedback/controls.js +316 -0
- package/dist/cjs/feedback/index.d.ts +9 -0
- package/dist/cjs/feedback/index.js +56 -0
- package/dist/cjs/feedback/logs.d.ts +45 -0
- package/dist/cjs/feedback/logs.js +241 -0
- package/dist/cjs/feedback/quartz.d.ts +18 -0
- package/dist/cjs/feedback/quartz.js +105 -0
- package/dist/cjs/feedback/send.d.ts +28 -0
- package/dist/cjs/feedback/send.js +203 -0
- package/dist/cjs/feedback/styles.d.ts +10 -0
- package/dist/cjs/feedback/styles.js +8 -0
- package/dist/cjs/feedback/template.d.ts +2 -0
- package/dist/cjs/feedback/template.js +162 -0
- package/dist/cjs/feedback/ui.d.ts +63 -0
- package/dist/cjs/feedback/ui.js +709 -0
- package/dist/cjs/heatmap/send.d.ts +13 -0
- package/dist/cjs/heatmap/send.js +82 -0
- package/dist/cjs/heatmap/track.d.ts +4 -0
- package/dist/cjs/heatmap/track.js +448 -0
- package/dist/cjs/index.d.ts +22 -0
- package/dist/cjs/index.js +162 -0
- package/dist/cjs/lifecycle.d.ts +21 -0
- package/dist/cjs/lifecycle.js +734 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/remoteconfig/country.d.ts +4 -0
- package/dist/cjs/remoteconfig/country.js +73 -0
- package/dist/cjs/remoteconfig/custom.d.ts +10 -0
- package/dist/cjs/remoteconfig/custom.js +58 -0
- package/dist/cjs/remoteconfig/evaluate.d.ts +24 -0
- package/dist/cjs/remoteconfig/evaluate.js +184 -0
- package/dist/cjs/remoteconfig/fetch.d.ts +24 -0
- package/dist/cjs/remoteconfig/fetch.js +200 -0
- package/dist/cjs/remoteconfig/index.d.ts +15 -0
- package/dist/cjs/remoteconfig/index.js +116 -0
- package/dist/cjs/remoteconfig/store.d.ts +18 -0
- package/dist/cjs/remoteconfig/store.js +98 -0
- package/dist/cjs/remoteconfig/tz-countries.d.ts +8 -0
- package/dist/cjs/remoteconfig/tz-countries.js +13 -0
- package/dist/cjs/remotelog/gate.d.ts +2 -0
- package/dist/cjs/remotelog/gate.js +28 -0
- package/dist/cjs/remotelog/index.d.ts +8 -0
- package/dist/cjs/remotelog/logger.d.ts +22 -0
- package/dist/cjs/remotelog/logger.js +111 -0
- package/dist/cjs/remotelog/send.d.ts +13 -0
- package/dist/cjs/remotelog/send.js +153 -0
- package/dist/cjs/remotelogger/index.d.ts +12 -0
- package/dist/cjs/remotelogger/index.js +18 -0
- package/dist/cjs/scheduler.d.ts +8 -0
- package/dist/cjs/scheduler.js +78 -0
- package/dist/cjs/types.d.ts +385 -0
- package/dist/cjs/user/index.d.ts +33 -0
- package/dist/cjs/user/index.js +183 -0
- package/dist/esm/auto-init.d.ts +8 -0
- package/dist/esm/auto-init.js +29 -0
- package/dist/esm/core/attempts.d.ts +28 -0
- package/dist/esm/core/attempts.js +106 -0
- package/dist/esm/core/batch.d.ts +32 -0
- package/dist/esm/core/batch.js +109 -0
- package/dist/esm/core/callsite.d.ts +34 -0
- package/dist/esm/core/callsite.js +110 -0
- package/dist/esm/core/consent.d.ts +27 -0
- package/dist/esm/core/consent.js +122 -0
- package/dist/esm/core/constants.d.ts +237 -0
- package/dist/esm/core/constants.js +292 -0
- package/dist/esm/core/db.d.ts +48 -0
- package/dist/esm/core/db.js +453 -0
- package/dist/esm/core/debug.d.ts +22 -0
- package/dist/esm/core/debug.js +81 -0
- package/dist/esm/core/env.d.ts +28 -0
- package/dist/esm/core/env.js +251 -0
- package/dist/esm/core/framework-id.d.ts +1 -0
- package/dist/esm/core/framework-id.js +7 -0
- package/dist/esm/core/guard.d.ts +11 -0
- package/dist/esm/core/guard.js +83 -0
- package/dist/esm/core/hooks.d.ts +39 -0
- package/dist/esm/core/hooks.js +20 -0
- package/dist/esm/core/locks.d.ts +9 -0
- package/dist/esm/core/locks.js +20 -0
- package/dist/esm/core/logger.d.ts +15 -0
- package/dist/esm/core/logger.js +46 -0
- package/dist/esm/core/state.d.ts +70 -0
- package/dist/esm/core/state.js +73 -0
- package/dist/esm/core/storage.d.ts +61 -0
- package/dist/esm/core/storage.js +314 -0
- package/dist/esm/core/stylesheet.d.ts +8 -0
- package/dist/esm/core/stylesheet.js +27 -0
- package/dist/esm/core/transport.d.ts +85 -0
- package/dist/esm/core/transport.js +439 -0
- package/dist/esm/core/utils.d.ts +26 -0
- package/dist/esm/core/utils.js +161 -0
- package/dist/esm/core/validate.d.ts +18 -0
- package/dist/esm/core/validate.js +226 -0
- package/dist/esm/device/appversion.d.ts +15 -0
- package/dist/esm/device/appversion.js +164 -0
- package/dist/esm/device/index.d.ts +34 -0
- package/dist/esm/device/index.js +461 -0
- package/dist/esm/engagement/api-rules.d.ts +49 -0
- package/dist/esm/engagement/api-rules.js +199 -0
- package/dist/esm/engagement/auto-api.d.ts +7 -0
- package/dist/esm/engagement/auto-api.js +198 -0
- package/dist/esm/engagement/auto-screen.d.ts +18 -0
- package/dist/esm/engagement/auto-screen.js +301 -0
- package/dist/esm/engagement/defined-events.d.ts +23 -0
- package/dist/esm/engagement/defined-events.js +55 -0
- package/dist/esm/engagement/send.d.ts +6 -0
- package/dist/esm/engagement/send.js +101 -0
- package/dist/esm/engagement/session.d.ts +51 -0
- package/dist/esm/engagement/session.js +448 -0
- package/dist/esm/engagement/track.d.ts +56 -0
- package/dist/esm/engagement/track.js +365 -0
- package/dist/esm/errors/send.d.ts +6 -0
- package/dist/esm/errors/send.js +70 -0
- package/dist/esm/errors/track.d.ts +4 -0
- package/dist/esm/errors/track.js +163 -0
- package/dist/esm/feedback/controls.d.ts +37 -0
- package/dist/esm/feedback/controls.js +309 -0
- package/dist/esm/feedback/index.d.ts +9 -0
- package/dist/esm/feedback/index.js +51 -0
- package/dist/esm/feedback/logs.d.ts +45 -0
- package/dist/esm/feedback/logs.js +227 -0
- package/dist/esm/feedback/quartz.d.ts +18 -0
- package/dist/esm/feedback/quartz.js +99 -0
- package/dist/esm/feedback/send.d.ts +28 -0
- package/dist/esm/feedback/send.js +198 -0
- package/dist/esm/feedback/styles.d.ts +10 -0
- package/dist/esm/feedback/styles.js +4 -0
- package/dist/esm/feedback/template.d.ts +2 -0
- package/dist/esm/feedback/template.js +159 -0
- package/dist/esm/feedback/ui.d.ts +63 -0
- package/dist/esm/feedback/ui.js +703 -0
- package/dist/esm/heatmap/send.d.ts +13 -0
- package/dist/esm/heatmap/send.js +79 -0
- package/dist/esm/heatmap/track.d.ts +4 -0
- package/dist/esm/heatmap/track.js +445 -0
- package/dist/esm/index.d.ts +22 -0
- package/dist/esm/index.js +150 -0
- package/dist/esm/lifecycle.d.ts +21 -0
- package/dist/esm/lifecycle.js +729 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/remoteconfig/country.d.ts +4 -0
- package/dist/esm/remoteconfig/country.js +70 -0
- package/dist/esm/remoteconfig/custom.d.ts +10 -0
- package/dist/esm/remoteconfig/custom.js +54 -0
- package/dist/esm/remoteconfig/evaluate.d.ts +24 -0
- package/dist/esm/remoteconfig/evaluate.js +179 -0
- package/dist/esm/remoteconfig/fetch.d.ts +24 -0
- package/dist/esm/remoteconfig/fetch.js +196 -0
- package/dist/esm/remoteconfig/index.d.ts +15 -0
- package/dist/esm/remoteconfig/index.js +111 -0
- package/dist/esm/remoteconfig/store.d.ts +18 -0
- package/dist/esm/remoteconfig/store.js +91 -0
- package/dist/esm/remoteconfig/tz-countries.d.ts +8 -0
- package/dist/esm/remoteconfig/tz-countries.js +11 -0
- package/dist/esm/remotelog/gate.d.ts +2 -0
- package/dist/esm/remotelog/gate.js +26 -0
- package/dist/esm/remotelog/index.d.ts +8 -0
- package/dist/esm/remotelog/logger.d.ts +22 -0
- package/dist/esm/remotelog/logger.js +108 -0
- package/dist/esm/remotelog/send.d.ts +13 -0
- package/dist/esm/remotelog/send.js +149 -0
- package/dist/esm/remotelogger/index.d.ts +12 -0
- package/dist/esm/remotelogger/index.js +13 -0
- package/dist/esm/scheduler.d.ts +8 -0
- package/dist/esm/scheduler.js +74 -0
- package/dist/esm/types.d.ts +385 -0
- package/dist/esm/user/index.d.ts +33 -0
- package/dist/esm/user/index.js +176 -0
- package/dist/feedback.esm.min.js +3 -0
- package/dist/feedback.esm.min.js.map +1 -0
- package/package.json +122 -7
- package/src/appticssdk.js +0 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var constants = require('./constants.js');
|
|
5
|
+
var utils = require('./utils.js');
|
|
6
|
+
var frameworkId = require('./framework-id.js');
|
|
7
|
+
|
|
8
|
+
function initialState() {
|
|
9
|
+
return {
|
|
10
|
+
_initialised: false,
|
|
11
|
+
_ready: false,
|
|
12
|
+
_pending: [],
|
|
13
|
+
_readyPromise: null,
|
|
14
|
+
_regDeviceSending: false,
|
|
15
|
+
_regDeviceResolve: [],
|
|
16
|
+
_regDeviceReject: [],
|
|
17
|
+
_sending: false,
|
|
18
|
+
_deferSendTimer: null,
|
|
19
|
+
_config: { ...constants.AP_CONFIG },
|
|
20
|
+
_defaultoptions: {},
|
|
21
|
+
inactiveduration: constants.DEFAULT_INACTIVE_MINUTES,
|
|
22
|
+
_token: '', // no i18n
|
|
23
|
+
// issued by Apptics at pack time; see scripts/register-version.mjs
|
|
24
|
+
_frameworkID: frameworkId.FRAMEWORK_ID,
|
|
25
|
+
_platform: constants.AP_CONSTANTS.BROWSER,
|
|
26
|
+
_isanonrequired: true,
|
|
27
|
+
_devicestatus: constants.AP_TRACKING_STATUS.USAGE_TRACKING_WITHOUT_PII,
|
|
28
|
+
_uuid: '', // no i18n
|
|
29
|
+
_apid: '', // no i18n
|
|
30
|
+
_mapid: '', // no i18n
|
|
31
|
+
_device_info: {},
|
|
32
|
+
_user_info: {},
|
|
33
|
+
_current_screen: {},
|
|
34
|
+
_current_session: {},
|
|
35
|
+
_properties: {},
|
|
36
|
+
_ignoreDnt: false,
|
|
37
|
+
_isGlobalErrorTracking: true,
|
|
38
|
+
_shouldTrack: true,
|
|
39
|
+
_engagementTracking: true,
|
|
40
|
+
_heatmapTracking: true,
|
|
41
|
+
_remoteLoggerEnabled: true,
|
|
42
|
+
_remoteConfigEnabled: true,
|
|
43
|
+
_remoteConfigReported: true,
|
|
44
|
+
_feedbackEnabled: true,
|
|
45
|
+
_nextConfigCheck: 0,
|
|
46
|
+
_debugUntil: 0,
|
|
47
|
+
_errorTracking: true,
|
|
48
|
+
_quartz: { enabled: false, workspace: '', department: '', domain: '', cdnUrl: '' }, // no i18n
|
|
49
|
+
_trackinfo: {},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const _ZAP = initialState();
|
|
53
|
+
function getConfig(key) {
|
|
54
|
+
return _ZAP._config[key];
|
|
55
|
+
}
|
|
56
|
+
/** The oldest timestamp still worth keeping: now minus batch_request_timeout days. */
|
|
57
|
+
function oldestKeptTime() {
|
|
58
|
+
return utils.nowMs() - getConfig('batch_request_timeout') * 24 * 60 * 60 * 1000; // no i18n
|
|
59
|
+
}
|
|
60
|
+
/** How far ahead of this clock a timestamp may be before it counts as nonsense. */
|
|
61
|
+
const CLOCK_SKEW_MS = 60 * 1000;
|
|
62
|
+
/**
|
|
63
|
+
* True for an item too old (or dated far enough in the future to be nonsense) to be worth
|
|
64
|
+
* sending. Queues use it to drop such items on the way in, and the sender uses it to drop the
|
|
65
|
+
* ones already stored. A minute of slack absorbs clock differences between tabs and machines,
|
|
66
|
+
* so an item a few milliseconds ahead of this clock is still kept.
|
|
67
|
+
*/
|
|
68
|
+
function isExpired(time) {
|
|
69
|
+
if (typeof time !== 'number' || !isFinite(time)) {
|
|
70
|
+
return false; // no usable timestamp: leave it to the caller's own rules
|
|
71
|
+
}
|
|
72
|
+
return time < oldestKeptTime() || time > utils.nowMs() + CLOCK_SKEW_MS;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
exports._ZAP = _ZAP;
|
|
76
|
+
exports.getConfig = getConfig;
|
|
77
|
+
exports.isExpired = isExpired;
|
|
78
|
+
exports.oldestKeptTime = oldestKeptTime;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type Backend, type QueueName } from './db.js';
|
|
2
|
+
import type { Dict, QueueItem, TrackingStatus } from '../types.js';
|
|
3
|
+
/** Opens storage, migrates 1.x data and loads settings into memory. Shared by all callers. */
|
|
4
|
+
export declare function storageReady(): Promise<Backend | null>;
|
|
5
|
+
export interface Queue {
|
|
6
|
+
readonly name: QueueName;
|
|
7
|
+
all(): Promise<QueueItem[]>;
|
|
8
|
+
payload(): Promise<QueueItem[]>;
|
|
9
|
+
add(item: QueueItem): Promise<void>;
|
|
10
|
+
update(item: QueueItem): Promise<void>;
|
|
11
|
+
remove(items?: QueueItem[]): Promise<void>;
|
|
12
|
+
clear(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
/** Sessions, screens, events and api calls waiting to be sent. */
|
|
15
|
+
export declare const engagement_transactions: Queue;
|
|
16
|
+
/** Errors waiting to be sent. */
|
|
17
|
+
export declare const error_transactions: Queue;
|
|
18
|
+
/**
|
|
19
|
+
* Feedback log lines and diagnostics entries, from addFeedbackLog() and addDiagnosticsInfo().
|
|
20
|
+
* These are not sent on their own: feedback/logs.ts renders them into the files that
|
|
21
|
+
* feedback/add carries, and removes the ones a submission took with it.
|
|
22
|
+
*/
|
|
23
|
+
export declare const feedbacklog_transactions: Queue;
|
|
24
|
+
/** Clicks and scrolls waiting for heatmap/add. */
|
|
25
|
+
export declare const heatmap_transactions: Queue;
|
|
26
|
+
/**
|
|
27
|
+
* Remote log lines waiting for log/add. Stored rather than sent straight out because the
|
|
28
|
+
* endpoint takes one line per call and counts retries (`attempt`), so a line has to outlive a
|
|
29
|
+
* failed send — and a reload.
|
|
30
|
+
*/
|
|
31
|
+
export declare const remotelog_transactions: Queue;
|
|
32
|
+
/**
|
|
33
|
+
* Sets one key of the stored device_info, and of this tab's copy: the uuid the device is
|
|
34
|
+
* registered under, whether it has had a session. Its other keys stay as they are.
|
|
35
|
+
*/
|
|
36
|
+
export declare function setDeviceInfoKey(key: string, value: unknown): void;
|
|
37
|
+
/** device_info (uuid included), app_version_info, trackinfo (tracking_status included), users, user_info, and the rest. */
|
|
38
|
+
export declare const user_defaults: {
|
|
39
|
+
all(): Dict;
|
|
40
|
+
item(key: string): any;
|
|
41
|
+
add(key: string, value: unknown): void;
|
|
42
|
+
/** As add(), and resolves once the value is in storage, where other tabs can read it. */
|
|
43
|
+
save(key: string, value: unknown): Promise<void>;
|
|
44
|
+
clear(): void;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Re-reads `keys` from storage. Settings are loaded into memory once, when a tab starts, so a value
|
|
48
|
+
* another tab of this site wrote since then — the device ids it registered — is only in storage.
|
|
49
|
+
* A key storage doesn't hold keeps this tab's value.
|
|
50
|
+
*/
|
|
51
|
+
export declare function reloadSettings(keys: string[]): Promise<void>;
|
|
52
|
+
/** The visitor's tracking status, stored in trackinfo as tracking_status. */
|
|
53
|
+
export declare function storedTrackingStatus(): TrackingStatus | undefined;
|
|
54
|
+
/** Opt-in status, stored in the trackinfo setting as tracking_status. */
|
|
55
|
+
export declare const tracking_preference: {
|
|
56
|
+
_tracking_status: string;
|
|
57
|
+
all(): Dict;
|
|
58
|
+
opt_in_status(): TrackingStatus;
|
|
59
|
+
update_status(tracking_status: TrackingStatus): void;
|
|
60
|
+
};
|
|
61
|
+
export declare function getKeyFromDeviceInfo(key: string): any;
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var constants = require('./constants.js');
|
|
5
|
+
var state = require('./state.js');
|
|
6
|
+
var logger = require('./logger.js');
|
|
7
|
+
var utils = require('./utils.js');
|
|
8
|
+
var db = require('./db.js');
|
|
9
|
+
|
|
10
|
+
var readyPromise = null;
|
|
11
|
+
var settings = {};
|
|
12
|
+
/** Runs `op` once storage is ready, in call order. Never rejects. */
|
|
13
|
+
function withBackend(label, fallback, op) {
|
|
14
|
+
return storageReady().then(function (b) {
|
|
15
|
+
return b ? op(b) : fallback;
|
|
16
|
+
}).catch(function (err) {
|
|
17
|
+
logger.Console.warn('apptics: storage ' + label + ' failed: ' + String(err)); // no i18n
|
|
18
|
+
return fallback;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function migrateLegacy(b) {
|
|
22
|
+
if (b.kind !== 'indexeddb' || !b.importAll) { // no i18n
|
|
23
|
+
return Promise.resolve();
|
|
24
|
+
}
|
|
25
|
+
var raw;
|
|
26
|
+
try {
|
|
27
|
+
raw = {
|
|
28
|
+
settings: localStorage.getItem(db.LEGACY_KEYS.settings),
|
|
29
|
+
engagements: localStorage.getItem(db.LEGACY_KEYS.engagements),
|
|
30
|
+
errors: localStorage.getItem(db.LEGACY_KEYS.errors),
|
|
31
|
+
logs: localStorage.getItem(db.LEGACY_KEYS.logs),
|
|
32
|
+
consolelogs: localStorage.getItem(db.LEGACY_KEYS.consolelogs),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
return Promise.resolve();
|
|
37
|
+
}
|
|
38
|
+
if (raw.settings === null && raw.engagements === null && raw.errors === null && raw.logs === null
|
|
39
|
+
&& raw.consolelogs === null) {
|
|
40
|
+
return Promise.resolve();
|
|
41
|
+
}
|
|
42
|
+
var parse = function (text) {
|
|
43
|
+
try {
|
|
44
|
+
return text === null ? null : JSON.parse(text);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
// 1.x's keys are logs and consolelogs; they are feedbacklogs and remotelogs now, and a
|
|
51
|
+
// feedback entry's type is feedbacklog or feedbackdiagnostics instead of log or diagnostics
|
|
52
|
+
var queues = {
|
|
53
|
+
engagements: db.asList(parse(raw.engagements)),
|
|
54
|
+
errors: db.asList(parse(raw.errors)),
|
|
55
|
+
feedbacklogs: db.asList(parse(raw.logs)).map(db.renameFeedbackType),
|
|
56
|
+
remotelogs: db.asList(parse(raw.consolelogs)),
|
|
57
|
+
// nothing to migrate: 1.x had no heatmaps
|
|
58
|
+
heatmaps: [],
|
|
59
|
+
};
|
|
60
|
+
queues.engagements.concat(queues.errors, queues.feedbacklogs, queues.remotelogs).forEach(function (item) {
|
|
61
|
+
if (!item.id)
|
|
62
|
+
item.id = utils.getNewUUID();
|
|
63
|
+
});
|
|
64
|
+
var importAll = b.importAll.bind(b);
|
|
65
|
+
// Promise.resolve().then(...) turns a synchronous throw inside importAll into a rejection
|
|
66
|
+
return Promise.resolve().then(function () {
|
|
67
|
+
return importAll(db.asDict(parse(raw.settings)), queues);
|
|
68
|
+
}).then(function () {
|
|
69
|
+
Object.values(db.LEGACY_KEYS).forEach(function (key) {
|
|
70
|
+
try {
|
|
71
|
+
localStorage.removeItem(key);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
// keys stay; the import is idempotent
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
logger.Console.log('apptics: moved 1.x data from localStorage to IndexedDB'); // no i18n
|
|
78
|
+
}).catch(function (err) {
|
|
79
|
+
logger.Console.warn('apptics: 1.x data migration failed, will retry next load: ' + String(err)); // no i18n
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/** Opens storage, migrates 1.x data and loads settings into memory. Shared by all callers. */
|
|
83
|
+
function storageReady() {
|
|
84
|
+
if (!readyPromise) {
|
|
85
|
+
readyPromise = db.openBackend().then(function (b) {
|
|
86
|
+
if (!b) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
return migrateLegacy(b).then(function () {
|
|
90
|
+
return b.loadSettings();
|
|
91
|
+
}).then(function (loaded) {
|
|
92
|
+
// writes made before loading finished win over stored values
|
|
93
|
+
settings = Object.assign({}, loaded, settings);
|
|
94
|
+
moveRetiredSettings();
|
|
95
|
+
return b;
|
|
96
|
+
});
|
|
97
|
+
}).catch(function (err) {
|
|
98
|
+
logger.Console.warn('apptics: storage unavailable: ' + String(err)); // no i18n
|
|
99
|
+
return null;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return readyPromise;
|
|
103
|
+
}
|
|
104
|
+
/** When an item happened: engagements carry starttime, errors and logs happenedat. */
|
|
105
|
+
function itemTime(item) {
|
|
106
|
+
return item.starttime !== undefined ? item.starttime : item.happenedat;
|
|
107
|
+
}
|
|
108
|
+
/** First batch_size items, capped at 1 MB. */
|
|
109
|
+
function takeBatch(items) {
|
|
110
|
+
const targetSize = 1024 * 1024; // 1 MB in bytes
|
|
111
|
+
let dataSize = 0;
|
|
112
|
+
const result = [];
|
|
113
|
+
for (const item of items.slice(0, state.getConfig('batch_size'))) { // no i18n
|
|
114
|
+
const size = utils.sizeof(JSON.stringify(item));
|
|
115
|
+
if (dataSize + size > targetSize) {
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
result.push(item);
|
|
119
|
+
dataSize += size;
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
function createQueue(name) {
|
|
124
|
+
const queue = {
|
|
125
|
+
name: name,
|
|
126
|
+
all() {
|
|
127
|
+
return withBackend('read ' + name, [], function (b) { return b.queueAll(name); }); // no i18n
|
|
128
|
+
},
|
|
129
|
+
payload() {
|
|
130
|
+
return queue.all().then(takeBatch);
|
|
131
|
+
},
|
|
132
|
+
add(item) {
|
|
133
|
+
if (!item.id) {
|
|
134
|
+
item.id = utils.getNewUUID();
|
|
135
|
+
}
|
|
136
|
+
// a week-old item would only be dropped at send time, so don't store it at all
|
|
137
|
+
if (state.isExpired(itemTime(item))) {
|
|
138
|
+
logger.Console.warn('apptics: dropping a ' + name + ' item older than ' + state.getConfig('batch_request_timeout') + ' days'); // no i18n
|
|
139
|
+
return Promise.resolve();
|
|
140
|
+
}
|
|
141
|
+
return withBackend('add ' + name, undefined, function (b) { return b.queuePut(name, [item]); }); // no i18n
|
|
142
|
+
},
|
|
143
|
+
update(item) {
|
|
144
|
+
return withBackend('update ' + name, undefined, function (b) { return b.queuePut(name, [item]); }); // no i18n
|
|
145
|
+
},
|
|
146
|
+
remove(itemsToRemove) {
|
|
147
|
+
const ids = (itemsToRemove || []).map(function (item) { return String(item.id); });
|
|
148
|
+
return withBackend('remove ' + name, undefined, function (b) { return b.queueDelete(name, ids); }); // no i18n
|
|
149
|
+
},
|
|
150
|
+
clear() {
|
|
151
|
+
return withBackend('clear ' + name, undefined, function (b) { return b.queueClear(name); }); // no i18n
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
return queue;
|
|
155
|
+
}
|
|
156
|
+
/** Sessions, screens, events and api calls waiting to be sent. */
|
|
157
|
+
const engagement_transactions = createQueue('engagements'); // no i18n
|
|
158
|
+
/** Errors waiting to be sent. */
|
|
159
|
+
const error_transactions = createQueue('errors'); // no i18n
|
|
160
|
+
/**
|
|
161
|
+
* Feedback log lines and diagnostics entries, from addFeedbackLog() and addDiagnosticsInfo().
|
|
162
|
+
* These are not sent on their own: feedback/logs.ts renders them into the files that
|
|
163
|
+
* feedback/add carries, and removes the ones a submission took with it.
|
|
164
|
+
*/
|
|
165
|
+
const feedbacklog_transactions = createQueue('feedbacklogs'); // no i18n
|
|
166
|
+
/** Clicks and scrolls waiting for heatmap/add. */
|
|
167
|
+
const heatmap_transactions = createQueue('heatmaps'); // no i18n
|
|
168
|
+
/**
|
|
169
|
+
* Remote log lines waiting for log/add. Stored rather than sent straight out because the
|
|
170
|
+
* endpoint takes one line per call and counts retries (`attempt`), so a line has to outlive a
|
|
171
|
+
* failed send — and a reload.
|
|
172
|
+
*/
|
|
173
|
+
const remotelog_transactions = createQueue('remotelogs'); // no i18n
|
|
174
|
+
/* ---------------- settings (sync reads, background writes) ---------------- */
|
|
175
|
+
/** Writes `key`, or removes it from storage altogether when `value` is undefined. */
|
|
176
|
+
function writeSetting(b, key) {
|
|
177
|
+
return settings[key] === undefined ? b.deleteSetting(key) : b.putSetting(key, settings[key]);
|
|
178
|
+
}
|
|
179
|
+
function setSetting(key, value) {
|
|
180
|
+
if (value === undefined) {
|
|
181
|
+
delete settings[key];
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
settings[key] = utils.cloneObject(value);
|
|
185
|
+
}
|
|
186
|
+
withBackend('save ' + key, undefined, function (b) { return writeSetting(b, key); }); // no i18n
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Settings 2.0.0-beta kept as keys of their own, now kept inside device_info and trackinfo.
|
|
190
|
+
* Moved once, on the first load after an upgrade, before anything reads them: the uuid is the one
|
|
191
|
+
* the device is registered under, and the tracking status is the visitor's own choice, so losing
|
|
192
|
+
* either would register a new device or forget a consent. token was never read, and goes.
|
|
193
|
+
* appkey and appversion are read and removed by init(), which compares them with this visit's app.
|
|
194
|
+
*/
|
|
195
|
+
function moveRetiredSettings() {
|
|
196
|
+
var device = settings.device_info && typeof settings.device_info === 'object' ? settings.device_info : null; // no i18n
|
|
197
|
+
if (settings.uuid !== undefined || settings.hadsession !== undefined) {
|
|
198
|
+
device = Object.assign({}, device || {});
|
|
199
|
+
if (utils.isEmpty(device.uuid) && !utils.isEmpty(settings.uuid)) {
|
|
200
|
+
device.uuid = settings.uuid;
|
|
201
|
+
}
|
|
202
|
+
if (settings.hadsession === true) {
|
|
203
|
+
device.hadsession = true;
|
|
204
|
+
}
|
|
205
|
+
setSetting('device_info', device); // no i18n
|
|
206
|
+
setSetting('uuid', undefined); // no i18n
|
|
207
|
+
setSetting('hadsession', undefined); // no i18n
|
|
208
|
+
}
|
|
209
|
+
if (settings.tracking_status !== undefined) {
|
|
210
|
+
var track = Object.assign({}, settings.trackinfo && typeof settings.trackinfo === 'object' ? settings.trackinfo : {}); // no i18n
|
|
211
|
+
if (track.tracking_status === undefined) {
|
|
212
|
+
track.tracking_status = settings.tracking_status;
|
|
213
|
+
}
|
|
214
|
+
setSetting('trackinfo', track); // no i18n
|
|
215
|
+
setSetting('tracking_status', undefined); // no i18n
|
|
216
|
+
}
|
|
217
|
+
if (settings.token !== undefined) {
|
|
218
|
+
setSetting('token', undefined); // no i18n
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Sets one key of the stored device_info, and of this tab's copy: the uuid the device is
|
|
223
|
+
* registered under, whether it has had a session. Its other keys stay as they are.
|
|
224
|
+
*/
|
|
225
|
+
function setDeviceInfoKey(key, value) {
|
|
226
|
+
var device = Object.assign({}, settings.device_info && typeof settings.device_info === 'object' ? settings.device_info : {}); // no i18n
|
|
227
|
+
device[key] = value;
|
|
228
|
+
if (state._ZAP._device_info && typeof state._ZAP._device_info === 'object') { // no i18n
|
|
229
|
+
state._ZAP._device_info[key] = value;
|
|
230
|
+
}
|
|
231
|
+
setSetting('device_info', device); // no i18n
|
|
232
|
+
}
|
|
233
|
+
/** device_info (uuid included), app_version_info, trackinfo (tracking_status included), users, user_info, and the rest. */
|
|
234
|
+
const user_defaults = {
|
|
235
|
+
all() {
|
|
236
|
+
return utils.cloneObject(settings);
|
|
237
|
+
},
|
|
238
|
+
item(key) {
|
|
239
|
+
const value = settings[key];
|
|
240
|
+
return value === undefined ? undefined : utils.cloneObject(value);
|
|
241
|
+
},
|
|
242
|
+
add(key, value) {
|
|
243
|
+
setSetting(key, value);
|
|
244
|
+
},
|
|
245
|
+
/** As add(), and resolves once the value is in storage, where other tabs can read it. */
|
|
246
|
+
save(key, value) {
|
|
247
|
+
if (value === undefined) {
|
|
248
|
+
delete settings[key];
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
settings[key] = utils.cloneObject(value);
|
|
252
|
+
}
|
|
253
|
+
return withBackend('save ' + key, undefined, function (b) { return writeSetting(b, key); }); // no i18n
|
|
254
|
+
},
|
|
255
|
+
clear() {
|
|
256
|
+
settings = {};
|
|
257
|
+
withBackend('clear settings', undefined, function (b) { return b.clearSettings(); }); // no i18n
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
/**
|
|
261
|
+
* Re-reads `keys` from storage. Settings are loaded into memory once, when a tab starts, so a value
|
|
262
|
+
* another tab of this site wrote since then — the device ids it registered — is only in storage.
|
|
263
|
+
* A key storage doesn't hold keeps this tab's value.
|
|
264
|
+
*/
|
|
265
|
+
function reloadSettings(keys) {
|
|
266
|
+
return withBackend('reload settings', undefined, function (b) {
|
|
267
|
+
return b.loadSettings().then(function (loaded) {
|
|
268
|
+
keys.forEach(function (key) {
|
|
269
|
+
if (loaded[key] !== undefined) {
|
|
270
|
+
settings[key] = loaded[key];
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
/** The visitor's tracking status, stored in trackinfo as tracking_status. */
|
|
277
|
+
function storedTrackingStatus() {
|
|
278
|
+
var track = settings.trackinfo;
|
|
279
|
+
var status = track && typeof track === 'object' ? track.tracking_status : undefined; // no i18n
|
|
280
|
+
// a status only: getsdkconfig's own answer uses the same key for its per-module flags, and
|
|
281
|
+
// one stored by mistake must not read as a consent and stop all tracking
|
|
282
|
+
return status === constants.AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII || status === constants.AP_TRACKING_STATUS.USAGE_TRACKING_WITHOUT_PII
|
|
283
|
+
|| status === constants.AP_TRACKING_STATUS.NO_TRACKING ? status : undefined;
|
|
284
|
+
}
|
|
285
|
+
/** Opt-in status, stored in the trackinfo setting as tracking_status. */
|
|
286
|
+
const tracking_preference = {
|
|
287
|
+
_tracking_status: 'tracking_status', // no i18n
|
|
288
|
+
all() {
|
|
289
|
+
return user_defaults.all();
|
|
290
|
+
},
|
|
291
|
+
opt_in_status() {
|
|
292
|
+
return (storedTrackingStatus() || constants.AP_TRACKING_STATUS.USAGE_TRACKING_WITHOUT_PII);
|
|
293
|
+
},
|
|
294
|
+
update_status(tracking_status) {
|
|
295
|
+
state._ZAP._devicestatus = tracking_status;
|
|
296
|
+
// Legacy order kept: this reads the status *before* the write below (setTrackingStatus recomputes it after).
|
|
297
|
+
state._ZAP._isanonrequired =
|
|
298
|
+
tracking_preference.opt_in_status() == constants.AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII ? false : state._ZAP._isanonrequired;
|
|
299
|
+
var track = Object.assign({}, settings.trackinfo && typeof settings.trackinfo === 'object' ? settings.trackinfo : {}); // no i18n
|
|
300
|
+
track.tracking_status = tracking_status;
|
|
301
|
+
if (state._ZAP._trackinfo && typeof state._ZAP._trackinfo === 'object') { // no i18n
|
|
302
|
+
state._ZAP._trackinfo.tracking_status = tracking_status;
|
|
303
|
+
}
|
|
304
|
+
setSetting('trackinfo', track); // no i18n
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
function getKeyFromDeviceInfo(key) {
|
|
308
|
+
var current_device_info = settings['device_info']; // no i18n
|
|
309
|
+
if (current_device_info !== undefined && current_device_info !== null && current_device_info !== '' &&
|
|
310
|
+
current_device_info[key] !== undefined && current_device_info[key] !== null && current_device_info[key] !== '') {
|
|
311
|
+
return utils.cloneObject(current_device_info[key]);
|
|
312
|
+
}
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
exports.engagement_transactions = engagement_transactions;
|
|
317
|
+
exports.error_transactions = error_transactions;
|
|
318
|
+
exports.feedbacklog_transactions = feedbacklog_transactions;
|
|
319
|
+
exports.getKeyFromDeviceInfo = getKeyFromDeviceInfo;
|
|
320
|
+
exports.heatmap_transactions = heatmap_transactions;
|
|
321
|
+
exports.reloadSettings = reloadSettings;
|
|
322
|
+
exports.remotelog_transactions = remotelog_transactions;
|
|
323
|
+
exports.setDeviceInfoKey = setDeviceInfoKey;
|
|
324
|
+
exports.storageReady = storageReady;
|
|
325
|
+
exports.storedTrackingStatus = storedTrackingStatus;
|
|
326
|
+
exports.tracking_preference = tracking_preference;
|
|
327
|
+
exports.user_defaults = user_defaults;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adds the feedback form's styles to the page, once, as a <style> element, so no app imports or
|
|
3
|
+
* links a stylesheet: the css is carried in the JavaScript, for npm and the CDN builds alike.
|
|
4
|
+
*
|
|
5
|
+
* Nothing happens when `css` is empty (running from source, as the tests do) or when the page
|
|
6
|
+
* already has the styles (the element is marked data-apptics="style"). Never throws.
|
|
7
|
+
*/
|
|
8
|
+
export declare function injectStylesheet(css: string): void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Adds the feedback form's styles to the page, once, as a <style> element, so no app imports or
|
|
6
|
+
* links a stylesheet: the css is carried in the JavaScript, for npm and the CDN builds alike.
|
|
7
|
+
*
|
|
8
|
+
* Nothing happens when `css` is empty (running from source, as the tests do) or when the page
|
|
9
|
+
* already has the styles (the element is marked data-apptics="style"). Never throws.
|
|
10
|
+
*/
|
|
11
|
+
function injectStylesheet(css) {
|
|
12
|
+
try {
|
|
13
|
+
if (!css || typeof document === 'undefined') { // no i18n
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (document.querySelector('[data-apptics="style"]')) { // no i18n
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
var style = document.createElement('style'); // no i18n
|
|
20
|
+
style.setAttribute('data-apptics', 'style'); // no i18n
|
|
21
|
+
style.textContent = css;
|
|
22
|
+
(document.head || document.documentElement).appendChild(style);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
// the form still works unstyled; the app must not break over a stylesheet
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
exports.injectStylesheet = injectStylesheet;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { DEFAULT_API_PATHS } from './constants.js';
|
|
2
|
+
import type { Dict, ServerResult } from '../types.js';
|
|
3
|
+
export type ApiPath = keyof typeof DEFAULT_API_PATHS;
|
|
4
|
+
export type RequestHeaders = Record<string, string>;
|
|
5
|
+
export type RequestBody = XMLHttpRequestBodyInit | null;
|
|
6
|
+
/**
|
|
7
|
+
* How long a request may take before it counts as failed. Without a limit a request the network
|
|
8
|
+
* never answers keeps its caller waiting for good, and with it the queue it was sending.
|
|
9
|
+
*/
|
|
10
|
+
export declare const REQUEST_TIMEOUT_MS = 30000;
|
|
11
|
+
export declare function makeRequest(url: string, method: string, payload: RequestBody, headers?: RequestHeaders): Promise<string>;
|
|
12
|
+
export declare function getHeaderParams(key: string): string;
|
|
13
|
+
export declare function getParameters(path: ApiPath): string;
|
|
14
|
+
/**
|
|
15
|
+
* `extra` appends params the path needs per call rather than per state, which console/addlog does
|
|
16
|
+
* (happenedtime and module change with every line). Values are encoded; the keys are our own.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getUrlWithParams(path: ApiPath, extra?: Dict): string;
|
|
19
|
+
/** Whether this path should go to its debug twin. */
|
|
20
|
+
export declare function usesDebugApi(path: ApiPath): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Headers for every call made after device registration.
|
|
23
|
+
*
|
|
24
|
+
* apid and mapid are the only two, because they are the only two every url allows: the v2
|
|
25
|
+
* endpoints declare Access-Control-Allow-Headers as exactly "apid,mapid", and a browser drops
|
|
26
|
+
* any header outside that list at the preflight. Asking for the debug twin is done with the url
|
|
27
|
+
* alone, which needs no permission to send.
|
|
28
|
+
*/
|
|
29
|
+
export declare function apiHeaders(): RequestHeaders;
|
|
30
|
+
/**
|
|
31
|
+
* A rejection that carries the server's own answer, so a caller can tell *why* it failed.
|
|
32
|
+
* Without this the reason is flattened into a string and a permanent refusal is indistinguishable
|
|
33
|
+
* from a dropped connection.
|
|
34
|
+
*/
|
|
35
|
+
export interface ServerRejection extends Error {
|
|
36
|
+
serverResult?: ServerResult;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Whether a rejection is the server saying "never": the batch is malformed and keeping it would
|
|
40
|
+
* block every later batch behind it, for good. Anything else — a 5xx, a timeout, no network — is
|
|
41
|
+
* worth retrying and must not be treated this way.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isPermanentRefusal(err: unknown): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Sends one request. Resolves with the parsed response when it reports success; otherwise
|
|
46
|
+
* rejects with an Error carrying the server's answer. Requests are independent of each other:
|
|
47
|
+
* nothing orders one behind another.
|
|
48
|
+
*/
|
|
49
|
+
export declare function postToApptics(path: ApiPath, payload: RequestBody, headers: RequestHeaders, label: string, extra?: Dict): Promise<ServerResult>;
|
|
50
|
+
/**
|
|
51
|
+
* The most a page may have in flight as keepalive bodies at once. Browsers refuse a keepalive
|
|
52
|
+
* request once the bodies still in flight would pass 64 KiB; this stays under that with room for
|
|
53
|
+
* the url and headers.
|
|
54
|
+
*/
|
|
55
|
+
export declare const KEEPALIVE_BUDGET: number;
|
|
56
|
+
/**
|
|
57
|
+
* Sends as the page goes away, where a normal XHR would be cancelled with the document.
|
|
58
|
+
*
|
|
59
|
+
* `keepalive` is what lets the request outlive the page. fetch is used rather than sendBeacon
|
|
60
|
+
* because sendBeacon cannot carry the apid and mapid headers these urls require.
|
|
61
|
+
*
|
|
62
|
+
* The request leaves before this returns, so a caller never has to wait on it to send the next
|
|
63
|
+
* thing. The promise settles when the answer arrives, if the page is still there to see it: a
|
|
64
|
+
* caller removes what it sent only then. Data whose answer never comes stays stored and goes
|
|
65
|
+
* again on the next visit as attempt 2, which `attempt` and `firstattempttime` let the server
|
|
66
|
+
* recognise as a copy rather than store twice.
|
|
67
|
+
*
|
|
68
|
+
* A body that would take the page past the keepalive budget is not sent at all: the browser would
|
|
69
|
+
* refuse it, and it is better kept for the next visit than lost.
|
|
70
|
+
*/
|
|
71
|
+
export declare function postKeepalive(path: ApiPath, payload: RequestBody, headers: RequestHeaders, label: string, extra?: Dict): Promise<ServerResult>;
|
|
72
|
+
/** A labelled rejection for crawlers (the SDK does nothing for them), otherwise null. */
|
|
73
|
+
export declare function rejectIfDisabled(label: string): Promise<never> | null;
|
|
74
|
+
/** A labelled rejection when the browser is offline, otherwise null. */
|
|
75
|
+
export declare function rejectIfOffline(label: string): Promise<never> | null;
|
|
76
|
+
/** Device ids sent alongside every payload. */
|
|
77
|
+
export declare function getMetaObj(): Dict;
|
|
78
|
+
/**
|
|
79
|
+
* Calls made after registration need apid/mapid. Without them this asks device.ts to
|
|
80
|
+
* refresh device info (which registers) and returns a labelled rejection; otherwise null. Shared by sender, user
|
|
81
|
+
* and feedback (P11).
|
|
82
|
+
*/
|
|
83
|
+
export declare function rejectIfNoDeviceIds(label: string): Promise<never> | null;
|
|
84
|
+
/** Whether device/add has given this browser its deviceid. */
|
|
85
|
+
export declare function hasDeviceId(): boolean;
|