@firebase/remote-config 0.4.11 → 0.5.0-canary.01f36ea41
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/dist/esm/index.esm2017.js +115 -10
- package/dist/esm/index.esm2017.js.map +1 -1
- package/dist/esm/src/api.d.ts +12 -1
- package/dist/esm/src/client/remote_config_fetch_client.d.ts +6 -0
- package/dist/esm/src/constants.d.ts +3 -0
- package/dist/esm/src/errors.d.ts +5 -1
- package/dist/esm/src/public_types.d.ts +16 -0
- package/dist/esm/src/storage/storage.d.ts +21 -2
- package/dist/esm/src/storage/storage_cache.d.ts +4 -1
- package/dist/index.cjs.js +115 -9
- package/dist/index.cjs.js.map +1 -1
- package/dist/remote-config-public.d.ts +29 -0
- package/dist/remote-config.d.ts +29 -0
- package/dist/src/api.d.ts +12 -1
- package/dist/src/client/remote_config_fetch_client.d.ts +6 -0
- package/dist/src/constants.d.ts +3 -0
- package/dist/src/errors.d.ts +5 -1
- package/dist/src/public_types.d.ts +16 -0
- package/dist/src/storage/storage.d.ts +21 -2
- package/dist/src/storage/storage_cache.d.ts +4 -1
- package/package.json +7 -7
|
@@ -5,7 +5,7 @@ import { LogLevel, Logger } from '@firebase/logger';
|
|
|
5
5
|
import '@firebase/installations';
|
|
6
6
|
|
|
7
7
|
const name = "@firebase/remote-config";
|
|
8
|
-
const version = "0.
|
|
8
|
+
const version = "0.5.0-canary.01f36ea41";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @license
|
|
@@ -60,6 +60,9 @@ class RemoteConfigAbortSignal {
|
|
|
60
60
|
* limitations under the License.
|
|
61
61
|
*/
|
|
62
62
|
const RC_COMPONENT_NAME = 'remote-config';
|
|
63
|
+
const RC_CUSTOM_SIGNAL_MAX_ALLOWED_SIGNALS = 100;
|
|
64
|
+
const RC_CUSTOM_SIGNAL_KEY_MAX_LENGTH = 250;
|
|
65
|
+
const RC_CUSTOM_SIGNAL_VALUE_MAX_LENGTH = 500;
|
|
63
66
|
|
|
64
67
|
/**
|
|
65
68
|
* @license
|
|
@@ -96,7 +99,8 @@ const ERROR_DESCRIPTION_MAP = {
|
|
|
96
99
|
["fetch-client-parse" /* ErrorCode.FETCH_PARSE */]: 'Fetch client could not parse response.' +
|
|
97
100
|
' Original error: {$originalErrorMessage}.',
|
|
98
101
|
["fetch-status" /* ErrorCode.FETCH_STATUS */]: 'Fetch server returned an HTTP error status. HTTP status: {$httpStatus}.',
|
|
99
|
-
["indexed-db-unavailable" /* ErrorCode.INDEXED_DB_UNAVAILABLE */]: 'Indexed DB is not supported by current browser'
|
|
102
|
+
["indexed-db-unavailable" /* ErrorCode.INDEXED_DB_UNAVAILABLE */]: 'Indexed DB is not supported by current browser',
|
|
103
|
+
["custom-signal-max-allowed-signals" /* ErrorCode.CUSTOM_SIGNAL_MAX_ALLOWED_SIGNALS */]: 'Setting more than {$maxSignals} custom signals is not supported.'
|
|
100
104
|
};
|
|
101
105
|
const ERROR_FACTORY = new ErrorFactory('remoteconfig' /* service */, 'Remote Config' /* service name */, ERROR_DESCRIPTION_MAP);
|
|
102
106
|
// Note how this is like typeof/instanceof, but for ErrorCode.
|
|
@@ -247,11 +251,16 @@ async function fetchConfig(remoteConfig) {
|
|
|
247
251
|
// Note a very low delay, eg < 10ms, can elapse before listeners are initialized.
|
|
248
252
|
abortSignal.abort();
|
|
249
253
|
}, rc.settings.fetchTimeoutMillis);
|
|
254
|
+
const customSignals = rc._storageCache.getCustomSignals();
|
|
255
|
+
if (customSignals) {
|
|
256
|
+
rc._logger.debug(`Fetching config with custom signals: ${JSON.stringify(customSignals)}`);
|
|
257
|
+
}
|
|
250
258
|
// Catches *all* errors thrown by client so status can be set consistently.
|
|
251
259
|
try {
|
|
252
260
|
await rc._client.fetch({
|
|
253
261
|
cacheMaxAgeMillis: rc.settings.minimumFetchIntervalMillis,
|
|
254
|
-
signal: abortSignal
|
|
262
|
+
signal: abortSignal,
|
|
263
|
+
customSignals
|
|
255
264
|
});
|
|
256
265
|
await rc._storageCache.setLastFetchStatus('success');
|
|
257
266
|
}
|
|
@@ -375,6 +384,41 @@ function setLogLevel(remoteConfig, logLevel) {
|
|
|
375
384
|
function getAllKeys(obj1 = {}, obj2 = {}) {
|
|
376
385
|
return Object.keys(Object.assign(Object.assign({}, obj1), obj2));
|
|
377
386
|
}
|
|
387
|
+
/**
|
|
388
|
+
* Sets the custom signals for the app instance.
|
|
389
|
+
*
|
|
390
|
+
* @param remoteConfig - The {@link RemoteConfig} instance.
|
|
391
|
+
* @param customSignals - Map (key, value) of the custom signals to be set for the app instance. If
|
|
392
|
+
* a key already exists, the value is overwritten. Setting the value of a custom signal to null
|
|
393
|
+
* unsets the signal. The signals will be persisted locally on the client.
|
|
394
|
+
*
|
|
395
|
+
* @public
|
|
396
|
+
*/
|
|
397
|
+
async function setCustomSignals(remoteConfig, customSignals) {
|
|
398
|
+
const rc = getModularInstance(remoteConfig);
|
|
399
|
+
if (Object.keys(customSignals).length === 0) {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
// eslint-disable-next-line guard-for-in
|
|
403
|
+
for (const key in customSignals) {
|
|
404
|
+
if (key.length > RC_CUSTOM_SIGNAL_KEY_MAX_LENGTH) {
|
|
405
|
+
rc._logger.error(`Custom signal key ${key} is too long, max allowed length is ${RC_CUSTOM_SIGNAL_KEY_MAX_LENGTH}.`);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
const value = customSignals[key];
|
|
409
|
+
if (typeof value === 'string' &&
|
|
410
|
+
value.length > RC_CUSTOM_SIGNAL_VALUE_MAX_LENGTH) {
|
|
411
|
+
rc._logger.error(`Value supplied for custom signal ${key} is too long, max allowed length is ${RC_CUSTOM_SIGNAL_VALUE_MAX_LENGTH}.`);
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
try {
|
|
416
|
+
await rc._storageCache.setCustomSignals(customSignals);
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
rc._logger.error(`Error encountered while setting custom signals: ${error}`);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
378
422
|
|
|
379
423
|
/**
|
|
380
424
|
* @license
|
|
@@ -555,7 +599,8 @@ class RestClient {
|
|
|
555
599
|
app_instance_id: installationId,
|
|
556
600
|
app_instance_id_token: installationToken,
|
|
557
601
|
app_id: this.appId,
|
|
558
|
-
language_code: getUserLanguage()
|
|
602
|
+
language_code: getUserLanguage(),
|
|
603
|
+
custom_signals: request.customSignals
|
|
559
604
|
/* eslint-enable camelcase */
|
|
560
605
|
};
|
|
561
606
|
const options = {
|
|
@@ -936,10 +981,43 @@ class Storage {
|
|
|
936
981
|
deleteThrottleMetadata() {
|
|
937
982
|
return this.delete('throttle_metadata');
|
|
938
983
|
}
|
|
939
|
-
|
|
984
|
+
getCustomSignals() {
|
|
985
|
+
return this.get('custom_signals');
|
|
986
|
+
}
|
|
987
|
+
async setCustomSignals(customSignals) {
|
|
940
988
|
const db = await this.openDbPromise;
|
|
989
|
+
const transaction = db.transaction([APP_NAMESPACE_STORE], 'readwrite');
|
|
990
|
+
const storedSignals = await this.getWithTransaction('custom_signals', transaction);
|
|
991
|
+
const combinedSignals = Object.assign(Object.assign({}, storedSignals), customSignals);
|
|
992
|
+
// Filter out key-value assignments with null values since they are signals being unset
|
|
993
|
+
const updatedSignals = Object.fromEntries(Object.entries(combinedSignals)
|
|
994
|
+
.filter(([_, v]) => v !== null)
|
|
995
|
+
.map(([k, v]) => {
|
|
996
|
+
// Stringify numbers to store a map of string keys and values which can be sent
|
|
997
|
+
// as-is in a fetch call.
|
|
998
|
+
if (typeof v === 'number') {
|
|
999
|
+
return [k, v.toString()];
|
|
1000
|
+
}
|
|
1001
|
+
return [k, v];
|
|
1002
|
+
}));
|
|
1003
|
+
// Throw an error if the number of custom signals to be stored exceeds the limit
|
|
1004
|
+
if (Object.keys(updatedSignals).length > RC_CUSTOM_SIGNAL_MAX_ALLOWED_SIGNALS) {
|
|
1005
|
+
throw ERROR_FACTORY.create("custom-signal-max-allowed-signals" /* ErrorCode.CUSTOM_SIGNAL_MAX_ALLOWED_SIGNALS */, {
|
|
1006
|
+
maxSignals: RC_CUSTOM_SIGNAL_MAX_ALLOWED_SIGNALS
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
await this.setWithTransaction('custom_signals', updatedSignals, transaction);
|
|
1010
|
+
return updatedSignals;
|
|
1011
|
+
}
|
|
1012
|
+
/**
|
|
1013
|
+
* Gets a value from the database using the provided transaction.
|
|
1014
|
+
*
|
|
1015
|
+
* @param key The key of the value to get.
|
|
1016
|
+
* @param transaction The transaction to use for the operation.
|
|
1017
|
+
* @returns The value associated with the key, or undefined if no such value exists.
|
|
1018
|
+
*/
|
|
1019
|
+
async getWithTransaction(key, transaction) {
|
|
941
1020
|
return new Promise((resolve, reject) => {
|
|
942
|
-
const transaction = db.transaction([APP_NAMESPACE_STORE], 'readonly');
|
|
943
1021
|
const objectStore = transaction.objectStore(APP_NAMESPACE_STORE);
|
|
944
1022
|
const compositeKey = this.createCompositeKey(key);
|
|
945
1023
|
try {
|
|
@@ -964,10 +1042,16 @@ class Storage {
|
|
|
964
1042
|
}
|
|
965
1043
|
});
|
|
966
1044
|
}
|
|
967
|
-
|
|
968
|
-
|
|
1045
|
+
/**
|
|
1046
|
+
* Sets a value in the database using the provided transaction.
|
|
1047
|
+
*
|
|
1048
|
+
* @param key The key of the value to set.
|
|
1049
|
+
* @param value The value to set.
|
|
1050
|
+
* @param transaction The transaction to use for the operation.
|
|
1051
|
+
* @returns A promise that resolves when the operation is complete.
|
|
1052
|
+
*/
|
|
1053
|
+
async setWithTransaction(key, value, transaction) {
|
|
969
1054
|
return new Promise((resolve, reject) => {
|
|
970
|
-
const transaction = db.transaction([APP_NAMESPACE_STORE], 'readwrite');
|
|
971
1055
|
const objectStore = transaction.objectStore(APP_NAMESPACE_STORE);
|
|
972
1056
|
const compositeKey = this.createCompositeKey(key);
|
|
973
1057
|
try {
|
|
@@ -989,6 +1073,16 @@ class Storage {
|
|
|
989
1073
|
}
|
|
990
1074
|
});
|
|
991
1075
|
}
|
|
1076
|
+
async get(key) {
|
|
1077
|
+
const db = await this.openDbPromise;
|
|
1078
|
+
const transaction = db.transaction([APP_NAMESPACE_STORE], 'readonly');
|
|
1079
|
+
return this.getWithTransaction(key, transaction);
|
|
1080
|
+
}
|
|
1081
|
+
async set(key, value) {
|
|
1082
|
+
const db = await this.openDbPromise;
|
|
1083
|
+
const transaction = db.transaction([APP_NAMESPACE_STORE], 'readwrite');
|
|
1084
|
+
return this.setWithTransaction(key, value, transaction);
|
|
1085
|
+
}
|
|
992
1086
|
async delete(key) {
|
|
993
1087
|
const db = await this.openDbPromise;
|
|
994
1088
|
return new Promise((resolve, reject) => {
|
|
@@ -1052,6 +1146,9 @@ class StorageCache {
|
|
|
1052
1146
|
getActiveConfig() {
|
|
1053
1147
|
return this.activeConfig;
|
|
1054
1148
|
}
|
|
1149
|
+
getCustomSignals() {
|
|
1150
|
+
return this.customSignals;
|
|
1151
|
+
}
|
|
1055
1152
|
/**
|
|
1056
1153
|
* Read-ahead getter
|
|
1057
1154
|
*/
|
|
@@ -1059,6 +1156,7 @@ class StorageCache {
|
|
|
1059
1156
|
const lastFetchStatusPromise = this.storage.getLastFetchStatus();
|
|
1060
1157
|
const lastSuccessfulFetchTimestampMillisPromise = this.storage.getLastSuccessfulFetchTimestampMillis();
|
|
1061
1158
|
const activeConfigPromise = this.storage.getActiveConfig();
|
|
1159
|
+
const customSignalsPromise = this.storage.getCustomSignals();
|
|
1062
1160
|
// Note:
|
|
1063
1161
|
// 1. we consistently check for undefined to avoid clobbering defined values
|
|
1064
1162
|
// in memory
|
|
@@ -1077,6 +1175,10 @@ class StorageCache {
|
|
|
1077
1175
|
if (activeConfig) {
|
|
1078
1176
|
this.activeConfig = activeConfig;
|
|
1079
1177
|
}
|
|
1178
|
+
const customSignals = await customSignalsPromise;
|
|
1179
|
+
if (customSignals) {
|
|
1180
|
+
this.customSignals = customSignals;
|
|
1181
|
+
}
|
|
1080
1182
|
}
|
|
1081
1183
|
/**
|
|
1082
1184
|
* Write-through setters
|
|
@@ -1093,6 +1195,9 @@ class StorageCache {
|
|
|
1093
1195
|
this.activeConfig = activeConfig;
|
|
1094
1196
|
return this.storage.setActiveConfig(activeConfig);
|
|
1095
1197
|
}
|
|
1198
|
+
async setCustomSignals(customSignals) {
|
|
1199
|
+
this.customSignals = await this.storage.setCustomSignals(customSignals);
|
|
1200
|
+
}
|
|
1096
1201
|
}
|
|
1097
1202
|
|
|
1098
1203
|
/**
|
|
@@ -1229,5 +1334,5 @@ async function isSupported() {
|
|
|
1229
1334
|
/** register component and version */
|
|
1230
1335
|
registerRemoteConfig();
|
|
1231
1336
|
|
|
1232
|
-
export { activate, ensureInitialized, fetchAndActivate, fetchConfig, getAll, getBoolean, getNumber, getRemoteConfig, getString, getValue, isSupported, setLogLevel };
|
|
1337
|
+
export { activate, ensureInitialized, fetchAndActivate, fetchConfig, getAll, getBoolean, getNumber, getRemoteConfig, getString, getValue, isSupported, setCustomSignals, setLogLevel };
|
|
1233
1338
|
//# sourceMappingURL=index.esm2017.js.map
|