instantsearch.js 4.49.4 → 4.50.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 (167) hide show
  1. package/cjs/components/Pagination/Pagination.js +1 -1
  2. package/cjs/connectors/hits/connectHits.js +2 -1
  3. package/cjs/connectors/infinite-hits/connectInfiniteHits.js +3 -2
  4. package/cjs/lib/InstantSearch.js +3 -7
  5. package/cjs/lib/templating/prepareTemplateProps.js +1 -2
  6. package/cjs/lib/templating/renderTemplate.js +3 -0
  7. package/cjs/lib/utils/createSendEventForHits.js +6 -5
  8. package/cjs/lib/version.js +1 -1
  9. package/cjs/widgets/hits/hits.js +3 -4
  10. package/cjs/widgets/index/index.js +18 -1
  11. package/cjs/widgets/infinite-hits/infinite-hits.js +3 -4
  12. package/dist/instantsearch.development.d.ts +11 -3
  13. package/dist/instantsearch.development.js +89 -37
  14. package/dist/instantsearch.development.js.map +1 -1
  15. package/dist/instantsearch.production.d.ts +11 -3
  16. package/dist/instantsearch.production.min.d.ts +11 -3
  17. package/dist/instantsearch.production.min.js +2 -2
  18. package/dist/instantsearch.production.min.js.map +1 -1
  19. package/es/components/Answers/Answers.d.ts +3 -3
  20. package/es/components/Breadcrumb/Breadcrumb.d.ts +3 -3
  21. package/es/components/ClearRefinements/ClearRefinements.d.ts +3 -3
  22. package/es/components/CurrentRefinements/CurrentRefinements.d.ts +2 -2
  23. package/es/components/GeoSearchControls/GeoSearchButton.d.ts +1 -1
  24. package/es/components/GeoSearchControls/GeoSearchControls.d.ts +1 -1
  25. package/es/components/GeoSearchControls/GeoSearchToggle.d.ts +1 -1
  26. package/es/components/Highlight/Highlight.d.ts +2 -2
  27. package/es/components/Hits/Hits.d.ts +3 -3
  28. package/es/components/InfiniteHits/InfiniteHits.d.ts +3 -3
  29. package/es/components/MenuSelect/MenuSelect.d.ts +4 -4
  30. package/es/components/Pagination/Pagination.d.ts +3 -3
  31. package/es/components/Pagination/Pagination.js +1 -1
  32. package/es/components/Panel/Panel.d.ts +3 -3
  33. package/es/components/PoweredBy/PoweredBy.d.ts +2 -2
  34. package/es/components/QueryRuleCustomData/QueryRuleCustomData.d.ts +3 -3
  35. package/es/components/RangeInput/RangeInput.d.ts +3 -3
  36. package/es/components/RefinementList/RefinementList.d.ts +7 -7
  37. package/es/components/RefinementList/RefinementListItem.d.ts +1 -1
  38. package/es/components/RelevantSort/RelevantSort.d.ts +3 -3
  39. package/es/components/ReverseHighlight/ReverseHighlight.d.ts +2 -2
  40. package/es/components/ReverseSnippet/ReverseSnippet.d.ts +2 -2
  41. package/es/components/SearchBox/SearchBox.d.ts +5 -5
  42. package/es/components/Selector/Selector.d.ts +3 -3
  43. package/es/components/Slider/Rheostat.d.ts +6 -6
  44. package/es/components/Slider/Slider.d.ts +2 -2
  45. package/es/components/Snippet/Snippet.d.ts +2 -2
  46. package/es/components/Stats/Stats.d.ts +3 -3
  47. package/es/components/Template/Template.d.ts +1 -1
  48. package/es/components/ToggleRefinement/ToggleRefinement.d.ts +3 -3
  49. package/es/components/VoiceSearch/VoiceSearch.d.ts +3 -3
  50. package/es/connectors/answers/connectAnswers.d.ts +4 -4
  51. package/es/connectors/autocomplete/connectAutocomplete.d.ts +4 -4
  52. package/es/connectors/breadcrumb/connectBreadcrumb.d.ts +5 -5
  53. package/es/connectors/clear-refinements/connectClearRefinements.d.ts +4 -4
  54. package/es/connectors/configure/connectConfigure.d.ts +5 -5
  55. package/es/connectors/configure-related-items/connectConfigureRelatedItems.d.ts +5 -5
  56. package/es/connectors/current-refinements/connectCurrentRefinements.d.ts +6 -6
  57. package/es/connectors/dynamic-widgets/connectDynamicWidgets.d.ts +4 -4
  58. package/es/connectors/geo-search/connectGeoSearch.d.ts +6 -6
  59. package/es/connectors/hierarchical-menu/connectHierarchicalMenu.d.ts +5 -5
  60. package/es/connectors/hits/connectHits.d.ts +4 -4
  61. package/es/connectors/hits/connectHits.js +2 -1
  62. package/es/connectors/hits-per-page/connectHitsPerPage.d.ts +6 -6
  63. package/es/connectors/infinite-hits/connectInfiniteHits.d.ts +8 -8
  64. package/es/connectors/infinite-hits/connectInfiniteHits.js +3 -2
  65. package/es/connectors/menu/connectMenu.d.ts +5 -5
  66. package/es/connectors/numeric-menu/connectNumericMenu.d.ts +6 -6
  67. package/es/connectors/pagination/connectPagination.d.ts +4 -4
  68. package/es/connectors/powered-by/connectPoweredBy.d.ts +4 -4
  69. package/es/connectors/query-rules/connectQueryRules.d.ts +7 -7
  70. package/es/connectors/range/connectRange.d.ts +8 -8
  71. package/es/connectors/rating-menu/connectRatingMenu.d.ts +6 -6
  72. package/es/connectors/refinement-list/connectRefinementList.d.ts +5 -5
  73. package/es/connectors/relevant-sort/connectRelevantSort.d.ts +5 -5
  74. package/es/connectors/search-box/connectSearchBox.d.ts +4 -4
  75. package/es/connectors/sort-by/connectSortBy.d.ts +5 -5
  76. package/es/connectors/stats/connectStats.d.ts +4 -4
  77. package/es/connectors/toggle-refinement/connectToggleRefinement.d.ts +9 -9
  78. package/es/connectors/toggle-refinement/types.d.ts +5 -5
  79. package/es/connectors/voice-search/connectVoiceSearch.d.ts +4 -4
  80. package/es/helpers/components/Highlight.d.ts +1 -1
  81. package/es/helpers/components/ReverseHighlight.d.ts +1 -1
  82. package/es/helpers/components/ReverseSnippet.d.ts +1 -1
  83. package/es/helpers/components/Snippet.d.ts +1 -1
  84. package/es/helpers/highlight.d.ts +1 -1
  85. package/es/helpers/reverseHighlight.d.ts +1 -1
  86. package/es/helpers/reverseSnippet.d.ts +1 -1
  87. package/es/helpers/snippet.d.ts +1 -1
  88. package/es/index.d.ts +1 -1
  89. package/es/lib/InstantSearch.d.ts +3 -3
  90. package/es/lib/InstantSearch.js +3 -7
  91. package/es/lib/createHelpers.d.ts +1 -1
  92. package/es/lib/insights/listener.d.ts +1 -1
  93. package/es/lib/routers/history.d.ts +3 -3
  94. package/es/lib/suit.d.ts +2 -2
  95. package/es/lib/templating/prepareTemplateProps.d.ts +2 -2
  96. package/es/lib/templating/prepareTemplateProps.js +1 -2
  97. package/es/lib/templating/renderTemplate.js +3 -0
  98. package/es/lib/utils/checkIndexUiState.d.ts +1 -1
  99. package/es/lib/utils/createConcurrentSafePromise.d.ts +2 -2
  100. package/es/lib/utils/createSendEventForFacet.d.ts +4 -4
  101. package/es/lib/utils/createSendEventForHits.d.ts +8 -7
  102. package/es/lib/utils/createSendEventForHits.js +6 -5
  103. package/es/lib/utils/debounce.d.ts +2 -2
  104. package/es/lib/utils/defer.d.ts +2 -2
  105. package/es/lib/utils/documentation.d.ts +2 -2
  106. package/es/lib/utils/escapeFacetValue.d.ts +1 -1
  107. package/es/lib/utils/geo-search.d.ts +1 -1
  108. package/es/lib/utils/getRefinements.d.ts +6 -6
  109. package/es/lib/utils/logger.d.ts +2 -2
  110. package/es/lib/utils/range.d.ts +1 -1
  111. package/es/lib/utils/safelyRunOnBrowser.d.ts +2 -2
  112. package/es/lib/utils/toArray.d.ts +1 -1
  113. package/es/lib/version.d.ts +1 -1
  114. package/es/lib/version.js +1 -1
  115. package/es/lib/voiceSearchHelper/types.d.ts +5 -5
  116. package/es/middlewares/createInsightsMiddleware.d.ts +3 -3
  117. package/es/middlewares/createRouterMiddleware.d.ts +1 -1
  118. package/es/types/component.d.ts +1 -1
  119. package/es/types/connector.d.ts +4 -4
  120. package/es/types/insights.d.ts +5 -5
  121. package/es/types/middleware.d.ts +4 -4
  122. package/es/types/render-state.d.ts +5 -5
  123. package/es/types/results.d.ts +16 -16
  124. package/es/types/router.d.ts +2 -2
  125. package/es/types/templates.d.ts +14 -6
  126. package/es/types/ui-state.d.ts +4 -4
  127. package/es/types/utils.d.ts +6 -6
  128. package/es/types/widget-factory.d.ts +2 -2
  129. package/es/types/widget.d.ts +23 -23
  130. package/es/widgets/analytics/analytics.d.ts +4 -4
  131. package/es/widgets/answers/answers.d.ts +4 -4
  132. package/es/widgets/breadcrumb/breadcrumb.d.ts +4 -4
  133. package/es/widgets/clear-refinements/clear-refinements.d.ts +4 -4
  134. package/es/widgets/configure/configure.d.ts +2 -2
  135. package/es/widgets/configure-related-items/configure-related-items.d.ts +2 -2
  136. package/es/widgets/current-refinements/current-refinements.d.ts +3 -3
  137. package/es/widgets/dynamic-widgets/dynamic-widgets.d.ts +2 -2
  138. package/es/widgets/geo-search/createHTMLMarker.d.ts +1 -1
  139. package/es/widgets/geo-search/geo-search.d.ts +7 -7
  140. package/es/widgets/hierarchical-menu/hierarchical-menu.d.ts +6 -6
  141. package/es/widgets/hits/hits.d.ts +4 -4
  142. package/es/widgets/hits/hits.js +3 -4
  143. package/es/widgets/hits-per-page/hits-per-page.d.ts +3 -3
  144. package/es/widgets/index/index.d.ts +5 -5
  145. package/es/widgets/index/index.js +18 -1
  146. package/es/widgets/infinite-hits/infinite-hits.d.ts +4 -4
  147. package/es/widgets/infinite-hits/infinite-hits.js +3 -4
  148. package/es/widgets/menu/menu.d.ts +6 -6
  149. package/es/widgets/menu-select/menu-select.d.ts +4 -4
  150. package/es/widgets/numeric-menu/numeric-menu.d.ts +6 -6
  151. package/es/widgets/pagination/pagination.d.ts +4 -4
  152. package/es/widgets/panel/panel.d.ts +9 -9
  153. package/es/widgets/places/places.d.ts +6 -6
  154. package/es/widgets/powered-by/powered-by.d.ts +3 -3
  155. package/es/widgets/query-rule-context/query-rule-context.d.ts +2 -2
  156. package/es/widgets/query-rule-custom-data/query-rule-custom-data.d.ts +4 -4
  157. package/es/widgets/range-input/range-input.d.ts +4 -4
  158. package/es/widgets/range-slider/range-slider.d.ts +4 -4
  159. package/es/widgets/rating-menu/rating-menu.d.ts +6 -6
  160. package/es/widgets/refinement-list/refinement-list.d.ts +10 -10
  161. package/es/widgets/relevant-sort/relevant-sort.d.ts +4 -4
  162. package/es/widgets/search-box/search-box.d.ts +4 -4
  163. package/es/widgets/sort-by/sort-by.d.ts +4 -4
  164. package/es/widgets/stats/stats.d.ts +5 -5
  165. package/es/widgets/toggle-refinement/toggle-refinement.d.ts +4 -4
  166. package/es/widgets/voice-search/voice-search.d.ts +5 -5
  167. package/package.json +7 -5
@@ -44,7 +44,7 @@ function Pagination(props) {
44
44
  }), props.pages.map(function (pageNumber) {
45
45
  return (0, _preact.h)(PaginationLink, {
46
46
  key: pageNumber,
47
- ariaLabel: "".concat(pageNumber + 1),
47
+ ariaLabel: "Page ".concat(pageNumber + 1),
48
48
  className: props.cssClasses.pageItem,
49
49
  isSelected: pageNumber === props.currentPage,
50
50
  label: "".concat(pageNumber + 1),
@@ -61,7 +61,8 @@ var connectHits = function connectHits(renderFn) {
61
61
  if (!bindEvent) {
62
62
  bindEvent = (0, _utils.createBindEventForHits)({
63
63
  index: helper.getIndex(),
64
- widgetType: this.$$type
64
+ widgetType: this.$$type,
65
+ instantSearchInstance: instantSearchInstance
65
66
  });
66
67
  }
67
68
  if (!results) {
@@ -151,7 +151,8 @@ var connectInfiniteHits = function connectInfiniteHits(renderFn) {
151
151
  });
152
152
  bindEvent = (0, _utils.createBindEventForHits)({
153
153
  index: helper.getIndex(),
154
- widgetType: this.$$type
154
+ widgetType: this.$$type,
155
+ instantSearchInstance: instantSearchInstance
155
156
  });
156
157
  isFirstPage = state.page === undefined || getFirstReceivedPage(state, cachedHits) === 0;
157
158
  } else {
@@ -165,7 +166,7 @@ var connectInfiniteHits = function connectInfiniteHits(renderFn) {
165
166
  var transformedHits = transformItems(hitsWithAbsolutePositionAndQueryID, {
166
167
  results: results
167
168
  });
168
- if (cachedHits[_page] === undefined && !results.__isArtificial) {
169
+ if (cachedHits[_page] === undefined && !results.__isArtificial && instantSearchInstance.status === 'idle') {
169
170
  cachedHits[_page] = transformedHits;
170
171
  cache.write({
171
172
  state: state,
@@ -80,8 +80,9 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
80
80
  }
81
81
  }));
82
82
  _defineProperty(_assertThisInitialized(_this), "scheduleRender", (0, _utils.defer)(function () {
83
+ var _this$mainHelper;
83
84
  var shouldResetStatus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
84
- if (!_this.mainHelper.hasPendingRequests()) {
85
+ if (!((_this$mainHelper = _this.mainHelper) !== null && _this$mainHelper !== void 0 && _this$mainHelper.hasPendingRequests())) {
85
86
  clearTimeout(_this._searchStalledTimer);
86
87
  _this._searchStalledTimer = null;
87
88
  if (shouldResetStatus) {
@@ -349,12 +350,7 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
349
350
  var mainHelper = this.mainHelper || (0, _algoliasearchHelper.default)(this.client, this.indexName);
350
351
  mainHelper.search = function () {
351
352
  _this3.status = 'loading';
352
- // @MAJOR: use scheduleRender here
353
- // For now, widgets don't expect to be rendered at the start of `loading`,
354
- // so it would be a breaking change to add an extra render. We don't have
355
- // these guarantees about the render event, thus emitting it once more
356
- // isn't a breaking change.
357
- _this3.emit('render');
353
+ _this3.scheduleRender(false);
358
354
 
359
355
  // This solution allows us to keep the exact same API for the users but
360
356
  // under the hood, we have a different implementation. It should be
@@ -26,8 +26,7 @@ defaultTemplates) {
26
26
  var defaultTemplate = defaultTemplates ? defaultTemplates[key] : undefined;
27
27
  var customTemplate = templates[key];
28
28
  var isCustomTemplate = customTemplate !== undefined && customTemplate !== defaultTemplate;
29
- config.templates[key] = isCustomTemplate ? customTemplate // typescript doesn't recognize that this condition asserts customTemplate is defined
30
- : defaultTemplate;
29
+ config.templates[key] = isCustomTemplate ? customTemplate : defaultTemplate;
31
30
  config.useCustomCompileOptions[key] = isCustomTemplate;
32
31
  return config;
33
32
  }, {
@@ -57,6 +57,9 @@ function renderTemplate(_ref) {
57
57
  Snippet: _components.Snippet,
58
58
  ReverseSnippet: _components.ReverseSnippet
59
59
  };
60
+
61
+ // @MAJOR remove the `as any` when string templates are removed
62
+ // needed because not every template receives sendEvent
60
63
  return template(data, params);
61
64
  }
62
65
  var transformedHelpers = transformHelpersToHogan(helpers, compileOptions, data);
@@ -20,7 +20,7 @@ var buildPayloads = function buildPayloads(_ref) {
20
20
  widgetType = _ref.widgetType,
21
21
  methodName = _ref.methodName,
22
22
  args = _ref.args,
23
- isSearchStalled = _ref.isSearchStalled;
23
+ instantSearchInstance = _ref.instantSearchInstance;
24
24
  // when there's only one argument, that means it's custom
25
25
  if (args.length === 1 && _typeof(args[0]) === 'object') {
26
26
  return [args[0]];
@@ -59,7 +59,7 @@ var buildPayloads = function buildPayloads(_ref) {
59
59
  });
60
60
  });
61
61
  if (eventType === 'view') {
62
- if (isSearchStalled) {
62
+ if (instantSearchInstance.status !== 'idle') {
63
63
  return [];
64
64
  }
65
65
  return hitsChunks.map(function (batch, i) {
@@ -129,7 +129,7 @@ function createSendEventForHits(_ref2) {
129
129
  index: index,
130
130
  methodName: 'sendEvent',
131
131
  args: args,
132
- isSearchStalled: instantSearchInstance.status === 'stalled'
132
+ instantSearchInstance: instantSearchInstance
133
133
  });
134
134
  payloads.forEach(function (payload) {
135
135
  return instantSearchInstance.sendEventToInsights(payload);
@@ -139,7 +139,8 @@ function createSendEventForHits(_ref2) {
139
139
  }
140
140
  function createBindEventForHits(_ref3) {
141
141
  var index = _ref3.index,
142
- widgetType = _ref3.widgetType;
142
+ widgetType = _ref3.widgetType,
143
+ instantSearchInstance = _ref3.instantSearchInstance;
143
144
  var bindEventForHits = function bindEventForHits() {
144
145
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
145
146
  args[_key2] = arguments[_key2];
@@ -149,7 +150,7 @@ function createBindEventForHits(_ref3) {
149
150
  index: index,
150
151
  methodName: 'bindEvent',
151
152
  args: args,
152
- isSearchStalled: false
153
+ instantSearchInstance: instantSearchInstance
153
154
  });
154
155
  return payloads.length ? "data-insights-event=".concat((0, _serializer.serializePayload)(payloads)) : '';
155
156
  };
@@ -4,5 +4,5 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _default = '4.49.4';
7
+ var _default = '4.50.1';
8
8
  exports.default = _default;
@@ -35,7 +35,8 @@ var renderer = function renderer(_ref) {
35
35
  results = _ref2.results,
36
36
  instantSearchInstance = _ref2.instantSearchInstance,
37
37
  insights = _ref2.insights,
38
- bindEvent = _ref2.bindEvent;
38
+ bindEvent = _ref2.bindEvent,
39
+ sendEvent = _ref2.sendEvent;
39
40
  if (isFirstRendering) {
40
41
  renderState.templateProps = (0, _templating.prepareTemplateProps)({
41
42
  defaultTemplates: _defaultTemplates.default,
@@ -50,9 +51,7 @@ var renderer = function renderer(_ref) {
50
51
  results: results,
51
52
  templateProps: renderState.templateProps,
52
53
  insights: insights,
53
- sendEvent: function sendEvent(event) {
54
- instantSearchInstance.sendEventToInsights(event);
55
- },
54
+ sendEvent: sendEvent,
56
55
  bindEvent: bindEvent
57
56
  }), containerNode);
58
57
  };
@@ -108,6 +108,7 @@ var index = function index(widgetParams) {
108
108
  var localParent = null;
109
109
  var helper = null;
110
110
  var derivedHelper = null;
111
+ var lastValidSearchParameters = null;
111
112
  return {
112
113
  $$type: 'ais.index',
113
114
  $$widgetType: 'ais.index',
@@ -121,7 +122,16 @@ var index = function index(widgetParams) {
121
122
  return helper;
122
123
  },
123
124
  getResults: function getResults() {
124
- return derivedHelper && derivedHelper.lastResults;
125
+ var _derivedHelper;
126
+ if (!((_derivedHelper = derivedHelper) !== null && _derivedHelper !== void 0 && _derivedHelper.lastResults)) return null;
127
+
128
+ // To make the UI optimistic, we patch the state to display to the current
129
+ // one instead of the one associated with the latest results.
130
+ // This means user-driven UI changes (e.g., checked checkbox) are reflected
131
+ // immediately instead of waiting for Algolia to respond, regardless of
132
+ // the status of the network request.
133
+ derivedHelper.lastResults._state = helper.state;
134
+ return derivedHelper.lastResults;
125
135
  },
126
136
  getScopedResults: function getScopedResults() {
127
137
  var widgetParent = this.getParent();
@@ -326,6 +336,7 @@ var index = function index(widgetParams) {
326
336
  // does not have access to lastResults, which it used to in pre-federated
327
337
  // search behavior.
328
338
  helper.lastResults = results;
339
+ lastValidSearchParameters = results._state;
329
340
  });
330
341
 
331
342
  // We compute the render state before calling `init` in a separate loop
@@ -384,6 +395,12 @@ var index = function index(widgetParams) {
384
395
  if (!this.getResults()) {
385
396
  return;
386
397
  }
398
+
399
+ // we can't attach a listener to the error event of search, as the error
400
+ // then would no longer be thrown for global handlers.
401
+ if (instantSearchInstance.status === 'error' && !instantSearchInstance.mainHelper.hasPendingRequests()) {
402
+ helper.setState(lastValidSearchParameters);
403
+ }
387
404
  localWidgets.forEach(function (widget) {
388
405
  if (widget.getRenderState) {
389
406
  var renderState = widget.getRenderState(instantSearchInstance.renderState[_this4.getIndexId()] || {}, (0, _utils.createRenderArgs)(instantSearchInstance, _this4));
@@ -40,7 +40,8 @@ var renderer = function renderer(_ref) {
40
40
  isLastPage = _ref2.isLastPage,
41
41
  instantSearchInstance = _ref2.instantSearchInstance,
42
42
  insights = _ref2.insights,
43
- bindEvent = _ref2.bindEvent;
43
+ bindEvent = _ref2.bindEvent,
44
+ sendEvent = _ref2.sendEvent;
44
45
  if (isFirstRendering) {
45
46
  renderState.templateProps = (0, _templating.prepareTemplateProps)({
46
47
  defaultTemplates: _defaultTemplates.default,
@@ -60,9 +61,7 @@ var renderer = function renderer(_ref) {
60
61
  isFirstPage: isFirstPage,
61
62
  isLastPage: isLastPage,
62
63
  insights: insights,
63
- sendEvent: function sendEvent(event) {
64
- instantSearchInstance.sendEventToInsights(event);
65
- },
64
+ sendEvent: sendEvent,
66
65
  bindEvent: bindEvent
67
66
  }), containerNode);
68
67
  };
@@ -2832,7 +2832,7 @@ declare namespace middlewares {
2832
2832
  }
2833
2833
  }
2834
2834
 
2835
- declare type NoInfer<T> = [T][T extends any ? 0 : never];
2835
+ declare type NoInfer<T> = T extends infer S ? S : never;
2836
2836
 
2837
2837
  declare const numericMenu: NumericMenuWidget;
2838
2838
 
@@ -5052,7 +5052,7 @@ declare type Status = 'initial' | 'askingPermission' | 'waiting' | 'recognizing'
5052
5052
 
5053
5053
  declare type Template<TTemplateData = void> = string | ((data: TTemplateData, params: TemplateParams) => VNode | VNode[] | string);
5054
5054
 
5055
- declare type TemplateParams = BindEventForHits & {
5055
+ declare type TemplateParams = {
5056
5056
  html: typeof html;
5057
5057
  components: {
5058
5058
  Highlight: typeof Highlight;
@@ -5067,7 +5067,15 @@ declare type Templates = {
5067
5067
  [key: string]: Template<any> | TemplateWithBindEvent<any> | undefined;
5068
5068
  };
5069
5069
 
5070
- declare type TemplateWithBindEvent<TTemplateData = void> = string | ((data: TTemplateData, params: TemplateParams) => VNode | VNode[] | string);
5070
+ declare type TemplateWithBindEvent<TTemplateData = void> = string | ((data: TTemplateData, params: TemplateWithBindEventParams) => VNode | VNode[] | string);
5071
+
5072
+ declare interface TemplateWithBindEventParams extends TemplateParams {
5073
+ /** @deprecated use sendEvent instead */
5074
+ (...args: Parameters<BuiltInBindEventForHits>): ReturnType<BuiltInBindEventForHits>;
5075
+ /** @deprecated use sendEvent instead */
5076
+ (...args: Parameters<CustomBindEventForHits>): ReturnType<CustomBindEventForHits>;
5077
+ sendEvent: SendEventForHits;
5078
+ }
5071
5079
 
5072
5080
  declare type TextTemplateProps = {
5073
5081
  hasManyResults: boolean;
@@ -1,4 +1,4 @@
1
- /*! InstantSearch.js 4.49.4 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch.js */
1
+ /*! InstantSearch.js 4.50.1 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch.js */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
4
4
  typeof define === 'function' && define.amd ? define(factory) :
@@ -3150,7 +3150,33 @@
3150
3150
  };
3151
3151
  });
3152
3152
  } else if (results._state.isHierarchicalFacet(attribute)) {
3153
- return find(results.hierarchicalFacets, predicate);
3153
+ var hierarchicalFacetValues = find(results.hierarchicalFacets, predicate);
3154
+ if (!hierarchicalFacetValues) return hierarchicalFacetValues;
3155
+
3156
+ var hierarchicalFacet = results._state.getHierarchicalFacetByName(attribute);
3157
+ var currentRefinementSplit = unescapeFacetValue$2(
3158
+ results._state.getHierarchicalRefinement(attribute)[0] || ''
3159
+ ).split(results._state._getHierarchicalFacetSeparator(hierarchicalFacet));
3160
+ currentRefinementSplit.unshift(attribute);
3161
+
3162
+ setIsRefined(hierarchicalFacetValues, currentRefinementSplit, 0);
3163
+
3164
+ return hierarchicalFacetValues;
3165
+ }
3166
+ }
3167
+
3168
+ /**
3169
+ * Set the isRefined of a hierarchical facet result based on the current state.
3170
+ * @param {SearchResults.HierarchicalFacet} item Hierarchical facet to fix
3171
+ * @param {string[]} currentRefinementSplit array of parts of the current hierarchical refinement
3172
+ * @param {number} depth recursion depth in the currentRefinement
3173
+ */
3174
+ function setIsRefined(item, currentRefinement, depth) {
3175
+ item.isRefined = item.name === currentRefinement[depth];
3176
+ if (item.data) {
3177
+ item.data.forEach(function(child) {
3178
+ setIsRefined(child, currentRefinement, depth + 1);
3179
+ });
3154
3180
  }
3155
3181
  }
3156
3182
 
@@ -4239,7 +4265,7 @@
4239
4265
 
4240
4266
  var requestBuilder_1 = requestBuilder;
4241
4267
 
4242
- var version = '3.11.2';
4268
+ var version = '3.11.3';
4243
4269
 
4244
4270
  var escapeFacetValue$3 = escapeFacetValue_1.escapeFacetValue;
4245
4271
 
@@ -6278,7 +6304,7 @@
6278
6304
  widgetType = _ref.widgetType,
6279
6305
  methodName = _ref.methodName,
6280
6306
  args = _ref.args,
6281
- isSearchStalled = _ref.isSearchStalled;
6307
+ instantSearchInstance = _ref.instantSearchInstance;
6282
6308
  // when there's only one argument, that means it's custom
6283
6309
  if (args.length === 1 && _typeof(args[0]) === 'object') {
6284
6310
  return [args[0]];
@@ -6313,7 +6339,7 @@
6313
6339
  });
6314
6340
  });
6315
6341
  if (eventType === 'view') {
6316
- if (isSearchStalled) {
6342
+ if (instantSearchInstance.status !== 'idle') {
6317
6343
  return [];
6318
6344
  }
6319
6345
  return hitsChunks.map(function (batch, i) {
@@ -6381,7 +6407,7 @@
6381
6407
  index: index,
6382
6408
  methodName: 'sendEvent',
6383
6409
  args: args,
6384
- isSearchStalled: instantSearchInstance.status === 'stalled'
6410
+ instantSearchInstance: instantSearchInstance
6385
6411
  });
6386
6412
  payloads.forEach(function (payload) {
6387
6413
  return instantSearchInstance.sendEventToInsights(payload);
@@ -6391,7 +6417,8 @@
6391
6417
  }
6392
6418
  function createBindEventForHits(_ref3) {
6393
6419
  var index = _ref3.index,
6394
- widgetType = _ref3.widgetType;
6420
+ widgetType = _ref3.widgetType,
6421
+ instantSearchInstance = _ref3.instantSearchInstance;
6395
6422
  var bindEventForHits = function bindEventForHits() {
6396
6423
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
6397
6424
  args[_key2] = arguments[_key2];
@@ -6401,7 +6428,7 @@
6401
6428
  index: index,
6402
6429
  methodName: 'bindEvent',
6403
6430
  args: args,
6404
- isSearchStalled: false
6431
+ instantSearchInstance: instantSearchInstance
6405
6432
  });
6406
6433
  return payloads.length ? "data-insights-event=".concat(serializePayload(payloads)) : '';
6407
6434
  };
@@ -7218,6 +7245,7 @@
7218
7245
  var localParent = null;
7219
7246
  var helper = null;
7220
7247
  var derivedHelper = null;
7248
+ var lastValidSearchParameters = null;
7221
7249
  return {
7222
7250
  $$type: 'ais.index',
7223
7251
  $$widgetType: 'ais.index',
@@ -7231,7 +7259,16 @@
7231
7259
  return helper;
7232
7260
  },
7233
7261
  getResults: function getResults() {
7234
- return derivedHelper && derivedHelper.lastResults;
7262
+ var _derivedHelper;
7263
+ if (!((_derivedHelper = derivedHelper) !== null && _derivedHelper !== void 0 && _derivedHelper.lastResults)) return null;
7264
+
7265
+ // To make the UI optimistic, we patch the state to display to the current
7266
+ // one instead of the one associated with the latest results.
7267
+ // This means user-driven UI changes (e.g., checked checkbox) are reflected
7268
+ // immediately instead of waiting for Algolia to respond, regardless of
7269
+ // the status of the network request.
7270
+ derivedHelper.lastResults._state = helper.state;
7271
+ return derivedHelper.lastResults;
7235
7272
  },
7236
7273
  getScopedResults: function getScopedResults() {
7237
7274
  var widgetParent = this.getParent();
@@ -7436,6 +7473,7 @@
7436
7473
  // does not have access to lastResults, which it used to in pre-federated
7437
7474
  // search behavior.
7438
7475
  helper.lastResults = results;
7476
+ lastValidSearchParameters = results._state;
7439
7477
  });
7440
7478
 
7441
7479
  // We compute the render state before calling `init` in a separate loop
@@ -7494,6 +7532,12 @@
7494
7532
  if (!this.getResults()) {
7495
7533
  return;
7496
7534
  }
7535
+
7536
+ // we can't attach a listener to the error event of search, as the error
7537
+ // then would no longer be thrown for global handlers.
7538
+ if (instantSearchInstance.status === 'error' && !instantSearchInstance.mainHelper.hasPendingRequests()) {
7539
+ helper.setState(lastValidSearchParameters);
7540
+ }
7497
7541
  localWidgets.forEach(function (widget) {
7498
7542
  if (widget.getRenderState) {
7499
7543
  var renderState = widget.getRenderState(instantSearchInstance.renderState[_this4.getIndexId()] || {}, createRenderArgs(instantSearchInstance, _this4));
@@ -7573,7 +7617,7 @@
7573
7617
  instantSearchInstance.renderState = _objectSpread2(_objectSpread2({}, instantSearchInstance.renderState), {}, _defineProperty({}, parentIndexName, _objectSpread2(_objectSpread2({}, instantSearchInstance.renderState[parentIndexName]), renderState)));
7574
7618
  }
7575
7619
 
7576
- var version$1 = '4.49.4';
7620
+ var version$1 = '4.50.1';
7577
7621
 
7578
7622
  var NAMESPACE = 'ais';
7579
7623
  var component = function component(componentName) {
@@ -8036,6 +8080,7 @@
8036
8080
 
8037
8081
  i += 1;
8038
8082
  c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
8083
+ /* eslint operator-linebreak: [2, "before"] */
8039
8084
  out += hexTable[0xF0 | (c >> 18)]
8040
8085
  + hexTable[0x80 | ((c >> 12) & 0x3F)]
8041
8086
  + hexTable[0x80 | ((c >> 6) & 0x3F)]
@@ -8125,6 +8170,7 @@
8125
8170
  };
8126
8171
 
8127
8172
  var isArray$1 = Array.isArray;
8173
+ var split = String.prototype.split;
8128
8174
  var push = Array.prototype.push;
8129
8175
  var pushToArray = function (arr, valueOrArray) {
8130
8176
  push.apply(arr, isArray$1(valueOrArray) ? valueOrArray : [valueOrArray]);
@@ -8202,6 +8248,14 @@
8202
8248
  if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
8203
8249
  if (encoder) {
8204
8250
  var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);
8251
+ if (generateArrayPrefix === 'comma' && encodeValuesOnly) {
8252
+ var valuesArray = split.call(String(obj), ',');
8253
+ var valuesJoined = '';
8254
+ for (var i = 0; i < valuesArray.length; ++i) {
8255
+ valuesJoined += (i === 0 ? '' : ',') + formatter(encoder(valuesArray[i], defaults.encoder, charset, 'value', format));
8256
+ }
8257
+ return [formatter(keyValue) + '=' + valuesJoined];
8258
+ }
8205
8259
  return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
8206
8260
  }
8207
8261
  return [formatter(prefix) + '=' + formatter(String(obj))];
@@ -8216,7 +8270,7 @@
8216
8270
  var objKeys;
8217
8271
  if (generateArrayPrefix === 'comma' && isArray$1(obj)) {
8218
8272
  // we need to join elements in
8219
- objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : undefined }];
8273
+ objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];
8220
8274
  } else if (isArray$1(filter)) {
8221
8275
  objKeys = filter;
8222
8276
  } else {
@@ -8224,9 +8278,9 @@
8224
8278
  objKeys = sort ? keys.sort(sort) : keys;
8225
8279
  }
8226
8280
 
8227
- for (var i = 0; i < objKeys.length; ++i) {
8228
- var key = objKeys[i];
8229
- var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key];
8281
+ for (var j = 0; j < objKeys.length; ++j) {
8282
+ var key = objKeys[j];
8283
+ var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key];
8230
8284
 
8231
8285
  if (skipNulls && value === null) {
8232
8286
  continue;
@@ -8262,7 +8316,7 @@
8262
8316
  return defaults;
8263
8317
  }
8264
8318
 
8265
- if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') {
8319
+ if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') {
8266
8320
  throw new TypeError('Encoder has to be a function.');
8267
8321
  }
8268
8322
 
@@ -8517,7 +8571,7 @@
8517
8571
  ) {
8518
8572
  obj = [];
8519
8573
  obj[index] = leaf;
8520
- } else {
8574
+ } else if (cleanRoot !== '__proto__') {
8521
8575
  obj[cleanRoot] = leaf;
8522
8576
  }
8523
8577
  }
@@ -9045,8 +9099,9 @@
9045
9099
  }
9046
9100
  }));
9047
9101
  _defineProperty(_assertThisInitialized(_this), "scheduleRender", defer(function () {
9102
+ var _this$mainHelper;
9048
9103
  var shouldResetStatus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
9049
- if (!_this.mainHelper.hasPendingRequests()) {
9104
+ if (!((_this$mainHelper = _this.mainHelper) !== null && _this$mainHelper !== void 0 && _this$mainHelper.hasPendingRequests())) {
9050
9105
  clearTimeout(_this._searchStalledTimer);
9051
9106
  _this._searchStalledTimer = null;
9052
9107
  if (shouldResetStatus) {
@@ -9314,12 +9369,7 @@
9314
9369
  var mainHelper = this.mainHelper || algoliasearchHelper_1(this.client, this.indexName);
9315
9370
  mainHelper.search = function () {
9316
9371
  _this3.status = 'loading';
9317
- // @MAJOR: use scheduleRender here
9318
- // For now, widgets don't expect to be rendered at the start of `loading`,
9319
- // so it would be a breaking change to add an extra render. We don't have
9320
- // these guarantees about the render event, thus emitting it once more
9321
- // isn't a breaking change.
9322
- _this3.emit('render');
9372
+ _this3.scheduleRender(false);
9323
9373
 
9324
9374
  // This solution allows us to keep the exact same API for the users but
9325
9375
  // under the hood, we have a different implementation. It should be
@@ -10115,7 +10165,8 @@
10115
10165
  if (!bindEvent) {
10116
10166
  bindEvent = createBindEventForHits({
10117
10167
  index: helper.getIndex(),
10118
- widgetType: this.$$type
10168
+ widgetType: this.$$type,
10169
+ instantSearchInstance: instantSearchInstance
10119
10170
  });
10120
10171
  }
10121
10172
  if (!results) {
@@ -10587,7 +10638,8 @@
10587
10638
  });
10588
10639
  bindEvent = createBindEventForHits({
10589
10640
  index: helper.getIndex(),
10590
- widgetType: this.$$type
10641
+ widgetType: this.$$type,
10642
+ instantSearchInstance: instantSearchInstance
10591
10643
  });
10592
10644
  isFirstPage = state.page === undefined || getFirstReceivedPage(state, cachedHits) === 0;
10593
10645
  } else {
@@ -10601,7 +10653,7 @@
10601
10653
  var transformedHits = transformItems(hitsWithAbsolutePositionAndQueryID, {
10602
10654
  results: results
10603
10655
  });
10604
- if (cachedHits[_page] === undefined && !results.__isArtificial) {
10656
+ if (cachedHits[_page] === undefined && !results.__isArtificial && instantSearchInstance.status === 'idle') {
10605
10657
  cachedHits[_page] = transformedHits;
10606
10658
  cache.write({
10607
10659
  state: state,
@@ -14152,8 +14204,7 @@
14152
14204
  var defaultTemplate = defaultTemplates ? defaultTemplates[key] : undefined;
14153
14205
  var customTemplate = templates[key];
14154
14206
  var isCustomTemplate = customTemplate !== undefined && customTemplate !== defaultTemplate;
14155
- config.templates[key] = isCustomTemplate ? customTemplate // typescript doesn't recognize that this condition asserts customTemplate is defined
14156
- : defaultTemplate;
14207
+ config.templates[key] = isCustomTemplate ? customTemplate : defaultTemplate;
14157
14208
  config.useCustomCompileOptions[key] = isCustomTemplate;
14158
14209
  return config;
14159
14210
  }, {
@@ -15279,6 +15330,9 @@
15279
15330
  Snippet: Snippet$1,
15280
15331
  ReverseSnippet: ReverseSnippet$1
15281
15332
  };
15333
+
15334
+ // @MAJOR remove the `as any` when string templates are removed
15335
+ // needed because not every template receives sendEvent
15282
15336
  return template(data, params);
15283
15337
  }
15284
15338
  var transformedHelpers = transformHelpersToHogan(helpers, compileOptions, data);
@@ -17165,7 +17219,8 @@
17165
17219
  results = _ref2.results,
17166
17220
  instantSearchInstance = _ref2.instantSearchInstance,
17167
17221
  insights = _ref2.insights,
17168
- bindEvent = _ref2.bindEvent;
17222
+ bindEvent = _ref2.bindEvent,
17223
+ sendEvent = _ref2.sendEvent;
17169
17224
  if (isFirstRendering) {
17170
17225
  renderState.templateProps = prepareTemplateProps({
17171
17226
  defaultTemplates: defaultTemplates$5,
@@ -17180,9 +17235,7 @@
17180
17235
  results: results,
17181
17236
  templateProps: renderState.templateProps,
17182
17237
  insights: insights,
17183
- sendEvent: function sendEvent(event) {
17184
- instantSearchInstance.sendEventToInsights(event);
17185
- },
17238
+ sendEvent: sendEvent,
17186
17239
  bindEvent: bindEvent
17187
17240
  }), containerNode);
17188
17241
  };
@@ -17403,7 +17456,8 @@
17403
17456
  isLastPage = _ref2.isLastPage,
17404
17457
  instantSearchInstance = _ref2.instantSearchInstance,
17405
17458
  insights = _ref2.insights,
17406
- bindEvent = _ref2.bindEvent;
17459
+ bindEvent = _ref2.bindEvent,
17460
+ sendEvent = _ref2.sendEvent;
17407
17461
  if (isFirstRendering) {
17408
17462
  renderState.templateProps = prepareTemplateProps({
17409
17463
  defaultTemplates: defaultTemplates$6,
@@ -17423,9 +17477,7 @@
17423
17477
  isFirstPage: isFirstPage,
17424
17478
  isLastPage: isLastPage,
17425
17479
  insights: insights,
17426
- sendEvent: function sendEvent(event) {
17427
- instantSearchInstance.sendEventToInsights(event);
17428
- },
17480
+ sendEvent: sendEvent,
17429
17481
  bindEvent: bindEvent
17430
17482
  }), containerNode);
17431
17483
  };
@@ -17902,7 +17954,7 @@
17902
17954
  }), props.pages.map(function (pageNumber) {
17903
17955
  return h(PaginationLink, {
17904
17956
  key: pageNumber,
17905
- ariaLabel: "".concat(pageNumber + 1),
17957
+ ariaLabel: "Page ".concat(pageNumber + 1),
17906
17958
  className: props.cssClasses.pageItem,
17907
17959
  isSelected: pageNumber === props.currentPage,
17908
17960
  label: "".concat(pageNumber + 1),