forked from mirrors/gecko-dev
105 lines
2.8 KiB
JavaScript
105 lines
2.8 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
"use strict";
|
|
|
|
/**
|
|
* @typedef {import("../@types/ExperimentManager").Enrollment} Enrollment
|
|
*/
|
|
|
|
const EXPORTED_SYMBOLS = ["ExperimentStore"];
|
|
|
|
const { SharedDataMap } = ChromeUtils.import(
|
|
"resource://messaging-system/lib/SharedDataMap.jsm"
|
|
);
|
|
|
|
const DEFAULT_STORE_ID = "ExperimentStoreData";
|
|
|
|
class ExperimentStore extends SharedDataMap {
|
|
constructor(sharedDataKey, options) {
|
|
super(sharedDataKey || DEFAULT_STORE_ID, options);
|
|
}
|
|
|
|
/**
|
|
* Given a group identifier, find an active experiment that matches that group identifier.
|
|
* For example, getExperimentForGroup("B") would return an experiment with groups ["A", "B", "C"]
|
|
* This assumes, for now, that there is only one active experiment per group per browser.
|
|
*
|
|
* @param {string} group
|
|
* @returns {Enrollment|undefined} An active experiment if it exists
|
|
* @memberof ExperimentStore
|
|
*/
|
|
getExperimentForGroup(group) {
|
|
for (const experiment of this.getAll()) {
|
|
if (experiment.active && experiment.branch.groups?.includes(group)) {
|
|
return experiment;
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
/**
|
|
* Check if an active experiment already exists for a set of groups
|
|
*
|
|
* @param {Array<string>} groups
|
|
* @returns {boolean} Does an active experiment exist for that group?
|
|
* @memberof ExperimentStore
|
|
*/
|
|
hasExperimentForGroups(groups) {
|
|
if (!groups || !groups.length) {
|
|
return false;
|
|
}
|
|
for (const experiment of this.getAll()) {
|
|
if (
|
|
experiment.active &&
|
|
experiment.branch.groups?.filter(g => groups.includes(g)).length
|
|
) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @returns {Enrollment[]}
|
|
*/
|
|
getAll() {
|
|
return Object.values(this._data);
|
|
}
|
|
|
|
/**
|
|
* @returns {Enrollment[]}
|
|
*/
|
|
getAllActive() {
|
|
return this.getAll().filter(experiment => experiment.active);
|
|
}
|
|
|
|
/**
|
|
* Add an experiment. Short form for .set(slug, experiment)
|
|
* @param {Enrollment} experiment
|
|
*/
|
|
addExperiment(experiment) {
|
|
if (!experiment || !experiment.slug) {
|
|
throw new Error(
|
|
`Tried to add an experiment but it didn't have a .slug property.`
|
|
);
|
|
}
|
|
this.set(experiment.slug, experiment);
|
|
}
|
|
|
|
/**
|
|
* Merge new properties into the properties of an existing experiment
|
|
* @param {string} slug
|
|
* @param {Partial<Enrollment>} newProperties
|
|
*/
|
|
updateExperiment(slug, newProperties) {
|
|
const oldProperties = this.get(slug);
|
|
if (!oldProperties) {
|
|
throw new Error(
|
|
`Tried to update experiment ${slug} bug it doesn't exist`
|
|
);
|
|
}
|
|
this.set(slug, { ...oldProperties, ...newProperties });
|
|
}
|
|
}
|