algolia-experiences 1.6.5 → 1.6.7

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.
@@ -5810,7 +5810,7 @@
5810
5810
 
5811
5811
  var sortAndMergeRecommendations_1 = sortAndMergeRecommendations;
5812
5812
 
5813
- var version = '3.26.1';
5813
+ var version = '3.27.0';
5814
5814
 
5815
5815
  var escapeFacetValue$3 = escapeFacetValue_1.escapeFacetValue;
5816
5816
 
@@ -12966,7 +12966,7 @@
12966
12966
  };
12967
12967
  }
12968
12968
 
12969
- var version$1 = '4.85.1';
12969
+ var version$1 = '4.86.0';
12970
12970
 
12971
12971
  function _typeof$j(o) {
12972
12972
  "@babel/helpers - typeof";
@@ -20510,10 +20510,33 @@
20510
20510
 
20511
20511
  /**
20512
20512
  * The **SortBy** connector provides the logic to build a custom widget that will display a
20513
- * list of indices. With Algolia, this is most commonly used for changing ranking strategy. This allows
20514
- * a user to change how the hits are being sorted.
20513
+ * list of indices or sorting strategies. With Algolia, this is most commonly used for changing
20514
+ * ranking strategy. This allows a user to change how the hits are being sorted.
20515
+ *
20516
+ * This connector supports two sorting modes:
20517
+ * 1. **Index-based (traditional)**: Uses the `value` property to switch between different indices.
20518
+ * This is the standard behavior for non-composition setups.
20519
+ *
20520
+ * 2. **Strategy-based (composition mode)**: Uses the `strategy` property to apply sorting strategies
20521
+ * via the `sortBy` search parameter. This is only available when using Algolia Compositions.
20522
+ *
20523
+ * Items can mix both types in the same widget, allowing for flexible sorting options.
20515
20524
  */
20516
20525
 
20526
+ function isStrategyItem(item) {
20527
+ return 'strategy' in item && item.strategy !== undefined;
20528
+ }
20529
+ function getItemValue(item) {
20530
+ if (isStrategyItem(item)) {
20531
+ return item.strategy;
20532
+ }
20533
+ return item.value;
20534
+ }
20535
+ function isValidStrategy(itemsLookup, value) {
20536
+ if (!value) return false;
20537
+ var item = itemsLookup[value];
20538
+ return item !== undefined && isStrategyItem(item);
20539
+ }
20517
20540
  var connectSortBy = function connectSortBy(renderFn) {
20518
20541
  var unmountFn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
20519
20542
  checkRendering(renderFn, withUsage$g());
@@ -20528,14 +20551,38 @@
20528
20551
  if (!Array.isArray(items)) {
20529
20552
  throw new Error(withUsage$g('The `items` option expects an array of objects.'));
20530
20553
  }
20554
+ var itemsLookup = {};
20555
+ items.forEach(function (item, index) {
20556
+ var hasValue = 'value' in item && item.value !== undefined;
20557
+ var hasStrategy = 'strategy' in item && item.strategy !== undefined;
20558
+
20559
+ // Validate mutual exclusivity
20560
+ if (hasValue && hasStrategy) {
20561
+ throw new Error(withUsage$g("Item at index ".concat(index, " cannot have both \"value\" and \"strategy\" properties.")));
20562
+ }
20563
+ if (!hasValue && !hasStrategy) {
20564
+ throw new Error(withUsage$g("Item at index ".concat(index, " must have either a \"value\" or \"strategy\" property.")));
20565
+ }
20566
+ var itemValue = getItemValue(item);
20567
+ itemsLookup[itemValue] = item;
20568
+ });
20569
+ connectorState.itemsLookup = itemsLookup;
20531
20570
  return {
20532
20571
  $$type: 'ais.sortBy',
20533
20572
  init: function init(initOptions) {
20534
20573
  var instantSearchInstance = initOptions.instantSearchInstance;
20574
+
20575
+ // Check if strategies are used outside composition mode
20576
+ var hasStrategyItems = items.some(function (item) {
20577
+ return 'strategy' in item && item.strategy;
20578
+ });
20579
+ if (hasStrategyItems && !instantSearchInstance.compositionID) {
20580
+ throw new Error(withUsage$g('Sorting strategies can only be used in composition mode. Please provide a "compositionID" to your InstantSearch instance.'));
20581
+ }
20535
20582
  var widgetRenderState = this.getWidgetRenderState(initOptions);
20536
20583
  var currentIndex = widgetRenderState.currentRefinement;
20537
20584
  var isCurrentIndexInItems = find$1(items, function (item) {
20538
- return item.value === currentIndex;
20585
+ return getItemValue(item) === currentIndex;
20539
20586
  });
20540
20587
  renderFn(_objectSpread$E(_objectSpread$E({}, widgetRenderState), {}, {
20541
20588
  instantSearchInstance: instantSearchInstance
@@ -20550,7 +20597,17 @@
20550
20597
  dispose: function dispose(_ref2) {
20551
20598
  var state = _ref2.state;
20552
20599
  unmountFn();
20553
- return connectorState.initialIndex ? state.setIndex(connectorState.initialIndex) : state;
20600
+
20601
+ // Clear sortBy parameter if it was set
20602
+ if (connectorState.isUsingComposition && state.sortBy) {
20603
+ state = state.setQueryParameter('sortBy', undefined);
20604
+ }
20605
+
20606
+ // Restore initial index if changed
20607
+ if (connectorState.initialValue && state.index !== connectorState.initialValue) {
20608
+ return state.setIndex(connectorState.initialValue);
20609
+ }
20610
+ return state;
20554
20611
  },
20555
20612
  getRenderState: function getRenderState(renderState, renderOptions) {
20556
20613
  return _objectSpread$E(_objectSpread$E({}, renderState), {}, {
@@ -20561,22 +20618,54 @@
20561
20618
  var results = _ref3.results,
20562
20619
  helper = _ref3.helper,
20563
20620
  state = _ref3.state,
20564
- parent = _ref3.parent;
20565
- if (!connectorState.initialIndex && parent) {
20566
- connectorState.initialIndex = parent.getIndexName();
20621
+ parent = _ref3.parent,
20622
+ instantSearchInstance = _ref3.instantSearchInstance;
20623
+ // Capture initial value (composition ID or main index)
20624
+ if (!connectorState.initialValue && parent) {
20625
+ connectorState.initialValue = parent.getIndexName();
20567
20626
  }
20568
- if (!connectorState.setIndex) {
20569
- connectorState.setIndex = function (indexName) {
20570
- helper.setIndex(indexName).search();
20627
+
20628
+ // Create refine function if not exists
20629
+ if (!connectorState.refine) {
20630
+ // Cache composition mode status for lifecycle methods that don't have access to instantSearchInstance
20631
+ connectorState.isUsingComposition = Boolean(instantSearchInstance === null || instantSearchInstance === void 0 ? void 0 : instantSearchInstance.compositionID);
20632
+ connectorState.refine = function (value) {
20633
+ // O(1) lookup using the items lookup table
20634
+ var item = connectorState.itemsLookup[value];
20635
+ if (item && isStrategyItem(item)) {
20636
+ // Strategy-based: set sortBy parameter for composition API
20637
+ // The composition backend will interpret this and apply the sorting strategy
20638
+ helper.setQueryParameter('sortBy', item.strategy).search();
20639
+ } else {
20640
+ // Index-based: clear any existing sortBy parameter and switch to the new index
20641
+ // Clearing sortBy is critical when transitioning from strategy to index-based sorting
20642
+ helper.setQueryParameter('sortBy', undefined).setIndex(value).search();
20643
+ }
20571
20644
  };
20572
20645
  }
20646
+
20647
+ // Transform items first (on original structure)
20648
+ var transformedItems = transformItems(items, {
20649
+ results: results
20650
+ });
20651
+
20652
+ // Normalize items: all get a 'value' property for the render state
20653
+ var normalizedItems = transformedItems.map(function (item) {
20654
+ return {
20655
+ label: item.label,
20656
+ value: getItemValue(item)
20657
+ };
20658
+ });
20659
+
20660
+ // Determine current refinement
20661
+ // In composition mode, prefer sortBy parameter if it corresponds to a valid strategy item
20662
+ // Otherwise use the index (for index-based items or when no valid strategy is active)
20663
+ var currentRefinement = connectorState.isUsingComposition && isValidStrategy(connectorState.itemsLookup, state.sortBy) ? state.sortBy : state.index;
20573
20664
  var hasNoResults = results ? results.nbHits === 0 : true;
20574
20665
  return {
20575
- currentRefinement: state.index,
20576
- options: transformItems(items, {
20577
- results: results
20578
- }),
20579
- refine: connectorState.setIndex,
20666
+ currentRefinement: currentRefinement,
20667
+ options: normalizedItems,
20668
+ refine: connectorState.refine,
20580
20669
  hasNoResults: hasNoResults,
20581
20670
  canRefine: !hasNoResults && items.length > 0,
20582
20671
  widgetParams: widgetParams
@@ -20584,14 +20673,25 @@
20584
20673
  },
20585
20674
  getWidgetUiState: function getWidgetUiState(uiState, _ref4) {
20586
20675
  var searchParameters = _ref4.searchParameters;
20587
- var currentIndex = searchParameters.index;
20676
+ // In composition mode with an active strategy, use sortBy parameter
20677
+ // Otherwise use index-based behavior (traditional mode)
20678
+ var currentValue = connectorState.isUsingComposition && isValidStrategy(connectorState.itemsLookup, searchParameters.sortBy) ? searchParameters.sortBy : searchParameters.index;
20588
20679
  return _objectSpread$E(_objectSpread$E({}, uiState), {}, {
20589
- sortBy: currentIndex !== connectorState.initialIndex ? currentIndex : undefined
20680
+ sortBy: currentValue !== connectorState.initialValue ? currentValue : undefined
20590
20681
  });
20591
20682
  },
20592
20683
  getWidgetSearchParameters: function getWidgetSearchParameters(searchParameters, _ref5) {
20593
20684
  var uiState = _ref5.uiState;
20594
- return searchParameters.setQueryParameter('index', uiState.sortBy || connectorState.initialIndex || searchParameters.index);
20685
+ var sortByValue = uiState.sortBy || connectorState.initialValue || searchParameters.index;
20686
+ if (isValidStrategy(connectorState.itemsLookup, sortByValue)) {
20687
+ var item = connectorState.itemsLookup[sortByValue];
20688
+ // Strategy-based: set the sortBy parameter for composition API
20689
+ // The index remains as the compositionID
20690
+ return searchParameters.setQueryParameter('sortBy', item.strategy);
20691
+ }
20692
+
20693
+ // Index-based: set the index parameter (traditional behavior)
20694
+ return searchParameters.setQueryParameter('index', sortByValue);
20595
20695
  }
20596
20696
  };
20597
20697
  };