From 0dd2de209c35064e6e336da93a150476a53d9225 Mon Sep 17 00:00:00 2001 From: Julien Ramboz Date: Thu, 30 May 2024 16:20:51 -0700 Subject: [PATCH 1/5] feat: add support for MAB split overrides --- src/index.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/index.js b/src/index.js index 86b96ea..bc4305d 100644 --- a/src/index.js +++ b/src/index.js @@ -236,6 +236,7 @@ function getConfigForInstantExperiment( status: context.getMetadata(`${pluginOptions.experimentsMetaTag}-status`) || 'Active', startDate: context.getMetadata(`${pluginOptions.experimentsMetaTag}-start-date`), endDate: context.getMetadata(`${pluginOptions.experimentsMetaTag}-end-date`), + selfLearning: context.getMetadata(`${pluginOptions.experimentsMetaTag}-self-learning`) || 'false', id: experimentId, variants: {}, variantNames: [], @@ -365,6 +366,19 @@ async function getConfig(experiment, instantExperiment, pluginOptions, context) return null; } + // Load MAB split overrides + if (['active', 'on', 'true'].includes(context.toClassName(experimentConfig.selfLearning))) { + try { + const request = await fetch('/mab.config.json'); + const json = await request.json(); + Object.entries(experimentConfig.variants).forEach(([k, v]) => { + v.percentageSplit = json[experimentConfig.id][k]; + }); + } catch (err) { + // Nothing to do + } + } + const forcedAudience = usp.has(pluginOptions.audiencesQueryParameter) ? context.toClassName(usp.get(pluginOptions.audiencesQueryParameter)) : null; From eeb789995d5c729a2f29c55aa8b747aedb87092b Mon Sep 17 00:00:00 2001 From: Julien Ramboz Date: Thu, 30 May 2024 16:50:46 -0700 Subject: [PATCH 2/5] feat: add support for MAB split overrides --- src/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index bc4305d..e993b84 100644 --- a/src/index.js +++ b/src/index.js @@ -29,6 +29,8 @@ export const DEFAULT_OPTIONS = { experimentsConfigFile: 'manifest.json', experimentsMetaTag: 'experiment', experimentsQueryParameter: 'experiment', + + mabConfig: '/experiments.mab.json', }; /** @@ -369,10 +371,10 @@ async function getConfig(experiment, instantExperiment, pluginOptions, context) // Load MAB split overrides if (['active', 'on', 'true'].includes(context.toClassName(experimentConfig.selfLearning))) { try { - const request = await fetch('/mab.config.json'); + const request = await fetch(pluginOptions.mabConfig); const json = await request.json(); Object.entries(experimentConfig.variants).forEach(([k, v]) => { - v.percentageSplit = json[experimentConfig.id][k]; + v.percentageSplit = (json[experimentConfig.id][k] / 100).toFixed(4); }); } catch (err) { // Nothing to do From 56d4e122024a8d2ada28fc018bb3011aebc55511 Mon Sep 17 00:00:00 2001 From: Julien Ramboz Date: Mon, 3 Jun 2024 07:39:33 -0700 Subject: [PATCH 3/5] feat: add support for MAB split overrides --- src/index.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/index.js b/src/index.js index e993b84..e226af9 100644 --- a/src/index.js +++ b/src/index.js @@ -373,9 +373,13 @@ async function getConfig(experiment, instantExperiment, pluginOptions, context) try { const request = await fetch(pluginOptions.mabConfig); const json = await request.json(); - Object.entries(experimentConfig.variants).forEach(([k, v]) => { - v.percentageSplit = (json[experimentConfig.id][k] / 100).toFixed(4); - }); + const config = json[window.location.pathname] + && json[window.location.pathname][experimentConfig.id]; + if (config) { + Object.entries(experimentConfig.variants).forEach(([k, v]) => { + v.percentageSplit = (config[k] / 100).toFixed(4); + }); + } } catch (err) { // Nothing to do } From fb87a9c9ca0c035a21e3329f5050dd942d796d20 Mon Sep 17 00:00:00 2001 From: Julien Ramboz Date: Thu, 6 Jun 2024 14:28:50 -0700 Subject: [PATCH 4/5] chore: update to latest code --- src/index.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/index.js b/src/index.js index e226af9..995984c 100644 --- a/src/index.js +++ b/src/index.js @@ -30,7 +30,7 @@ export const DEFAULT_OPTIONS = { experimentsMetaTag: 'experiment', experimentsQueryParameter: 'experiment', - mabConfig: '/experiments.mab.json', + mabConfig: '/experiments.splits.json', }; /** @@ -373,11 +373,14 @@ async function getConfig(experiment, instantExperiment, pluginOptions, context) try { const request = await fetch(pluginOptions.mabConfig); const json = await request.json(); - const config = json[window.location.pathname] - && json[window.location.pathname][experimentConfig.id]; - if (config) { + const [, pageConfig] = Object.entries(json) + .find(([url]) => new URL(url).pathname === window.location.pathname); + const mabConfig = pageConfig + ? pageConfig[context.toClassName(experimentConfig.id)] + : null; + if (mabConfig) { Object.entries(experimentConfig.variants).forEach(([k, v]) => { - v.percentageSplit = (config[k] / 100).toFixed(4); + v.percentageSplit = (mabConfig[k]).toFixed(4); }); } } catch (err) { From e4d74e0b4a1dd160c537785b1609f36cdcc163f9 Mon Sep 17 00:00:00 2001 From: Julien Ramboz Date: Thu, 20 Jun 2024 13:45:21 -0700 Subject: [PATCH 5/5] chore: rename self learning to auto allocate --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 995984c..2e7cc1e 100644 --- a/src/index.js +++ b/src/index.js @@ -238,7 +238,7 @@ function getConfigForInstantExperiment( status: context.getMetadata(`${pluginOptions.experimentsMetaTag}-status`) || 'Active', startDate: context.getMetadata(`${pluginOptions.experimentsMetaTag}-start-date`), endDate: context.getMetadata(`${pluginOptions.experimentsMetaTag}-end-date`), - selfLearning: context.getMetadata(`${pluginOptions.experimentsMetaTag}-self-learning`) || 'false', + selfLearning: context.getMetadata(`${pluginOptions.experimentsMetaTag}-auto-allocate`) || 'false', id: experimentId, variants: {}, variantNames: [],