instantsearch.js 4.32.0 → 4.33.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 (34) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/cjs/connectors/powered-by/connectPoweredBy.js +13 -4
  3. package/cjs/lib/InstantSearch.js +4 -2
  4. package/cjs/lib/infiniteHitsCache/sessionStorage.js +16 -12
  5. package/cjs/lib/routers/history.js +89 -42
  6. package/cjs/lib/utils/detect-insights-client.js +10 -1
  7. package/cjs/lib/utils/index.js +10 -1
  8. package/cjs/lib/utils/safelyRunOnBrowser.js +30 -0
  9. package/cjs/lib/version.js +1 -1
  10. package/cjs/lib/voiceSearchHelper/index.js +5 -0
  11. package/cjs/middlewares/createMetadataMiddleware.js +12 -3
  12. package/dist/instantsearch.development.d.ts +13 -2
  13. package/dist/instantsearch.development.js +161 -66
  14. package/dist/instantsearch.development.js.map +1 -1
  15. package/dist/instantsearch.development.min.d.ts +13 -2
  16. package/dist/instantsearch.production.d.ts +13 -2
  17. package/dist/instantsearch.production.min.d.ts +13 -2
  18. package/dist/instantsearch.production.min.js +2 -2
  19. package/dist/instantsearch.production.min.js.map +1 -1
  20. package/es/connectors/powered-by/connectPoweredBy.js +14 -5
  21. package/es/lib/InstantSearch.js +4 -2
  22. package/es/lib/infiniteHitsCache/sessionStorage.js +17 -14
  23. package/es/lib/routers/history.d.ts +13 -2
  24. package/es/lib/routers/history.js +88 -42
  25. package/es/lib/utils/detect-insights-client.js +9 -1
  26. package/es/lib/utils/index.d.ts +1 -0
  27. package/es/lib/utils/index.js +2 -1
  28. package/es/lib/utils/safelyRunOnBrowser.d.ts +14 -0
  29. package/es/lib/utils/safelyRunOnBrowser.js +23 -0
  30. package/es/lib/version.d.ts +1 -1
  31. package/es/lib/version.js +1 -1
  32. package/es/lib/voiceSearchHelper/index.js +5 -0
  33. package/es/middlewares/createMetadataMiddleware.js +12 -3
  34. package/package.json +2 -2
@@ -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.33.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
  });
@@ -8441,7 +8465,7 @@
8441
8465
  instantSearchInstance.renderState = _objectSpread2(_objectSpread2({}, instantSearchInstance.renderState), {}, _defineProperty({}, parentIndexName, _objectSpread2(_objectSpread2({}, instantSearchInstance.renderState[parentIndexName]), renderState)));
8442
8466
  }
8443
8467
 
8444
- var version$1 = '4.32.0';
8468
+ var version$1 = '4.33.0';
8445
8469
 
8446
8470
  var NAMESPACE = 'ais';
8447
8471
  var component = function component(componentName) {
@@ -9509,6 +9533,8 @@
9509
9533
 
9510
9534
  var setWindowTitle = function setWindowTitle(title) {
9511
9535
  if (title) {
9536
+ // This function is only executed on browsers so we can disable this check.
9537
+ // eslint-disable-next-line no-restricted-globals
9512
9538
  window.document.title = title;
9513
9539
  }
9514
9540
  };
@@ -9519,11 +9545,14 @@
9519
9545
  * using web APIs (`window.location.pushState` and `onpopstate` event).
9520
9546
  */
9521
9547
  function BrowserHistory(_ref) {
9548
+ var _this = this;
9549
+
9522
9550
  var windowTitle = _ref.windowTitle,
9523
9551
  _ref$writeDelay = _ref.writeDelay,
9524
9552
  writeDelay = _ref$writeDelay === void 0 ? 400 : _ref$writeDelay,
9525
9553
  createURL = _ref.createURL,
9526
- parseURL = _ref.parseURL;
9554
+ parseURL = _ref.parseURL,
9555
+ getLocation = _ref.getLocation;
9527
9556
 
9528
9557
  _classCallCheck(this, BrowserHistory);
9529
9558
 
@@ -9535,15 +9564,23 @@
9535
9564
 
9536
9565
  _defineProperty(this, "parseURL", void 0);
9537
9566
 
9567
+ _defineProperty(this, "getLocation", void 0);
9568
+
9538
9569
  _defineProperty(this, "writeTimer", void 0);
9539
9570
 
9571
+ _defineProperty(this, "shouldPushState", true);
9572
+
9540
9573
  this.windowTitle = windowTitle;
9541
9574
  this.writeTimer = undefined;
9542
9575
  this.writeDelay = writeDelay;
9543
9576
  this._createURL = createURL;
9544
9577
  this.parseURL = parseURL;
9545
- var title = this.windowTitle && this.windowTitle(this.read());
9546
- setWindowTitle(title);
9578
+ this.getLocation = getLocation;
9579
+ safelyRunOnBrowser(function () {
9580
+ var title = _this.windowTitle && _this.windowTitle(_this.read());
9581
+
9582
+ setWindowTitle(title);
9583
+ });
9547
9584
  }
9548
9585
  /**
9549
9586
  * Reads the URL and returns a syncable UI search state.
@@ -9555,7 +9592,7 @@
9555
9592
  value: function read() {
9556
9593
  return this.parseURL({
9557
9594
  qsModule: lib$1,
9558
- location: window.location
9595
+ location: this.getLocation()
9559
9596
  });
9560
9597
  }
9561
9598
  /**
@@ -9565,20 +9602,30 @@
9565
9602
  }, {
9566
9603
  key: "write",
9567
9604
  value: function write(routeState) {
9568
- var _this = this;
9605
+ var _this2 = this;
9569
9606
 
9570
- var url = this.createURL(routeState);
9571
- var title = this.windowTitle && this.windowTitle(routeState);
9607
+ safelyRunOnBrowser(function (_ref2) {
9608
+ var window = _ref2.window;
9572
9609
 
9573
- if (this.writeTimer) {
9574
- window.clearTimeout(this.writeTimer);
9575
- }
9610
+ var url = _this2.createURL(routeState);
9611
+
9612
+ var title = _this2.windowTitle && _this2.windowTitle(routeState);
9613
+
9614
+ if (_this2.writeTimer) {
9615
+ clearTimeout(_this2.writeTimer);
9616
+ }
9617
+
9618
+ _this2.writeTimer = setTimeout(function () {
9619
+ setWindowTitle(title);
9576
9620
 
9577
- this.writeTimer = window.setTimeout(function () {
9578
- setWindowTitle(title);
9579
- window.history.pushState(routeState, title || '', url);
9580
- _this.writeTimer = undefined;
9581
- }, this.writeDelay);
9621
+ if (_this2.shouldPushState) {
9622
+ window.history.pushState(routeState, title || '', url);
9623
+ }
9624
+
9625
+ _this2.shouldPushState = true;
9626
+ _this2.writeTimer = undefined;
9627
+ }, _this2.writeDelay);
9628
+ });
9582
9629
  }
9583
9630
  /**
9584
9631
  * Sets a callback on the `onpopstate` event of the history API of the current page.
@@ -9588,26 +9635,30 @@
9588
9635
  }, {
9589
9636
  key: "onUpdate",
9590
9637
  value: function onUpdate(callback) {
9591
- var _this2 = this;
9638
+ var _this3 = this;
9592
9639
 
9593
9640
  this._onPopState = function (event) {
9594
- if (_this2.writeTimer) {
9595
- window.clearTimeout(_this2.writeTimer);
9596
- _this2.writeTimer = undefined;
9641
+ if (_this3.writeTimer) {
9642
+ clearTimeout(_this3.writeTimer);
9643
+ _this3.writeTimer = undefined;
9597
9644
  }
9598
9645
 
9646
+ _this3.shouldPushState = false;
9599
9647
  var routeState = event.state; // At initial load, the state is read from the URL without update.
9600
9648
  // Therefore the state object is not available.
9601
9649
  // In this case, we fallback and read the URL.
9602
9650
 
9603
9651
  if (!routeState) {
9604
- callback(_this2.read());
9652
+ callback(_this3.read());
9605
9653
  } else {
9606
9654
  callback(routeState);
9607
9655
  }
9608
9656
  };
9609
9657
 
9610
- window.addEventListener('popstate', this._onPopState);
9658
+ safelyRunOnBrowser(function (_ref3) {
9659
+ var window = _ref3.window;
9660
+ window.addEventListener('popstate', _this3._onPopState);
9661
+ });
9611
9662
  }
9612
9663
  /**
9613
9664
  * Creates a complete URL from a given syncable UI state.
@@ -9623,7 +9674,7 @@
9623
9674
  return this._createURL({
9624
9675
  qsModule: lib$1,
9625
9676
  routeState: routeState,
9626
- location: window.location
9677
+ location: this.getLocation()
9627
9678
  });
9628
9679
  }
9629
9680
  /**
@@ -9633,12 +9684,18 @@
9633
9684
  }, {
9634
9685
  key: "dispose",
9635
9686
  value: function dispose() {
9636
- if (this._onPopState) {
9637
- window.removeEventListener('popstate', this._onPopState);
9638
- }
9687
+ var _this4 = this;
9688
+
9689
+ safelyRunOnBrowser(function (_ref4) {
9690
+ var window = _ref4.window;
9691
+
9692
+ if (_this4._onPopState) {
9693
+ window.removeEventListener('popstate', _this4._onPopState);
9694
+ }
9695
+ });
9639
9696
 
9640
9697
  if (this.writeTimer) {
9641
- window.clearTimeout(this.writeTimer);
9698
+ clearTimeout(this.writeTimer);
9642
9699
  }
9643
9700
 
9644
9701
  this.write({});
@@ -9649,12 +9706,12 @@
9649
9706
  }();
9650
9707
 
9651
9708
  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;
9709
+ var _ref5 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
9710
+ _ref5$createURL = _ref5.createURL,
9711
+ createURL = _ref5$createURL === void 0 ? function (_ref6) {
9712
+ var qsModule = _ref6.qsModule,
9713
+ routeState = _ref6.routeState,
9714
+ location = _ref6.location;
9658
9715
  var protocol = location.protocol,
9659
9716
  hostname = location.hostname,
9660
9717
  _location$port = location.port,
@@ -9670,11 +9727,11 @@
9670
9727
  }
9671
9728
 
9672
9729
  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;
9730
+ } : _ref5$createURL,
9731
+ _ref5$parseURL = _ref5.parseURL,
9732
+ parseURL = _ref5$parseURL === void 0 ? function (_ref7) {
9733
+ var qsModule = _ref7.qsModule,
9734
+ location = _ref7.location;
9678
9735
  // `qs` by default converts arrays with more than 20 items to an object.
9679
9736
  // We want to avoid this because the data structure manipulated can therefore vary.
9680
9737
  // Setting the limit to `100` seems a good number because the engine's default is 100
@@ -9688,16 +9745,28 @@
9688
9745
  return qsModule.parse(location.search.slice(1), {
9689
9746
  arrayLimit: 99
9690
9747
  });
9691
- } : _ref2$parseURL,
9692
- _ref2$writeDelay = _ref2.writeDelay,
9693
- writeDelay = _ref2$writeDelay === void 0 ? 400 : _ref2$writeDelay,
9694
- windowTitle = _ref2.windowTitle;
9748
+ } : _ref5$parseURL,
9749
+ _ref5$writeDelay = _ref5.writeDelay,
9750
+ writeDelay = _ref5$writeDelay === void 0 ? 400 : _ref5$writeDelay,
9751
+ windowTitle = _ref5.windowTitle,
9752
+ _ref5$getLocation = _ref5.getLocation,
9753
+ getLocation = _ref5$getLocation === void 0 ? function () {
9754
+ return safelyRunOnBrowser(function (_ref8) {
9755
+ var window = _ref8.window;
9756
+ return window.location;
9757
+ }, {
9758
+ fallback: function fallback() {
9759
+ throw new Error('You need to provide `getLocation` to the `history` router in environments where `window` does not exist.');
9760
+ }
9761
+ });
9762
+ } : _ref5$getLocation;
9695
9763
 
9696
9764
  return new BrowserHistory({
9697
9765
  createURL: createURL,
9698
9766
  parseURL: parseURL,
9699
9767
  writeDelay: writeDelay,
9700
- windowTitle: windowTitle
9768
+ windowTitle: windowTitle,
9769
+ getLocation: getLocation
9701
9770
  });
9702
9771
  }
9703
9772
 
@@ -9791,7 +9860,14 @@
9791
9860
  }
9792
9861
 
9793
9862
  function isMetadataEnabled() {
9794
- return typeof window !== 'undefined' && window.navigator.userAgent.indexOf('Algolia Crawler') > -1;
9863
+ return safelyRunOnBrowser(function (_ref) {
9864
+ var window = _ref.window;
9865
+ return window.navigator.userAgent.indexOf('Algolia Crawler') > -1;
9866
+ }, {
9867
+ fallback: function fallback() {
9868
+ return false;
9869
+ }
9870
+ });
9795
9871
  }
9796
9872
  /**
9797
9873
  * Exposes the metadata of mounted widgets in a custom
@@ -9802,8 +9878,8 @@
9802
9878
  */
9803
9879
 
9804
9880
  function createMetadataMiddleware() {
9805
- return function (_ref) {
9806
- var instantSearchInstance = _ref.instantSearchInstance;
9881
+ return function (_ref2) {
9882
+ var instantSearchInstance = _ref2.instantSearchInstance;
9807
9883
  var payload = {
9808
9884
  widgets: []
9809
9885
  };
@@ -10296,15 +10372,17 @@
10296
10372
  var nextUiState = typeof uiState === 'function' ? uiState(this.mainIndex.getWidgetUiState({})) : uiState;
10297
10373
 
10298
10374
  var setIndexHelperState = function setIndexHelperState(indexWidget) {
10375
+ var nextIndexUiState = nextUiState[indexWidget.getIndexId()] || {};
10376
+
10299
10377
  {
10300
10378
  checkIndexUiState({
10301
10379
  index: indexWidget,
10302
- indexUiState: nextUiState[indexWidget.getIndexId()]
10380
+ indexUiState: nextIndexUiState
10303
10381
  });
10304
10382
  }
10305
10383
 
10306
10384
  indexWidget.getHelper().setState(indexWidget.getWidgetSearchParameters(indexWidget.getHelper().state, {
10307
- uiState: nextUiState[indexWidget.getIndexId()]
10385
+ uiState: nextIndexUiState
10308
10386
  }));
10309
10387
  indexWidget.getWidgets().filter(isIndexWidget).forEach(setIndexHelperState);
10310
10388
  };
@@ -14122,11 +14200,20 @@
14122
14200
  var connectPoweredBy = function connectPoweredBy(renderFn) {
14123
14201
  var unmountFn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
14124
14202
  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';
14203
+ var defaultUrl = 'https://www.algolia.com/?' + 'utm_source=instantsearch.js&' + 'utm_medium=website&' + "utm_content=".concat(safelyRunOnBrowser(function (_ref) {
14204
+ var _window$location;
14205
+
14206
+ var window = _ref.window;
14207
+ return ((_window$location = window.location) === null || _window$location === void 0 ? void 0 : _window$location.hostname) || '';
14208
+ }, {
14209
+ fallback: function fallback() {
14210
+ return '';
14211
+ }
14212
+ }), "&") + 'utm_campaign=poweredby';
14126
14213
  return function (widgetParams) {
14127
- var _ref = widgetParams || {},
14128
- _ref$url = _ref.url,
14129
- url = _ref$url === void 0 ? defaultUrl : _ref$url;
14214
+ var _ref2 = widgetParams || {},
14215
+ _ref2$url = _ref2.url,
14216
+ url = _ref2$url === void 0 ? defaultUrl : _ref2$url;
14130
14217
 
14131
14218
  return {
14132
14219
  $$type: 'ais.poweredBy',
@@ -14611,6 +14698,11 @@
14611
14698
  };
14612
14699
  };
14613
14700
 
14701
+ // `SpeechRecognition` is an API used on the browser so we can safely disable
14702
+ // the `window` check.
14703
+
14704
+ /* eslint-disable no-restricted-globals */
14705
+
14614
14706
  /* global SpeechRecognition SpeechRecognitionEvent */
14615
14707
  var createVoiceSearchHelper = function createVoiceSearchHelper(_ref) {
14616
14708
  var searchAsYouSpeak = _ref.searchAsYouSpeak,
@@ -21487,28 +21579,27 @@
21487
21579
  }
21488
21580
 
21489
21581
  var KEY = 'ais.infiniteHits';
21490
-
21491
- function hasSessionStorage() {
21492
- return typeof window !== 'undefined' && typeof window.sessionStorage !== 'undefined';
21493
- }
21494
-
21495
21582
  function createInfiniteHitsSessionStorageCache() {
21496
21583
  return {
21497
21584
  read: function read(_ref2) {
21498
21585
  var state = _ref2.state;
21586
+ var sessionStorage = safelyRunOnBrowser(function (_ref3) {
21587
+ var window = _ref3.window;
21588
+ return window.sessionStorage;
21589
+ });
21499
21590
 
21500
- if (!hasSessionStorage()) {
21591
+ if (!sessionStorage) {
21501
21592
  return null;
21502
21593
  }
21503
21594
 
21504
21595
  try {
21505
21596
  var cache = JSON.parse( // @ts-expect-error JSON.parse() requires a string, but it actually accepts null, too.
21506
- window.sessionStorage.getItem(KEY));
21597
+ sessionStorage.getItem(KEY));
21507
21598
  return cache && isEqual(cache.state, getStateWithoutPage$1(state)) ? cache.hits : null;
21508
21599
  } catch (error) {
21509
21600
  if (error instanceof SyntaxError) {
21510
21601
  try {
21511
- window.sessionStorage.removeItem(KEY);
21602
+ sessionStorage.removeItem(KEY);
21512
21603
  } catch (err) {// do nothing
21513
21604
  }
21514
21605
  }
@@ -21516,16 +21607,20 @@
21516
21607
  return null;
21517
21608
  }
21518
21609
  },
21519
- write: function write(_ref3) {
21520
- var state = _ref3.state,
21521
- hits = _ref3.hits;
21610
+ write: function write(_ref4) {
21611
+ var state = _ref4.state,
21612
+ hits = _ref4.hits;
21613
+ var sessionStorage = safelyRunOnBrowser(function (_ref5) {
21614
+ var window = _ref5.window;
21615
+ return window.sessionStorage;
21616
+ });
21522
21617
 
21523
- if (!hasSessionStorage()) {
21618
+ if (!sessionStorage) {
21524
21619
  return;
21525
21620
  }
21526
21621
 
21527
21622
  try {
21528
- window.sessionStorage.setItem(KEY, JSON.stringify({
21623
+ sessionStorage.setItem(KEY, JSON.stringify({
21529
21624
  state: getStateWithoutPage$1(state),
21530
21625
  hits: hits
21531
21626
  }));