@funnelsgrove/runtime 0.1.39 → 0.1.40
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.
|
@@ -7,37 +7,31 @@ type FunnelExperimentBase = {
|
|
|
7
7
|
status?: FunnelExperimentStatus;
|
|
8
8
|
launchDate: string;
|
|
9
9
|
};
|
|
10
|
+
type FunnelRouteExperimentVariantDefinition = {
|
|
11
|
+
variantKey?: string;
|
|
12
|
+
stepId: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
trafficPercent: number;
|
|
15
|
+
};
|
|
16
|
+
type FunnelPricingExperimentVariantDefinition = {
|
|
17
|
+
variantKey?: string;
|
|
18
|
+
offerSetKey: string;
|
|
19
|
+
label?: string;
|
|
20
|
+
trafficPercent: number;
|
|
21
|
+
};
|
|
10
22
|
export type FunnelRouteExperimentDefinition = FunnelExperimentBase & {
|
|
11
23
|
type: FunnelRouteExperimentType;
|
|
12
24
|
stepId?: string;
|
|
13
|
-
control:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
label?: string;
|
|
17
|
-
trafficPercent: number;
|
|
18
|
-
};
|
|
19
|
-
variant: {
|
|
20
|
-
variantKey?: string;
|
|
21
|
-
stepId: string;
|
|
22
|
-
label?: string;
|
|
23
|
-
trafficPercent: number;
|
|
24
|
-
};
|
|
25
|
+
control: FunnelRouteExperimentVariantDefinition;
|
|
26
|
+
variant: FunnelRouteExperimentVariantDefinition;
|
|
27
|
+
variants?: readonly FunnelRouteExperimentVariantDefinition[];
|
|
25
28
|
};
|
|
26
29
|
export type FunnelPricingExperimentDefinition = FunnelExperimentBase & {
|
|
27
30
|
type: 'pricing';
|
|
28
31
|
paywallStepId: string;
|
|
29
|
-
control:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
label?: string;
|
|
33
|
-
trafficPercent: number;
|
|
34
|
-
};
|
|
35
|
-
variant: {
|
|
36
|
-
variantKey?: string;
|
|
37
|
-
offerSetKey: string;
|
|
38
|
-
label?: string;
|
|
39
|
-
trafficPercent: number;
|
|
40
|
-
};
|
|
32
|
+
control: FunnelPricingExperimentVariantDefinition;
|
|
33
|
+
variant: FunnelPricingExperimentVariantDefinition;
|
|
34
|
+
variants?: readonly FunnelPricingExperimentVariantDefinition[];
|
|
41
35
|
};
|
|
42
36
|
export type FunnelExperimentDefinition = FunnelRouteExperimentDefinition | FunnelPricingExperimentDefinition;
|
|
43
37
|
export type PaywallExperimentDefinition = FunnelRouteExperimentDefinition & {
|
|
@@ -1,6 +1,33 @@
|
|
|
1
|
+
const getExperimentVariants = (experiment) => {
|
|
2
|
+
var _a;
|
|
3
|
+
return (((_a = experiment.variants) === null || _a === void 0 ? void 0 : _a.length)
|
|
4
|
+
? experiment.variants
|
|
5
|
+
: [experiment.control, experiment.variant]);
|
|
6
|
+
};
|
|
7
|
+
const getRouteExperimentVariants = (experiment) => {
|
|
8
|
+
var _a;
|
|
9
|
+
return (((_a = experiment.variants) === null || _a === void 0 ? void 0 : _a.length)
|
|
10
|
+
? experiment.variants
|
|
11
|
+
: [experiment.control, experiment.variant]);
|
|
12
|
+
};
|
|
13
|
+
const getPricingExperimentVariants = (experiment) => {
|
|
14
|
+
var _a;
|
|
15
|
+
return (((_a = experiment.variants) === null || _a === void 0 ? void 0 : _a.length)
|
|
16
|
+
? experiment.variants
|
|
17
|
+
: [experiment.control, experiment.variant]);
|
|
18
|
+
};
|
|
19
|
+
const getDefaultVariantKey = (experiment, index) => {
|
|
20
|
+
var _a;
|
|
21
|
+
if (index === 0) {
|
|
22
|
+
return 'control';
|
|
23
|
+
}
|
|
24
|
+
return ((_a = experiment.variants) === null || _a === void 0 ? void 0 : _a.length)
|
|
25
|
+
? `variant_${String.fromCharCode(96 + index)}`
|
|
26
|
+
: 'variant_b';
|
|
27
|
+
};
|
|
1
28
|
export const defineFunnelExperiments = (experiments) => {
|
|
2
29
|
for (const experiment of experiments) {
|
|
3
|
-
const trafficTotal = experiment.
|
|
30
|
+
const trafficTotal = getExperimentVariants(experiment).reduce((sum, variant) => sum + variant.trafficPercent, 0);
|
|
4
31
|
if (trafficTotal !== 100) {
|
|
5
32
|
throw new Error(`Experiment "${experiment.id}" traffic must sum to 100`);
|
|
6
33
|
}
|
|
@@ -9,17 +36,17 @@ export const defineFunnelExperiments = (experiments) => {
|
|
|
9
36
|
};
|
|
10
37
|
export const toManifestExperiments = (experiments) => experiments
|
|
11
38
|
.filter((experiment) => { var _a; return ((_a = experiment.status) !== null && _a !== void 0 ? _a : 'running') === 'running'; })
|
|
12
|
-
.map((experiment) =>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
})
|
|
39
|
+
.map((experiment) => {
|
|
40
|
+
if (experiment.type === 'pricing') {
|
|
41
|
+
return {
|
|
42
|
+
experimentId: experiment.id,
|
|
43
|
+
stepId: experiment.paywallStepId,
|
|
44
|
+
variants: getPricingExperimentVariants(experiment).map((variant, index) => (Object.assign(Object.assign({ variantKey: variant.variantKey || getDefaultVariantKey(experiment, index) }, (variant.label ? { label: variant.label } : {})), { trafficPercent: variant.trafficPercent, routeToStepId: experiment.paywallStepId }))),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
experimentId: experiment.id,
|
|
49
|
+
stepId: experiment.stepId || experiment.control.stepId,
|
|
50
|
+
variants: getRouteExperimentVariants(experiment).map((variant, index) => (Object.assign(Object.assign({ variantKey: variant.variantKey || getDefaultVariantKey(experiment, index) }, (variant.label ? { label: variant.label } : {})), { trafficPercent: variant.trafficPercent, routeToStepId: variant.stepId }))),
|
|
51
|
+
};
|
|
52
|
+
});
|