instantsearch.js 4.33.0 → 4.35.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 (36) hide show
  1. package/CHANGELOG.md +41 -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/search-box/connectSearchBox.js +4 -3
  8. package/cjs/connectors/sort-by/connectSortBy.js +2 -1
  9. package/cjs/connectors/stats/connectStats.js +4 -4
  10. package/cjs/connectors/toggle-refinement/connectToggleRefinement.js +1 -1
  11. package/cjs/lib/InstantSearch.js +23 -2
  12. package/cjs/lib/version.js +1 -1
  13. package/cjs/widgets/index/index.js +21 -3
  14. package/dist/instantsearch.development.d.ts +9 -2
  15. package/dist/instantsearch.development.js +72 -28
  16. package/dist/instantsearch.development.js.map +1 -1
  17. package/dist/instantsearch.development.min.d.ts +9 -2
  18. package/dist/instantsearch.production.d.ts +9 -2
  19. package/dist/instantsearch.production.min.d.ts +9 -2
  20. package/dist/instantsearch.production.min.js +2 -2
  21. package/dist/instantsearch.production.min.js.map +1 -1
  22. package/es/connectors/autocomplete/connectAutocomplete.js +2 -1
  23. package/es/connectors/infinite-hits/connectInfiniteHits.js +1 -1
  24. package/es/connectors/numeric-menu/connectNumericMenu.js +6 -4
  25. package/es/connectors/pagination/connectPagination.js +3 -3
  26. package/es/connectors/search-box/connectSearchBox.js +4 -3
  27. package/es/connectors/sort-by/connectSortBy.js +2 -1
  28. package/es/connectors/stats/connectStats.js +4 -4
  29. package/es/connectors/toggle-refinement/connectToggleRefinement.js +1 -1
  30. package/es/lib/InstantSearch.d.ts +3 -3
  31. package/es/lib/InstantSearch.js +23 -2
  32. package/es/lib/version.d.ts +1 -1
  33. package/es/lib/version.js +1 -1
  34. package/es/types/results.d.ts +7 -0
  35. package/es/widgets/index/index.js +21 -3
  36. package/package.json +10 -7
package/CHANGELOG.md CHANGED
@@ -1,3 +1,44 @@
1
+ # [4.35.0](https://github.com/algolia/instantsearch.js/compare/v4.34.0...v4.35.0) (2021-12-13)
2
+
3
+
4
+ ### Features
5
+
6
+ * **events:** move to @algolia/events ([#4961](https://github.com/algolia/instantsearch.js/issues/4961)) ([1c56726](https://github.com/algolia/instantsearch.js/commit/1c5672640c65d7ed6f6e381a3162e508bdda44f3))
7
+
8
+ ### Bug Fixes
9
+
10
+ * **deps:** Add missing peer dependency ([#4950](https://github.com/algolia/instantsearch.js/issues/4950)) ([468578da9](https://github.com/algolia/instantsearch.js/commit/468578da948a12224c892fd12cba4c880aa7b25f))
11
+
12
+
13
+
14
+ # [4.34.0](https://github.com/algolia/instantsearch.js/compare/v4.33.2...v4.34.0) (2021-12-07)
15
+
16
+
17
+ ### Features
18
+
19
+ * rely on `state` in `getWidgetRenderState` ([#4960](https://github.com/algolia/instantsearch.js/issues/4960)) ([5006841](https://github.com/algolia/instantsearch.js/commit/50068417e5e7211802bc717b582946f6e630d7ac))
20
+ * support initial results (experimental) ([#4967](https://github.com/algolia/instantsearch.js/issues/4967)) ([db11c13](https://github.com/algolia/instantsearch.js/commit/db11c13ea55433491f5e924633bff12a303c1bc6))
21
+
22
+
23
+
24
+ ## [4.33.2](https://github.com/algolia/instantsearch.js/compare/v4.33.1...v4.33.2) (2021-11-16)
25
+
26
+
27
+ ### Bug Fixes
28
+
29
+ * **connectNumericMenu:** allow option for same start/end values ([#4951](https://github.com/algolia/instantsearch.js/issues/4951)) ([18da714](https://github.com/algolia/instantsearch.js/commit/18da714574fa98957d29014add3123e9c377551f))
30
+
31
+
32
+
33
+ ## [4.33.1](https://github.com/algolia/instantsearch.js/compare/v4.33.0...v4.33.1) (2021-11-02)
34
+
35
+
36
+ ### Bug Fixes
37
+
38
+ * **getUiState:** support `initialUiState` ([#4948](https://github.com/algolia/instantsearch.js/issues/4948)) ([532474d](https://github.com/algolia/instantsearch.js/commit/532474dfaf49446ab59a2a27424ca220947dd5bd))
39
+
40
+
41
+
1
42
  # [4.33.0](https://github.com/algolia/instantsearch.js/compare/v4.32.0...v4.33.0) (2021-10-26)
2
43
 
3
44
 
package/README.md CHANGED
@@ -29,6 +29,7 @@ InstantSearch.js is a vanilla JavaScript library that lets you create an instant
29
29
  - [Why](#why)
30
30
  - [Getting started](#getting-started)
31
31
  - [Installation](#installation)
32
+ - [TypeScript users](#typescript-users)
32
33
  - [Documentation](#documentation)
33
34
  - [Demos](#demos)
34
35
  - [Playground](#playground)
@@ -102,6 +103,28 @@ npm install instantsearch.js algoliasearch
102
103
  yarn add instantsearch.js algoliasearch
103
104
  ```
104
105
 
106
+ ### TypeScript users
107
+
108
+ To use InstantSearch.js in a TypeScript environment, depending on your [`algoliasearch`](https://github.com/algolia/algoliasearch-client-javascript) version, you need to import different types.
109
+
110
+ >You still need to import these types even if you don't use InstantSearch.js with [`algoliasearch`](https://github.com/algolia/algoliasearch-client-javascript).
111
+
112
+ #### `algoliasearch` v4.x
113
+
114
+ This version uses types provided by both `algoliasearch` and `@algolia/client-search`.
115
+
116
+ ```bash
117
+ yarn add algoliasearch@4 @algolia/client-search
118
+ ```
119
+
120
+ #### `algoliasearch` v3.x
121
+
122
+ ```bash
123
+ yarn add @types/algoliasearch@3
124
+ ```
125
+
126
+ >v3.x is deprecated and will soon no longer be supported.
127
+
105
128
  ## Documentation
106
129
 
107
130
  The documentation is available on the [Algolia website](https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/).
@@ -110,7 +133,7 @@ The documentation is available on the [Algolia website](https://www.algolia.com/
110
133
 
111
134
  | E-commerce | Media | Travel |
112
135
  | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
113
- | <a href="https://instantsearchjs.netlify.com/examples/e-commerce/"><img src="https://www.algolia.com/doc/assets/images/build-search-ui/demos/e-commerce-2c7ed6b6.png" width="250" alt="E-commerce demo preview"></a> | <a href="https://instantsearchjs.netlify.com/examples/media/"><img src="https://instantsearchjs.netlify.com/examples/media/capture.png" width="250" alt="Media demo preview"></a> | <a href="https://instantsearchjs.netlify.com/examples/tourism/"><img src="https://instantsearchjs.netlify.com/examples/tourism/capture.png" width="250" alt="Tourism demo preview"></a> |
136
+ | <a href="https://instantsearchjs.netlify.com/examples/e-commerce/"><img src="https://www.algolia.com/doc/assets/images/build-search-ui/demos/e-commerce-2c7ed6b6.png" width="250" alt="E-commerce demo preview"></a> | <a href="https://instantsearchjs.netlify.com/examples/media/"><img src="./examples/media/capture.png" width="250" alt="Media demo preview"></a> | <a href="https://instantsearchjs.netlify.com/examples/tourism/"><img src="https://instantsearchjs.netlify.com/examples/tourism/capture.png" width="250" alt="Tourism demo preview"></a> |
114
137
 
115
138
  See more demos [on the website](https://www.algolia.com/doc/guides/building-search-ui/resources/demos/js/).
116
139
 
@@ -60,6 +60,7 @@ var connectAutocomplete = function connectAutocomplete(renderFn) {
60
60
  var _this = this;
61
61
 
62
62
  var helper = _ref4.helper,
63
+ state = _ref4.state,
63
64
  scopedResults = _ref4.scopedResults,
64
65
  instantSearchInstance = _ref4.instantSearchInstance;
65
66
 
@@ -87,7 +88,7 @@ var connectAutocomplete = function connectAutocomplete(renderFn) {
87
88
  };
88
89
  });
89
90
  return {
90
- currentRefinement: helper.state.query || '',
91
+ currentRefinement: state.query || '',
91
92
  indices: indices,
92
93
  refine: connectorState.refine,
93
94
  widgetParams: widgetParams
@@ -173,7 +173,7 @@ var connectInfiniteHits = function connectInfiniteHits(renderFn) {
173
173
  index: helper.getIndex(),
174
174
  widgetType: this.$$type
175
175
  });
176
- isFirstPage = helper.state.page === undefined || getFirstReceivedPage(helper.state, cachedHits) === 0;
176
+ isFirstPage = state.page === undefined || getFirstReceivedPage(state, cachedHits) === 0;
177
177
  } else {
178
178
  var _state$page3 = state.page,
179
179
  _page = _state$page3 === void 0 ? 0 : _state$page3;
@@ -242,6 +242,8 @@ function isRefined(state, attribute, option) {
242
242
  if (option.start !== undefined && option.end !== undefined) {
243
243
  if (option.start === option.end) {
244
244
  return hasNumericRefinement(currentRefinements, '=', option.start);
245
+ } else {
246
+ return hasNumericRefinement(currentRefinements, '>=', option.start) && hasNumericRefinement(currentRefinements, '<=', option.end);
245
247
  }
246
248
  }
247
249
 
@@ -295,17 +297,17 @@ function getRefinedState(state, attribute, facetValue) {
295
297
  if (refinedOption.start !== undefined) {
296
298
  if (hasNumericRefinement(currentRefinements, '>=', refinedOption.start)) {
297
299
  resolvedState = resolvedState.removeNumericRefinement(attribute, '>=', refinedOption.start);
298
- } else {
299
- resolvedState = resolvedState.addNumericRefinement(attribute, '>=', refinedOption.start);
300
300
  }
301
+
302
+ resolvedState = resolvedState.addNumericRefinement(attribute, '>=', refinedOption.start);
301
303
  }
302
304
 
303
305
  if (refinedOption.end !== undefined) {
304
306
  if (hasNumericRefinement(currentRefinements, '<=', refinedOption.end)) {
305
307
  resolvedState = resolvedState.removeNumericRefinement(attribute, '<=', refinedOption.end);
306
- } else {
307
- resolvedState = resolvedState.addNumericRefinement(attribute, '<=', refinedOption.end);
308
308
  }
309
+
310
+ resolvedState = resolvedState.addNumericRefinement(attribute, '<=', refinedOption.end);
309
311
  }
310
312
 
311
313
  if (typeof resolvedState.page === 'number') {
@@ -89,6 +89,7 @@ var connectPagination = function connectPagination(renderFn) {
89
89
  getWidgetRenderState: function getWidgetRenderState(_ref6) {
90
90
  var results = _ref6.results,
91
91
  helper = _ref6.helper,
92
+ state = _ref6.state,
92
93
  createURL = _ref6.createURL;
93
94
 
94
95
  if (!connectorState.refine) {
@@ -99,14 +100,13 @@ var connectPagination = function connectPagination(renderFn) {
99
100
  }
100
101
 
101
102
  if (!connectorState.createURL) {
102
- connectorState.createURL = function (state) {
103
+ connectorState.createURL = function (helperState) {
103
104
  return function (page) {
104
- return createURL(state.setPage(page));
105
+ return createURL(helperState.setPage(page));
105
106
  };
106
107
  };
107
108
  }
108
109
 
109
- var state = helper.state;
110
110
  var page = state.page || 0;
111
111
  var nbPages = getMaxPage(results || {
112
112
  nbPages: 0
@@ -71,11 +71,12 @@ var connectSearchBox = function connectSearchBox(renderFn) {
71
71
  },
72
72
  getWidgetRenderState: function getWidgetRenderState(_ref3) {
73
73
  var helper = _ref3.helper,
74
- searchMetadata = _ref3.searchMetadata;
74
+ searchMetadata = _ref3.searchMetadata,
75
+ state = _ref3.state;
75
76
 
76
77
  if (!_refine) {
77
78
  var setQueryAndSearch = function setQueryAndSearch(query) {
78
- if (query !== helper.state.query) {
79
+ if (query !== state.query) {
79
80
  helper.setQuery(query).search();
80
81
  }
81
82
  };
@@ -92,7 +93,7 @@ var connectSearchBox = function connectSearchBox(renderFn) {
92
93
 
93
94
  _clear = clear(helper);
94
95
  return {
95
- query: helper.state.query || '',
96
+ query: state.query || '',
96
97
  refine: _refine,
97
98
  clear: _cachedClear,
98
99
  widgetParams: widgetParams,
@@ -72,6 +72,7 @@ var connectSortBy = function connectSortBy(renderFn) {
72
72
  getWidgetRenderState: function getWidgetRenderState(_ref3) {
73
73
  var results = _ref3.results,
74
74
  helper = _ref3.helper,
75
+ state = _ref3.state,
75
76
  parent = _ref3.parent;
76
77
 
77
78
  if (!connectorState.initialIndex && parent) {
@@ -85,7 +86,7 @@ var connectSortBy = function connectSortBy(renderFn) {
85
86
  }
86
87
 
87
88
  return {
88
- currentRefinement: helper.state.index,
89
+ currentRefinement: state.index,
89
90
  options: transformItems(items),
90
91
  refine: connectorState.setIndex,
91
92
  hasNoResults: results ? results.nbHits === 0 : true,
@@ -50,18 +50,18 @@ var connectStats = function connectStats(renderFn) {
50
50
  },
51
51
  getWidgetRenderState: function getWidgetRenderState(_ref) {
52
52
  var results = _ref.results,
53
- helper = _ref.helper;
53
+ state = _ref.state;
54
54
 
55
55
  if (!results) {
56
56
  return {
57
- hitsPerPage: helper.state.hitsPerPage,
57
+ hitsPerPage: state.hitsPerPage,
58
58
  nbHits: 0,
59
59
  nbSortedHits: undefined,
60
60
  areHitsSorted: false,
61
61
  nbPages: 0,
62
- page: helper.state.page || 0,
62
+ page: state.page || 0,
63
63
  processingTimeMS: -1,
64
- query: helper.state.query || '',
64
+ query: state.query || '',
65
65
  widgetParams: widgetParams
66
66
  };
67
67
  }
@@ -185,7 +185,7 @@ var connectToggleRefinement = function connectToggleRefinement(renderFn) {
185
185
  createURL = _ref6.createURL,
186
186
  instantSearchInstance = _ref6.instantSearchInstance;
187
187
  var isRefined = results ? on.every(function (v) {
188
- return helper.state.isDisjunctiveFacetRefined(attribute, v);
188
+ return state.isDisjunctiveFacetRefined(attribute, v);
189
189
  }) : on.every(function (v) {
190
190
  return state.isDisjunctiveFacetRefined(attribute, v);
191
191
  });
@@ -9,7 +9,7 @@ exports.default = void 0;
9
9
 
10
10
  var _algoliasearchHelper = _interopRequireDefault(require("algoliasearch-helper"));
11
11
 
12
- var _events = _interopRequireDefault(require("events"));
12
+ var _events = _interopRequireDefault(require("@algolia/events"));
13
13
 
14
14
  var _index = _interopRequireWildcard(require("../widgets/index/index"));
15
15
 
@@ -112,6 +112,8 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
112
112
 
113
113
  _defineProperty(_assertThisInitialized(_this), "_initialUiState", void 0);
114
114
 
115
+ _defineProperty(_assertThisInitialized(_this), "_initialResults", void 0);
116
+
115
117
  _defineProperty(_assertThisInitialized(_this), "_createURL", void 0);
116
118
 
117
119
  _defineProperty(_assertThisInitialized(_this), "_searchFunction", void 0);
@@ -216,6 +218,7 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
216
218
  _this._isSearchStalled = false;
217
219
  _this._createURL = defaultCreateURL;
218
220
  _this._initialUiState = initialUiState;
221
+ _this._initialResults = null;
219
222
 
220
223
  if (searchFunction) {
221
224
  _this._searchFunction = searchFunction;
@@ -458,9 +461,27 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
458
461
  parent: null,
459
462
  uiState: this._initialUiState
460
463
  });
461
- this.scheduleSearch(); // Keep the previous reference for legacy purpose, some pattern use
464
+
465
+ if (this._initialResults) {
466
+ var originalScheduleSearch = this.scheduleSearch; // We don't schedule a first search when initial results are provided
467
+ // because we already have the results to render. This skips the initial
468
+ // network request on the browser on `start`.
469
+
470
+ this.scheduleSearch = (0, _utils.defer)(_utils.noop); // We also skip the initial network request when widgets are dynamically
471
+ // added in the first tick (that's the case in all the framework-based flavors).
472
+ // When we add a widget to `index`, it calls `scheduleSearch`. We can rely
473
+ // on our `defer` util to restore the original `scheduleSearch` value once
474
+ // widgets are added to hook back to the regular lifecycle.
475
+
476
+ (0, _utils.defer)(function () {
477
+ _this3.scheduleSearch = originalScheduleSearch;
478
+ })();
479
+ } else {
480
+ this.scheduleSearch();
481
+ } // Keep the previous reference for legacy purpose, some pattern use
462
482
  // the direct Helper access `search.helper` (e.g multi-index).
463
483
 
484
+
464
485
  this.helper = this.mainIndex.getHelper(); // track we started the search if we add more widgets,
465
486
  // to init them directly after add
466
487
 
@@ -4,5 +4,5 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _default = '4.33.0';
7
+ var _default = '4.35.0';
8
8
  exports.default = _default;
@@ -289,7 +289,8 @@ var index = function index(widgetParams) {
289
289
  return this;
290
290
  },
291
291
  init: function init(_ref2) {
292
- var _this3 = this;
292
+ var _this3 = this,
293
+ _instantSearchInstanc;
293
294
 
294
295
  var instantSearchInstance = _ref2.instantSearchInstance,
295
296
  parent = _ref2.parent,
@@ -347,11 +348,21 @@ var index = function index(widgetParams) {
347
348
 
348
349
  derivedHelper = mainHelper.derive(function () {
349
350
  return _utils.mergeSearchParameters.apply(void 0, _toConsumableArray((0, _utils.resolveSearchParameters)(_this3)));
350
- }); // Subscribe to the Helper state changes for the page before widgets
351
+ });
352
+ var indexInitialResults = (_instantSearchInstanc = instantSearchInstance._initialResults) === null || _instantSearchInstanc === void 0 ? void 0 : _instantSearchInstanc[this.getIndexId()];
353
+
354
+ if (indexInitialResults) {
355
+ // We restore the shape of the results provided to the instance to respect
356
+ // the helper's structure.
357
+ var results = new _algoliasearchHelper.default.SearchResults(new _algoliasearchHelper.default.SearchParameters(indexInitialResults.state), indexInitialResults.results);
358
+ derivedHelper.lastResults = results;
359
+ helper.lastResults = results;
360
+ } // Subscribe to the Helper state changes for the page before widgets
351
361
  // are initialized. This behavior mimics the original one of the Helper.
352
362
  // It makes sense to replicate it at the `init` step. We have another
353
363
  // listener on `change` below, once `init` is done.
354
364
 
365
+
355
366
  helper.on('change', function (_ref3) {
356
367
  var isPageReset = _ref3.isPageReset;
357
368
 
@@ -452,6 +463,13 @@ var index = function index(widgetParams) {
452
463
  instantSearchInstance.onInternalStateChange();
453
464
  }
454
465
  });
466
+
467
+ if (indexInitialResults) {
468
+ // If there are initial results, we're not notified of the next results
469
+ // because we don't trigger an initial search. We therefore need to directly
470
+ // schedule a render that will render the results injected on the helper.
471
+ instantSearchInstance.scheduleRender();
472
+ }
455
473
  },
456
474
  render: function render(_ref5) {
457
475
  var _this4 = this;
@@ -555,7 +573,7 @@ var index = function index(widgetParams) {
555
573
  localUiState = getLocalWidgetsUiState(localWidgets, {
556
574
  searchParameters: this.getHelper().state,
557
575
  helper: this.getHelper()
558
- });
576
+ }, localUiState);
559
577
  }
560
578
  };
561
579
  };
@@ -1,10 +1,9 @@
1
1
  /// <reference types="google.maps" />
2
- /// <reference types="node" />
3
2
 
4
3
  import type algoliasearch from 'algoliasearch/lite';
5
4
  import type { AlgoliaSearchHelper } from 'algoliasearch-helper';
6
5
  import type * as ClientSearch from '@algolia/client-search';
7
- import EventEmitter from 'events';
6
+ import EventEmitter from '@algolia/events';
8
7
  import type { InsightsClient as InsightsClient_2 } from 'search-insights';
9
8
  import type { InsightsMethodMap } from 'search-insights';
10
9
  import type * as Places from 'places.js';
@@ -2194,6 +2193,13 @@ declare type InfiniteHitsWidgetParams = {
2194
2193
  cache?: InfiniteHitsCache;
2195
2194
  };
2196
2195
 
2196
+ declare type InitialResult = {
2197
+ state: PlainSearchParameters;
2198
+ results: SearchResults['_rawResults'];
2199
+ };
2200
+
2201
+ declare type InitialResults = Record<string, InitialResult>;
2202
+
2197
2203
  declare type InitOptions = SharedRenderOptions & {
2198
2204
  uiState: UiState;
2199
2205
  results?: undefined;
@@ -2258,6 +2264,7 @@ declare class InstantSearch<TUiState extends UiState = UiState, TRouteState = TU
2258
2264
  _searchStalledTimer: any;
2259
2265
  _isSearchStalled: boolean;
2260
2266
  _initialUiState: UiState;
2267
+ _initialResults: InitialResults | null;
2261
2268
  _createURL: CreateURL<UiState>;
2262
2269
  _searchFunction?: InstantSearchOptions['searchFunction'];
2263
2270
  _mainHelperSearch?: AlgoliaSearchHelper['search'];