@uniformdev/context 19.61.1 → 19.62.1-alpha.127
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.txt +1 -1
- package/dist/api/api.d.mts +2 -2
- package/dist/api/api.d.ts +2 -2
- package/dist/index.d.mts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.esm.js +204 -27
- package/dist/index.js +204 -27
- package/dist/index.mjs +204 -27
- package/dist/{types-012db0cb.d.ts → types-WtfxfDct.d.mts} +56 -8
- package/dist/types-WtfxfDct.d.ts +1176 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
@@ -193,6 +193,15 @@ var SignalInstance = class {
|
|
193
193
|
_evaluator = new WeakMap();
|
194
194
|
_onLogMessage = new WeakMap();
|
195
195
|
|
196
|
+
// src/manifest/utils/control.ts
|
197
|
+
var rollForControlGroup = (value) => {
|
198
|
+
let control = value;
|
199
|
+
if (control >= 1) {
|
200
|
+
control = control / 100;
|
201
|
+
}
|
202
|
+
return Math.random() < control;
|
203
|
+
};
|
204
|
+
|
196
205
|
// src/manifest/ManifestInstance.ts
|
197
206
|
var _mf, _signalInstances, _onLogMessage2;
|
198
207
|
var ManifestInstance = class {
|
@@ -216,8 +225,8 @@ var ManifestInstance = class {
|
|
216
225
|
__privateSet(this, _onLogMessage2, onLogMessage);
|
217
226
|
}
|
218
227
|
rollForControlGroup() {
|
219
|
-
var _a
|
220
|
-
return
|
228
|
+
var _a;
|
229
|
+
return rollForControlGroup(((_a = __privateGet(this, _mf).pz) == null ? void 0 : _a.control) || 0);
|
221
230
|
}
|
222
231
|
getTest(name) {
|
223
232
|
var _a;
|
@@ -565,7 +574,30 @@ function evaluateDimensionMatch(crit, vec, onLogMessage) {
|
|
565
574
|
var _a, _b;
|
566
575
|
const { op, l: lhs } = crit;
|
567
576
|
const lhsScore = (_a = vec[lhs]) != null ? _a : 0;
|
568
|
-
if (op === "
|
577
|
+
if (op === "^") {
|
578
|
+
const [cat] = lhs.split(ENR_SEPARATOR);
|
579
|
+
let topVectorName = void 0;
|
580
|
+
let topScore = 0;
|
581
|
+
Object.keys(vec).forEach((vectorName) => {
|
582
|
+
if (vectorName.startsWith(`${cat}${ENR_SEPARATOR}`)) {
|
583
|
+
const score = vec[vectorName];
|
584
|
+
if (score > topScore) {
|
585
|
+
topVectorName = vectorName;
|
586
|
+
topScore = score;
|
587
|
+
}
|
588
|
+
}
|
589
|
+
});
|
590
|
+
const result = topVectorName === lhs;
|
591
|
+
onLogMessage == null ? void 0 : onLogMessage([
|
592
|
+
"info",
|
593
|
+
302,
|
594
|
+
{
|
595
|
+
matched: result,
|
596
|
+
description: `${crit.l} has the highest score in the category`
|
597
|
+
}
|
598
|
+
]);
|
599
|
+
return result;
|
600
|
+
} else if (op === "+") {
|
569
601
|
const result = Math.max(...Object.values(vec)) === lhsScore && lhsScore > 0;
|
570
602
|
onLogMessage == null ? void 0 : onLogMessage([
|
571
603
|
"info",
|
@@ -652,31 +684,70 @@ function personalizeVariations({
|
|
652
684
|
take = 1,
|
653
685
|
onLogMessage
|
654
686
|
}) {
|
655
|
-
var _a, _b, _c;
|
687
|
+
var _a, _b, _c, _d;
|
656
688
|
onLogMessage == null ? void 0 : onLogMessage(["info", 300, "GROUP", { name, take }]);
|
657
689
|
try {
|
658
690
|
const control = (_a = context.storage.data.controlGroup) != null ? _a : false;
|
659
691
|
const results = [];
|
660
692
|
let personalized = false;
|
661
693
|
const scores = context.scores;
|
694
|
+
let index = 0;
|
695
|
+
const defaultVariants = [];
|
696
|
+
for (const variant of variations) {
|
697
|
+
if (!((_b = variant.pz) == null ? void 0 : _b.crit.length)) {
|
698
|
+
defaultVariants.push(variant);
|
699
|
+
}
|
700
|
+
}
|
662
701
|
for (const variant of variations) {
|
702
|
+
const currentIndex = index++;
|
663
703
|
if (results.length === take) {
|
664
704
|
break;
|
665
705
|
}
|
666
|
-
if (!((
|
667
|
-
onLogMessage == null ? void 0 : onLogMessage(["info", 301, "GROUP", { id: variant.id, op: (
|
706
|
+
if (!((_c = variant.pz) == null ? void 0 : _c.crit.length)) {
|
707
|
+
onLogMessage == null ? void 0 : onLogMessage(["info", 301, "GROUP", { id: variant.id, op: (_d = variant.pz) == null ? void 0 : _d.op }]);
|
668
708
|
onLogMessage == null ? void 0 : onLogMessage(["info", 302, { matched: true, description: "default variation" }]);
|
669
709
|
onLogMessage == null ? void 0 : onLogMessage(["info", 303, true]);
|
670
710
|
onLogMessage == null ? void 0 : onLogMessage(["info", 301, "ENDGROUP"]);
|
671
|
-
results.push(
|
711
|
+
results.push({
|
712
|
+
...variant,
|
713
|
+
control: false
|
714
|
+
});
|
672
715
|
continue;
|
673
716
|
}
|
674
717
|
if (control) {
|
675
718
|
continue;
|
676
719
|
}
|
677
720
|
if (evaluateVariantMatch(variant.id, variant.pz, scores, onLogMessage)) {
|
678
|
-
|
679
|
-
|
721
|
+
let variantToAdd = variant;
|
722
|
+
let isControl = false;
|
723
|
+
const isDefault = defaultVariants.find((v) => v.id === variant.id);
|
724
|
+
if (take === 1 && !isDefault && defaultVariants.length && typeof variant.pz.control === "number") {
|
725
|
+
isControl = context.getPersonalizeVariantControl(name, currentIndex);
|
726
|
+
if (typeof isControl === "undefined") {
|
727
|
+
isControl = rollForControlGroup(variant.pz.control);
|
728
|
+
context.storage.updateData([
|
729
|
+
{
|
730
|
+
type: "setpersonalizecontrol",
|
731
|
+
data: {
|
732
|
+
personlizationName: name,
|
733
|
+
index: currentIndex,
|
734
|
+
control: isControl
|
735
|
+
}
|
736
|
+
}
|
737
|
+
]);
|
738
|
+
}
|
739
|
+
if (isControl) {
|
740
|
+
variantToAdd = {
|
741
|
+
...defaultVariants[0],
|
742
|
+
id: variant.id
|
743
|
+
};
|
744
|
+
}
|
745
|
+
}
|
746
|
+
personalized = personalized || typeof variantToAdd.pz !== "undefined";
|
747
|
+
results.push({
|
748
|
+
...variantToAdd,
|
749
|
+
control: isControl
|
750
|
+
});
|
680
751
|
}
|
681
752
|
}
|
682
753
|
return {
|
@@ -923,16 +994,19 @@ function parseScoreCookie(cookieValue) {
|
|
923
994
|
if (!cookieValue)
|
924
995
|
return;
|
925
996
|
const types = cookieValue.split(TYPE_SEP);
|
926
|
-
if (types.length >
|
997
|
+
if (types.length > 5)
|
927
998
|
return;
|
928
|
-
const [abTestData, sessionScores, visitorScores] = types;
|
929
|
-
|
999
|
+
const [abTestData, sessionScores, visitorScores, controlGroup, personalizeVariants] = types;
|
1000
|
+
const data = {
|
930
1001
|
// this is true since we're reading a cookie, which wouldn't exist if consent wasn't given
|
931
1002
|
consent: true,
|
932
1003
|
sessionScores: decodeCookieType(parseCookieType(sessionScores)),
|
933
1004
|
scores: decodeCookieType(parseCookieType(visitorScores)),
|
934
|
-
tests: parseCookieType(abTestData)
|
1005
|
+
tests: parseCookieType(abTestData),
|
1006
|
+
controlGroup: controlGroup === "1",
|
1007
|
+
personalizeVariants: decodePersonalizeVariants(personalizeVariants)
|
935
1008
|
};
|
1009
|
+
return data;
|
936
1010
|
}
|
937
1011
|
function parseCookieType(type) {
|
938
1012
|
if (!type) {
|
@@ -956,9 +1030,48 @@ function serializeCookie(data) {
|
|
956
1030
|
return [
|
957
1031
|
serializeCookieType(data.tests),
|
958
1032
|
serializeCookieType(encodeCookieType(data.sessionScores)),
|
959
|
-
serializeCookieType(encodeCookieType(data.scores))
|
1033
|
+
serializeCookieType(encodeCookieType(data.scores)),
|
1034
|
+
data.controlGroup ? "1" : "0",
|
1035
|
+
serializePersonalizeVariants(data)
|
960
1036
|
].join(TYPE_SEP);
|
961
1037
|
}
|
1038
|
+
function serializePersonalizeVariants({
|
1039
|
+
personalizeVariants
|
1040
|
+
}) {
|
1041
|
+
const data = {};
|
1042
|
+
if (typeof personalizeVariants === "object") {
|
1043
|
+
Object.keys(personalizeVariants).forEach((personalizationName) => {
|
1044
|
+
const results = [];
|
1045
|
+
const variants = personalizeVariants[personalizationName];
|
1046
|
+
variants.forEach((variant) => {
|
1047
|
+
results.push(`${variant.index}:${variant.control ? "1" : "0"}`);
|
1048
|
+
});
|
1049
|
+
data[personalizationName] = results.join(",");
|
1050
|
+
});
|
1051
|
+
}
|
1052
|
+
const serialized = serializeCookieType(data);
|
1053
|
+
return serialized;
|
1054
|
+
}
|
1055
|
+
function decodePersonalizeVariants(data) {
|
1056
|
+
const parsed = parseCookieType(data);
|
1057
|
+
const keys = Object.keys(parsed);
|
1058
|
+
if (!keys.length) {
|
1059
|
+
return void 0;
|
1060
|
+
}
|
1061
|
+
const results = {};
|
1062
|
+
Object.keys(parsed).forEach((k) => {
|
1063
|
+
const variants = parsed[k].split(",");
|
1064
|
+
const key = decodeURIComponent(k);
|
1065
|
+
results[key] = variants.map((variant) => {
|
1066
|
+
const [index, control] = variant.split(":");
|
1067
|
+
return {
|
1068
|
+
index: parseInt(index, 10),
|
1069
|
+
control: control === "1"
|
1070
|
+
};
|
1071
|
+
});
|
1072
|
+
});
|
1073
|
+
return results;
|
1074
|
+
}
|
962
1075
|
function encodeCookieType(type) {
|
963
1076
|
return Object.entries(type).reduce((acc, [key, value]) => {
|
964
1077
|
acc[key] = ntob(value);
|
@@ -1046,7 +1159,8 @@ var emptyVisitorData = () => ({
|
|
1046
1159
|
sessionScores: {},
|
1047
1160
|
tests: {},
|
1048
1161
|
consent: false,
|
1049
|
-
controlGroup: false
|
1162
|
+
controlGroup: false,
|
1163
|
+
personalizeVariants: {}
|
1050
1164
|
});
|
1051
1165
|
|
1052
1166
|
// src/storage/VisitorDataStore.ts
|
@@ -1095,6 +1209,25 @@ function applyCommandsToData(commands, state, inControlGroup) {
|
|
1095
1209
|
case "setcontrol":
|
1096
1210
|
newData.controlGroup = command.data;
|
1097
1211
|
break;
|
1212
|
+
case "setpersonalizecontrol":
|
1213
|
+
if (!newData.personalizeVariants) {
|
1214
|
+
newData.personalizeVariants = {};
|
1215
|
+
}
|
1216
|
+
if (!newData.personalizeVariants[command.data.personlizationName]) {
|
1217
|
+
newData.personalizeVariants[command.data.personlizationName] = [];
|
1218
|
+
}
|
1219
|
+
const existingDef = newData.personalizeVariants[command.data.personlizationName].find(
|
1220
|
+
(i) => i.index === command.data.index
|
1221
|
+
);
|
1222
|
+
if (!existingDef) {
|
1223
|
+
newData.personalizeVariants[command.data.personlizationName].push({
|
1224
|
+
index: command.data.index,
|
1225
|
+
control: command.data.control
|
1226
|
+
});
|
1227
|
+
} else {
|
1228
|
+
console.warn("Overwriting existing control group definition is not allowed");
|
1229
|
+
}
|
1230
|
+
break;
|
1098
1231
|
default:
|
1099
1232
|
throw new Error(`Unknown command`);
|
1100
1233
|
}
|
@@ -1456,7 +1589,7 @@ var Context = class {
|
|
1456
1589
|
* will NOT result in a recomputation of signal state.
|
1457
1590
|
*/
|
1458
1591
|
async update(newData) {
|
1459
|
-
var _a, _b, _c;
|
1592
|
+
var _a, _b, _c, _d;
|
1460
1593
|
const commands = [];
|
1461
1594
|
const newServerSideTests = {};
|
1462
1595
|
if ((_a = __privateGet(this, _serverTransitionState)) == null ? void 0 : _a.quirks) {
|
@@ -1486,6 +1619,17 @@ var Context = class {
|
|
1486
1619
|
);
|
1487
1620
|
}
|
1488
1621
|
}
|
1622
|
+
if ((_c = __privateGet(this, _serverTransitionState)) == null ? void 0 : _c.personalizeVariants) {
|
1623
|
+
Object.keys(__privateGet(this, _serverTransitionState).personalizeVariants).forEach((personalizationName) => {
|
1624
|
+
const variants = __privateGet(this, _serverTransitionState).personalizeVariants[personalizationName];
|
1625
|
+
variants.forEach((e) => {
|
1626
|
+
commands.push({
|
1627
|
+
type: "setpersonalizecontrol",
|
1628
|
+
data: { personlizationName: personalizationName, index: e.index, control: e.control }
|
1629
|
+
});
|
1630
|
+
});
|
1631
|
+
});
|
1632
|
+
}
|
1489
1633
|
try {
|
1490
1634
|
__privateGet(this, _mitt3).emit("log", [
|
1491
1635
|
"info",
|
@@ -1495,7 +1639,7 @@ var Context = class {
|
|
1495
1639
|
...newData,
|
1496
1640
|
// need to convert url to string so it can be json serialized
|
1497
1641
|
// to go over postMessage to chrome extension
|
1498
|
-
url: (
|
1642
|
+
url: (_d = newData.url) == null ? void 0 : _d.toString()
|
1499
1643
|
}
|
1500
1644
|
]);
|
1501
1645
|
if (newData.quirks) {
|
@@ -1577,6 +1721,13 @@ var Context = class {
|
|
1577
1721
|
}
|
1578
1722
|
]);
|
1579
1723
|
}
|
1724
|
+
getPersonalizeVariantControl(name, index) {
|
1725
|
+
var _a, _b, _c;
|
1726
|
+
const source = (_b = (_a = __privateGet(this, _serverTransitionState)) == null ? void 0 : _a.personalizeVariants) != null ? _b : this.storage.data.personalizeVariants;
|
1727
|
+
const variants = (_c = source == null ? void 0 : source[name]) != null ? _c : [];
|
1728
|
+
const variant = variants.find((v) => v.index === index);
|
1729
|
+
return variant == null ? void 0 : variant.control;
|
1730
|
+
}
|
1580
1731
|
/**
|
1581
1732
|
* Writes a message to the Context log sink.
|
1582
1733
|
* Used by Uniform internal SDK; not intended for public use.
|
@@ -1619,10 +1770,10 @@ var Context = class {
|
|
1619
1770
|
const previousPlacement = __privateGet(this, _pzCache)[options.name];
|
1620
1771
|
const eventData = {
|
1621
1772
|
name: options.name,
|
1622
|
-
variantIds: value.variations.map((variation) => {
|
1623
|
-
|
1624
|
-
|
1625
|
-
}),
|
1773
|
+
variantIds: value.variations.map((variation) => ({
|
1774
|
+
id: variation.id || "Unknown",
|
1775
|
+
control: variation.control
|
1776
|
+
})),
|
1626
1777
|
control: this.storage.data.controlGroup,
|
1627
1778
|
changed: true
|
1628
1779
|
};
|
@@ -1650,7 +1801,8 @@ var Context = class {
|
|
1650
1801
|
const transitionState = {
|
1651
1802
|
quirks: this.storage.data.quirks,
|
1652
1803
|
ssv: __privateGet(this, _scores),
|
1653
|
-
tests: {}
|
1804
|
+
tests: {},
|
1805
|
+
personalizeVariants: this.storage.data.personalizeVariants
|
1654
1806
|
};
|
1655
1807
|
const allTests = this.storage.data.tests;
|
1656
1808
|
Object.entries(allTests).map(([testName, testValue]) => {
|
@@ -1661,6 +1813,18 @@ var Context = class {
|
|
1661
1813
|
});
|
1662
1814
|
return transitionState;
|
1663
1815
|
}
|
1816
|
+
/** @deprecated */
|
1817
|
+
internal_processTestEvent(event) {
|
1818
|
+
if (event.variantId) {
|
1819
|
+
this.setTestVariantId(event.name, event.variantId);
|
1820
|
+
__privateMethod(this, _emitTest, emitTest_fn).call(this, event);
|
1821
|
+
}
|
1822
|
+
}
|
1823
|
+
/** @deprecated */
|
1824
|
+
internal_processPersonalizationEvent(event) {
|
1825
|
+
__privateGet(this, _pzCache)[event.name] = event.variantIds;
|
1826
|
+
__privateGet(this, _mitt3).emit("personalizationResult", event);
|
1827
|
+
}
|
1664
1828
|
};
|
1665
1829
|
_serverTransitionState = new WeakMap();
|
1666
1830
|
_scores = new WeakMap();
|
@@ -1694,7 +1858,7 @@ calculateScores_fn = function(newData) {
|
|
1694
1858
|
|
1695
1859
|
// src/devTools/enableContextDevTools.ts
|
1696
1860
|
var isBrowser = typeof top !== "undefined";
|
1697
|
-
function enableContextDevTools() {
|
1861
|
+
function enableContextDevTools(options) {
|
1698
1862
|
return {
|
1699
1863
|
logDrain: (message) => {
|
1700
1864
|
if (!isBrowser) {
|
@@ -1747,7 +1911,11 @@ function enableContextDevTools() {
|
|
1747
1911
|
return;
|
1748
1912
|
}
|
1749
1913
|
const message = event.data;
|
1750
|
-
await handleMessageFromDevTools(
|
1914
|
+
await handleMessageFromDevTools({
|
1915
|
+
message,
|
1916
|
+
context,
|
1917
|
+
afterMessageReceived: options == null ? void 0 : options.onAfterMessageReceived
|
1918
|
+
});
|
1751
1919
|
});
|
1752
1920
|
} catch (e) {
|
1753
1921
|
console.warn(
|
@@ -1767,26 +1935,35 @@ function enableContextDevTools() {
|
|
1767
1935
|
context.events.on("personalizationResult", onPersonalizationResult);
|
1768
1936
|
context.events.on("testResult", onTestResult);
|
1769
1937
|
context.events.on("scoresUpdated", onContextDataUpdated);
|
1770
|
-
context.storage.events.on("*", onContextDataUpdated);
|
1771
1938
|
return () => {
|
1772
1939
|
context.events.off("scoresUpdated", onContextDataUpdated);
|
1773
|
-
context.storage.events.off("*", onContextDataUpdated);
|
1774
1940
|
context.events.off("personalizationResult", onPersonalizationResult);
|
1775
1941
|
context.events.off("testResult", onTestResult);
|
1776
1942
|
};
|
1777
1943
|
}
|
1778
1944
|
};
|
1779
1945
|
}
|
1780
|
-
async function handleMessageFromDevTools(
|
1946
|
+
async function handleMessageFromDevTools({
|
1947
|
+
message,
|
1948
|
+
context,
|
1949
|
+
afterMessageReceived
|
1950
|
+
}) {
|
1951
|
+
let receivedUniformMessage = false;
|
1781
1952
|
if (message.type === "uniform-in:context:update" && message.newData) {
|
1953
|
+
receivedUniformMessage = true;
|
1782
1954
|
await context.update(message.newData);
|
1783
1955
|
}
|
1784
1956
|
if (message.type === "uniform-in:context:commands" && message.commands && Array.isArray(message.commands)) {
|
1957
|
+
receivedUniformMessage = true;
|
1785
1958
|
await context.storage.updateData(message.commands);
|
1786
1959
|
}
|
1787
1960
|
if (message.type === "uniform-in:context:forget") {
|
1961
|
+
receivedUniformMessage = true;
|
1788
1962
|
await context.forget(false);
|
1789
1963
|
}
|
1964
|
+
if (receivedUniformMessage && typeof afterMessageReceived === "function") {
|
1965
|
+
afterMessageReceived(message);
|
1966
|
+
}
|
1790
1967
|
}
|
1791
1968
|
|
1792
1969
|
// src/edge/index.ts
|