@uniformdev/context 20.6.2-alpha.11 → 20.7.1-alpha.102

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
@@ -51,6 +51,7 @@ __export(src_exports, {
51
51
  KV_SEP: () => KV_SEP,
52
52
  ManifestInstance: () => ManifestInstance,
53
53
  PAIR_SEP: () => PAIR_SEP,
54
+ QUIRK_KV_SEP: () => QUIRK_KV_SEP,
54
55
  QUIRK_SEP: () => QUIRK_SEP,
55
56
  SERVER_STATE_ID: () => SERVER_STATE_ID,
56
57
  STRONGEST_SCORE_PERSONALIZATION_ALGORITHM: () => STRONGEST_SCORE_PERSONALIZATION_ALGORITHM,
@@ -320,6 +321,10 @@ var ManifestInstance = class {
320
321
  }
321
322
  return (_d = (_c = __privateGet(this, _mf).pz) == null ? void 0 : _c.enr) == null ? void 0 : _d[scoreKey.substring(0, enrichmentIndex)];
322
323
  }
324
+ getAggregateDimensionByKey(scoreKey) {
325
+ var _a, _b;
326
+ return (_b = (_a = __privateGet(this, _mf).pz) == null ? void 0 : _a.agg) == null ? void 0 : _b[scoreKey];
327
+ }
323
328
  };
324
329
  _mf = new WeakMap();
325
330
  _signalInstances = new WeakMap();
@@ -889,6 +894,7 @@ function strongestScorePersonalizationSelectionAlgorithm({
889
894
  const needsConsentToPersonalize = context.requireConsentForPersonalization;
890
895
  const isInGlobalControlGroup = (_a = context.storage.data.controlGroup) != null ? _a : false;
891
896
  const personalizationAllowed = !needsConsentToPersonalize || context.storage.data.consent;
897
+ let originalIndex = 0;
892
898
  for (const variation of variations) {
893
899
  const isInvalidFormat = variation.pz && typeof variation.pz !== "object";
894
900
  let validVariation;
@@ -906,12 +912,19 @@ function strongestScorePersonalizationSelectionAlgorithm({
906
912
  if (score === void 0 || score <= 0) {
907
913
  continue;
908
914
  }
909
- variationMatches.push({ variation: validVariation, score });
915
+ variationMatches.push({ variation: validVariation, score, originalIndex });
916
+ originalIndex++;
910
917
  } else {
911
918
  defaultVariations.push(validVariation);
912
919
  }
913
920
  }
914
- variationMatches.sort((a, b) => b.score - a.score);
921
+ variationMatches.sort((a, b) => {
922
+ const scoreComparison = b.score - a.score;
923
+ if (scoreComparison === 0) {
924
+ return a.originalIndex - b.originalIndex;
925
+ }
926
+ return scoreComparison;
927
+ });
915
928
  const result = [];
916
929
  for (let i = 0; i < variationMatches.length; i++) {
917
930
  const variationMatch = variationMatches[i];
@@ -1010,11 +1023,11 @@ var testVariations = ({
1010
1023
  }
1011
1024
  if (!selectedVariant) {
1012
1025
  const distributions = normalizeVariationDistributions(variations);
1013
- const random = Math.floor(Math.random() * 100);
1026
+ const random = Math.random() * 100;
1014
1027
  let distributionOffset = 0;
1015
1028
  selectedVariant = variations.find((variant, index) => {
1016
1029
  const distribution = distributions[index];
1017
- if ((random > distributionOffset || random === 0) && random <= distributionOffset + distribution) {
1030
+ if (random >= distributionOffset && random < distributionOffset + distribution) {
1018
1031
  return variant;
1019
1032
  }
1020
1033
  distributionOffset += distribution;
@@ -1026,6 +1039,9 @@ var testVariations = ({
1026
1039
  }
1027
1040
  if (selectedVariant) {
1028
1041
  onLogMessage == null ? void 0 : onLogMessage(["info", 404, selectedVariant.id]);
1042
+ if (selectedVariant.control === void 0) {
1043
+ selectedVariant.control = variations.findIndex((variation) => variation.id === selectedVariantId) === 0;
1044
+ }
1029
1045
  }
1030
1046
  return {
1031
1047
  result: selectedVariant,
@@ -1207,6 +1223,7 @@ _quirksEnabled = new WeakMap();
1207
1223
  var TYPE_SEP = "~";
1208
1224
  var PAIR_SEP = "!";
1209
1225
  var KV_SEP = "-";
1226
+ var QUIRK_KV_SEP = "=";
1210
1227
  var QUIRK_SEP = "!!";
1211
1228
  function parseScoreCookie(cookieValue, quirkCookieValue) {
1212
1229
  if (!cookieValue) return;
@@ -1230,7 +1247,7 @@ function parseScoreCookie(cookieValue, quirkCookieValue) {
1230
1247
  function parseQuirkCookie(quirkCookieValue) {
1231
1248
  const pairs = quirkCookieValue.split(QUIRK_SEP);
1232
1249
  const splitPairs = pairs.map((pair) => {
1233
- const sep = pair.indexOf(KV_SEP);
1250
+ const sep = pair.indexOf(QUIRK_KV_SEP);
1234
1251
  if (sep === -1) {
1235
1252
  return void 0;
1236
1253
  }
@@ -1331,7 +1348,7 @@ function serializeCookieType(type) {
1331
1348
  return Object.entries(type).map((kv) => kv.join(KV_SEP)).join(PAIR_SEP);
1332
1349
  }
1333
1350
  function serializeQuirks(quirks) {
1334
- return Object.entries(quirks).map((kv) => kv.join(KV_SEP)).join(QUIRK_SEP);
1351
+ return Object.entries(quirks).map((kv) => kv.join(QUIRK_KV_SEP)).join(QUIRK_SEP);
1335
1352
  }
1336
1353
 
1337
1354
  // src/storage/EdgeTransitionDataStore.ts
@@ -1822,6 +1839,9 @@ var Context = class {
1822
1839
  __privateSet(this, _scores, state.ssv);
1823
1840
  __privateGet(this, _mitt3).emit("log", ["debug", 130, state]);
1824
1841
  }
1842
+ if (state.compositionMetadata) {
1843
+ __privateGet(this, _state).compositionMetadata = state.compositionMetadata;
1844
+ }
1825
1845
  },
1826
1846
  onLogMessage: (message) => __privateGet(this, _mitt3).emit("log", message)
1827
1847
  });
@@ -1974,10 +1994,16 @@ var Context = class {
1974
1994
  scores: __privateGet(this, _serverTransitionState) ? __privateMethod(this, _Context_instances, calculateScores_fn).call(this, this.storage.data) : __privateGet(this, _scores)
1975
1995
  })
1976
1996
  );
1997
+ const previousCompositionMetadata = __privateGet(this, _state).compositionMetadata;
1977
1998
  __privateSet(this, _state, {
1978
1999
  ...__privateGet(this, _state),
1979
2000
  ...newData
1980
2001
  });
2002
+ if (newData.compositionMetadata && // deep equal is not too bad, as we only have 1 level of depth in dynamic inputs
2003
+ !(0, import_lite5.dequal)(previousCompositionMetadata, __privateGet(this, _state).compositionMetadata)) {
2004
+ __privateGet(this, _mitt3).emit("canvasDataUpdated", __privateGet(this, _state).compositionMetadata);
2005
+ __privateGet(this, _state).compositionMetadata = newData.compositionMetadata;
2006
+ }
1981
2007
  await this.storage.updateData(commands);
1982
2008
  if (__privateGet(this, _serverTransitionState)) {
1983
2009
  await this.processServerCommands({
@@ -1989,7 +2015,9 @@ var Context = class {
1989
2015
  __privateMethod(this, _Context_instances, emitTest_fn).call(this, {
1990
2016
  name: testName,
1991
2017
  variantId: testVariantId,
1992
- variantAssigned: true
2018
+ variantAssigned: true,
2019
+ control: false,
2020
+ compositionMetadata: void 0
1993
2021
  });
1994
2022
  });
1995
2023
  const haveQuirksChanged = __privateGet(this, _serverTransitionState) && !(0, import_lite5.dequal)(__privateGet(this, _serverTransitionState).quirks, this.storage.data.quirks);
@@ -2005,7 +2033,7 @@ var Context = class {
2005
2033
  if (!plugin.update) {
2006
2034
  continue;
2007
2035
  }
2008
- await plugin.update(newData);
2036
+ await plugin.update(newData, __privateGet(this, _scores));
2009
2037
  }
2010
2038
  }
2011
2039
  (_e = __privateGet(this, _commands)) == null ? void 0 : _e.push(...commands);
@@ -2071,7 +2099,7 @@ var Context = class {
2071
2099
  }
2072
2100
  /** Executes an A/B test with a given set of variants, showing the visitor's assigned variant (or selecting one to assign, if none is set yet) */
2073
2101
  test(options) {
2074
- var _a, _b, _c;
2102
+ var _a, _b, _c, _d, _e;
2075
2103
  if (options.name === CONTEXTUAL_EDITING_TEST_NAME) {
2076
2104
  const selectedVariant = (_a = options.variations.find((variant) => variant.id === CONTEXTUAL_EDITING_TEST_SELECTED_VARIANT_ID)) != null ? _a : options.variations.at(-1);
2077
2105
  const value2 = {
@@ -2088,7 +2116,9 @@ var Context = class {
2088
2116
  __privateMethod(this, _Context_instances, emitTest_fn).call(this, {
2089
2117
  name: options.name,
2090
2118
  variantId: (_c = (_b = value.result) == null ? void 0 : _b.id) != null ? _c : void 0,
2091
- variantAssigned: value.variantAssigned
2119
+ variantAssigned: value.variantAssigned,
2120
+ control: (_e = (_d = value.result) == null ? void 0 : _d.control) != null ? _e : false,
2121
+ compositionMetadata: options.compositionMetadata
2092
2122
  });
2093
2123
  return value;
2094
2124
  }
@@ -2117,7 +2147,8 @@ var Context = class {
2117
2147
  control: variation.control
2118
2148
  })),
2119
2149
  control: this.storage.data.controlGroup,
2120
- changed: true
2150
+ changed: true,
2151
+ compositionMetadata: options.compositionMetadata
2121
2152
  };
2122
2153
  if (previousPlacement && (0, import_lite5.dequal)(eventData.variantIds, previousPlacement)) {
2123
2154
  eventData.changed = false;
@@ -2131,7 +2162,10 @@ var Context = class {
2131
2162
  * @param fromAllDevices for an identified user, whether to delete all their data (for the entire account) - true, or data for this device (sign out) - false
2132
2163
  */
2133
2164
  async forget(fromAllDevices) {
2134
- __privateSet(this, _state, {});
2165
+ const previousCompositionMetadata = __privateGet(this, _state).compositionMetadata;
2166
+ __privateSet(this, _state, {
2167
+ compositionMetadata: previousCompositionMetadata
2168
+ });
2135
2169
  if (__privateGet(this, _plugins)) {
2136
2170
  for (let i = 0; i < __privateGet(this, _plugins).length; i++) {
2137
2171
  const plugin = __privateGet(this, _plugins)[i];
@@ -2154,7 +2188,8 @@ var Context = class {
2154
2188
  ssv: __privateGet(this, _scores),
2155
2189
  tests: {},
2156
2190
  personalizeVariants: this.storage.data.personalizeVariants,
2157
- commands: __privateGet(this, _commands)
2191
+ commands: __privateGet(this, _commands),
2192
+ compositionMetadata: __privateGet(this, _state).compositionMetadata
2158
2193
  };
2159
2194
  const allTests = this.storage.data.tests;
2160
2195
  Object.entries(allTests).map(([testName, testValue]) => {
@@ -2177,6 +2212,27 @@ var Context = class {
2177
2212
  __privateGet(this, _pzCache)[event.name] = event.variantIds;
2178
2213
  __privateGet(this, _mitt3).emit("personalizationResult", event);
2179
2214
  }
2215
+ /**
2216
+ * Gets the current canvas data
2217
+ */
2218
+ getCompositionMetadata() {
2219
+ return __privateGet(this, _state).compositionMetadata;
2220
+ }
2221
+ /**
2222
+ * Updates the canvas data and emits a canvasDataUpdated event
2223
+ */
2224
+ async updateCompositionMetadata(newData) {
2225
+ const currentCanvas = __privateGet(this, _state).compositionMetadata || {};
2226
+ const updatedCanvas = { ...currentCanvas, ...newData };
2227
+ if (!(0, import_lite5.dequal)(currentCanvas, updatedCanvas)) {
2228
+ __privateSet(this, _state, {
2229
+ ...__privateGet(this, _state),
2230
+ compositionMetadata: updatedCanvas
2231
+ });
2232
+ __privateGet(this, _mitt3).emit("canvasDataUpdated", updatedCanvas);
2233
+ __privateGet(this, _mitt3).emit("log", ["info", 4, "Canvas data updated"]);
2234
+ }
2235
+ }
2180
2236
  };
2181
2237
  _personalizationSelectionAlgorithms = new WeakMap();
2182
2238
  _serverTransitionState = new WeakMap();
@@ -2341,8 +2397,31 @@ var ScriptType = /* @__PURE__ */ ((ScriptType2) => {
2341
2397
  })(ScriptType || {});
2342
2398
  var EdgeNodeTagName = "nesitag";
2343
2399
 
2344
- // src/insights/index.ts
2345
- var import_uuid = require("uuid");
2400
+ // src/insights/storage.ts
2401
+ var createInsightsStorage = () => {
2402
+ const STORAGE_KEY2 = "ufin";
2403
+ return {
2404
+ get: () => {
2405
+ const data = localStorage.getItem(STORAGE_KEY2);
2406
+ if (!data) {
2407
+ return;
2408
+ }
2409
+ return JSON.parse(data);
2410
+ },
2411
+ set: (data) => {
2412
+ const toSet = {
2413
+ ...data,
2414
+ updated: Date.now()
2415
+ };
2416
+ localStorage.setItem(STORAGE_KEY2, JSON.stringify(toSet));
2417
+ },
2418
+ clear: () => {
2419
+ localStorage.removeItem(STORAGE_KEY2);
2420
+ }
2421
+ };
2422
+ };
2423
+
2424
+ // src/insights/types.ts
2346
2425
  var getBasePayload = () => {
2347
2426
  const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
2348
2427
  const locale = navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.userLanguage || navigator.language || navigator.browserLanguage || "en";
@@ -2355,13 +2434,34 @@ var getBasePayload = () => {
2355
2434
  href: window.location.href
2356
2435
  };
2357
2436
  };
2437
+ var generateVisitorId = () => {
2438
+ return `visitor_${generalRandomId()}`;
2439
+ };
2440
+ var generateSessionId = () => {
2441
+ return `session_${generalRandomId()}`;
2442
+ };
2443
+ var generatePageId = () => {
2444
+ return `page_${generalRandomId()}`;
2445
+ };
2446
+ var generalRandomId = () => {
2447
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
2448
+ const id = crypto.randomUUID();
2449
+ return id.replaceAll("-", "").toLowerCase();
2450
+ }
2451
+ return Math.random().toString(32).substring(2);
2452
+ };
2453
+
2454
+ // src/insights/v1.ts
2358
2455
  var createInsightsClient = ({ endpoint }) => {
2359
2456
  let endpointUrl;
2360
2457
  const apiKey = endpoint.apiKey;
2361
2458
  const projectId = endpoint.projectId;
2362
2459
  if (endpoint.type === "api") {
2363
2460
  const url = new URL(endpoint.host);
2364
- url.pathname = "/v0/events";
2461
+ url.pathname = `/v0/events`;
2462
+ if (endpoint.host.includes("tinybird.co")) {
2463
+ url.pathname = "/v0/events";
2464
+ }
2365
2465
  url.searchParams.set("name", "analytics_events");
2366
2466
  endpointUrl = url.toString();
2367
2467
  } else {
@@ -2491,38 +2591,7 @@ var createInsightsClient = ({ endpoint }) => {
2491
2591
  }
2492
2592
  };
2493
2593
  };
2494
- var createInsightsStorage = () => {
2495
- const STORAGE_KEY2 = "ufin";
2496
- return {
2497
- get: () => {
2498
- const data = localStorage.getItem(STORAGE_KEY2);
2499
- if (!data) {
2500
- return;
2501
- }
2502
- return JSON.parse(data);
2503
- },
2504
- set: (data) => {
2505
- const toSet = {
2506
- ...data,
2507
- updated: Date.now()
2508
- };
2509
- localStorage.setItem(STORAGE_KEY2, JSON.stringify(toSet));
2510
- },
2511
- clear: () => {
2512
- localStorage.removeItem(STORAGE_KEY2);
2513
- }
2514
- };
2515
- };
2516
- var generateVisitorId = () => {
2517
- return `visitor_${generalRandomId()}`;
2518
- };
2519
- var generateSessionId = () => {
2520
- return `session_${generalRandomId()}`;
2521
- };
2522
- var generatePageId = () => {
2523
- return `page_${generalRandomId()}`;
2524
- };
2525
- var createInsights = ({
2594
+ var createInsightsV1 = ({
2526
2595
  endpoint,
2527
2596
  sessionDurationSeconds = 30 * 60
2528
2597
  }) => {
@@ -2623,8 +2692,10 @@ var createInsights = ({
2623
2692
  }
2624
2693
  };
2625
2694
  };
2695
+
2696
+ // src/insights/index.ts
2626
2697
  var enableUniformInsights = (options) => {
2627
- const insights = createInsights({
2698
+ const insights = createInsightsV1({
2628
2699
  endpoint: options.endpoint
2629
2700
  });
2630
2701
  let previousUrl = void 0;
@@ -2670,8 +2741,8 @@ var enableUniformInsights = (options) => {
2670
2741
  };
2671
2742
  },
2672
2743
  update: (context) => {
2673
- if (context.url && context.url !== previousUrl) {
2674
- previousUrl = context.url;
2744
+ if (context.url && context.url.toString() !== previousUrl) {
2745
+ previousUrl = context.url.toString();
2675
2746
  insights.pageHit();
2676
2747
  }
2677
2748
  },
@@ -2680,10 +2751,6 @@ var enableUniformInsights = (options) => {
2680
2751
  }
2681
2752
  };
2682
2753
  };
2683
- var generalRandomId = () => {
2684
- const id = (0, import_uuid.v4)();
2685
- return id.replaceAll("-", "").toLowerCase();
2686
- };
2687
2754
 
2688
2755
  // src/logging/enableConsoleLogDrain.ts
2689
2756
  var import_rfdc2 = __toESM(require("rfdc"));
@@ -2881,6 +2948,7 @@ function parseQuickConnect(serialized) {
2881
2948
  KV_SEP,
2882
2949
  ManifestInstance,
2883
2950
  PAIR_SEP,
2951
+ QUIRK_KV_SEP,
2884
2952
  QUIRK_SEP,
2885
2953
  SERVER_STATE_ID,
2886
2954
  STRONGEST_SCORE_PERSONALIZATION_ALGORITHM,