@firebase/remote-config 0.4.11 → 0.5.0-canary.144bc3709

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/index.cjs.js CHANGED
@@ -9,7 +9,7 @@ var logger = require('@firebase/logger');
9
9
  require('@firebase/installations');
10
10
 
11
11
  const name = "@firebase/remote-config";
12
- const version = "0.4.11";
12
+ const version = "0.5.0-canary.144bc3709";
13
13
 
14
14
  /**
15
15
  * @license
@@ -64,6 +64,9 @@ class RemoteConfigAbortSignal {
64
64
  * limitations under the License.
65
65
  */
66
66
  const RC_COMPONENT_NAME = 'remote-config';
67
+ const RC_CUSTOM_SIGNAL_MAX_ALLOWED_SIGNALS = 100;
68
+ const RC_CUSTOM_SIGNAL_KEY_MAX_LENGTH = 250;
69
+ const RC_CUSTOM_SIGNAL_VALUE_MAX_LENGTH = 500;
67
70
 
68
71
  /**
69
72
  * @license
@@ -100,7 +103,8 @@ const ERROR_DESCRIPTION_MAP = {
100
103
  ["fetch-client-parse" /* ErrorCode.FETCH_PARSE */]: 'Fetch client could not parse response.' +
101
104
  ' Original error: {$originalErrorMessage}.',
102
105
  ["fetch-status" /* ErrorCode.FETCH_STATUS */]: 'Fetch server returned an HTTP error status. HTTP status: {$httpStatus}.',
103
- ["indexed-db-unavailable" /* ErrorCode.INDEXED_DB_UNAVAILABLE */]: 'Indexed DB is not supported by current browser'
106
+ ["indexed-db-unavailable" /* ErrorCode.INDEXED_DB_UNAVAILABLE */]: 'Indexed DB is not supported by current browser',
107
+ ["custom-signal-max-allowed-signals" /* ErrorCode.CUSTOM_SIGNAL_MAX_ALLOWED_SIGNALS */]: 'Setting more than {$maxSignals} custom signals is not supported.'
104
108
  };
105
109
  const ERROR_FACTORY = new util.ErrorFactory('remoteconfig' /* service */, 'Remote Config' /* service name */, ERROR_DESCRIPTION_MAP);
106
110
  // Note how this is like typeof/instanceof, but for ErrorCode.
@@ -251,11 +255,16 @@ async function fetchConfig(remoteConfig) {
251
255
  // Note a very low delay, eg < 10ms, can elapse before listeners are initialized.
252
256
  abortSignal.abort();
253
257
  }, rc.settings.fetchTimeoutMillis);
258
+ const customSignals = rc._storageCache.getCustomSignals();
259
+ if (customSignals) {
260
+ rc._logger.debug(`Fetching config with custom signals: ${JSON.stringify(customSignals)}`);
261
+ }
254
262
  // Catches *all* errors thrown by client so status can be set consistently.
255
263
  try {
256
264
  await rc._client.fetch({
257
265
  cacheMaxAgeMillis: rc.settings.minimumFetchIntervalMillis,
258
- signal: abortSignal
266
+ signal: abortSignal,
267
+ customSignals
259
268
  });
260
269
  await rc._storageCache.setLastFetchStatus('success');
261
270
  }
@@ -379,6 +388,41 @@ function setLogLevel(remoteConfig, logLevel) {
379
388
  function getAllKeys(obj1 = {}, obj2 = {}) {
380
389
  return Object.keys(Object.assign(Object.assign({}, obj1), obj2));
381
390
  }
391
+ /**
392
+ * Sets the custom signals for the app instance.
393
+ *
394
+ * @param remoteConfig - The {@link RemoteConfig} instance.
395
+ * @param customSignals - Map (key, value) of the custom signals to be set for the app instance. If
396
+ * a key already exists, the value is overwritten. Setting the value of a custom signal to null
397
+ * unsets the signal. The signals will be persisted locally on the client.
398
+ *
399
+ * @public
400
+ */
401
+ async function setCustomSignals(remoteConfig, customSignals) {
402
+ const rc = util.getModularInstance(remoteConfig);
403
+ if (Object.keys(customSignals).length === 0) {
404
+ return;
405
+ }
406
+ // eslint-disable-next-line guard-for-in
407
+ for (const key in customSignals) {
408
+ if (key.length > RC_CUSTOM_SIGNAL_KEY_MAX_LENGTH) {
409
+ rc._logger.error(`Custom signal key ${key} is too long, max allowed length is ${RC_CUSTOM_SIGNAL_KEY_MAX_LENGTH}.`);
410
+ return;
411
+ }
412
+ const value = customSignals[key];
413
+ if (typeof value === 'string' &&
414
+ value.length > RC_CUSTOM_SIGNAL_VALUE_MAX_LENGTH) {
415
+ rc._logger.error(`Value supplied for custom signal ${key} is too long, max allowed length is ${RC_CUSTOM_SIGNAL_VALUE_MAX_LENGTH}.`);
416
+ return;
417
+ }
418
+ }
419
+ try {
420
+ await rc._storageCache.setCustomSignals(customSignals);
421
+ }
422
+ catch (error) {
423
+ rc._logger.error(`Error encountered while setting custom signals: ${error}`);
424
+ }
425
+ }
382
426
 
383
427
  /**
384
428
  * @license
@@ -559,7 +603,8 @@ class RestClient {
559
603
  app_instance_id: installationId,
560
604
  app_instance_id_token: installationToken,
561
605
  app_id: this.appId,
562
- language_code: getUserLanguage()
606
+ language_code: getUserLanguage(),
607
+ custom_signals: request.customSignals
563
608
  /* eslint-enable camelcase */
564
609
  };
565
610
  const options = {
@@ -940,10 +985,43 @@ class Storage {
940
985
  deleteThrottleMetadata() {
941
986
  return this.delete('throttle_metadata');
942
987
  }
943
- async get(key) {
988
+ getCustomSignals() {
989
+ return this.get('custom_signals');
990
+ }
991
+ async setCustomSignals(customSignals) {
944
992
  const db = await this.openDbPromise;
993
+ const transaction = db.transaction([APP_NAMESPACE_STORE], 'readwrite');
994
+ const storedSignals = await this.getWithTransaction('custom_signals', transaction);
995
+ const combinedSignals = Object.assign(Object.assign({}, storedSignals), customSignals);
996
+ // Filter out key-value assignments with null values since they are signals being unset
997
+ const updatedSignals = Object.fromEntries(Object.entries(combinedSignals)
998
+ .filter(([_, v]) => v !== null)
999
+ .map(([k, v]) => {
1000
+ // Stringify numbers to store a map of string keys and values which can be sent
1001
+ // as-is in a fetch call.
1002
+ if (typeof v === 'number') {
1003
+ return [k, v.toString()];
1004
+ }
1005
+ return [k, v];
1006
+ }));
1007
+ // Throw an error if the number of custom signals to be stored exceeds the limit
1008
+ if (Object.keys(updatedSignals).length > RC_CUSTOM_SIGNAL_MAX_ALLOWED_SIGNALS) {
1009
+ throw ERROR_FACTORY.create("custom-signal-max-allowed-signals" /* ErrorCode.CUSTOM_SIGNAL_MAX_ALLOWED_SIGNALS */, {
1010
+ maxSignals: RC_CUSTOM_SIGNAL_MAX_ALLOWED_SIGNALS
1011
+ });
1012
+ }
1013
+ await this.setWithTransaction('custom_signals', updatedSignals, transaction);
1014
+ return updatedSignals;
1015
+ }
1016
+ /**
1017
+ * Gets a value from the database using the provided transaction.
1018
+ *
1019
+ * @param key The key of the value to get.
1020
+ * @param transaction The transaction to use for the operation.
1021
+ * @returns The value associated with the key, or undefined if no such value exists.
1022
+ */
1023
+ async getWithTransaction(key, transaction) {
945
1024
  return new Promise((resolve, reject) => {
946
- const transaction = db.transaction([APP_NAMESPACE_STORE], 'readonly');
947
1025
  const objectStore = transaction.objectStore(APP_NAMESPACE_STORE);
948
1026
  const compositeKey = this.createCompositeKey(key);
949
1027
  try {
@@ -968,10 +1046,16 @@ class Storage {
968
1046
  }
969
1047
  });
970
1048
  }
971
- async set(key, value) {
972
- const db = await this.openDbPromise;
1049
+ /**
1050
+ * Sets a value in the database using the provided transaction.
1051
+ *
1052
+ * @param key The key of the value to set.
1053
+ * @param value The value to set.
1054
+ * @param transaction The transaction to use for the operation.
1055
+ * @returns A promise that resolves when the operation is complete.
1056
+ */
1057
+ async setWithTransaction(key, value, transaction) {
973
1058
  return new Promise((resolve, reject) => {
974
- const transaction = db.transaction([APP_NAMESPACE_STORE], 'readwrite');
975
1059
  const objectStore = transaction.objectStore(APP_NAMESPACE_STORE);
976
1060
  const compositeKey = this.createCompositeKey(key);
977
1061
  try {
@@ -993,6 +1077,16 @@ class Storage {
993
1077
  }
994
1078
  });
995
1079
  }
1080
+ async get(key) {
1081
+ const db = await this.openDbPromise;
1082
+ const transaction = db.transaction([APP_NAMESPACE_STORE], 'readonly');
1083
+ return this.getWithTransaction(key, transaction);
1084
+ }
1085
+ async set(key, value) {
1086
+ const db = await this.openDbPromise;
1087
+ const transaction = db.transaction([APP_NAMESPACE_STORE], 'readwrite');
1088
+ return this.setWithTransaction(key, value, transaction);
1089
+ }
996
1090
  async delete(key) {
997
1091
  const db = await this.openDbPromise;
998
1092
  return new Promise((resolve, reject) => {
@@ -1056,6 +1150,9 @@ class StorageCache {
1056
1150
  getActiveConfig() {
1057
1151
  return this.activeConfig;
1058
1152
  }
1153
+ getCustomSignals() {
1154
+ return this.customSignals;
1155
+ }
1059
1156
  /**
1060
1157
  * Read-ahead getter
1061
1158
  */
@@ -1063,6 +1160,7 @@ class StorageCache {
1063
1160
  const lastFetchStatusPromise = this.storage.getLastFetchStatus();
1064
1161
  const lastSuccessfulFetchTimestampMillisPromise = this.storage.getLastSuccessfulFetchTimestampMillis();
1065
1162
  const activeConfigPromise = this.storage.getActiveConfig();
1163
+ const customSignalsPromise = this.storage.getCustomSignals();
1066
1164
  // Note:
1067
1165
  // 1. we consistently check for undefined to avoid clobbering defined values
1068
1166
  // in memory
@@ -1081,6 +1179,10 @@ class StorageCache {
1081
1179
  if (activeConfig) {
1082
1180
  this.activeConfig = activeConfig;
1083
1181
  }
1182
+ const customSignals = await customSignalsPromise;
1183
+ if (customSignals) {
1184
+ this.customSignals = customSignals;
1185
+ }
1084
1186
  }
1085
1187
  /**
1086
1188
  * Write-through setters
@@ -1097,6 +1199,9 @@ class StorageCache {
1097
1199
  this.activeConfig = activeConfig;
1098
1200
  return this.storage.setActiveConfig(activeConfig);
1099
1201
  }
1202
+ async setCustomSignals(customSignals) {
1203
+ this.customSignals = await this.storage.setCustomSignals(customSignals);
1204
+ }
1100
1205
  }
1101
1206
 
1102
1207
  /**
@@ -1244,5 +1349,6 @@ exports.getRemoteConfig = getRemoteConfig;
1244
1349
  exports.getString = getString;
1245
1350
  exports.getValue = getValue;
1246
1351
  exports.isSupported = isSupported;
1352
+ exports.setCustomSignals = setCustomSignals;
1247
1353
  exports.setLogLevel = setLogLevel;
1248
1354
  //# sourceMappingURL=index.cjs.js.map