@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,4 @@
|
|
|
1
|
+
/** The ISO code of a time zone's country, '' for one with none (UTC) or unknown. */
|
|
2
|
+
export declare function timeZoneCountryCode(timeZone: string): string;
|
|
3
|
+
/** The country: the user's, else the time zone's. '' when neither says. */
|
|
4
|
+
export declare function deviceCountry(): string;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
|
+
import { _ZAP } from '../core/state.js';
|
|
3
|
+
import { getTimeZone } from '../core/env.js';
|
|
4
|
+
import { TZ_COUNTRIES } from './tz-countries.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The country of this device, for remote config's `country` criteria, by its English name as the
|
|
8
|
+
* console lists it ("India").
|
|
9
|
+
*
|
|
10
|
+
* The one AppticsUser.setUser registered comes first. Otherwise it is the country of the
|
|
11
|
+
* browser's time zone, which is the device clock's: Asia/Kolkata (or Chrome's Asia/Calcutta) is
|
|
12
|
+
* India, whatever language the browser is in. A browser has no other source short of asking for
|
|
13
|
+
* the user's location, which is a permission prompt. A zone shared by several countries is the
|
|
14
|
+
* one tzdata names for it.
|
|
15
|
+
*/
|
|
16
|
+
/** Zone -> ISO code, unpacked on first use. */
|
|
17
|
+
var byZone = null;
|
|
18
|
+
function zones() {
|
|
19
|
+
if (byZone !== null) {
|
|
20
|
+
return byZone;
|
|
21
|
+
}
|
|
22
|
+
var out = {};
|
|
23
|
+
TZ_COUNTRIES.split(';').forEach(function (entry) {
|
|
24
|
+
var colon = entry.indexOf(':'); // no i18n
|
|
25
|
+
var code = entry.slice(0, colon);
|
|
26
|
+
entry.slice(colon + 1).split('|').forEach(function (group) {
|
|
27
|
+
// "Area/City,City", or bare names with no area ("Cuba,Egypt")
|
|
28
|
+
var slash = group.indexOf('/'); // no i18n
|
|
29
|
+
var area = slash === -1 ? '' : group.slice(0, slash + 1); // no i18n
|
|
30
|
+
group.slice(area.length).split(',').forEach(function (city) {
|
|
31
|
+
out[area + city] = code;
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
byZone = out;
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
/** The ISO code of a time zone's country, '' for one with none (UTC) or unknown. */
|
|
39
|
+
function timeZoneCountryCode(timeZone) {
|
|
40
|
+
var all = zones();
|
|
41
|
+
return Object.prototype.hasOwnProperty.call(all, timeZone) ? all[timeZone] : ''; // no i18n
|
|
42
|
+
}
|
|
43
|
+
/** IN -> India, in English; the code itself where the browser has no region names. */
|
|
44
|
+
function regionName(code) {
|
|
45
|
+
try {
|
|
46
|
+
var names = new Intl.DisplayNames(['en'], { type: 'region' }); // no i18n
|
|
47
|
+
return names.of(code) || code;
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
return code;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** The country: the user's, else the time zone's. '' when neither says. */
|
|
54
|
+
function deviceCountry() {
|
|
55
|
+
var named = String(_ZAP._user_info.country || '').trim(); // no i18n
|
|
56
|
+
if (named !== '') {
|
|
57
|
+
return named;
|
|
58
|
+
}
|
|
59
|
+
var timeZone = ''; // no i18n
|
|
60
|
+
try {
|
|
61
|
+
timeZone = String(getTimeZone() || ''); // no i18n
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
timeZone = ''; // no i18n
|
|
65
|
+
}
|
|
66
|
+
var code = timeZoneCountryCode(timeZone);
|
|
67
|
+
return code === '' ? '' : regionName(code); // no i18n
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export { deviceCountry, timeZoneCountryCode };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The values set for a condition, by its name; empty when none are. */
|
|
2
|
+
export declare function customConditionValues(conditionname: string): string[];
|
|
3
|
+
/**
|
|
4
|
+
* Sets what this device is for a custom condition, by its name, as comma separated values; an
|
|
5
|
+
* empty value removes it. Re-applies the stored rules once storage is ready, so the next read sees
|
|
6
|
+
* the new result without a fetch.
|
|
7
|
+
*/
|
|
8
|
+
export declare function setCustomConditionValue(conditionname: string, value: string | number | boolean | null | undefined): void;
|
|
9
|
+
/** reset(): forgets the values set on this page. */
|
|
10
|
+
export declare function clearCustomConditionValues(): void;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
|
+
import { storageReady } from '../core/storage.js';
|
|
3
|
+
import { Console } from '../core/logger.js';
|
|
4
|
+
import { reresolve } from './store.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Custom condition values: a console condition on the custom criteria (`custom_sdk_value`) is
|
|
8
|
+
* answered by what the app says this device is for that condition, by the condition's name:
|
|
9
|
+
*
|
|
10
|
+
* AppticsRemoteConfig.setCustomConditionValue('is_custom', 'custom_color');
|
|
11
|
+
* AppticsRemoteConfig.setCustomConditionValue('is_custom', 'gold,platinum'); // several
|
|
12
|
+
*
|
|
13
|
+
* The condition matches when one of the comma separated values is one of the values it lists.
|
|
14
|
+
* Values are for this page: an app sets them as it starts, as it would any other app state.
|
|
15
|
+
*/
|
|
16
|
+
var mine = {};
|
|
17
|
+
/** The values set for a condition, by its name; empty when none are. */
|
|
18
|
+
function customConditionValues(conditionname) {
|
|
19
|
+
var name = String(conditionname || '').trim(); // no i18n
|
|
20
|
+
return Object.prototype.hasOwnProperty.call(mine, name) ? mine[name] : [];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Sets what this device is for a custom condition, by its name, as comma separated values; an
|
|
24
|
+
* empty value removes it. Re-applies the stored rules once storage is ready, so the next read sees
|
|
25
|
+
* the new result without a fetch.
|
|
26
|
+
*/
|
|
27
|
+
function setCustomConditionValue(conditionname, value) {
|
|
28
|
+
var name = typeof conditionname === 'string' ? conditionname.trim() : ''; // no i18n
|
|
29
|
+
if (name === '') { // no i18n
|
|
30
|
+
Console.warn('AppticsRemoteConfig.setCustomConditionValue: a condition name is required'); // no i18n
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
var values = (value === null || value === undefined ? '' : String(value)).split(',') // no i18n
|
|
34
|
+
.map(function (one) { return one.trim(); })
|
|
35
|
+
.filter(function (one, i, all) { return one !== '' && all.indexOf(one) === i; }); // no i18n
|
|
36
|
+
if (values.length === 0) {
|
|
37
|
+
delete mine[name];
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
mine[name] = values;
|
|
41
|
+
}
|
|
42
|
+
storageReady().then(function (backend) {
|
|
43
|
+
// only once storage has loaded: re-resolving before it would read an empty rule set and keep it
|
|
44
|
+
if (backend) {
|
|
45
|
+
reresolve();
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** reset(): forgets the values set on this page. */
|
|
50
|
+
function clearCustomConditionValues() {
|
|
51
|
+
mine = {};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { clearCustomConditionValues, customConditionValues, setCustomConditionValue };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Dict } from '../types.js';
|
|
2
|
+
/** Forgets what has been complained about, so a new rule set is judged afresh. */
|
|
3
|
+
export declare function resetEvaluationWarnings(): void;
|
|
4
|
+
/**
|
|
5
|
+
* Whether a condition holds: every one of its criteria must. The template requires at least one
|
|
6
|
+
* (`array-size=">=1"`), so a condition with none is malformed and does not match — rather than
|
|
7
|
+
* matching vacuously, which would apply it to every device.
|
|
8
|
+
*/
|
|
9
|
+
export declare function conditionMatches(condition: Dict): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* The value of one parameter on this device, as the string the server stores it as.
|
|
12
|
+
*
|
|
13
|
+
* `conditions` is `all_condition` as the server sent it: its order is the order they are tried
|
|
14
|
+
* in. The parameter's own `conditions` say which of them apply to it, and with what value.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolve(parameter: Dict, conditions: Dict[]): string;
|
|
17
|
+
/**
|
|
18
|
+
* Every parameter resolved against this device, as a flat name -> value map.
|
|
19
|
+
*
|
|
20
|
+
* Built in one pass and kept, rather than resolved per read: the rule set only changes when a
|
|
21
|
+
* fetch brings a new one, and an app reading twenty flags during a render should not walk every
|
|
22
|
+
* condition twenty times.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveAll(remoteconfig: Dict): Record<string, string>;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
|
+
import { Console } from '../core/logger.js';
|
|
3
|
+
import { _ZAP } from '../core/state.js';
|
|
4
|
+
import { isEmpty } from '../core/utils.js';
|
|
5
|
+
import { customConditionValues } from './custom.js';
|
|
6
|
+
import { deviceCountry } from './country.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Working out what a parameter is worth on this device.
|
|
10
|
+
*
|
|
11
|
+
* The server sends the whole rule set, not an answer: every parameter with its default, every
|
|
12
|
+
* condition with its criteria, and the mapping between them. Resolving it here rather than on
|
|
13
|
+
* the server is what lets a value be read with no network at all on the next visit.
|
|
14
|
+
*
|
|
15
|
+
* A parameter resolves by walking the conditions in the order of `all_condition`, the console's
|
|
16
|
+
* own order, and taking the value the parameter maps to the first one that both applies to it and
|
|
17
|
+
* matches this device. A condition matches when every one of its criteria does. Nothing matches,
|
|
18
|
+
* or nothing is mapped: the parameter's default value.
|
|
19
|
+
*
|
|
20
|
+
* Criteria are answered from what the browser knows about itself (app version, device type,
|
|
21
|
+
* country...), except a custom one (`custom_sdk_value`): that is answered by what the app set with
|
|
22
|
+
* setCustomConditionValue(conditionname, 'a,b'), and matches when one of those values is listed.
|
|
23
|
+
*
|
|
24
|
+
* Everything fails closed. An operator we do not recognise, a criteria key we cannot answer, a
|
|
25
|
+
* condition the parameter names but the server did not send: each one means "does not match",
|
|
26
|
+
* never "matches". A config system that guesses hands an app a value its author never chose, on
|
|
27
|
+
* a device they cannot see, and that is far worse than falling back to the default.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Criteria operators, by the code the server sends in `status`.
|
|
31
|
+
*
|
|
32
|
+
* Only `1` is confirmed, from the one worked example we have: key `appversion`, status `"1"`,
|
|
33
|
+
* value `["1.1"]`, meaning the version is one of the listed values. The rest of the series is
|
|
34
|
+
* not written down anywhere we can see, so an unrecognised code is treated as no match and said
|
|
35
|
+
* once in the log — rather than guessed at, which would silently hand out the wrong value.
|
|
36
|
+
*/
|
|
37
|
+
const OPERATORS = Object.freeze({
|
|
38
|
+
'1': 'in', // no i18n
|
|
39
|
+
});
|
|
40
|
+
/** Criteria keys this SDK can answer about a browser. */
|
|
41
|
+
const FACTS = Object.freeze({
|
|
42
|
+
appversion: function () { return String(_ZAP._defaultoptions.appversion || ''); }, // no i18n
|
|
43
|
+
platform: function () { return String(_ZAP._platform || ''); }, // no i18n
|
|
44
|
+
browser: function () { return String(_ZAP._device_info.browser || ''); }, // no i18n
|
|
45
|
+
browserversion: function () { return String(_ZAP._device_info.browserversion || ''); }, // no i18n
|
|
46
|
+
osversion: function () { return String(_ZAP._device_info.osversion || ''); }, // no i18n
|
|
47
|
+
devicetype: function () { return String(_ZAP._device_info.devicetype || ''); }, // no i18n
|
|
48
|
+
language: function () { return String(navigator.language || ''); }, // no i18n
|
|
49
|
+
country: deviceCountry,
|
|
50
|
+
customergroupid: function () { return String(_ZAP._user_info.groupid || ''); }, // no i18n
|
|
51
|
+
userid: function () { return String(_ZAP._user_info.userid || ''); }, // no i18n
|
|
52
|
+
});
|
|
53
|
+
/** The criteria key of a custom condition, answered by setCustomConditionValue. */
|
|
54
|
+
const CUSTOM_KEY = 'custom_sdk_value'; // no i18n
|
|
55
|
+
/** Codes and keys already complained about, so one unknown rule is not a log per read. */
|
|
56
|
+
var reported = {};
|
|
57
|
+
function sayOnce(key, message) {
|
|
58
|
+
if (reported[key]) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
reported[key] = true;
|
|
62
|
+
Console.warn(message);
|
|
63
|
+
}
|
|
64
|
+
/** Forgets what has been complained about, so a new rule set is judged afresh. */
|
|
65
|
+
function resetEvaluationWarnings() {
|
|
66
|
+
reported = {};
|
|
67
|
+
}
|
|
68
|
+
/** The values of a criteria, as strings: the template types them as an array of safe_string. */
|
|
69
|
+
function valuesOf(criteria) {
|
|
70
|
+
var raw = criteria.value;
|
|
71
|
+
if (!Array.isArray(raw)) {
|
|
72
|
+
return isEmpty(raw) ? [] : [String(raw)];
|
|
73
|
+
}
|
|
74
|
+
return raw.map(function (one) { return String(one); });
|
|
75
|
+
}
|
|
76
|
+
/** Whether one criteria holds on this device; `conditionname` answers a custom criteria. */
|
|
77
|
+
function criteriaMatches(criteria, conditionname) {
|
|
78
|
+
var key = String(criteria.key || ''); // no i18n
|
|
79
|
+
var operator = OPERATORS[String(criteria.status)];
|
|
80
|
+
if (operator === undefined) {
|
|
81
|
+
sayOnce('op:' + criteria.status, 'AppticsRemoteConfig: unknown criteria operator "' + criteria.status // no i18n
|
|
82
|
+
+ '", so conditions using it will not match'); // no i18n
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
var listed = valuesOf(criteria);
|
|
86
|
+
if (key === CUSTOM_KEY) {
|
|
87
|
+
var mine = customConditionValues(conditionname);
|
|
88
|
+
if (mine.length === 0) {
|
|
89
|
+
sayOnce('custom:' + conditionname, 'AppticsRemoteConfig: no value for the custom condition "' + conditionname // no i18n
|
|
90
|
+
+ '"; set one with setCustomConditionValue, or it will not match'); // no i18n
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
// 'in': one of the values the app set is one of the listed ones
|
|
94
|
+
return mine.some(function (one) { return listed.indexOf(one) !== -1; });
|
|
95
|
+
}
|
|
96
|
+
var fact = FACTS[key];
|
|
97
|
+
if (fact === undefined) {
|
|
98
|
+
// not something a browser knows about itself
|
|
99
|
+
sayOnce('key:' + key, 'AppticsRemoteConfig: unknown criteria "' + key // no i18n
|
|
100
|
+
+ '", so conditions using it will not match'); // no i18n
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
var actual = fact();
|
|
104
|
+
if (actual === '') {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
// 'in': the device's value is one of the listed ones. Compared as strings because that is
|
|
108
|
+
// what both sides are - '1.1' is a version, not the number 1.1
|
|
109
|
+
return listed.indexOf(actual) !== -1;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Whether a condition holds: every one of its criteria must. The template requires at least one
|
|
113
|
+
* (`array-size=">=1"`), so a condition with none is malformed and does not match — rather than
|
|
114
|
+
* matching vacuously, which would apply it to every device.
|
|
115
|
+
*/
|
|
116
|
+
function conditionMatches(condition) {
|
|
117
|
+
var criterias = condition && condition.criterias;
|
|
118
|
+
if (!Array.isArray(criterias) || criterias.length === 0) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
for (var i = 0; i < criterias.length; i++) {
|
|
122
|
+
if (!criteriaMatches(criterias[i], String(condition.conditionname || ''))) { // no i18n
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The value of one parameter on this device, as the string the server stores it as.
|
|
130
|
+
*
|
|
131
|
+
* `conditions` is `all_condition` as the server sent it: its order is the order they are tried
|
|
132
|
+
* in. The parameter's own `conditions` say which of them apply to it, and with what value.
|
|
133
|
+
*/
|
|
134
|
+
function resolve(parameter, conditions) {
|
|
135
|
+
var links = {};
|
|
136
|
+
(Array.isArray(parameter.conditions) ? parameter.conditions : []).forEach(function (link) {
|
|
137
|
+
links[String(link.conditionid)] = link;
|
|
138
|
+
});
|
|
139
|
+
var sent = {};
|
|
140
|
+
for (var i = 0; i < conditions.length; i++) {
|
|
141
|
+
var condition = conditions[i];
|
|
142
|
+
var id = String(condition.conditionid);
|
|
143
|
+
sent[id] = true;
|
|
144
|
+
var link = links[id];
|
|
145
|
+
if (link !== undefined && conditionMatches(condition)) {
|
|
146
|
+
return String(link.value === undefined || link.value === null ? '' : link.value);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
Object.keys(links).forEach(function (id) {
|
|
150
|
+
if (!sent[id]) {
|
|
151
|
+
// the parameter points at a condition the answer did not include
|
|
152
|
+
sayOnce('missing:' + id, 'AppticsRemoteConfig: parameter "' + parameter.paramname // no i18n
|
|
153
|
+
+ '" uses condition ' + id + ', which the server did not send'); // no i18n
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
return String(parameter.defaultvalue === undefined || parameter.defaultvalue === null ? '' : parameter.defaultvalue);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Every parameter resolved against this device, as a flat name -> value map.
|
|
160
|
+
*
|
|
161
|
+
* Built in one pass and kept, rather than resolved per read: the rule set only changes when a
|
|
162
|
+
* fetch brings a new one, and an app reading twenty flags during a render should not walk every
|
|
163
|
+
* condition twenty times.
|
|
164
|
+
*/
|
|
165
|
+
function resolveAll(remoteconfig) {
|
|
166
|
+
var out = {};
|
|
167
|
+
var parameters = Array.isArray(remoteconfig.all_parameter) ? remoteconfig.all_parameter : [];
|
|
168
|
+
var conditions = Array.isArray(remoteconfig.all_condition) ? remoteconfig.all_condition : [];
|
|
169
|
+
parameters.forEach(function (parameter) {
|
|
170
|
+
var name = String(parameter.paramname || ''); // no i18n
|
|
171
|
+
if (name === '') {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
out[name] = resolve(parameter, conditions);
|
|
175
|
+
});
|
|
176
|
+
return out;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export { conditionMatches, resetEvaluationWarnings, resolve, resolveAll };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asks for the rule set, if anything has changed since the last one.
|
|
3
|
+
*
|
|
4
|
+
* Resolves with the parameters as they stand afterwards, whether or not the answer carried a new
|
|
5
|
+
* rule set — an answer with no `remoteconfig` block means nothing has changed, which is the
|
|
6
|
+
* normal case and not a failure.
|
|
7
|
+
*
|
|
8
|
+
* A second caller joins the first rather than making another request.
|
|
9
|
+
*/
|
|
10
|
+
export declare function fetchRemoteConfig(): Promise<Record<string, unknown>>;
|
|
11
|
+
/**
|
|
12
|
+
* reset(): forgets the rule set, its values and what the server last reported, and disowns a
|
|
13
|
+
* request still in flight, whose answer would otherwise put the old rule set back.
|
|
14
|
+
*/
|
|
15
|
+
export declare function resetRemoteConfig(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Makes sure the values are this page's own: from a fetch that just succeeded, or one within
|
|
18
|
+
* CACHE_MS. Resolves true when they are, false when the fetch failed or could not be made — the
|
|
19
|
+
* caller then decides whether stored values will do. Never rejects.
|
|
20
|
+
*
|
|
21
|
+
* Waits for start-up and for the device to be registered, which a first visit is still doing
|
|
22
|
+
* when ready() resolves: getupdates is refused without the device ids.
|
|
23
|
+
*/
|
|
24
|
+
export declare function obtain(): Promise<boolean>;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
|
+
import { SDK_MODULE } from '../core/constants.js';
|
|
3
|
+
import { hooks } from '../core/hooks.js';
|
|
4
|
+
import { _ZAP } from '../core/state.js';
|
|
5
|
+
import { Console } from '../core/logger.js';
|
|
6
|
+
import { nowMs } from '../core/utils.js';
|
|
7
|
+
import { rejectIfOffline, rejectIfNoDeviceIds, postToApptics, apiHeaders } from '../core/transport.js';
|
|
8
|
+
import { deviceReady } from '../device/index.js';
|
|
9
|
+
import { ready } from '../lifecycle.js';
|
|
10
|
+
import { clearCustomConditionValues } from './custom.js';
|
|
11
|
+
import { store, storeUnchanged, flagtime, reresolve, clearRemoteConfig } from './store.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The getupdates call.
|
|
15
|
+
*
|
|
16
|
+
* getupdates is not a synonym for getsdkconfig. It takes a body naming the modules being asked
|
|
17
|
+
* about and answers with their payloads — remote config's rule set among them — while
|
|
18
|
+
* getsdkconfig answers only with which modules are on at all.
|
|
19
|
+
*
|
|
20
|
+
* getsdkconfig stays the source of truth for that. getupdates also reports a `tracking_status`,
|
|
21
|
+
* but only for modules that have something to say in that answer, and it can disagree with
|
|
22
|
+
* getsdkconfig when the two are in flight together: an app update prompt shown by one and
|
|
23
|
+
* switched off moments later by the other. Where they disagree, getsdkconfig wins; what
|
|
24
|
+
* getupdates says is used for one thing only, which is to stop asking about a module it has
|
|
25
|
+
* reported off.
|
|
26
|
+
*/
|
|
27
|
+
const LABEL = 'AppticsRemoteConfig'; // no i18n
|
|
28
|
+
/** getupdatesobj caps moduleids at nine entries; this SDK asks about one. */
|
|
29
|
+
const MODULES = [Number(SDK_MODULE.REMOTE_CONFIG)];
|
|
30
|
+
var inFlight = null;
|
|
31
|
+
/** Bumped by reset(); an answer to a request made before it is not stored. */
|
|
32
|
+
var generation = 0;
|
|
33
|
+
/**
|
|
34
|
+
* How long a fetch that succeeded on this page answers for later ones, as on Android: a value
|
|
35
|
+
* read on every render must not be a request on every render.
|
|
36
|
+
*/
|
|
37
|
+
const CACHE_MS = 5 * 60 * 1000;
|
|
38
|
+
/** When a fetch on this page last succeeded; 0 until one has. */
|
|
39
|
+
var fetchedAt = 0;
|
|
40
|
+
/**
|
|
41
|
+
* Whether remote config is still worth asking about.
|
|
42
|
+
*
|
|
43
|
+
* Two switches, and they are not the same one. getsdkconfig's module flag is the authority and
|
|
44
|
+
* is read from `_ZAP._remoteConfigEnabled`; `_remoteConfigReported` is what the last getupdates
|
|
45
|
+
* answer said, which exists only so that a module reported off is dropped from the next
|
|
46
|
+
* request's `moduleids` rather than asked about again.
|
|
47
|
+
*/
|
|
48
|
+
function wanted() {
|
|
49
|
+
return _ZAP._remoteConfigEnabled !== false && _ZAP._remoteConfigReported !== false;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The body. appversionid and flagtime are the two keys getupdatesobj declares mandatory.
|
|
53
|
+
*
|
|
54
|
+
* osversionid and apilevel are left out on purpose: both are declared, and both are Android's —
|
|
55
|
+
* an int api level means nothing in a browser, and the osversionid a browser holds is a server
|
|
56
|
+
* id for "macOS 15", not the small int this template types. languagecode is sent when there is
|
|
57
|
+
* one, since safe_string cannot match an empty string.
|
|
58
|
+
*/
|
|
59
|
+
function body() {
|
|
60
|
+
var payload = {
|
|
61
|
+
appversionid: String(_ZAP._device_info.appversionid || ''), // no i18n
|
|
62
|
+
moduleids: MODULES,
|
|
63
|
+
flagtime: flagtime(),
|
|
64
|
+
};
|
|
65
|
+
var language = String(navigator.language || '').slice(0, 10); // no i18n
|
|
66
|
+
if (language !== '') {
|
|
67
|
+
payload.languagecode = language; // no i18n
|
|
68
|
+
}
|
|
69
|
+
return JSON.stringify(payload);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Reads the module flags getupdates reports.
|
|
73
|
+
*
|
|
74
|
+
* Only to stop asking: getsdkconfig decides whether the feature is on. A module reported off
|
|
75
|
+
* here is dropped from the next request, which is what the API asks for.
|
|
76
|
+
*/
|
|
77
|
+
function applyReportedModules(data) {
|
|
78
|
+
var status = data.tracking_status;
|
|
79
|
+
if (!status || typeof status !== 'object') {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
var entry = status[SDK_MODULE.REMOTE_CONFIG];
|
|
83
|
+
if (entry && typeof entry === 'object') {
|
|
84
|
+
_ZAP._remoteConfigReported = entry.enabled !== false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Asks for the rule set, if anything has changed since the last one.
|
|
89
|
+
*
|
|
90
|
+
* Resolves with the parameters as they stand afterwards, whether or not the answer carried a new
|
|
91
|
+
* rule set — an answer with no `remoteconfig` block means nothing has changed, which is the
|
|
92
|
+
* normal case and not a failure.
|
|
93
|
+
*
|
|
94
|
+
* A second caller joins the first rather than making another request.
|
|
95
|
+
*/
|
|
96
|
+
function fetchRemoteConfig() {
|
|
97
|
+
if (inFlight !== null) {
|
|
98
|
+
return inFlight;
|
|
99
|
+
}
|
|
100
|
+
if (!wanted()) {
|
|
101
|
+
Console.log(LABEL + ': switched off by the server, not asking'); // no i18n
|
|
102
|
+
return Promise.resolve({});
|
|
103
|
+
}
|
|
104
|
+
var blocked = rejectIfOffline(LABEL) || rejectIfNoDeviceIds(LABEL);
|
|
105
|
+
if (blocked) {
|
|
106
|
+
return blocked;
|
|
107
|
+
}
|
|
108
|
+
var asked = generation;
|
|
109
|
+
var request = postToApptics('getupdates', body(), apiHeaders(), LABEL).then(function (result) {
|
|
110
|
+
var data = (result.data || {});
|
|
111
|
+
if (asked !== generation) {
|
|
112
|
+
// asked before a reset(): the answer is about the device and app that were just forgotten
|
|
113
|
+
return data;
|
|
114
|
+
}
|
|
115
|
+
applyReportedModules(data);
|
|
116
|
+
var rules = data.remoteconfig;
|
|
117
|
+
var at = nowMs();
|
|
118
|
+
fetchedAt = at;
|
|
119
|
+
if (rules && typeof rules === 'object') {
|
|
120
|
+
store(rules, at);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// nothing has changed since our flagtime, which is the answer most of the time
|
|
124
|
+
storeUnchanged(at);
|
|
125
|
+
Console.log(LABEL + ': no changes since ' + flagtime()); // no i18n
|
|
126
|
+
}
|
|
127
|
+
return data;
|
|
128
|
+
}).then(function (data) {
|
|
129
|
+
settle();
|
|
130
|
+
return data;
|
|
131
|
+
}, function (err) {
|
|
132
|
+
settle();
|
|
133
|
+
return Promise.reject(err);
|
|
134
|
+
});
|
|
135
|
+
// a request reset() has disowned must not clear the in-flight slot of one made after it
|
|
136
|
+
function settle() {
|
|
137
|
+
if (inFlight === request) {
|
|
138
|
+
inFlight = null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
inFlight = request;
|
|
142
|
+
return inFlight;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* reset(): forgets the rule set, its values and what the server last reported, and disowns a
|
|
146
|
+
* request still in flight, whose answer would otherwise put the old rule set back.
|
|
147
|
+
*/
|
|
148
|
+
function resetRemoteConfig() {
|
|
149
|
+
generation++;
|
|
150
|
+
inFlight = null;
|
|
151
|
+
fetchedAt = 0;
|
|
152
|
+
_ZAP._remoteConfigReported = true;
|
|
153
|
+
clearCustomConditionValues();
|
|
154
|
+
clearRemoteConfig();
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Makes sure the values are this page's own: from a fetch that just succeeded, or one within
|
|
158
|
+
* CACHE_MS. Resolves true when they are, false when the fetch failed or could not be made — the
|
|
159
|
+
* caller then decides whether stored values will do. Never rejects.
|
|
160
|
+
*
|
|
161
|
+
* Waits for start-up and for the device to be registered, which a first visit is still doing
|
|
162
|
+
* when ready() resolves: getupdates is refused without the device ids.
|
|
163
|
+
*/
|
|
164
|
+
function obtain() {
|
|
165
|
+
return ready().then(function (running) {
|
|
166
|
+
if (!running) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
var now = nowMs();
|
|
170
|
+
if (fetchedAt > 0 && now - fetchedAt < CACHE_MS) {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
return deviceReady().then(function () {
|
|
174
|
+
return fetchRemoteConfig();
|
|
175
|
+
}).then(function () {
|
|
176
|
+
return true;
|
|
177
|
+
}, function (err) {
|
|
178
|
+
Console.log(LABEL + ': fetch failed: ' + String(err)); // no i18n
|
|
179
|
+
return false;
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
/** Start-up's own fetch, so values are this session's without the app asking. */
|
|
184
|
+
function fetchOnStart() {
|
|
185
|
+
obtain();
|
|
186
|
+
}
|
|
187
|
+
hooks.resetRemoteConfig = resetRemoteConfig;
|
|
188
|
+
hooks.remoteConfigStarted = fetchOnStart;
|
|
189
|
+
// a condition on the customer group answers differently once AppticsUser.setUser has named one
|
|
190
|
+
hooks.remoteConfigUserChanged = reresolve;
|
|
191
|
+
// imported after start-up has already finished (a lazy import, say): fetch now, as start-up would have
|
|
192
|
+
if (_ZAP._ready) {
|
|
193
|
+
fetchOnStart();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export { fetchRemoteConfig, obtain, resetRemoteConfig };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** AppticsRemoteConfig: fetchValue, fetchValues and setCustomConditionValue, each with the parameter names the console shows. */
|
|
2
|
+
export declare const AppticsRemoteConfig: {
|
|
3
|
+
fetchValue: (name: string, callback?: (value: string | null) => void) => Promise<string | null>;
|
|
4
|
+
/** The parameters named, or every parameter when none are: name -> value, null when there is none. */
|
|
5
|
+
fetchValues: {
|
|
6
|
+
(names?: string[], callback?: (values: Record<string, string | null>) => void): Promise<Record<string, string | null>>;
|
|
7
|
+
(callback: (values: Record<string, string | null>) => void): Promise<Record<string, string | null>>;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* What this device is for a custom condition, by the condition's name, as comma separated
|
|
11
|
+
* values: it matches when one of them is listed. An empty value removes it.
|
|
12
|
+
*/
|
|
13
|
+
setCustomConditionValue: (conditionname: string, value: string | number | boolean | null) => void;
|
|
14
|
+
};
|
|
15
|
+
export default AppticsRemoteConfig;
|