@firebase/remote-config 0.8.5 → 0.9.0

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.5";
8
+ const version = "0.9.0";
9
9
 
10
10
  /**
11
11
  * @license
@@ -760,6 +760,7 @@ class RestClient {
760
760
  let state;
761
761
  let templateVersion;
762
762
  let experiments;
763
+ let rollouts;
763
764
  // JSON parsing throws SyntaxError if the response body isn't a JSON string.
764
765
  // Requesting application/json and checking for a 200 ensures there's JSON data.
765
766
  if (response.status === 200) {
@@ -776,6 +777,7 @@ class RestClient {
776
777
  state = responseBody['state'];
777
778
  templateVersion = responseBody['templateVersion'];
778
779
  experiments = responseBody['experimentDescriptions'];
780
+ rollouts = responseBody['rolloutMetadata'];
779
781
  }
780
782
  // Normalizes based on legacy state.
781
783
  if (state === 'INSTANCE_STATE_UNSPECIFIED') {
@@ -788,6 +790,7 @@ class RestClient {
788
790
  // These cases can be fixed remotely, so normalize to safe value.
789
791
  config = {};
790
792
  experiments = [];
793
+ rollouts = [];
791
794
  }
792
795
  // Normalize to exception-based control flow for non-success cases.
793
796
  // Encapsulates HTTP specifics in this class as much as possible. Status is still the best for
@@ -798,7 +801,14 @@ class RestClient {
798
801
  httpStatus: status
799
802
  });
800
803
  }
801
- return { status, eTag: responseEtag, config, templateVersion, experiments };
804
+ return {
805
+ status,
806
+ eTag: responseEtag,
807
+ config,
808
+ templateVersion,
809
+ experiments,
810
+ rollouts
811
+ };
802
812
  }
803
813
  }
804
814
 
@@ -1772,9 +1782,14 @@ class RealtimeHandler {
1772
1782
  const oldExperiments = oldFetchResponse?.experiments || [];
1773
1783
  const newExperimentsMap = this.createExperimentsMap(newExperiments);
1774
1784
  const oldExperimentsMap = this.createExperimentsMap(oldExperiments);
1785
+ const newRollouts = newFetchResponse.rollouts || [];
1786
+ const oldRollouts = oldFetchResponse?.rollouts || [];
1787
+ const newRolloutsMap = this.createRolloutsMap(newRollouts);
1788
+ const oldRolloutsMap = this.createRolloutsMap(oldRollouts);
1775
1789
  for (const key of newKeys) {
1776
1790
  if (!oldKeys.has(key) || newConfig[key] !== oldConfig[key]) {
1777
1791
  changedKeys.add(key);
1792
+ continue;
1778
1793
  }
1779
1794
  if (newExperimentsMap.has(key) !== oldExperimentsMap.has(key)) {
1780
1795
  changedKeys.add(key);
@@ -1786,6 +1801,18 @@ class RealtimeHandler {
1786
1801
  oldExperiment &&
1787
1802
  !this.areExperimentsEqual(newExperiment, oldExperiment)) {
1788
1803
  changedKeys.add(key);
1804
+ continue;
1805
+ }
1806
+ if (newRolloutsMap.has(key) !== oldRolloutsMap.has(key)) {
1807
+ changedKeys.add(key);
1808
+ continue;
1809
+ }
1810
+ const newRollout = newRolloutsMap.get(key);
1811
+ const oldRollout = oldRolloutsMap.get(key);
1812
+ if (newRollout &&
1813
+ oldRollout &&
1814
+ !this.areRolloutsEqual(newRollout, oldRollout)) {
1815
+ changedKeys.add(key);
1789
1816
  }
1790
1817
  }
1791
1818
  for (const key of oldKeys) {
@@ -1801,6 +1828,17 @@ class RealtimeHandler {
1801
1828
  newExperiment.timeToLiveMillis === oldExperiment.timeToLiveMillis &&
1802
1829
  newExperiment.triggerTimeoutMillis === oldExperiment.triggerTimeoutMillis);
1803
1830
  }
1831
+ areRolloutsEqual(newRollout, oldRollout) {
1832
+ if (newRollout.size !== oldRollout.size) {
1833
+ return false;
1834
+ }
1835
+ for (const [key, value] of newRollout) {
1836
+ if (oldRollout.get(key) !== value) {
1837
+ return false;
1838
+ }
1839
+ }
1840
+ return true;
1841
+ }
1804
1842
  /** Creates a map where the key is the config key and the value is the experiment description. */
1805
1843
  createExperimentsMap(experimentDescriptions) {
1806
1844
  const experimentsMap = new Map();
@@ -1815,6 +1853,24 @@ class RealtimeHandler {
1815
1853
  }
1816
1854
  return experimentsMap;
1817
1855
  }
1856
+ /** Creates a map where the key is the config key and the value is the rollout metadata. */
1857
+ createRolloutsMap(rollouts) {
1858
+ const rolloutMetadataMap = new Map();
1859
+ for (const rollout of rollouts) {
1860
+ const rolloutId = rollout.rolloutId;
1861
+ const variantId = rollout.variantId;
1862
+ const affectedParameterKeys = rollout.affectedParameterKeys || [];
1863
+ for (const parameterKey of affectedParameterKeys) {
1864
+ let parameterKeyRolloutMetadata = rolloutMetadataMap.get(parameterKey);
1865
+ if (!parameterKeyRolloutMetadata) {
1866
+ parameterKeyRolloutMetadata = new Map();
1867
+ rolloutMetadataMap.set(parameterKey, parameterKeyRolloutMetadata);
1868
+ }
1869
+ parameterKeyRolloutMetadata.set(rolloutId, variantId);
1870
+ }
1871
+ }
1872
+ return rolloutMetadataMap;
1873
+ }
1818
1874
  async fetchLatestConfig(remainingAttempts, targetVersion) {
1819
1875
  const remainingAttemptsAfterFetch = remainingAttempts - 1;
1820
1876
  const currentAttempt = MAXIMUM_FETCH_ATTEMPTS - remainingAttemptsAfterFetch;