instantsearch.js 4.63.1 → 4.64.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 (30) hide show
  1. package/cjs/connectors/numeric-menu/connectNumericMenu.js +5 -5
  2. package/cjs/connectors/rating-menu/connectRatingMenu.js +1 -2
  3. package/cjs/connectors/refinement-list/connectRefinementList.js +1 -2
  4. package/cjs/connectors/toggle-refinement/connectToggleRefinement.js +1 -1
  5. package/cjs/lib/InstantSearch.js +2 -6
  6. package/cjs/lib/server.js +27 -4
  7. package/cjs/lib/utils/hydrateSearchClient.js +10 -7
  8. package/cjs/lib/version.js +1 -1
  9. package/cjs/middlewares/createInsightsMiddleware.js +57 -21
  10. package/dist/instantsearch.development.d.ts +4 -6
  11. package/dist/instantsearch.development.js +93 -54
  12. package/dist/instantsearch.development.js.map +1 -1
  13. package/dist/instantsearch.production.d.ts +4 -6
  14. package/dist/instantsearch.production.min.d.ts +4 -6
  15. package/dist/instantsearch.production.min.js +2 -2
  16. package/dist/instantsearch.production.min.js.map +1 -1
  17. package/es/connectors/numeric-menu/connectNumericMenu.js +5 -5
  18. package/es/connectors/rating-menu/connectRatingMenu.js +1 -2
  19. package/es/connectors/refinement-list/connectRefinementList.js +1 -2
  20. package/es/connectors/toggle-refinement/connectToggleRefinement.js +1 -1
  21. package/es/lib/InstantSearch.d.ts +2 -6
  22. package/es/lib/InstantSearch.js +2 -6
  23. package/es/lib/server.d.ts +8 -3
  24. package/es/lib/server.js +27 -4
  25. package/es/lib/utils/hydrateSearchClient.js +10 -7
  26. package/es/lib/version.d.ts +1 -1
  27. package/es/lib/version.js +1 -1
  28. package/es/middlewares/createInsightsMiddleware.js +57 -21
  29. package/es/types/results.d.ts +2 -0
  30. package/package.json +6 -6
@@ -82,7 +82,7 @@ var connectNumericMenu = function connectNumericMenu(renderFn) {
82
82
  dispose: function dispose(_ref4) {
83
83
  var state = _ref4.state;
84
84
  unmountFn();
85
- return state.clearRefinements(attribute);
85
+ return state.removeNumericRefinement(attribute);
86
86
  },
87
87
  getWidgetUiState: function getWidgetUiState(uiState, _ref5) {
88
88
  var searchParameters = _ref5.searchParameters;
@@ -102,11 +102,11 @@ var connectNumericMenu = function connectNumericMenu(renderFn) {
102
102
  getWidgetSearchParameters: function getWidgetSearchParameters(searchParameters, _ref6) {
103
103
  var uiState = _ref6.uiState;
104
104
  var value = uiState.numericMenu && uiState.numericMenu[attribute];
105
- var withoutRefinements = searchParameters.clearRefinements(attribute);
105
+ var withoutRefinements = searchParameters.setQueryParameters({
106
+ numericRefinements: _objectSpread(_objectSpread({}, searchParameters.numericRefinements), {}, _defineProperty({}, attribute, {}))
107
+ });
106
108
  if (!value) {
107
- return withoutRefinements.setQueryParameters({
108
- numericRefinements: _objectSpread(_objectSpread({}, withoutRefinements.numericRefinements), {}, _defineProperty({}, attribute, {}))
109
- });
109
+ return withoutRefinements;
110
110
  }
111
111
  var isExact = value.indexOf(':') === -1;
112
112
  if (isExact) {
@@ -263,8 +263,7 @@ var connectRatingMenu = function connectRatingMenu(renderFn) {
263
263
  getWidgetSearchParameters: function getWidgetSearchParameters(searchParameters, _ref8) {
264
264
  var uiState = _ref8.uiState;
265
265
  var value = uiState.ratingMenu && uiState.ratingMenu[attribute];
266
- var withoutRefinements = searchParameters.clearRefinements(attribute);
267
- var withDisjunctiveFacet = withoutRefinements.addDisjunctiveFacet(attribute);
266
+ var withDisjunctiveFacet = searchParameters.addDisjunctiveFacet(attribute).removeNumericRefinement(attribute).removeDisjunctiveFacetRefinement(attribute);
268
267
  if (!value) {
269
268
  return withDisjunctiveFacet.setQueryParameters({
270
269
  numericRefinements: _objectSpread(_objectSpread({}, withDisjunctiveFacet.numericRefinements), {}, _defineProperty({}, attribute, {}))
@@ -259,8 +259,7 @@ var connectRefinementList = function connectRefinementList(renderFn) {
259
259
  return searchParameters;
260
260
  }
261
261
  var values = uiState.refinementList && uiState.refinementList[attribute];
262
- var withoutRefinements = searchParameters.clearRefinements(attribute);
263
- var withFacetConfiguration = isDisjunctive ? withoutRefinements.addDisjunctiveFacet(attribute) : withoutRefinements.addFacet(attribute);
262
+ var withFacetConfiguration = isDisjunctive ? searchParameters.addDisjunctiveFacet(attribute).removeDisjunctiveFacetRefinement(attribute) : searchParameters.addFacet(attribute).removeFacetRefinement(attribute);
264
263
  var currentMaxValuesPerFacet = withFacetConfiguration.maxValuesPerFacet || 0;
265
264
  var nextMaxValuesPerFacet = Math.max(currentMaxValuesPerFacet, showMore ? showMoreLimit : limit);
266
265
  var withMaxValuesPerFacet = withFacetConfiguration.setQueryParameter('maxValuesPerFacet', nextMaxValuesPerFacet);
@@ -277,7 +277,7 @@ var connectToggleRefinement = function connectToggleRefinement(renderFn) {
277
277
  process.env.NODE_ENV === 'development' ? warning(false, "ToggleRefinement: Attribute \"".concat(attribute, "\" is already used by another widget of a different type.\nAs this is not supported, please make sure to remove this other widget or this ToggleRefinement widget will not work at all.")) : void 0;
278
278
  return searchParameters;
279
279
  }
280
- var withFacetConfiguration = searchParameters.clearRefinements(attribute).addDisjunctiveFacet(attribute);
280
+ var withFacetConfiguration = searchParameters.addDisjunctiveFacet(attribute).removeDisjunctiveFacetRefinement(attribute);
281
281
  var isRefined = Boolean(uiState.toggle && uiState.toggle[attribute]);
282
282
  if (isRefined) {
283
283
  if (on) {
@@ -205,15 +205,11 @@ declare class InstantSearch<TUiState extends UiState = UiState, TRouteState = TU
205
205
  removeWidgets(widgets: Array<Widget | IndexWidget>): this;
206
206
  /**
207
207
  * Ends the initialization of InstantSearch.js and triggers the
208
- * first search. This method should be called after all widgets have been added
209
- * to the instance of InstantSearch.js. InstantSearch.js also supports adding and removing
210
- * widgets after the start as an **EXPERIMENTAL** feature.
208
+ * first search.
211
209
  */
212
210
  start(): void;
213
211
  /**
214
- * Removes all widgets without triggering a search afterwards. This is an **EXPERIMENTAL** feature,
215
- * if you find an issue with it, please
216
- * [open an issue](https://github.com/algolia/instantsearch/issues/new?title=Problem%20with%20dispose).
212
+ * Removes all widgets without triggering a search afterwards.
217
213
  * @return {undefined} This method does not return anything
218
214
  */
219
215
  dispose(): void;
@@ -357,9 +357,7 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
357
357
 
358
358
  /**
359
359
  * Ends the initialization of InstantSearch.js and triggers the
360
- * first search. This method should be called after all widgets have been added
361
- * to the instance of InstantSearch.js. InstantSearch.js also supports adding and removing
362
- * widgets after the start as an **EXPERIMENTAL** feature.
360
+ * first search.
363
361
  */
364
362
  }, {
365
363
  key: "start",
@@ -511,9 +509,7 @@ var InstantSearch = /*#__PURE__*/function (_EventEmitter) {
511
509
  }
512
510
 
513
511
  /**
514
- * Removes all widgets without triggering a search afterwards. This is an **EXPERIMENTAL** feature,
515
- * if you find an issue with it, please
516
- * [open an issue](https://github.com/algolia/instantsearch/issues/new?title=Problem%20with%20dispose).
512
+ * Removes all widgets without triggering a search afterwards.
517
513
  * @return {undefined} This method does not return anything
518
514
  */
519
515
  }, {
@@ -1,10 +1,15 @@
1
- import type { IndexWidget, InitialResults, InstantSearch } from '../types';
1
+ import type { IndexWidget, InitialResults, InstantSearch, SearchOptions } from '../types';
2
2
  /**
3
3
  * Waits for the results from the search instance to coordinate the next steps
4
4
  * in `getServerState()`.
5
5
  */
6
- export declare function waitForResults(search: InstantSearch): Promise<void>;
6
+ export declare function waitForResults(search: InstantSearch): Promise<SearchOptions[]>;
7
7
  /**
8
8
  * Walks the InstantSearch root index to construct the initial results.
9
9
  */
10
- export declare function getInitialResults(rootIndex: IndexWidget): InitialResults;
10
+ export declare function getInitialResults(rootIndex: IndexWidget,
11
+ /**
12
+ * Search parameters sent to the search client,
13
+ * returned by `waitForResults()`.
14
+ */
15
+ requestParamsList?: SearchOptions[]): InitialResults;
package/es/lib/server.js CHANGED
@@ -11,12 +11,26 @@ import { walkIndex } from "./utils/index.js";
11
11
  */
12
12
  export function waitForResults(search) {
13
13
  var helper = search.mainHelper;
14
+
15
+ // Extract search parameters from the search client to use them
16
+ // later during hydration.
17
+ var requestParamsList;
18
+ var client = helper.getClient();
19
+ helper.setClient({
20
+ search: function search(queries) {
21
+ requestParamsList = queries.map(function (_ref) {
22
+ var params = _ref.params;
23
+ return params;
24
+ });
25
+ return client.search(queries);
26
+ }
27
+ });
14
28
  helper.searchOnlyWithDerivedHelpers();
15
29
  return new Promise(function (resolve, reject) {
16
30
  // All derived helpers resolve in the same tick so we're safe only relying
17
31
  // on the first one.
18
32
  helper.derivedHelpers[0].on('result', function () {
19
- resolve();
33
+ resolve(requestParamsList);
20
34
  });
21
35
 
22
36
  // However, we listen to errors that can happen on any derived helper because
@@ -38,17 +52,26 @@ export function waitForResults(search) {
38
52
  /**
39
53
  * Walks the InstantSearch root index to construct the initial results.
40
54
  */
41
- export function getInitialResults(rootIndex) {
55
+ export function getInitialResults(rootIndex,
56
+ /**
57
+ * Search parameters sent to the search client,
58
+ * returned by `waitForResults()`.
59
+ */
60
+ requestParamsList) {
42
61
  var initialResults = {};
62
+ var requestParamsIndex = 0;
43
63
  walkIndex(rootIndex, function (widget) {
44
64
  var searchResults = widget.getResults();
45
65
  if (searchResults) {
46
- initialResults[widget.getIndexId()] = {
66
+ var requestParams = requestParamsList === null || requestParamsList === void 0 ? void 0 : requestParamsList[requestParamsIndex++];
67
+ initialResults[widget.getIndexId()] = _objectSpread({
47
68
  // We convert the Helper state to a plain object to pass parsable data
48
69
  // structures from server to client.
49
70
  state: _objectSpread({}, searchResults._state),
50
71
  results: searchResults._rawResults
51
- };
72
+ }, requestParams && {
73
+ requestParams: requestParams
74
+ });
52
75
  }
53
76
  });
54
77
  if (Object.keys(initialResults).length === 0) {
@@ -23,13 +23,16 @@ export function hydrateSearchClient(client, results) {
23
23
  return;
24
24
  }
25
25
  var cachedRequest = Object.keys(results).map(function (key) {
26
- return results[key].results.map(function (result) {
27
- return {
28
- indexName: result.index,
29
- // We normalize the params received from the server as they can
30
- // be serialized differently depending on the engine.
31
- params: serializeQueryParameters(deserializeQueryParameters(result.params))
32
- };
26
+ var _results$key = results[key],
27
+ state = _results$key.state,
28
+ requestParams = _results$key.requestParams,
29
+ serverResults = _results$key.results;
30
+ return serverResults.map(function (result) {
31
+ return _objectSpread({
32
+ indexName: state.index || result.index
33
+ }, requestParams || result.params ? {
34
+ params: serializeQueryParameters(requestParams || deserializeQueryParameters(result.params))
35
+ } : {});
33
36
  });
34
37
  });
35
38
  var cachedResults = Object.keys(results).reduce(function (acc, key) {
@@ -1,2 +1,2 @@
1
- declare const _default: "4.63.1";
1
+ declare const _default: "4.64.1";
2
2
  export default _default;
package/es/lib/version.js CHANGED
@@ -1 +1 @@
1
- export default '4.63.1';
1
+ export default '4.64.1';
@@ -74,8 +74,11 @@ export function createInsightsMiddleware() {
74
74
  // search-insights.js also throws an error so dev-only clarification is sufficient
75
75
  process.env.NODE_ENV === 'development' ? warning(Boolean(appId && apiKey), 'could not extract Algolia credentials from searchClient in insights middleware.') : void 0;
76
76
  var queuedUserToken = undefined;
77
+ var queuedAuthenticatedUserToken = undefined;
77
78
  var userTokenBeforeInit = undefined;
78
- if (Array.isArray(insightsClient.queue)) {
79
+ var authenticatedUserTokenBeforeInit = undefined;
80
+ var queue = insightsClient.queue;
81
+ if (Array.isArray(queue)) {
79
82
  // Context: The umd build of search-insights is asynchronously loaded by the snippet.
80
83
  //
81
84
  // When user calls `aa('setUserToken', 'my-user-token')` before `search-insights` is loaded,
@@ -86,22 +89,32 @@ export function createInsightsMiddleware() {
86
89
  // At this point, even though `search-insights` is not loaded yet,
87
90
  // we still want to read the token from the queue.
88
91
  // Otherwise, the first search call will be fired without the token.
89
- var _ref3 = find(insightsClient.queue.slice().reverse(), function (_ref5) {
90
- var _ref6 = _slicedToArray(_ref5, 1),
91
- method = _ref6[0];
92
- return method === 'setUserToken';
93
- }) || [];
94
- var _ref4 = _slicedToArray(_ref3, 2);
95
- queuedUserToken = _ref4[1];
92
+ var _map = ['setUserToken', 'setAuthenticatedUserToken'].map(function (key) {
93
+ var _ref3 = find(queue.slice().reverse(), function (_ref5) {
94
+ var _ref6 = _slicedToArray(_ref5, 1),
95
+ method = _ref6[0];
96
+ return method === key;
97
+ }) || [],
98
+ _ref4 = _slicedToArray(_ref3, 2),
99
+ value = _ref4[1];
100
+ return value;
101
+ });
102
+ var _map2 = _slicedToArray(_map, 2);
103
+ queuedUserToken = _map2[0];
104
+ queuedAuthenticatedUserToken = _map2[1];
96
105
  }
106
+
107
+ // If user called `aa('setUserToken')` or `aa('setAuthenticatedUserToken')`
108
+ // before creating the Insights middleware, we temporarily store the token
109
+ // and set it later on.
110
+ //
111
+ // Otherwise, the `init` call might override them with anonymous user token.
97
112
  insightsClient('getUserToken', null, function (_error, userToken) {
98
- // If user has called `aa('setUserToken', 'my-user-token')` before creating
99
- // the `insights` middleware, we store them temporarily and
100
- // set it later on.
101
- //
102
- // Otherwise, the `init` call might override it with anonymous user token.
103
113
  userTokenBeforeInit = normalizeUserToken(userToken);
104
114
  });
115
+ insightsClient('getAuthenticatedUserToken', null, function (_error, userToken) {
116
+ authenticatedUserTokenBeforeInit = normalizeUserToken(userToken);
117
+ });
105
118
 
106
119
  // Only `init` if the `insightsInitParams` option is passed or
107
120
  // if the `insightsClient` version doesn't supports optional `init` calling.
@@ -183,21 +196,43 @@ export function createInsightsMiddleware() {
183
196
  // We can set it as userToken.
184
197
  setUserTokenToSearch(anonymousUserToken, true);
185
198
  }
199
+ function setUserToken(token, userToken, authenticatedUserToken) {
200
+ setUserTokenToSearch(token, true);
201
+ if (userToken) {
202
+ insightsClient('setUserToken', userToken);
203
+ }
204
+ if (authenticatedUserToken) {
205
+ insightsClient('setAuthenticatedUserToken', authenticatedUserToken);
206
+ }
207
+ }
186
208
 
187
- // We consider the `userToken` coming from a `init` call to have a higher
188
- // importance than the one coming from the queue.
189
- if (userTokenBeforeInit) {
190
- setUserTokenToSearch(userTokenBeforeInit, true);
191
- insightsClient('setUserToken', userTokenBeforeInit);
192
- } else if (queuedUserToken) {
193
- setUserTokenToSearch(queuedUserToken, true);
194
- insightsClient('setUserToken', queuedUserToken);
209
+ // We consider the `userToken` or `authenticatedUserToken` before an
210
+ // `init` call of higher importance than one from the queue.
211
+ var tokenBeforeInit = authenticatedUserTokenBeforeInit || userTokenBeforeInit;
212
+ var queuedToken = queuedAuthenticatedUserToken || queuedUserToken;
213
+ if (tokenBeforeInit) {
214
+ setUserToken(tokenBeforeInit, userTokenBeforeInit, authenticatedUserTokenBeforeInit);
215
+ } else if (queuedToken) {
216
+ setUserToken(queuedToken, queuedUserToken, queuedAuthenticatedUserToken);
195
217
  }
196
218
 
197
219
  // This updates userToken which is set explicitly by `aa('setUserToken', userToken)`
198
220
  insightsClient('onUserTokenChange', setUserTokenToSearch, {
199
221
  immediate: true
200
222
  });
223
+
224
+ // This updates userToken which is set explicitly by `aa('setAuthenticatedtUserToken', authenticatedUserToken)`
225
+ insightsClient('onAuthenticatedUserTokenChange', function (authenticatedUserToken) {
226
+ // If we're unsetting the `authenticatedUserToken`, we revert to the `userToken`
227
+ if (!authenticatedUserToken) {
228
+ insightsClient('getUserToken', null, function (_, userToken) {
229
+ setUserTokenToSearch(userToken);
230
+ });
231
+ }
232
+ setUserTokenToSearch(authenticatedUserToken);
233
+ }, {
234
+ immediate: true
235
+ });
201
236
  var insightsClientWithLocalCredentials = insightsClient;
202
237
  if (isModernInsightsClient(insightsClient)) {
203
238
  insightsClientWithLocalCredentials = function insightsClientWithLocalCredentials(method, payload) {
@@ -233,6 +268,7 @@ export function createInsightsMiddleware() {
233
268
  },
234
269
  unsubscribe: function unsubscribe() {
235
270
  insightsClient('onUserTokenChange', undefined);
271
+ insightsClient('onAuthenticatedUserTokenChange', undefined);
236
272
  instantSearchInstance.sendEventToInsights = noop;
237
273
  if (helper && initialParameters) {
238
274
  helper.overrideStateWithoutTriggeringChangeEvent(_objectSpread(_objectSpread({}, helper.state), initialParameters));
@@ -1,3 +1,4 @@
1
+ import type { SearchOptions } from './algoliasearch';
1
2
  import type { PlainSearchParameters, SearchForFacetValues, SearchResults } from 'algoliasearch-helper';
2
3
  export type HitAttributeHighlightResult = {
3
4
  value: string;
@@ -66,6 +67,7 @@ export type Refinement = FacetRefinement | NumericRefinement;
66
67
  type InitialResult = {
67
68
  state: PlainSearchParameters;
68
69
  results: SearchResults['_rawResults'];
70
+ requestParams?: SearchOptions;
69
71
  };
70
72
  export type InitialResults = Record<string, InitialResult>;
71
73
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instantsearch.js",
3
- "version": "4.63.1",
3
+ "version": "4.64.1",
4
4
  "description": "InstantSearch.js is a JavaScript library for building performant and instant search experiences with Algolia.",
5
5
  "homepage": "https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/",
6
6
  "types": "es/index.d.ts",
@@ -33,7 +33,7 @@
33
33
  "@types/google.maps": "^3.45.3",
34
34
  "@types/hogan.js": "^3.0.0",
35
35
  "@types/qs": "^6.5.3",
36
- "algoliasearch-helper": "3.16.1",
36
+ "algoliasearch-helper": "3.16.2",
37
37
  "hogan.js": "^3.0.2",
38
38
  "htm": "^3.0.0",
39
39
  "preact": "^10.10.0",
@@ -55,9 +55,9 @@
55
55
  "version": "./scripts/version/update-version.js"
56
56
  },
57
57
  "devDependencies": {
58
- "@instantsearch/mocks": "1.33.0",
59
- "@instantsearch/tests": "1.33.0",
60
- "@instantsearch/testutils": "1.22.0",
58
+ "@instantsearch/mocks": "1.35.0",
59
+ "@instantsearch/tests": "1.35.0",
60
+ "@instantsearch/testutils": "1.24.0",
61
61
  "@storybook/html": "5.3.9",
62
62
  "@types/scriptjs": "0.0.2",
63
63
  "algoliasearch": "4.14.3",
@@ -65,5 +65,5 @@
65
65
  "scriptjs": "2.5.9",
66
66
  "webpack": "4.47.0"
67
67
  },
68
- "gitHead": "4e99d1220b9c7872130f52bded4c1a84900bd0a3"
68
+ "gitHead": "3f061b181adf4358629406027eec8f79d2577196"
69
69
  }