@firebase/remote-config 0.8.5 → 0.9.0-20260707141122

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.
@@ -95,8 +95,11 @@ export declare class RealtimeHandler {
95
95
  */
96
96
  private getChangedParams;
97
97
  private areExperimentsEqual;
98
+ private areRolloutsEqual;
98
99
  /** Creates a map where the key is the config key and the value is the experiment description. */
99
100
  private createExperimentsMap;
101
+ /** Creates a map where the key is the config key and the value is the rollout metadata. */
102
+ private createRolloutsMap;
100
103
  private fetchLatestConfig;
101
104
  private autoFetch;
102
105
  /**
@@ -67,6 +67,11 @@ export interface FirebaseExperimentDescription {
67
67
  timeToLiveMillis: string;
68
68
  affectedParameterKeys?: string[];
69
69
  }
70
+ export interface FirebaseRolloutMetadata {
71
+ rolloutId: string;
72
+ variantId: string;
73
+ affectedParameterKeys: string[];
74
+ }
70
75
  /**
71
76
  * Defines a successful response (200 or 304).
72
77
  *
@@ -109,6 +114,12 @@ export interface FetchResponse {
109
114
  * @remarks Only defined for 200 responses.
110
115
  */
111
116
  experiments?: FirebaseExperimentDescription[];
117
+ /**
118
+ * Metadata for Remote Config Rollout experiments.
119
+ *
120
+ * @remarks Only defined for 200 responses.
121
+ */
122
+ rollouts?: FirebaseRolloutMetadata[];
112
123
  }
113
124
  /**
114
125
  * Options for Remote Config initialization.
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.8.5";
12
+ const version = "0.9.0-20260707141122";
13
13
 
14
14
  /**
15
15
  * @license
@@ -764,6 +764,7 @@ class RestClient {
764
764
  let state;
765
765
  let templateVersion;
766
766
  let experiments;
767
+ let rollouts;
767
768
  // JSON parsing throws SyntaxError if the response body isn't a JSON string.
768
769
  // Requesting application/json and checking for a 200 ensures there's JSON data.
769
770
  if (response.status === 200) {
@@ -780,6 +781,7 @@ class RestClient {
780
781
  state = responseBody['state'];
781
782
  templateVersion = responseBody['templateVersion'];
782
783
  experiments = responseBody['experimentDescriptions'];
784
+ rollouts = responseBody['rolloutMetadata'];
783
785
  }
784
786
  // Normalizes based on legacy state.
785
787
  if (state === 'INSTANCE_STATE_UNSPECIFIED') {
@@ -792,6 +794,7 @@ class RestClient {
792
794
  // These cases can be fixed remotely, so normalize to safe value.
793
795
  config = {};
794
796
  experiments = [];
797
+ rollouts = [];
795
798
  }
796
799
  // Normalize to exception-based control flow for non-success cases.
797
800
  // Encapsulates HTTP specifics in this class as much as possible. Status is still the best for
@@ -802,7 +805,14 @@ class RestClient {
802
805
  httpStatus: status
803
806
  });
804
807
  }
805
- return { status, eTag: responseEtag, config, templateVersion, experiments };
808
+ return {
809
+ status,
810
+ eTag: responseEtag,
811
+ config,
812
+ templateVersion,
813
+ experiments,
814
+ rollouts
815
+ };
806
816
  }
807
817
  }
808
818
 
@@ -1776,9 +1786,14 @@ class RealtimeHandler {
1776
1786
  const oldExperiments = oldFetchResponse?.experiments || [];
1777
1787
  const newExperimentsMap = this.createExperimentsMap(newExperiments);
1778
1788
  const oldExperimentsMap = this.createExperimentsMap(oldExperiments);
1789
+ const newRollouts = newFetchResponse.rollouts || [];
1790
+ const oldRollouts = oldFetchResponse?.rollouts || [];
1791
+ const newRolloutsMap = this.createRolloutsMap(newRollouts);
1792
+ const oldRolloutsMap = this.createRolloutsMap(oldRollouts);
1779
1793
  for (const key of newKeys) {
1780
1794
  if (!oldKeys.has(key) || newConfig[key] !== oldConfig[key]) {
1781
1795
  changedKeys.add(key);
1796
+ continue;
1782
1797
  }
1783
1798
  if (newExperimentsMap.has(key) !== oldExperimentsMap.has(key)) {
1784
1799
  changedKeys.add(key);
@@ -1790,6 +1805,18 @@ class RealtimeHandler {
1790
1805
  oldExperiment &&
1791
1806
  !this.areExperimentsEqual(newExperiment, oldExperiment)) {
1792
1807
  changedKeys.add(key);
1808
+ continue;
1809
+ }
1810
+ if (newRolloutsMap.has(key) !== oldRolloutsMap.has(key)) {
1811
+ changedKeys.add(key);
1812
+ continue;
1813
+ }
1814
+ const newRollout = newRolloutsMap.get(key);
1815
+ const oldRollout = oldRolloutsMap.get(key);
1816
+ if (newRollout &&
1817
+ oldRollout &&
1818
+ !this.areRolloutsEqual(newRollout, oldRollout)) {
1819
+ changedKeys.add(key);
1793
1820
  }
1794
1821
  }
1795
1822
  for (const key of oldKeys) {
@@ -1805,6 +1832,17 @@ class RealtimeHandler {
1805
1832
  newExperiment.timeToLiveMillis === oldExperiment.timeToLiveMillis &&
1806
1833
  newExperiment.triggerTimeoutMillis === oldExperiment.triggerTimeoutMillis);
1807
1834
  }
1835
+ areRolloutsEqual(newRollout, oldRollout) {
1836
+ if (newRollout.size !== oldRollout.size) {
1837
+ return false;
1838
+ }
1839
+ for (const [key, value] of newRollout) {
1840
+ if (oldRollout.get(key) !== value) {
1841
+ return false;
1842
+ }
1843
+ }
1844
+ return true;
1845
+ }
1808
1846
  /** Creates a map where the key is the config key and the value is the experiment description. */
1809
1847
  createExperimentsMap(experimentDescriptions) {
1810
1848
  const experimentsMap = new Map();
@@ -1819,6 +1857,24 @@ class RealtimeHandler {
1819
1857
  }
1820
1858
  return experimentsMap;
1821
1859
  }
1860
+ /** Creates a map where the key is the config key and the value is the rollout metadata. */
1861
+ createRolloutsMap(rollouts) {
1862
+ const rolloutMetadataMap = new Map();
1863
+ for (const rollout of rollouts) {
1864
+ const rolloutId = rollout.rolloutId;
1865
+ const variantId = rollout.variantId;
1866
+ const affectedParameterKeys = rollout.affectedParameterKeys || [];
1867
+ for (const parameterKey of affectedParameterKeys) {
1868
+ let parameterKeyRolloutMetadata = rolloutMetadataMap.get(parameterKey);
1869
+ if (!parameterKeyRolloutMetadata) {
1870
+ parameterKeyRolloutMetadata = new Map();
1871
+ rolloutMetadataMap.set(parameterKey, parameterKeyRolloutMetadata);
1872
+ }
1873
+ parameterKeyRolloutMetadata.set(rolloutId, variantId);
1874
+ }
1875
+ }
1876
+ return rolloutMetadataMap;
1877
+ }
1822
1878
  async fetchLatestConfig(remainingAttempts, targetVersion) {
1823
1879
  const remainingAttemptsAfterFetch = remainingAttempts - 1;
1824
1880
  const currentAttempt = MAXIMUM_FETCH_ATTEMPTS - remainingAttemptsAfterFetch;