@daouy/loader-splits 1.0.67
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.
- package/LICENSE +21 -0
- package/README.md +3 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.esm.js +236 -0
- package/dist/index.esm.js.map +7 -0
- package/dist/index.js +266 -0
- package/dist/index.js.map +7 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Chung Wu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Split } from '@daouy/loader-fetcher';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Gets a more human-readable description of the variation
|
|
5
|
+
*/
|
|
6
|
+
export declare function describeVariation(splits: Split[], variation: Record<string, string>): Record<string, PickedVariationDescription>;
|
|
7
|
+
|
|
8
|
+
export declare function describeVariationForKey(splits: Split[], key: string, value: string): PickedVariationDescription;
|
|
9
|
+
|
|
10
|
+
declare interface ExternalIDsFilters {
|
|
11
|
+
projectIds?: string[];
|
|
12
|
+
customFilter?: (split: Split) => boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export declare function getActiveVariation(opts: {
|
|
16
|
+
splits: Split[];
|
|
17
|
+
traits: Record<string, string | number | boolean>;
|
|
18
|
+
getKnownValue?: (key: string) => string | undefined;
|
|
19
|
+
updateKnownValue?: (key: string, value: string) => void;
|
|
20
|
+
getRandomValue?: (key: string) => number;
|
|
21
|
+
enableUnseededExperiments?: boolean;
|
|
22
|
+
useSeedBucketing?: boolean;
|
|
23
|
+
seedRange?: number;
|
|
24
|
+
}): Record<string, string>;
|
|
25
|
+
|
|
26
|
+
export declare function getExternalIds(splits: Split[], variation: Record<string, string>, filters?: ExternalIDsFilters): Record<string, string>;
|
|
27
|
+
|
|
28
|
+
export declare const getSeededRandomFunction: (strSeed: string) => () => number;
|
|
29
|
+
|
|
30
|
+
export declare const getSplitKey: (split: Split) => string;
|
|
31
|
+
|
|
32
|
+
export declare interface PickedVariationDescription {
|
|
33
|
+
name: string;
|
|
34
|
+
description?: string;
|
|
35
|
+
pagesPaths: string[];
|
|
36
|
+
type: "original" | "override";
|
|
37
|
+
chosenValue: string;
|
|
38
|
+
externalIdGroup?: string;
|
|
39
|
+
externalIdValue?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { }
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
+
var __spreadValues = (a, b) => {
|
|
7
|
+
for (var prop in b || (b = {}))
|
|
8
|
+
if (__hasOwnProp.call(b, prop))
|
|
9
|
+
__defNormalProp(a, prop, b[prop]);
|
|
10
|
+
if (__getOwnPropSymbols)
|
|
11
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
12
|
+
if (__propIsEnum.call(b, prop))
|
|
13
|
+
__defNormalProp(a, prop, b[prop]);
|
|
14
|
+
}
|
|
15
|
+
return a;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// src/random.ts
|
|
19
|
+
var getSeededRandomFunction = (strSeed) => {
|
|
20
|
+
function cyrb128(str) {
|
|
21
|
+
let h1 = 1779033703, h2 = 3144134277, h3 = 1013904242, h4 = 2773480762;
|
|
22
|
+
for (let i = 0, k; i < str.length; i++) {
|
|
23
|
+
k = str.charCodeAt(i);
|
|
24
|
+
h1 = h2 ^ Math.imul(h1 ^ k, 597399067);
|
|
25
|
+
h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);
|
|
26
|
+
h3 = h4 ^ Math.imul(h3 ^ k, 951274213);
|
|
27
|
+
h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);
|
|
28
|
+
}
|
|
29
|
+
h1 = Math.imul(h3 ^ h1 >>> 18, 597399067);
|
|
30
|
+
h2 = Math.imul(h4 ^ h2 >>> 22, 2869860233);
|
|
31
|
+
h3 = Math.imul(h1 ^ h3 >>> 17, 951274213);
|
|
32
|
+
h4 = Math.imul(h2 ^ h4 >>> 19, 2716044179);
|
|
33
|
+
return [
|
|
34
|
+
(h1 ^ h2 ^ h3 ^ h4) >>> 0,
|
|
35
|
+
(h2 ^ h1) >>> 0,
|
|
36
|
+
(h3 ^ h1) >>> 0,
|
|
37
|
+
(h4 ^ h1) >>> 0
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
function sfc32(a, b, c, d) {
|
|
41
|
+
return function() {
|
|
42
|
+
a >>>= 0;
|
|
43
|
+
b >>>= 0;
|
|
44
|
+
c >>>= 0;
|
|
45
|
+
d >>>= 0;
|
|
46
|
+
let t = a + b | 0;
|
|
47
|
+
a = b ^ b >>> 9;
|
|
48
|
+
b = c + (c << 3) | 0;
|
|
49
|
+
c = c << 21 | c >>> 11;
|
|
50
|
+
d = d + 1 | 0;
|
|
51
|
+
t = t + d | 0;
|
|
52
|
+
c = c + t | 0;
|
|
53
|
+
return (t >>> 0) / 4294967296;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const seed = cyrb128(strSeed);
|
|
57
|
+
const rand = sfc32(seed[0], seed[1], seed[2], seed[3]);
|
|
58
|
+
return rand;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// src/variation.ts
|
|
62
|
+
import jsonLogic from "json-logic-js";
|
|
63
|
+
var isBrowser = typeof window !== "undefined" && window != null && typeof window.document !== "undefined";
|
|
64
|
+
var DAOUY_SEED = "daouy_seed";
|
|
65
|
+
var BUILTIN_TRAITS_UNKNOWN = {
|
|
66
|
+
pageUrl: "unknown"
|
|
67
|
+
};
|
|
68
|
+
var getBrowserBuiltinTraits = () => {
|
|
69
|
+
if (!isBrowser) {
|
|
70
|
+
return {};
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
pageUrl: document.location.href
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
var getSplitKey = (split) => {
|
|
77
|
+
return `${split.type === "experiment" ? "exp." : "seg."}${split.id}`;
|
|
78
|
+
};
|
|
79
|
+
function getActiveVariation(opts) {
|
|
80
|
+
const { splits, getKnownValue, updateKnownValue } = opts;
|
|
81
|
+
const getRandomValue = (key) => {
|
|
82
|
+
var _a;
|
|
83
|
+
if (opts.getRandomValue) {
|
|
84
|
+
return opts.getRandomValue(key);
|
|
85
|
+
}
|
|
86
|
+
if (opts.traits[DAOUY_SEED]) {
|
|
87
|
+
const rand = getSeededRandomFunction(
|
|
88
|
+
((_a = opts.traits[DAOUY_SEED]) != null ? _a : "") + key
|
|
89
|
+
);
|
|
90
|
+
return rand();
|
|
91
|
+
}
|
|
92
|
+
if (!opts.enableUnseededExperiments) {
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
return Math.random();
|
|
96
|
+
};
|
|
97
|
+
const variation = {};
|
|
98
|
+
splits.forEach((split) => {
|
|
99
|
+
var _a;
|
|
100
|
+
const key = getSplitKey(split);
|
|
101
|
+
const knownVal = split.type === "experiment" ? getKnownValue == null ? void 0 : getKnownValue(key) : void 0;
|
|
102
|
+
if (knownVal) {
|
|
103
|
+
variation[key] = knownVal;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const numSlices = split.slices.length;
|
|
107
|
+
let chosenSlice = void 0;
|
|
108
|
+
if (split.type === "experiment") {
|
|
109
|
+
if (opts.useSeedBucketing) {
|
|
110
|
+
const seed = opts.traits[DAOUY_SEED];
|
|
111
|
+
const buckets = [];
|
|
112
|
+
const totalBuckets = (_a = opts.seedRange) != null ? _a : 1;
|
|
113
|
+
let avaiableBuckets = totalBuckets;
|
|
114
|
+
for (let i = 0; i < numSlices; i++) {
|
|
115
|
+
const slice = split.slices[i];
|
|
116
|
+
const numBuckets = Math.min(
|
|
117
|
+
Math.floor(slice.prob * totalBuckets),
|
|
118
|
+
avaiableBuckets
|
|
119
|
+
);
|
|
120
|
+
for (let j = 0; j < numBuckets; j++) {
|
|
121
|
+
buckets.push(slice.id);
|
|
122
|
+
}
|
|
123
|
+
avaiableBuckets -= numBuckets;
|
|
124
|
+
}
|
|
125
|
+
if (buckets.length > 0) {
|
|
126
|
+
const shuffleRand = getSeededRandomFunction(split.id);
|
|
127
|
+
for (let i = 0; i < buckets.length; i++) {
|
|
128
|
+
const j = Math.floor(shuffleRand() * (i + 1));
|
|
129
|
+
[buckets[i], buckets[j]] = [buckets[j], buckets[i]];
|
|
130
|
+
}
|
|
131
|
+
const sliceIdx = +(seed != null ? seed : "0") % buckets.length;
|
|
132
|
+
chosenSlice = split.slices.find((s) => s.id === buckets[sliceIdx]);
|
|
133
|
+
} else {
|
|
134
|
+
chosenSlice = split.slices[numSlices - 1];
|
|
135
|
+
}
|
|
136
|
+
} else {
|
|
137
|
+
let p = getRandomValue(split.id);
|
|
138
|
+
chosenSlice = split.slices[numSlices - 1];
|
|
139
|
+
for (let i = 0; i < numSlices; i++) {
|
|
140
|
+
if (p - split.slices[i].prob <= 0) {
|
|
141
|
+
chosenSlice = split.slices[i];
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
p -= split.slices[i].prob;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
} else if (split.type === "segment") {
|
|
148
|
+
for (let i = 0; i < numSlices; i++) {
|
|
149
|
+
if (jsonLogic.apply(split.slices[i].cond, __spreadValues(__spreadValues(__spreadValues({
|
|
150
|
+
time: (/* @__PURE__ */ new Date()).toISOString()
|
|
151
|
+
}, BUILTIN_TRAITS_UNKNOWN), getBrowserBuiltinTraits()), opts.traits))) {
|
|
152
|
+
chosenSlice = split.slices[i];
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (chosenSlice) {
|
|
157
|
+
variation[key] = chosenSlice.id;
|
|
158
|
+
if (split.externalId && chosenSlice.externalId) {
|
|
159
|
+
variation[`ext.${split.externalId}`] = chosenSlice.externalId;
|
|
160
|
+
}
|
|
161
|
+
if (split.type === "experiment") {
|
|
162
|
+
updateKnownValue == null ? void 0 : updateKnownValue(key, chosenSlice.id);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
return variation;
|
|
167
|
+
}
|
|
168
|
+
function getExternalIds(splits, variation, filters) {
|
|
169
|
+
const externalVariation = {};
|
|
170
|
+
function shouldIncludeSplit(split) {
|
|
171
|
+
if (!filters) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
if (filters.projectIds && !filters.projectIds.includes(split.projectId)) {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
if (filters.customFilter && !filters.customFilter(split)) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
Object.keys(variation).forEach((variationKey) => {
|
|
183
|
+
const [, splitId] = variationKey.split(".");
|
|
184
|
+
const sliceId = variation[variationKey];
|
|
185
|
+
const split = splits.find(
|
|
186
|
+
(s) => s.id === splitId || s.externalId === splitId
|
|
187
|
+
);
|
|
188
|
+
if (split && split.externalId && shouldIncludeSplit(split)) {
|
|
189
|
+
const slice = split.slices.find((s) => s.id === sliceId || s.externalId === sliceId);
|
|
190
|
+
if (slice == null ? void 0 : slice.externalId) {
|
|
191
|
+
externalVariation[`${split.externalId}`] = slice.externalId;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
return externalVariation;
|
|
196
|
+
}
|
|
197
|
+
function describeVariationForKey(splits, key, value) {
|
|
198
|
+
const [, splitId] = key.split(".");
|
|
199
|
+
const split = splits.find(
|
|
200
|
+
(s) => s.id === splitId || s.externalId === splitId
|
|
201
|
+
);
|
|
202
|
+
if (!split) {
|
|
203
|
+
throw new Error(`Split not found for key "${key}"`);
|
|
204
|
+
}
|
|
205
|
+
const sliceIndex = split.slices.findIndex(
|
|
206
|
+
(s) => s.id === value || s.externalId === value
|
|
207
|
+
);
|
|
208
|
+
if (sliceIndex === -1) {
|
|
209
|
+
throw new Error(`Invalid split value "${value}" for key "${key}"`);
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
name: split.name,
|
|
213
|
+
description: split.description,
|
|
214
|
+
pagesPaths: split.pagesPaths,
|
|
215
|
+
type: sliceIndex === 0 ? "original" : "override",
|
|
216
|
+
chosenValue: value,
|
|
217
|
+
externalIdGroup: split.externalId,
|
|
218
|
+
externalIdValue: sliceIndex >= 0 && split.slices[sliceIndex].externalId ? split.slices[sliceIndex].externalId : void 0
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function describeVariation(splits, variation) {
|
|
222
|
+
return Object.fromEntries(
|
|
223
|
+
Object.entries(variation).map(([key, value]) => {
|
|
224
|
+
return [key, describeVariationForKey(splits, key, value)];
|
|
225
|
+
})
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
export {
|
|
229
|
+
describeVariation,
|
|
230
|
+
describeVariationForKey,
|
|
231
|
+
getActiveVariation,
|
|
232
|
+
getExternalIds,
|
|
233
|
+
getSeededRandomFunction,
|
|
234
|
+
getSplitKey
|
|
235
|
+
};
|
|
236
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/random.ts", "../src/variation.ts"],
|
|
4
|
+
"sourcesContent": ["export const getSeededRandomFunction = (strSeed: string) => {\n // https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript\n function cyrb128(str: string) {\n let h1 = 1779033703,\n h2 = 3144134277,\n h3 = 1013904242,\n h4 = 2773480762;\n for (let i = 0, k; i < str.length; i++) {\n k = str.charCodeAt(i);\n h1 = h2 ^ Math.imul(h1 ^ k, 597399067);\n h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);\n h3 = h4 ^ Math.imul(h3 ^ k, 951274213);\n h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);\n }\n h1 = Math.imul(h3 ^ (h1 >>> 18), 597399067);\n h2 = Math.imul(h4 ^ (h2 >>> 22), 2869860233);\n h3 = Math.imul(h1 ^ (h3 >>> 17), 951274213);\n h4 = Math.imul(h2 ^ (h4 >>> 19), 2716044179);\n return [\n (h1 ^ h2 ^ h3 ^ h4) >>> 0,\n (h2 ^ h1) >>> 0,\n (h3 ^ h1) >>> 0,\n (h4 ^ h1) >>> 0,\n ];\n }\n function sfc32(a: number, b: number, c: number, d: number) {\n return function () {\n a >>>= 0;\n b >>>= 0;\n c >>>= 0;\n d >>>= 0;\n let t = (a + b) | 0;\n a = b ^ (b >>> 9);\n b = (c + (c << 3)) | 0;\n c = (c << 21) | (c >>> 11);\n d = (d + 1) | 0;\n t = (t + d) | 0;\n c = (c + t) | 0;\n return (t >>> 0) / 4294967296;\n };\n }\n const seed = cyrb128(strSeed);\n const rand = sfc32(seed[0], seed[1], seed[2], seed[3]);\n return rand;\n};\n", "import type {\n ExperimentSlice,\n SegmentSlice,\n Split,\n} from \"@daouy/loader-fetcher\";\nimport jsonLogic from \"json-logic-js\";\nimport { getSeededRandomFunction } from \"./random\";\n\nconst isBrowser =\n typeof window !== \"undefined\" &&\n window != null &&\n typeof window.document !== \"undefined\";\n\nconst DAOUY_SEED = \"daouy_seed\";\n\nconst BUILTIN_TRAITS_UNKNOWN = {\n pageUrl: \"unknown\",\n};\n\nconst getBrowserBuiltinTraits = () => {\n if (!isBrowser) {\n return {};\n }\n return {\n pageUrl: document.location.href,\n };\n};\n\nexport const getSplitKey = (split: Split) => {\n return `${split.type === \"experiment\" ? \"exp.\" : \"seg.\"}${split.id}`;\n};\n\nexport function getActiveVariation(opts: {\n splits: Split[];\n traits: Record<string, string | number | boolean>;\n getKnownValue?: (key: string) => string | undefined;\n updateKnownValue?: (key: string, value: string) => void;\n getRandomValue?: (key: string) => number;\n enableUnseededExperiments?: boolean;\n useSeedBucketing?: boolean;\n seedRange?: number;\n}) {\n const { splits, getKnownValue, updateKnownValue } = opts;\n const getRandomValue = (key: string) => {\n if (opts.getRandomValue) {\n return opts.getRandomValue(key);\n }\n\n if (opts.traits[DAOUY_SEED]) {\n const rand = getSeededRandomFunction(\n (opts.traits[DAOUY_SEED] ?? \"\") + key\n );\n return rand();\n }\n\n // If we don't have a seed we won't be able to get a consistent variation\n // in SSR, so we just return 0. Unless if expressly enabled.\n if (!opts.enableUnseededExperiments) {\n return 0;\n }\n\n return Math.random();\n };\n const variation: Record<string, string> = {};\n splits.forEach((split) => {\n const key = getSplitKey(split);\n // We will only get the known value for experiments, for segments we will always evaluate the traits\n const knownVal =\n split.type === \"experiment\" ? getKnownValue?.(key) : undefined;\n if (knownVal) {\n variation[key] = knownVal;\n return;\n }\n const numSlices = split.slices.length;\n let chosenSlice = undefined;\n if (split.type === \"experiment\") {\n /**\n * If useSeedBucketing is enabled, we will use the seed to bucket the user\n * into a slice. Otherwise, we will use the random value to bucket the user\n * into a slice.\n *\n * By using seed bucketing, we ensure the number of seeds that each slice gets,\n * is proportional to the slice's probability.\n */\n if (opts.useSeedBucketing) {\n const seed = opts.traits[DAOUY_SEED];\n const buckets: string[] = [];\n const totalBuckets = opts.seedRange ?? 1;\n let avaiableBuckets = totalBuckets;\n for (let i = 0; i < numSlices; i++) {\n const slice = split.slices[i];\n const numBuckets = Math.min(\n Math.floor(slice.prob * totalBuckets),\n avaiableBuckets\n );\n for (let j = 0; j < numBuckets; j++) {\n buckets.push(slice.id);\n }\n avaiableBuckets -= numBuckets;\n }\n if (buckets.length > 0) {\n // We need to stable shuffle the buckets to ensure that the order of the\n // buckets is deterministic.\n const shuffleRand = getSeededRandomFunction(split.id);\n for (let i = 0; i < buckets.length; i++) {\n const j = Math.floor(shuffleRand() * (i + 1));\n [buckets[i], buckets[j]] = [buckets[j], buckets[i]];\n }\n // We use the seed to bucket the user into a slice.\n const sliceIdx = +(seed ?? \"0\") % buckets.length;\n chosenSlice = split.slices.find((s) => s.id === buckets[sliceIdx]);\n } else {\n chosenSlice = split.slices[numSlices - 1];\n }\n } else {\n let p = getRandomValue(split.id);\n chosenSlice = split.slices[numSlices - 1];\n for (let i = 0; i < numSlices; i++) {\n if (p - split.slices[i].prob <= 0) {\n chosenSlice = split.slices[i];\n break;\n }\n p -= split.slices[i].prob;\n }\n }\n } else if (split.type === \"segment\") {\n for (let i = 0; i < numSlices; i++) {\n if (\n jsonLogic.apply(split.slices[i].cond, {\n time: new Date().toISOString(),\n ...BUILTIN_TRAITS_UNKNOWN,\n ...getBrowserBuiltinTraits(),\n ...opts.traits,\n })\n ) {\n chosenSlice = split.slices[i];\n }\n }\n }\n\n if (chosenSlice) {\n variation[key] = chosenSlice.id;\n if (split.externalId && chosenSlice.externalId) {\n variation[`ext.${split.externalId}`] = chosenSlice.externalId;\n }\n if (split.type === \"experiment\") {\n updateKnownValue?.(key, chosenSlice.id);\n }\n }\n });\n\n return variation;\n}\n\ninterface ExternalIDsFilters {\n projectIds?: string[];\n customFilter?: (split: Split) => boolean;\n}\n\nexport function getExternalIds(\n splits: Split[],\n variation: Record<string, string>,\n filters?: ExternalIDsFilters\n) {\n const externalVariation: Record<string, string> = {};\n\n function shouldIncludeSplit(split: Split) {\n if (!filters) {\n return true;\n }\n if (filters.projectIds && !filters.projectIds.includes(split.projectId)) {\n return false;\n }\n if (filters.customFilter && !filters.customFilter(split)) {\n return false;\n }\n return true;\n }\n\n Object.keys(variation).forEach((variationKey) => {\n const [, splitId] = variationKey.split(\".\");\n const sliceId = variation[variationKey];\n const split = splits.find(\n (s) => s.id === splitId || s.externalId === splitId\n );\n if (split && split.externalId && shouldIncludeSplit(split)) {\n const slice = (\n split.slices as Array<ExperimentSlice | SegmentSlice>\n ).find((s) => s.id === sliceId || s.externalId === sliceId);\n if (slice?.externalId) {\n // Save variation without ext prefix\n externalVariation[`${split.externalId}`] = slice.externalId;\n }\n }\n });\n return externalVariation;\n}\n\nexport interface PickedVariationDescription {\n name: string;\n description?: string;\n pagesPaths: string[];\n type: \"original\" | \"override\";\n chosenValue: string;\n externalIdGroup?: string;\n externalIdValue?: string;\n}\n\nexport function describeVariationForKey(\n splits: Split[],\n key: string,\n value: string\n): PickedVariationDescription {\n const [, splitId] = key.split(\".\");\n const split = splits.find(\n (s) => s.id === splitId || s.externalId === splitId\n );\n\n if (!split) {\n throw new Error(`Split not found for key \"${key}\"`);\n }\n\n const sliceIndex = split.slices.findIndex(\n (s) => s.id === value || s.externalId === value\n );\n\n if (sliceIndex === -1) {\n throw new Error(`Invalid split value \"${value}\" for key \"${key}\"`);\n }\n\n return {\n name: split.name,\n description: split.description,\n pagesPaths: split.pagesPaths,\n type: sliceIndex === 0 ? \"original\" : \"override\",\n chosenValue: value,\n externalIdGroup: split.externalId,\n externalIdValue:\n sliceIndex >= 0 && split.slices[sliceIndex].externalId\n ? split.slices[sliceIndex].externalId\n : undefined,\n };\n}\n\n/**\n * Gets a more human-readable description of the variation\n */\nexport function describeVariation(\n splits: Split[],\n variation: Record<string, string>\n): Record<string, PickedVariationDescription> {\n return Object.fromEntries(\n Object.entries(variation).map(([key, value]) => {\n return [key, describeVariationForKey(splits, key, value)];\n })\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
+
var __spreadValues = (a, b) => {
|
|
12
|
+
for (var prop in b || (b = {}))
|
|
13
|
+
if (__hasOwnProp.call(b, prop))
|
|
14
|
+
__defNormalProp(a, prop, b[prop]);
|
|
15
|
+
if (__getOwnPropSymbols)
|
|
16
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
+
if (__propIsEnum.call(b, prop))
|
|
18
|
+
__defNormalProp(a, prop, b[prop]);
|
|
19
|
+
}
|
|
20
|
+
return a;
|
|
21
|
+
};
|
|
22
|
+
var __export = (target, all) => {
|
|
23
|
+
for (var name in all)
|
|
24
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
25
|
+
};
|
|
26
|
+
var __copyProps = (to, from, except, desc) => {
|
|
27
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
28
|
+
for (let key of __getOwnPropNames(from))
|
|
29
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
30
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
31
|
+
}
|
|
32
|
+
return to;
|
|
33
|
+
};
|
|
34
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
35
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
36
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
37
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
38
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
39
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
40
|
+
mod
|
|
41
|
+
));
|
|
42
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
43
|
+
|
|
44
|
+
// src/index.ts
|
|
45
|
+
var src_exports = {};
|
|
46
|
+
__export(src_exports, {
|
|
47
|
+
describeVariation: () => describeVariation,
|
|
48
|
+
describeVariationForKey: () => describeVariationForKey,
|
|
49
|
+
getActiveVariation: () => getActiveVariation,
|
|
50
|
+
getExternalIds: () => getExternalIds,
|
|
51
|
+
getSeededRandomFunction: () => getSeededRandomFunction,
|
|
52
|
+
getSplitKey: () => getSplitKey
|
|
53
|
+
});
|
|
54
|
+
module.exports = __toCommonJS(src_exports);
|
|
55
|
+
|
|
56
|
+
// src/random.ts
|
|
57
|
+
var getSeededRandomFunction = (strSeed) => {
|
|
58
|
+
function cyrb128(str) {
|
|
59
|
+
let h1 = 1779033703, h2 = 3144134277, h3 = 1013904242, h4 = 2773480762;
|
|
60
|
+
for (let i = 0, k; i < str.length; i++) {
|
|
61
|
+
k = str.charCodeAt(i);
|
|
62
|
+
h1 = h2 ^ Math.imul(h1 ^ k, 597399067);
|
|
63
|
+
h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);
|
|
64
|
+
h3 = h4 ^ Math.imul(h3 ^ k, 951274213);
|
|
65
|
+
h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);
|
|
66
|
+
}
|
|
67
|
+
h1 = Math.imul(h3 ^ h1 >>> 18, 597399067);
|
|
68
|
+
h2 = Math.imul(h4 ^ h2 >>> 22, 2869860233);
|
|
69
|
+
h3 = Math.imul(h1 ^ h3 >>> 17, 951274213);
|
|
70
|
+
h4 = Math.imul(h2 ^ h4 >>> 19, 2716044179);
|
|
71
|
+
return [
|
|
72
|
+
(h1 ^ h2 ^ h3 ^ h4) >>> 0,
|
|
73
|
+
(h2 ^ h1) >>> 0,
|
|
74
|
+
(h3 ^ h1) >>> 0,
|
|
75
|
+
(h4 ^ h1) >>> 0
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
function sfc32(a, b, c, d) {
|
|
79
|
+
return function() {
|
|
80
|
+
a >>>= 0;
|
|
81
|
+
b >>>= 0;
|
|
82
|
+
c >>>= 0;
|
|
83
|
+
d >>>= 0;
|
|
84
|
+
let t = a + b | 0;
|
|
85
|
+
a = b ^ b >>> 9;
|
|
86
|
+
b = c + (c << 3) | 0;
|
|
87
|
+
c = c << 21 | c >>> 11;
|
|
88
|
+
d = d + 1 | 0;
|
|
89
|
+
t = t + d | 0;
|
|
90
|
+
c = c + t | 0;
|
|
91
|
+
return (t >>> 0) / 4294967296;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const seed = cyrb128(strSeed);
|
|
95
|
+
const rand = sfc32(seed[0], seed[1], seed[2], seed[3]);
|
|
96
|
+
return rand;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// src/variation.ts
|
|
100
|
+
var import_json_logic_js = __toESM(require("json-logic-js"));
|
|
101
|
+
var isBrowser = typeof window !== "undefined" && window != null && typeof window.document !== "undefined";
|
|
102
|
+
var DAOUY_SEED = "daouy_seed";
|
|
103
|
+
var BUILTIN_TRAITS_UNKNOWN = {
|
|
104
|
+
pageUrl: "unknown"
|
|
105
|
+
};
|
|
106
|
+
var getBrowserBuiltinTraits = () => {
|
|
107
|
+
if (!isBrowser) {
|
|
108
|
+
return {};
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
pageUrl: document.location.href
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
var getSplitKey = (split) => {
|
|
115
|
+
return `${split.type === "experiment" ? "exp." : "seg."}${split.id}`;
|
|
116
|
+
};
|
|
117
|
+
function getActiveVariation(opts) {
|
|
118
|
+
const { splits, getKnownValue, updateKnownValue } = opts;
|
|
119
|
+
const getRandomValue = (key) => {
|
|
120
|
+
var _a;
|
|
121
|
+
if (opts.getRandomValue) {
|
|
122
|
+
return opts.getRandomValue(key);
|
|
123
|
+
}
|
|
124
|
+
if (opts.traits[DAOUY_SEED]) {
|
|
125
|
+
const rand = getSeededRandomFunction(
|
|
126
|
+
((_a = opts.traits[DAOUY_SEED]) != null ? _a : "") + key
|
|
127
|
+
);
|
|
128
|
+
return rand();
|
|
129
|
+
}
|
|
130
|
+
if (!opts.enableUnseededExperiments) {
|
|
131
|
+
return 0;
|
|
132
|
+
}
|
|
133
|
+
return Math.random();
|
|
134
|
+
};
|
|
135
|
+
const variation = {};
|
|
136
|
+
splits.forEach((split) => {
|
|
137
|
+
var _a;
|
|
138
|
+
const key = getSplitKey(split);
|
|
139
|
+
const knownVal = split.type === "experiment" ? getKnownValue == null ? void 0 : getKnownValue(key) : void 0;
|
|
140
|
+
if (knownVal) {
|
|
141
|
+
variation[key] = knownVal;
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const numSlices = split.slices.length;
|
|
145
|
+
let chosenSlice = void 0;
|
|
146
|
+
if (split.type === "experiment") {
|
|
147
|
+
if (opts.useSeedBucketing) {
|
|
148
|
+
const seed = opts.traits[DAOUY_SEED];
|
|
149
|
+
const buckets = [];
|
|
150
|
+
const totalBuckets = (_a = opts.seedRange) != null ? _a : 1;
|
|
151
|
+
let avaiableBuckets = totalBuckets;
|
|
152
|
+
for (let i = 0; i < numSlices; i++) {
|
|
153
|
+
const slice = split.slices[i];
|
|
154
|
+
const numBuckets = Math.min(
|
|
155
|
+
Math.floor(slice.prob * totalBuckets),
|
|
156
|
+
avaiableBuckets
|
|
157
|
+
);
|
|
158
|
+
for (let j = 0; j < numBuckets; j++) {
|
|
159
|
+
buckets.push(slice.id);
|
|
160
|
+
}
|
|
161
|
+
avaiableBuckets -= numBuckets;
|
|
162
|
+
}
|
|
163
|
+
if (buckets.length > 0) {
|
|
164
|
+
const shuffleRand = getSeededRandomFunction(split.id);
|
|
165
|
+
for (let i = 0; i < buckets.length; i++) {
|
|
166
|
+
const j = Math.floor(shuffleRand() * (i + 1));
|
|
167
|
+
[buckets[i], buckets[j]] = [buckets[j], buckets[i]];
|
|
168
|
+
}
|
|
169
|
+
const sliceIdx = +(seed != null ? seed : "0") % buckets.length;
|
|
170
|
+
chosenSlice = split.slices.find((s) => s.id === buckets[sliceIdx]);
|
|
171
|
+
} else {
|
|
172
|
+
chosenSlice = split.slices[numSlices - 1];
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
let p = getRandomValue(split.id);
|
|
176
|
+
chosenSlice = split.slices[numSlices - 1];
|
|
177
|
+
for (let i = 0; i < numSlices; i++) {
|
|
178
|
+
if (p - split.slices[i].prob <= 0) {
|
|
179
|
+
chosenSlice = split.slices[i];
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
p -= split.slices[i].prob;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
} else if (split.type === "segment") {
|
|
186
|
+
for (let i = 0; i < numSlices; i++) {
|
|
187
|
+
if (import_json_logic_js.default.apply(split.slices[i].cond, __spreadValues(__spreadValues(__spreadValues({
|
|
188
|
+
time: (/* @__PURE__ */ new Date()).toISOString()
|
|
189
|
+
}, BUILTIN_TRAITS_UNKNOWN), getBrowserBuiltinTraits()), opts.traits))) {
|
|
190
|
+
chosenSlice = split.slices[i];
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (chosenSlice) {
|
|
195
|
+
variation[key] = chosenSlice.id;
|
|
196
|
+
if (split.externalId && chosenSlice.externalId) {
|
|
197
|
+
variation[`ext.${split.externalId}`] = chosenSlice.externalId;
|
|
198
|
+
}
|
|
199
|
+
if (split.type === "experiment") {
|
|
200
|
+
updateKnownValue == null ? void 0 : updateKnownValue(key, chosenSlice.id);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
return variation;
|
|
205
|
+
}
|
|
206
|
+
function getExternalIds(splits, variation, filters) {
|
|
207
|
+
const externalVariation = {};
|
|
208
|
+
function shouldIncludeSplit(split) {
|
|
209
|
+
if (!filters) {
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
if (filters.projectIds && !filters.projectIds.includes(split.projectId)) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
if (filters.customFilter && !filters.customFilter(split)) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
Object.keys(variation).forEach((variationKey) => {
|
|
221
|
+
const [, splitId] = variationKey.split(".");
|
|
222
|
+
const sliceId = variation[variationKey];
|
|
223
|
+
const split = splits.find(
|
|
224
|
+
(s) => s.id === splitId || s.externalId === splitId
|
|
225
|
+
);
|
|
226
|
+
if (split && split.externalId && shouldIncludeSplit(split)) {
|
|
227
|
+
const slice = split.slices.find((s) => s.id === sliceId || s.externalId === sliceId);
|
|
228
|
+
if (slice == null ? void 0 : slice.externalId) {
|
|
229
|
+
externalVariation[`${split.externalId}`] = slice.externalId;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
return externalVariation;
|
|
234
|
+
}
|
|
235
|
+
function describeVariationForKey(splits, key, value) {
|
|
236
|
+
const [, splitId] = key.split(".");
|
|
237
|
+
const split = splits.find(
|
|
238
|
+
(s) => s.id === splitId || s.externalId === splitId
|
|
239
|
+
);
|
|
240
|
+
if (!split) {
|
|
241
|
+
throw new Error(`Split not found for key "${key}"`);
|
|
242
|
+
}
|
|
243
|
+
const sliceIndex = split.slices.findIndex(
|
|
244
|
+
(s) => s.id === value || s.externalId === value
|
|
245
|
+
);
|
|
246
|
+
if (sliceIndex === -1) {
|
|
247
|
+
throw new Error(`Invalid split value "${value}" for key "${key}"`);
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
name: split.name,
|
|
251
|
+
description: split.description,
|
|
252
|
+
pagesPaths: split.pagesPaths,
|
|
253
|
+
type: sliceIndex === 0 ? "original" : "override",
|
|
254
|
+
chosenValue: value,
|
|
255
|
+
externalIdGroup: split.externalId,
|
|
256
|
+
externalIdValue: sliceIndex >= 0 && split.slices[sliceIndex].externalId ? split.slices[sliceIndex].externalId : void 0
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
function describeVariation(splits, variation) {
|
|
260
|
+
return Object.fromEntries(
|
|
261
|
+
Object.entries(variation).map(([key, value]) => {
|
|
262
|
+
return [key, describeVariationForKey(splits, key, value)];
|
|
263
|
+
})
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../src/random.ts", "../src/variation.ts"],
|
|
4
|
+
"sourcesContent": ["export { getSeededRandomFunction } from \"./random\";\nexport * from \"./variation\";\n", "export const getSeededRandomFunction = (strSeed: string) => {\n // https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript\n function cyrb128(str: string) {\n let h1 = 1779033703,\n h2 = 3144134277,\n h3 = 1013904242,\n h4 = 2773480762;\n for (let i = 0, k; i < str.length; i++) {\n k = str.charCodeAt(i);\n h1 = h2 ^ Math.imul(h1 ^ k, 597399067);\n h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);\n h3 = h4 ^ Math.imul(h3 ^ k, 951274213);\n h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);\n }\n h1 = Math.imul(h3 ^ (h1 >>> 18), 597399067);\n h2 = Math.imul(h4 ^ (h2 >>> 22), 2869860233);\n h3 = Math.imul(h1 ^ (h3 >>> 17), 951274213);\n h4 = Math.imul(h2 ^ (h4 >>> 19), 2716044179);\n return [\n (h1 ^ h2 ^ h3 ^ h4) >>> 0,\n (h2 ^ h1) >>> 0,\n (h3 ^ h1) >>> 0,\n (h4 ^ h1) >>> 0,\n ];\n }\n function sfc32(a: number, b: number, c: number, d: number) {\n return function () {\n a >>>= 0;\n b >>>= 0;\n c >>>= 0;\n d >>>= 0;\n let t = (a + b) | 0;\n a = b ^ (b >>> 9);\n b = (c + (c << 3)) | 0;\n c = (c << 21) | (c >>> 11);\n d = (d + 1) | 0;\n t = (t + d) | 0;\n c = (c + t) | 0;\n return (t >>> 0) / 4294967296;\n };\n }\n const seed = cyrb128(strSeed);\n const rand = sfc32(seed[0], seed[1], seed[2], seed[3]);\n return rand;\n};\n", "import type {\n ExperimentSlice,\n SegmentSlice,\n Split,\n} from \"@daouy/loader-fetcher\";\nimport jsonLogic from \"json-logic-js\";\nimport { getSeededRandomFunction } from \"./random\";\n\nconst isBrowser =\n typeof window !== \"undefined\" &&\n window != null &&\n typeof window.document !== \"undefined\";\n\nconst DAOUY_SEED = \"daouy_seed\";\n\nconst BUILTIN_TRAITS_UNKNOWN = {\n pageUrl: \"unknown\",\n};\n\nconst getBrowserBuiltinTraits = () => {\n if (!isBrowser) {\n return {};\n }\n return {\n pageUrl: document.location.href,\n };\n};\n\nexport const getSplitKey = (split: Split) => {\n return `${split.type === \"experiment\" ? \"exp.\" : \"seg.\"}${split.id}`;\n};\n\nexport function getActiveVariation(opts: {\n splits: Split[];\n traits: Record<string, string | number | boolean>;\n getKnownValue?: (key: string) => string | undefined;\n updateKnownValue?: (key: string, value: string) => void;\n getRandomValue?: (key: string) => number;\n enableUnseededExperiments?: boolean;\n useSeedBucketing?: boolean;\n seedRange?: number;\n}) {\n const { splits, getKnownValue, updateKnownValue } = opts;\n const getRandomValue = (key: string) => {\n if (opts.getRandomValue) {\n return opts.getRandomValue(key);\n }\n\n if (opts.traits[DAOUY_SEED]) {\n const rand = getSeededRandomFunction(\n (opts.traits[DAOUY_SEED] ?? \"\") + key\n );\n return rand();\n }\n\n // If we don't have a seed we won't be able to get a consistent variation\n // in SSR, so we just return 0. Unless if expressly enabled.\n if (!opts.enableUnseededExperiments) {\n return 0;\n }\n\n return Math.random();\n };\n const variation: Record<string, string> = {};\n splits.forEach((split) => {\n const key = getSplitKey(split);\n // We will only get the known value for experiments, for segments we will always evaluate the traits\n const knownVal =\n split.type === \"experiment\" ? getKnownValue?.(key) : undefined;\n if (knownVal) {\n variation[key] = knownVal;\n return;\n }\n const numSlices = split.slices.length;\n let chosenSlice = undefined;\n if (split.type === \"experiment\") {\n /**\n * If useSeedBucketing is enabled, we will use the seed to bucket the user\n * into a slice. Otherwise, we will use the random value to bucket the user\n * into a slice.\n *\n * By using seed bucketing, we ensure the number of seeds that each slice gets,\n * is proportional to the slice's probability.\n */\n if (opts.useSeedBucketing) {\n const seed = opts.traits[DAOUY_SEED];\n const buckets: string[] = [];\n const totalBuckets = opts.seedRange ?? 1;\n let avaiableBuckets = totalBuckets;\n for (let i = 0; i < numSlices; i++) {\n const slice = split.slices[i];\n const numBuckets = Math.min(\n Math.floor(slice.prob * totalBuckets),\n avaiableBuckets\n );\n for (let j = 0; j < numBuckets; j++) {\n buckets.push(slice.id);\n }\n avaiableBuckets -= numBuckets;\n }\n if (buckets.length > 0) {\n // We need to stable shuffle the buckets to ensure that the order of the\n // buckets is deterministic.\n const shuffleRand = getSeededRandomFunction(split.id);\n for (let i = 0; i < buckets.length; i++) {\n const j = Math.floor(shuffleRand() * (i + 1));\n [buckets[i], buckets[j]] = [buckets[j], buckets[i]];\n }\n // We use the seed to bucket the user into a slice.\n const sliceIdx = +(seed ?? \"0\") % buckets.length;\n chosenSlice = split.slices.find((s) => s.id === buckets[sliceIdx]);\n } else {\n chosenSlice = split.slices[numSlices - 1];\n }\n } else {\n let p = getRandomValue(split.id);\n chosenSlice = split.slices[numSlices - 1];\n for (let i = 0; i < numSlices; i++) {\n if (p - split.slices[i].prob <= 0) {\n chosenSlice = split.slices[i];\n break;\n }\n p -= split.slices[i].prob;\n }\n }\n } else if (split.type === \"segment\") {\n for (let i = 0; i < numSlices; i++) {\n if (\n jsonLogic.apply(split.slices[i].cond, {\n time: new Date().toISOString(),\n ...BUILTIN_TRAITS_UNKNOWN,\n ...getBrowserBuiltinTraits(),\n ...opts.traits,\n })\n ) {\n chosenSlice = split.slices[i];\n }\n }\n }\n\n if (chosenSlice) {\n variation[key] = chosenSlice.id;\n if (split.externalId && chosenSlice.externalId) {\n variation[`ext.${split.externalId}`] = chosenSlice.externalId;\n }\n if (split.type === \"experiment\") {\n updateKnownValue?.(key, chosenSlice.id);\n }\n }\n });\n\n return variation;\n}\n\ninterface ExternalIDsFilters {\n projectIds?: string[];\n customFilter?: (split: Split) => boolean;\n}\n\nexport function getExternalIds(\n splits: Split[],\n variation: Record<string, string>,\n filters?: ExternalIDsFilters\n) {\n const externalVariation: Record<string, string> = {};\n\n function shouldIncludeSplit(split: Split) {\n if (!filters) {\n return true;\n }\n if (filters.projectIds && !filters.projectIds.includes(split.projectId)) {\n return false;\n }\n if (filters.customFilter && !filters.customFilter(split)) {\n return false;\n }\n return true;\n }\n\n Object.keys(variation).forEach((variationKey) => {\n const [, splitId] = variationKey.split(\".\");\n const sliceId = variation[variationKey];\n const split = splits.find(\n (s) => s.id === splitId || s.externalId === splitId\n );\n if (split && split.externalId && shouldIncludeSplit(split)) {\n const slice = (\n split.slices as Array<ExperimentSlice | SegmentSlice>\n ).find((s) => s.id === sliceId || s.externalId === sliceId);\n if (slice?.externalId) {\n // Save variation without ext prefix\n externalVariation[`${split.externalId}`] = slice.externalId;\n }\n }\n });\n return externalVariation;\n}\n\nexport interface PickedVariationDescription {\n name: string;\n description?: string;\n pagesPaths: string[];\n type: \"original\" | \"override\";\n chosenValue: string;\n externalIdGroup?: string;\n externalIdValue?: string;\n}\n\nexport function describeVariationForKey(\n splits: Split[],\n key: string,\n value: string\n): PickedVariationDescription {\n const [, splitId] = key.split(\".\");\n const split = splits.find(\n (s) => s.id === splitId || s.externalId === splitId\n );\n\n if (!split) {\n throw new Error(`Split not found for key \"${key}\"`);\n }\n\n const sliceIndex = split.slices.findIndex(\n (s) => s.id === value || s.externalId === value\n );\n\n if (sliceIndex === -1) {\n throw new Error(`Invalid split value \"${value}\" for key \"${key}\"`);\n }\n\n return {\n name: split.name,\n description: split.description,\n pagesPaths: split.pagesPaths,\n type: sliceIndex === 0 ? \"original\" : \"override\",\n chosenValue: value,\n externalIdGroup: split.externalId,\n externalIdValue:\n sliceIndex >= 0 && split.slices[sliceIndex].externalId\n ? split.slices[sliceIndex].externalId\n : undefined,\n };\n}\n\n/**\n * Gets a more human-readable description of the variation\n */\nexport function describeVariation(\n splits: Split[],\n variation: Record<string, string>\n): Record<string, PickedVariationDescription> {\n return Object.fromEntries(\n Object.entries(variation).map(([key, value]) => {\n return [key, describeVariationForKey(splits, key, value)];\n })\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["jsonLogic"]
|
|
7
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.67",
|
|
3
|
+
"license": "MIT",
|
|
4
|
+
"types": "./dist/index.d.ts",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.esm.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.esm.js",
|
|
11
|
+
"require": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=10"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "yarn build:types && yarn build:index",
|
|
22
|
+
"build:types": "yarn tsc",
|
|
23
|
+
"build:index": "node ../../build.mjs ./src/index.ts",
|
|
24
|
+
"yalcp": "yalc publish --push",
|
|
25
|
+
"test": "TEST_CWD=`pwd` yarn --cwd=../.. test --passWithNoTests",
|
|
26
|
+
"coverage": "TEST_CWD=`pwd` yarn --cwd=../.. test --coverage --passWithNoTests",
|
|
27
|
+
"lint": "eslint",
|
|
28
|
+
"prepublishOnly": "npm run build",
|
|
29
|
+
"postpublish": "bash ../../scripts/publish-api-doc-model.sh",
|
|
30
|
+
"size": "size-limit",
|
|
31
|
+
"analyze": "size-limit --why"
|
|
32
|
+
},
|
|
33
|
+
"name": "@daouy/loader-splits",
|
|
34
|
+
"author": "Chung Wu",
|
|
35
|
+
"size-limit": [
|
|
36
|
+
{
|
|
37
|
+
"path": "./dist/index.js",
|
|
38
|
+
"limit": "10 KB"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@daouy/loader-fetcher": "^1.0.58",
|
|
43
|
+
"@types/json-logic-js": "^1.2.1",
|
|
44
|
+
"typescript": "^5.9.3"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"json-logic-js": "^2.0.2"
|
|
48
|
+
},
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public"
|
|
51
|
+
},
|
|
52
|
+
"gitHead": "fa53f7d79f0e26d8b061102fda0c06788da6f8a7"
|
|
53
|
+
}
|