@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.
@@ -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.4.11";
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
- async get(key) {
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
- async set(key, value) {
968
- const db = await this.openDbPromise;
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