instantsearch.js 4.40.6 → 4.41.2

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,32 @@
1
+ ## [4.41.2](https://github.com/algolia/instantsearch.js/compare/v4.41.1...v4.41.2) (2022-06-15)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **hierarchicalMenu:** show full hierarchical parent values ([#5063](https://github.com/algolia/instantsearch.js/issues/5063)) ([cd1db34](https://github.com/algolia/instantsearch.js/commit/cd1db34815f92acb3d2d0cec6c1ae7865d14fb13))
7
+
8
+
9
+
10
+ ## [4.41.1](https://github.com/algolia/instantsearch.js/compare/v4.41.0...v4.41.1) (2022-06-14)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **insights:** don't send view event if search is stalled ([#5058](https://github.com/algolia/instantsearch.js/issues/5058)) ([1686dfb](https://github.com/algolia/instantsearch.js/commit/1686dfb096cfce062e268feda7956e3b160bf2da)), closes [/github.com/algolia/instantsearch.js/blob/99f6fe1dc51e4815e5b9efcfb30e3e2f3127e763/src/lib/utils/createSendEventForHits.ts#L168](https://github.com//github.com/algolia/instantsearch.js/blob/99f6fe1dc51e4815e5b9efcfb30e3e2f3127e763/src/lib/utils/createSendEventForHits.ts/issues/L168) [/github.com/algolia/instantsearch.js/blob/55313e4ea4105b777f3f102e9f48a7e440496d25/src/middlewares/createInsightsMiddleware.ts#L144](https://github.com//github.com/algolia/instantsearch.js/blob/55313e4ea4105b777f3f102e9f48a7e440496d25/src/middlewares/createInsightsMiddleware.ts/issues/L144)
16
+ * **types:** avoid inferring UiState type from initialUiState ([#5061](https://github.com/algolia/instantsearch.js/issues/5061)) ([80ca07e](https://github.com/algolia/instantsearch.js/commit/80ca07e29064357343ee997be94ef10beadba637)), closes [/github.com/Microsoft/TypeScript/issues/14829#issuecomment-504042546](https://github.com//github.com/Microsoft/TypeScript/issues/14829/issues/issuecomment-504042546) [#5060](https://github.com/algolia/instantsearch.js/issues/5060)
17
+ * **types:** make all usages of UiState in InstantSearch generic ([#5060](https://github.com/algolia/instantsearch.js/issues/5060)) ([2b9e76b](https://github.com/algolia/instantsearch.js/commit/2b9e76b568fb4d4cc5bd49c384ee583d84d6f39a))
18
+
19
+
20
+
21
+ # [4.41.0](https://github.com/algolia/instantsearch.js/compare/v4.40.6...v4.41.0) (2022-06-01)
22
+
23
+
24
+ ### Features
25
+
26
+ * **core:** don't schedule search without widgets ([#5056](https://github.com/algolia/instantsearch.js/issues/5056)) ([ea3d6d9](https://github.com/algolia/instantsearch.js/commit/ea3d6d9c6ae1fe2f90bf5643d4bdcbb89507e9bc))
27
+
28
+
29
+
1
30
  ## [4.40.6](https://github.com/algolia/instantsearch.js/compare/v4.40.5...v4.40.6) (2022-05-24)
2
31
 
3
32
 
@@ -61,10 +61,9 @@ var withUsage = (0, _index2.createDocumentationMessageGenerator)({
61
61
 
62
62
  function defaultCreateURL() {
63
63
  return '#';
64
- }
65
- /**
66
- * Global options for an InstantSearch instance.
67
- */
64
+ } // this purposely breaks typescript's type inference to ensure it's not used
65
+ // as it's used for a default parameter for example
66
+ // source: https://github.com/Microsoft/TypeScript/issues/14829#issuecomment-504042546
68
67
 
69
68
 
70
69
  /**
@@ -481,9 +480,17 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
481
480
  (0, _index2.defer)(function () {
482
481
  _this3.scheduleSearch = originalScheduleSearch;
483
482
  })();
484
- } else {
485
- this.scheduleSearch();
486
- } // Keep the previous reference for legacy purpose, some pattern use
483
+ } // We only schedule a search when widgets have been added before `start()`
484
+ // because there are listeners that can use these results.
485
+ // This is especially useful in framework-based flavors that wait for
486
+ // dynamically-added widgets to trigger a network request. It avoids
487
+ // having to batch this initial network request with the one coming from
488
+ // `addWidgets()`.
489
+ // Later, we could also skip `index()` widgets and widgets that don't read
490
+ // the results, but this is an optimization that has a very low impact for now.
491
+ else if (this.mainIndex.getWidgets().length > 0) {
492
+ this.scheduleSearch();
493
+ } // Keep the previous reference for legacy purpose, some pattern use
487
494
  // the direct Helper access `search.helper` (e.g multi-index).
488
495
 
489
496
 
@@ -25,7 +25,8 @@ var buildPayloads = function buildPayloads(_ref) {
25
25
  var index = _ref.index,
26
26
  widgetType = _ref.widgetType,
27
27
  methodName = _ref.methodName,
28
- args = _ref.args;
28
+ args = _ref.args,
29
+ isSearchStalled = _ref.isSearchStalled;
29
30
 
30
31
  // when there's only one argument, that means it's custom
31
32
  if (args.length === 1 && _typeof(args[0]) === 'object') {
@@ -72,6 +73,10 @@ var buildPayloads = function buildPayloads(_ref) {
72
73
  });
73
74
 
74
75
  if (eventType === 'view') {
76
+ if (isSearchStalled) {
77
+ return [];
78
+ }
79
+
75
80
  return hitsChunks.map(function (batch, i) {
76
81
  return {
77
82
  insightsMethod: 'viewedObjectIDs',
@@ -142,7 +147,8 @@ function createSendEventForHits(_ref2) {
142
147
  widgetType: widgetType,
143
148
  index: index,
144
149
  methodName: 'sendEvent',
145
- args: args
150
+ args: args,
151
+ isSearchStalled: instantSearchInstance._isSearchStalled
146
152
  });
147
153
  payloads.forEach(function (payload) {
148
154
  return instantSearchInstance.sendEventToInsights(payload);
@@ -165,7 +171,8 @@ function createBindEventForHits(_ref3) {
165
171
  widgetType: widgetType,
166
172
  index: index,
167
173
  methodName: 'bindEvent',
168
- args: args
174
+ args: args,
175
+ isSearchStalled: false
169
176
  });
170
177
  return payloads.length ? "data-insights-event=".concat((0, _serializer.serializePayload)(payloads)) : '';
171
178
  };
@@ -4,5 +4,5 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _default = '4.40.6';
7
+ var _default = '4.41.2';
8
8
  exports.default = _default;
@@ -2286,7 +2286,7 @@ declare class InstantSearch<TUiState extends UiState = UiState, TRouteState = TU
2286
2286
  client: InstantSearchOptions['searchClient'];
2287
2287
  indexName: string;
2288
2288
  insightsClient: InsightsClient | null;
2289
- onStateChange: InstantSearchOptions['onStateChange'] | null;
2289
+ onStateChange: InstantSearchOptions<TUiState>['onStateChange'] | null;
2290
2290
  helper: AlgoliaSearchHelper | null;
2291
2291
  mainHelper: AlgoliaSearchHelper | null;
2292
2292
  mainIndex: IndexWidget;
@@ -2296,9 +2296,9 @@ declare class InstantSearch<TUiState extends UiState = UiState, TRouteState = TU
2296
2296
  _stalledSearchDelay: number;
2297
2297
  _searchStalledTimer: any;
2298
2298
  _isSearchStalled: boolean;
2299
- _initialUiState: UiState;
2299
+ _initialUiState: TUiState;
2300
2300
  _initialResults: InitialResults | null;
2301
- _createURL: CreateURL<UiState>;
2301
+ _createURL: CreateURL<TUiState>;
2302
2302
  _searchFunction?: InstantSearchOptions['searchFunction'];
2303
2303
  _mainHelperSearch?: AlgoliaSearchHelper['search'];
2304
2304
  middleware: Array<{
@@ -2368,13 +2368,13 @@ declare class InstantSearch<TUiState extends UiState = UiState, TRouteState = TU
2368
2368
  cancel(): void;
2369
2369
  };
2370
2370
  scheduleStalledRender(): void;
2371
- setUiState(uiState: UiState | ((previousUiState: UiState) => UiState)): void;
2372
- getUiState(): UiState;
2371
+ setUiState(uiState: TUiState | ((previousUiState: TUiState) => TUiState)): void;
2372
+ getUiState(): TUiState;
2373
2373
  onInternalStateChange: ((...args: any[]) => void) & {
2374
2374
  wait(): Promise<void>;
2375
2375
  cancel(): void;
2376
2376
  };
2377
- createURL(nextState?: UiState): string;
2377
+ createURL(nextState?: TUiState): string;
2378
2378
  refresh(): void;
2379
2379
  }
2380
2380
 
@@ -2466,8 +2466,8 @@ declare type InstantSearchOptions<TUiState extends UiState = UiState, TRouteStat
2466
2466
  * become in charge of updating the UI state with the `setUiState` function.
2467
2467
  */
2468
2468
  onStateChange?: (params: {
2469
- uiState: UiState;
2470
- setUiState(uiState: UiState | ((previousUiState: UiState) => UiState)): void;
2469
+ uiState: TUiState;
2470
+ setUiState(uiState: TUiState | ((previousUiState: TUiState) => TUiState)): void;
2471
2471
  }) => void;
2472
2472
  /**
2473
2473
  * Injects a `uiState` to the `instantsearch` instance. You can use this option
@@ -2475,7 +2475,7 @@ declare type InstantSearchOptions<TUiState extends UiState = UiState, TRouteStat
2475
2475
  * for the first search. To unconditionally pass additional parameters to the
2476
2476
  * Algolia API, take a look at the `configure` widget.
2477
2477
  */
2478
- initialUiState?: TUiState;
2478
+ initialUiState?: NoInfer<TUiState>;
2479
2479
  /**
2480
2480
  * Time before a search is considered stalled. The default is 200ms
2481
2481
  */
@@ -2779,6 +2779,8 @@ declare namespace middlewares {
2779
2779
  }
2780
2780
  }
2781
2781
 
2782
+ declare type NoInfer<T> = [T][T extends any ? 0 : never];
2783
+
2782
2784
  declare const numericMenu: NumericMenuWidget;
2783
2785
 
2784
2786
  declare type NumericMenuComponentCSSClasses = ComponentCSSClasses<NumericMenuCSSClasses>;
@@ -1,4 +1,4 @@
1
- /*! InstantSearch.js 4.40.6 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch.js */
1
+ /*! InstantSearch.js 4.41.2 | © 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) :
@@ -2989,7 +2989,7 @@
2989
2989
  nextDisjunctiveResult++;
2990
2990
  });
2991
2991
 
2992
- // if we have some root level values for hierarchical facets, merge them
2992
+ // if we have some parent level values for hierarchical facets, merge them
2993
2993
  state.getRefinedHierarchicalFacets().forEach(function(refinedFacet) {
2994
2994
  var hierarchicalFacet = state.getHierarchicalFacetByName(refinedFacet);
2995
2995
  var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);
@@ -3001,47 +3001,49 @@
3001
3001
  return;
3002
3002
  }
3003
3003
 
3004
- var result = results[nextDisjunctiveResult];
3005
- var facets = result && result.facets
3006
- ? result.facets
3007
- : {};
3008
- Object.keys(facets).forEach(function(dfacet) {
3009
- var facetResults = facets[dfacet];
3010
- var position = findIndex(state.hierarchicalFacets, function(f) {
3011
- return f.name === hierarchicalFacet.name;
3012
- });
3013
- var attributeIndex = findIndex(self.hierarchicalFacets[position], function(f) {
3014
- return f.attribute === dfacet;
3015
- });
3004
+ results.slice(nextDisjunctiveResult).forEach(function(result) {
3005
+ var facets = result && result.facets
3006
+ ? result.facets
3007
+ : {};
3016
3008
 
3017
- // previous refinements and no results so not able to find it
3018
- if (attributeIndex === -1) {
3019
- return;
3020
- }
3009
+ Object.keys(facets).forEach(function(dfacet) {
3010
+ var facetResults = facets[dfacet];
3011
+ var position = findIndex(state.hierarchicalFacets, function(f) {
3012
+ return f.name === hierarchicalFacet.name;
3013
+ });
3014
+ var attributeIndex = findIndex(self.hierarchicalFacets[position], function(f) {
3015
+ return f.attribute === dfacet;
3016
+ });
3021
3017
 
3022
- // when we always get root levels, if the hits refinement is `beers > IPA` (count: 5),
3023
- // then the disjunctive values will be `beers` (count: 100),
3024
- // but we do not want to display
3025
- // | beers (100)
3026
- // > IPA (5)
3027
- // We want
3028
- // | beers (5)
3029
- // > IPA (5)
3030
- var defaultData = {};
3031
-
3032
- if (currentRefinement.length > 0) {
3033
- var root = currentRefinement[0].split(separator)[0];
3034
- defaultData[root] = self.hierarchicalFacets[position][attributeIndex].data[root];
3035
- }
3018
+ // previous refinements and no results so not able to find it
3019
+ if (attributeIndex === -1) {
3020
+ return;
3021
+ }
3036
3022
 
3037
- self.hierarchicalFacets[position][attributeIndex].data = defaultsPure(
3038
- defaultData,
3039
- facetResults,
3040
- self.hierarchicalFacets[position][attributeIndex].data
3041
- );
3042
- });
3023
+ // when we always get root levels, if the hits refinement is `beers > IPA` (count: 5),
3024
+ // then the disjunctive values will be `beers` (count: 100),
3025
+ // but we do not want to display
3026
+ // | beers (100)
3027
+ // > IPA (5)
3028
+ // We want
3029
+ // | beers (5)
3030
+ // > IPA (5)
3031
+ var defaultData = {};
3032
+
3033
+ if (currentRefinement.length > 0) {
3034
+ var root = currentRefinement[0].split(separator)[0];
3035
+ defaultData[root] = self.hierarchicalFacets[position][attributeIndex].data[root];
3036
+ }
3043
3037
 
3044
- nextDisjunctiveResult++;
3038
+ self.hierarchicalFacets[position][attributeIndex].data = defaultsPure(
3039
+ defaultData,
3040
+ facetResults,
3041
+ self.hierarchicalFacets[position][attributeIndex].data
3042
+ );
3043
+ });
3044
+
3045
+ nextDisjunctiveResult++;
3046
+ });
3045
3047
  });
3046
3048
 
3047
3049
  // add the excludes
@@ -3869,18 +3871,38 @@
3869
3871
  });
3870
3872
  });
3871
3873
 
3872
- // maybe more to get the root level of hierarchical facets when activated
3874
+ // More to get the parent levels of the hierarchical facets when refined
3873
3875
  state.getRefinedHierarchicalFacets().forEach(function(refinedFacet) {
3874
3876
  var hierarchicalFacet = state.getHierarchicalFacetByName(refinedFacet);
3875
-
3876
3877
  var currentRefinement = state.getHierarchicalRefinement(refinedFacet);
3877
- // if we are deeper than level 0 (starting from `beer > IPA`)
3878
- // we want to get the root values
3879
3878
  var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);
3879
+
3880
+ // If we are deeper than level 0 (starting from `beer > IPA`)
3881
+ // we want to get all parent values
3880
3882
  if (currentRefinement.length > 0 && currentRefinement[0].split(separator).length > 1) {
3881
- queries.push({
3882
- indexName: index,
3883
- params: requestBuilder._getDisjunctiveFacetSearchParams(state, refinedFacet, true)
3883
+ // We generate a map of the filters we will use for our facet values queries
3884
+ var filtersMap = currentRefinement[0].split(separator).slice(0, -1).reduce(
3885
+ function createFiltersMap(map, segment, level) {
3886
+ return map.concat({
3887
+ attribute: hierarchicalFacet.attributes[level],
3888
+ value: level === 0
3889
+ ? segment
3890
+ : [map[map.length - 1].value, segment].join(separator)
3891
+ });
3892
+ }
3893
+ , []);
3894
+
3895
+ filtersMap.forEach(function(filter, level) {
3896
+ var params = requestBuilder._getDisjunctiveFacetSearchParams(
3897
+ state,
3898
+ filter.attribute,
3899
+ level === 0
3900
+ );
3901
+
3902
+ var parent = filtersMap[level - 1];
3903
+ params.facetFilters = level > 0 ? [parent.attribute + ':' + parent.value] : undefined;
3904
+
3905
+ queries.push({indexName: index, params: params});
3884
3906
  });
3885
3907
  }
3886
3908
  });
@@ -4163,7 +4185,7 @@
4163
4185
 
4164
4186
  var requestBuilder_1 = requestBuilder;
4165
4187
 
4166
- var version = '3.8.2';
4188
+ var version = '3.8.3';
4167
4189
 
4168
4190
  var escapeFacetValue$3 = escapeFacetValue_1.escapeFacetValue;
4169
4191
 
@@ -7692,7 +7714,8 @@
7692
7714
  var index = _ref.index,
7693
7715
  widgetType = _ref.widgetType,
7694
7716
  methodName = _ref.methodName,
7695
- args = _ref.args;
7717
+ args = _ref.args,
7718
+ isSearchStalled = _ref.isSearchStalled;
7696
7719
 
7697
7720
  // when there's only one argument, that means it's custom
7698
7721
  if (args.length === 1 && _typeof(args[0]) === 'object') {
@@ -7735,6 +7758,10 @@
7735
7758
  });
7736
7759
 
7737
7760
  if (eventType === 'view') {
7761
+ if (isSearchStalled) {
7762
+ return [];
7763
+ }
7764
+
7738
7765
  return hitsChunks.map(function (batch, i) {
7739
7766
  return {
7740
7767
  insightsMethod: 'viewedObjectIDs',
@@ -7803,7 +7830,8 @@
7803
7830
  widgetType: widgetType,
7804
7831
  index: index,
7805
7832
  methodName: 'sendEvent',
7806
- args: args
7833
+ args: args,
7834
+ isSearchStalled: instantSearchInstance._isSearchStalled
7807
7835
  });
7808
7836
  payloads.forEach(function (payload) {
7809
7837
  return instantSearchInstance.sendEventToInsights(payload);
@@ -7825,7 +7853,8 @@
7825
7853
  widgetType: widgetType,
7826
7854
  index: index,
7827
7855
  methodName: 'bindEvent',
7828
- args: args
7856
+ args: args,
7857
+ isSearchStalled: false
7829
7858
  });
7830
7859
  return payloads.length ? "data-insights-event=".concat(serializePayload(payloads)) : '';
7831
7860
  };
@@ -8536,7 +8565,7 @@
8536
8565
  instantSearchInstance.renderState = _objectSpread2(_objectSpread2({}, instantSearchInstance.renderState), {}, _defineProperty({}, parentIndexName, _objectSpread2(_objectSpread2({}, instantSearchInstance.renderState[parentIndexName]), renderState)));
8537
8566
  }
8538
8567
 
8539
- var version$1 = '4.40.6';
8568
+ var version$1 = '4.41.2';
8540
8569
 
8541
8570
  var NAMESPACE = 'ais';
8542
8571
  var component = function component(componentName) {
@@ -10026,10 +10055,9 @@
10026
10055
 
10027
10056
  function defaultCreateURL() {
10028
10057
  return '#';
10029
- }
10030
- /**
10031
- * Global options for an InstantSearch instance.
10032
- */
10058
+ } // this purposely breaks typescript's type inference to ensure it's not used
10059
+ // as it's used for a default parameter for example
10060
+ // source: https://github.com/Microsoft/TypeScript/issues/14829#issuecomment-504042546
10033
10061
 
10034
10062
 
10035
10063
  /**
@@ -10446,9 +10474,17 @@
10446
10474
  defer(function () {
10447
10475
  _this3.scheduleSearch = originalScheduleSearch;
10448
10476
  })();
10449
- } else {
10450
- this.scheduleSearch();
10451
- } // Keep the previous reference for legacy purpose, some pattern use
10477
+ } // We only schedule a search when widgets have been added before `start()`
10478
+ // because there are listeners that can use these results.
10479
+ // This is especially useful in framework-based flavors that wait for
10480
+ // dynamically-added widgets to trigger a network request. It avoids
10481
+ // having to batch this initial network request with the one coming from
10482
+ // `addWidgets()`.
10483
+ // Later, we could also skip `index()` widgets and widgets that don't read
10484
+ // the results, but this is an optimization that has a very low impact for now.
10485
+ else if (this.mainIndex.getWidgets().length > 0) {
10486
+ this.scheduleSearch();
10487
+ } // Keep the previous reference for legacy purpose, some pattern use
10452
10488
  // the direct Helper access `search.helper` (e.g multi-index).
10453
10489
 
10454
10490