@uniformdev/context 19.135.0 → 19.135.1-alpha.11

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/dist/index.js CHANGED
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __typeError = (msg) => {
9
+ throw TypeError(msg);
10
+ };
8
11
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
12
  var __export = (target, all) => {
10
13
  for (var name in all)
@@ -27,32 +30,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
30
  mod
28
31
  ));
29
32
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
- var __publicField = (obj, key, value) => {
31
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
32
- return value;
33
- };
34
- var __accessCheck = (obj, member, msg) => {
35
- if (!member.has(obj))
36
- throw TypeError("Cannot " + msg);
37
- };
38
- var __privateGet = (obj, member, getter) => {
39
- __accessCheck(obj, member, "read from private field");
40
- return getter ? getter.call(obj) : member.get(obj);
41
- };
42
- var __privateAdd = (obj, member, value) => {
43
- if (member.has(obj))
44
- throw TypeError("Cannot add the same private member more than once");
45
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
46
- };
47
- var __privateSet = (obj, member, value, setter) => {
48
- __accessCheck(obj, member, "write to private field");
49
- setter ? setter.call(obj, value) : member.set(obj, value);
50
- return value;
51
- };
52
- var __privateMethod = (obj, member, method) => {
53
- __accessCheck(obj, member, "access private method");
54
- return method;
55
- };
33
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
34
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
35
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
36
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
37
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
38
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
56
39
 
57
40
  // src/index.ts
58
41
  var src_exports = {};
@@ -64,22 +47,30 @@ __export(src_exports, {
64
47
  EdgeNodeTagName: () => EdgeNodeTagName,
65
48
  EdgeTransitionDataStore: () => EdgeTransitionDataStore,
66
49
  GroupCriteriaEvaluator: () => GroupCriteriaEvaluator,
50
+ KV_SEP: () => KV_SEP,
67
51
  ManifestInstance: () => ManifestInstance,
52
+ PAIR_SEP: () => PAIR_SEP,
68
53
  SERVER_STATE_ID: () => SERVER_STATE_ID,
69
54
  ScriptType: () => ScriptType,
55
+ TYPE_SEP: () => TYPE_SEP,
70
56
  TransitionDataStore: () => TransitionDataStore,
71
57
  UNIFORM_DEFAULT_COOKIE_NAME: () => UNIFORM_DEFAULT_COOKIE_NAME,
72
58
  VisitorDataStore: () => VisitorDataStore,
59
+ areCommandsEqual: () => areCommandsEqual,
73
60
  computeAggregateDimensions: () => computeAggregateDimensions,
74
61
  cookieEvaluator: () => cookieEvaluator,
75
62
  createConsoleLogDrain: () => createConsoleLogDrain,
76
63
  createDebugConsoleLogDrain: () => createDebugConsoleLogDrain,
77
64
  createLinearDecay: () => createLinearDecay,
78
65
  currentPageEvaluator: () => currentPageEvaluator,
66
+ decodeCookieType: () => decodeCookieType,
67
+ decodePersonalizeVariants: () => decodePersonalizeVariants,
79
68
  emptyVisitorData: () => emptyVisitorData,
80
69
  enableConsoleLogDrain: () => enableConsoleLogDrain,
81
70
  enableContextDevTools: () => enableContextDevTools,
82
71
  enableDebugConsoleLogDrain: () => enableDebugConsoleLogDrain,
72
+ enableUniformInsights: () => enableUniformInsights,
73
+ encodeCookieType: () => encodeCookieType,
83
74
  evaluateVariantMatch: () => evaluateVariantMatch,
84
75
  eventEvaluator: () => eventEvaluator,
85
76
  explainStringMatch: () => explainStringMatch,
@@ -88,10 +79,16 @@ __export(src_exports, {
88
79
  isStringMatch: () => isStringMatch,
89
80
  pageViewCountDimension: () => pageViewCountDimension,
90
81
  pageViewCountEvaluator: () => pageViewCountEvaluator,
82
+ parseCookieScores: () => parseCookieScores,
83
+ parseCookieType: () => parseCookieType,
91
84
  parseQuickConnect: () => parseQuickConnect,
85
+ parseScoreCookie: () => parseScoreCookie,
92
86
  personalizeVariations: () => personalizeVariations,
93
87
  queryStringEvaluator: () => queryStringEvaluator,
94
88
  quirkEvaluator: () => quirkEvaluator,
89
+ serializeCookie: () => serializeCookie,
90
+ serializeCookieType: () => serializeCookieType,
91
+ serializePersonalizeVariants: () => serializePersonalizeVariants,
95
92
  serializeQuickConnect: () => serializeQuickConnect,
96
93
  testVariations: () => testVariations
97
94
  });
@@ -146,12 +143,34 @@ function computeAggregateDimension(primitiveScores, aggregateDimension, allAggre
146
143
  // src/manifest/constants.ts
147
144
  var ENR_SEPARATOR = "_";
148
145
 
146
+ // src/manifest/goals/evaluators/SignalGoalEvaluator.ts
147
+ var _id;
148
+ var SignalGoalEvaluator = class {
149
+ constructor(options) {
150
+ __privateAdd(this, _id);
151
+ __privateSet(this, _id, options.id);
152
+ }
153
+ get id() {
154
+ return __privateGet(this, _id);
155
+ }
156
+ evaluate({ scores, quirks }) {
157
+ const score = scores == null ? void 0 : scores[__privateGet(this, _id)];
158
+ const key = `goal_${__privateGet(this, _id)}_triggered`;
159
+ const hasGoalTriggered = (quirks == null ? void 0 : quirks[key]) === "1";
160
+ return {
161
+ key,
162
+ triggered: typeof score === "number" && !hasGoalTriggered
163
+ };
164
+ }
165
+ };
166
+ _id = new WeakMap();
167
+
149
168
  // src/manifest/signals/SignalInstance.ts
150
169
  var _evaluator, _onLogMessage;
151
170
  var SignalInstance = class {
152
171
  constructor(data, evaluator, onLogMessage) {
153
- __privateAdd(this, _evaluator, void 0);
154
- __privateAdd(this, _onLogMessage, void 0);
172
+ __privateAdd(this, _evaluator);
173
+ __privateAdd(this, _onLogMessage);
155
174
  __publicField(this, "signal");
156
175
  this.signal = data;
157
176
  __privateSet(this, _evaluator, evaluator);
@@ -203,7 +222,7 @@ var rollForControlGroup = (value) => {
203
222
  };
204
223
 
205
224
  // src/manifest/ManifestInstance.ts
206
- var _mf, _signalInstances, _onLogMessage2;
225
+ var _mf, _signalInstances, _goalEvaluators, _onLogMessage2;
207
226
  var ManifestInstance = class {
208
227
  constructor({
209
228
  manifest,
@@ -213,15 +232,21 @@ var ManifestInstance = class {
213
232
  }
214
233
  }) {
215
234
  __publicField(this, "data");
216
- __privateAdd(this, _mf, void 0);
217
- __privateAdd(this, _signalInstances, void 0);
218
- __privateAdd(this, _onLogMessage2, void 0);
219
- var _a, _b, _c;
235
+ __privateAdd(this, _mf);
236
+ __privateAdd(this, _signalInstances);
237
+ __privateAdd(this, _goalEvaluators, []);
238
+ __privateAdd(this, _onLogMessage2);
239
+ var _a, _b, _c, _d, _e;
220
240
  __privateSet(this, _mf, (_a = manifest.project) != null ? _a : {});
221
241
  this.data = manifest;
222
242
  __privateSet(this, _signalInstances, Object.entries((_c = (_b = __privateGet(this, _mf).pz) == null ? void 0 : _b.sig) != null ? _c : []).map(
223
243
  ([id, signal]) => new SignalInstance({ ...signal, id }, evaluator, onLogMessage)
224
244
  ));
245
+ Object.entries((_e = (_d = __privateGet(this, _mf).pz) == null ? void 0 : _d.sig) != null ? _e : []).forEach(([id, signal]) => {
246
+ if (signal.conversion) {
247
+ __privateGet(this, _goalEvaluators).push(new SignalGoalEvaluator({ id, signal }));
248
+ }
249
+ });
225
250
  __privateSet(this, _onLogMessage2, onLogMessage);
226
251
  }
227
252
  rollForControlGroup() {
@@ -249,6 +274,28 @@ var ManifestInstance = class {
249
274
  }
250
275
  return commands;
251
276
  }
277
+ computeGoals(data) {
278
+ const commands = [];
279
+ __privateGet(this, _goalEvaluators).forEach((evaluator) => {
280
+ const { triggered, key } = evaluator.evaluate(data);
281
+ if (triggered) {
282
+ commands.push({
283
+ type: "setgoal",
284
+ data: {
285
+ goal: evaluator.id
286
+ }
287
+ });
288
+ commands.push({
289
+ type: "setquirk",
290
+ data: {
291
+ key,
292
+ value: "1"
293
+ }
294
+ });
295
+ }
296
+ });
297
+ return commands;
298
+ }
252
299
  /**
253
300
  * Computes aggregated scores based on other dimensions
254
301
  */
@@ -267,6 +314,7 @@ var ManifestInstance = class {
267
314
  };
268
315
  _mf = new WeakMap();
269
316
  _signalInstances = new WeakMap();
317
+ _goalEvaluators = new WeakMap();
270
318
  _onLogMessage2 = new WeakMap();
271
319
 
272
320
  // src/manifest/signals/criteria/evaluators/cookieEvaluator.ts
@@ -504,7 +552,7 @@ var quirkEvaluator = ({ update, criteria, signal, onLogMessage }) => {
504
552
  var _evaluators;
505
553
  var GroupCriteriaEvaluator = class {
506
554
  constructor(criteriaEvaluators) {
507
- __privateAdd(this, _evaluators, void 0);
555
+ __privateAdd(this, _evaluators);
508
556
  __privateSet(this, _evaluators, criteriaEvaluators);
509
557
  }
510
558
  evaluate(update, crit, commands, signal, onLogMessage) {
@@ -684,75 +732,66 @@ function personalizeVariations({
684
732
  take = 1,
685
733
  onLogMessage
686
734
  }) {
687
- var _a, _b, _c, _d;
735
+ var _a, _b, _c;
688
736
  onLogMessage == null ? void 0 : onLogMessage(["info", 300, "GROUP", { name, take }]);
689
737
  try {
690
- const control = (_a = context.storage.data.controlGroup) != null ? _a : false;
691
- const results = [];
692
- let personalized = false;
693
- const scores = context.scores;
694
- let index = 0;
738
+ const variantMatches = [];
695
739
  const defaultVariants = [];
696
740
  for (const variant of variations) {
697
- if (!((_b = variant.pz) == null ? void 0 : _b.crit.length)) {
741
+ if ((_a = variant.pz) == null ? void 0 : _a.crit.length) {
742
+ if (variantMatches.length !== take && evaluateVariantMatch(variant.id, variant.pz, context.scores, onLogMessage)) {
743
+ variantMatches.push(variant);
744
+ }
745
+ } else {
698
746
  defaultVariants.push(variant);
699
747
  }
700
748
  }
701
- for (const variant of variations) {
702
- const currentIndex = index++;
703
- if (results.length === take) {
704
- break;
705
- }
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 }]);
708
- onLogMessage == null ? void 0 : onLogMessage(["info", 302, { matched: true, description: "default variation" }]);
709
- onLogMessage == null ? void 0 : onLogMessage(["info", 303, true]);
710
- onLogMessage == null ? void 0 : onLogMessage(["info", 301, "ENDGROUP"]);
711
- results.push({
712
- ...variant,
713
- control: false
714
- });
715
- continue;
716
- }
717
- if (control) {
718
- continue;
719
- }
720
- if (evaluateVariantMatch(variant.id, variant.pz, scores, onLogMessage)) {
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
- }
749
+ const result = [];
750
+ for (let i = 0; i < variantMatches.length; i++) {
751
+ let isControl = (_b = context.storage.data.controlGroup) != null ? _b : false;
752
+ const variant = variantMatches[i];
753
+ if (!isControl && typeof ((_c = variant.pz) == null ? void 0 : _c.control) === "number") {
754
+ isControl = context.getPersonalizeVariantControl(name, i);
755
+ if (typeof isControl === "undefined") {
756
+ isControl = rollForControlGroup(variant.pz.control);
757
+ context.storage.updateData([
758
+ {
759
+ type: "setpersonalizecontrol",
760
+ data: {
761
+ personlizationName: name,
762
+ index: i,
763
+ control: isControl
736
764
  }
737
- ]);
738
- }
739
- if (isControl) {
740
- variantToAdd = {
741
- ...defaultVariants[0],
742
- id: variant.id
743
- };
744
- }
765
+ }
766
+ ]);
745
767
  }
746
- personalized = personalized || typeof variantToAdd.pz !== "undefined";
747
- results.push({
748
- ...variantToAdd,
749
- control: isControl
750
- });
768
+ }
769
+ let variantToAdd = variant;
770
+ if (isControl) {
771
+ const defaultReplacement = defaultVariants.shift();
772
+ if (defaultReplacement) {
773
+ variantToAdd = {
774
+ ...defaultReplacement,
775
+ id: variant.id
776
+ };
777
+ } else {
778
+ variantToAdd = void 0;
779
+ }
780
+ }
781
+ if (variantToAdd) {
782
+ result.push({ ...variantToAdd, control: isControl });
751
783
  }
752
784
  }
785
+ while (result.length < take && defaultVariants.length) {
786
+ result.push({ ...defaultVariants.shift(), control: false });
787
+ }
788
+ const personalized = result.some((v) => {
789
+ var _a2;
790
+ return (_a2 = v.pz) == null ? void 0 : _a2.crit.length;
791
+ });
753
792
  return {
754
793
  personalized,
755
- variations: results
794
+ variations: result
756
795
  };
757
796
  } finally {
758
797
  onLogMessage == null ? void 0 : onLogMessage(["info", 300, "ENDGROUP"]);
@@ -820,7 +859,7 @@ var testVariations = ({
820
859
  let distributionOffset = 0;
821
860
  selectedVariant = variations.find((variant, index) => {
822
861
  const distribution = distributions[index];
823
- if (random > distributionOffset && random <= distributionOffset + distribution) {
862
+ if ((random > distributionOffset || random === 0) && random <= distributionOffset + distribution) {
824
863
  return variant;
825
864
  }
826
865
  distributionOffset += distribution;
@@ -842,18 +881,27 @@ var testVariations = ({
842
881
  }
843
882
  };
844
883
 
884
+ // src/storage/commands.ts
885
+ var import_lite2 = require("dequal/lite");
886
+ var areCommandsEqual = (a, b) => {
887
+ if (a.type !== b.type) {
888
+ return false;
889
+ }
890
+ return (0, import_lite2.dequal)(a, b);
891
+ };
892
+
845
893
  // src/storage/CookieTransitionDataStore.ts
846
894
  var import_js_cookie = __toESM(require("js-cookie"));
847
895
 
848
896
  // src/storage/TransitionDataStore.ts
849
- var import_lite2 = require("dequal/lite");
897
+ var import_lite3 = require("dequal/lite");
850
898
  var import_mitt = __toESM(require("mitt"));
851
899
  var SERVER_STATE_ID = "__UNIFORM_DATA__";
852
900
  var _data, _initialData, _mitt;
853
901
  var TransitionDataStore = class {
854
902
  constructor({ initialData }) {
855
- __privateAdd(this, _data, void 0);
856
- __privateAdd(this, _initialData, void 0);
903
+ __privateAdd(this, _data);
904
+ __privateAdd(this, _initialData);
857
905
  __privateAdd(this, _mitt, (0, import_mitt.default)());
858
906
  /**
859
907
  * Subscribe to events from the transition storage
@@ -892,7 +940,7 @@ var TransitionDataStore = class {
892
940
  await this.handleDelete(fromAllDevices);
893
941
  }
894
942
  signalAsyncDataUpdate(newScores) {
895
- if ((0, import_lite2.dequal)(this.data, newScores)) {
943
+ if ((0, import_lite3.dequal)(this.data, newScores)) {
896
944
  return;
897
945
  }
898
946
  __privateSet(this, _data, newScores);
@@ -924,8 +972,7 @@ for (let i = 0; i < alphabet.length; i++) {
924
972
  s2b[alphabet.charCodeAt(i)] = i;
925
973
  }
926
974
  var ntob = (number) => {
927
- if (number < 0)
928
- return `-${ntob(-number)}`;
975
+ if (number < 0) return `-${ntob(-number)}`;
929
976
  let lo = number >>> 0;
930
977
  let hi = number / 4294967296 >>> 0;
931
978
  let right = "";
@@ -964,20 +1011,18 @@ var CookieTransitionDataStore = class extends TransitionDataStore {
964
1011
  super({
965
1012
  initialData: ssr ? parseScoreCookie(serverCookieValue) : void 0
966
1013
  });
967
- __privateAdd(this, _cookieName, void 0);
968
- __privateAdd(this, _cookieAttributes, void 0);
1014
+ __privateAdd(this, _cookieName);
1015
+ __privateAdd(this, _cookieAttributes);
969
1016
  __privateSet(this, _cookieName, cookieName);
970
1017
  __privateSet(this, _cookieAttributes, cookieAttributes);
971
1018
  }
972
1019
  handleDelete() {
973
- if (ssr)
974
- return Promise.resolve();
1020
+ if (ssr) return Promise.resolve();
975
1021
  import_js_cookie.default.remove(__privateGet(this, _cookieName));
976
1022
  return Promise.resolve();
977
1023
  }
978
1024
  async handleUpdateData(_, computedValue) {
979
- if (ssr)
980
- return;
1025
+ if (ssr) return;
981
1026
  if (computedValue.consent) {
982
1027
  import_js_cookie.default.set(__privateGet(this, _cookieName), serializeCookie(computedValue), __privateGet(this, _cookieAttributes));
983
1028
  } else {
@@ -991,31 +1036,40 @@ var TYPE_SEP = "~";
991
1036
  var PAIR_SEP = "!";
992
1037
  var KV_SEP = "-";
993
1038
  function parseScoreCookie(cookieValue) {
994
- if (!cookieValue)
995
- return;
1039
+ if (!cookieValue) return;
996
1040
  const types = cookieValue.split(TYPE_SEP);
997
- if (types.length > 5)
998
- return;
1041
+ if (types.length > 5) return;
999
1042
  const [abTestData, sessionScores, visitorScores, controlGroup, personalizeVariants] = types;
1000
1043
  const data = {
1001
1044
  // this is true since we're reading a cookie, which wouldn't exist if consent wasn't given
1002
1045
  consent: true,
1003
- sessionScores: decodeCookieType(parseCookieType(sessionScores)),
1004
- scores: decodeCookieType(parseCookieType(visitorScores)),
1046
+ sessionScores: decodeCookieType(parseCookieScores(sessionScores)),
1047
+ scores: decodeCookieType(parseCookieScores(visitorScores)),
1005
1048
  tests: parseCookieType(abTestData),
1006
1049
  controlGroup: controlGroup === "1",
1007
1050
  personalizeVariants: decodePersonalizeVariants(personalizeVariants)
1008
1051
  };
1009
1052
  return data;
1010
1053
  }
1054
+ function parseCookieScores(type) {
1055
+ if (!type) {
1056
+ return {};
1057
+ }
1058
+ const pairs = type.split(PAIR_SEP).map((pair) => pair.split(KV_SEP));
1059
+ return pairs.reduce((acc, cur) => {
1060
+ if (cur.length < 2) return acc;
1061
+ const key = cur.slice(0, -1).join(KV_SEP);
1062
+ acc[key] = cur[cur.length - 1];
1063
+ return acc;
1064
+ }, {});
1065
+ }
1011
1066
  function parseCookieType(type) {
1012
1067
  if (!type) {
1013
1068
  return {};
1014
1069
  }
1015
1070
  const pairs = type.split(PAIR_SEP).map((pair) => pair.split(KV_SEP));
1016
1071
  return pairs.reduce((acc, cur) => {
1017
- if (cur.length < 2)
1018
- return acc;
1072
+ if (cur.length < 2) return acc;
1019
1073
  acc[cur[0]] = cur.slice(1).join("-");
1020
1074
  return acc;
1021
1075
  }, {});
@@ -1083,13 +1137,13 @@ function serializeCookieType(type) {
1083
1137
  }
1084
1138
 
1085
1139
  // src/storage/EdgeTransitionDataStore.ts
1086
- var _fetchData, fetchData_fn;
1140
+ var _EdgeTransitionDataStore_instances, fetchData_fn;
1087
1141
  var EdgeTransitionDataStore = class extends TransitionDataStore {
1088
1142
  constructor({ serverCookieValue, visitorIdCookieName = "ufvi", ...base }) {
1089
1143
  super(base);
1090
- __privateAdd(this, _fetchData);
1144
+ __privateAdd(this, _EdgeTransitionDataStore_instances);
1091
1145
  if (!base.initialData) {
1092
- __privateMethod(this, _fetchData, fetchData_fn).call(this).catch((err) => {
1146
+ __privateMethod(this, _EdgeTransitionDataStore_instances, fetchData_fn).call(this).catch((err) => {
1093
1147
  console.error(err);
1094
1148
  });
1095
1149
  }
@@ -1108,7 +1162,7 @@ var EdgeTransitionDataStore = class extends TransitionDataStore {
1108
1162
  }
1109
1163
  }
1110
1164
  };
1111
- _fetchData = new WeakSet();
1165
+ _EdgeTransitionDataStore_instances = new WeakSet();
1112
1166
  fetchData_fn = async function() {
1113
1167
  const serviceData = await new Promise((resolve) => {
1114
1168
  setTimeout(() => {
@@ -1158,22 +1212,23 @@ var emptyVisitorData = () => ({
1158
1212
  scores: {},
1159
1213
  sessionScores: {},
1160
1214
  tests: {},
1215
+ goals: {},
1161
1216
  consent: false,
1162
1217
  controlGroup: false,
1163
1218
  personalizeVariants: {}
1164
1219
  });
1165
1220
 
1166
1221
  // src/storage/VisitorDataStore.ts
1167
- var import_lite3 = require("dequal/lite");
1222
+ var import_lite4 = require("dequal/lite");
1168
1223
  var import_mitt2 = __toESM(require("mitt"));
1169
1224
 
1170
1225
  // src/storage/util/applyCommandsToData.ts
1171
1226
  var import_rfdc = __toESM(require("rfdc"));
1172
1227
  var clone = (0, import_rfdc.default)();
1173
- function applyCommandsToData(commands, state, inControlGroup) {
1228
+ function applyCommandsToData(commands, state) {
1174
1229
  const newData = state ? clone(state) : emptyVisitorData();
1175
1230
  commands.forEach((command) => {
1176
- var _a, _b;
1231
+ var _a, _b, _c;
1177
1232
  switch (command.type) {
1178
1233
  case "consent":
1179
1234
  newData.consent = command.data;
@@ -1185,8 +1240,6 @@ function applyCommandsToData(commands, state, inControlGroup) {
1185
1240
  newData.tests[command.data.test] = command.data.variant;
1186
1241
  break;
1187
1242
  case "modscore":
1188
- if (inControlGroup)
1189
- break;
1190
1243
  const delta = Number(command.data.delta);
1191
1244
  if (isNaN(delta)) {
1192
1245
  throw new Error("Non-number delta received");
@@ -1195,8 +1248,6 @@ function applyCommandsToData(commands, state, inControlGroup) {
1195
1248
  newData.scores[command.data.dimension] = existing + delta;
1196
1249
  break;
1197
1250
  case "modscoreS":
1198
- if (inControlGroup)
1199
- break;
1200
1251
  const deltaS = Number(command.data.delta);
1201
1252
  if (isNaN(deltaS)) {
1202
1253
  throw new Error("Non-number delta received");
@@ -1228,6 +1279,10 @@ function applyCommandsToData(commands, state, inControlGroup) {
1228
1279
  console.warn("Overwriting existing control group definition is not allowed");
1229
1280
  }
1230
1281
  break;
1282
+ case "setgoal":
1283
+ newData.goals = (_c = newData.goals) != null ? _c : {};
1284
+ newData.goals[command.data.goal] = true;
1285
+ break;
1231
1286
  default:
1232
1287
  throw new Error(`Unknown command`);
1233
1288
  }
@@ -1236,71 +1291,65 @@ function applyCommandsToData(commands, state, inControlGroup) {
1236
1291
  }
1237
1292
 
1238
1293
  // src/storage/util/LocalStorage.ts
1294
+ var _LocalStorage_instances, key_fn;
1239
1295
  var LocalStorage = class {
1240
- constructor() {
1296
+ constructor(partitionKey) {
1297
+ this.partitionKey = partitionKey;
1298
+ __privateAdd(this, _LocalStorage_instances);
1241
1299
  __publicField(this, "inMemoryFallback", {});
1242
1300
  __publicField(this, "hasLocalStorageObject", typeof localStorage !== "undefined");
1243
1301
  }
1244
1302
  get(key) {
1245
- const fallbackValue = this.inMemoryFallback[key];
1303
+ const keyValue = __privateMethod(this, _LocalStorage_instances, key_fn).call(this, key);
1304
+ const fallbackValue = this.inMemoryFallback[keyValue];
1246
1305
  if (!this.hasLocalStorageObject || fallbackValue) {
1247
1306
  return fallbackValue;
1248
1307
  }
1249
1308
  try {
1250
- const value = localStorage.getItem(key);
1309
+ const value = localStorage.getItem(keyValue);
1251
1310
  return value ? JSON.parse(value) : void 0;
1252
1311
  } catch (e) {
1253
1312
  return fallbackValue;
1254
1313
  }
1255
1314
  }
1256
1315
  set(key, value, storageConsent) {
1257
- this.inMemoryFallback[key] = value;
1316
+ const keyValue = __privateMethod(this, _LocalStorage_instances, key_fn).call(this, key);
1317
+ this.inMemoryFallback[keyValue] = value;
1258
1318
  if (!this.hasLocalStorageObject || !storageConsent) {
1259
1319
  return;
1260
1320
  }
1261
1321
  try {
1262
- localStorage.setItem(key, JSON.stringify(value));
1322
+ localStorage.setItem(keyValue, JSON.stringify(value));
1263
1323
  } catch (e) {
1264
1324
  console.warn(e);
1265
1325
  }
1266
1326
  }
1267
1327
  delete(key, leaveInMemory) {
1328
+ const keyValue = __privateMethod(this, _LocalStorage_instances, key_fn).call(this, key);
1268
1329
  if (!leaveInMemory) {
1269
- delete this.inMemoryFallback[key];
1330
+ delete this.inMemoryFallback[keyValue];
1270
1331
  }
1271
1332
  try {
1272
- localStorage.removeItem(key);
1333
+ localStorage.removeItem(keyValue);
1273
1334
  } catch (e) {
1274
1335
  }
1275
1336
  }
1276
1337
  };
1338
+ _LocalStorage_instances = new WeakSet();
1339
+ key_fn = function(key) {
1340
+ return this.partitionKey ? `${this.partitionKey}.${key}` : key;
1341
+ };
1277
1342
 
1278
1343
  // src/storage/VisitorDataStore.ts
1279
1344
  var STORAGE_KEY = "ufvisitor";
1280
- var _mitt2, _persist, _visitTimeout, _options, _currentData, currentData_get, _replaceData, replaceData_fn, _setVisitTimeout, setVisitTimeout_fn, _isExpired, isExpired_fn, _handleCaps, handleCaps_fn, _defaultData, defaultData_fn;
1345
+ var _mitt2, _persist, _visitTimeout, _options, _VisitorDataStore_instances, currentData_get, replaceData_fn, setVisitTimeout_fn, isExpired_fn, handleCaps_fn, defaultData_fn;
1281
1346
  var VisitorDataStore = class {
1282
1347
  constructor(options) {
1283
- /** Gets the current client-side storage data. This property is always up to date. */
1284
- __privateAdd(this, _currentData);
1285
- /**
1286
- * IMPORTANT: This function mutates the input data. This is done,
1287
- * because all the sources that call it have either already spread or cloned
1288
- * the data, so we can safely mutate it for better perf.
1289
- */
1290
- __privateAdd(this, _replaceData);
1291
- __privateAdd(this, _setVisitTimeout);
1292
- __privateAdd(this, _isExpired);
1293
- /**
1294
- * IMPORTANT: This function mutates the input data. This is done,
1295
- * because all the sources that call it have either already spread or cloned
1296
- * the data, so we can safely mutate it for better perf.
1297
- */
1298
- __privateAdd(this, _handleCaps);
1299
- __privateAdd(this, _defaultData);
1348
+ __privateAdd(this, _VisitorDataStore_instances);
1300
1349
  __privateAdd(this, _mitt2, (0, import_mitt2.default)());
1301
- __privateAdd(this, _persist, new LocalStorage());
1302
- __privateAdd(this, _visitTimeout, void 0);
1303
- __privateAdd(this, _options, void 0);
1350
+ __privateAdd(this, _persist);
1351
+ __privateAdd(this, _visitTimeout);
1352
+ __privateAdd(this, _options);
1304
1353
  /**
1305
1354
  * Subscribe to events from storage
1306
1355
  */
@@ -1309,8 +1358,9 @@ var VisitorDataStore = class {
1309
1358
  off: __privateGet(this, _mitt2).off
1310
1359
  });
1311
1360
  __privateSet(this, _options, options);
1312
- if (!__privateGet(this, _currentData, currentData_get)) {
1313
- __privateMethod(this, _replaceData, replaceData_fn).call(this, __privateMethod(this, _defaultData, defaultData_fn).call(this), true);
1361
+ __privateSet(this, _persist, new LocalStorage(options.partitionKey));
1362
+ if (!__privateGet(this, _VisitorDataStore_instances, currentData_get)) {
1363
+ __privateMethod(this, _VisitorDataStore_instances, replaceData_fn).call(this, __privateMethod(this, _VisitorDataStore_instances, defaultData_fn).call(this), true);
1314
1364
  }
1315
1365
  if (options.transitionStore) {
1316
1366
  const serverToClientTransitionState = options.transitionStore.getClientTransitionState();
@@ -1318,17 +1368,17 @@ var VisitorDataStore = class {
1318
1368
  options.onServerTransitionReceived(serverToClientTransitionState);
1319
1369
  }
1320
1370
  options.transitionStore.events.on("dataUpdatedAsync", (data) => {
1321
- __privateMethod(this, _replaceData, replaceData_fn).call(this, {
1322
- ...__privateGet(this, _currentData, currentData_get).visitorData,
1371
+ __privateMethod(this, _VisitorDataStore_instances, replaceData_fn).call(this, {
1372
+ ...__privateGet(this, _VisitorDataStore_instances, currentData_get).visitorData,
1323
1373
  ...data
1324
1374
  });
1325
1375
  });
1326
1376
  const transitionData = options.transitionStore.data;
1327
1377
  if (transitionData) {
1328
- __privateMethod(this, _replaceData, replaceData_fn).call(
1378
+ __privateMethod(this, _VisitorDataStore_instances, replaceData_fn).call(
1329
1379
  this,
1330
1380
  // we know _currentData is not empty because we inited it above if it was
1331
- { ...__privateGet(this, _currentData, currentData_get).visitorData, ...transitionData },
1381
+ { ...__privateGet(this, _VisitorDataStore_instances, currentData_get).visitorData, ...transitionData },
1332
1382
  true
1333
1383
  );
1334
1384
  }
@@ -1336,13 +1386,13 @@ var VisitorDataStore = class {
1336
1386
  }
1337
1387
  /** Gets the current visitor data. This property is always up to date. */
1338
1388
  get data() {
1339
- var _a, _b;
1340
- const data = __privateGet(this, _currentData, currentData_get);
1341
- if (__privateMethod(this, _isExpired, isExpired_fn).call(this, data)) {
1389
+ var _a, _b, _c;
1390
+ const data = (_a = __privateGet(this, _VisitorDataStore_instances, currentData_get)) != null ? _a : { visitorData: __privateMethod(this, _VisitorDataStore_instances, defaultData_fn).call(this), updated: (/* @__PURE__ */ new Date()).getTime() };
1391
+ if (__privateMethod(this, _VisitorDataStore_instances, isExpired_fn).call(this, data)) {
1342
1392
  const { sessionScores, ...newData } = data.visitorData;
1343
- __privateMethod(this, _replaceData, replaceData_fn).call(this, { ...newData, sessionScores: {} });
1344
- (_b = (_a = __privateGet(this, _options)).onLogMessage) == null ? void 0 : _b.call(_a, ["info", 120]);
1345
- return __privateGet(this, _currentData, currentData_get).visitorData;
1393
+ __privateMethod(this, _VisitorDataStore_instances, replaceData_fn).call(this, { ...newData, sessionScores: {} });
1394
+ (_c = (_b = __privateGet(this, _options)).onLogMessage) == null ? void 0 : _c.call(_b, ["info", 120]);
1395
+ return __privateGet(this, _VisitorDataStore_instances, currentData_get).visitorData;
1346
1396
  }
1347
1397
  return data.visitorData;
1348
1398
  }
@@ -1354,17 +1404,18 @@ var VisitorDataStore = class {
1354
1404
  }
1355
1405
  /** Push data update command(s) into the visitor data */
1356
1406
  async updateData(commands) {
1357
- var _a, _b, _c, _d;
1407
+ var _a, _b, _c;
1358
1408
  if (commands.length === 0) {
1359
1409
  return;
1360
1410
  }
1361
1411
  (_b = (_a = __privateGet(this, _options)).onLogMessage) == null ? void 0 : _b.call(_a, ["debug", 101, commands]);
1362
- const newData = applyCommandsToData(commands, this.data, (_c = __privateGet(this, _currentData, currentData_get)) == null ? void 0 : _c.visitorData.controlGroup);
1412
+ const newData = applyCommandsToData(commands, this.data);
1363
1413
  if (commands.some((c) => c.type === "consent" && !c.data)) {
1364
1414
  __privateGet(this, _persist).delete(STORAGE_KEY, true);
1365
1415
  }
1366
- __privateMethod(this, _replaceData, replaceData_fn).call(this, newData);
1367
- await ((_d = __privateGet(this, _options).transitionStore) == null ? void 0 : _d.updateData(commands, __privateGet(this, _currentData, currentData_get).visitorData));
1416
+ __privateMethod(this, _VisitorDataStore_instances, replaceData_fn).call(this, newData);
1417
+ await ((_c = __privateGet(this, _options).transitionStore) == null ? void 0 : _c.updateData(commands, __privateGet(this, _VisitorDataStore_instances, currentData_get).visitorData));
1418
+ __privateGet(this, _mitt2).emit("commandsExecuted", commands);
1368
1419
  }
1369
1420
  /**
1370
1421
  * Deletes visitor data (forgetting them)
@@ -1377,7 +1428,7 @@ var VisitorDataStore = class {
1377
1428
  try {
1378
1429
  __privateGet(this, _persist).delete(STORAGE_KEY, false);
1379
1430
  await ((_c = __privateGet(this, _options).transitionStore) == null ? void 0 : _c.delete(fromAllDevices));
1380
- __privateMethod(this, _replaceData, replaceData_fn).call(this, __privateMethod(this, _defaultData, defaultData_fn).call(this));
1431
+ __privateMethod(this, _VisitorDataStore_instances, replaceData_fn).call(this, __privateMethod(this, _VisitorDataStore_instances, defaultData_fn).call(this));
1381
1432
  } finally {
1382
1433
  (_e = (_d = __privateGet(this, _options)).onLogMessage) == null ? void 0 : _e.call(_d, ["info", 103, "ENDGROUP"]);
1383
1434
  }
@@ -1387,38 +1438,38 @@ _mitt2 = new WeakMap();
1387
1438
  _persist = new WeakMap();
1388
1439
  _visitTimeout = new WeakMap();
1389
1440
  _options = new WeakMap();
1390
- _currentData = new WeakSet();
1441
+ _VisitorDataStore_instances = new WeakSet();
1391
1442
  currentData_get = function() {
1392
1443
  return __privateGet(this, _persist).get(STORAGE_KEY);
1393
1444
  };
1394
- _replaceData = new WeakSet();
1445
+ /**
1446
+ * IMPORTANT: This function mutates the input data. This is done,
1447
+ * because all the sources that call it have either already spread or cloned
1448
+ * the data, so we can safely mutate it for better perf.
1449
+ */
1395
1450
  replaceData_fn = function(data, quiet = false) {
1396
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1397
- const oldData = __privateGet(this, _currentData, currentData_get);
1451
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
1452
+ const oldData = __privateGet(this, _VisitorDataStore_instances, currentData_get);
1398
1453
  const now = Date.now();
1399
- if (data.controlGroup) {
1400
- data.scores = {};
1401
- data.sessionScores = {};
1402
- } else {
1403
- __privateMethod(this, _handleCaps, handleCaps_fn).call(this, data.scores);
1404
- __privateMethod(this, _handleCaps, handleCaps_fn).call(this, data.sessionScores);
1405
- (_b = (_a = __privateGet(this, _options)).decay) == null ? void 0 : _b.call(_a, {
1406
- now,
1407
- lastUpd: oldData == null ? void 0 : oldData.updated,
1408
- scores: data.scores,
1409
- sessionScores: data.sessionScores,
1410
- onLogMessage: __privateGet(this, _options).onLogMessage
1411
- });
1412
- }
1413
- const haveScoresChanged = !(0, import_lite3.dequal)(oldData == null ? void 0 : oldData.visitorData.scores, data.scores);
1414
- const haveSessionScoresChanged = !(0, import_lite3.dequal)(oldData == null ? void 0 : oldData.visitorData.sessionScores, data.sessionScores);
1415
- const haveQuirksChanged = !(0, import_lite3.dequal)(oldData == null ? void 0 : oldData.visitorData.quirks, data.quirks);
1416
- const haveTestsChanged = !(0, import_lite3.dequal)(oldData == null ? void 0 : oldData.visitorData.tests, data.tests);
1454
+ __privateMethod(this, _VisitorDataStore_instances, handleCaps_fn).call(this, data.scores);
1455
+ __privateMethod(this, _VisitorDataStore_instances, handleCaps_fn).call(this, data.sessionScores);
1456
+ (_b = (_a = __privateGet(this, _options)).decay) == null ? void 0 : _b.call(_a, {
1457
+ now,
1458
+ lastUpd: oldData == null ? void 0 : oldData.updated,
1459
+ scores: data.scores,
1460
+ sessionScores: data.sessionScores,
1461
+ onLogMessage: __privateGet(this, _options).onLogMessage
1462
+ });
1463
+ const haveScoresChanged = !(0, import_lite4.dequal)(oldData == null ? void 0 : oldData.visitorData.scores, data.scores);
1464
+ const haveSessionScoresChanged = !(0, import_lite4.dequal)(oldData == null ? void 0 : oldData.visitorData.sessionScores, data.sessionScores);
1465
+ const haveQuirksChanged = !(0, import_lite4.dequal)(oldData == null ? void 0 : oldData.visitorData.quirks, data.quirks);
1466
+ const haveTestsChanged = !(0, import_lite4.dequal)(oldData == null ? void 0 : oldData.visitorData.tests, data.tests);
1467
+ const haveGoalsChanged = !(0, import_lite4.dequal)(oldData == null ? void 0 : oldData.visitorData.goals, data.goals);
1417
1468
  const updatedData = {
1418
1469
  updated: now,
1419
1470
  visitorData: data
1420
1471
  };
1421
- __privateMethod(this, _setVisitTimeout, setVisitTimeout_fn).call(this);
1472
+ __privateMethod(this, _VisitorDataStore_instances, setVisitTimeout_fn).call(this);
1422
1473
  __privateGet(this, _persist).set(STORAGE_KEY, updatedData, !!data.consent);
1423
1474
  (_d = (_c = __privateGet(this, _options)).onLogMessage) == null ? void 0 : _d.call(_c, ["debug", 102, data]);
1424
1475
  if (!quiet) {
@@ -1438,9 +1489,17 @@ replaceData_fn = function(data, quiet = false) {
1438
1489
  __privateGet(this, _mitt2).emit("controlGroupUpdated", data);
1439
1490
  (_i = (_h = __privateGet(this, _options)).onLogMessage) == null ? void 0 : _i.call(_h, ["debug", 104, (_g = data.controlGroup) != null ? _g : false]);
1440
1491
  }
1492
+ if (haveGoalsChanged) {
1493
+ const newGoalKeys = Object.keys((_j = data.goals) != null ? _j : {});
1494
+ for (let i = 0; i < newGoalKeys.length; i++) {
1495
+ const key = newGoalKeys[i];
1496
+ if (!((_k = oldData == null ? void 0 : oldData.visitorData.goals) == null ? void 0 : _k[key])) {
1497
+ __privateGet(this, _mitt2).emit("goalConverted", { goalId: key });
1498
+ }
1499
+ }
1500
+ }
1441
1501
  }
1442
1502
  };
1443
- _setVisitTimeout = new WeakSet();
1444
1503
  setVisitTimeout_fn = function() {
1445
1504
  if (typeof document === "undefined" || !__privateGet(this, _options).visitLifespan) {
1446
1505
  return;
@@ -1452,12 +1511,15 @@ setVisitTimeout_fn = function() {
1452
1511
  this.data;
1453
1512
  }, __privateGet(this, _options).visitLifespan + 50));
1454
1513
  };
1455
- _isExpired = new WeakSet();
1456
1514
  isExpired_fn = function(data) {
1457
1515
  const expires = __privateGet(this, _options).visitLifespan;
1458
1516
  return expires ? data.updated + expires < Date.now() : false;
1459
1517
  };
1460
- _handleCaps = new WeakSet();
1518
+ /**
1519
+ * IMPORTANT: This function mutates the input data. This is done,
1520
+ * because all the sources that call it have either already spread or cloned
1521
+ * the data, so we can safely mutate it for better perf.
1522
+ */
1461
1523
  handleCaps_fn = function(scores) {
1462
1524
  var _a, _b;
1463
1525
  if (!__privateGet(this, _options).manifest) {
@@ -1475,7 +1537,6 @@ handleCaps_fn = function(scores) {
1475
1537
  }
1476
1538
  }
1477
1539
  };
1478
- _defaultData = new WeakSet();
1479
1540
  defaultData_fn = function() {
1480
1541
  var _a, _b, _c;
1481
1542
  return {
@@ -1486,21 +1547,21 @@ defaultData_fn = function() {
1486
1547
  };
1487
1548
 
1488
1549
  // src/Context.ts
1489
- var import_lite4 = require("dequal/lite");
1550
+ var import_lite5 = require("dequal/lite");
1490
1551
  var import_mitt3 = __toESM(require("mitt"));
1491
1552
  var CONTEXTUAL_EDITING_TEST_NAME = "contextual_editing_test";
1492
1553
  var CONTEXTUAL_EDITING_TEST_SELECTED_VARIANT_ID = "contextual_editing_test_selected_variant";
1493
- var _serverTransitionState, _scores, _state, _pzCache, _mitt3, _emitTest, emitTest_fn, _updateComputedScores, updateComputedScores_fn, _calculateScores, calculateScores_fn;
1554
+ var _serverTransitionState, _scores, _state, _pzCache, _plugins, _commands, _mitt3, _Context_instances, emitTest_fn, updateGoals_fn, updateComputedScores_fn, calculateScores_fn;
1494
1555
  var Context = class {
1495
1556
  constructor(options) {
1496
- __privateAdd(this, _emitTest);
1497
- __privateAdd(this, _updateComputedScores);
1498
- __privateAdd(this, _calculateScores);
1557
+ __privateAdd(this, _Context_instances);
1499
1558
  __publicField(this, "manifest");
1500
- __privateAdd(this, _serverTransitionState, void 0);
1559
+ __privateAdd(this, _serverTransitionState);
1501
1560
  __privateAdd(this, _scores, {});
1502
- __privateAdd(this, _state, void 0);
1561
+ __privateAdd(this, _state);
1503
1562
  __privateAdd(this, _pzCache, {});
1563
+ __privateAdd(this, _plugins);
1564
+ __privateAdd(this, _commands);
1504
1565
  __privateAdd(this, _mitt3, (0, import_mitt3.default)());
1505
1566
  /**
1506
1567
  * Subscribe to events
@@ -1513,7 +1574,11 @@ var Context = class {
1513
1574
  var _a, _b;
1514
1575
  const { manifest, ...storageOptions } = options;
1515
1576
  __privateSet(this, _state, {});
1516
- (_a = options.plugins) == null ? void 0 : _a.forEach((plugin) => {
1577
+ __privateSet(this, _plugins, options.plugins);
1578
+ if (typeof options.transitionStore !== "undefined") {
1579
+ __privateSet(this, _commands, []);
1580
+ }
1581
+ (_a = __privateGet(this, _plugins)) == null ? void 0 : _a.forEach((plugin) => {
1517
1582
  if (!plugin.logDrain) {
1518
1583
  return;
1519
1584
  }
@@ -1545,9 +1610,9 @@ var Context = class {
1545
1610
  },
1546
1611
  onLogMessage: (message) => __privateGet(this, _mitt3).emit("log", message)
1547
1612
  });
1548
- this.storage.events.on("scoresUpdated", __privateMethod(this, _updateComputedScores, updateComputedScores_fn).bind(this));
1613
+ this.storage.events.on("scoresUpdated", __privateMethod(this, _Context_instances, updateComputedScores_fn).bind(this));
1549
1614
  if (!__privateGet(this, _serverTransitionState)) {
1550
- __privateMethod(this, _updateComputedScores, updateComputedScores_fn).call(this, this.storage.data);
1615
+ __privateMethod(this, _Context_instances, updateComputedScores_fn).call(this, this.storage.data);
1551
1616
  }
1552
1617
  this.storage.events.on("quirksUpdated", (quirks) => {
1553
1618
  const updates = this.manifest.computeSignals({
@@ -1556,11 +1621,15 @@ var Context = class {
1556
1621
  previousState: __privateGet(this, _state),
1557
1622
  visitor: this.storage.data
1558
1623
  });
1624
+ __privateMethod(this, _Context_instances, updateGoals_fn).call(this, {
1625
+ quirks: quirks.quirks,
1626
+ scores: void 0
1627
+ });
1559
1628
  this.storage.updateData(updates);
1560
1629
  __privateGet(this, _mitt3).emit("quirksUpdated", quirks.quirks);
1561
1630
  __privateGet(this, _mitt3).emit("log", ["info", 4, quirks.quirks]);
1562
1631
  });
1563
- (_b = options.plugins) == null ? void 0 : _b.forEach((plugin) => {
1632
+ (_b = __privateGet(this, _plugins)) == null ? void 0 : _b.forEach((plugin) => {
1564
1633
  if (!plugin.init) {
1565
1634
  return;
1566
1635
  }
@@ -1569,6 +1638,9 @@ var Context = class {
1569
1638
  } finally {
1570
1639
  __privateGet(this, _mitt3).emit("log", ["info", 1, "ENDGROUP"]);
1571
1640
  }
1641
+ if (typeof window !== "undefined") {
1642
+ window.__UNIFORM_CONTEXTUAL_EDITING_CONTEXT__ = this;
1643
+ }
1572
1644
  }
1573
1645
  /** Gets the current visitor's dimension score vector. */
1574
1646
  get scores() {
@@ -1589,7 +1661,7 @@ var Context = class {
1589
1661
  * will NOT result in a recomputation of signal state.
1590
1662
  */
1591
1663
  async update(newData) {
1592
- var _a, _b, _c, _d;
1664
+ var _a, _b, _c, _d, _e;
1593
1665
  const commands = [];
1594
1666
  const newServerSideTests = {};
1595
1667
  if ((_a = __privateGet(this, _serverTransitionState)) == null ? void 0 : _a.quirks) {
@@ -1675,7 +1747,7 @@ var Context = class {
1675
1747
  // re-compute using scores from storage instead of the current scores since
1676
1748
  // server transition scores might have adjusted values already integrated into them,
1677
1749
  // which causes issues when you are near limits.
1678
- scores: __privateGet(this, _serverTransitionState) ? __privateMethod(this, _calculateScores, calculateScores_fn).call(this, this.storage.data) : __privateGet(this, _scores)
1750
+ scores: __privateGet(this, _serverTransitionState) ? __privateMethod(this, _Context_instances, calculateScores_fn).call(this, this.storage.data) : __privateGet(this, _scores)
1679
1751
  })
1680
1752
  );
1681
1753
  __privateSet(this, _state, {
@@ -1684,9 +1756,13 @@ var Context = class {
1684
1756
  });
1685
1757
  await this.storage.updateData(commands);
1686
1758
  if (__privateGet(this, _serverTransitionState)) {
1687
- __privateMethod(this, _updateComputedScores, updateComputedScores_fn).call(this, this.storage.data);
1759
+ await this.processServerCommands({
1760
+ serverCommands: __privateGet(this, _serverTransitionState).commands,
1761
+ commands
1762
+ });
1763
+ __privateMethod(this, _Context_instances, updateComputedScores_fn).call(this, this.storage.data);
1688
1764
  Object.entries(newServerSideTests).forEach(([testName, testVariantId]) => {
1689
- __privateMethod(this, _emitTest, emitTest_fn).call(this, {
1765
+ __privateMethod(this, _Context_instances, emitTest_fn).call(this, {
1690
1766
  name: testName,
1691
1767
  variantId: testVariantId,
1692
1768
  variantAssigned: true
@@ -1695,10 +1771,40 @@ var Context = class {
1695
1771
  __privateSet(this, _serverTransitionState, void 0);
1696
1772
  __privateGet(this, _mitt3).emit("log", ["debug", 131]);
1697
1773
  }
1774
+ if (__privateGet(this, _plugins)) {
1775
+ for (let i = 0; i < __privateGet(this, _plugins).length; i++) {
1776
+ const plugin = __privateGet(this, _plugins)[i];
1777
+ if (!plugin.update) {
1778
+ continue;
1779
+ }
1780
+ await plugin.update(newData);
1781
+ }
1782
+ }
1783
+ (_e = __privateGet(this, _commands)) == null ? void 0 : _e.push(...commands);
1698
1784
  } finally {
1699
1785
  __privateGet(this, _mitt3).emit("log", ["info", 2, "ENDGROUP"]);
1700
1786
  }
1701
1787
  }
1788
+ async processServerCommands({
1789
+ serverCommands,
1790
+ commands
1791
+ }) {
1792
+ if (!(serverCommands == null ? void 0 : serverCommands.length)) {
1793
+ return;
1794
+ }
1795
+ const notExecutedCommands = [];
1796
+ serverCommands.forEach((serverCommand) => {
1797
+ const found = commands.find((command) => {
1798
+ return areCommandsEqual(command, serverCommand);
1799
+ });
1800
+ if (!found) {
1801
+ notExecutedCommands.push(serverCommand);
1802
+ }
1803
+ });
1804
+ if (notExecutedCommands.length > 0) {
1805
+ await this.storage.updateData(notExecutedCommands);
1806
+ }
1807
+ }
1702
1808
  /** use test() instead */
1703
1809
  getTestVariantId(testName) {
1704
1810
  var _a, _b, _c, _d;
@@ -1753,7 +1859,7 @@ var Context = class {
1753
1859
  context: this,
1754
1860
  onLogMessage: (message) => __privateGet(this, _mitt3).emit("log", message)
1755
1861
  });
1756
- __privateMethod(this, _emitTest, emitTest_fn).call(this, {
1862
+ __privateMethod(this, _Context_instances, emitTest_fn).call(this, {
1757
1863
  name: options.name,
1758
1864
  variantId: (_c = (_b = value.result) == null ? void 0 : _b.id) != null ? _c : void 0,
1759
1865
  variantAssigned: value.variantAssigned
@@ -1777,7 +1883,7 @@ var Context = class {
1777
1883
  control: this.storage.data.controlGroup,
1778
1884
  changed: true
1779
1885
  };
1780
- if (previousPlacement && (0, import_lite4.dequal)(eventData.variantIds, previousPlacement)) {
1886
+ if (previousPlacement && (0, import_lite5.dequal)(eventData.variantIds, previousPlacement)) {
1781
1887
  eventData.changed = false;
1782
1888
  }
1783
1889
  __privateGet(this, _mitt3).emit("personalizationResult", eventData);
@@ -1790,6 +1896,15 @@ var Context = class {
1790
1896
  */
1791
1897
  async forget(fromAllDevices) {
1792
1898
  __privateSet(this, _state, {});
1899
+ if (__privateGet(this, _plugins)) {
1900
+ for (let i = 0; i < __privateGet(this, _plugins).length; i++) {
1901
+ const plugin = __privateGet(this, _plugins)[i];
1902
+ if (!plugin.forget) {
1903
+ continue;
1904
+ }
1905
+ await plugin.forget();
1906
+ }
1907
+ }
1793
1908
  await this.storage.delete(fromAllDevices);
1794
1909
  }
1795
1910
  /**
@@ -1802,7 +1917,8 @@ var Context = class {
1802
1917
  quirks: this.storage.data.quirks,
1803
1918
  ssv: __privateGet(this, _scores),
1804
1919
  tests: {},
1805
- personalizeVariants: this.storage.data.personalizeVariants
1920
+ personalizeVariants: this.storage.data.personalizeVariants,
1921
+ commands: __privateGet(this, _commands)
1806
1922
  };
1807
1923
  const allTests = this.storage.data.tests;
1808
1924
  Object.entries(allTests).map(([testName, testValue]) => {
@@ -1817,7 +1933,7 @@ var Context = class {
1817
1933
  internal_processTestEvent(event) {
1818
1934
  if (event.variantId) {
1819
1935
  this.setTestVariantId(event.name, event.variantId);
1820
- __privateMethod(this, _emitTest, emitTest_fn).call(this, event);
1936
+ __privateMethod(this, _Context_instances, emitTest_fn).call(this, event);
1821
1937
  }
1822
1938
  }
1823
1939
  /** @deprecated */
@@ -1830,22 +1946,32 @@ _serverTransitionState = new WeakMap();
1830
1946
  _scores = new WeakMap();
1831
1947
  _state = new WeakMap();
1832
1948
  _pzCache = new WeakMap();
1949
+ _plugins = new WeakMap();
1950
+ _commands = new WeakMap();
1833
1951
  _mitt3 = new WeakMap();
1834
- _emitTest = new WeakSet();
1952
+ _Context_instances = new WeakSet();
1835
1953
  emitTest_fn = function(event) {
1836
1954
  __privateGet(this, _mitt3).emit("testResult", event);
1837
1955
  };
1838
- _updateComputedScores = new WeakSet();
1956
+ updateGoals_fn = async function(data) {
1957
+ const goalCommands = this.manifest.computeGoals(data);
1958
+ if (goalCommands.length !== 0) {
1959
+ await this.storage.updateData(goalCommands);
1960
+ }
1961
+ };
1839
1962
  updateComputedScores_fn = function(newData) {
1840
- const newScores = __privateMethod(this, _calculateScores, calculateScores_fn).call(this, newData);
1841
- const newScoresHaveChanged = !(0, import_lite4.dequal)(newScores, __privateGet(this, _scores));
1963
+ const newScores = __privateMethod(this, _Context_instances, calculateScores_fn).call(this, newData);
1964
+ const newScoresHaveChanged = !(0, import_lite5.dequal)(newScores, __privateGet(this, _scores));
1842
1965
  if (newScoresHaveChanged) {
1843
1966
  __privateSet(this, _scores, newScores);
1967
+ __privateMethod(this, _Context_instances, updateGoals_fn).call(this, {
1968
+ scores: __privateGet(this, _scores),
1969
+ quirks: void 0
1970
+ });
1844
1971
  __privateGet(this, _mitt3).emit("scoresUpdated", newScores);
1845
1972
  __privateGet(this, _mitt3).emit("log", ["info", 3, newScores]);
1846
1973
  }
1847
1974
  };
1848
- _calculateScores = new WeakSet();
1849
1975
  calculateScores_fn = function(newData) {
1850
1976
  var _a;
1851
1977
  let newScores = { ...newData.scores };
@@ -1894,13 +2020,11 @@ function enableContextDevTools(options) {
1894
2020
  );
1895
2021
  };
1896
2022
  const onPersonalizationResult = (e) => {
1897
- if (!e.changed)
1898
- return;
2023
+ if (!e.changed) return;
1899
2024
  personalizations.push(e);
1900
2025
  };
1901
2026
  const onTestResult = (e) => {
1902
- if (!e.variantAssigned)
1903
- return;
2027
+ if (!e.variantAssigned) return;
1904
2028
  tests.push(e);
1905
2029
  };
1906
2030
  if (isBrowser) {
@@ -1979,6 +2103,344 @@ var ScriptType = /* @__PURE__ */ ((ScriptType2) => {
1979
2103
  })(ScriptType || {});
1980
2104
  var EdgeNodeTagName = "nesitag";
1981
2105
 
2106
+ // src/insights/index.ts
2107
+ var import_uuid = require("uuid");
2108
+ var getBasePayload = () => {
2109
+ const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
2110
+ const locale = navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.userLanguage || navigator.language || navigator.browserLanguage || "en";
2111
+ return {
2112
+ "user-agent": window.navigator.userAgent,
2113
+ locale,
2114
+ location: timeZone,
2115
+ referrer: document.referrer,
2116
+ pathname: window.location.pathname,
2117
+ href: window.location.href
2118
+ };
2119
+ };
2120
+ var createInsightsClient = ({ endpoint }) => {
2121
+ let endpointUrl;
2122
+ const apiKey = endpoint.apiKey;
2123
+ if (endpoint.type === "api") {
2124
+ const url = new URL(endpoint.host);
2125
+ url.pathname = "/v0/events";
2126
+ url.searchParams.set("name", "analytics_events");
2127
+ endpointUrl = url.toString();
2128
+ } else {
2129
+ endpointUrl = endpoint.path;
2130
+ }
2131
+ const sendMessage = async (message) => {
2132
+ if (typeof window.__UNIFORM_CONTEXTUAL_EDITING__ !== "undefined") {
2133
+ return;
2134
+ }
2135
+ const converted = {
2136
+ ...message,
2137
+ payload: JSON.stringify(message.payload)
2138
+ };
2139
+ const headers = {
2140
+ "Content-Type": "application/json"
2141
+ };
2142
+ if (apiKey) {
2143
+ headers.Authorization = `Bearer ${apiKey}`;
2144
+ }
2145
+ const response = await fetch(endpointUrl, {
2146
+ method: "POST",
2147
+ headers,
2148
+ body: JSON.stringify(converted)
2149
+ });
2150
+ const json = await response.json();
2151
+ return json;
2152
+ };
2153
+ return {
2154
+ sessionStart: (options) => {
2155
+ const message = {
2156
+ action: "session_start",
2157
+ version: "1",
2158
+ session_id: options.sessionId,
2159
+ visitor_id: options.visitorId,
2160
+ page_view_id: options.pageId,
2161
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2162
+ payload: {
2163
+ ...getBasePayload(),
2164
+ previous_session_id: options.previousSessionId
2165
+ }
2166
+ };
2167
+ return sendMessage(message);
2168
+ },
2169
+ pageHit: (options) => {
2170
+ const message = {
2171
+ action: "page_hit",
2172
+ version: "1",
2173
+ session_id: options.sessionId,
2174
+ visitor_id: options.visitorId,
2175
+ page_view_id: options.pageId,
2176
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2177
+ payload: getBasePayload()
2178
+ };
2179
+ return sendMessage(message);
2180
+ },
2181
+ testResult: async (options) => {
2182
+ const message = {
2183
+ action: "test_result",
2184
+ version: "1",
2185
+ session_id: options.sessionId,
2186
+ visitor_id: options.visitorId,
2187
+ page_view_id: options.pageId,
2188
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2189
+ payload: {
2190
+ ...getBasePayload(),
2191
+ ...options
2192
+ }
2193
+ };
2194
+ return sendMessage(message);
2195
+ },
2196
+ personalizationResult: async (options) => {
2197
+ const messages = options.variantIds.map((variant) => {
2198
+ const message = {
2199
+ action: "personalization_result",
2200
+ version: "1",
2201
+ session_id: options.sessionId,
2202
+ visitor_id: options.visitorId,
2203
+ page_view_id: options.pageId,
2204
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2205
+ payload: {
2206
+ ...getBasePayload(),
2207
+ name: options.name,
2208
+ variantId: variant.id,
2209
+ control: variant.control || options.control,
2210
+ changed: options.changed
2211
+ }
2212
+ };
2213
+ return message;
2214
+ });
2215
+ await Promise.all(messages.map((message) => sendMessage(message)));
2216
+ },
2217
+ goalConvert: (options) => {
2218
+ const message = {
2219
+ action: "goal_convert",
2220
+ version: "1",
2221
+ session_id: options.sessionId,
2222
+ visitor_id: options.visitorId,
2223
+ page_view_id: options.pageId,
2224
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2225
+ payload: {
2226
+ ...getBasePayload(),
2227
+ goalId: options.goalId
2228
+ }
2229
+ };
2230
+ return sendMessage(message);
2231
+ },
2232
+ scoresChange: async (options) => {
2233
+ const message = {
2234
+ action: "scores_change",
2235
+ version: "1",
2236
+ session_id: options.sessionId,
2237
+ visitor_id: options.visitorId,
2238
+ page_view_id: options.pageId,
2239
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2240
+ payload: {
2241
+ ...getBasePayload(),
2242
+ scores: options.scores
2243
+ }
2244
+ };
2245
+ return sendMessage(message);
2246
+ }
2247
+ };
2248
+ };
2249
+ var createInsightsStorage = () => {
2250
+ const STORAGE_KEY2 = "ufin";
2251
+ return {
2252
+ get: () => {
2253
+ const data = localStorage.getItem(STORAGE_KEY2);
2254
+ if (!data) {
2255
+ return;
2256
+ }
2257
+ return JSON.parse(data);
2258
+ },
2259
+ set: (data) => {
2260
+ const toSet = {
2261
+ ...data,
2262
+ updated: Date.now()
2263
+ };
2264
+ localStorage.setItem(STORAGE_KEY2, JSON.stringify(toSet));
2265
+ },
2266
+ clear: () => {
2267
+ localStorage.removeItem(STORAGE_KEY2);
2268
+ }
2269
+ };
2270
+ };
2271
+ var generateVisitorId = () => {
2272
+ return `visitor_${generalRandomId()}`;
2273
+ };
2274
+ var generateSessionId = () => {
2275
+ return `session_${generalRandomId()}`;
2276
+ };
2277
+ var generatePageId = () => {
2278
+ return `page_${generalRandomId()}`;
2279
+ };
2280
+ var createInsights = ({
2281
+ endpoint,
2282
+ sessionDurationSeconds = 30 * 60
2283
+ }) => {
2284
+ const client = createInsightsClient({
2285
+ endpoint
2286
+ });
2287
+ const storage = createInsightsStorage();
2288
+ let storageData = void 0;
2289
+ let pageId = generatePageId();
2290
+ let previousUrl = void 0;
2291
+ return {
2292
+ init: () => {
2293
+ storageData = storage.get();
2294
+ if (!storageData || Date.now() - storageData.updated > sessionDurationSeconds * 1e3) {
2295
+ const previousSessionId = storageData == null ? void 0 : storageData.sessionId;
2296
+ storageData = {
2297
+ visitorId: (storageData == null ? void 0 : storageData.visitorId) || generateVisitorId(),
2298
+ sessionId: generateSessionId(),
2299
+ updated: Date.now()
2300
+ };
2301
+ storage.set(storageData);
2302
+ client.sessionStart({
2303
+ visitorId: storageData.visitorId,
2304
+ sessionId: storageData.sessionId,
2305
+ previousSessionId,
2306
+ maxAgeSeconds: sessionDurationSeconds,
2307
+ pageId
2308
+ });
2309
+ } else if (storageData) {
2310
+ storage.set(storageData);
2311
+ }
2312
+ },
2313
+ pageHit: () => {
2314
+ if (!storageData) {
2315
+ return;
2316
+ }
2317
+ if (previousUrl === window.location.href) {
2318
+ return;
2319
+ }
2320
+ previousUrl = window.location.href;
2321
+ pageId = generatePageId();
2322
+ client.pageHit({
2323
+ visitorId: storageData.visitorId,
2324
+ sessionId: storageData.sessionId,
2325
+ pageId
2326
+ });
2327
+ },
2328
+ testResult: (result) => {
2329
+ if (!storageData) {
2330
+ console.error("Insights not initialized");
2331
+ return;
2332
+ }
2333
+ client.testResult({
2334
+ ...result,
2335
+ visitorId: storageData.visitorId,
2336
+ sessionId: storageData.sessionId,
2337
+ pageId
2338
+ });
2339
+ },
2340
+ personalizationResult: (result) => {
2341
+ if (!storageData) {
2342
+ return;
2343
+ }
2344
+ client.personalizationResult({
2345
+ ...result,
2346
+ visitorId: storageData.visitorId,
2347
+ sessionId: storageData.sessionId,
2348
+ pageId
2349
+ });
2350
+ },
2351
+ goalConvert: (goalId) => {
2352
+ if (!storageData) {
2353
+ return;
2354
+ }
2355
+ client.goalConvert({
2356
+ visitorId: storageData.visitorId,
2357
+ sessionId: storageData.sessionId,
2358
+ goalId,
2359
+ pageId
2360
+ });
2361
+ },
2362
+ scoresChange: (scores) => {
2363
+ if (!storageData) {
2364
+ return;
2365
+ }
2366
+ client.scoresChange({
2367
+ visitorId: storageData.visitorId,
2368
+ sessionId: storageData.sessionId,
2369
+ scores,
2370
+ pageId
2371
+ });
2372
+ },
2373
+ forget: () => {
2374
+ storage.clear();
2375
+ storageData = void 0;
2376
+ },
2377
+ get sessionId() {
2378
+ return storageData == null ? void 0 : storageData.sessionId;
2379
+ }
2380
+ };
2381
+ };
2382
+ var enableUniformInsights = (options) => {
2383
+ const insights = createInsights({
2384
+ endpoint: options.endpoint
2385
+ });
2386
+ let previousUrl = void 0;
2387
+ return {
2388
+ init: (context) => {
2389
+ if (typeof window === "undefined") {
2390
+ return () => {
2391
+ };
2392
+ }
2393
+ const consentChanged = () => {
2394
+ if (context.storage.data.consent) {
2395
+ insights.init();
2396
+ } else {
2397
+ insights.forget();
2398
+ }
2399
+ };
2400
+ const handlePersonalizationResult = (data) => {
2401
+ insights.personalizationResult(data);
2402
+ };
2403
+ const handleTestResult = (result) => {
2404
+ insights.testResult(result);
2405
+ };
2406
+ const handleGoalConvert = (result) => {
2407
+ insights.goalConvert(result.goalId);
2408
+ };
2409
+ const handleScoreChange = (scores) => {
2410
+ insights.scoresChange(scores);
2411
+ };
2412
+ context.storage.events.on("goalConverted", handleGoalConvert);
2413
+ context.storage.events.on("consentUpdated", consentChanged);
2414
+ context.events.on("personalizationResult", handlePersonalizationResult);
2415
+ context.events.on("testResult", handleTestResult);
2416
+ context.events.on("scoresUpdated", handleScoreChange);
2417
+ if (context.storage.data.consent) {
2418
+ consentChanged();
2419
+ }
2420
+ return () => {
2421
+ context.storage.events.off("consentUpdated", consentChanged);
2422
+ context.storage.events.off("goalConverted", handleGoalConvert);
2423
+ context.events.off("personalizationResult", handlePersonalizationResult);
2424
+ context.events.off("testResult", handleTestResult);
2425
+ context.events.off("scoresUpdated", handleScoreChange);
2426
+ };
2427
+ },
2428
+ update: (context) => {
2429
+ if (context.url && context.url !== previousUrl) {
2430
+ previousUrl = context.url;
2431
+ insights.pageHit();
2432
+ }
2433
+ },
2434
+ forget: () => {
2435
+ insights.forget();
2436
+ }
2437
+ };
2438
+ };
2439
+ var generalRandomId = () => {
2440
+ const id = (0, import_uuid.v4)();
2441
+ return id.replaceAll("-", "").toLowerCase();
2442
+ };
2443
+
1982
2444
  // src/logging/enableConsoleLogDrain.ts
1983
2445
  var import_rfdc2 = __toESM(require("rfdc"));
1984
2446
 
@@ -2167,22 +2629,30 @@ function parseQuickConnect(serialized) {
2167
2629
  EdgeNodeTagName,
2168
2630
  EdgeTransitionDataStore,
2169
2631
  GroupCriteriaEvaluator,
2632
+ KV_SEP,
2170
2633
  ManifestInstance,
2634
+ PAIR_SEP,
2171
2635
  SERVER_STATE_ID,
2172
2636
  ScriptType,
2637
+ TYPE_SEP,
2173
2638
  TransitionDataStore,
2174
2639
  UNIFORM_DEFAULT_COOKIE_NAME,
2175
2640
  VisitorDataStore,
2641
+ areCommandsEqual,
2176
2642
  computeAggregateDimensions,
2177
2643
  cookieEvaluator,
2178
2644
  createConsoleLogDrain,
2179
2645
  createDebugConsoleLogDrain,
2180
2646
  createLinearDecay,
2181
2647
  currentPageEvaluator,
2648
+ decodeCookieType,
2649
+ decodePersonalizeVariants,
2182
2650
  emptyVisitorData,
2183
2651
  enableConsoleLogDrain,
2184
2652
  enableContextDevTools,
2185
2653
  enableDebugConsoleLogDrain,
2654
+ enableUniformInsights,
2655
+ encodeCookieType,
2186
2656
  evaluateVariantMatch,
2187
2657
  eventEvaluator,
2188
2658
  explainStringMatch,
@@ -2191,10 +2661,16 @@ function parseQuickConnect(serialized) {
2191
2661
  isStringMatch,
2192
2662
  pageViewCountDimension,
2193
2663
  pageViewCountEvaluator,
2664
+ parseCookieScores,
2665
+ parseCookieType,
2194
2666
  parseQuickConnect,
2667
+ parseScoreCookie,
2195
2668
  personalizeVariations,
2196
2669
  queryStringEvaluator,
2197
2670
  quirkEvaluator,
2671
+ serializeCookie,
2672
+ serializeCookieType,
2673
+ serializePersonalizeVariants,
2198
2674
  serializeQuickConnect,
2199
2675
  testVariations
2200
2676
  });