vue-instantsearch 4.1.1 → 4.2.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 (40) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/package.json +5 -5
  3. package/src/components/DynamicWidgets.js +1 -1
  4. package/src/components/ExperimentalDynamicWidgets.js +10 -0
  5. package/src/components/__tests__/ExperimentalDynamicWidgets.js +41 -0
  6. package/src/mixins/widget.js +1 -1
  7. package/src/util/__tests__/createServerRootMixin.test.js +141 -61
  8. package/src/util/createServerRootMixin.js +36 -107
  9. package/src/util/testutils/helper.js +2 -2
  10. package/src/widgets.js +3 -0
  11. package/vue2/cjs/index.js +1 -1
  12. package/vue2/cjs/index.js.map +1 -1
  13. package/vue2/es/package.json.js +1 -1
  14. package/vue2/es/src/components/DynamicWidgets.js +1 -1
  15. package/vue2/es/src/components/DynamicWidgets.js.map +1 -1
  16. package/vue2/es/src/components/ExperimentalDynamicWidgets.js +2 -0
  17. package/vue2/es/src/components/ExperimentalDynamicWidgets.js.map +1 -0
  18. package/vue2/es/src/instantsearch.js +1 -1
  19. package/vue2/es/src/mixins/widget.js +1 -1
  20. package/vue2/es/src/mixins/widget.js.map +1 -1
  21. package/vue2/es/src/util/createServerRootMixin.js +1 -1
  22. package/vue2/es/src/util/createServerRootMixin.js.map +1 -1
  23. package/vue2/es/src/widgets.js +1 -1
  24. package/vue2/umd/index.js +1 -1
  25. package/vue2/umd/index.js.map +1 -1
  26. package/vue3/cjs/index.js +1 -1
  27. package/vue3/cjs/index.js.map +1 -1
  28. package/vue3/es/package.json.js +1 -1
  29. package/vue3/es/src/components/DynamicWidgets.js +1 -1
  30. package/vue3/es/src/components/DynamicWidgets.js.map +1 -1
  31. package/vue3/es/src/components/ExperimentalDynamicWidgets.js +2 -0
  32. package/vue3/es/src/components/ExperimentalDynamicWidgets.js.map +1 -0
  33. package/vue3/es/src/instantsearch.js +1 -1
  34. package/vue3/es/src/mixins/widget.js +1 -1
  35. package/vue3/es/src/mixins/widget.js.map +1 -1
  36. package/vue3/es/src/util/createServerRootMixin.js +1 -1
  37. package/vue3/es/src/util/createServerRootMixin.js.map +1 -1
  38. package/vue3/es/src/widgets.js +1 -1
  39. package/vue3/umd/index.js +1 -1
  40. package/vue3/umd/index.js.map +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ # [4.2.0](https://github.com/algolia/vue-instantsearch/compare/v4.1.1...v4.2.0) (2021-12-13)
2
+
3
+
4
+ ### Features
5
+
6
+ * **dynamicWidgets:** release as production ([#1086](https://github.com/algolia/vue-instantsearch/issues/1086)) ([9e0902b](https://github.com/algolia/vue-instantsearch/commit/9e0902bc7a3afe3eb2211b78e681e65b3677dd78))
7
+ * **instantsearch:** update version ([dbf485f](https://github.com/algolia/vue-instantsearch/commit/dbf485f6263d9821aaf169e682ff1ab94157d15f))
8
+ * **ssr:** prevent initial network request ([#1090](https://github.com/algolia/vue-instantsearch/issues/1090)) ([d97eea2](https://github.com/algolia/vue-instantsearch/commit/d97eea21fbd059b0ca0634a6984a6a8b02acdd3d))
9
+
10
+
11
+
1
12
  ## [4.1.1](https://github.com/algolia/vue-instantsearch/compare/v4.1.0...v4.1.1) (2021-10-27)
2
13
 
3
14
 
package/package.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "autocomplete"
17
17
  ],
18
18
  "license": "MIT",
19
- "version": "4.1.1",
19
+ "version": "4.2.0",
20
20
  "files": [
21
21
  "vue2",
22
22
  "vue3",
@@ -48,8 +48,7 @@
48
48
  "release": "shipjs prepare"
49
49
  },
50
50
  "dependencies": {
51
- "algoliasearch-helper": "^3.6.2",
52
- "instantsearch.js": "^4.32.0",
51
+ "instantsearch.js": "^4.35.0",
53
52
  "mitt": "^2.1.0"
54
53
  },
55
54
  "peerDependencies": {
@@ -82,6 +81,7 @@
82
81
  "@wdio/spec-reporter": "^5.11.7",
83
82
  "@wdio/static-server-service": "^5.11.0",
84
83
  "algoliasearch": "4.0.1",
84
+ "algoliasearch-helper": "3.7.0",
85
85
  "babel-eslint": "10.0.1",
86
86
  "babel-jest": "23.6.0",
87
87
  "babel-preset-es2015": "6.24.1",
@@ -132,11 +132,11 @@
132
132
  "bundlesize": [
133
133
  {
134
134
  "path": "./vue2/umd/index.js",
135
- "maxSize": "55.25 kB"
135
+ "maxSize": "56.00 kB"
136
136
  },
137
137
  {
138
138
  "path": "./vue3/umd/index.js",
139
- "maxSize": "56.75 kB"
139
+ "maxSize": "57.00 kB"
140
140
  },
141
141
  {
142
142
  "path": "./vue2/cjs/index.js",
@@ -40,7 +40,7 @@ function getWidgetAttribute(vnode) {
40
40
  }
41
41
 
42
42
  export default {
43
- name: 'AisExperimentalDynamicWidgets',
43
+ name: 'AisDynamicWidgets',
44
44
  mixins: [
45
45
  createWidgetMixin({ connector: connectDynamicWidgets }),
46
46
  createSuitMixin({ name: 'DynamicWidgets' }),
@@ -0,0 +1,10 @@
1
+ import AisDynamicWidgets from './DynamicWidgets';
2
+ import { warn } from '../util/warn';
3
+
4
+ // @MAJOR remove this file
5
+ export default Object.assign({}, AisDynamicWidgets, {
6
+ name: 'AisExperimentalDynamicWidgets',
7
+ mounted() {
8
+ warn('Use AisDynamicWidgets instead of AisExperimentalDynamicWidgets.');
9
+ },
10
+ });
@@ -0,0 +1,41 @@
1
+ import { mount } from '../../../test/utils';
2
+ import ExperimentalDynamicWidgets from '../ExperimentalDynamicWidgets';
3
+ import { warn } from '../../util/warn';
4
+ import { __setState } from '../../mixins/widget';
5
+ import DynamicWidgets from '../DynamicWidgets';
6
+
7
+ jest.mock('../../mixins/widget');
8
+ jest.mock('../../util/warn', () => ({ warn: jest.fn() }));
9
+
10
+ it('warns on mount', () => {
11
+ __setState(null);
12
+
13
+ mount({
14
+ template: '<ExperimentalDynamicWidgets />',
15
+ components: {
16
+ ExperimentalDynamicWidgets,
17
+ },
18
+ });
19
+ expect(warn).toHaveBeenCalledTimes(1);
20
+ expect(warn.mock.calls[0][0]).toMatchInlineSnapshot(
21
+ `"Use AisDynamicWidgets instead of AisExperimentalDynamicWidgets."`
22
+ );
23
+ });
24
+
25
+ it('behaves the same as DynamicWidgets', () => {
26
+ Object.keys(ExperimentalDynamicWidgets).forEach(key => {
27
+ if (key === 'name') {
28
+ // name is different
29
+ expect(ExperimentalDynamicWidgets[key]).toBe(
30
+ 'AisExperimentalDynamicWidgets'
31
+ );
32
+ } else if (key === 'mounted') {
33
+ // mounted has the warning
34
+ expect(ExperimentalDynamicWidgets[key]).toEqual(expect.any(Function));
35
+ } else if (key[0] === '_') {
36
+ // private Vue behavior, not tested
37
+ } else {
38
+ expect(ExperimentalDynamicWidgets[key]).toEqual(DynamicWidgets[key]);
39
+ }
40
+ });
41
+ });
@@ -31,7 +31,7 @@ export const createWidgetMixin = ({ connector } = {}) => ({
31
31
  this.getParentIndex().addWidgets([this.widget]);
32
32
 
33
33
  if (
34
- this.instantSearchInstance.__initialSearchResults &&
34
+ this.instantSearchInstance._initialResults &&
35
35
  !this.instantSearchInstance.started
36
36
  ) {
37
37
  if (typeof this.instantSearchInstance.__forceRender !== 'function') {
@@ -11,9 +11,9 @@ import { createFakeClient } from '../testutils/client';
11
11
  import { createSerializedState } from '../testutils/helper';
12
12
  import { isVue3, isVue2, Vue2, renderCompat } from '../vue-compat';
13
13
  import {
14
- SearchResults,
15
- SearchParameters,
16
14
  AlgoliaSearchHelper,
15
+ SearchParameters,
16
+ SearchResults,
17
17
  } from 'algoliasearch-helper';
18
18
 
19
19
  jest.unmock('instantsearch.js/es');
@@ -57,9 +57,11 @@ describe('createServerRootMixin', () => {
57
57
  }),
58
58
  ],
59
59
  })
60
- ).toThrowErrorMatchingInlineSnapshot(
61
- `"createServerRootMixin requires \`searchClient\` and \`indexName\` in the first argument"`
62
- );
60
+ ).toThrowErrorMatchingInlineSnapshot(`
61
+ "The \`searchClient\` option is required.
62
+
63
+ See documentation: https://www.algolia.com/doc/api-reference/widgets/instantsearch/js/"
64
+ `);
63
65
  });
64
66
 
65
67
  it('requires indexName', () => {
@@ -72,9 +74,11 @@ describe('createServerRootMixin', () => {
72
74
  }),
73
75
  ],
74
76
  })
75
- ).toThrowErrorMatchingInlineSnapshot(
76
- `"createServerRootMixin requires \`searchClient\` and \`indexName\` in the first argument"`
77
- );
77
+ ).toThrowErrorMatchingInlineSnapshot(`
78
+ "The \`indexName\` option is required.
79
+
80
+ See documentation: https://www.algolia.com/doc/api-reference/widgets/instantsearch/js/"
81
+ `);
78
82
  });
79
83
 
80
84
  it('creates an instantsearch instance on "data"', () => {
@@ -301,14 +305,13 @@ Array [
301
305
  renderToString,
302
306
  });
303
307
  expect(state).toEqual({
304
- __identifier: 'stringified',
305
308
  hello: {
306
- _rawResults: [
309
+ results: [
307
310
  {
308
311
  query: '',
309
312
  },
310
313
  ],
311
- _state: {
314
+ state: {
312
315
  disjunctiveFacets: [],
313
316
  disjunctiveFacetsRefinements: {},
314
317
  facets: [],
@@ -534,7 +537,7 @@ Array [
534
537
  this.instantsearch.mainIndex.getWidgets().map(w => w.$$type)
535
538
  ).toEqual(['ais.configure']);
536
539
 
537
- expect(res.hello._state.hitsPerPage).toBe(100);
540
+ expect(res.hello.state.hitsPerPage).toBe(100);
538
541
  })
539
542
  // jest throws an error we need to catch, since stuck in the flow
540
543
  .catch(e => {
@@ -656,11 +659,73 @@ Array [
656
659
 
657
660
  await renderToString(wrapper);
658
661
  });
662
+
663
+ it('searches only once', async () => {
664
+ const searchClient = createFakeClient();
665
+ const app = {
666
+ mixins: [
667
+ forceIsServerMixin,
668
+ createServerRootMixin({
669
+ searchClient,
670
+ indexName: 'hello',
671
+ }),
672
+ ],
673
+ render: renderCompat(h =>
674
+ /**
675
+ * This code triggers this warning in Vue 3:
676
+ * > Non-function value encountered for default slot. Prefer function slots for better performance.
677
+ *
678
+ * To fix it, replace the third argument
679
+ * > [h(...), h(...)]
680
+ * with
681
+ * > { default: () => [h(...), h(...)] }
682
+ *
683
+ * but it's not important (and not compatible in vue2), we're leaving it as-is.
684
+ */
685
+ h(InstantSearchSsr, {}, [
686
+ h(Configure, {
687
+ attrs: {
688
+ hitsPerPage: 100,
689
+ },
690
+ }),
691
+ h(SearchBox),
692
+ ])
693
+ ),
694
+ serverPrefetch() {
695
+ return this.instantsearch.findResultsState({
696
+ component: this,
697
+ renderToString,
698
+ });
699
+ },
700
+ };
701
+
702
+ const wrapper = createSSRApp({
703
+ mixins: [forceIsServerMixin],
704
+ render: renderCompat(h => h(app)),
705
+ });
706
+
707
+ await renderToString(wrapper);
708
+
709
+ expect(searchClient.search).toHaveBeenCalledTimes(1);
710
+ expect(searchClient.search.mock.calls[0][0]).toMatchInlineSnapshot(`
711
+ Array [
712
+ Object {
713
+ "indexName": "hello",
714
+ "params": Object {
715
+ "facets": Array [],
716
+ "hitsPerPage": 100,
717
+ "query": "",
718
+ "tagFilters": "",
719
+ },
720
+ },
721
+ ]
722
+ `);
723
+ });
659
724
  }
660
725
  });
661
726
 
662
727
  describe('hydrate', () => {
663
- it('sets __initialSearchResults', () => {
728
+ it('sets _initialResults', () => {
664
729
  const serialized = createSerializedState();
665
730
 
666
731
  const app = {
@@ -683,7 +748,6 @@ Array [
683
748
  // in test, beforeCreated doesn't have $data yet, but IRL it does
684
749
  created() {
685
750
  this.instantsearch.hydrate({
686
- __identifier: 'stringified',
687
751
  hello: serialized,
688
752
  });
689
753
  },
@@ -693,57 +757,20 @@ Array [
693
757
  vm: { instantsearch },
694
758
  } = mount(app);
695
759
 
696
- expect(instantsearch.__initialSearchResults).toEqual(
697
- expect.objectContaining({ hello: expect.any(SearchResults) })
760
+ expect(instantsearch._initialResults).toEqual(
761
+ expect.objectContaining({
762
+ hello: {
763
+ state: expect.any(Object),
764
+ results: expect.any(Object),
765
+ },
766
+ })
698
767
  );
699
768
 
700
- expect(instantsearch.__initialSearchResults.hello).toEqual(
769
+ expect(instantsearch._initialResults.hello).toEqual(
701
770
  expect.objectContaining(serialized)
702
771
  );
703
772
  });
704
773
 
705
- it('accepts non-stringified results', () => {
706
- const serialized = createSerializedState();
707
- const nonSerialized = new SearchResults(
708
- new SearchParameters(serialized._state),
709
- serialized._rawResults
710
- );
711
-
712
- const app = {
713
- mixins: [
714
- createServerRootMixin({
715
- searchClient: createFakeClient(),
716
- indexName: 'movies',
717
- }),
718
- ],
719
- render: renderCompat(h =>
720
- h(InstantSearchSsr, {}, [
721
- h(Configure, {
722
- attrs: {
723
- hitsPerPage: 100,
724
- },
725
- }),
726
- h(SearchBox),
727
- ])
728
- ),
729
- created() {
730
- this.instantsearch.hydrate({
731
- movies: nonSerialized,
732
- });
733
-
734
- expect(this.instantsearch.__initialSearchResults).toEqual(
735
- expect.objectContaining({ movies: expect.any(SearchResults) })
736
- );
737
-
738
- expect(this.instantsearch.__initialSearchResults.movies).toEqual(
739
- nonSerialized
740
- );
741
- },
742
- };
743
-
744
- mount(app);
745
- });
746
-
747
774
  it('inits the main index', () => {
748
775
  const serialized = createSerializedState();
749
776
 
@@ -773,7 +800,6 @@ Array [
773
800
  expect(instantsearch.mainIndex.getHelper()).toBe(null);
774
801
 
775
802
  instantsearch.hydrate({
776
- __identifier: 'stringified',
777
803
  hello: serialized,
778
804
  });
779
805
 
@@ -812,7 +838,6 @@ Array [
812
838
  expect(instantsearch.mainHelper).toBe(null);
813
839
 
814
840
  instantsearch.hydrate({
815
- __identifier: 'stringified',
816
841
  hello: serialized,
817
842
  });
818
843
 
@@ -834,6 +859,7 @@ Array [
834
859
  created() {
835
860
  instantSearchInstance = this.instantsearch;
836
861
  },
862
+ render() {},
837
863
  });
838
864
 
839
865
  const widget = {
@@ -894,6 +920,58 @@ Object {
894
920
  );
895
921
  });
896
922
 
923
+ it('uses the results passed to hydrate for rendering', () => {
924
+ let instantSearchInstance;
925
+ mount({
926
+ mixins: [
927
+ createServerRootMixin({
928
+ searchClient: createFakeClient(),
929
+ indexName: 'lol',
930
+ }),
931
+ ],
932
+ created() {
933
+ instantSearchInstance = this.instantsearch;
934
+ },
935
+ render() {},
936
+ });
937
+
938
+ const widget = {
939
+ init: jest.fn(),
940
+ render: jest.fn(),
941
+ };
942
+
943
+ const resultsState = createSerializedState();
944
+ const state = new SearchParameters(resultsState.state);
945
+ const results = new SearchResults(state, resultsState.results);
946
+
947
+ instantSearchInstance.hydrate({
948
+ lol: resultsState,
949
+ });
950
+
951
+ instantSearchInstance.__forceRender(
952
+ widget,
953
+ instantSearchInstance.mainIndex
954
+ );
955
+
956
+ expect(widget.init).toHaveBeenCalledTimes(0);
957
+ expect(widget.render).toHaveBeenCalledTimes(1);
958
+
959
+ const renderArgs = widget.render.mock.calls[0][0];
960
+
961
+ expect(renderArgs).toEqual(
962
+ expect.objectContaining({
963
+ state,
964
+ results,
965
+ scopedResults: [
966
+ expect.objectContaining({
967
+ indexId: 'lol',
968
+ results,
969
+ }),
970
+ ],
971
+ })
972
+ );
973
+ });
974
+
897
975
  describe('createURL', () => {
898
976
  it('returns # if instantsearch has no routing', () => {
899
977
  let instantSearchInstance;
@@ -907,6 +985,7 @@ Object {
907
985
  created() {
908
986
  instantSearchInstance = this.instantsearch;
909
987
  },
988
+ render() {},
910
989
  });
911
990
 
912
991
  const widget = {
@@ -940,6 +1019,7 @@ Object {
940
1019
  created() {
941
1020
  instantSearchInstance = this.instantsearch;
942
1021
  },
1022
+ render() {},
943
1023
  });
944
1024
 
945
1025
  const widget = {
@@ -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) {
@@ -76,18 +74,10 @@ function defaultCloneComponent(componentInstance, { mixins = [] } = {}) {
76
74
  return app;
77
75
  }
78
76
 
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);
77
+ function augmentInstantSearch(instantSearchOptions, cloneComponent) {
88
78
  const search = instantsearch(instantSearchOptions);
89
79
 
90
- let resultsState;
80
+ let initialResults;
91
81
 
92
82
  /**
93
83
  * main API for SSR, called in serverPrefetch of a root component which contains instantsearch
@@ -104,7 +94,7 @@ function augmentInstantSearch(
104
94
  }
105
95
 
106
96
  let app;
107
- let renderedComponent;
97
+ let instance;
108
98
 
109
99
  return Promise.resolve()
110
100
  .then(() => {
@@ -112,55 +102,36 @@ function augmentInstantSearch(
112
102
  mixins: [
113
103
  {
114
104
  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
- });
105
+ instance = this.instantsearch;
106
+
107
+ instance.start();
108
+ // although we use start for initializing the main index,
109
+ // we don't want to send search requests yet
110
+ instance.started = false;
125
111
  },
126
112
  },
127
113
  ],
128
114
  });
129
115
  })
130
116
  .then(() => renderToString(app))
131
- .then(() => searchOnlyWithDerivedHelpers(helper))
117
+ .then(() => searchOnlyWithDerivedHelpers(instance.mainHelper))
132
118
  .then(() => {
133
- const results = {};
134
- walkIndex(renderedComponent.instantsearch.mainIndex, widget => {
135
- results[widget.getIndexId()] = widget.getResults();
119
+ initialResults = {};
120
+ walkIndex(instance.mainIndex, widget => {
121
+ const { _state, _rawResults } = widget.getResults();
122
+
123
+ initialResults[widget.getIndexId()] = {
124
+ // copy just the values of SearchParameters, not the functions
125
+ state: Object.keys(_state).reduce((acc, key) => {
126
+ // eslint-disable-next-line no-param-reassign
127
+ acc[key] = _state[key];
128
+ return acc;
129
+ }, {}),
130
+ results: _rawResults,
131
+ };
136
132
  });
137
133
 
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
- );
134
+ search.hydrate(initialResults);
164
135
  return search.getState();
165
136
  });
166
137
  };
@@ -169,10 +140,10 @@ function augmentInstantSearch(
169
140
  * @returns {Promise} result state to serialize and enter into .hydrate
170
141
  */
171
142
  search.getState = function() {
172
- if (!resultsState) {
143
+ if (!initialResults) {
173
144
  throw new Error('You need to wait for findResultsState to finish');
174
145
  }
175
- return resultsState;
146
+ return initialResults;
176
147
  };
177
148
 
178
149
  /**
@@ -184,18 +155,17 @@ function augmentInstantSearch(
184
155
  * @returns {void}
185
156
  */
186
157
  search.__forceRender = function(widget, parent) {
187
- const localHelper = parent.getHelper();
188
-
189
- const results = search.__initialSearchResults[parent.getIndexId()];
158
+ const results = parent.getResults();
190
159
 
191
160
  // this happens when a different InstantSearch gets rendered initially,
192
161
  // after the hydrate finished. There's thus no initial results available.
193
- if (!results) {
162
+ if (results === null) {
194
163
  return;
195
164
  }
196
165
 
197
166
  const state = results._state;
198
167
 
168
+ const localHelper = parent.getHelper();
199
169
  // helper gets created in init, but that means it doesn't get the injected
200
170
  // parameters, because those are from the lastResults
201
171
  localHelper.state = state;
@@ -203,11 +173,7 @@ function augmentInstantSearch(
203
173
  widget.render({
204
174
  helper: localHelper,
205
175
  results,
206
- scopedResults: parent.getScopedResults().map(result =>
207
- Object.assign(result, {
208
- results: search.__initialSearchResults[result.indexId],
209
- })
210
- ),
176
+ scopedResults: parent.getScopedResults(),
211
177
  parent,
212
178
  state,
213
179
  templatesConfig: {},
@@ -232,55 +198,18 @@ function augmentInstantSearch(
232
198
  return;
233
199
  }
234
200
 
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;
201
+ search._initialResults = results;
250
202
 
251
- search.helper = helper;
252
- search.mainHelper = helper;
253
-
254
- search.mainIndex.init({
255
- instantSearchInstance: search,
256
- parent: null,
257
- uiState: search._initialUiState,
258
- });
203
+ search.start();
204
+ search.started = false;
259
205
  };
260
-
261
- /* eslint-enable no-param-reassign */
262
206
  return search;
263
207
  }
264
208
 
265
209
  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
- }
210
+ const { $cloneComponent = defaultCloneComponent } = instantSearchOptions;
277
211
 
278
- const search = augmentInstantSearch(
279
- instantSearchOptions,
280
- searchClient,
281
- indexName,
282
- $cloneComponent
283
- );
212
+ const search = augmentInstantSearch(instantSearchOptions, $cloneComponent);
284
213
 
285
214
  // put this in the user's root Vue instance
286
215
  // we can then reuse that InstantSearch instance seamlessly from `ais-instant-search-ssr`
@@ -292,7 +221,7 @@ export function createServerRootMixin(instantSearchOptions = {}) {
292
221
  },
293
222
  data() {
294
223
  return {
295
- // this is in data, so that the real & duplicated render do not share
224
+ // this is in data, so that the real & cloned render do not share
296
225
  // the same instantsearch instance.
297
226
  instantsearch: search,
298
227
  };
@@ -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';