vue-instantsearch 3.6.0 → 3.9.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 (96) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/vue-instantsearch.common.js +1 -1
  3. package/dist/vue-instantsearch.common.js.map +1 -1
  4. package/dist/vue-instantsearch.js +1 -1
  5. package/dist/vue-instantsearch.js.map +1 -1
  6. package/es/package.json.js +1 -1
  7. package/es/src/components/Breadcrumb.vue.js +1 -1
  8. package/es/src/components/Breadcrumb.vue.js.map +1 -1
  9. package/es/src/components/ClearRefinements.vue.js +1 -1
  10. package/es/src/components/ClearRefinements.vue.js.map +1 -1
  11. package/es/src/components/CurrentRefinements.vue.js +1 -1
  12. package/es/src/components/CurrentRefinements.vue.js.map +1 -1
  13. package/es/src/components/DynamicWidgets.js +2 -0
  14. package/es/src/components/DynamicWidgets.js.map +1 -0
  15. package/es/src/components/HierarchicalMenu.vue.js +1 -1
  16. package/es/src/components/HierarchicalMenu.vue.js.map +1 -1
  17. package/es/src/components/Highlighter.vue.js.map +1 -1
  18. package/es/src/components/Hits.vue.js +1 -1
  19. package/es/src/components/Hits.vue.js.map +1 -1
  20. package/es/src/components/HitsPerPage.vue.js +1 -1
  21. package/es/src/components/HitsPerPage.vue.js.map +1 -1
  22. package/es/src/components/InfiniteHits.vue.js +1 -1
  23. package/es/src/components/InfiniteHits.vue.js.map +1 -1
  24. package/es/src/components/InstantSearch.js +1 -1
  25. package/es/src/components/InstantSearch.js.map +1 -1
  26. package/es/src/components/Menu.vue.js +1 -1
  27. package/es/src/components/Menu.vue.js.map +1 -1
  28. package/es/src/components/MenuSelect.vue.js +1 -1
  29. package/es/src/components/MenuSelect.vue.js.map +1 -1
  30. package/es/src/components/NumericMenu.vue.js +1 -1
  31. package/es/src/components/NumericMenu.vue.js.map +1 -1
  32. package/es/src/components/Pagination.vue.js +1 -1
  33. package/es/src/components/Pagination.vue.js.map +1 -1
  34. package/es/src/components/QueryRuleContext.js +1 -1
  35. package/es/src/components/QueryRuleContext.js.map +1 -1
  36. package/es/src/components/QueryRuleCustomData.vue.js +1 -1
  37. package/es/src/components/QueryRuleCustomData.vue.js.map +1 -1
  38. package/es/src/components/RangeInput.vue.js +1 -1
  39. package/es/src/components/RangeInput.vue.js.map +1 -1
  40. package/es/src/components/RatingMenu.vue.js +1 -1
  41. package/es/src/components/RatingMenu.vue.js.map +1 -1
  42. package/es/src/components/RefinementList.vue.js +1 -1
  43. package/es/src/components/RefinementList.vue.js.map +1 -1
  44. package/es/src/components/SortBy.vue.js +1 -1
  45. package/es/src/components/SortBy.vue.js.map +1 -1
  46. package/es/src/components/ToggleRefinement.vue.js +1 -1
  47. package/es/src/components/ToggleRefinement.vue.js.map +1 -1
  48. package/es/src/instantsearch.js +1 -1
  49. package/es/src/mixins/widget.js +1 -1
  50. package/es/src/mixins/widget.js.map +1 -1
  51. package/es/src/util/createInstantSearchComponent.js +1 -1
  52. package/es/src/util/createInstantSearchComponent.js.map +1 -1
  53. package/es/src/util/createServerRootMixin.js +1 -1
  54. package/es/src/util/createServerRootMixin.js.map +1 -1
  55. package/es/src/widgets.js +1 -1
  56. package/package.json +5 -5
  57. package/src/__tests__/index.js +2 -0
  58. package/src/components/Breadcrumb.vue +3 -5
  59. package/src/components/ClearRefinements.vue +3 -7
  60. package/src/components/CurrentRefinements.vue +3 -7
  61. package/src/components/DynamicWidgets.js +87 -0
  62. package/src/components/HierarchicalMenu.vue +8 -11
  63. package/src/components/Highlighter.vue +16 -4
  64. package/src/components/Hits.vue +2 -3
  65. package/src/components/HitsPerPage.vue +1 -4
  66. package/src/components/InfiniteHits.vue +2 -3
  67. package/src/components/InstantSearch.js +11 -7
  68. package/src/components/Menu.vue +5 -8
  69. package/src/components/MenuSelect.vue +2 -3
  70. package/src/components/NumericMenu.vue +2 -3
  71. package/src/components/Pagination.vue +1 -1
  72. package/src/components/QueryRuleContext.js +1 -1
  73. package/src/components/QueryRuleCustomData.vue +1 -1
  74. package/src/components/RangeInput.vue +3 -0
  75. package/src/components/RatingMenu.vue +2 -1
  76. package/src/components/RefinementList.vue +8 -7
  77. package/src/components/SortBy.vue +1 -3
  78. package/src/components/ToggleRefinement.vue +1 -2
  79. package/src/components/__tests__/DynamicWidgets.js +419 -0
  80. package/src/components/__tests__/HierarchicalMenu.js +23 -0
  81. package/src/components/__tests__/Hits.js +22 -1
  82. package/src/components/__tests__/InfiniteHits.js +21 -0
  83. package/src/components/__tests__/InstantSearch-integration.js +155 -1
  84. package/src/components/__tests__/Menu.js +22 -0
  85. package/src/components/__tests__/MenuSelect.js +22 -0
  86. package/src/components/__tests__/NumericMenu.js +22 -0
  87. package/src/components/__tests__/RangeInput.js +22 -0
  88. package/src/components/__tests__/RatingMenu.js +23 -0
  89. package/src/components/__tests__/RefinementList.js +22 -0
  90. package/src/components/__tests__/ToggleRefinement.js +22 -0
  91. package/src/mixins/widget.js +1 -1
  92. package/src/util/__tests__/createServerRootMixin.test.js +229 -83
  93. package/src/util/createInstantSearchComponent.js +16 -0
  94. package/src/util/createServerRootMixin.js +40 -104
  95. package/src/util/testutils/helper.js +2 -2
  96. package/src/widgets.js +1 -0
@@ -1,7 +1,5 @@
1
1
  import Vue from 'vue';
2
2
  import instantsearch from 'instantsearch.js/es';
3
- import algoliaHelper from 'algoliasearch-helper';
4
- const { SearchResults, SearchParameters } = algoliaHelper;
5
3
  import { warn } from './warn';
6
4
 
7
5
  function walkIndex(indexWidget, visit) {
@@ -53,7 +51,10 @@ function defaultCloneComponent(componentInstance) {
53
51
 
54
52
  const Extended = componentInstance.$vnode
55
53
  ? componentInstance.$vnode.componentOptions.Ctor.extend(options)
56
- : Vue.component(Object.assign({}, componentInstance.$options, options));
54
+ : Vue.component(
55
+ options.name,
56
+ Object.assign({}, componentInstance.$options, options)
57
+ );
57
58
 
58
59
  const app = new Extended({
59
60
  propsData: componentInstance.$options.propsData,
@@ -67,18 +68,10 @@ function defaultCloneComponent(componentInstance) {
67
68
  return app;
68
69
  }
69
70
 
70
- function augmentInstantSearch(
71
- instantSearchOptions,
72
- searchClient,
73
- indexName,
74
- cloneComponent
75
- ) {
76
- /* eslint-disable no-param-reassign */
77
-
78
- const helper = algoliaHelper(searchClient, indexName);
71
+ function augmentInstantSearch(instantSearchOptions, cloneComponent) {
79
72
  const search = instantsearch(instantSearchOptions);
80
73
 
81
- let resultsState;
74
+ let initialResults;
82
75
 
83
76
  /**
84
77
  * main API for SSR, called in serverPrefetch of a root component which contains instantsearch
@@ -97,54 +90,38 @@ function augmentInstantSearch(
97
90
  }
98
91
 
99
92
  let app;
93
+ let instance;
100
94
 
101
95
  return Promise.resolve()
102
96
  .then(() => {
103
97
  app = cloneComponent(componentInstance);
104
98
 
105
- app.instantsearch.helper = helper;
106
- app.instantsearch.mainHelper = helper;
99
+ instance = app.instantsearch;
107
100
 
108
- app.instantsearch.mainIndex.init({
109
- instantSearchInstance: app.instantsearch,
110
- parent: null,
111
- uiState: app.instantsearch._initialUiState,
112
- });
101
+ instance.start();
102
+ // although we use start for initializing the main index,
103
+ // we don't want to send search requests yet
104
+ instance.started = false;
113
105
  })
114
106
  .then(() => renderToString(app, _renderToString))
115
- .then(() => searchOnlyWithDerivedHelpers(helper))
107
+ .then(() => searchOnlyWithDerivedHelpers(instance.mainHelper))
116
108
  .then(() => {
117
- const results = {};
118
- walkIndex(app.instantsearch.mainIndex, widget => {
119
- results[widget.getIndexId()] = widget.getResults();
109
+ initialResults = {};
110
+ walkIndex(instance.mainIndex, widget => {
111
+ const { _state, _rawResults } = widget.getResults();
112
+
113
+ initialResults[widget.getIndexId()] = {
114
+ // copy just the values of SearchParameters, not the functions
115
+ state: Object.keys(_state).reduce((acc, key) => {
116
+ // eslint-disable-next-line no-param-reassign
117
+ acc[key] = _state[key];
118
+ return acc;
119
+ }, {}),
120
+ results: _rawResults,
121
+ };
120
122
  });
121
123
 
122
- search.hydrate(results);
123
-
124
- resultsState = Object.keys(results)
125
- .map(indexId => {
126
- const { _state, _rawResults } = results[indexId];
127
- return [
128
- indexId,
129
- {
130
- // copy just the values of SearchParameters, not the functions
131
- _state: Object.keys(_state).reduce((acc, key) => {
132
- acc[key] = _state[key];
133
- return acc;
134
- }, {}),
135
- _rawResults,
136
- },
137
- ];
138
- })
139
- .reduce(
140
- (acc, [key, val]) => {
141
- acc[key] = val;
142
- return acc;
143
- },
144
- {
145
- __identifier: 'stringified',
146
- }
147
- );
124
+ search.hydrate(initialResults);
148
125
  return search.getState();
149
126
  });
150
127
  };
@@ -153,10 +130,10 @@ function augmentInstantSearch(
153
130
  * @returns {Promise} result state to serialize and enter into .hydrate
154
131
  */
155
132
  search.getState = function() {
156
- if (!resultsState) {
133
+ if (!initialResults) {
157
134
  throw new Error('You need to wait for findResultsState to finish');
158
135
  }
159
- return resultsState;
136
+ return initialResults;
160
137
  };
161
138
 
162
139
  /**
@@ -168,18 +145,17 @@ function augmentInstantSearch(
168
145
  * @returns {void}
169
146
  */
170
147
  search.__forceRender = function(widget, parent) {
171
- const localHelper = parent.getHelper();
172
-
173
- const results = search.__initialSearchResults[parent.getIndexId()];
148
+ const results = parent.getResults();
174
149
 
175
150
  // this happens when a different InstantSearch gets rendered initially,
176
151
  // after the hydrate finished. There's thus no initial results available.
177
- if (!results) {
152
+ if (results === null) {
178
153
  return;
179
154
  }
180
155
 
181
156
  const state = results._state;
182
157
 
158
+ const localHelper = parent.getHelper();
183
159
  // helper gets created in init, but that means it doesn't get the injected
184
160
  // parameters, because those are from the lastResults
185
161
  localHelper.state = state;
@@ -187,11 +163,8 @@ function augmentInstantSearch(
187
163
  widget.render({
188
164
  helper: localHelper,
189
165
  results,
190
- scopedResults: parent.getScopedResults().map(result =>
191
- Object.assign(result, {
192
- results: search.__initialSearchResults[result.indexId],
193
- })
194
- ),
166
+ scopedResults: parent.getScopedResults(),
167
+ parent,
195
168
  state,
196
169
  templatesConfig: {},
197
170
  createURL: parent.createURL,
@@ -215,55 +188,18 @@ function augmentInstantSearch(
215
188
  return;
216
189
  }
217
190
 
218
- const initialResults =
219
- results.__identifier === 'stringified'
220
- ? Object.keys(results).reduce((acc, indexId) => {
221
- if (indexId === '__identifier') {
222
- return acc;
223
- }
224
- acc[indexId] = new SearchResults(
225
- new SearchParameters(results[indexId]._state),
226
- results[indexId]._rawResults
227
- );
228
- return acc;
229
- }, {})
230
- : results;
231
-
232
- search.__initialSearchResults = initialResults;
191
+ search._initialResults = results;
233
192
 
234
- search.helper = helper;
235
- search.mainHelper = helper;
236
-
237
- search.mainIndex.init({
238
- instantSearchInstance: search,
239
- parent: null,
240
- uiState: search._initialUiState,
241
- });
193
+ search.start();
194
+ search.started = false;
242
195
  };
243
-
244
- /* eslint-enable no-param-reassign */
245
196
  return search;
246
197
  }
247
198
 
248
199
  export function createServerRootMixin(instantSearchOptions = {}) {
249
- const {
250
- searchClient,
251
- indexName,
252
- $cloneComponent = defaultCloneComponent,
253
- } = instantSearchOptions;
254
-
255
- if (!searchClient || !indexName) {
256
- throw new Error(
257
- 'createServerRootMixin requires `searchClient` and `indexName` in the first argument'
258
- );
259
- }
200
+ const { $cloneComponent = defaultCloneComponent } = instantSearchOptions;
260
201
 
261
- const search = augmentInstantSearch(
262
- instantSearchOptions,
263
- searchClient,
264
- indexName,
265
- $cloneComponent
266
- );
202
+ const search = augmentInstantSearch(instantSearchOptions, $cloneComponent);
267
203
 
268
204
  // put this in the user's root Vue instance
269
205
  // we can then reuse that InstantSearch instance seamlessly from `ais-instant-search-ssr`
@@ -275,7 +211,7 @@ export function createServerRootMixin(instantSearchOptions = {}) {
275
211
  },
276
212
  data() {
277
213
  return {
278
- // this is in data, so that the real & duplicated render do not share
214
+ // this is in data, so that the real & cloned render do not share
279
215
  // the same instantsearch instance.
280
216
  instantsearch: search,
281
217
  };
@@ -1,5 +1,5 @@
1
1
  export const createSerializedState = () => ({
2
- _rawResults: [
2
+ results: [
3
3
  {
4
4
  hits: [
5
5
  {
@@ -50,7 +50,7 @@ export const createSerializedState = () => ({
50
50
  index: 'movies',
51
51
  },
52
52
  ],
53
- _state: {
53
+ state: {
54
54
  index: 'movies',
55
55
  query: 'hi',
56
56
  facets: [],
package/src/widgets.js CHANGED
@@ -43,3 +43,4 @@ export {
43
43
  } from './components/ToggleRefinement.vue';
44
44
  export { default as AisVoiceSearch } from './components/VoiceSearch.vue';
45
45
  export { default as AisRelevantSort } from './components/RelevantSort.vue';
46
+ export { default as AisDynamicWidgets } from './components/DynamicWidgets';