@zoho_apptics/apptics-js-sdk 2.0.0-beta → 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 +191 -21
- package/README.md +519 -333
- 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 +2 -2
- package/dist/cjs/core/consent.d.ts +18 -4
- package/dist/cjs/core/consent.js +31 -15
- package/dist/cjs/core/constants.d.ts +57 -27
- package/dist/cjs/core/constants.js +52 -33
- package/dist/cjs/core/db.d.ts +12 -4
- package/dist/cjs/core/db.js +167 -34
- 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.d.ts +9 -0
- package/dist/cjs/core/guard.js +27 -13
- package/dist/cjs/core/hooks.d.ts +7 -4
- package/dist/cjs/core/hooks.js +3 -3
- package/dist/cjs/core/locks.d.ts +9 -0
- package/dist/cjs/core/locks.js +22 -0
- package/dist/cjs/core/logger.d.ts +3 -4
- package/dist/cjs/core/logger.js +4 -40
- package/dist/cjs/core/state.d.ts +9 -6
- package/dist/cjs/core/state.js +3 -5
- package/dist/cjs/core/storage.d.ts +20 -5
- package/dist/cjs/core/storage.js +115 -20
- package/dist/cjs/core/stylesheet.d.ts +8 -0
- package/dist/cjs/core/stylesheet.js +29 -0
- package/dist/cjs/core/transport.d.ts +2 -0
- package/dist/cjs/core/transport.js +30 -18
- package/dist/cjs/core/utils.js +1 -1
- package/dist/cjs/core/validate.js +2 -2
- package/dist/cjs/device/appversion.d.ts +10 -6
- package/dist/cjs/device/appversion.js +38 -3
- package/dist/cjs/device/index.d.ts +28 -2
- package/dist/cjs/device/index.js +312 -44
- package/dist/cjs/engagement/api-rules.d.ts +32 -67
- package/dist/cjs/engagement/api-rules.js +144 -157
- package/dist/cjs/engagement/auto-api.js +2 -2
- package/dist/cjs/engagement/auto-screen.d.ts +2 -0
- package/dist/cjs/engagement/auto-screen.js +67 -3
- package/dist/cjs/engagement/defined-events.js +1 -1
- package/dist/cjs/engagement/send.js +12 -3
- package/dist/cjs/engagement/session.d.ts +29 -3
- package/dist/cjs/engagement/session.js +253 -26
- package/dist/cjs/engagement/track.d.ts +4 -4
- package/dist/cjs/engagement/track.js +58 -30
- package/dist/cjs/errors/send.js +2 -2
- package/dist/cjs/errors/track.d.ts +2 -1
- package/dist/cjs/errors/track.js +49 -7
- package/dist/cjs/feedback/controls.d.ts +12 -0
- package/dist/cjs/feedback/controls.js +104 -25
- package/dist/cjs/feedback/index.d.ts +8 -7
- package/dist/cjs/feedback/index.js +32 -13
- package/dist/cjs/feedback/logs.d.ts +13 -11
- package/dist/cjs/feedback/logs.js +57 -28
- package/dist/cjs/feedback/quartz.d.ts +18 -0
- package/dist/cjs/feedback/quartz.js +105 -0
- package/dist/cjs/feedback/send.d.ts +5 -2
- package/dist/cjs/feedback/send.js +30 -28
- package/dist/cjs/feedback/styles.d.ts +10 -0
- package/dist/cjs/feedback/styles.js +8 -0
- package/dist/cjs/feedback/template.d.ts +1 -1
- package/dist/cjs/feedback/template.js +20 -12
- package/dist/cjs/feedback/ui.d.ts +21 -6
- package/dist/cjs/feedback/ui.js +283 -70
- package/dist/cjs/heatmap/send.d.ts +2 -0
- package/dist/cjs/heatmap/send.js +3 -5
- package/dist/cjs/heatmap/track.d.ts +1 -1
- package/dist/cjs/heatmap/track.js +87 -16
- package/dist/cjs/index.d.ts +16 -63
- package/dist/cjs/index.js +144 -95
- package/dist/cjs/lifecycle.d.ts +21 -3
- package/dist/cjs/lifecycle.js +353 -89
- package/dist/cjs/remoteconfig/country.d.ts +4 -0
- package/dist/cjs/remoteconfig/country.js +73 -0
- package/dist/cjs/remoteconfig/custom.d.ts +7 -7
- package/dist/cjs/remoteconfig/custom.js +31 -51
- package/dist/cjs/remoteconfig/evaluate.d.ts +3 -3
- package/dist/cjs/remoteconfig/evaluate.js +56 -43
- package/dist/cjs/remoteconfig/fetch.d.ts +16 -9
- package/dist/cjs/remoteconfig/fetch.js +120 -39
- package/dist/cjs/remoteconfig/index.d.ts +19 -8
- package/dist/cjs/remoteconfig/index.js +81 -39
- package/dist/cjs/remoteconfig/store.d.ts +15 -7
- package/dist/cjs/remoteconfig/store.js +68 -35
- package/dist/cjs/remoteconfig/tz-countries.d.ts +8 -0
- package/dist/cjs/remoteconfig/tz-countries.js +13 -0
- package/dist/{esm/core → cjs/remotelog}/callsite.d.ts +11 -4
- package/dist/cjs/{core → remotelog}/callsite.js +30 -7
- package/dist/cjs/remotelog/gate.d.ts +2 -11
- package/dist/cjs/remotelog/gate.js +9 -35
- package/dist/cjs/remotelog/index.d.ts +4 -21
- package/dist/cjs/remotelog/logger.d.ts +11 -17
- package/dist/cjs/remotelog/logger.js +31 -59
- package/dist/cjs/remotelog/send.js +11 -11
- package/dist/cjs/remotelogger/index.d.ts +12 -0
- package/dist/cjs/remotelogger/index.js +18 -0
- package/dist/cjs/scheduler.d.ts +3 -1
- package/dist/cjs/scheduler.js +25 -22
- package/dist/cjs/types.d.ts +208 -90
- package/dist/cjs/user/index.js +16 -7
- package/dist/esm/core/attempts.js +1 -1
- package/dist/esm/core/batch.js +2 -2
- package/dist/esm/core/consent.d.ts +18 -4
- package/dist/esm/core/consent.js +32 -17
- package/dist/esm/core/constants.d.ts +57 -27
- package/dist/esm/core/constants.js +51 -33
- package/dist/esm/core/db.d.ts +12 -4
- package/dist/esm/core/db.js +164 -35
- 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.d.ts +9 -0
- package/dist/esm/core/guard.js +27 -14
- package/dist/esm/core/hooks.d.ts +7 -4
- package/dist/esm/core/hooks.js +3 -3
- package/dist/esm/core/locks.d.ts +9 -0
- package/dist/esm/core/locks.js +20 -0
- package/dist/esm/core/logger.d.ts +3 -4
- package/dist/esm/core/logger.js +4 -40
- package/dist/esm/core/state.d.ts +9 -6
- package/dist/esm/core/state.js +3 -5
- package/dist/esm/core/storage.d.ts +20 -5
- package/dist/esm/core/storage.js +113 -21
- package/dist/esm/core/stylesheet.d.ts +8 -0
- package/dist/esm/core/stylesheet.js +27 -0
- package/dist/esm/core/transport.d.ts +2 -0
- package/dist/esm/core/transport.js +30 -19
- package/dist/esm/core/utils.js +1 -1
- package/dist/esm/core/validate.js +2 -2
- package/dist/esm/device/appversion.d.ts +10 -6
- package/dist/esm/device/appversion.js +37 -4
- package/dist/esm/device/index.d.ts +28 -2
- package/dist/esm/device/index.js +313 -49
- package/dist/esm/engagement/api-rules.d.ts +32 -67
- package/dist/esm/engagement/api-rules.js +143 -155
- package/dist/esm/engagement/auto-api.js +3 -3
- package/dist/esm/engagement/auto-screen.d.ts +2 -0
- package/dist/esm/engagement/auto-screen.js +67 -4
- package/dist/esm/engagement/defined-events.js +1 -1
- package/dist/esm/engagement/send.js +12 -3
- package/dist/esm/engagement/session.d.ts +29 -3
- package/dist/esm/engagement/session.js +251 -30
- package/dist/esm/engagement/track.d.ts +4 -4
- package/dist/esm/engagement/track.js +65 -37
- package/dist/esm/errors/send.js +2 -2
- package/dist/esm/errors/track.d.ts +2 -1
- package/dist/esm/errors/track.js +49 -7
- package/dist/esm/feedback/controls.d.ts +12 -0
- package/dist/esm/feedback/controls.js +103 -26
- package/dist/esm/feedback/index.d.ts +8 -7
- package/dist/esm/feedback/index.js +34 -13
- package/dist/esm/feedback/logs.d.ts +13 -11
- package/dist/esm/feedback/logs.js +59 -30
- package/dist/esm/feedback/quartz.d.ts +18 -0
- package/dist/esm/feedback/quartz.js +99 -0
- package/dist/esm/feedback/send.d.ts +5 -2
- package/dist/esm/feedback/send.js +31 -31
- package/dist/esm/feedback/styles.d.ts +10 -0
- package/dist/esm/feedback/styles.js +4 -0
- package/dist/esm/feedback/template.d.ts +1 -1
- package/dist/esm/feedback/template.js +20 -12
- package/dist/esm/feedback/ui.d.ts +21 -6
- package/dist/esm/feedback/ui.js +283 -71
- package/dist/esm/heatmap/send.d.ts +2 -0
- package/dist/esm/heatmap/send.js +3 -5
- package/dist/esm/heatmap/track.d.ts +1 -1
- package/dist/esm/heatmap/track.js +87 -16
- package/dist/esm/index.d.ts +16 -63
- package/dist/esm/index.js +148 -83
- package/dist/esm/lifecycle.d.ts +21 -3
- package/dist/esm/lifecycle.js +359 -98
- package/dist/esm/remoteconfig/country.d.ts +4 -0
- package/dist/esm/remoteconfig/country.js +70 -0
- package/dist/esm/remoteconfig/custom.d.ts +7 -7
- package/dist/esm/remoteconfig/custom.js +32 -52
- package/dist/esm/remoteconfig/evaluate.d.ts +3 -3
- package/dist/esm/remoteconfig/evaluate.js +57 -44
- package/dist/esm/remoteconfig/fetch.d.ts +16 -9
- package/dist/esm/remoteconfig/fetch.js +120 -39
- package/dist/esm/remoteconfig/index.d.ts +19 -8
- package/dist/esm/remoteconfig/index.js +82 -40
- package/dist/esm/remoteconfig/store.d.ts +15 -7
- package/dist/esm/remoteconfig/store.js +68 -36
- package/dist/esm/remoteconfig/tz-countries.d.ts +8 -0
- package/dist/esm/remoteconfig/tz-countries.js +11 -0
- package/dist/{cjs/core → esm/remotelog}/callsite.d.ts +11 -4
- package/dist/esm/{core → remotelog}/callsite.js +30 -8
- package/dist/esm/remotelog/gate.d.ts +2 -11
- package/dist/esm/remotelog/gate.js +10 -32
- package/dist/esm/remotelog/index.d.ts +4 -21
- package/dist/esm/remotelog/logger.d.ts +11 -17
- package/dist/esm/remotelog/logger.js +33 -61
- package/dist/esm/remotelog/send.js +13 -13
- package/dist/esm/remotelogger/index.d.ts +12 -0
- package/dist/esm/remotelogger/index.js +13 -0
- package/dist/esm/scheduler.d.ts +3 -1
- package/dist/esm/scheduler.js +26 -24
- package/dist/esm/types.d.ts +208 -90
- package/dist/esm/user/index.js +18 -8
- 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 +16 -17
- package/dist/chunks/batch-BU_mTpm1.min.js +0 -3
- package/dist/chunks/batch-BU_mTpm1.min.js.map +0 -1
- package/dist/chunks/logs-Bea5zUW_.min.js +0 -3
- package/dist/chunks/logs-Bea5zUW_.min.js.map +0 -1
- package/dist/cjs/auto-init.d.ts +0 -8
- package/dist/cjs/auto-init.js +0 -32
- package/dist/cjs/heatmap/index.d.ts +0 -16
- package/dist/cjs/heatmap/index.js +0 -22
- package/dist/cjs/remotelog/index.js +0 -55
- package/dist/esm/auto-init.d.ts +0 -8
- package/dist/esm/auto-init.js +0 -29
- package/dist/esm/heatmap/index.d.ts +0 -16
- package/dist/esm/heatmap/index.js +0 -17
- package/dist/esm/remotelog/index.js +0 -51
- package/dist/heatmap.esm.min.js +0 -3
- package/dist/heatmap.esm.min.js.map +0 -1
- package/dist/style.css +0 -1
|
@@ -1,219 +1,206 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
var logger = require('../core/logger.js');
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
|
-
*
|
|
7
|
+
* Which API calls are recorded, and under what name: Android's AppticsApiTracker.configure, built
|
|
6
8
|
* with ApiTrackingBuilder the way user properties are built with UserBuilder:
|
|
7
9
|
*
|
|
8
10
|
* configureApiTracking(new ApiTrackingBuilder()
|
|
9
|
-
* .
|
|
10
|
-
* .
|
|
11
|
-
* .
|
|
12
|
-
* .addPattern('/v2/catalog/{categoryId}/items/{itemId}')
|
|
11
|
+
* .allowRegex(/^https:\/\/api\.zylker\.(com|in)\//)
|
|
12
|
+
* .ignoreEquals('https://api.zylker.com/health')
|
|
13
|
+
* .ignoreRegex(/\/internal\//)
|
|
13
14
|
* .build());
|
|
14
15
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* Four rules, two kinds by two: an exact URL (equals) or a regular expression (regex), to allow or
|
|
17
|
+
* to ignore. Each is tried on the call's URL as `scheme://host[:port]/path`, with its query and
|
|
18
|
+
* fragment removed, so one rule can name a host, a path or a single endpoint. Ignore rules are
|
|
19
|
+
* tried first and always win; then, when there are allow rules, a call must match one of them.
|
|
20
|
+
*
|
|
21
|
+
* The name a call is recorded under is not configured: the query goes, and numeric ids, UUIDs and
|
|
22
|
+
* JWTs in its path become `*`, so `/users/42/orders` and `/users/43/orders` are one endpoint.
|
|
20
23
|
*
|
|
21
24
|
* Both apply to every call, the ones the fetch/XHR wrappers catch and the ones the app reports
|
|
22
|
-
* with
|
|
25
|
+
* with startTrackApi(), so one set of rules decides what the API page shows.
|
|
23
26
|
*/
|
|
24
27
|
function emptyConfig() {
|
|
25
|
-
return {
|
|
26
|
-
ignoreDomains: [], allowOnlyDomains: [], allowOnlyTLDs: [], ignoreTLDs: [],
|
|
27
|
-
ignoreDomainPrefixes: [], ignoreDomainSuffixes: [], groupDomains: [], ignoreEndpoints: [],
|
|
28
|
-
patterns: [], preserveSegments: [], autoDetection: true,
|
|
29
|
-
};
|
|
28
|
+
return { allowEquals: [], ignoreEquals: [], allowRegex: [], ignoreRegex: [] };
|
|
30
29
|
}
|
|
31
|
-
/**
|
|
32
|
-
|
|
30
|
+
/**
|
|
31
|
+
* A URL as the rules compare it: `scheme://host[:port]/path`, the scheme and host lower-cased,
|
|
32
|
+
* the default port dropped, the query, fragment and a trailing slash removed. '' when it is not
|
|
33
|
+
* an absolute http(s) URL.
|
|
34
|
+
*/
|
|
35
|
+
function ruleUrl(raw) {
|
|
36
|
+
try {
|
|
37
|
+
var url = new URL(String(raw).trim());
|
|
38
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:') { // no i18n
|
|
39
|
+
return ''; // no i18n
|
|
40
|
+
}
|
|
41
|
+
var path = url.pathname.length > 1 ? url.pathname.replace(/\/+$/, '') : url.pathname; // no i18n
|
|
42
|
+
return url.protocol + '//' + url.host.toLowerCase() + path; // no i18n
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
return ''; // no i18n
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** The exact URLs given, as rules compare them; anything that is not an absolute URL is refused, and said. */
|
|
49
|
+
function cleanUrls(method, values) {
|
|
33
50
|
var out = [];
|
|
34
51
|
values.forEach(function (value) {
|
|
35
|
-
|
|
52
|
+
var url = typeof value === 'string' ? ruleUrl(value) : ''; // no i18n
|
|
53
|
+
if (url === '') { // no i18n
|
|
54
|
+
logger.warnAlways('ApiTrackingBuilder.' + method + ': ' + JSON.stringify(value) + ' is not a full http(s) URL, as https://api.example.com/health, and is left out'); // no i18n
|
|
36
55
|
return;
|
|
37
56
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
out.push(lower ? one.toLowerCase() : one);
|
|
57
|
+
if (out.indexOf(url) === -1) {
|
|
58
|
+
out.push(url);
|
|
41
59
|
}
|
|
42
60
|
});
|
|
43
61
|
return out;
|
|
44
62
|
}
|
|
45
|
-
/**
|
|
46
|
-
function
|
|
47
|
-
|
|
63
|
+
/** The regular expressions given, a RegExp or its source as a string; an invalid one is refused, and said. */
|
|
64
|
+
function cleanRegexes(method, values) {
|
|
65
|
+
var out = [];
|
|
66
|
+
values.forEach(function (value) {
|
|
67
|
+
if (value instanceof RegExp) {
|
|
68
|
+
out.push(value);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (typeof value === 'string' && value !== '') { // no i18n
|
|
72
|
+
try {
|
|
73
|
+
out.push(new RegExp(value));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
// falls through to the warning
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
logger.warnAlways('ApiTrackingBuilder.' + method + ': ' + String(value) + ' is not a regular expression, and is left out'); // no i18n
|
|
81
|
+
});
|
|
82
|
+
return out;
|
|
48
83
|
}
|
|
49
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* Builds the rules configure takes. Each method may be called more than once, and takes any number
|
|
86
|
+
* of values: `new ApiTrackingBuilder().allowEquals(a, b).ignoreRegex(/x/).build()`.
|
|
87
|
+
*/
|
|
50
88
|
class ApiTrackingBuilder {
|
|
51
89
|
constructor() {
|
|
52
90
|
this.rules = emptyConfig();
|
|
53
91
|
}
|
|
54
|
-
/**
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
|
|
58
|
-
/** Records only
|
|
59
|
-
|
|
60
|
-
/** Never records
|
|
61
|
-
|
|
62
|
-
/** Never records hosts starting with these, e.g. `dev.`. */
|
|
63
|
-
ignoreDomainPrefixes(...prefixes) { this.rules.ignoreDomainPrefixes.push(...cleanList(prefixes, true)); return this; }
|
|
64
|
-
/** Never records hosts ending with these, e.g. `.cdn.net`. */
|
|
65
|
-
ignoreDomainSuffixes(...suffixes) { this.rules.ignoreDomainSuffixes.push(...cleanList(suffixes, true)); return this; }
|
|
66
|
-
/** Records the hosts a pattern such as `api.myapp.*` matches under that one name. */
|
|
67
|
-
groupDomains(...patterns) { this.rules.groupDomains.push(...cleanList(patterns, true)); return this; }
|
|
68
|
-
/** Never records these paths: exact, `*` or `{name}` for one segment, `**` at the end for a prefix. */
|
|
69
|
-
ignoreEndpoint(...paths) { this.rules.ignoreEndpoints.push(...cleanList(paths, false)); return this; }
|
|
70
|
-
/** Records a path this pattern matches as the pattern, with each `{name}` as `*`. Tried before auto-detection. */
|
|
71
|
-
addPattern(...patterns) { this.rules.patterns.push(...cleanList(patterns, false)); return this; }
|
|
72
|
-
/** Segments never turned into `*`, e.g. `v1` or `404`. */
|
|
73
|
-
preserveSegments(...segments) { this.rules.preserveSegments.push(...cleanList(segments, false)); return this; }
|
|
74
|
-
/** `false`: only addPattern paths are normalized; every other path is recorded as it is. */
|
|
75
|
-
autoDetection(enabled) { this.rules.autoDetection = enabled !== false; return this; }
|
|
92
|
+
/** Records only these URLs (and those any allowRegex matches): `https://api.example.com/orders`. */
|
|
93
|
+
allowEquals(...urls) { this.rules.allowEquals.push(...cleanUrls('allowEquals', urls)); return this; }
|
|
94
|
+
/** Never records these URLs: `https://api.example.com/health`. */
|
|
95
|
+
ignoreEquals(...urls) { this.rules.ignoreEquals.push(...cleanUrls('ignoreEquals', urls)); return this; }
|
|
96
|
+
/** Records only URLs these match (and those any allowEquals names): `/^https:\/\/api\.example\.com\//`. */
|
|
97
|
+
allowRegex(...patterns) { this.rules.allowRegex.push(...cleanRegexes('allowRegex', patterns)); return this; }
|
|
98
|
+
/** Never records URLs these match: `/\/internal\//`. */
|
|
99
|
+
ignoreRegex(...patterns) { this.rules.ignoreRegex.push(...cleanRegexes('ignoreRegex', patterns)); return this; }
|
|
76
100
|
build() {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
101
|
+
return {
|
|
102
|
+
allowEquals: this.rules.allowEquals.slice(),
|
|
103
|
+
ignoreEquals: this.rules.ignoreEquals.slice(),
|
|
104
|
+
allowRegex: this.rules.allowRegex.slice(),
|
|
105
|
+
ignoreRegex: this.rules.ignoreRegex.slice(),
|
|
106
|
+
};
|
|
83
107
|
}
|
|
84
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* 2.0.0-beta's builder methods, now gone. Called, each throws a TypeError that names what to use
|
|
111
|
+
* instead: a rule silently missing would record what the app meant to leave out.
|
|
112
|
+
*/
|
|
113
|
+
const RETIRED_METHODS = Object.freeze({
|
|
114
|
+
ignoreDomains: 'ignoreRegex', // no i18n
|
|
115
|
+
allowOnlyDomains: 'allowRegex', // no i18n
|
|
116
|
+
allowOnlyTLDs: 'allowRegex', // no i18n
|
|
117
|
+
ignoreTLDs: 'ignoreRegex', // no i18n
|
|
118
|
+
ignoreDomainPrefixes: 'ignoreRegex', // no i18n
|
|
119
|
+
ignoreDomainSuffixes: 'ignoreRegex', // no i18n
|
|
120
|
+
groupDomains: '', // no i18n
|
|
121
|
+
ignoreEndpoint: 'ignoreEquals or ignoreRegex', // no i18n
|
|
122
|
+
addPattern: '', // no i18n
|
|
123
|
+
preserveSegments: '', // no i18n
|
|
124
|
+
autoDetection: '', // no i18n
|
|
125
|
+
});
|
|
126
|
+
Object.keys(RETIRED_METHODS).forEach(function (name) {
|
|
127
|
+
Object.defineProperty(ApiTrackingBuilder.prototype, name, {
|
|
128
|
+
configurable: true,
|
|
129
|
+
value: function () {
|
|
130
|
+
var instead = RETIRED_METHODS[name];
|
|
131
|
+
throw new TypeError('ApiTrackingBuilder.' + name + '() is no longer supported: ' // no i18n
|
|
132
|
+
+ (instead ? 'use ' + instead + ', which match the URL without its query' : 'ids, UUIDs and tokens in a path become * on their own')); // no i18n
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
});
|
|
85
136
|
var current = emptyConfig();
|
|
137
|
+
/** The values of `list` that are of the kind `keep` accepts. */
|
|
138
|
+
function listOf(value, keep) {
|
|
139
|
+
return Array.isArray(value) ? value.filter(keep) : [];
|
|
140
|
+
}
|
|
86
141
|
/**
|
|
87
142
|
* Applies the rules, replacing any given before. Takes what build() returned, or the builder
|
|
88
143
|
* itself. Call it once, before the requests it should cover; it works before init().
|
|
89
144
|
*/
|
|
90
145
|
function configureApiTracking(config) {
|
|
91
|
-
var built = config instanceof ApiTrackingBuilder ? config.build() : config;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
var value = built[key];
|
|
96
|
-
if (key === 'autoDetection') { // no i18n
|
|
97
|
-
next.autoDetection = value !== false;
|
|
98
|
-
}
|
|
99
|
-
else if (Array.isArray(value)) {
|
|
100
|
-
next[key] = value.slice();
|
|
101
|
-
}
|
|
102
|
-
});
|
|
146
|
+
var built = (config instanceof ApiTrackingBuilder ? config.build() : config);
|
|
147
|
+
if (!built || typeof built !== 'object') { // no i18n
|
|
148
|
+
current = emptyConfig();
|
|
149
|
+
return;
|
|
103
150
|
}
|
|
104
|
-
|
|
151
|
+
var isString = function (one) { return typeof one === 'string'; }; // no i18n
|
|
152
|
+
var isRegExp = function (one) { return one instanceof RegExp; };
|
|
153
|
+
current = {
|
|
154
|
+
// a hand-written object gets the same clean-up the builder gives
|
|
155
|
+
allowEquals: cleanUrls('allowEquals', listOf(built.allowEquals, isString)), // no i18n
|
|
156
|
+
ignoreEquals: cleanUrls('ignoreEquals', listOf(built.ignoreEquals, isString)), // no i18n
|
|
157
|
+
allowRegex: listOf(built.allowRegex, isRegExp).concat(cleanRegexes('allowRegex', listOf(built.allowRegex, isString))), // no i18n
|
|
158
|
+
ignoreRegex: listOf(built.ignoreRegex, isRegExp).concat(cleanRegexes('ignoreRegex', listOf(built.ignoreRegex, isString))), // no i18n
|
|
159
|
+
};
|
|
105
160
|
}
|
|
106
|
-
|
|
107
|
-
function
|
|
108
|
-
|
|
161
|
+
/** Whether a regular expression matches, whatever its flags: a /g one keeps a position between tests. */
|
|
162
|
+
function regexMatches(re, url) {
|
|
163
|
+
re.lastIndex = 0;
|
|
164
|
+
return re.test(url);
|
|
109
165
|
}
|
|
110
|
-
/**
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
if (current.allowOnlyDomains.length > 0 && current.allowOnlyDomains.indexOf(host) === -1) {
|
|
166
|
+
/**
|
|
167
|
+
* Whether a call to `url` is recorded. Ignore rules are tried first and always win; then, when
|
|
168
|
+
* there are allow rules, the URL must match one. A URL that cannot be read is not recorded.
|
|
169
|
+
*/
|
|
170
|
+
function urlTracked(url) {
|
|
171
|
+
var target = ruleUrl(url);
|
|
172
|
+
if (target === '') { // no i18n
|
|
120
173
|
return false;
|
|
121
174
|
}
|
|
122
|
-
if (current.
|
|
175
|
+
if (current.ignoreEquals.indexOf(target) !== -1 || current.ignoreRegex.some(function (re) { return regexMatches(re, target); })) {
|
|
123
176
|
return false;
|
|
124
177
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
function wildcardHost(pattern) {
|
|
128
|
-
var source = pattern.split('*').map(function (part) {
|
|
129
|
-
return part.replace(/[.+?^${}()|[\]\\]/g, '\\$&'); // no i18n
|
|
130
|
-
}).join('[a-z0-9.-]+'); // no i18n
|
|
131
|
-
return new RegExp('^' + source + '$'); // no i18n
|
|
132
|
-
}
|
|
133
|
-
/** The name a host is recorded under: the first groupDomains pattern it matches, or itself. */
|
|
134
|
-
function groupedHost(hostname) {
|
|
135
|
-
var host = String(hostname || '').toLowerCase(); // no i18n
|
|
136
|
-
for (var i = 0; i < current.groupDomains.length; i++) {
|
|
137
|
-
var pattern = current.groupDomains[i];
|
|
138
|
-
if (pattern.indexOf('*') !== -1 && wildcardHost(pattern).test(host)) { // no i18n
|
|
139
|
-
return pattern;
|
|
140
|
-
}
|
|
178
|
+
if (current.allowEquals.length === 0 && current.allowRegex.length === 0) {
|
|
179
|
+
return true;
|
|
141
180
|
}
|
|
142
|
-
return
|
|
181
|
+
return current.allowEquals.indexOf(target) !== -1 || current.allowRegex.some(function (re) { return regexMatches(re, target); });
|
|
143
182
|
}
|
|
144
|
-
/* ----------------
|
|
183
|
+
/* ---------------- the name a call is recorded under ---------------- */
|
|
145
184
|
/** The path without its query string or fragment, which is where ids and tokens travel. */
|
|
146
185
|
function withoutQuery(path) {
|
|
147
186
|
var cut = String(path || '').split(/[?#]/)[0]; // no i18n
|
|
148
187
|
return cut === '' ? '/' : cut; // no i18n
|
|
149
188
|
}
|
|
150
|
-
function segmentsOf(path) {
|
|
151
|
-
var trimmed = path.length > 1 ? path.replace(/\/+$/, '') : path; // no i18n
|
|
152
|
-
return trimmed.split('/').slice(1); // no i18n
|
|
153
|
-
}
|
|
154
|
-
const ONE_SEGMENT = /^(\*|\{[^/{}]*\})$/;
|
|
155
|
-
/** Whether a path matches a pattern: `*` and `{name}` are one segment, a final `**` is the rest. */
|
|
156
|
-
function matches(pattern, path) {
|
|
157
|
-
var want = segmentsOf(pattern);
|
|
158
|
-
var have = segmentsOf(path);
|
|
159
|
-
for (var i = 0; i < want.length; i++) {
|
|
160
|
-
var part = want[i];
|
|
161
|
-
if (part === '**' && i === want.length - 1) { // no i18n
|
|
162
|
-
return true;
|
|
163
|
-
}
|
|
164
|
-
if (i >= have.length) {
|
|
165
|
-
return false;
|
|
166
|
-
}
|
|
167
|
-
if (ONE_SEGMENT.test(part)) {
|
|
168
|
-
if (have[i] === '') { // no i18n
|
|
169
|
-
return false;
|
|
170
|
-
}
|
|
171
|
-
continue;
|
|
172
|
-
}
|
|
173
|
-
if (part !== have[i]) {
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
return want.length === have.length;
|
|
178
|
-
}
|
|
179
|
-
/** Whether ignoreEndpoint leaves this path out. Matched on the path as called, query removed. */
|
|
180
|
-
function endpointIgnored(path) {
|
|
181
|
-
var bare = withoutQuery(path);
|
|
182
|
-
return current.ignoreEndpoints.some(function (pattern) { return matches(pattern, bare); });
|
|
183
|
-
}
|
|
184
189
|
const NUMERIC = /^\d+$/;
|
|
185
190
|
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
186
191
|
// three base64url parts, the first starting eyJ — the encoding of '{"' every JWT header opens
|
|
187
192
|
// with. Without that start, a file name such as jquery.min.js would pass for a token
|
|
188
193
|
const JWT = /^eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
|
|
189
|
-
/**
|
|
190
|
-
* The path a call is recorded under. The query goes; then the first addPattern that matches is
|
|
191
|
-
* used, with each `{name}` as `*` (the server's path rule has no room for braces); otherwise, with
|
|
192
|
-
* autoDetection on, numeric ids, UUIDs and JWTs become `*`, except preserveSegments.
|
|
193
|
-
*/
|
|
194
|
+
/** The path a call is recorded under: the query goes, and numeric ids, UUIDs and JWTs become `*`. */
|
|
194
195
|
function normalizeApiPath(path) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
var pattern = current.patterns[i];
|
|
198
|
-
if (matches(pattern, bare)) {
|
|
199
|
-
return pattern.replace(/\{[^/{}]*\}/g, '*'); // no i18n
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
if (!current.autoDetection) {
|
|
203
|
-
return bare;
|
|
204
|
-
}
|
|
205
|
-
return bare.split('/').map(function (segment) {
|
|
206
|
-
if (segment === '' || current.preserveSegments.indexOf(segment) !== -1) { // no i18n
|
|
207
|
-
return segment;
|
|
208
|
-
}
|
|
209
|
-
return NUMERIC.test(segment) || UUID.test(segment) || JWT.test(segment) ? '*' : segment; // no i18n
|
|
196
|
+
return withoutQuery(path).split('/').map(function (segment) {
|
|
197
|
+
return segment !== '' && (NUMERIC.test(segment) || UUID.test(segment) || JWT.test(segment)) ? '*' : segment; // no i18n
|
|
210
198
|
}).join('/'); // no i18n
|
|
211
199
|
}
|
|
212
200
|
|
|
213
201
|
exports.ApiTrackingBuilder = ApiTrackingBuilder;
|
|
214
202
|
exports.configureApiTracking = configureApiTracking;
|
|
215
|
-
exports.endpointIgnored = endpointIgnored;
|
|
216
|
-
exports.groupedHost = groupedHost;
|
|
217
|
-
exports.hostAllowed = hostAllowed;
|
|
218
203
|
exports.normalizeApiPath = normalizeApiPath;
|
|
204
|
+
exports.ruleUrl = ruleUrl;
|
|
205
|
+
exports.urlTracked = urlTracked;
|
|
219
206
|
exports.withoutQuery = withoutQuery;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var state = require('../core/state.js');
|
|
@@ -66,7 +66,7 @@ function shouldTrack(rawUrl) {
|
|
|
66
66
|
}
|
|
67
67
|
// configureApiTracking's rules: checked here too so a call left out is not even timed. trackApi checks them again, for the
|
|
68
68
|
// calls an app reports itself
|
|
69
|
-
return apiRules.
|
|
69
|
+
return apiRules.urlTracked(absolute.href);
|
|
70
70
|
}
|
|
71
71
|
/** One finished call. Never throws: a tracking failure must not surface in the app's call. */
|
|
72
72
|
function record(method, url, starttime, responsecode, responsemessage) {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** A path as screen_routes compares it: no query or fragment, no trailing slash but on the root. */
|
|
2
|
+
export declare function routePath(path: string): string;
|
|
1
3
|
/**
|
|
2
4
|
* Starts or stops automatic screen tracking. Starting records the screen the page is on, unless
|
|
3
5
|
* the app has already called inScreen() for it. Safe to call repeatedly: wrapping history twice
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var logger = require('../core/logger.js');
|
|
@@ -32,9 +32,14 @@ var track = require('./track.js');
|
|
|
32
32
|
* On by default: most apps never call inScreen() themselves, and a screen-less session says
|
|
33
33
|
* little. An app that wants only its own calls sets `track_screen: false`.
|
|
34
34
|
*/
|
|
35
|
+
/** A path as screen_routes compares it: no query or fragment, no trailing slash but on the root. */
|
|
36
|
+
function routePath(path) {
|
|
37
|
+
var bare = String(path || '').split(/[?#]/)[0] || '/'; // no i18n
|
|
38
|
+
return bare.length > 1 ? bare.replace(/\/+$/, '') : bare; // no i18n
|
|
39
|
+
}
|
|
35
40
|
/** The most a screen name may be, and the characters it may hold (see validateScreenName). */
|
|
36
41
|
const NAME_MAX = 99;
|
|
37
|
-
const NAME_DISALLOWED = /[^\w\s
|
|
42
|
+
const NAME_DISALLOWED = /[^\w\s.\-&/:*]/g;
|
|
38
43
|
/** How long an automatic view waits for the app's own inScreen() of the same navigation. */
|
|
39
44
|
const SETTLE_MS = 300;
|
|
40
45
|
var installed = false;
|
|
@@ -82,13 +87,61 @@ function cleanName(raw) {
|
|
|
82
87
|
}
|
|
83
88
|
return name.replace(NAME_DISALLOWED, '_').trim().slice(0, NAME_MAX); // no i18n
|
|
84
89
|
}
|
|
90
|
+
/** Whether a pattern segment is a wildcard: `{id}`, `:id` or `*`. */
|
|
91
|
+
function isWildcard(segment) {
|
|
92
|
+
return segment === '*' || /^\{[^/]*\}$/.test(segment) || /^:[^/]+$/.test(segment); // no i18n
|
|
93
|
+
}
|
|
94
|
+
/** Whether a route pattern matches a path: every segment, `{id}`, `:id` and `*` matching any one. */
|
|
95
|
+
function patternMatches(pattern, path) {
|
|
96
|
+
var segments = routePath(pattern).split('/'); // no i18n
|
|
97
|
+
var actual = path.split('/'); // no i18n
|
|
98
|
+
if (segments.length !== actual.length) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
for (var j = 0; j < segments.length; j++) {
|
|
102
|
+
var seg = segments[j];
|
|
103
|
+
if (!isWildcard(seg) && seg !== actual[j]) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The name screen_routes gives a path, or the path itself when no entry matches. Tried in order:
|
|
111
|
+
* a route pattern records the path with its variable segments as `*` (`/users/{id}/orders`
|
|
112
|
+
* claims `/users/1/orders`, not `/users/1/orders/2`); an exact path or a regular expression
|
|
113
|
+
* records the name the entry gives. Matched on the path without its query.
|
|
114
|
+
*/
|
|
115
|
+
function applyRoutes(path) {
|
|
116
|
+
var routes = state._ZAP._config.screen_routes;
|
|
117
|
+
if (!routes || routes.length === 0) {
|
|
118
|
+
return path;
|
|
119
|
+
}
|
|
120
|
+
var bare = routePath(path);
|
|
121
|
+
for (var i = 0; i < routes.length; i++) {
|
|
122
|
+
var route = routes[i];
|
|
123
|
+
if (route.kind === 'equals' && route.path === bare) { // no i18n
|
|
124
|
+
return route.name;
|
|
125
|
+
}
|
|
126
|
+
if (route.kind === 'regex') { // no i18n
|
|
127
|
+
route.regex.lastIndex = 0; // a /g regular expression keeps a position between tests
|
|
128
|
+
if (route.regex.test(bare)) {
|
|
129
|
+
return route.name;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (route.kind === 'pattern' && patternMatches(route.pattern, bare)) { // no i18n
|
|
133
|
+
return routePath(route.pattern).split('/').map((s) => (isWildcard(s) ? '*' : s)).join('/'); // no i18n
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return path;
|
|
137
|
+
}
|
|
85
138
|
/**
|
|
86
139
|
* The name for the page as it is now, from its url, or '' to record nothing. Never throws. An app
|
|
87
140
|
* that wants its own names calls inScreen() as the route changes, which replaces this view.
|
|
88
141
|
*/
|
|
89
142
|
function currentName() {
|
|
90
143
|
try {
|
|
91
|
-
return cleanName(nameFromUrl(new URL(window.location.href)));
|
|
144
|
+
return cleanName(applyRoutes(nameFromUrl(new URL(window.location.href))));
|
|
92
145
|
}
|
|
93
146
|
catch (err) {
|
|
94
147
|
return ''; // no i18n
|
|
@@ -140,8 +193,18 @@ function cancelPending() {
|
|
|
140
193
|
* Collects the history calls and events of one navigation into a single check. The first call of
|
|
141
194
|
* a navigation starts it afresh: a inScreen() from before it belonged to the previous screen,
|
|
142
195
|
* and a view still waiting is a page left too soon to count.
|
|
196
|
+
*
|
|
197
|
+
* A history call that leaves the screen where it is, is not a navigation. Next.js and other
|
|
198
|
+
* routers replaceState the same url right after a route change, to store their state or the
|
|
199
|
+
* scroll position. Treated as one, it cancelled the view still waiting to settle, and the check
|
|
200
|
+
* that followed found the url already seen and recorded nothing: the page went untracked and the
|
|
201
|
+
* view before it was never ended.
|
|
143
202
|
*/
|
|
144
203
|
function navigated() {
|
|
204
|
+
var name = currentName();
|
|
205
|
+
if (name !== '' && (name === pendingName || (pendingName === '' && name === lastName))) { // no i18n
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
145
208
|
if (timer === null) {
|
|
146
209
|
claimed = false;
|
|
147
210
|
cancelPending();
|
|
@@ -239,3 +302,4 @@ hooks.hooks.screenTrackedByApp = screenTrackedByApp;
|
|
|
239
302
|
|
|
240
303
|
exports.automaticScreenName = automaticScreenName;
|
|
241
304
|
exports.enableScreenTracking = enableScreenTracking;
|
|
305
|
+
exports.routePath = routePath;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var constants = require('../core/constants.js');
|
|
@@ -15,8 +15,7 @@ var transport = require('../core/transport.js');
|
|
|
15
15
|
* Sends pending engagements to the Apptics API.
|
|
16
16
|
*/
|
|
17
17
|
function sendEngagementData(forget) {
|
|
18
|
-
|
|
19
|
-
if (env.is_apptics_disabled() || !consent.shouldTrackOrSendData() || !state._ZAP._engagementTracking) {
|
|
18
|
+
if (env.is_apptics_disabled() || !consent.shouldTrackOrSendData()) {
|
|
20
19
|
return Promise.resolve();
|
|
21
20
|
}
|
|
22
21
|
if (navigator.onLine == false) {
|
|
@@ -39,6 +38,11 @@ function sendEngagementData(forget) {
|
|
|
39
38
|
var _payload = {};
|
|
40
39
|
var sent = [];
|
|
41
40
|
utils.cloneObject(engagement_items).forEach(function (item) {
|
|
41
|
+
// a kind the server has turned off (getsdkconfig's event, api, screen or session
|
|
42
|
+
// module) stays queued until it is back on or the item expires
|
|
43
|
+
if (state._ZAP._engagementTracking[item.type] === false) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
42
46
|
const itemWithId = { ...item };
|
|
43
47
|
if (item.type == constants.AP_CONSTANTS.EVENT) {
|
|
44
48
|
eventObj.push(item);
|
|
@@ -58,6 +62,11 @@ function sendEngagementData(forget) {
|
|
|
58
62
|
sent.push(itemWithId);
|
|
59
63
|
delete item.id;
|
|
60
64
|
delete item.type;
|
|
65
|
+
// which tabs share a session, which tab shows a screen and when it was last seen: the
|
|
66
|
+
// SDK's own bookkeeping, not part of the payload
|
|
67
|
+
delete item.tabs;
|
|
68
|
+
delete item.tab;
|
|
69
|
+
delete item.lastseen;
|
|
61
70
|
});
|
|
62
71
|
if (eventObj.length > 0)
|
|
63
72
|
_payload.events = eventObj;
|
|
@@ -15,8 +15,16 @@ export declare function updateScreenWithEndtime(): Promise<void>;
|
|
|
15
15
|
* @param sessionData A set of properties belonging to the session.
|
|
16
16
|
*/
|
|
17
17
|
export declare function trackSession(sessionData: Dict): Promise<void>;
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* This tab's session while it is open, otherwise the newest open session in storage: the one the
|
|
20
|
+
* site's other tabs are on, which this tab joins rather than starting a second session beside it.
|
|
21
|
+
*/
|
|
19
22
|
export declare function currentSession(): Promise<QueueItem | undefined>;
|
|
23
|
+
export declare function tabId(): string;
|
|
24
|
+
/** Takes this tab's lock, held until the page is gone. Once per page. */
|
|
25
|
+
export declare function holdTabLock(): void;
|
|
26
|
+
/** Ends the open screen views of tabs that are gone. Resolves right away without Web Locks. */
|
|
27
|
+
export declare function closeScreensOfGoneTabs(): Promise<void>;
|
|
20
28
|
/**
|
|
21
29
|
* Writes the waiting session, if there is one. Called by the timer and by anything that tracks an
|
|
22
30
|
* item, so an event in the first seconds takes its session with it.
|
|
@@ -28,8 +36,26 @@ export declare function dropPendingSession(): boolean;
|
|
|
28
36
|
export declare function hasPendingSession(): boolean;
|
|
29
37
|
export declare function startNewSession(time: number): Promise<void>;
|
|
30
38
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
39
|
+
* The tab went inactive. That moment becomes the session's lastactivetime, the time it ends at if
|
|
40
|
+
* the user does not come back within inactiveduration. If they do not, the session is ended at it
|
|
41
|
+
* then, and `onEnded` sends it, rather than staying open until they return or the tab closes.
|
|
42
|
+
* Going inactive twice (a window blur, then the tab hidden) keeps the first moment.
|
|
43
|
+
*/
|
|
44
|
+
export declare function markTabInactive(onEnded: () => void): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* The tab is active again. The caller then settles the session (checkAndUpdateSession): back
|
|
47
|
+
* within inactiveduration it continues, later it has ended and a new one starts.
|
|
48
|
+
*/
|
|
49
|
+
export declare function markTabActive(): void;
|
|
50
|
+
/** reset(): no timer left running, and the tab counts as active. */
|
|
51
|
+
export declare function resetInactivity(): void;
|
|
52
|
+
/**
|
|
53
|
+
* This tab is closing, or the page is being replaced. The session ends here when this is the last
|
|
54
|
+
* tab using it, so it can be sent; while another tab of the site is still on it, this tab only
|
|
55
|
+
* leaves it, and the last tab to close ends it. Nothing happens when it is already closed.
|
|
56
|
+
*
|
|
57
|
+
* A tab closed while inactive ends the session when the user left (its lastactivetime), not when
|
|
58
|
+
* the tab closed: the time it sat hidden or in the background is not session time.
|
|
33
59
|
*/
|
|
34
60
|
export declare function endCurrentSession(): Promise<void>;
|
|
35
61
|
/**
|