instantsearch.js 4.44.0 → 4.45.1

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/cjs/connectors/hits-per-page/connectHitsPerPage.js +3 -1
  3. package/cjs/connectors/numeric-menu/connectNumericMenu.js +31 -43
  4. package/cjs/connectors/range/connectRange.js +7 -46
  5. package/cjs/connectors/rating-menu/connectRatingMenu.js +10 -4
  6. package/cjs/connectors/sort-by/connectSortBy.js +3 -1
  7. package/cjs/lib/version.js +1 -1
  8. package/cjs/widgets/clear-refinements/clear-refinements.js +2 -2
  9. package/dist/instantsearch.development.d.ts +29 -10
  10. package/dist/instantsearch.development.js +113 -124
  11. package/dist/instantsearch.development.js.map +1 -1
  12. package/dist/instantsearch.production.d.ts +29 -10
  13. package/dist/instantsearch.production.min.d.ts +29 -10
  14. package/dist/instantsearch.production.min.js +2 -2
  15. package/dist/instantsearch.production.min.js.map +1 -1
  16. package/es/components/Answers/Answers.d.ts +2 -2
  17. package/es/components/Hits/Hits.d.ts +2 -2
  18. package/es/components/InfiniteHits/InfiniteHits.d.ts +2 -2
  19. package/es/connectors/answers/connectAnswers.d.ts +2 -2
  20. package/es/connectors/autocomplete/connectAutocomplete.d.ts +2 -2
  21. package/es/connectors/hits-per-page/connectHitsPerPage.d.ts +5 -0
  22. package/es/connectors/hits-per-page/connectHitsPerPage.js +3 -1
  23. package/es/connectors/numeric-menu/connectNumericMenu.d.ts +8 -0
  24. package/es/connectors/numeric-menu/connectNumericMenu.js +32 -44
  25. package/es/connectors/range/connectRange.js +8 -47
  26. package/es/connectors/rating-menu/connectRatingMenu.d.ts +2 -0
  27. package/es/connectors/rating-menu/connectRatingMenu.js +10 -4
  28. package/es/connectors/sort-by/connectSortBy.d.ts +5 -0
  29. package/es/connectors/sort-by/connectSortBy.js +3 -1
  30. package/es/lib/insights/client.d.ts +2 -2
  31. package/es/lib/utils/createSendEventForHits.d.ts +3 -3
  32. package/es/lib/version.d.ts +1 -1
  33. package/es/lib/version.js +1 -1
  34. package/es/types/connector.d.ts +2 -2
  35. package/es/widgets/clear-refinements/clear-refinements.js +2 -2
  36. package/package.json +4 -3
package/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ ## [4.45.1](https://github.com/algolia/instantsearch.js/compare/v4.45.0...v4.45.1) (2022-09-06)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **ratingMenu:** fix `undefined` facet values error when `disjunctiveFacets` is empty ([#5096](https://github.com/algolia/instantsearch.js/issues/5096)) ([dd870d5](https://github.com/algolia/instantsearch.js/commit/dd870d5a658ce42b068eadf34f9b69772291aa20))
7
+
8
+
9
+
10
+ # [4.45.0](https://github.com/algolia/instantsearch.js/compare/v4.44.1...v4.45.0) (2022-08-29)
11
+
12
+
13
+ ### Features
14
+
15
+ * **connectors:** deprecate `hasNoResults` in favor of `canRefine` ([#5091](https://github.com/algolia/instantsearch.js/issues/5091)) ([1749a4e](https://github.com/algolia/instantsearch.js/commit/1749a4eb9a2f28fa4a8d442163e3b10acbde7c22))
16
+
17
+
18
+
19
+ ## [4.44.1](https://github.com/algolia/instantsearch.js/compare/v4.44.0...v4.44.1) (2022-08-25)
20
+
21
+
22
+ ### Bug Fixes
23
+
24
+ * **connectNumericMenu + connectRange:** stop sending invalid clickedFilters event ([#5085](https://github.com/algolia/instantsearch.js/issues/5085)) ([20996c7](https://github.com/algolia/instantsearch.js/commit/20996c7a159988c58e00ff24d2d2dc98af8b980f))
25
+
26
+
27
+
1
28
  # [4.44.0](https://github.com/algolia/instantsearch.js/compare/v4.43.1...v4.44.0) (2022-08-08)
2
29
 
3
30
 
@@ -127,6 +127,7 @@ var connectHitsPerPage = function connectHitsPerPage(renderFn) {
127
127
  results = _ref5.results,
128
128
  createURL = _ref5.createURL,
129
129
  helper = _ref5.helper;
130
+ var canRefine = results ? results.nbHits > 0 : false;
130
131
  return {
131
132
  items: transformItems(normalizeItems(state), {
132
133
  results: results
@@ -136,7 +137,8 @@ var connectHitsPerPage = function connectHitsPerPage(renderFn) {
136
137
  state: state,
137
138
  createURL: createURL
138
139
  }),
139
- hasNoResults: results ? results.nbHits === 0 : true,
140
+ hasNoResults: !canRefine,
141
+ canRefine: canRefine,
140
142
  widgetParams: widgetParams
141
143
  };
142
144
  },
@@ -7,6 +7,8 @@ exports.default = void 0;
7
7
 
8
8
  var _index = require("../../lib/utils/index.js");
9
9
 
10
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
11
+
10
12
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
11
13
 
12
14
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -32,46 +34,11 @@ var withUsage = (0, _index.createDocumentationMessageGenerator)({
32
34
  var $$type = 'ais.numericMenu';
33
35
 
34
36
  var createSendEvent = function createSendEvent(_ref) {
35
- var instantSearchInstance = _ref.instantSearchInstance,
36
- helper = _ref.helper,
37
- attribute = _ref.attribute;
37
+ var instantSearchInstance = _ref.instantSearchInstance;
38
38
  return function () {
39
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
40
- args[_key] = arguments[_key];
41
- }
42
-
43
- if (args.length === 1) {
44
- instantSearchInstance.sendEventToInsights(args[0]);
45
- return;
46
- }
47
-
48
- var eventType = args[0],
49
- facetValue = args[1],
50
- _args$ = args[2],
51
- eventName = _args$ === void 0 ? 'Filter Applied' : _args$;
52
-
53
- if (eventType !== 'click') {
39
+ if (arguments.length === 1) {
40
+ instantSearchInstance.sendEventToInsights(arguments.length <= 0 ? undefined : arguments[0]);
54
41
  return;
55
- } // facetValue === "%7B%22start%22:5,%22end%22:10%7D"
56
-
57
-
58
- var filters = (0, _index.convertNumericRefinementsToFilters)(getRefinedState(helper.state, attribute, facetValue), attribute);
59
-
60
- if (filters && filters.length > 0) {
61
- /*
62
- filters === ["price<=10", "price>=5"]
63
- */
64
- instantSearchInstance.sendEventToInsights({
65
- insightsMethod: 'clickedFilters',
66
- widgetType: $$type,
67
- eventType: eventType,
68
- payload: {
69
- eventName: eventName,
70
- index: helper.getIndex(),
71
- filters: filters
72
- },
73
- attribute: attribute
74
- });
75
42
  }
76
43
  };
77
44
  };
@@ -216,18 +183,39 @@ var connectNumericMenu = function connectNumericMenu(renderFn) {
216
183
 
217
184
  if (!connectorState.sendEvent) {
218
185
  connectorState.sendEvent = createSendEvent({
219
- instantSearchInstance: instantSearchInstance,
220
- helper: helper,
221
- attribute: attribute
186
+ instantSearchInstance: instantSearchInstance
222
187
  });
223
188
  }
224
189
 
190
+ var hasNoResults = results ? results.nbHits === 0 : true;
191
+ var preparedItems = prepareItems(state);
192
+ var allIsSelected = true;
193
+
194
+ var _iterator = _createForOfIteratorHelper(preparedItems),
195
+ _step;
196
+
197
+ try {
198
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
199
+ var item = _step.value;
200
+
201
+ if (item.isRefined && decodeURI(item.value) !== '{}') {
202
+ allIsSelected = false;
203
+ break;
204
+ }
205
+ }
206
+ } catch (err) {
207
+ _iterator.e(err);
208
+ } finally {
209
+ _iterator.f();
210
+ }
211
+
225
212
  return {
226
213
  createURL: connectorState.createURL(state),
227
- items: transformItems(prepareItems(state), {
214
+ items: transformItems(preparedItems, {
228
215
  results: results
229
216
  }),
230
- hasNoResults: results ? results.nbHits === 0 : true,
217
+ hasNoResults: hasNoResults,
218
+ canRefine: !(hasNoResults && allIsSelected),
231
219
  refine: connectorState.refine,
232
220
  sendEvent: connectorState.sendEvent,
233
221
  widgetParams: widgetParams
@@ -156,50 +156,12 @@ var connectRange = function connectRange(renderFn) {
156
156
  return null;
157
157
  };
158
158
 
159
- var sendEventWithRefinedState = function sendEventWithRefinedState(refinedState, instantSearchInstance, helper) {
160
- var eventName = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'Filter Applied';
161
- var filters = (0, _index.convertNumericRefinementsToFilters)(refinedState, attribute);
162
-
163
- if (filters && filters.length > 0) {
164
- instantSearchInstance.sendEventToInsights({
165
- insightsMethod: 'clickedFilters',
166
- widgetType: $$type,
167
- eventType: 'click',
168
- payload: {
169
- eventName: eventName,
170
- index: helper.getIndex(),
171
- filters: filters
172
- },
173
- attribute: attribute
174
- });
175
- }
176
- };
177
-
178
- var createSendEvent = function createSendEvent(instantSearchInstance, helper, currentRange) {
159
+ var createSendEvent = function createSendEvent(instantSearchInstance) {
179
160
  return function () {
180
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
181
- args[_key] = arguments[_key];
182
- }
183
-
184
- if (args.length === 1) {
185
- instantSearchInstance.sendEventToInsights(args[0]);
161
+ if (arguments.length === 1) {
162
+ instantSearchInstance.sendEventToInsights(arguments.length <= 0 ? undefined : arguments[0]);
186
163
  return;
187
164
  }
188
-
189
- var eventType = args[0],
190
- facetValue = args[1],
191
- eventName = args[2];
192
-
193
- if (eventType !== 'click') {
194
- return;
195
- }
196
-
197
- var _facetValue = _slicedToArray(facetValue, 2),
198
- nextMin = _facetValue[0],
199
- nextMax = _facetValue[1];
200
-
201
- var refinedState = getRefinedState(helper, currentRange, nextMin, nextMax);
202
- sendEventWithRefinedState(refinedState, instantSearchInstance, helper, eventName);
203
165
  };
204
166
  };
205
167
 
@@ -245,7 +207,7 @@ var connectRange = function connectRange(renderFn) {
245
207
  return [min, max];
246
208
  }
247
209
 
248
- function _refine(instantSearchInstance, helper, currentRange) {
210
+ function _refine(helper, currentRange) {
249
211
  return function () {
250
212
  var _ref11 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [undefined, undefined],
251
213
  _ref12 = _slicedToArray(_ref11, 2),
@@ -255,7 +217,6 @@ var connectRange = function connectRange(renderFn) {
255
217
  var refinedState = getRefinedState(helper, currentRange, nextMin, nextMax);
256
218
 
257
219
  if (refinedState) {
258
- sendEventWithRefinedState(refinedState, instantSearchInstance, helper);
259
220
  helper.setState(refinedState).search();
260
221
  }
261
222
  };
@@ -301,12 +262,12 @@ var connectRange = function connectRange(renderFn) {
301
262
  // On first render pass an empty range
302
263
  // to be able to bypass the validation
303
264
  // related to it
304
- refine = _refine(instantSearchInstance, helper, {
265
+ refine = _refine(helper, {
305
266
  min: undefined,
306
267
  max: undefined
307
268
  });
308
269
  } else {
309
- refine = _refine(instantSearchInstance, helper, currentRange);
270
+ refine = _refine(helper, currentRange);
310
271
  }
311
272
 
312
273
  return {
@@ -314,7 +275,7 @@ var connectRange = function connectRange(renderFn) {
314
275
  canRefine: currentRange.min !== currentRange.max,
315
276
  format: rangeFormatter,
316
277
  range: currentRange,
317
- sendEvent: createSendEvent(instantSearchInstance, helper, currentRange),
278
+ sendEvent: createSendEvent(instantSearchInstance),
318
279
  widgetParams: _objectSpread(_objectSpread({}, widgetParams), {}, {
319
280
  precision: precision
320
281
  }),
@@ -218,8 +218,11 @@ var connectRatingMenu = function connectRatingMenu(renderFn) {
218
218
  });
219
219
  }
220
220
 
221
- if (results) {
222
- var facetResults = results.getFacetValues(attribute, {});
221
+ var refinementIsApplied = false;
222
+ var totalCount = 0;
223
+ var facetResults = results === null || results === void 0 ? void 0 : results.getFacetValues(attribute, {});
224
+
225
+ if (results && facetResults) {
223
226
  var maxValuesPerFacet = facetResults.length;
224
227
  var maxDecimalPlaces = getFacetsMaxDecimalPlaces(facetResults);
225
228
  var maxFacets = Math.pow(10, maxDecimalPlaces) * max;
@@ -233,6 +236,7 @@ var connectRatingMenu = function connectRatingMenu(renderFn) {
233
236
 
234
237
  var _loop = function _loop(star) {
235
238
  var isRefined = refinedStar === star;
239
+ refinementIsApplied = refinementIsApplied || isRefined;
236
240
  var count = facetResults.filter(function (f) {
237
241
  return Number(f.name) >= star && Number(f.name) <= max;
238
242
  }).map(function (f) {
@@ -240,6 +244,7 @@ var connectRatingMenu = function connectRatingMenu(renderFn) {
240
244
  }).reduce(function (sum, current) {
241
245
  return sum + current;
242
246
  }, 0);
247
+ totalCount += count;
243
248
 
244
249
  if (refinedStar && !isRefined && count === 0) {
245
250
  // skip count==0 when at least 1 refinement is enabled
@@ -269,10 +274,11 @@ var connectRatingMenu = function connectRatingMenu(renderFn) {
269
274
  }
270
275
 
271
276
  facetValues = facetValues.reverse();
277
+ var hasNoResults = results ? results.nbHits === 0 : true;
272
278
  return {
273
279
  items: facetValues,
274
- hasNoResults: results ? results.nbHits === 0 : true,
275
- canRefine: facetValues.length > 0,
280
+ hasNoResults: hasNoResults,
281
+ canRefine: (!hasNoResults || refinementIsApplied) && totalCount > 0,
276
282
  refine: connectorState.toggleRefinementFactory(helper),
277
283
  sendEvent: sendEvent,
278
284
  createURL: connectorState.createURLFactory({
@@ -85,13 +85,15 @@ var connectSortBy = function connectSortBy(renderFn) {
85
85
  };
86
86
  }
87
87
 
88
+ var hasNoResults = results ? results.nbHits === 0 : true;
88
89
  return {
89
90
  currentRefinement: state.index,
90
91
  options: transformItems(items, {
91
92
  results: results
92
93
  }),
93
94
  refine: connectorState.setIndex,
94
- hasNoResults: results ? results.nbHits === 0 : true,
95
+ hasNoResults: hasNoResults,
96
+ canRefine: !hasNoResults && items.length > 0,
95
97
  widgetParams: widgetParams
96
98
  };
97
99
  },
@@ -4,5 +4,5 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _default = '4.44.0';
7
+ var _default = '4.45.1';
8
8
  exports.default = _default;
@@ -39,7 +39,7 @@ var renderer = function renderer(_ref) {
39
39
  templates = _ref.templates;
40
40
  return function (_ref2, isFirstRendering) {
41
41
  var refine = _ref2.refine,
42
- hasRefinements = _ref2.hasRefinements,
42
+ canRefine = _ref2.canRefine,
43
43
  instantSearchInstance = _ref2.instantSearchInstance;
44
44
 
45
45
  if (isFirstRendering) {
@@ -54,7 +54,7 @@ var renderer = function renderer(_ref) {
54
54
  (0, _preact.render)((0, _preact.h)(_ClearRefinements.default, {
55
55
  refine: refine,
56
56
  cssClasses: cssClasses,
57
- hasRefinements: hasRefinements,
57
+ hasRefinements: canRefine,
58
58
  templateProps: renderState.templateProps
59
59
  }), containerNode);
60
60
  };
@@ -173,7 +173,7 @@ declare type AnswersRenderState = {
173
173
  /**
174
174
  * The matched hits from Algolia API.
175
175
  */
176
- hits: Hits;
176
+ hits: Hit[];
177
177
  /**
178
178
  * Whether it's still loading the results from the Answers API.
179
179
  */
@@ -264,7 +264,7 @@ declare type AutocompleteRenderState = {
264
264
  /**
265
265
  * The resolved hits from the index matching the query.
266
266
  */
267
- hits: Hits;
267
+ hits: Hit[];
268
268
  /**
269
269
  * The full results object from the Algolia API.
270
270
  */
@@ -518,11 +518,11 @@ declare type BrowserHistoryArgs<TRouteState> = {
518
518
  getLocation(): Location;
519
519
  };
520
520
 
521
- declare type BuiltInBindEventForHits = (eventType: string, hits: Hit | Hits, eventName?: string) => string;
521
+ declare type BuiltInBindEventForHits = (eventType: string, hits: Hit | Hit[], eventName?: string) => string;
522
522
 
523
523
  declare type BuiltInSendEventForFacet = (eventType: string, facetValue: string, eventName?: string) => void;
524
524
 
525
- declare type BuiltInSendEventForHits = (eventType: string, hits: Hit | Hits, eventName?: string) => void;
525
+ declare type BuiltInSendEventForHits = (eventType: string, hits: Hit | Hit[], eventName?: string) => void;
526
526
 
527
527
  declare type BuiltInSendEventForToggle = (eventType: string, isRefined: boolean, eventName?: string) => void;
528
528
 
@@ -1769,11 +1769,6 @@ declare type HitHighlightResult = {
1769
1769
  [attribute: string]: HitAttributeHighlightResult | HitAttributeHighlightResult[] | HitHighlightResult[] | HitHighlightResult;
1770
1770
  };
1771
1771
 
1772
- /**
1773
- * @deprecated use Hit[] directly instead
1774
- */
1775
- declare type Hits = Hit[];
1776
-
1777
1772
  declare const hits: HitsWidget;
1778
1773
 
1779
1774
  declare type HitsConnector<THit extends BaseHit = BaseHit> = Connector<HitsWidgetDescription<THit>, HitsConnectorParams<THit>>;
@@ -1872,8 +1867,13 @@ declare type HitsPerPageRenderState = {
1872
1867
  refine: (value: number) => void;
1873
1868
  /**
1874
1869
  * Indicates whether or not the search has results.
1870
+ * @deprecated Use `canRefine` instead.
1875
1871
  */
1876
1872
  hasNoResults: boolean;
1873
+ /**
1874
+ * Indicates if search state can be refined.
1875
+ */
1876
+ canRefine: boolean;
1877
1877
  };
1878
1878
 
1879
1879
  declare type HitsPerPageRenderStateItem = {
@@ -2401,6 +2401,10 @@ declare type InstantSearchModule = {
2401
2401
  reverseHighlight: typeof helpers.reverseHighlight;
2402
2402
  snippet: typeof helpers.snippet;
2403
2403
  reverseSnippet: typeof helpers.reverseSnippet;
2404
+ /**
2405
+ * @deprecated use createInsightsMiddleware
2406
+ * @link https://www.algolia.com/doc/api-reference/widgets/insights/js/
2407
+ */
2404
2408
  insights: typeof helpers.insights;
2405
2409
  };
2406
2410
 
@@ -2855,8 +2859,16 @@ declare type NumericMenuRenderState = {
2855
2859
  createURL: CreateURL<NumericMenuRenderStateItem['value']>;
2856
2860
  /**
2857
2861
  * `true` if the last search contains no result
2862
+ * @deprecated Use `canRefine` instead.
2858
2863
  */
2859
2864
  hasNoResults: boolean;
2865
+ /**
2866
+ * Indicates if search state can be refined.
2867
+ *
2868
+ * This is `true` if the last search contains no result and
2869
+ * "All" range is selected
2870
+ */
2871
+ canRefine: boolean;
2860
2872
  /**
2861
2873
  * Sets the selected value and trigger a new search
2862
2874
  */
@@ -3721,6 +3733,8 @@ declare type RatingMenuRenderState = {
3721
3733
  refine: (value: string) => void;
3722
3734
  /**
3723
3735
  * `true` if the last search contains no result.
3736
+ *
3737
+ * @deprecated Use `canRefine` instead.
3724
3738
  */
3725
3739
  hasNoResults: boolean;
3726
3740
  /**
@@ -4240,7 +4254,7 @@ declare type RendererOptions<TWidgetParams> = {
4240
4254
  * The mutable list of hits. The may change depending
4241
4255
  * of the given transform items function.
4242
4256
  */
4243
- hits?: Hits;
4257
+ hits?: Hit[];
4244
4258
  /**
4245
4259
  * The current insights client, if any.
4246
4260
  */
@@ -4683,8 +4697,13 @@ declare type SortByRenderState = {
4683
4697
  refine: (value: string) => void;
4684
4698
  /**
4685
4699
  * `true` if the last search contains no result.
4700
+ * @deprecated Use `canRefine` instead.
4686
4701
  */
4687
4702
  hasNoResults: boolean;
4703
+ /**
4704
+ * `true` if we can refine.
4705
+ */
4706
+ canRefine: boolean;
4688
4707
  };
4689
4708
 
4690
4709
  declare type SortByWidget = WidgetFactory<SortByWidgetDescription & {