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