@firebase/remote-config 0.8.3 → 0.8.4-eap-crashlytics.558ee841d

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.8.3";
8
+ const version = "0.8.4-eap-crashlytics.558ee841d";
9
9
 
10
10
  /**
11
11
  * @license
@@ -299,9 +299,7 @@ async function activate(remoteConfig) {
299
299
  return false;
300
300
  }
301
301
  const experiment = new Experiment(rc);
302
- const updateActiveExperiments = lastSuccessfulFetchResponse.experiments
303
- ? experiment.updateActiveExperiments(lastSuccessfulFetchResponse.experiments)
304
- : Promise.resolve();
302
+ const updateActiveExperiments = experiment.updateActiveExperiments(lastSuccessfulFetchResponse.experiments || []);
305
303
  await Promise.all([
306
304
  rc._storageCache.setActiveConfig(lastSuccessfulFetchResponse.config),
307
305
  rc._storage.setActiveConfigEtag(lastSuccessfulFetchResponse.eTag),
@@ -1548,6 +1546,7 @@ const NO_FAILED_REALTIME_STREAMS = 0;
1548
1546
  const REALTIME_DISABLED_KEY = 'featureDisabled';
1549
1547
  const REALTIME_RETRY_INTERVAL = 'retryIntervalSeconds';
1550
1548
  const TEMPLATE_VERSION_KEY = 'latestTemplateVersionNumber';
1549
+ const ROLLOUT_ID_PREFIX = '_exp_rollout';
1551
1550
  class RealtimeHandler {
1552
1551
  constructor(firebaseInstallations, storage, sdkVersion, namespace, projectId, apiKey, appId, logger, storageCache, cachingClient) {
1553
1552
  this.firebaseInstallations = firebaseInstallations;
@@ -1765,14 +1764,29 @@ class RealtimeHandler {
1765
1764
  * Compares two configuration objects and returns a set of keys that have changed.
1766
1765
  * A key is considered changed if it's new, removed, or has a different value.
1767
1766
  */
1768
- getChangedParams(newConfig, oldConfig) {
1767
+ getChangedParams(newConfig, oldConfig, newFetchResponse, oldFetchResponse) {
1769
1768
  const changedKeys = new Set();
1770
1769
  const newKeys = new Set(Object.keys(newConfig || {}));
1771
1770
  const oldKeys = new Set(Object.keys(oldConfig || {}));
1771
+ const newExperiments = newFetchResponse.experiments || [];
1772
+ const oldExperiments = oldFetchResponse?.experiments || [];
1773
+ const newExperimentsMap = this.createExperimentsMap(newExperiments);
1774
+ const oldExperimentsMap = this.createExperimentsMap(oldExperiments);
1772
1775
  for (const key of newKeys) {
1773
1776
  if (!oldKeys.has(key) || newConfig[key] !== oldConfig[key]) {
1774
1777
  changedKeys.add(key);
1775
1778
  }
1779
+ if (newExperimentsMap.has(key) !== oldExperimentsMap.has(key)) {
1780
+ changedKeys.add(key);
1781
+ continue;
1782
+ }
1783
+ const newExperiment = newExperimentsMap.get(key);
1784
+ const oldExperiment = oldExperimentsMap.get(key);
1785
+ if (newExperiment &&
1786
+ oldExperiment &&
1787
+ !this.areExperimentsEqual(newExperiment, oldExperiment)) {
1788
+ changedKeys.add(key);
1789
+ }
1776
1790
  }
1777
1791
  for (const key of oldKeys) {
1778
1792
  if (!newKeys.has(key)) {
@@ -1781,6 +1795,26 @@ class RealtimeHandler {
1781
1795
  }
1782
1796
  return changedKeys;
1783
1797
  }
1798
+ areExperimentsEqual(newExperiment, oldExperiment) {
1799
+ return (newExperiment.experimentId === oldExperiment.experimentId &&
1800
+ newExperiment.variantId === oldExperiment.variantId &&
1801
+ newExperiment.timeToLiveMillis === oldExperiment.timeToLiveMillis &&
1802
+ newExperiment.triggerTimeoutMillis === oldExperiment.triggerTimeoutMillis);
1803
+ }
1804
+ /** Creates a map where the key is the config key and the value is the experiment description. */
1805
+ createExperimentsMap(experimentDescriptions) {
1806
+ const experimentsMap = new Map();
1807
+ for (const experimentDescription of experimentDescriptions) {
1808
+ if (!experimentDescription.affectedParameterKeys ||
1809
+ experimentDescription.experimentId.startsWith(ROLLOUT_ID_PREFIX)) {
1810
+ continue;
1811
+ }
1812
+ for (const key of experimentDescription.affectedParameterKeys) {
1813
+ experimentsMap.set(key, experimentDescription);
1814
+ }
1815
+ }
1816
+ return experimentsMap;
1817
+ }
1784
1818
  async fetchLatestConfig(remainingAttempts, targetVersion) {
1785
1819
  const remainingAttemptsAfterFetch = remainingAttempts - 1;
1786
1820
  const currentAttempt = MAXIMUM_FETCH_ATTEMPTS - remainingAttemptsAfterFetch;
@@ -1797,6 +1831,7 @@ class RealtimeHandler {
1797
1831
  fetchType: 'REALTIME',
1798
1832
  fetchAttempt: currentAttempt
1799
1833
  };
1834
+ const lastFetchResponse = await this.storage.getLastSuccessfulFetchResponse();
1800
1835
  const fetchResponse = await this.cachingClient.fetch(fetchRequest);
1801
1836
  let activatedConfigs = await this.storage.getActiveConfig();
1802
1837
  if (!this.fetchResponseIsUpToDate(fetchResponse, targetVersion)) {
@@ -1813,7 +1848,7 @@ class RealtimeHandler {
1813
1848
  if (activatedConfigs == null) {
1814
1849
  activatedConfigs = {};
1815
1850
  }
1816
- const updatedKeys = this.getChangedParams(fetchResponse.config, activatedConfigs);
1851
+ const updatedKeys = this.getChangedParams(fetchResponse.config, activatedConfigs, fetchResponse, lastFetchResponse);
1817
1852
  if (updatedKeys.size === 0) {
1818
1853
  this.logger.debug('Config was fetched, but no params changed.');
1819
1854
  return;