@zoho_apptics/apptics-js-sdk 2.0.0-beta.1 → 2.0.0-beta.2
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 +80 -16
- package/README.md +187 -100
- package/dist/apptics.esm.min.js +2 -2
- package/dist/apptics.esm.min.js.map +1 -1
- package/dist/apptics.min.js +2 -2
- package/dist/apptics.min.js.map +1 -1
- package/dist/chunks/lifecycle-C6m1W7jo.min.js +3 -0
- package/dist/chunks/lifecycle-C6m1W7jo.min.js.map +1 -0
- package/dist/chunks/send-CgUO82ne.min.js +3 -0
- package/dist/chunks/send-CgUO82ne.min.js.map +1 -0
- package/dist/cjs/core/attempts.js +1 -1
- package/dist/cjs/core/batch.js +1 -2
- package/dist/cjs/core/consent.d.ts +13 -3
- package/dist/cjs/core/consent.js +24 -10
- package/dist/cjs/core/constants.d.ts +22 -17
- package/dist/cjs/core/constants.js +22 -19
- package/dist/cjs/core/db.js +1 -1
- package/dist/cjs/core/debug.js +1 -1
- package/dist/cjs/core/env.d.ts +0 -3
- package/dist/cjs/core/env.js +1 -9
- package/dist/cjs/core/framework-id.d.ts +1 -1
- package/dist/cjs/core/framework-id.js +3 -3
- package/dist/cjs/core/guard.js +1 -1
- package/dist/cjs/core/hooks.d.ts +5 -0
- package/dist/cjs/core/hooks.js +2 -1
- package/dist/cjs/core/locks.js +1 -1
- package/dist/cjs/core/logger.js +1 -1
- package/dist/cjs/core/state.d.ts +6 -4
- package/dist/cjs/core/state.js +2 -4
- package/dist/cjs/core/storage.js +1 -4
- package/dist/cjs/core/stylesheet.js +1 -1
- package/dist/cjs/core/transport.js +13 -16
- package/dist/cjs/core/utils.js +1 -1
- package/dist/cjs/core/validate.js +1 -1
- package/dist/cjs/device/appversion.d.ts +10 -1
- package/dist/cjs/device/appversion.js +26 -3
- package/dist/cjs/device/index.d.ts +17 -2
- package/dist/cjs/device/index.js +195 -27
- package/dist/cjs/engagement/api-rules.js +1 -1
- package/dist/cjs/engagement/auto-api.js +1 -1
- package/dist/cjs/engagement/auto-screen.js +1 -1
- package/dist/cjs/engagement/defined-events.js +1 -1
- package/dist/cjs/engagement/send.js +7 -3
- package/dist/cjs/engagement/session.d.ts +17 -0
- package/dist/cjs/engagement/session.js +95 -4
- package/dist/cjs/engagement/track.d.ts +4 -4
- package/dist/cjs/engagement/track.js +15 -12
- package/dist/cjs/errors/send.js +2 -2
- package/dist/cjs/errors/track.d.ts +2 -1
- package/dist/cjs/errors/track.js +6 -4
- package/dist/cjs/feedback/controls.d.ts +6 -0
- package/dist/cjs/feedback/controls.js +74 -25
- package/dist/cjs/feedback/index.js +1 -1
- package/dist/cjs/feedback/logs.d.ts +3 -6
- package/dist/cjs/feedback/logs.js +8 -18
- package/dist/cjs/feedback/quartz.js +1 -1
- package/dist/cjs/feedback/send.d.ts +2 -2
- package/dist/cjs/feedback/send.js +4 -27
- package/dist/cjs/feedback/styles.js +2 -2
- package/dist/cjs/feedback/template.d.ts +1 -1
- package/dist/cjs/feedback/template.js +9 -1
- package/dist/cjs/feedback/ui.d.ts +7 -0
- package/dist/cjs/feedback/ui.js +160 -25
- package/dist/cjs/heatmap/send.d.ts +2 -0
- package/dist/cjs/heatmap/send.js +3 -5
- package/dist/cjs/heatmap/track.js +1 -1
- package/dist/cjs/index.d.ts +1 -2
- package/dist/cjs/index.js +54 -17
- package/dist/cjs/lifecycle.d.ts +13 -2
- package/dist/cjs/lifecycle.js +122 -54
- package/dist/cjs/remoteconfig/country.js +1 -1
- package/dist/cjs/remoteconfig/custom.js +1 -1
- package/dist/cjs/remoteconfig/evaluate.js +1 -1
- package/dist/cjs/remoteconfig/fetch.d.ts +17 -10
- package/dist/cjs/remoteconfig/fetch.js +126 -31
- package/dist/cjs/remoteconfig/index.d.ts +13 -4
- package/dist/cjs/remoteconfig/index.js +36 -20
- package/dist/cjs/remoteconfig/store.d.ts +15 -7
- package/dist/cjs/remoteconfig/store.js +68 -35
- package/dist/cjs/remoteconfig/tz-countries.js +1 -1
- package/dist/cjs/{core → remotelog}/callsite.d.ts +5 -4
- package/dist/cjs/{core → remotelog}/callsite.js +6 -5
- package/dist/cjs/remotelog/gate.js +1 -1
- package/dist/cjs/remotelog/logger.js +2 -2
- package/dist/cjs/remotelog/send.js +2 -2
- package/dist/cjs/remotelogger/index.js +1 -1
- package/dist/cjs/scheduler.d.ts +3 -1
- package/dist/cjs/scheduler.js +24 -21
- package/dist/cjs/types.d.ts +61 -16
- package/dist/cjs/user/index.js +6 -2
- package/dist/esm/core/attempts.js +1 -1
- package/dist/esm/core/batch.js +1 -2
- package/dist/esm/core/consent.d.ts +13 -3
- package/dist/esm/core/consent.js +24 -11
- package/dist/esm/core/constants.d.ts +22 -17
- package/dist/esm/core/constants.js +22 -19
- package/dist/esm/core/db.js +1 -1
- package/dist/esm/core/debug.js +1 -1
- package/dist/esm/core/env.d.ts +0 -3
- package/dist/esm/core/env.js +2 -9
- package/dist/esm/core/framework-id.d.ts +1 -1
- package/dist/esm/core/framework-id.js +3 -3
- package/dist/esm/core/guard.js +1 -1
- package/dist/esm/core/hooks.d.ts +5 -0
- package/dist/esm/core/hooks.js +2 -1
- package/dist/esm/core/locks.js +1 -1
- package/dist/esm/core/logger.js +1 -1
- package/dist/esm/core/state.d.ts +6 -4
- package/dist/esm/core/state.js +2 -4
- package/dist/esm/core/storage.js +1 -4
- package/dist/esm/core/stylesheet.js +1 -1
- package/dist/esm/core/transport.js +13 -16
- package/dist/esm/core/utils.js +1 -1
- package/dist/esm/core/validate.js +1 -1
- package/dist/esm/device/appversion.d.ts +10 -1
- package/dist/esm/device/appversion.js +26 -4
- package/dist/esm/device/index.d.ts +17 -2
- package/dist/esm/device/index.js +195 -30
- package/dist/esm/engagement/api-rules.js +1 -1
- package/dist/esm/engagement/auto-api.js +1 -1
- package/dist/esm/engagement/auto-screen.js +1 -1
- package/dist/esm/engagement/defined-events.js +1 -1
- package/dist/esm/engagement/send.js +7 -3
- package/dist/esm/engagement/session.d.ts +17 -0
- package/dist/esm/engagement/session.js +93 -5
- package/dist/esm/engagement/track.d.ts +4 -4
- package/dist/esm/engagement/track.js +16 -13
- package/dist/esm/errors/send.js +2 -2
- package/dist/esm/errors/track.d.ts +2 -1
- package/dist/esm/errors/track.js +6 -4
- package/dist/esm/feedback/controls.d.ts +6 -0
- package/dist/esm/feedback/controls.js +74 -26
- package/dist/esm/feedback/index.js +1 -1
- package/dist/esm/feedback/logs.d.ts +3 -6
- package/dist/esm/feedback/logs.js +8 -18
- package/dist/esm/feedback/quartz.js +1 -1
- package/dist/esm/feedback/send.d.ts +2 -2
- package/dist/esm/feedback/send.js +6 -29
- package/dist/esm/feedback/styles.js +2 -2
- package/dist/esm/feedback/template.d.ts +1 -1
- package/dist/esm/feedback/template.js +9 -1
- package/dist/esm/feedback/ui.d.ts +7 -0
- package/dist/esm/feedback/ui.js +161 -26
- package/dist/esm/heatmap/send.d.ts +2 -0
- package/dist/esm/heatmap/send.js +3 -5
- package/dist/esm/heatmap/track.js +1 -1
- package/dist/esm/index.d.ts +1 -2
- package/dist/esm/index.js +57 -20
- package/dist/esm/lifecycle.d.ts +13 -2
- package/dist/esm/lifecycle.js +126 -60
- package/dist/esm/remoteconfig/country.js +1 -1
- package/dist/esm/remoteconfig/custom.js +1 -1
- package/dist/esm/remoteconfig/evaluate.js +1 -1
- package/dist/esm/remoteconfig/fetch.d.ts +17 -10
- package/dist/esm/remoteconfig/fetch.js +127 -32
- package/dist/esm/remoteconfig/index.d.ts +13 -4
- package/dist/esm/remoteconfig/index.js +36 -20
- package/dist/esm/remoteconfig/store.d.ts +15 -7
- package/dist/esm/remoteconfig/store.js +68 -36
- package/dist/esm/remoteconfig/tz-countries.js +1 -1
- package/dist/esm/{core → remotelog}/callsite.d.ts +5 -4
- package/dist/esm/{core → remotelog}/callsite.js +6 -5
- package/dist/esm/remotelog/gate.js +1 -1
- package/dist/esm/remotelog/logger.js +2 -2
- package/dist/esm/remotelog/send.js +2 -2
- package/dist/esm/remotelogger/index.js +1 -1
- package/dist/esm/scheduler.d.ts +3 -1
- package/dist/esm/scheduler.js +25 -23
- package/dist/esm/types.d.ts +61 -16
- package/dist/esm/user/index.js +7 -3
- package/dist/feedback.esm.min.js +2 -2
- package/dist/feedback.esm.min.js.map +1 -1
- package/dist/remoteconfig.esm.min.js +3 -0
- package/dist/remoteconfig.esm.min.js.map +1 -0
- package/dist/remotelogger.esm.min.js +3 -0
- package/dist/remotelogger.esm.min.js.map +1 -0
- package/package.json +3 -2
- package/dist/chunks/lifecycle-VYr43KcB.min.js +0 -3
- package/dist/chunks/lifecycle-VYr43KcB.min.js.map +0 -1
- package/dist/cjs/auto-init.d.ts +0 -8
- package/dist/cjs/auto-init.js +0 -32
- package/dist/esm/auto-init.d.ts +0 -8
- package/dist/esm/auto-init.js +0 -29
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const FRAMEWORK_ID =
|
|
1
|
+
export declare const FRAMEWORK_ID = 6003;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (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.
|
|
5
|
-
const FRAMEWORK_ID =
|
|
4
|
+
// (version 2.0.0-beta.2, platform Browser). Regenerated on every npm pack.
|
|
5
|
+
const FRAMEWORK_ID = 6003;
|
|
6
6
|
|
|
7
7
|
export { FRAMEWORK_ID };
|
package/dist/esm/core/guard.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
import { _ZAP } from './state.js';
|
|
3
3
|
import { warnAlways, logFailure } from './logger.js';
|
|
4
4
|
|
package/dist/esm/core/hooks.d.ts
CHANGED
|
@@ -36,4 +36,9 @@ export declare const hooks: {
|
|
|
36
36
|
remoteConfigStarted: () => void;
|
|
37
37
|
/** Set by remoteconfig/fetch.ts: AppticsUser.setUser changed who this is, so conditions on the user re-apply. */
|
|
38
38
|
remoteConfigUserChanged: () => void;
|
|
39
|
+
/**
|
|
40
|
+
* Set by device/index.ts: getsdkconfig is asked now, outside its next_check_after. setUser calls
|
|
41
|
+
* it once a user is registered, and remote config when getupdates reports a module changed.
|
|
42
|
+
*/
|
|
43
|
+
askServerSettings: () => void;
|
|
39
44
|
};
|
package/dist/esm/core/hooks.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (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
|
|
@@ -15,6 +15,7 @@ const hooks = {
|
|
|
15
15
|
screenTrackedByApp: () => { },
|
|
16
16
|
remoteConfigStarted: () => { },
|
|
17
17
|
remoteConfigUserChanged: () => { },
|
|
18
|
+
askServerSettings: () => { },
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
export { hooks };
|
package/dist/esm/core/locks.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
/**
|
|
3
3
|
* Runs `run` while holding the Web Lock `name`, waiting for it if another tab of this site holds
|
|
4
4
|
* it. Locks are shared by every tab of an origin, which is what keeps two tabs from registering
|
package/dist/esm/core/logger.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
import { _ZAP } from './state.js';
|
|
3
3
|
import { each } from './utils.js';
|
|
4
4
|
|
package/dist/esm/core/state.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ApConfig } from './constants.js';
|
|
1
|
+
import { type ApConfig, type EngagementType } from './constants.js';
|
|
2
2
|
import type { DeviceInfo, Dict, QuartzSettings, TrackingStatus, UserInfo } from '../types.js';
|
|
3
3
|
/** Runtime state shared by every module (the former `_ZAP` object). */
|
|
4
4
|
export interface State {
|
|
@@ -19,7 +19,6 @@ export interface State {
|
|
|
19
19
|
_token: string;
|
|
20
20
|
_frameworkID: number;
|
|
21
21
|
_platform: string;
|
|
22
|
-
_isanonrequired: boolean;
|
|
23
22
|
_devicestatus: TrackingStatus;
|
|
24
23
|
_uuid: string;
|
|
25
24
|
_apid: string;
|
|
@@ -30,9 +29,12 @@ export interface State {
|
|
|
30
29
|
_current_session: Dict;
|
|
31
30
|
_properties: Dict;
|
|
32
31
|
_ignoreDnt: boolean;
|
|
33
|
-
_isGlobalErrorTracking: boolean;
|
|
34
32
|
_shouldTrack: boolean;
|
|
35
|
-
|
|
33
|
+
/**
|
|
34
|
+
* getsdkconfig's engagement modules, one per kind of item, keyed by the item's type: event (5),
|
|
35
|
+
* api (6), screen (10) and session (11).
|
|
36
|
+
*/
|
|
37
|
+
_engagementTracking: Record<EngagementType, boolean>;
|
|
36
38
|
_errorTracking: boolean;
|
|
37
39
|
/** getsdkconfig module 18. Heatmap has its own flag in v2; before that it rode engagement. */
|
|
38
40
|
_heatmapTracking: boolean;
|
package/dist/esm/core/state.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
import { AP_TRACKING_STATUS, AP_CONSTANTS, DEFAULT_INACTIVE_MINUTES, AP_CONFIG } from './constants.js';
|
|
3
3
|
import { nowMs } from './utils.js';
|
|
4
4
|
import { FRAMEWORK_ID } from './framework-id.js';
|
|
@@ -21,7 +21,6 @@ function initialState() {
|
|
|
21
21
|
// issued by Apptics at pack time; see scripts/register-version.mjs
|
|
22
22
|
_frameworkID: FRAMEWORK_ID,
|
|
23
23
|
_platform: AP_CONSTANTS.BROWSER,
|
|
24
|
-
_isanonrequired: true,
|
|
25
24
|
_devicestatus: AP_TRACKING_STATUS.USAGE_TRACKING_WITHOUT_PII,
|
|
26
25
|
_uuid: '', // no i18n
|
|
27
26
|
_apid: '', // no i18n
|
|
@@ -32,9 +31,8 @@ function initialState() {
|
|
|
32
31
|
_current_session: {},
|
|
33
32
|
_properties: {},
|
|
34
33
|
_ignoreDnt: false,
|
|
35
|
-
_isGlobalErrorTracking: true,
|
|
36
34
|
_shouldTrack: true,
|
|
37
|
-
_engagementTracking: true,
|
|
35
|
+
_engagementTracking: { event: true, screen: true, session: true, api: true },
|
|
38
36
|
_heatmapTracking: true,
|
|
39
37
|
_remoteLoggerEnabled: true,
|
|
40
38
|
_remoteConfigEnabled: true,
|
package/dist/esm/core/storage.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
import { AP_TRACKING_STATUS } from './constants.js';
|
|
3
3
|
import { _ZAP, isExpired, getConfig } from './state.js';
|
|
4
4
|
import { Console } from './logger.js';
|
|
@@ -291,9 +291,6 @@ const tracking_preference = {
|
|
|
291
291
|
},
|
|
292
292
|
update_status(tracking_status) {
|
|
293
293
|
_ZAP._devicestatus = tracking_status;
|
|
294
|
-
// Legacy order kept: this reads the status *before* the write below (setTrackingStatus recomputes it after).
|
|
295
|
-
_ZAP._isanonrequired =
|
|
296
|
-
tracking_preference.opt_in_status() == AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII ? false : _ZAP._isanonrequired;
|
|
297
294
|
var track = Object.assign({}, settings.trackinfo && typeof settings.trackinfo === 'object' ? settings.trackinfo : {}); // no i18n
|
|
298
295
|
track.tracking_status = tracking_status;
|
|
299
296
|
if (_ZAP._trackinfo && typeof _ZAP._trackinfo === 'object') { // no i18n
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
/**
|
|
3
3
|
* Adds the feedback form's styles to the page, once, as a <style> element, so no app imports or
|
|
4
4
|
* links a stylesheet: the css is carried in the JavaScript, for npm and the CDN builds alike.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
import { API_VERSIONS, PATHS_WITHOUT_ORG, DEFAULT_API_PATHS, DEBUG_CAPABLE_PATHS, AP_TRACKING_STATUS, DEVICE_NAME_MAX } from './constants.js';
|
|
3
3
|
import { getConfig, _ZAP } from './state.js';
|
|
4
4
|
import { Console } from './logger.js';
|
|
@@ -139,19 +139,17 @@ function getParameters(path) {
|
|
|
139
139
|
// v2 device/add declares neither identifier, platform nor appversion: the build is already
|
|
140
140
|
// known from app/addversion, and sending an undeclared param is refused as EXTRA_PARAM_FOUND.
|
|
141
141
|
// What it does declare as mandatory is appversionid, which v1 treated as optional.
|
|
142
|
+
// isanonrequired is always false: the web SDK has no anonymous mode, only the tracking
|
|
143
|
+
// statuses (with PII, without PII, none), which devicestatus carries.
|
|
142
144
|
if (path == 'regdevice') { // no i18n
|
|
143
|
-
returnVal = '?isanonrequired=
|
|
145
|
+
returnVal = '?isanonrequired=false&devicestatus=' + _ZAP._devicestatus; // no i18n
|
|
144
146
|
if (!isEmpty(_ZAP._device_info.deviceid)) {
|
|
145
147
|
returnVal += '&deviceid=' + encodeURIComponent(String(_ZAP._device_info.deviceid)); // no i18n
|
|
146
148
|
}
|
|
147
149
|
return returnVal + mandatoryParams(returnVal);
|
|
148
150
|
}
|
|
149
|
-
// getsdkconfig
|
|
150
|
-
|
|
151
|
-
// with NOT_AUTHENTICATED. getupdates declares the same param with plain paramdecrypt, so it
|
|
152
|
-
// does carry one. It still needs appversionid and frameworkid, added at the end.
|
|
153
|
-
var identifiesDevice = path != 'sdkconfig'; // no i18n
|
|
154
|
-
if (identifiesDevice) {
|
|
151
|
+
// getsdkconfig carries no deviceid: the user's ids below are what it answers for
|
|
152
|
+
if (path != 'sdkconfig') { // no i18n
|
|
155
153
|
if (isEmpty(_ZAP._device_info.deviceid)) {
|
|
156
154
|
hooks.refreshDeviceInfo();
|
|
157
155
|
// the device is missing, but appversionid and frameworkid are mandatory regardless:
|
|
@@ -176,14 +174,13 @@ function getParameters(path) {
|
|
|
176
174
|
// them, and refuses userid as EXTRA_PARAM_FOUND; it has no use for them either, since remote
|
|
177
175
|
// config conditions on the user are evaluated here, against the rule set it answers with
|
|
178
176
|
var carriesUser = path != 'reguser' && path != 'getupdates'; // no i18n
|
|
179
|
-
if (carriesUser &&
|
|
180
|
-
if (
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
177
|
+
if (carriesUser && opt_in_status() == AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII) {
|
|
178
|
+
if (_ZAP._user_info.hasOwnProperty('userid') && !isEmpty(_ZAP._user_info.userid)) { // no i18n
|
|
179
|
+
// getsdkconfig has no deviceid before it, so its userid starts the query
|
|
180
|
+
returnVal += (returnVal === '' ? '?' : '&') + 'userid=' + encodeURIComponent(String(_ZAP._user_info.userid)); // no i18n
|
|
181
|
+
}
|
|
182
|
+
if (_ZAP._user_info.hasOwnProperty('groupid') && !isEmpty(_ZAP._user_info.groupid)) { // no i18n
|
|
183
|
+
returnVal += (returnVal === '' ? '?' : '&') + 'customergroupid=' + encodeURIComponent(String(_ZAP._user_info.groupid)); // no i18n
|
|
187
184
|
}
|
|
188
185
|
}
|
|
189
186
|
returnVal += deviceNameParam(path, returnVal);
|
package/dist/esm/core/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
import { AP_CONSTANTS } from './constants.js';
|
|
3
3
|
|
|
4
4
|
/** Returned from an `each` iterator to stop iterating objects and array-likes. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
import { Console } from './logger.js';
|
|
3
3
|
import { isEmpty, isEmptyObj } from './utils.js';
|
|
4
4
|
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* A fingerprint of the auth key, which is what is stored to tell one key from another: enough to
|
|
3
|
+
* notice that init() was given a different one, without keeping a second copy of the key itself.
|
|
4
|
+
* FNV-1a, 32 bits, as hex; '' for no key.
|
|
5
|
+
*/
|
|
6
|
+
export declare function keyFingerprint(key: unknown): string;
|
|
7
|
+
/**
|
|
8
|
+
* Whether we already hold usable ids for the app, auth key and version running now. Ids stored by
|
|
9
|
+
* a build that kept no key fingerprint register again once, and the answer then records it.
|
|
10
|
+
*/
|
|
2
11
|
export declare function hasAppVersion(): boolean;
|
|
3
12
|
export declare function appVersionFailedForNetwork(): boolean;
|
|
4
13
|
export declare function registerAppVersion(): Promise<boolean>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
import { _ZAP } from '../core/state.js';
|
|
3
3
|
import { Console, warnAlways } from '../core/logger.js';
|
|
4
4
|
import { isEmpty, isSuccess } from '../core/utils.js';
|
|
@@ -37,13 +37,34 @@ const REQUIRED_KEYS = ['aaid', 'portalid', 'projectid', 'apid', 'mapid', 'appver
|
|
|
37
37
|
function missingKeys(data) {
|
|
38
38
|
return REQUIRED_KEYS.filter(function (key) { return isEmpty(data[key]); });
|
|
39
39
|
}
|
|
40
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* A fingerprint of the auth key, which is what is stored to tell one key from another: enough to
|
|
42
|
+
* notice that init() was given a different one, without keeping a second copy of the key itself.
|
|
43
|
+
* FNV-1a, 32 bits, as hex; '' for no key.
|
|
44
|
+
*/
|
|
45
|
+
function keyFingerprint(key) {
|
|
46
|
+
var text = isEmpty(key) ? '' : String(key); // no i18n
|
|
47
|
+
if (text === '') { // no i18n
|
|
48
|
+
return ''; // no i18n
|
|
49
|
+
}
|
|
50
|
+
var hash = 0x811c9dc5;
|
|
51
|
+
for (var i = 0; i < text.length; i++) {
|
|
52
|
+
hash ^= text.charCodeAt(i);
|
|
53
|
+
hash = Math.imul(hash, 0x01000193) >>> 0;
|
|
54
|
+
}
|
|
55
|
+
return ('0000000' + hash.toString(16)).slice(-8); // no i18n
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Whether we already hold usable ids for the app, auth key and version running now. Ids stored by
|
|
59
|
+
* a build that kept no key fingerprint register again once, and the answer then records it.
|
|
60
|
+
*/
|
|
41
61
|
function hasAppVersion() {
|
|
42
62
|
var saved = stored();
|
|
43
63
|
return missingKeys(saved).length === 0
|
|
44
64
|
&& saved.appversion === _ZAP._defaultoptions.appversion
|
|
45
65
|
&& saved.identifier === _ZAP._defaultoptions.identifier
|
|
46
|
-
&& saved.serviceUrl === _ZAP._defaultoptions.serviceUrl
|
|
66
|
+
&& saved.serviceUrl === _ZAP._defaultoptions.serviceUrl
|
|
67
|
+
&& saved.zakhash === keyFingerprint(_ZAP._defaultoptions.zak);
|
|
47
68
|
}
|
|
48
69
|
/** Puts the ids where the rest of the SDK reads them from. */
|
|
49
70
|
function apply(data) {
|
|
@@ -124,6 +145,7 @@ function registerAppVersion() {
|
|
|
124
145
|
appversion: _ZAP._defaultoptions.appversion,
|
|
125
146
|
identifier: _ZAP._defaultoptions.identifier,
|
|
126
147
|
serviceUrl: _ZAP._defaultoptions.serviceUrl,
|
|
148
|
+
zakhash: keyFingerprint(_ZAP._defaultoptions.zak),
|
|
127
149
|
};
|
|
128
150
|
RESULT_KEYS.forEach(function (key) {
|
|
129
151
|
if (!isEmpty(data[key])) {
|
|
@@ -161,4 +183,4 @@ function clearAppVersion() {
|
|
|
161
183
|
user_defaults.add(STORE_KEY, undefined);
|
|
162
184
|
}
|
|
163
185
|
|
|
164
|
-
export { appVersionFailedForNetwork, applyStoredAppVersion, clearAppVersion, hasAppVersion, registerAppVersion };
|
|
186
|
+
export { appVersionFailedForNetwork, applyStoredAppVersion, clearAppVersion, hasAppVersion, keyFingerprint, registerAppVersion };
|
|
@@ -28,7 +28,22 @@ export declare function getUpdatesFromServer(): Promise<Dict>;
|
|
|
28
28
|
*/
|
|
29
29
|
export declare function restoreServerSettings(): void;
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
* next_check_after as a time: the server's value is milliseconds, either a timestamp or a wait
|
|
32
|
+
* from now. Anything below 1e12 (2001 as a timestamp) can only be a wait.
|
|
33
|
+
*/
|
|
34
|
+
export declare function nextCheckTime(value: unknown, now: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* Asks for the server settings now if the device is registered, then schedules the next ask
|
|
37
|
+
* for the time the answer gave in next_check_after. On a first visit the ids don't exist yet;
|
|
38
|
+
* registerDeviceWithApptics calls this as soon as device/add succeeds.
|
|
33
39
|
*/
|
|
34
40
|
export declare function refreshServerSettings(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Start-up's getsdkconfig. Asked on a first visit and on the first page load in each tab; any
|
|
43
|
+
* other load (a reload, a link to another page of the site, back/forward) uses the saved answer
|
|
44
|
+
* and waits for its next_check_after, unless that has already passed. Nothing happens if one has
|
|
45
|
+
* gone out already on this load (after device/add).
|
|
46
|
+
*/
|
|
47
|
+
export declare function startServerSettingChecks(): void;
|
|
48
|
+
/** reset(): no more checks, and the next init() asks again straight away. */
|
|
49
|
+
export declare function stopServerSettingChecks(): void;
|
package/dist/esm/device/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
import { SDK_MODULE } from '../core/constants.js';
|
|
3
|
-
import { _ZAP } from '../core/state.js';
|
|
3
|
+
import { _ZAP, getConfig } from '../core/state.js';
|
|
4
4
|
import { Console } from '../core/logger.js';
|
|
5
|
-
import { isEmpty, getNewUUID, isSuccess, compareTwoObjects } from '../core/utils.js';
|
|
5
|
+
import { isEmpty, nowMs, getNewUUID, isSuccess, compareTwoObjects } from '../core/utils.js';
|
|
6
6
|
import { user_defaults, getKeyFromDeviceInfo, setDeviceInfoKey, storedTrackingStatus, reloadSettings } from '../core/storage.js';
|
|
7
7
|
import { withLock } from '../core/locks.js';
|
|
8
8
|
import { getTimeZone, getConnectionType, getReferringURL, getDevice, getBrowserVersion, getBrowser, getOS } from '../core/env.js';
|
|
@@ -106,10 +106,18 @@ function checkAndUpdateDeviceInfo() {
|
|
|
106
106
|
user_defaults.add('device_info', _ZAP._device_info); // no i18n
|
|
107
107
|
addOrUpdateDeviceID(_ZAP._device_info, previous);
|
|
108
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Whether device/add has registered this device: it has a deviceid. anonymousid is not required:
|
|
111
|
+
* not every Apptics server sends one, nothing the SDK sends carries it, and requiring it had a
|
|
112
|
+
* server that leaves it out register the same device again on every page load.
|
|
113
|
+
*/
|
|
114
|
+
function isRegistered(info) {
|
|
115
|
+
return !!info && !isEmpty(info.deviceid);
|
|
116
|
+
}
|
|
109
117
|
function addOrUpdateDeviceID(device_info, previous) {
|
|
110
118
|
var old_device_info = previous !== undefined ? previous : user_defaults.item('device_info') || {}; // no i18n
|
|
111
119
|
// Compare the old and new device infos and update the server if anything changed in the new.
|
|
112
|
-
if (device_info
|
|
120
|
+
if (!isRegistered(device_info) || device_info.frameworkid == null) {
|
|
113
121
|
device_info.frameworkid = _ZAP._frameworkID;
|
|
114
122
|
Console.log('addOrUpdateDeviceID: Initiated register the device'); // no i18n
|
|
115
123
|
registerDeviceWithApptics().then(function (result_device_info) {
|
|
@@ -186,7 +194,7 @@ function useStoredUuid() {
|
|
|
186
194
|
function adoptRegisteredDevice() {
|
|
187
195
|
return reloadSettings(['device_info']).then(function () {
|
|
188
196
|
var stored = user_defaults.item('device_info') || {}; // no i18n
|
|
189
|
-
if (
|
|
197
|
+
if (!isRegistered(stored)) {
|
|
190
198
|
return null;
|
|
191
199
|
}
|
|
192
200
|
// the device is registered under the uuid the other tab sent
|
|
@@ -211,7 +219,7 @@ function adoptRegisteredDevice() {
|
|
|
211
219
|
*/
|
|
212
220
|
function prepareDevice() {
|
|
213
221
|
var cached = user_defaults.item('device_info') || {}; // no i18n
|
|
214
|
-
if (
|
|
222
|
+
if (isRegistered(cached)) {
|
|
215
223
|
useStoredUuid();
|
|
216
224
|
checkAndUpdateDeviceInfo();
|
|
217
225
|
return Promise.resolve();
|
|
@@ -276,7 +284,7 @@ function registerDeviceWithApptics() {
|
|
|
276
284
|
if (offline) {
|
|
277
285
|
return offline;
|
|
278
286
|
}
|
|
279
|
-
if (_ZAP._device_info
|
|
287
|
+
if (isRegistered(_ZAP._device_info)) {
|
|
280
288
|
return Promise.resolve(_ZAP._device_info);
|
|
281
289
|
}
|
|
282
290
|
return new Promise((resolve, reject) => {
|
|
@@ -304,8 +312,10 @@ function registerDeviceWithApptics() {
|
|
|
304
312
|
}).then(function (result) {
|
|
305
313
|
settleRegistration(true, result);
|
|
306
314
|
resolve(result);
|
|
307
|
-
// first visit: the ids exist now, so fetch the server settings right away
|
|
308
|
-
|
|
315
|
+
// first visit: the ids exist now, so fetch the server settings right away. A device
|
|
316
|
+
// registered again later (its details or the framework id changed) asks nothing more:
|
|
317
|
+
// start-up has already asked on this page load
|
|
318
|
+
startServerSettingChecks();
|
|
309
319
|
}).catch(function (err) {
|
|
310
320
|
settleRegistration(false, err);
|
|
311
321
|
reject(err);
|
|
@@ -337,6 +347,12 @@ function getUpdatesFromServer() {
|
|
|
337
347
|
return postToApptics('sdkconfig', '', apiHeaders(), label).then(function (result) {
|
|
338
348
|
var data = result.data || {};
|
|
339
349
|
applyServerFlags(data);
|
|
350
|
+
if (_ZAP._nextConfigCheck === 0) {
|
|
351
|
+
// no next_check_after: getupdates_interval from now, stored so a later page load
|
|
352
|
+
// can tell whether the answer is still current
|
|
353
|
+
_ZAP._nextConfigCheck = nowMs() + getConfig('getupdates_interval'); // no i18n
|
|
354
|
+
_ZAP._trackinfo.next_check_after = _ZAP._nextConfigCheck;
|
|
355
|
+
}
|
|
340
356
|
// the visitor's tracking status lives in trackinfo too, and is not the server's to replace
|
|
341
357
|
var saved = storedTrackingStatus();
|
|
342
358
|
user_defaults.add('trackinfo', saved === undefined ? _ZAP._trackinfo : Object.assign({}, _ZAP._trackinfo, { tracking_status: saved })); // no i18n
|
|
@@ -372,6 +388,10 @@ function applyServerFlags(data) {
|
|
|
372
388
|
if (data.hasOwnProperty('tracking_enabled')) { // no i18n
|
|
373
389
|
_ZAP._shouldTrack = data.tracking_enabled !== false;
|
|
374
390
|
}
|
|
391
|
+
else if (data.hasOwnProperty('shouldtrack')) { // no i18n
|
|
392
|
+
// what this SDK saves, read back on the next visit
|
|
393
|
+
_ZAP._shouldTrack = data.shouldtrack !== false;
|
|
394
|
+
}
|
|
375
395
|
else {
|
|
376
396
|
// the old shape: archived versions and untracked customer groups
|
|
377
397
|
var versionArchived = !data.hasOwnProperty('versionarchivestatus') || isEmpty(data.versionarchivestatus)
|
|
@@ -381,9 +401,14 @@ function applyServerFlags(data) {
|
|
|
381
401
|
_ZAP._shouldTrack = versionArchived || !customerGroupTracking;
|
|
382
402
|
}
|
|
383
403
|
if (hasModules) {
|
|
384
|
-
//
|
|
385
|
-
_ZAP._engagementTracking =
|
|
386
|
-
|
|
404
|
+
// each kind of engagement item has its own module, so the server can turn one off alone
|
|
405
|
+
_ZAP._engagementTracking = {
|
|
406
|
+
event: moduleEnabled(status, SDK_MODULE.EVENT),
|
|
407
|
+
api: moduleEnabled(status, SDK_MODULE.API),
|
|
408
|
+
screen: moduleEnabled(status, SDK_MODULE.SCREEN),
|
|
409
|
+
session: moduleEnabled(status, SDK_MODULE.SESSION),
|
|
410
|
+
};
|
|
411
|
+
_ZAP._errorTracking = moduleEnabled(status, SDK_MODULE.JS_ERROR);
|
|
387
412
|
_ZAP._heatmapTracking = moduleEnabled(status, SDK_MODULE.HEATMAP);
|
|
388
413
|
_ZAP._remoteLoggerEnabled = moduleEnabled(status, SDK_MODULE.REMOTE_LOGGER);
|
|
389
414
|
_ZAP._feedbackEnabled = moduleEnabled(status, SDK_MODULE.FEEDBACK);
|
|
@@ -392,11 +417,22 @@ function applyServerFlags(data) {
|
|
|
392
417
|
_ZAP._remoteConfigEnabled = moduleEnabled(status, SDK_MODULE.REMOTE_CONFIG);
|
|
393
418
|
}
|
|
394
419
|
else {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
420
|
+
// this SDK saves one flag per kind under engagement; an earlier build saved one
|
|
421
|
+
// engagementtracking flag for all four
|
|
422
|
+
var saved = (data.engagement && typeof data.engagement === 'object' // no i18n
|
|
423
|
+
? data.engagement : null);
|
|
424
|
+
var kindOn = function (kind) {
|
|
425
|
+
return saved ? saved[kind] !== false : data.engagementtracking !== false;
|
|
426
|
+
};
|
|
427
|
+
_ZAP._engagementTracking = { event: kindOn('event'), api: kindOn('api'), screen: kindOn('screen'), session: kindOn('session') }; // no i18n
|
|
428
|
+
// the same for the others: read the short key this SDK saves, else the earlier build's
|
|
429
|
+
var flagOn = function (key, oldKey) {
|
|
430
|
+
return (data.hasOwnProperty(key) ? data[key] : data[oldKey]) !== false;
|
|
431
|
+
};
|
|
432
|
+
_ZAP._errorTracking = flagOn('error', 'errortracking'); // no i18n
|
|
433
|
+
_ZAP._heatmapTracking = flagOn('heatmap', 'heatmaptracking'); // no i18n
|
|
434
|
+
_ZAP._remoteLoggerEnabled = flagOn('remotelogger', 'remoteloggerenabled'); // no i18n
|
|
435
|
+
_ZAP._feedbackEnabled = flagOn('feedback', 'feedbackenabled'); // no i18n
|
|
400
436
|
}
|
|
401
437
|
// screen recording, set up in the console: everything the form needs comes from here
|
|
402
438
|
var quartz = (data.quartz && typeof data.quartz === 'object' ? data.quartz : {});
|
|
@@ -410,16 +446,15 @@ function applyServerFlags(data) {
|
|
|
410
446
|
domain: text(quartz.quartz_domain),
|
|
411
447
|
cdnUrl: text(quartz.quartz_cdn_url),
|
|
412
448
|
};
|
|
413
|
-
// when to ask again, which replaces polling on a fixed interval
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
}
|
|
449
|
+
// when to ask again, which replaces polling on a fixed interval. Kept as a timestamp, so the
|
|
450
|
+
// stored copy reads back the same. An answer without one falls back to getupdates_interval
|
|
451
|
+
_ZAP._nextConfigCheck = nextCheckTime(data.next_check_after, nowMs());
|
|
417
452
|
_ZAP._trackinfo = {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
453
|
+
engagement: _ZAP._engagementTracking,
|
|
454
|
+
error: _ZAP._errorTracking,
|
|
455
|
+
heatmap: _ZAP._heatmapTracking,
|
|
456
|
+
remotelogger: _ZAP._remoteLoggerEnabled,
|
|
457
|
+
feedback: _ZAP._feedbackEnabled,
|
|
423
458
|
// in the server's own shape, so restoring it on the next visit reads it the same way
|
|
424
459
|
quartz: {
|
|
425
460
|
quartz_enabled: _ZAP._quartz.enabled,
|
|
@@ -440,22 +475,152 @@ function restoreServerSettings() {
|
|
|
440
475
|
var saved = user_defaults.item('trackinfo'); // no i18n
|
|
441
476
|
if (saved && typeof saved === 'object') { // no i18n
|
|
442
477
|
applyServerFlags(saved);
|
|
478
|
+
// saved by an earlier build under the old names: store it again in this SDK's shape now,
|
|
479
|
+
// rather than at the next getsdkconfig, which may be a while off. The visitor's tracking
|
|
480
|
+
// status is kept as it is
|
|
481
|
+
if (OLD_TRACKINFO_KEYS.some(function (key) { return saved.hasOwnProperty(key); })) {
|
|
482
|
+
user_defaults.add('trackinfo', saved.tracking_status === undefined ? _ZAP._trackinfo // no i18n
|
|
483
|
+
: Object.assign({}, _ZAP._trackinfo, { tracking_status: saved.tracking_status }));
|
|
484
|
+
}
|
|
443
485
|
Console.log('restoreServerSettings: ' + JSON.stringify(_ZAP._trackinfo)); // no i18n
|
|
444
486
|
}
|
|
445
487
|
}
|
|
488
|
+
/** trackinfo keys an earlier build saved, which this SDK saves under shorter names. */
|
|
489
|
+
var OLD_TRACKINFO_KEYS = ['engagementtracking', 'errortracking', 'heatmaptracking', 'remoteloggerenabled', 'feedbackenabled']; // no i18n
|
|
490
|
+
/**
|
|
491
|
+
* next_check_after as a time: the server's value is milliseconds, either a timestamp or a wait
|
|
492
|
+
* from now. Anything below 1e12 (2001 as a timestamp) can only be a wait.
|
|
493
|
+
*/
|
|
494
|
+
function nextCheckTime(value, now) {
|
|
495
|
+
if (typeof value !== 'number' || !(value > 0)) { // no i18n
|
|
496
|
+
return 0;
|
|
497
|
+
}
|
|
498
|
+
return value >= 1e12 ? value : now + value;
|
|
499
|
+
}
|
|
500
|
+
/** setTimeout's longest wait; a longer one fires straight away. */
|
|
501
|
+
var MAX_TIMEOUT = 2147483647;
|
|
502
|
+
var configTimer = null;
|
|
503
|
+
var configInFlight = false;
|
|
504
|
+
/** Bumped by stopServerSettingChecks(), so an answer to an ask from before a reset schedules nothing. */
|
|
505
|
+
var configRound = 0;
|
|
506
|
+
/** Whether this page load has asked, or set the timer from the saved answer instead. */
|
|
507
|
+
var configAsked = false;
|
|
508
|
+
/** A user registered, or getupdates reported a change, while a getsdkconfig was in flight: asked again when it answers. */
|
|
509
|
+
var configAskAgain = false;
|
|
510
|
+
/** When the next getsdkconfig is due, as a timestamp. 0 until the first answer. */
|
|
511
|
+
var configDueAt = 0;
|
|
446
512
|
/**
|
|
447
|
-
*
|
|
448
|
-
*
|
|
513
|
+
* Asks for the server settings now if the device is registered, then schedules the next ask
|
|
514
|
+
* for the time the answer gave in next_check_after. On a first visit the ids don't exist yet;
|
|
515
|
+
* registerDeviceWithApptics calls this as soon as device/add succeeds.
|
|
449
516
|
*/
|
|
450
517
|
function refreshServerSettings() {
|
|
451
|
-
if (isEmpty(getHeaderParams('apid')) && isEmpty(getHeaderParams('mapid'))) { // no i18n
|
|
518
|
+
if (configInFlight || !hasDeviceId() || (isEmpty(getHeaderParams('apid')) && isEmpty(getHeaderParams('mapid')))) { // no i18n
|
|
452
519
|
return;
|
|
453
520
|
}
|
|
521
|
+
if (configTimer !== null) {
|
|
522
|
+
clearTimeout(configTimer);
|
|
523
|
+
configTimer = null;
|
|
524
|
+
}
|
|
525
|
+
configInFlight = true;
|
|
526
|
+
configAsked = true;
|
|
527
|
+
markTabAsked();
|
|
528
|
+
var round = configRound;
|
|
529
|
+
var askedAt = nowMs();
|
|
454
530
|
getUpdatesFromServer().catch(function (err) {
|
|
455
531
|
Console.log(err);
|
|
532
|
+
}).then(function () {
|
|
533
|
+
if (round !== configRound) {
|
|
534
|
+
// stopServerSettingChecks() ran while this was in flight
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
configInFlight = false;
|
|
538
|
+
if (configAskAgain) {
|
|
539
|
+
configAskAgain = false;
|
|
540
|
+
refreshServerSettings();
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
// an answer without a usable next_check_after, or a failed call, waits getupdates_interval
|
|
544
|
+
configDueAt = _ZAP._nextConfigCheck > nowMs() ? _ZAP._nextConfigCheck : askedAt + getConfig('getupdates_interval'); // no i18n
|
|
545
|
+
scheduleServerSettingCheck();
|
|
456
546
|
});
|
|
457
547
|
}
|
|
548
|
+
/**
|
|
549
|
+
* getsdkconfig now, not at the next check: setUser registered a user, or getupdates reported a
|
|
550
|
+
* module changed.
|
|
551
|
+
*/
|
|
552
|
+
function askServerSettings() {
|
|
553
|
+
if (configInFlight) {
|
|
554
|
+
// the one in flight went out before the change: ask again once it answers
|
|
555
|
+
configAskAgain = true;
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
refreshServerSettings();
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Start-up's getsdkconfig. Asked on a first visit and on the first page load in each tab; any
|
|
562
|
+
* other load (a reload, a link to another page of the site, back/forward) uses the saved answer
|
|
563
|
+
* and waits for its next_check_after, unless that has already passed. Nothing happens if one has
|
|
564
|
+
* gone out already on this load (after device/add).
|
|
565
|
+
*/
|
|
566
|
+
function startServerSettingChecks() {
|
|
567
|
+
if (configAsked) {
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
if (tabHasAsked() && _ZAP._nextConfigCheck > nowMs()) {
|
|
571
|
+
Console.log('getsdkconfig: the saved answer is still current'); // no i18n
|
|
572
|
+
configAsked = true;
|
|
573
|
+
configDueAt = _ZAP._nextConfigCheck;
|
|
574
|
+
scheduleServerSettingCheck();
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
refreshServerSettings();
|
|
578
|
+
}
|
|
579
|
+
/** sessionStorage: per tab, and kept across a reload and the site's own links. */
|
|
580
|
+
var TAB_ASKED_KEY = '_apptics_sdkconfig_asked'; // no i18n
|
|
581
|
+
/** Whether getsdkconfig has gone out in this tab before, on an earlier page load. */
|
|
582
|
+
function tabHasAsked() {
|
|
583
|
+
try {
|
|
584
|
+
return sessionStorage.getItem(TAB_ASKED_KEY) === '1'; // no i18n
|
|
585
|
+
}
|
|
586
|
+
catch (e) {
|
|
587
|
+
return false; // no sessionStorage (private mode, sandboxed frame): every load asks
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
function markTabAsked() {
|
|
591
|
+
try {
|
|
592
|
+
sessionStorage.setItem(TAB_ASKED_KEY, '1'); // no i18n
|
|
593
|
+
}
|
|
594
|
+
catch (e) {
|
|
595
|
+
// as above: without it, every load asks
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
/** Sets the timer for the next getsdkconfig, at configDueAt. */
|
|
599
|
+
function scheduleServerSettingCheck() {
|
|
600
|
+
if (configTimer !== null) {
|
|
601
|
+
clearTimeout(configTimer);
|
|
602
|
+
}
|
|
603
|
+
var wait = Math.min(Math.max(configDueAt - nowMs(), 0), MAX_TIMEOUT);
|
|
604
|
+
Console.log('getsdkconfig: next check in ' + wait + ' ms'); // no i18n
|
|
605
|
+
configTimer = setTimeout(function () {
|
|
606
|
+
configTimer = null;
|
|
607
|
+
refreshServerSettings();
|
|
608
|
+
}, wait);
|
|
609
|
+
}
|
|
610
|
+
/** reset(): no more checks, and the next init() asks again straight away. */
|
|
611
|
+
function stopServerSettingChecks() {
|
|
612
|
+
if (configTimer !== null) {
|
|
613
|
+
clearTimeout(configTimer);
|
|
614
|
+
}
|
|
615
|
+
configTimer = null;
|
|
616
|
+
configRound++;
|
|
617
|
+
configInFlight = false;
|
|
618
|
+
configAsked = false;
|
|
619
|
+
configAskAgain = false;
|
|
620
|
+
configDueAt = 0;
|
|
621
|
+
}
|
|
458
622
|
hooks.updateDevice = updateDeviceWithApptics;
|
|
459
623
|
hooks.refreshDeviceInfo = checkAndUpdateDeviceInfo;
|
|
624
|
+
hooks.askServerSettings = askServerSettings;
|
|
460
625
|
|
|
461
|
-
export { addOrUpdateDeviceID, checkAndUpdateDeviceInfo, deviceReady, getUpdatesFromServer, needsDevice, prepareDevice, refreshServerSettings, registerDeviceWithApptics, restoreServerSettings, updateDeviceWithApptics };
|
|
626
|
+
export { addOrUpdateDeviceID, checkAndUpdateDeviceInfo, deviceReady, getUpdatesFromServer, needsDevice, nextCheckTime, prepareDevice, refreshServerSettings, registerDeviceWithApptics, restoreServerSettings, startServerSettingChecks, stopServerSettingChecks, updateDeviceWithApptics };
|