instantsearch.js 4.32.0 → 4.34.0

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 (55) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +24 -1
  3. package/cjs/connectors/autocomplete/connectAutocomplete.js +2 -1
  4. package/cjs/connectors/infinite-hits/connectInfiniteHits.js +1 -1
  5. package/cjs/connectors/numeric-menu/connectNumericMenu.js +6 -4
  6. package/cjs/connectors/pagination/connectPagination.js +3 -3
  7. package/cjs/connectors/powered-by/connectPoweredBy.js +13 -4
  8. package/cjs/connectors/search-box/connectSearchBox.js +4 -3
  9. package/cjs/connectors/sort-by/connectSortBy.js +2 -1
  10. package/cjs/connectors/stats/connectStats.js +4 -4
  11. package/cjs/connectors/toggle-refinement/connectToggleRefinement.js +1 -1
  12. package/cjs/lib/InstantSearch.js +26 -3
  13. package/cjs/lib/infiniteHitsCache/sessionStorage.js +16 -12
  14. package/cjs/lib/routers/history.js +89 -42
  15. package/cjs/lib/utils/detect-insights-client.js +10 -1
  16. package/cjs/lib/utils/index.js +10 -1
  17. package/cjs/lib/utils/safelyRunOnBrowser.js +30 -0
  18. package/cjs/lib/version.js +1 -1
  19. package/cjs/lib/voiceSearchHelper/index.js +5 -0
  20. package/cjs/middlewares/createMetadataMiddleware.js +12 -3
  21. package/cjs/widgets/index/index.js +21 -3
  22. package/dist/instantsearch.development.d.ts +21 -2
  23. package/dist/instantsearch.development.js +227 -88
  24. package/dist/instantsearch.development.js.map +1 -1
  25. package/dist/instantsearch.development.min.d.ts +21 -2
  26. package/dist/instantsearch.production.d.ts +21 -2
  27. package/dist/instantsearch.production.min.d.ts +21 -2
  28. package/dist/instantsearch.production.min.js +2 -2
  29. package/dist/instantsearch.production.min.js.map +1 -1
  30. package/es/connectors/autocomplete/connectAutocomplete.js +2 -1
  31. package/es/connectors/infinite-hits/connectInfiniteHits.js +1 -1
  32. package/es/connectors/numeric-menu/connectNumericMenu.js +6 -4
  33. package/es/connectors/pagination/connectPagination.js +3 -3
  34. package/es/connectors/powered-by/connectPoweredBy.js +14 -5
  35. package/es/connectors/search-box/connectSearchBox.js +4 -3
  36. package/es/connectors/sort-by/connectSortBy.js +2 -1
  37. package/es/connectors/stats/connectStats.js +4 -4
  38. package/es/connectors/toggle-refinement/connectToggleRefinement.js +1 -1
  39. package/es/lib/InstantSearch.d.ts +2 -1
  40. package/es/lib/InstantSearch.js +26 -3
  41. package/es/lib/infiniteHitsCache/sessionStorage.js +17 -14
  42. package/es/lib/routers/history.d.ts +13 -2
  43. package/es/lib/routers/history.js +88 -42
  44. package/es/lib/utils/detect-insights-client.js +9 -1
  45. package/es/lib/utils/index.d.ts +1 -0
  46. package/es/lib/utils/index.js +2 -1
  47. package/es/lib/utils/safelyRunOnBrowser.d.ts +14 -0
  48. package/es/lib/utils/safelyRunOnBrowser.js +23 -0
  49. package/es/lib/version.d.ts +1 -1
  50. package/es/lib/version.js +1 -1
  51. package/es/lib/voiceSearchHelper/index.js +5 -0
  52. package/es/middlewares/createMetadataMiddleware.js +12 -3
  53. package/es/types/results.d.ts +7 -0
  54. package/es/widgets/index/index.js +21 -3
  55. package/package.json +5 -5
@@ -1,4 +1,4 @@
1
- /*! InstantSearch.js 4.32.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch.js */
1
+ /*! InstantSearch.js 4.34.0 | © 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) :
@@ -7909,6 +7909,30 @@
7909
7909
  return attribute;
7910
7910
  }
7911
7911
 
7912
+ // eslint-disable-next-line no-restricted-globals
7913
+
7914
+ /**
7915
+ * Runs code on browser enviromnents safely.
7916
+ */
7917
+ function safelyRunOnBrowser(callback) {
7918
+ var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
7919
+ fallback: function fallback() {
7920
+ return undefined;
7921
+ }
7922
+ },
7923
+ fallback = _ref.fallback;
7924
+
7925
+ // eslint-disable-next-line no-restricted-globals
7926
+ if (typeof window === 'undefined') {
7927
+ return fallback();
7928
+ } // eslint-disable-next-line no-restricted-globals
7929
+
7930
+
7931
+ return callback({
7932
+ window: window
7933
+ });
7934
+ }
7935
+
7912
7936
  var withUsage = createDocumentationMessageGenerator({
7913
7937
  name: 'index-widget'
7914
7938
  });
@@ -8162,7 +8186,8 @@
8162
8186
  return this;
8163
8187
  },
8164
8188
  init: function init(_ref2) {
8165
- var _this3 = this;
8189
+ var _this3 = this,
8190
+ _instantSearchInstanc;
8166
8191
 
8167
8192
  var instantSearchInstance = _ref2.instantSearchInstance,
8168
8193
  parent = _ref2.parent,
@@ -8220,11 +8245,21 @@
8220
8245
 
8221
8246
  derivedHelper = mainHelper.derive(function () {
8222
8247
  return merge$1.apply(void 0, _toConsumableArray(resolveSearchParameters(_this3)));
8223
- }); // Subscribe to the Helper state changes for the page before widgets
8248
+ });
8249
+ var indexInitialResults = (_instantSearchInstanc = instantSearchInstance._initialResults) === null || _instantSearchInstanc === void 0 ? void 0 : _instantSearchInstanc[this.getIndexId()];
8250
+
8251
+ if (indexInitialResults) {
8252
+ // We restore the shape of the results provided to the instance to respect
8253
+ // the helper's structure.
8254
+ var results = new algoliasearchHelper_1.SearchResults(new algoliasearchHelper_1.SearchParameters(indexInitialResults.state), indexInitialResults.results);
8255
+ derivedHelper.lastResults = results;
8256
+ helper.lastResults = results;
8257
+ } // Subscribe to the Helper state changes for the page before widgets
8224
8258
  // are initialized. This behavior mimics the original one of the Helper.
8225
8259
  // It makes sense to replicate it at the `init` step. We have another
8226
8260
  // listener on `change` below, once `init` is done.
8227
8261
 
8262
+
8228
8263
  helper.on('change', function (_ref3) {
8229
8264
  var isPageReset = _ref3.isPageReset;
8230
8265
 
@@ -8325,6 +8360,13 @@
8325
8360
  instantSearchInstance.onInternalStateChange();
8326
8361
  }
8327
8362
  });
8363
+
8364
+ if (indexInitialResults) {
8365
+ // If there are initial results, we're not notified of the next results
8366
+ // because we don't trigger an initial search. We therefore need to directly
8367
+ // schedule a render that will render the results injected on the helper.
8368
+ instantSearchInstance.scheduleRender();
8369
+ }
8328
8370
  },
8329
8371
  render: function render(_ref5) {
8330
8372
  var _this4 = this;
@@ -8428,7 +8470,7 @@
8428
8470
  localUiState = getLocalWidgetsUiState(localWidgets, {
8429
8471
  searchParameters: this.getHelper().state,
8430
8472
  helper: this.getHelper()
8431
- });
8473
+ }, localUiState);
8432
8474
  }
8433
8475
  };
8434
8476
  };
@@ -8441,7 +8483,7 @@
8441
8483
  instantSearchInstance.renderState = _objectSpread2(_objectSpread2({}, instantSearchInstance.renderState), {}, _defineProperty({}, parentIndexName, _objectSpread2(_objectSpread2({}, instantSearchInstance.renderState[parentIndexName]), renderState)));
8442
8484
  }
8443
8485
 
8444
- var version$1 = '4.32.0';
8486
+ var version$1 = '4.34.0';
8445
8487
 
8446
8488
  var NAMESPACE = 'ais';
8447
8489
  var component = function component(componentName) {
@@ -9509,6 +9551,8 @@
9509
9551
 
9510
9552
  var setWindowTitle = function setWindowTitle(title) {
9511
9553
  if (title) {
9554
+ // This function is only executed on browsers so we can disable this check.
9555
+ // eslint-disable-next-line no-restricted-globals
9512
9556
  window.document.title = title;
9513
9557
  }
9514
9558
  };
@@ -9519,11 +9563,14 @@
9519
9563
  * using web APIs (`window.location.pushState` and `onpopstate` event).
9520
9564
  */
9521
9565
  function BrowserHistory(_ref) {
9566
+ var _this = this;
9567
+
9522
9568
  var windowTitle = _ref.windowTitle,
9523
9569
  _ref$writeDelay = _ref.writeDelay,
9524
9570
  writeDelay = _ref$writeDelay === void 0 ? 400 : _ref$writeDelay,
9525
9571
  createURL = _ref.createURL,
9526
- parseURL = _ref.parseURL;
9572
+ parseURL = _ref.parseURL,
9573
+ getLocation = _ref.getLocation;
9527
9574
 
9528
9575
  _classCallCheck(this, BrowserHistory);
9529
9576
 
@@ -9535,15 +9582,23 @@
9535
9582
 
9536
9583
  _defineProperty(this, "parseURL", void 0);
9537
9584
 
9585
+ _defineProperty(this, "getLocation", void 0);
9586
+
9538
9587
  _defineProperty(this, "writeTimer", void 0);
9539
9588
 
9589
+ _defineProperty(this, "shouldPushState", true);
9590
+
9540
9591
  this.windowTitle = windowTitle;
9541
9592
  this.writeTimer = undefined;
9542
9593
  this.writeDelay = writeDelay;
9543
9594
  this._createURL = createURL;
9544
9595
  this.parseURL = parseURL;
9545
- var title = this.windowTitle && this.windowTitle(this.read());
9546
- setWindowTitle(title);
9596
+ this.getLocation = getLocation;
9597
+ safelyRunOnBrowser(function () {
9598
+ var title = _this.windowTitle && _this.windowTitle(_this.read());
9599
+
9600
+ setWindowTitle(title);
9601
+ });
9547
9602
  }
9548
9603
  /**
9549
9604
  * Reads the URL and returns a syncable UI search state.
@@ -9555,7 +9610,7 @@
9555
9610
  value: function read() {
9556
9611
  return this.parseURL({
9557
9612
  qsModule: lib$1,
9558
- location: window.location
9613
+ location: this.getLocation()
9559
9614
  });
9560
9615
  }
9561
9616
  /**
@@ -9565,20 +9620,30 @@
9565
9620
  }, {
9566
9621
  key: "write",
9567
9622
  value: function write(routeState) {
9568
- var _this = this;
9623
+ var _this2 = this;
9569
9624
 
9570
- var url = this.createURL(routeState);
9571
- var title = this.windowTitle && this.windowTitle(routeState);
9625
+ safelyRunOnBrowser(function (_ref2) {
9626
+ var window = _ref2.window;
9572
9627
 
9573
- if (this.writeTimer) {
9574
- window.clearTimeout(this.writeTimer);
9575
- }
9628
+ var url = _this2.createURL(routeState);
9576
9629
 
9577
- this.writeTimer = window.setTimeout(function () {
9578
- setWindowTitle(title);
9579
- window.history.pushState(routeState, title || '', url);
9580
- _this.writeTimer = undefined;
9581
- }, this.writeDelay);
9630
+ var title = _this2.windowTitle && _this2.windowTitle(routeState);
9631
+
9632
+ if (_this2.writeTimer) {
9633
+ clearTimeout(_this2.writeTimer);
9634
+ }
9635
+
9636
+ _this2.writeTimer = setTimeout(function () {
9637
+ setWindowTitle(title);
9638
+
9639
+ if (_this2.shouldPushState) {
9640
+ window.history.pushState(routeState, title || '', url);
9641
+ }
9642
+
9643
+ _this2.shouldPushState = true;
9644
+ _this2.writeTimer = undefined;
9645
+ }, _this2.writeDelay);
9646
+ });
9582
9647
  }
9583
9648
  /**
9584
9649
  * Sets a callback on the `onpopstate` event of the history API of the current page.
@@ -9588,26 +9653,30 @@
9588
9653
  }, {
9589
9654
  key: "onUpdate",
9590
9655
  value: function onUpdate(callback) {
9591
- var _this2 = this;
9656
+ var _this3 = this;
9592
9657
 
9593
9658
  this._onPopState = function (event) {
9594
- if (_this2.writeTimer) {
9595
- window.clearTimeout(_this2.writeTimer);
9596
- _this2.writeTimer = undefined;
9659
+ if (_this3.writeTimer) {
9660
+ clearTimeout(_this3.writeTimer);
9661
+ _this3.writeTimer = undefined;
9597
9662
  }
9598
9663
 
9664
+ _this3.shouldPushState = false;
9599
9665
  var routeState = event.state; // At initial load, the state is read from the URL without update.
9600
9666
  // Therefore the state object is not available.
9601
9667
  // In this case, we fallback and read the URL.
9602
9668
 
9603
9669
  if (!routeState) {
9604
- callback(_this2.read());
9670
+ callback(_this3.read());
9605
9671
  } else {
9606
9672
  callback(routeState);
9607
9673
  }
9608
9674
  };
9609
9675
 
9610
- window.addEventListener('popstate', this._onPopState);
9676
+ safelyRunOnBrowser(function (_ref3) {
9677
+ var window = _ref3.window;
9678
+ window.addEventListener('popstate', _this3._onPopState);
9679
+ });
9611
9680
  }
9612
9681
  /**
9613
9682
  * Creates a complete URL from a given syncable UI state.
@@ -9623,7 +9692,7 @@
9623
9692
  return this._createURL({
9624
9693
  qsModule: lib$1,
9625
9694
  routeState: routeState,
9626
- location: window.location
9695
+ location: this.getLocation()
9627
9696
  });
9628
9697
  }
9629
9698
  /**
@@ -9633,12 +9702,18 @@
9633
9702
  }, {
9634
9703
  key: "dispose",
9635
9704
  value: function dispose() {
9636
- if (this._onPopState) {
9637
- window.removeEventListener('popstate', this._onPopState);
9638
- }
9705
+ var _this4 = this;
9706
+
9707
+ safelyRunOnBrowser(function (_ref4) {
9708
+ var window = _ref4.window;
9709
+
9710
+ if (_this4._onPopState) {
9711
+ window.removeEventListener('popstate', _this4._onPopState);
9712
+ }
9713
+ });
9639
9714
 
9640
9715
  if (this.writeTimer) {
9641
- window.clearTimeout(this.writeTimer);
9716
+ clearTimeout(this.writeTimer);
9642
9717
  }
9643
9718
 
9644
9719
  this.write({});
@@ -9649,12 +9724,12 @@
9649
9724
  }();
9650
9725
 
9651
9726
  function historyRouter() {
9652
- var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
9653
- _ref2$createURL = _ref2.createURL,
9654
- createURL = _ref2$createURL === void 0 ? function (_ref3) {
9655
- var qsModule = _ref3.qsModule,
9656
- routeState = _ref3.routeState,
9657
- location = _ref3.location;
9727
+ var _ref5 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
9728
+ _ref5$createURL = _ref5.createURL,
9729
+ createURL = _ref5$createURL === void 0 ? function (_ref6) {
9730
+ var qsModule = _ref6.qsModule,
9731
+ routeState = _ref6.routeState,
9732
+ location = _ref6.location;
9658
9733
  var protocol = location.protocol,
9659
9734
  hostname = location.hostname,
9660
9735
  _location$port = location.port,
@@ -9670,11 +9745,11 @@
9670
9745
  }
9671
9746
 
9672
9747
  return "".concat(protocol, "//").concat(hostname).concat(portWithPrefix).concat(pathname, "?").concat(queryString).concat(hash);
9673
- } : _ref2$createURL,
9674
- _ref2$parseURL = _ref2.parseURL,
9675
- parseURL = _ref2$parseURL === void 0 ? function (_ref4) {
9676
- var qsModule = _ref4.qsModule,
9677
- location = _ref4.location;
9748
+ } : _ref5$createURL,
9749
+ _ref5$parseURL = _ref5.parseURL,
9750
+ parseURL = _ref5$parseURL === void 0 ? function (_ref7) {
9751
+ var qsModule = _ref7.qsModule,
9752
+ location = _ref7.location;
9678
9753
  // `qs` by default converts arrays with more than 20 items to an object.
9679
9754
  // We want to avoid this because the data structure manipulated can therefore vary.
9680
9755
  // Setting the limit to `100` seems a good number because the engine's default is 100
@@ -9688,16 +9763,28 @@
9688
9763
  return qsModule.parse(location.search.slice(1), {
9689
9764
  arrayLimit: 99
9690
9765
  });
9691
- } : _ref2$parseURL,
9692
- _ref2$writeDelay = _ref2.writeDelay,
9693
- writeDelay = _ref2$writeDelay === void 0 ? 400 : _ref2$writeDelay,
9694
- windowTitle = _ref2.windowTitle;
9766
+ } : _ref5$parseURL,
9767
+ _ref5$writeDelay = _ref5.writeDelay,
9768
+ writeDelay = _ref5$writeDelay === void 0 ? 400 : _ref5$writeDelay,
9769
+ windowTitle = _ref5.windowTitle,
9770
+ _ref5$getLocation = _ref5.getLocation,
9771
+ getLocation = _ref5$getLocation === void 0 ? function () {
9772
+ return safelyRunOnBrowser(function (_ref8) {
9773
+ var window = _ref8.window;
9774
+ return window.location;
9775
+ }, {
9776
+ fallback: function fallback() {
9777
+ throw new Error('You need to provide `getLocation` to the `history` router in environments where `window` does not exist.');
9778
+ }
9779
+ });
9780
+ } : _ref5$getLocation;
9695
9781
 
9696
9782
  return new BrowserHistory({
9697
9783
  createURL: createURL,
9698
9784
  parseURL: parseURL,
9699
9785
  writeDelay: writeDelay,
9700
- windowTitle: windowTitle
9786
+ windowTitle: windowTitle,
9787
+ getLocation: getLocation
9701
9788
  });
9702
9789
  }
9703
9790
 
@@ -9791,7 +9878,14 @@
9791
9878
  }
9792
9879
 
9793
9880
  function isMetadataEnabled() {
9794
- return typeof window !== 'undefined' && window.navigator.userAgent.indexOf('Algolia Crawler') > -1;
9881
+ return safelyRunOnBrowser(function (_ref) {
9882
+ var window = _ref.window;
9883
+ return window.navigator.userAgent.indexOf('Algolia Crawler') > -1;
9884
+ }, {
9885
+ fallback: function fallback() {
9886
+ return false;
9887
+ }
9888
+ });
9795
9889
  }
9796
9890
  /**
9797
9891
  * Exposes the metadata of mounted widgets in a custom
@@ -9802,8 +9896,8 @@
9802
9896
  */
9803
9897
 
9804
9898
  function createMetadataMiddleware() {
9805
- return function (_ref) {
9806
- var instantSearchInstance = _ref.instantSearchInstance;
9899
+ return function (_ref2) {
9900
+ var instantSearchInstance = _ref2.instantSearchInstance;
9807
9901
  var payload = {
9808
9902
  widgets: []
9809
9903
  };
@@ -9886,6 +9980,8 @@
9886
9980
 
9887
9981
  _defineProperty(_assertThisInitialized(_this), "_initialUiState", void 0);
9888
9982
 
9983
+ _defineProperty(_assertThisInitialized(_this), "_initialResults", void 0);
9984
+
9889
9985
  _defineProperty(_assertThisInitialized(_this), "_createURL", void 0);
9890
9986
 
9891
9987
  _defineProperty(_assertThisInitialized(_this), "_searchFunction", void 0);
@@ -9990,6 +10086,7 @@
9990
10086
  _this._isSearchStalled = false;
9991
10087
  _this._createURL = defaultCreateURL;
9992
10088
  _this._initialUiState = initialUiState;
10089
+ _this._initialResults = null;
9993
10090
 
9994
10091
  if (searchFunction) {
9995
10092
  _this._searchFunction = searchFunction;
@@ -10232,9 +10329,27 @@
10232
10329
  parent: null,
10233
10330
  uiState: this._initialUiState
10234
10331
  });
10235
- this.scheduleSearch(); // Keep the previous reference for legacy purpose, some pattern use
10332
+
10333
+ if (this._initialResults) {
10334
+ var originalScheduleSearch = this.scheduleSearch; // We don't schedule a first search when initial results are provided
10335
+ // because we already have the results to render. This skips the initial
10336
+ // network request on the browser on `start`.
10337
+
10338
+ this.scheduleSearch = defer(noop); // We also skip the initial network request when widgets are dynamically
10339
+ // added in the first tick (that's the case in all the framework-based flavors).
10340
+ // When we add a widget to `index`, it calls `scheduleSearch`. We can rely
10341
+ // on our `defer` util to restore the original `scheduleSearch` value once
10342
+ // widgets are added to hook back to the regular lifecycle.
10343
+
10344
+ defer(function () {
10345
+ _this3.scheduleSearch = originalScheduleSearch;
10346
+ })();
10347
+ } else {
10348
+ this.scheduleSearch();
10349
+ } // Keep the previous reference for legacy purpose, some pattern use
10236
10350
  // the direct Helper access `search.helper` (e.g multi-index).
10237
10351
 
10352
+
10238
10353
  this.helper = this.mainIndex.getHelper(); // track we started the search if we add more widgets,
10239
10354
  // to init them directly after add
10240
10355
 
@@ -10296,15 +10411,17 @@
10296
10411
  var nextUiState = typeof uiState === 'function' ? uiState(this.mainIndex.getWidgetUiState({})) : uiState;
10297
10412
 
10298
10413
  var setIndexHelperState = function setIndexHelperState(indexWidget) {
10414
+ var nextIndexUiState = nextUiState[indexWidget.getIndexId()] || {};
10415
+
10299
10416
  {
10300
10417
  checkIndexUiState({
10301
10418
  index: indexWidget,
10302
- indexUiState: nextUiState[indexWidget.getIndexId()]
10419
+ indexUiState: nextIndexUiState
10303
10420
  });
10304
10421
  }
10305
10422
 
10306
10423
  indexWidget.getHelper().setState(indexWidget.getWidgetSearchParameters(indexWidget.getHelper().state, {
10307
- uiState: nextUiState[indexWidget.getIndexId()]
10424
+ uiState: nextIndexUiState
10308
10425
  }));
10309
10426
  indexWidget.getWidgets().filter(isIndexWidget).forEach(setIndexHelperState);
10310
10427
  };
@@ -11485,7 +11602,7 @@
11485
11602
  index: helper.getIndex(),
11486
11603
  widgetType: this.$$type
11487
11604
  });
11488
- isFirstPage = helper.state.page === undefined || getFirstReceivedPage(helper.state, cachedHits) === 0;
11605
+ isFirstPage = state.page === undefined || getFirstReceivedPage(state, cachedHits) === 0;
11489
11606
  } else {
11490
11607
  var _state$page3 = state.page,
11491
11608
  _page = _state$page3 === void 0 ? 0 : _state$page3;
@@ -11990,6 +12107,8 @@
11990
12107
  if (option.start !== undefined && option.end !== undefined) {
11991
12108
  if (option.start === option.end) {
11992
12109
  return hasNumericRefinement(currentRefinements, '=', option.start);
12110
+ } else {
12111
+ return hasNumericRefinement(currentRefinements, '>=', option.start) && hasNumericRefinement(currentRefinements, '<=', option.end);
11993
12112
  }
11994
12113
  }
11995
12114
 
@@ -12043,17 +12162,17 @@
12043
12162
  if (refinedOption.start !== undefined) {
12044
12163
  if (hasNumericRefinement(currentRefinements, '>=', refinedOption.start)) {
12045
12164
  resolvedState = resolvedState.removeNumericRefinement(attribute, '>=', refinedOption.start);
12046
- } else {
12047
- resolvedState = resolvedState.addNumericRefinement(attribute, '>=', refinedOption.start);
12048
12165
  }
12166
+
12167
+ resolvedState = resolvedState.addNumericRefinement(attribute, '>=', refinedOption.start);
12049
12168
  }
12050
12169
 
12051
12170
  if (refinedOption.end !== undefined) {
12052
12171
  if (hasNumericRefinement(currentRefinements, '<=', refinedOption.end)) {
12053
12172
  resolvedState = resolvedState.removeNumericRefinement(attribute, '<=', refinedOption.end);
12054
- } else {
12055
- resolvedState = resolvedState.addNumericRefinement(attribute, '<=', refinedOption.end);
12056
12173
  }
12174
+
12175
+ resolvedState = resolvedState.addNumericRefinement(attribute, '<=', refinedOption.end);
12057
12176
  }
12058
12177
 
12059
12178
  if (typeof resolvedState.page === 'number') {
@@ -12211,6 +12330,7 @@
12211
12330
  getWidgetRenderState: function getWidgetRenderState(_ref6) {
12212
12331
  var results = _ref6.results,
12213
12332
  helper = _ref6.helper,
12333
+ state = _ref6.state,
12214
12334
  createURL = _ref6.createURL;
12215
12335
 
12216
12336
  if (!connectorState.refine) {
@@ -12221,14 +12341,13 @@
12221
12341
  }
12222
12342
 
12223
12343
  if (!connectorState.createURL) {
12224
- connectorState.createURL = function (state) {
12344
+ connectorState.createURL = function (helperState) {
12225
12345
  return function (page) {
12226
- return createURL(state.setPage(page));
12346
+ return createURL(helperState.setPage(page));
12227
12347
  };
12228
12348
  };
12229
12349
  }
12230
12350
 
12231
- var state = helper.state;
12232
12351
  var page = state.page || 0;
12233
12352
  var nbPages = getMaxPage(results || {
12234
12353
  nbPages: 0
@@ -12948,11 +13067,12 @@
12948
13067
  },
12949
13068
  getWidgetRenderState: function getWidgetRenderState(_ref3) {
12950
13069
  var helper = _ref3.helper,
12951
- searchMetadata = _ref3.searchMetadata;
13070
+ searchMetadata = _ref3.searchMetadata,
13071
+ state = _ref3.state;
12952
13072
 
12953
13073
  if (!_refine) {
12954
13074
  var setQueryAndSearch = function setQueryAndSearch(query) {
12955
- if (query !== helper.state.query) {
13075
+ if (query !== state.query) {
12956
13076
  helper.setQuery(query).search();
12957
13077
  }
12958
13078
  };
@@ -12969,7 +13089,7 @@
12969
13089
 
12970
13090
  _clear = clear(helper);
12971
13091
  return {
12972
- query: helper.state.query || '',
13092
+ query: state.query || '',
12973
13093
  refine: _refine,
12974
13094
  clear: _cachedClear,
12975
13095
  widgetParams: widgetParams,
@@ -13055,6 +13175,7 @@
13055
13175
  getWidgetRenderState: function getWidgetRenderState(_ref3) {
13056
13176
  var results = _ref3.results,
13057
13177
  helper = _ref3.helper,
13178
+ state = _ref3.state,
13058
13179
  parent = _ref3.parent;
13059
13180
 
13060
13181
  if (!connectorState.initialIndex && parent) {
@@ -13068,7 +13189,7 @@
13068
13189
  }
13069
13190
 
13070
13191
  return {
13071
- currentRefinement: helper.state.index,
13192
+ currentRefinement: state.index,
13072
13193
  options: transformItems(items),
13073
13194
  refine: connectorState.setIndex,
13074
13195
  hasNoResults: results ? results.nbHits === 0 : true,
@@ -13412,18 +13533,18 @@
13412
13533
  },
13413
13534
  getWidgetRenderState: function getWidgetRenderState(_ref) {
13414
13535
  var results = _ref.results,
13415
- helper = _ref.helper;
13536
+ state = _ref.state;
13416
13537
 
13417
13538
  if (!results) {
13418
13539
  return {
13419
- hitsPerPage: helper.state.hitsPerPage,
13540
+ hitsPerPage: state.hitsPerPage,
13420
13541
  nbHits: 0,
13421
13542
  nbSortedHits: undefined,
13422
13543
  areHitsSorted: false,
13423
13544
  nbPages: 0,
13424
- page: helper.state.page || 0,
13545
+ page: state.page || 0,
13425
13546
  processingTimeMS: -1,
13426
- query: helper.state.query || '',
13547
+ query: state.query || '',
13427
13548
  widgetParams: widgetParams
13428
13549
  };
13429
13550
  }
@@ -13616,7 +13737,7 @@
13616
13737
  createURL = _ref6.createURL,
13617
13738
  instantSearchInstance = _ref6.instantSearchInstance;
13618
13739
  var isRefined = results ? on.every(function (v) {
13619
- return helper.state.isDisjunctiveFacetRefined(attribute, v);
13740
+ return state.isDisjunctiveFacetRefined(attribute, v);
13620
13741
  }) : on.every(function (v) {
13621
13742
  return state.isDisjunctiveFacetRefined(attribute, v);
13622
13743
  });
@@ -14122,11 +14243,20 @@
14122
14243
  var connectPoweredBy = function connectPoweredBy(renderFn) {
14123
14244
  var unmountFn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
14124
14245
  checkRendering(renderFn, withUsage$k());
14125
- var defaultUrl = 'https://www.algolia.com/?' + 'utm_source=instantsearch.js&' + 'utm_medium=website&' + "utm_content=".concat(typeof window !== 'undefined' && window.location ? window.location.hostname : '', "&") + 'utm_campaign=poweredby';
14246
+ var defaultUrl = 'https://www.algolia.com/?' + 'utm_source=instantsearch.js&' + 'utm_medium=website&' + "utm_content=".concat(safelyRunOnBrowser(function (_ref) {
14247
+ var _window$location;
14248
+
14249
+ var window = _ref.window;
14250
+ return ((_window$location = window.location) === null || _window$location === void 0 ? void 0 : _window$location.hostname) || '';
14251
+ }, {
14252
+ fallback: function fallback() {
14253
+ return '';
14254
+ }
14255
+ }), "&") + 'utm_campaign=poweredby';
14126
14256
  return function (widgetParams) {
14127
- var _ref = widgetParams || {},
14128
- _ref$url = _ref.url,
14129
- url = _ref$url === void 0 ? defaultUrl : _ref$url;
14257
+ var _ref2 = widgetParams || {},
14258
+ _ref2$url = _ref2.url,
14259
+ url = _ref2$url === void 0 ? defaultUrl : _ref2$url;
14130
14260
 
14131
14261
  return {
14132
14262
  $$type: 'ais.poweredBy',
@@ -14375,6 +14505,7 @@
14375
14505
  var _this = this;
14376
14506
 
14377
14507
  var helper = _ref4.helper,
14508
+ state = _ref4.state,
14378
14509
  scopedResults = _ref4.scopedResults,
14379
14510
  instantSearchInstance = _ref4.instantSearchInstance;
14380
14511
 
@@ -14402,7 +14533,7 @@
14402
14533
  };
14403
14534
  });
14404
14535
  return {
14405
- currentRefinement: helper.state.query || '',
14536
+ currentRefinement: state.query || '',
14406
14537
  indices: indices,
14407
14538
  refine: connectorState.refine,
14408
14539
  widgetParams: widgetParams
@@ -14611,6 +14742,11 @@
14611
14742
  };
14612
14743
  };
14613
14744
 
14745
+ // `SpeechRecognition` is an API used on the browser so we can safely disable
14746
+ // the `window` check.
14747
+
14748
+ /* eslint-disable no-restricted-globals */
14749
+
14614
14750
  /* global SpeechRecognition SpeechRecognitionEvent */
14615
14751
  var createVoiceSearchHelper = function createVoiceSearchHelper(_ref) {
14616
14752
  var searchAsYouSpeak = _ref.searchAsYouSpeak,
@@ -21487,28 +21623,27 @@
21487
21623
  }
21488
21624
 
21489
21625
  var KEY = 'ais.infiniteHits';
21490
-
21491
- function hasSessionStorage() {
21492
- return typeof window !== 'undefined' && typeof window.sessionStorage !== 'undefined';
21493
- }
21494
-
21495
21626
  function createInfiniteHitsSessionStorageCache() {
21496
21627
  return {
21497
21628
  read: function read(_ref2) {
21498
21629
  var state = _ref2.state;
21630
+ var sessionStorage = safelyRunOnBrowser(function (_ref3) {
21631
+ var window = _ref3.window;
21632
+ return window.sessionStorage;
21633
+ });
21499
21634
 
21500
- if (!hasSessionStorage()) {
21635
+ if (!sessionStorage) {
21501
21636
  return null;
21502
21637
  }
21503
21638
 
21504
21639
  try {
21505
21640
  var cache = JSON.parse( // @ts-expect-error JSON.parse() requires a string, but it actually accepts null, too.
21506
- window.sessionStorage.getItem(KEY));
21641
+ sessionStorage.getItem(KEY));
21507
21642
  return cache && isEqual(cache.state, getStateWithoutPage$1(state)) ? cache.hits : null;
21508
21643
  } catch (error) {
21509
21644
  if (error instanceof SyntaxError) {
21510
21645
  try {
21511
- window.sessionStorage.removeItem(KEY);
21646
+ sessionStorage.removeItem(KEY);
21512
21647
  } catch (err) {// do nothing
21513
21648
  }
21514
21649
  }
@@ -21516,16 +21651,20 @@
21516
21651
  return null;
21517
21652
  }
21518
21653
  },
21519
- write: function write(_ref3) {
21520
- var state = _ref3.state,
21521
- hits = _ref3.hits;
21654
+ write: function write(_ref4) {
21655
+ var state = _ref4.state,
21656
+ hits = _ref4.hits;
21657
+ var sessionStorage = safelyRunOnBrowser(function (_ref5) {
21658
+ var window = _ref5.window;
21659
+ return window.sessionStorage;
21660
+ });
21522
21661
 
21523
- if (!hasSessionStorage()) {
21662
+ if (!sessionStorage) {
21524
21663
  return;
21525
21664
  }
21526
21665
 
21527
21666
  try {
21528
- window.sessionStorage.setItem(KEY, JSON.stringify({
21667
+ sessionStorage.setItem(KEY, JSON.stringify({
21529
21668
  state: getStateWithoutPage$1(state),
21530
21669
  hits: hits
21531
21670
  }));