@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.mjs CHANGED
@@ -1,31 +1,14 @@
1
1
  var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
7
- var __accessCheck = (obj, member, msg) => {
8
- if (!member.has(obj))
9
- throw TypeError("Cannot " + msg);
10
- };
11
- var __privateGet = (obj, member, getter) => {
12
- __accessCheck(obj, member, "read from private field");
13
- return getter ? getter.call(obj) : member.get(obj);
14
- };
15
- var __privateAdd = (obj, member, value) => {
16
- if (member.has(obj))
17
- throw TypeError("Cannot add the same private member more than once");
18
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
19
- };
20
- var __privateSet = (obj, member, value, setter) => {
21
- __accessCheck(obj, member, "write to private field");
22
- setter ? setter.call(obj, value) : member.set(obj, value);
23
- return value;
24
- };
25
- var __privateMethod = (obj, member, method) => {
26
- __accessCheck(obj, member, "access private method");
27
- return method;
2
+ var __typeError = (msg) => {
3
+ throw TypeError(msg);
28
4
  };
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
8
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
9
+ 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);
10
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
11
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
29
12
 
30
13
  // src/manifest/aggregates/computeAggregateDimensions.ts
31
14
  function computeAggregateDimensions(primitiveScores, aggregates) {
@@ -76,12 +59,34 @@ function computeAggregateDimension(primitiveScores, aggregateDimension, allAggre
76
59
  // src/manifest/constants.ts
77
60
  var ENR_SEPARATOR = "_";
78
61
 
62
+ // src/manifest/goals/evaluators/SignalGoalEvaluator.ts
63
+ var _id;
64
+ var SignalGoalEvaluator = class {
65
+ constructor(options) {
66
+ __privateAdd(this, _id);
67
+ __privateSet(this, _id, options.id);
68
+ }
69
+ get id() {
70
+ return __privateGet(this, _id);
71
+ }
72
+ evaluate({ scores, quirks }) {
73
+ const score = scores == null ? void 0 : scores[__privateGet(this, _id)];
74
+ const key = `goal_${__privateGet(this, _id)}_triggered`;
75
+ const hasGoalTriggered = (quirks == null ? void 0 : quirks[key]) === "1";
76
+ return {
77
+ key,
78
+ triggered: typeof score === "number" && !hasGoalTriggered
79
+ };
80
+ }
81
+ };
82
+ _id = new WeakMap();
83
+
79
84
  // src/manifest/signals/SignalInstance.ts
80
85
  var _evaluator, _onLogMessage;
81
86
  var SignalInstance = class {
82
87
  constructor(data, evaluator, onLogMessage) {
83
- __privateAdd(this, _evaluator, void 0);
84
- __privateAdd(this, _onLogMessage, void 0);
88
+ __privateAdd(this, _evaluator);
89
+ __privateAdd(this, _onLogMessage);
85
90
  __publicField(this, "signal");
86
91
  this.signal = data;
87
92
  __privateSet(this, _evaluator, evaluator);
@@ -133,7 +138,7 @@ var rollForControlGroup = (value) => {
133
138
  };
134
139
 
135
140
  // src/manifest/ManifestInstance.ts
136
- var _mf, _signalInstances, _onLogMessage2;
141
+ var _mf, _signalInstances, _goalEvaluators, _onLogMessage2;
137
142
  var ManifestInstance = class {
138
143
  constructor({
139
144
  manifest,
@@ -143,15 +148,21 @@ var ManifestInstance = class {
143
148
  }
144
149
  }) {
145
150
  __publicField(this, "data");
146
- __privateAdd(this, _mf, void 0);
147
- __privateAdd(this, _signalInstances, void 0);
148
- __privateAdd(this, _onLogMessage2, void 0);
149
- var _a, _b, _c;
151
+ __privateAdd(this, _mf);
152
+ __privateAdd(this, _signalInstances);
153
+ __privateAdd(this, _goalEvaluators, []);
154
+ __privateAdd(this, _onLogMessage2);
155
+ var _a, _b, _c, _d, _e;
150
156
  __privateSet(this, _mf, (_a = manifest.project) != null ? _a : {});
151
157
  this.data = manifest;
152
158
  __privateSet(this, _signalInstances, Object.entries((_c = (_b = __privateGet(this, _mf).pz) == null ? void 0 : _b.sig) != null ? _c : []).map(
153
159
  ([id, signal]) => new SignalInstance({ ...signal, id }, evaluator, onLogMessage)
154
160
  ));
161
+ Object.entries((_e = (_d = __privateGet(this, _mf).pz) == null ? void 0 : _d.sig) != null ? _e : []).forEach(([id, signal]) => {
162
+ if (signal.conversion) {
163
+ __privateGet(this, _goalEvaluators).push(new SignalGoalEvaluator({ id, signal }));
164
+ }
165
+ });
155
166
  __privateSet(this, _onLogMessage2, onLogMessage);
156
167
  }
157
168
  rollForControlGroup() {
@@ -179,6 +190,28 @@ var ManifestInstance = class {
179
190
  }
180
191
  return commands;
181
192
  }
193
+ computeGoals(data) {
194
+ const commands = [];
195
+ __privateGet(this, _goalEvaluators).forEach((evaluator) => {
196
+ const { triggered, key } = evaluator.evaluate(data);
197
+ if (triggered) {
198
+ commands.push({
199
+ type: "setgoal",
200
+ data: {
201
+ goal: evaluator.id
202
+ }
203
+ });
204
+ commands.push({
205
+ type: "setquirk",
206
+ data: {
207
+ key,
208
+ value: "1"
209
+ }
210
+ });
211
+ }
212
+ });
213
+ return commands;
214
+ }
182
215
  /**
183
216
  * Computes aggregated scores based on other dimensions
184
217
  */
@@ -197,6 +230,7 @@ var ManifestInstance = class {
197
230
  };
198
231
  _mf = new WeakMap();
199
232
  _signalInstances = new WeakMap();
233
+ _goalEvaluators = new WeakMap();
200
234
  _onLogMessage2 = new WeakMap();
201
235
 
202
236
  // src/manifest/signals/criteria/evaluators/cookieEvaluator.ts
@@ -434,7 +468,7 @@ var quirkEvaluator = ({ update, criteria, signal, onLogMessage }) => {
434
468
  var _evaluators;
435
469
  var GroupCriteriaEvaluator = class {
436
470
  constructor(criteriaEvaluators) {
437
- __privateAdd(this, _evaluators, void 0);
471
+ __privateAdd(this, _evaluators);
438
472
  __privateSet(this, _evaluators, criteriaEvaluators);
439
473
  }
440
474
  evaluate(update, crit, commands, signal, onLogMessage) {
@@ -614,75 +648,66 @@ function personalizeVariations({
614
648
  take = 1,
615
649
  onLogMessage
616
650
  }) {
617
- var _a, _b, _c, _d;
651
+ var _a, _b, _c;
618
652
  onLogMessage == null ? void 0 : onLogMessage(["info", 300, "GROUP", { name, take }]);
619
653
  try {
620
- const control = (_a = context.storage.data.controlGroup) != null ? _a : false;
621
- const results = [];
622
- let personalized = false;
623
- const scores = context.scores;
624
- let index = 0;
654
+ const variantMatches = [];
625
655
  const defaultVariants = [];
626
656
  for (const variant of variations) {
627
- if (!((_b = variant.pz) == null ? void 0 : _b.crit.length)) {
657
+ if ((_a = variant.pz) == null ? void 0 : _a.crit.length) {
658
+ if (variantMatches.length !== take && evaluateVariantMatch(variant.id, variant.pz, context.scores, onLogMessage)) {
659
+ variantMatches.push(variant);
660
+ }
661
+ } else {
628
662
  defaultVariants.push(variant);
629
663
  }
630
664
  }
631
- for (const variant of variations) {
632
- const currentIndex = index++;
633
- if (results.length === take) {
634
- break;
635
- }
636
- if (!((_c = variant.pz) == null ? void 0 : _c.crit.length)) {
637
- onLogMessage == null ? void 0 : onLogMessage(["info", 301, "GROUP", { id: variant.id, op: (_d = variant.pz) == null ? void 0 : _d.op }]);
638
- onLogMessage == null ? void 0 : onLogMessage(["info", 302, { matched: true, description: "default variation" }]);
639
- onLogMessage == null ? void 0 : onLogMessage(["info", 303, true]);
640
- onLogMessage == null ? void 0 : onLogMessage(["info", 301, "ENDGROUP"]);
641
- results.push({
642
- ...variant,
643
- control: false
644
- });
645
- continue;
646
- }
647
- if (control) {
648
- continue;
649
- }
650
- if (evaluateVariantMatch(variant.id, variant.pz, scores, onLogMessage)) {
651
- let variantToAdd = variant;
652
- let isControl = false;
653
- const isDefault = defaultVariants.find((v) => v.id === variant.id);
654
- if (take === 1 && !isDefault && defaultVariants.length && typeof variant.pz.control === "number") {
655
- isControl = context.getPersonalizeVariantControl(name, currentIndex);
656
- if (typeof isControl === "undefined") {
657
- isControl = rollForControlGroup(variant.pz.control);
658
- context.storage.updateData([
659
- {
660
- type: "setpersonalizecontrol",
661
- data: {
662
- personlizationName: name,
663
- index: currentIndex,
664
- control: isControl
665
- }
665
+ const result = [];
666
+ for (let i = 0; i < variantMatches.length; i++) {
667
+ let isControl = (_b = context.storage.data.controlGroup) != null ? _b : false;
668
+ const variant = variantMatches[i];
669
+ if (!isControl && typeof ((_c = variant.pz) == null ? void 0 : _c.control) === "number") {
670
+ isControl = context.getPersonalizeVariantControl(name, i);
671
+ if (typeof isControl === "undefined") {
672
+ isControl = rollForControlGroup(variant.pz.control);
673
+ context.storage.updateData([
674
+ {
675
+ type: "setpersonalizecontrol",
676
+ data: {
677
+ personlizationName: name,
678
+ index: i,
679
+ control: isControl
666
680
  }
667
- ]);
668
- }
669
- if (isControl) {
670
- variantToAdd = {
671
- ...defaultVariants[0],
672
- id: variant.id
673
- };
674
- }
681
+ }
682
+ ]);
675
683
  }
676
- personalized = personalized || typeof variantToAdd.pz !== "undefined";
677
- results.push({
678
- ...variantToAdd,
679
- control: isControl
680
- });
684
+ }
685
+ let variantToAdd = variant;
686
+ if (isControl) {
687
+ const defaultReplacement = defaultVariants.shift();
688
+ if (defaultReplacement) {
689
+ variantToAdd = {
690
+ ...defaultReplacement,
691
+ id: variant.id
692
+ };
693
+ } else {
694
+ variantToAdd = void 0;
695
+ }
696
+ }
697
+ if (variantToAdd) {
698
+ result.push({ ...variantToAdd, control: isControl });
681
699
  }
682
700
  }
701
+ while (result.length < take && defaultVariants.length) {
702
+ result.push({ ...defaultVariants.shift(), control: false });
703
+ }
704
+ const personalized = result.some((v) => {
705
+ var _a2;
706
+ return (_a2 = v.pz) == null ? void 0 : _a2.crit.length;
707
+ });
683
708
  return {
684
709
  personalized,
685
- variations: results
710
+ variations: result
686
711
  };
687
712
  } finally {
688
713
  onLogMessage == null ? void 0 : onLogMessage(["info", 300, "ENDGROUP"]);
@@ -750,7 +775,7 @@ var testVariations = ({
750
775
  let distributionOffset = 0;
751
776
  selectedVariant = variations.find((variant, index) => {
752
777
  const distribution = distributions[index];
753
- if (random > distributionOffset && random <= distributionOffset + distribution) {
778
+ if ((random > distributionOffset || random === 0) && random <= distributionOffset + distribution) {
754
779
  return variant;
755
780
  }
756
781
  distributionOffset += distribution;
@@ -772,18 +797,27 @@ var testVariations = ({
772
797
  }
773
798
  };
774
799
 
800
+ // src/storage/commands.ts
801
+ import { dequal as dequal2 } from "dequal/lite";
802
+ var areCommandsEqual = (a, b) => {
803
+ if (a.type !== b.type) {
804
+ return false;
805
+ }
806
+ return dequal2(a, b);
807
+ };
808
+
775
809
  // src/storage/CookieTransitionDataStore.ts
776
810
  import Cookies from "js-cookie";
777
811
 
778
812
  // src/storage/TransitionDataStore.ts
779
- import { dequal as dequal2 } from "dequal/lite";
813
+ import { dequal as dequal3 } from "dequal/lite";
780
814
  import mitt from "mitt";
781
815
  var SERVER_STATE_ID = "__UNIFORM_DATA__";
782
816
  var _data, _initialData, _mitt;
783
817
  var TransitionDataStore = class {
784
818
  constructor({ initialData }) {
785
- __privateAdd(this, _data, void 0);
786
- __privateAdd(this, _initialData, void 0);
819
+ __privateAdd(this, _data);
820
+ __privateAdd(this, _initialData);
787
821
  __privateAdd(this, _mitt, mitt());
788
822
  /**
789
823
  * Subscribe to events from the transition storage
@@ -822,7 +856,7 @@ var TransitionDataStore = class {
822
856
  await this.handleDelete(fromAllDevices);
823
857
  }
824
858
  signalAsyncDataUpdate(newScores) {
825
- if (dequal2(this.data, newScores)) {
859
+ if (dequal3(this.data, newScores)) {
826
860
  return;
827
861
  }
828
862
  __privateSet(this, _data, newScores);
@@ -854,8 +888,7 @@ for (let i = 0; i < alphabet.length; i++) {
854
888
  s2b[alphabet.charCodeAt(i)] = i;
855
889
  }
856
890
  var ntob = (number) => {
857
- if (number < 0)
858
- return `-${ntob(-number)}`;
891
+ if (number < 0) return `-${ntob(-number)}`;
859
892
  let lo = number >>> 0;
860
893
  let hi = number / 4294967296 >>> 0;
861
894
  let right = "";
@@ -894,20 +927,18 @@ var CookieTransitionDataStore = class extends TransitionDataStore {
894
927
  super({
895
928
  initialData: ssr ? parseScoreCookie(serverCookieValue) : void 0
896
929
  });
897
- __privateAdd(this, _cookieName, void 0);
898
- __privateAdd(this, _cookieAttributes, void 0);
930
+ __privateAdd(this, _cookieName);
931
+ __privateAdd(this, _cookieAttributes);
899
932
  __privateSet(this, _cookieName, cookieName);
900
933
  __privateSet(this, _cookieAttributes, cookieAttributes);
901
934
  }
902
935
  handleDelete() {
903
- if (ssr)
904
- return Promise.resolve();
936
+ if (ssr) return Promise.resolve();
905
937
  Cookies.remove(__privateGet(this, _cookieName));
906
938
  return Promise.resolve();
907
939
  }
908
940
  async handleUpdateData(_, computedValue) {
909
- if (ssr)
910
- return;
941
+ if (ssr) return;
911
942
  if (computedValue.consent) {
912
943
  Cookies.set(__privateGet(this, _cookieName), serializeCookie(computedValue), __privateGet(this, _cookieAttributes));
913
944
  } else {
@@ -921,31 +952,40 @@ var TYPE_SEP = "~";
921
952
  var PAIR_SEP = "!";
922
953
  var KV_SEP = "-";
923
954
  function parseScoreCookie(cookieValue) {
924
- if (!cookieValue)
925
- return;
955
+ if (!cookieValue) return;
926
956
  const types = cookieValue.split(TYPE_SEP);
927
- if (types.length > 5)
928
- return;
957
+ if (types.length > 5) return;
929
958
  const [abTestData, sessionScores, visitorScores, controlGroup, personalizeVariants] = types;
930
959
  const data = {
931
960
  // this is true since we're reading a cookie, which wouldn't exist if consent wasn't given
932
961
  consent: true,
933
- sessionScores: decodeCookieType(parseCookieType(sessionScores)),
934
- scores: decodeCookieType(parseCookieType(visitorScores)),
962
+ sessionScores: decodeCookieType(parseCookieScores(sessionScores)),
963
+ scores: decodeCookieType(parseCookieScores(visitorScores)),
935
964
  tests: parseCookieType(abTestData),
936
965
  controlGroup: controlGroup === "1",
937
966
  personalizeVariants: decodePersonalizeVariants(personalizeVariants)
938
967
  };
939
968
  return data;
940
969
  }
970
+ function parseCookieScores(type) {
971
+ if (!type) {
972
+ return {};
973
+ }
974
+ const pairs = type.split(PAIR_SEP).map((pair) => pair.split(KV_SEP));
975
+ return pairs.reduce((acc, cur) => {
976
+ if (cur.length < 2) return acc;
977
+ const key = cur.slice(0, -1).join(KV_SEP);
978
+ acc[key] = cur[cur.length - 1];
979
+ return acc;
980
+ }, {});
981
+ }
941
982
  function parseCookieType(type) {
942
983
  if (!type) {
943
984
  return {};
944
985
  }
945
986
  const pairs = type.split(PAIR_SEP).map((pair) => pair.split(KV_SEP));
946
987
  return pairs.reduce((acc, cur) => {
947
- if (cur.length < 2)
948
- return acc;
988
+ if (cur.length < 2) return acc;
949
989
  acc[cur[0]] = cur.slice(1).join("-");
950
990
  return acc;
951
991
  }, {});
@@ -1013,13 +1053,13 @@ function serializeCookieType(type) {
1013
1053
  }
1014
1054
 
1015
1055
  // src/storage/EdgeTransitionDataStore.ts
1016
- var _fetchData, fetchData_fn;
1056
+ var _EdgeTransitionDataStore_instances, fetchData_fn;
1017
1057
  var EdgeTransitionDataStore = class extends TransitionDataStore {
1018
1058
  constructor({ serverCookieValue, visitorIdCookieName = "ufvi", ...base }) {
1019
1059
  super(base);
1020
- __privateAdd(this, _fetchData);
1060
+ __privateAdd(this, _EdgeTransitionDataStore_instances);
1021
1061
  if (!base.initialData) {
1022
- __privateMethod(this, _fetchData, fetchData_fn).call(this).catch((err) => {
1062
+ __privateMethod(this, _EdgeTransitionDataStore_instances, fetchData_fn).call(this).catch((err) => {
1023
1063
  console.error(err);
1024
1064
  });
1025
1065
  }
@@ -1038,7 +1078,7 @@ var EdgeTransitionDataStore = class extends TransitionDataStore {
1038
1078
  }
1039
1079
  }
1040
1080
  };
1041
- _fetchData = new WeakSet();
1081
+ _EdgeTransitionDataStore_instances = new WeakSet();
1042
1082
  fetchData_fn = async function() {
1043
1083
  const serviceData = await new Promise((resolve) => {
1044
1084
  setTimeout(() => {
@@ -1088,22 +1128,23 @@ var emptyVisitorData = () => ({
1088
1128
  scores: {},
1089
1129
  sessionScores: {},
1090
1130
  tests: {},
1131
+ goals: {},
1091
1132
  consent: false,
1092
1133
  controlGroup: false,
1093
1134
  personalizeVariants: {}
1094
1135
  });
1095
1136
 
1096
1137
  // src/storage/VisitorDataStore.ts
1097
- import { dequal as dequal3 } from "dequal/lite";
1138
+ import { dequal as dequal4 } from "dequal/lite";
1098
1139
  import mitt2 from "mitt";
1099
1140
 
1100
1141
  // src/storage/util/applyCommandsToData.ts
1101
1142
  import rfdc from "rfdc";
1102
1143
  var clone = rfdc();
1103
- function applyCommandsToData(commands, state, inControlGroup) {
1144
+ function applyCommandsToData(commands, state) {
1104
1145
  const newData = state ? clone(state) : emptyVisitorData();
1105
1146
  commands.forEach((command) => {
1106
- var _a, _b;
1147
+ var _a, _b, _c;
1107
1148
  switch (command.type) {
1108
1149
  case "consent":
1109
1150
  newData.consent = command.data;
@@ -1115,8 +1156,6 @@ function applyCommandsToData(commands, state, inControlGroup) {
1115
1156
  newData.tests[command.data.test] = command.data.variant;
1116
1157
  break;
1117
1158
  case "modscore":
1118
- if (inControlGroup)
1119
- break;
1120
1159
  const delta = Number(command.data.delta);
1121
1160
  if (isNaN(delta)) {
1122
1161
  throw new Error("Non-number delta received");
@@ -1125,8 +1164,6 @@ function applyCommandsToData(commands, state, inControlGroup) {
1125
1164
  newData.scores[command.data.dimension] = existing + delta;
1126
1165
  break;
1127
1166
  case "modscoreS":
1128
- if (inControlGroup)
1129
- break;
1130
1167
  const deltaS = Number(command.data.delta);
1131
1168
  if (isNaN(deltaS)) {
1132
1169
  throw new Error("Non-number delta received");
@@ -1158,6 +1195,10 @@ function applyCommandsToData(commands, state, inControlGroup) {
1158
1195
  console.warn("Overwriting existing control group definition is not allowed");
1159
1196
  }
1160
1197
  break;
1198
+ case "setgoal":
1199
+ newData.goals = (_c = newData.goals) != null ? _c : {};
1200
+ newData.goals[command.data.goal] = true;
1201
+ break;
1161
1202
  default:
1162
1203
  throw new Error(`Unknown command`);
1163
1204
  }
@@ -1166,71 +1207,65 @@ function applyCommandsToData(commands, state, inControlGroup) {
1166
1207
  }
1167
1208
 
1168
1209
  // src/storage/util/LocalStorage.ts
1210
+ var _LocalStorage_instances, key_fn;
1169
1211
  var LocalStorage = class {
1170
- constructor() {
1212
+ constructor(partitionKey) {
1213
+ this.partitionKey = partitionKey;
1214
+ __privateAdd(this, _LocalStorage_instances);
1171
1215
  __publicField(this, "inMemoryFallback", {});
1172
1216
  __publicField(this, "hasLocalStorageObject", typeof localStorage !== "undefined");
1173
1217
  }
1174
1218
  get(key) {
1175
- const fallbackValue = this.inMemoryFallback[key];
1219
+ const keyValue = __privateMethod(this, _LocalStorage_instances, key_fn).call(this, key);
1220
+ const fallbackValue = this.inMemoryFallback[keyValue];
1176
1221
  if (!this.hasLocalStorageObject || fallbackValue) {
1177
1222
  return fallbackValue;
1178
1223
  }
1179
1224
  try {
1180
- const value = localStorage.getItem(key);
1225
+ const value = localStorage.getItem(keyValue);
1181
1226
  return value ? JSON.parse(value) : void 0;
1182
1227
  } catch (e) {
1183
1228
  return fallbackValue;
1184
1229
  }
1185
1230
  }
1186
1231
  set(key, value, storageConsent) {
1187
- this.inMemoryFallback[key] = value;
1232
+ const keyValue = __privateMethod(this, _LocalStorage_instances, key_fn).call(this, key);
1233
+ this.inMemoryFallback[keyValue] = value;
1188
1234
  if (!this.hasLocalStorageObject || !storageConsent) {
1189
1235
  return;
1190
1236
  }
1191
1237
  try {
1192
- localStorage.setItem(key, JSON.stringify(value));
1238
+ localStorage.setItem(keyValue, JSON.stringify(value));
1193
1239
  } catch (e) {
1194
1240
  console.warn(e);
1195
1241
  }
1196
1242
  }
1197
1243
  delete(key, leaveInMemory) {
1244
+ const keyValue = __privateMethod(this, _LocalStorage_instances, key_fn).call(this, key);
1198
1245
  if (!leaveInMemory) {
1199
- delete this.inMemoryFallback[key];
1246
+ delete this.inMemoryFallback[keyValue];
1200
1247
  }
1201
1248
  try {
1202
- localStorage.removeItem(key);
1249
+ localStorage.removeItem(keyValue);
1203
1250
  } catch (e) {
1204
1251
  }
1205
1252
  }
1206
1253
  };
1254
+ _LocalStorage_instances = new WeakSet();
1255
+ key_fn = function(key) {
1256
+ return this.partitionKey ? `${this.partitionKey}.${key}` : key;
1257
+ };
1207
1258
 
1208
1259
  // src/storage/VisitorDataStore.ts
1209
1260
  var STORAGE_KEY = "ufvisitor";
1210
- var _mitt2, _persist, _visitTimeout, _options, _currentData, currentData_get, _replaceData, replaceData_fn, _setVisitTimeout, setVisitTimeout_fn, _isExpired, isExpired_fn, _handleCaps, handleCaps_fn, _defaultData, defaultData_fn;
1261
+ var _mitt2, _persist, _visitTimeout, _options, _VisitorDataStore_instances, currentData_get, replaceData_fn, setVisitTimeout_fn, isExpired_fn, handleCaps_fn, defaultData_fn;
1211
1262
  var VisitorDataStore = class {
1212
1263
  constructor(options) {
1213
- /** Gets the current client-side storage data. This property is always up to date. */
1214
- __privateAdd(this, _currentData);
1215
- /**
1216
- * IMPORTANT: This function mutates the input data. This is done,
1217
- * because all the sources that call it have either already spread or cloned
1218
- * the data, so we can safely mutate it for better perf.
1219
- */
1220
- __privateAdd(this, _replaceData);
1221
- __privateAdd(this, _setVisitTimeout);
1222
- __privateAdd(this, _isExpired);
1223
- /**
1224
- * IMPORTANT: This function mutates the input data. This is done,
1225
- * because all the sources that call it have either already spread or cloned
1226
- * the data, so we can safely mutate it for better perf.
1227
- */
1228
- __privateAdd(this, _handleCaps);
1229
- __privateAdd(this, _defaultData);
1264
+ __privateAdd(this, _VisitorDataStore_instances);
1230
1265
  __privateAdd(this, _mitt2, mitt2());
1231
- __privateAdd(this, _persist, new LocalStorage());
1232
- __privateAdd(this, _visitTimeout, void 0);
1233
- __privateAdd(this, _options, void 0);
1266
+ __privateAdd(this, _persist);
1267
+ __privateAdd(this, _visitTimeout);
1268
+ __privateAdd(this, _options);
1234
1269
  /**
1235
1270
  * Subscribe to events from storage
1236
1271
  */
@@ -1239,8 +1274,9 @@ var VisitorDataStore = class {
1239
1274
  off: __privateGet(this, _mitt2).off
1240
1275
  });
1241
1276
  __privateSet(this, _options, options);
1242
- if (!__privateGet(this, _currentData, currentData_get)) {
1243
- __privateMethod(this, _replaceData, replaceData_fn).call(this, __privateMethod(this, _defaultData, defaultData_fn).call(this), true);
1277
+ __privateSet(this, _persist, new LocalStorage(options.partitionKey));
1278
+ if (!__privateGet(this, _VisitorDataStore_instances, currentData_get)) {
1279
+ __privateMethod(this, _VisitorDataStore_instances, replaceData_fn).call(this, __privateMethod(this, _VisitorDataStore_instances, defaultData_fn).call(this), true);
1244
1280
  }
1245
1281
  if (options.transitionStore) {
1246
1282
  const serverToClientTransitionState = options.transitionStore.getClientTransitionState();
@@ -1248,17 +1284,17 @@ var VisitorDataStore = class {
1248
1284
  options.onServerTransitionReceived(serverToClientTransitionState);
1249
1285
  }
1250
1286
  options.transitionStore.events.on("dataUpdatedAsync", (data) => {
1251
- __privateMethod(this, _replaceData, replaceData_fn).call(this, {
1252
- ...__privateGet(this, _currentData, currentData_get).visitorData,
1287
+ __privateMethod(this, _VisitorDataStore_instances, replaceData_fn).call(this, {
1288
+ ...__privateGet(this, _VisitorDataStore_instances, currentData_get).visitorData,
1253
1289
  ...data
1254
1290
  });
1255
1291
  });
1256
1292
  const transitionData = options.transitionStore.data;
1257
1293
  if (transitionData) {
1258
- __privateMethod(this, _replaceData, replaceData_fn).call(
1294
+ __privateMethod(this, _VisitorDataStore_instances, replaceData_fn).call(
1259
1295
  this,
1260
1296
  // we know _currentData is not empty because we inited it above if it was
1261
- { ...__privateGet(this, _currentData, currentData_get).visitorData, ...transitionData },
1297
+ { ...__privateGet(this, _VisitorDataStore_instances, currentData_get).visitorData, ...transitionData },
1262
1298
  true
1263
1299
  );
1264
1300
  }
@@ -1266,13 +1302,13 @@ var VisitorDataStore = class {
1266
1302
  }
1267
1303
  /** Gets the current visitor data. This property is always up to date. */
1268
1304
  get data() {
1269
- var _a, _b;
1270
- const data = __privateGet(this, _currentData, currentData_get);
1271
- if (__privateMethod(this, _isExpired, isExpired_fn).call(this, data)) {
1305
+ var _a, _b, _c;
1306
+ 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() };
1307
+ if (__privateMethod(this, _VisitorDataStore_instances, isExpired_fn).call(this, data)) {
1272
1308
  const { sessionScores, ...newData } = data.visitorData;
1273
- __privateMethod(this, _replaceData, replaceData_fn).call(this, { ...newData, sessionScores: {} });
1274
- (_b = (_a = __privateGet(this, _options)).onLogMessage) == null ? void 0 : _b.call(_a, ["info", 120]);
1275
- return __privateGet(this, _currentData, currentData_get).visitorData;
1309
+ __privateMethod(this, _VisitorDataStore_instances, replaceData_fn).call(this, { ...newData, sessionScores: {} });
1310
+ (_c = (_b = __privateGet(this, _options)).onLogMessage) == null ? void 0 : _c.call(_b, ["info", 120]);
1311
+ return __privateGet(this, _VisitorDataStore_instances, currentData_get).visitorData;
1276
1312
  }
1277
1313
  return data.visitorData;
1278
1314
  }
@@ -1284,17 +1320,18 @@ var VisitorDataStore = class {
1284
1320
  }
1285
1321
  /** Push data update command(s) into the visitor data */
1286
1322
  async updateData(commands) {
1287
- var _a, _b, _c, _d;
1323
+ var _a, _b, _c;
1288
1324
  if (commands.length === 0) {
1289
1325
  return;
1290
1326
  }
1291
1327
  (_b = (_a = __privateGet(this, _options)).onLogMessage) == null ? void 0 : _b.call(_a, ["debug", 101, commands]);
1292
- const newData = applyCommandsToData(commands, this.data, (_c = __privateGet(this, _currentData, currentData_get)) == null ? void 0 : _c.visitorData.controlGroup);
1328
+ const newData = applyCommandsToData(commands, this.data);
1293
1329
  if (commands.some((c) => c.type === "consent" && !c.data)) {
1294
1330
  __privateGet(this, _persist).delete(STORAGE_KEY, true);
1295
1331
  }
1296
- __privateMethod(this, _replaceData, replaceData_fn).call(this, newData);
1297
- await ((_d = __privateGet(this, _options).transitionStore) == null ? void 0 : _d.updateData(commands, __privateGet(this, _currentData, currentData_get).visitorData));
1332
+ __privateMethod(this, _VisitorDataStore_instances, replaceData_fn).call(this, newData);
1333
+ await ((_c = __privateGet(this, _options).transitionStore) == null ? void 0 : _c.updateData(commands, __privateGet(this, _VisitorDataStore_instances, currentData_get).visitorData));
1334
+ __privateGet(this, _mitt2).emit("commandsExecuted", commands);
1298
1335
  }
1299
1336
  /**
1300
1337
  * Deletes visitor data (forgetting them)
@@ -1307,7 +1344,7 @@ var VisitorDataStore = class {
1307
1344
  try {
1308
1345
  __privateGet(this, _persist).delete(STORAGE_KEY, false);
1309
1346
  await ((_c = __privateGet(this, _options).transitionStore) == null ? void 0 : _c.delete(fromAllDevices));
1310
- __privateMethod(this, _replaceData, replaceData_fn).call(this, __privateMethod(this, _defaultData, defaultData_fn).call(this));
1347
+ __privateMethod(this, _VisitorDataStore_instances, replaceData_fn).call(this, __privateMethod(this, _VisitorDataStore_instances, defaultData_fn).call(this));
1311
1348
  } finally {
1312
1349
  (_e = (_d = __privateGet(this, _options)).onLogMessage) == null ? void 0 : _e.call(_d, ["info", 103, "ENDGROUP"]);
1313
1350
  }
@@ -1317,38 +1354,38 @@ _mitt2 = new WeakMap();
1317
1354
  _persist = new WeakMap();
1318
1355
  _visitTimeout = new WeakMap();
1319
1356
  _options = new WeakMap();
1320
- _currentData = new WeakSet();
1357
+ _VisitorDataStore_instances = new WeakSet();
1321
1358
  currentData_get = function() {
1322
1359
  return __privateGet(this, _persist).get(STORAGE_KEY);
1323
1360
  };
1324
- _replaceData = new WeakSet();
1361
+ /**
1362
+ * IMPORTANT: This function mutates the input data. This is done,
1363
+ * because all the sources that call it have either already spread or cloned
1364
+ * the data, so we can safely mutate it for better perf.
1365
+ */
1325
1366
  replaceData_fn = function(data, quiet = false) {
1326
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1327
- const oldData = __privateGet(this, _currentData, currentData_get);
1367
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
1368
+ const oldData = __privateGet(this, _VisitorDataStore_instances, currentData_get);
1328
1369
  const now = Date.now();
1329
- if (data.controlGroup) {
1330
- data.scores = {};
1331
- data.sessionScores = {};
1332
- } else {
1333
- __privateMethod(this, _handleCaps, handleCaps_fn).call(this, data.scores);
1334
- __privateMethod(this, _handleCaps, handleCaps_fn).call(this, data.sessionScores);
1335
- (_b = (_a = __privateGet(this, _options)).decay) == null ? void 0 : _b.call(_a, {
1336
- now,
1337
- lastUpd: oldData == null ? void 0 : oldData.updated,
1338
- scores: data.scores,
1339
- sessionScores: data.sessionScores,
1340
- onLogMessage: __privateGet(this, _options).onLogMessage
1341
- });
1342
- }
1343
- const haveScoresChanged = !dequal3(oldData == null ? void 0 : oldData.visitorData.scores, data.scores);
1344
- const haveSessionScoresChanged = !dequal3(oldData == null ? void 0 : oldData.visitorData.sessionScores, data.sessionScores);
1345
- const haveQuirksChanged = !dequal3(oldData == null ? void 0 : oldData.visitorData.quirks, data.quirks);
1346
- const haveTestsChanged = !dequal3(oldData == null ? void 0 : oldData.visitorData.tests, data.tests);
1370
+ __privateMethod(this, _VisitorDataStore_instances, handleCaps_fn).call(this, data.scores);
1371
+ __privateMethod(this, _VisitorDataStore_instances, handleCaps_fn).call(this, data.sessionScores);
1372
+ (_b = (_a = __privateGet(this, _options)).decay) == null ? void 0 : _b.call(_a, {
1373
+ now,
1374
+ lastUpd: oldData == null ? void 0 : oldData.updated,
1375
+ scores: data.scores,
1376
+ sessionScores: data.sessionScores,
1377
+ onLogMessage: __privateGet(this, _options).onLogMessage
1378
+ });
1379
+ const haveScoresChanged = !dequal4(oldData == null ? void 0 : oldData.visitorData.scores, data.scores);
1380
+ const haveSessionScoresChanged = !dequal4(oldData == null ? void 0 : oldData.visitorData.sessionScores, data.sessionScores);
1381
+ const haveQuirksChanged = !dequal4(oldData == null ? void 0 : oldData.visitorData.quirks, data.quirks);
1382
+ const haveTestsChanged = !dequal4(oldData == null ? void 0 : oldData.visitorData.tests, data.tests);
1383
+ const haveGoalsChanged = !dequal4(oldData == null ? void 0 : oldData.visitorData.goals, data.goals);
1347
1384
  const updatedData = {
1348
1385
  updated: now,
1349
1386
  visitorData: data
1350
1387
  };
1351
- __privateMethod(this, _setVisitTimeout, setVisitTimeout_fn).call(this);
1388
+ __privateMethod(this, _VisitorDataStore_instances, setVisitTimeout_fn).call(this);
1352
1389
  __privateGet(this, _persist).set(STORAGE_KEY, updatedData, !!data.consent);
1353
1390
  (_d = (_c = __privateGet(this, _options)).onLogMessage) == null ? void 0 : _d.call(_c, ["debug", 102, data]);
1354
1391
  if (!quiet) {
@@ -1368,9 +1405,17 @@ replaceData_fn = function(data, quiet = false) {
1368
1405
  __privateGet(this, _mitt2).emit("controlGroupUpdated", data);
1369
1406
  (_i = (_h = __privateGet(this, _options)).onLogMessage) == null ? void 0 : _i.call(_h, ["debug", 104, (_g = data.controlGroup) != null ? _g : false]);
1370
1407
  }
1408
+ if (haveGoalsChanged) {
1409
+ const newGoalKeys = Object.keys((_j = data.goals) != null ? _j : {});
1410
+ for (let i = 0; i < newGoalKeys.length; i++) {
1411
+ const key = newGoalKeys[i];
1412
+ if (!((_k = oldData == null ? void 0 : oldData.visitorData.goals) == null ? void 0 : _k[key])) {
1413
+ __privateGet(this, _mitt2).emit("goalConverted", { goalId: key });
1414
+ }
1415
+ }
1416
+ }
1371
1417
  }
1372
1418
  };
1373
- _setVisitTimeout = new WeakSet();
1374
1419
  setVisitTimeout_fn = function() {
1375
1420
  if (typeof document === "undefined" || !__privateGet(this, _options).visitLifespan) {
1376
1421
  return;
@@ -1382,12 +1427,15 @@ setVisitTimeout_fn = function() {
1382
1427
  this.data;
1383
1428
  }, __privateGet(this, _options).visitLifespan + 50));
1384
1429
  };
1385
- _isExpired = new WeakSet();
1386
1430
  isExpired_fn = function(data) {
1387
1431
  const expires = __privateGet(this, _options).visitLifespan;
1388
1432
  return expires ? data.updated + expires < Date.now() : false;
1389
1433
  };
1390
- _handleCaps = new WeakSet();
1434
+ /**
1435
+ * IMPORTANT: This function mutates the input data. This is done,
1436
+ * because all the sources that call it have either already spread or cloned
1437
+ * the data, so we can safely mutate it for better perf.
1438
+ */
1391
1439
  handleCaps_fn = function(scores) {
1392
1440
  var _a, _b;
1393
1441
  if (!__privateGet(this, _options).manifest) {
@@ -1405,7 +1453,6 @@ handleCaps_fn = function(scores) {
1405
1453
  }
1406
1454
  }
1407
1455
  };
1408
- _defaultData = new WeakSet();
1409
1456
  defaultData_fn = function() {
1410
1457
  var _a, _b, _c;
1411
1458
  return {
@@ -1416,21 +1463,21 @@ defaultData_fn = function() {
1416
1463
  };
1417
1464
 
1418
1465
  // src/Context.ts
1419
- import { dequal as dequal4 } from "dequal/lite";
1466
+ import { dequal as dequal5 } from "dequal/lite";
1420
1467
  import mitt3 from "mitt";
1421
1468
  var CONTEXTUAL_EDITING_TEST_NAME = "contextual_editing_test";
1422
1469
  var CONTEXTUAL_EDITING_TEST_SELECTED_VARIANT_ID = "contextual_editing_test_selected_variant";
1423
- var _serverTransitionState, _scores, _state, _pzCache, _mitt3, _emitTest, emitTest_fn, _updateComputedScores, updateComputedScores_fn, _calculateScores, calculateScores_fn;
1470
+ var _serverTransitionState, _scores, _state, _pzCache, _plugins, _commands, _mitt3, _Context_instances, emitTest_fn, updateGoals_fn, updateComputedScores_fn, calculateScores_fn;
1424
1471
  var Context = class {
1425
1472
  constructor(options) {
1426
- __privateAdd(this, _emitTest);
1427
- __privateAdd(this, _updateComputedScores);
1428
- __privateAdd(this, _calculateScores);
1473
+ __privateAdd(this, _Context_instances);
1429
1474
  __publicField(this, "manifest");
1430
- __privateAdd(this, _serverTransitionState, void 0);
1475
+ __privateAdd(this, _serverTransitionState);
1431
1476
  __privateAdd(this, _scores, {});
1432
- __privateAdd(this, _state, void 0);
1477
+ __privateAdd(this, _state);
1433
1478
  __privateAdd(this, _pzCache, {});
1479
+ __privateAdd(this, _plugins);
1480
+ __privateAdd(this, _commands);
1434
1481
  __privateAdd(this, _mitt3, mitt3());
1435
1482
  /**
1436
1483
  * Subscribe to events
@@ -1443,7 +1490,11 @@ var Context = class {
1443
1490
  var _a, _b;
1444
1491
  const { manifest, ...storageOptions } = options;
1445
1492
  __privateSet(this, _state, {});
1446
- (_a = options.plugins) == null ? void 0 : _a.forEach((plugin) => {
1493
+ __privateSet(this, _plugins, options.plugins);
1494
+ if (typeof options.transitionStore !== "undefined") {
1495
+ __privateSet(this, _commands, []);
1496
+ }
1497
+ (_a = __privateGet(this, _plugins)) == null ? void 0 : _a.forEach((plugin) => {
1447
1498
  if (!plugin.logDrain) {
1448
1499
  return;
1449
1500
  }
@@ -1475,9 +1526,9 @@ var Context = class {
1475
1526
  },
1476
1527
  onLogMessage: (message) => __privateGet(this, _mitt3).emit("log", message)
1477
1528
  });
1478
- this.storage.events.on("scoresUpdated", __privateMethod(this, _updateComputedScores, updateComputedScores_fn).bind(this));
1529
+ this.storage.events.on("scoresUpdated", __privateMethod(this, _Context_instances, updateComputedScores_fn).bind(this));
1479
1530
  if (!__privateGet(this, _serverTransitionState)) {
1480
- __privateMethod(this, _updateComputedScores, updateComputedScores_fn).call(this, this.storage.data);
1531
+ __privateMethod(this, _Context_instances, updateComputedScores_fn).call(this, this.storage.data);
1481
1532
  }
1482
1533
  this.storage.events.on("quirksUpdated", (quirks) => {
1483
1534
  const updates = this.manifest.computeSignals({
@@ -1486,11 +1537,15 @@ var Context = class {
1486
1537
  previousState: __privateGet(this, _state),
1487
1538
  visitor: this.storage.data
1488
1539
  });
1540
+ __privateMethod(this, _Context_instances, updateGoals_fn).call(this, {
1541
+ quirks: quirks.quirks,
1542
+ scores: void 0
1543
+ });
1489
1544
  this.storage.updateData(updates);
1490
1545
  __privateGet(this, _mitt3).emit("quirksUpdated", quirks.quirks);
1491
1546
  __privateGet(this, _mitt3).emit("log", ["info", 4, quirks.quirks]);
1492
1547
  });
1493
- (_b = options.plugins) == null ? void 0 : _b.forEach((plugin) => {
1548
+ (_b = __privateGet(this, _plugins)) == null ? void 0 : _b.forEach((plugin) => {
1494
1549
  if (!plugin.init) {
1495
1550
  return;
1496
1551
  }
@@ -1499,6 +1554,9 @@ var Context = class {
1499
1554
  } finally {
1500
1555
  __privateGet(this, _mitt3).emit("log", ["info", 1, "ENDGROUP"]);
1501
1556
  }
1557
+ if (typeof window !== "undefined") {
1558
+ window.__UNIFORM_CONTEXTUAL_EDITING_CONTEXT__ = this;
1559
+ }
1502
1560
  }
1503
1561
  /** Gets the current visitor's dimension score vector. */
1504
1562
  get scores() {
@@ -1519,7 +1577,7 @@ var Context = class {
1519
1577
  * will NOT result in a recomputation of signal state.
1520
1578
  */
1521
1579
  async update(newData) {
1522
- var _a, _b, _c, _d;
1580
+ var _a, _b, _c, _d, _e;
1523
1581
  const commands = [];
1524
1582
  const newServerSideTests = {};
1525
1583
  if ((_a = __privateGet(this, _serverTransitionState)) == null ? void 0 : _a.quirks) {
@@ -1605,7 +1663,7 @@ var Context = class {
1605
1663
  // re-compute using scores from storage instead of the current scores since
1606
1664
  // server transition scores might have adjusted values already integrated into them,
1607
1665
  // which causes issues when you are near limits.
1608
- scores: __privateGet(this, _serverTransitionState) ? __privateMethod(this, _calculateScores, calculateScores_fn).call(this, this.storage.data) : __privateGet(this, _scores)
1666
+ scores: __privateGet(this, _serverTransitionState) ? __privateMethod(this, _Context_instances, calculateScores_fn).call(this, this.storage.data) : __privateGet(this, _scores)
1609
1667
  })
1610
1668
  );
1611
1669
  __privateSet(this, _state, {
@@ -1614,9 +1672,13 @@ var Context = class {
1614
1672
  });
1615
1673
  await this.storage.updateData(commands);
1616
1674
  if (__privateGet(this, _serverTransitionState)) {
1617
- __privateMethod(this, _updateComputedScores, updateComputedScores_fn).call(this, this.storage.data);
1675
+ await this.processServerCommands({
1676
+ serverCommands: __privateGet(this, _serverTransitionState).commands,
1677
+ commands
1678
+ });
1679
+ __privateMethod(this, _Context_instances, updateComputedScores_fn).call(this, this.storage.data);
1618
1680
  Object.entries(newServerSideTests).forEach(([testName, testVariantId]) => {
1619
- __privateMethod(this, _emitTest, emitTest_fn).call(this, {
1681
+ __privateMethod(this, _Context_instances, emitTest_fn).call(this, {
1620
1682
  name: testName,
1621
1683
  variantId: testVariantId,
1622
1684
  variantAssigned: true
@@ -1625,10 +1687,40 @@ var Context = class {
1625
1687
  __privateSet(this, _serverTransitionState, void 0);
1626
1688
  __privateGet(this, _mitt3).emit("log", ["debug", 131]);
1627
1689
  }
1690
+ if (__privateGet(this, _plugins)) {
1691
+ for (let i = 0; i < __privateGet(this, _plugins).length; i++) {
1692
+ const plugin = __privateGet(this, _plugins)[i];
1693
+ if (!plugin.update) {
1694
+ continue;
1695
+ }
1696
+ await plugin.update(newData);
1697
+ }
1698
+ }
1699
+ (_e = __privateGet(this, _commands)) == null ? void 0 : _e.push(...commands);
1628
1700
  } finally {
1629
1701
  __privateGet(this, _mitt3).emit("log", ["info", 2, "ENDGROUP"]);
1630
1702
  }
1631
1703
  }
1704
+ async processServerCommands({
1705
+ serverCommands,
1706
+ commands
1707
+ }) {
1708
+ if (!(serverCommands == null ? void 0 : serverCommands.length)) {
1709
+ return;
1710
+ }
1711
+ const notExecutedCommands = [];
1712
+ serverCommands.forEach((serverCommand) => {
1713
+ const found = commands.find((command) => {
1714
+ return areCommandsEqual(command, serverCommand);
1715
+ });
1716
+ if (!found) {
1717
+ notExecutedCommands.push(serverCommand);
1718
+ }
1719
+ });
1720
+ if (notExecutedCommands.length > 0) {
1721
+ await this.storage.updateData(notExecutedCommands);
1722
+ }
1723
+ }
1632
1724
  /** use test() instead */
1633
1725
  getTestVariantId(testName) {
1634
1726
  var _a, _b, _c, _d;
@@ -1683,7 +1775,7 @@ var Context = class {
1683
1775
  context: this,
1684
1776
  onLogMessage: (message) => __privateGet(this, _mitt3).emit("log", message)
1685
1777
  });
1686
- __privateMethod(this, _emitTest, emitTest_fn).call(this, {
1778
+ __privateMethod(this, _Context_instances, emitTest_fn).call(this, {
1687
1779
  name: options.name,
1688
1780
  variantId: (_c = (_b = value.result) == null ? void 0 : _b.id) != null ? _c : void 0,
1689
1781
  variantAssigned: value.variantAssigned
@@ -1707,7 +1799,7 @@ var Context = class {
1707
1799
  control: this.storage.data.controlGroup,
1708
1800
  changed: true
1709
1801
  };
1710
- if (previousPlacement && dequal4(eventData.variantIds, previousPlacement)) {
1802
+ if (previousPlacement && dequal5(eventData.variantIds, previousPlacement)) {
1711
1803
  eventData.changed = false;
1712
1804
  }
1713
1805
  __privateGet(this, _mitt3).emit("personalizationResult", eventData);
@@ -1720,6 +1812,15 @@ var Context = class {
1720
1812
  */
1721
1813
  async forget(fromAllDevices) {
1722
1814
  __privateSet(this, _state, {});
1815
+ if (__privateGet(this, _plugins)) {
1816
+ for (let i = 0; i < __privateGet(this, _plugins).length; i++) {
1817
+ const plugin = __privateGet(this, _plugins)[i];
1818
+ if (!plugin.forget) {
1819
+ continue;
1820
+ }
1821
+ await plugin.forget();
1822
+ }
1823
+ }
1723
1824
  await this.storage.delete(fromAllDevices);
1724
1825
  }
1725
1826
  /**
@@ -1732,7 +1833,8 @@ var Context = class {
1732
1833
  quirks: this.storage.data.quirks,
1733
1834
  ssv: __privateGet(this, _scores),
1734
1835
  tests: {},
1735
- personalizeVariants: this.storage.data.personalizeVariants
1836
+ personalizeVariants: this.storage.data.personalizeVariants,
1837
+ commands: __privateGet(this, _commands)
1736
1838
  };
1737
1839
  const allTests = this.storage.data.tests;
1738
1840
  Object.entries(allTests).map(([testName, testValue]) => {
@@ -1747,7 +1849,7 @@ var Context = class {
1747
1849
  internal_processTestEvent(event) {
1748
1850
  if (event.variantId) {
1749
1851
  this.setTestVariantId(event.name, event.variantId);
1750
- __privateMethod(this, _emitTest, emitTest_fn).call(this, event);
1852
+ __privateMethod(this, _Context_instances, emitTest_fn).call(this, event);
1751
1853
  }
1752
1854
  }
1753
1855
  /** @deprecated */
@@ -1760,22 +1862,32 @@ _serverTransitionState = new WeakMap();
1760
1862
  _scores = new WeakMap();
1761
1863
  _state = new WeakMap();
1762
1864
  _pzCache = new WeakMap();
1865
+ _plugins = new WeakMap();
1866
+ _commands = new WeakMap();
1763
1867
  _mitt3 = new WeakMap();
1764
- _emitTest = new WeakSet();
1868
+ _Context_instances = new WeakSet();
1765
1869
  emitTest_fn = function(event) {
1766
1870
  __privateGet(this, _mitt3).emit("testResult", event);
1767
1871
  };
1768
- _updateComputedScores = new WeakSet();
1872
+ updateGoals_fn = async function(data) {
1873
+ const goalCommands = this.manifest.computeGoals(data);
1874
+ if (goalCommands.length !== 0) {
1875
+ await this.storage.updateData(goalCommands);
1876
+ }
1877
+ };
1769
1878
  updateComputedScores_fn = function(newData) {
1770
- const newScores = __privateMethod(this, _calculateScores, calculateScores_fn).call(this, newData);
1771
- const newScoresHaveChanged = !dequal4(newScores, __privateGet(this, _scores));
1879
+ const newScores = __privateMethod(this, _Context_instances, calculateScores_fn).call(this, newData);
1880
+ const newScoresHaveChanged = !dequal5(newScores, __privateGet(this, _scores));
1772
1881
  if (newScoresHaveChanged) {
1773
1882
  __privateSet(this, _scores, newScores);
1883
+ __privateMethod(this, _Context_instances, updateGoals_fn).call(this, {
1884
+ scores: __privateGet(this, _scores),
1885
+ quirks: void 0
1886
+ });
1774
1887
  __privateGet(this, _mitt3).emit("scoresUpdated", newScores);
1775
1888
  __privateGet(this, _mitt3).emit("log", ["info", 3, newScores]);
1776
1889
  }
1777
1890
  };
1778
- _calculateScores = new WeakSet();
1779
1891
  calculateScores_fn = function(newData) {
1780
1892
  var _a;
1781
1893
  let newScores = { ...newData.scores };
@@ -1824,13 +1936,11 @@ function enableContextDevTools(options) {
1824
1936
  );
1825
1937
  };
1826
1938
  const onPersonalizationResult = (e) => {
1827
- if (!e.changed)
1828
- return;
1939
+ if (!e.changed) return;
1829
1940
  personalizations.push(e);
1830
1941
  };
1831
1942
  const onTestResult = (e) => {
1832
- if (!e.variantAssigned)
1833
- return;
1943
+ if (!e.variantAssigned) return;
1834
1944
  tests.push(e);
1835
1945
  };
1836
1946
  if (isBrowser) {
@@ -1909,6 +2019,344 @@ var ScriptType = /* @__PURE__ */ ((ScriptType2) => {
1909
2019
  })(ScriptType || {});
1910
2020
  var EdgeNodeTagName = "nesitag";
1911
2021
 
2022
+ // src/insights/index.ts
2023
+ import { v4 } from "uuid";
2024
+ var getBasePayload = () => {
2025
+ const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
2026
+ const locale = navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.userLanguage || navigator.language || navigator.browserLanguage || "en";
2027
+ return {
2028
+ "user-agent": window.navigator.userAgent,
2029
+ locale,
2030
+ location: timeZone,
2031
+ referrer: document.referrer,
2032
+ pathname: window.location.pathname,
2033
+ href: window.location.href
2034
+ };
2035
+ };
2036
+ var createInsightsClient = ({ endpoint }) => {
2037
+ let endpointUrl;
2038
+ const apiKey = endpoint.apiKey;
2039
+ if (endpoint.type === "api") {
2040
+ const url = new URL(endpoint.host);
2041
+ url.pathname = "/v0/events";
2042
+ url.searchParams.set("name", "analytics_events");
2043
+ endpointUrl = url.toString();
2044
+ } else {
2045
+ endpointUrl = endpoint.path;
2046
+ }
2047
+ const sendMessage = async (message) => {
2048
+ if (typeof window.__UNIFORM_CONTEXTUAL_EDITING__ !== "undefined") {
2049
+ return;
2050
+ }
2051
+ const converted = {
2052
+ ...message,
2053
+ payload: JSON.stringify(message.payload)
2054
+ };
2055
+ const headers = {
2056
+ "Content-Type": "application/json"
2057
+ };
2058
+ if (apiKey) {
2059
+ headers.Authorization = `Bearer ${apiKey}`;
2060
+ }
2061
+ const response = await fetch(endpointUrl, {
2062
+ method: "POST",
2063
+ headers,
2064
+ body: JSON.stringify(converted)
2065
+ });
2066
+ const json = await response.json();
2067
+ return json;
2068
+ };
2069
+ return {
2070
+ sessionStart: (options) => {
2071
+ const message = {
2072
+ action: "session_start",
2073
+ version: "1",
2074
+ session_id: options.sessionId,
2075
+ visitor_id: options.visitorId,
2076
+ page_view_id: options.pageId,
2077
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2078
+ payload: {
2079
+ ...getBasePayload(),
2080
+ previous_session_id: options.previousSessionId
2081
+ }
2082
+ };
2083
+ return sendMessage(message);
2084
+ },
2085
+ pageHit: (options) => {
2086
+ const message = {
2087
+ action: "page_hit",
2088
+ version: "1",
2089
+ session_id: options.sessionId,
2090
+ visitor_id: options.visitorId,
2091
+ page_view_id: options.pageId,
2092
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2093
+ payload: getBasePayload()
2094
+ };
2095
+ return sendMessage(message);
2096
+ },
2097
+ testResult: async (options) => {
2098
+ const message = {
2099
+ action: "test_result",
2100
+ version: "1",
2101
+ session_id: options.sessionId,
2102
+ visitor_id: options.visitorId,
2103
+ page_view_id: options.pageId,
2104
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2105
+ payload: {
2106
+ ...getBasePayload(),
2107
+ ...options
2108
+ }
2109
+ };
2110
+ return sendMessage(message);
2111
+ },
2112
+ personalizationResult: async (options) => {
2113
+ const messages = options.variantIds.map((variant) => {
2114
+ const message = {
2115
+ action: "personalization_result",
2116
+ version: "1",
2117
+ session_id: options.sessionId,
2118
+ visitor_id: options.visitorId,
2119
+ page_view_id: options.pageId,
2120
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2121
+ payload: {
2122
+ ...getBasePayload(),
2123
+ name: options.name,
2124
+ variantId: variant.id,
2125
+ control: variant.control || options.control,
2126
+ changed: options.changed
2127
+ }
2128
+ };
2129
+ return message;
2130
+ });
2131
+ await Promise.all(messages.map((message) => sendMessage(message)));
2132
+ },
2133
+ goalConvert: (options) => {
2134
+ const message = {
2135
+ action: "goal_convert",
2136
+ version: "1",
2137
+ session_id: options.sessionId,
2138
+ visitor_id: options.visitorId,
2139
+ page_view_id: options.pageId,
2140
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2141
+ payload: {
2142
+ ...getBasePayload(),
2143
+ goalId: options.goalId
2144
+ }
2145
+ };
2146
+ return sendMessage(message);
2147
+ },
2148
+ scoresChange: async (options) => {
2149
+ const message = {
2150
+ action: "scores_change",
2151
+ version: "1",
2152
+ session_id: options.sessionId,
2153
+ visitor_id: options.visitorId,
2154
+ page_view_id: options.pageId,
2155
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2156
+ payload: {
2157
+ ...getBasePayload(),
2158
+ scores: options.scores
2159
+ }
2160
+ };
2161
+ return sendMessage(message);
2162
+ }
2163
+ };
2164
+ };
2165
+ var createInsightsStorage = () => {
2166
+ const STORAGE_KEY2 = "ufin";
2167
+ return {
2168
+ get: () => {
2169
+ const data = localStorage.getItem(STORAGE_KEY2);
2170
+ if (!data) {
2171
+ return;
2172
+ }
2173
+ return JSON.parse(data);
2174
+ },
2175
+ set: (data) => {
2176
+ const toSet = {
2177
+ ...data,
2178
+ updated: Date.now()
2179
+ };
2180
+ localStorage.setItem(STORAGE_KEY2, JSON.stringify(toSet));
2181
+ },
2182
+ clear: () => {
2183
+ localStorage.removeItem(STORAGE_KEY2);
2184
+ }
2185
+ };
2186
+ };
2187
+ var generateVisitorId = () => {
2188
+ return `visitor_${generalRandomId()}`;
2189
+ };
2190
+ var generateSessionId = () => {
2191
+ return `session_${generalRandomId()}`;
2192
+ };
2193
+ var generatePageId = () => {
2194
+ return `page_${generalRandomId()}`;
2195
+ };
2196
+ var createInsights = ({
2197
+ endpoint,
2198
+ sessionDurationSeconds = 30 * 60
2199
+ }) => {
2200
+ const client = createInsightsClient({
2201
+ endpoint
2202
+ });
2203
+ const storage = createInsightsStorage();
2204
+ let storageData = void 0;
2205
+ let pageId = generatePageId();
2206
+ let previousUrl = void 0;
2207
+ return {
2208
+ init: () => {
2209
+ storageData = storage.get();
2210
+ if (!storageData || Date.now() - storageData.updated > sessionDurationSeconds * 1e3) {
2211
+ const previousSessionId = storageData == null ? void 0 : storageData.sessionId;
2212
+ storageData = {
2213
+ visitorId: (storageData == null ? void 0 : storageData.visitorId) || generateVisitorId(),
2214
+ sessionId: generateSessionId(),
2215
+ updated: Date.now()
2216
+ };
2217
+ storage.set(storageData);
2218
+ client.sessionStart({
2219
+ visitorId: storageData.visitorId,
2220
+ sessionId: storageData.sessionId,
2221
+ previousSessionId,
2222
+ maxAgeSeconds: sessionDurationSeconds,
2223
+ pageId
2224
+ });
2225
+ } else if (storageData) {
2226
+ storage.set(storageData);
2227
+ }
2228
+ },
2229
+ pageHit: () => {
2230
+ if (!storageData) {
2231
+ return;
2232
+ }
2233
+ if (previousUrl === window.location.href) {
2234
+ return;
2235
+ }
2236
+ previousUrl = window.location.href;
2237
+ pageId = generatePageId();
2238
+ client.pageHit({
2239
+ visitorId: storageData.visitorId,
2240
+ sessionId: storageData.sessionId,
2241
+ pageId
2242
+ });
2243
+ },
2244
+ testResult: (result) => {
2245
+ if (!storageData) {
2246
+ console.error("Insights not initialized");
2247
+ return;
2248
+ }
2249
+ client.testResult({
2250
+ ...result,
2251
+ visitorId: storageData.visitorId,
2252
+ sessionId: storageData.sessionId,
2253
+ pageId
2254
+ });
2255
+ },
2256
+ personalizationResult: (result) => {
2257
+ if (!storageData) {
2258
+ return;
2259
+ }
2260
+ client.personalizationResult({
2261
+ ...result,
2262
+ visitorId: storageData.visitorId,
2263
+ sessionId: storageData.sessionId,
2264
+ pageId
2265
+ });
2266
+ },
2267
+ goalConvert: (goalId) => {
2268
+ if (!storageData) {
2269
+ return;
2270
+ }
2271
+ client.goalConvert({
2272
+ visitorId: storageData.visitorId,
2273
+ sessionId: storageData.sessionId,
2274
+ goalId,
2275
+ pageId
2276
+ });
2277
+ },
2278
+ scoresChange: (scores) => {
2279
+ if (!storageData) {
2280
+ return;
2281
+ }
2282
+ client.scoresChange({
2283
+ visitorId: storageData.visitorId,
2284
+ sessionId: storageData.sessionId,
2285
+ scores,
2286
+ pageId
2287
+ });
2288
+ },
2289
+ forget: () => {
2290
+ storage.clear();
2291
+ storageData = void 0;
2292
+ },
2293
+ get sessionId() {
2294
+ return storageData == null ? void 0 : storageData.sessionId;
2295
+ }
2296
+ };
2297
+ };
2298
+ var enableUniformInsights = (options) => {
2299
+ const insights = createInsights({
2300
+ endpoint: options.endpoint
2301
+ });
2302
+ let previousUrl = void 0;
2303
+ return {
2304
+ init: (context) => {
2305
+ if (typeof window === "undefined") {
2306
+ return () => {
2307
+ };
2308
+ }
2309
+ const consentChanged = () => {
2310
+ if (context.storage.data.consent) {
2311
+ insights.init();
2312
+ } else {
2313
+ insights.forget();
2314
+ }
2315
+ };
2316
+ const handlePersonalizationResult = (data) => {
2317
+ insights.personalizationResult(data);
2318
+ };
2319
+ const handleTestResult = (result) => {
2320
+ insights.testResult(result);
2321
+ };
2322
+ const handleGoalConvert = (result) => {
2323
+ insights.goalConvert(result.goalId);
2324
+ };
2325
+ const handleScoreChange = (scores) => {
2326
+ insights.scoresChange(scores);
2327
+ };
2328
+ context.storage.events.on("goalConverted", handleGoalConvert);
2329
+ context.storage.events.on("consentUpdated", consentChanged);
2330
+ context.events.on("personalizationResult", handlePersonalizationResult);
2331
+ context.events.on("testResult", handleTestResult);
2332
+ context.events.on("scoresUpdated", handleScoreChange);
2333
+ if (context.storage.data.consent) {
2334
+ consentChanged();
2335
+ }
2336
+ return () => {
2337
+ context.storage.events.off("consentUpdated", consentChanged);
2338
+ context.storage.events.off("goalConverted", handleGoalConvert);
2339
+ context.events.off("personalizationResult", handlePersonalizationResult);
2340
+ context.events.off("testResult", handleTestResult);
2341
+ context.events.off("scoresUpdated", handleScoreChange);
2342
+ };
2343
+ },
2344
+ update: (context) => {
2345
+ if (context.url && context.url !== previousUrl) {
2346
+ previousUrl = context.url;
2347
+ insights.pageHit();
2348
+ }
2349
+ },
2350
+ forget: () => {
2351
+ insights.forget();
2352
+ }
2353
+ };
2354
+ };
2355
+ var generalRandomId = () => {
2356
+ const id = v4();
2357
+ return id.replaceAll("-", "").toLowerCase();
2358
+ };
2359
+
1912
2360
  // src/logging/enableConsoleLogDrain.ts
1913
2361
  import rfdc2 from "rfdc";
1914
2362
 
@@ -2096,22 +2544,30 @@ export {
2096
2544
  EdgeNodeTagName,
2097
2545
  EdgeTransitionDataStore,
2098
2546
  GroupCriteriaEvaluator,
2547
+ KV_SEP,
2099
2548
  ManifestInstance,
2549
+ PAIR_SEP,
2100
2550
  SERVER_STATE_ID,
2101
2551
  ScriptType,
2552
+ TYPE_SEP,
2102
2553
  TransitionDataStore,
2103
2554
  UNIFORM_DEFAULT_COOKIE_NAME,
2104
2555
  VisitorDataStore,
2556
+ areCommandsEqual,
2105
2557
  computeAggregateDimensions,
2106
2558
  cookieEvaluator,
2107
2559
  createConsoleLogDrain,
2108
2560
  createDebugConsoleLogDrain,
2109
2561
  createLinearDecay,
2110
2562
  currentPageEvaluator,
2563
+ decodeCookieType,
2564
+ decodePersonalizeVariants,
2111
2565
  emptyVisitorData,
2112
2566
  enableConsoleLogDrain,
2113
2567
  enableContextDevTools,
2114
2568
  enableDebugConsoleLogDrain,
2569
+ enableUniformInsights,
2570
+ encodeCookieType,
2115
2571
  evaluateVariantMatch,
2116
2572
  eventEvaluator,
2117
2573
  explainStringMatch,
@@ -2120,10 +2576,16 @@ export {
2120
2576
  isStringMatch,
2121
2577
  pageViewCountDimension,
2122
2578
  pageViewCountEvaluator,
2579
+ parseCookieScores,
2580
+ parseCookieType,
2123
2581
  parseQuickConnect,
2582
+ parseScoreCookie,
2124
2583
  personalizeVariations,
2125
2584
  queryStringEvaluator,
2126
2585
  quirkEvaluator,
2586
+ serializeCookie,
2587
+ serializeCookieType,
2588
+ serializePersonalizeVariants,
2127
2589
  serializeQuickConnect,
2128
2590
  testVariations
2129
2591
  };