From 06efa758b5f0b39f352ece716d7a0c9f0fb68009 Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Mon, 15 Apr 2019 15:16:41 +0200 Subject: [PATCH 01/48] feat(client): remove algoliaClient alias --- .../src/components/InstantSearch.tsx | 1 - .../__snapshots__/createInstantSearch.js.snap | 40 ---- .../src/core/__tests__/createInstantSearch.js | 176 ++++++++---------- .../src/core/createInstantSearch.js | 16 +- .../__tests__/createInstantSearchServer.js | 71 +------ .../src/core/createInstantSearchServer.js | 13 +- 6 files changed, 79 insertions(+), 238 deletions(-) delete mode 100644 packages/react-instantsearch-core/src/core/__tests__/__snapshots__/createInstantSearch.js.snap diff --git a/packages/react-instantsearch-core/src/components/InstantSearch.tsx b/packages/react-instantsearch-core/src/components/InstantSearch.tsx index 3ce7767647..f651b4368e 100644 --- a/packages/react-instantsearch-core/src/components/InstantSearch.tsx +++ b/packages/react-instantsearch-core/src/components/InstantSearch.tsx @@ -85,7 +85,6 @@ type State = { * @propType {string} apiKey - Your Algolia search-only API key. * @propType {string} indexName - Main index in which to search. * @propType {boolean} [refresh=false] - Flag to activate when the cache needs to be cleared so that the front-end is updated when a change occurs in the index. - * @propType {object} [algoliaClient] - Provide a custom Algolia client instead of the internal one (deprecated in favor of `searchClient`). * @propType {object} [searchClient] - Provide a custom search client. * @propType {func} [onSearchStateChange] - Function to be called everytime a new search is done. Useful for [URL Routing](guide/Routing.html). * @propType {object} [searchState] - Object to inject some search state. Switches the InstantSearch component in controlled mode. Useful for [URL Routing](guide/Routing.html). diff --git a/packages/react-instantsearch-core/src/core/__tests__/__snapshots__/createInstantSearch.js.snap b/packages/react-instantsearch-core/src/core/__tests__/__snapshots__/createInstantSearch.js.snap deleted file mode 100644 index bf6924ec07..0000000000 --- a/packages/react-instantsearch-core/src/core/__tests__/__snapshots__/createInstantSearch.js.snap +++ /dev/null @@ -1,40 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`createInstantSearch expect to create InstantSearch with a custom root props 1`] = ` -Object { - "children": undefined, - "createURL": undefined, - "indexName": "name", - "onSearchParameters": undefined, - "onSearchStateChange": undefined, - "refresh": false, - "resultsState": undefined, - "root": Object { - "Root": "span", - "props": Object { - "style": Object { - "flex": 1, - }, - }, - }, - "searchState": undefined, - "stalledSearchDelay": 200, -} -`; - -exports[`createInstantSearch wraps InstantSearch 1`] = ` -Object { - "children": undefined, - "createURL": undefined, - "indexName": "name", - "onSearchParameters": undefined, - "onSearchStateChange": undefined, - "refresh": false, - "resultsState": undefined, - "root": Object { - "Root": "div", - }, - "searchState": undefined, - "stalledSearchDelay": 200, -} -`; diff --git a/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js b/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js index ba3ad28923..9ca756740b 100644 --- a/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js +++ b/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js @@ -8,15 +8,15 @@ import version from '../version'; Enzyme.configure({ adapter: new Adapter() }); describe('createInstantSearch', () => { - const algoliaClient = { addAlgoliaAgent: jest.fn() }; - const algoliaClientFactory = jest.fn(() => algoliaClient); - const CustomInstantSearch = createInstantSearch(algoliaClientFactory, { + const searchClient = { addAlgoliaAgent: jest.fn() }; + const searchClientFactory = jest.fn(() => searchClient); + const CustomInstantSearch = createInstantSearch(searchClientFactory, { Root: 'div', }); beforeEach(() => { - algoliaClient.addAlgoliaAgent.mockClear(); - algoliaClientFactory.mockClear(); + searchClient.addAlgoliaAgent.mockClear(); + searchClientFactory.mockClear(); }); it('wraps InstantSearch', () => { @@ -24,59 +24,59 @@ describe('createInstantSearch', () => { ); - const { - algoliaClient, // eslint-disable-line no-shadow - searchClient, - ...propsWithoutClient - } = wrapper.props(); + // eslint-disable-next-line no-shadow + const { searchClient, ...propsWithoutClient } = wrapper.props(); expect(wrapper.is(InstantSearch)).toBe(true); - expect(propsWithoutClient).toMatchSnapshot(); - expect(wrapper.props().algoliaClient).toBe(algoliaClient); expect(wrapper.props().searchClient).toBe(searchClient); + expect(propsWithoutClient).toMatchInlineSnapshot(` + Object { + "children": undefined, + "createURL": undefined, + "indexName": "name", + "onSearchParameters": undefined, + "onSearchStateChange": undefined, + "refresh": false, + "resultsState": undefined, + "root": Object { + "Root": "div", + }, + "searchState": undefined, + "stalledSearchDelay": 200, + } + `); }); it('creates an algolia client using the provided factory', () => { shallow(); - expect(algoliaClientFactory).toHaveBeenCalledTimes(1); - expect(algoliaClientFactory).toHaveBeenCalledWith('app', 'key', { + expect(searchClientFactory).toHaveBeenCalledTimes(1); + expect(searchClientFactory).toHaveBeenCalledWith('app', 'key', { _useRequestCache: true, }); - expect(algoliaClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); - expect(algoliaClient.addAlgoliaAgent).toHaveBeenCalledWith( + expect(searchClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); + expect(searchClient.addAlgoliaAgent).toHaveBeenCalledWith( `react-instantsearch (${version})` ); - expect(algoliaClient.addAlgoliaAgent).toHaveBeenCalledWith( + expect(searchClient.addAlgoliaAgent).toHaveBeenCalledWith( `react (${React.version})` ); }); - it('throws if algoliaClient is given with searchClient', () => { - const trigger = () => - shallow( - - ); - - expect(() => trigger()).toThrow(); - }); - it('throws if appId is given with searchClient', () => { const trigger = () => shallow( ); - expect(() => trigger()).toThrow(); + expect(() => trigger()).toThrowErrorMatchingInlineSnapshot( + `"react-instantsearch:: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` + ); }); it('throws if apiKey is given with searchClient', () => { @@ -85,14 +85,16 @@ describe('createInstantSearch', () => { ); - expect(() => trigger()).toThrow(); + expect(() => trigger()).toThrowErrorMatchingInlineSnapshot( + `"react-instantsearch:: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` + ); }); - it('updates the algoliaClient when appId or apiKey changes', () => { + it('updates the searchClient when appId or apiKey changes', () => { const wrapper = shallow( ); @@ -100,29 +102,19 @@ describe('createInstantSearch', () => { wrapper.setProps({ appId: 'app2', apiKey: 'key' }); wrapper.setProps({ appId: 'app', apiKey: 'key2' }); - expect(algoliaClientFactory).toHaveBeenCalledTimes(3); - expect(algoliaClientFactory.mock.calls[1]).toEqual(['app2', 'key']); - expect(algoliaClientFactory.mock.calls[2]).toEqual(['app', 'key2']); + expect(searchClientFactory).toHaveBeenCalledTimes(3); + expect(searchClientFactory.mock.calls[1]).toEqual(['app2', 'key']); + expect(searchClientFactory.mock.calls[2]).toEqual(['app', 'key2']); }); it('uses the provided searchClient', () => { const wrapper = shallow( - + ); - expect(algoliaClientFactory).toHaveBeenCalledTimes(0); - expect(algoliaClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); - expect(wrapper.props().searchClient).toBe(algoliaClient); - }); - - it('uses the provided algoliaClient', () => { - const wrapper = shallow( - - ); - - expect(algoliaClientFactory).toHaveBeenCalledTimes(0); - expect(algoliaClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); - expect(wrapper.props().algoliaClient).toBe(algoliaClient); + expect(searchClientFactory).toHaveBeenCalledTimes(0); + expect(searchClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); + expect(wrapper.props().searchClient).toBe(searchClient); }); it('does not throw if searchClient does not have a `addAlgoliaAgent()` method', () => { @@ -133,62 +125,23 @@ describe('createInstantSearch', () => { expect(() => trigger()).not.toThrow(); }); - it('does not throw if algoliaClient does not have a `addAlgoliaAgent()` method', () => { - const client = {}; - const trigger = () => - shallow(); - - expect(() => trigger()).not.toThrow(); - }); - - it('updates the algoliaClient when provided algoliaClient is passed down', () => { - const newAlgoliaClient = { - addAlgoliaAgent: jest.fn(), - }; - - const wrapper = shallow( - - ); - - expect(algoliaClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); - - wrapper.setProps({ - algoliaClient: newAlgoliaClient, - }); - - expect(wrapper.props().algoliaClient).toBe(newAlgoliaClient); - expect(newAlgoliaClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); - }); - it('updates the searchClient when provided searchClient is passed down', () => { - const newAlgoliaClient = { + const newSearchClient = { addAlgoliaAgent: jest.fn(), }; const wrapper = shallow( - + ); - expect(algoliaClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); + expect(searchClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); wrapper.setProps({ - searchClient: newAlgoliaClient, + searchClient: newSearchClient, }); - expect(wrapper.props().searchClient).toBe(newAlgoliaClient); - expect(newAlgoliaClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); - }); - - it('does not throw when algoliaClient gets updated and does not have a `addAlgoliaAgent()` method', () => { - const client = {}; - const makeWrapper = () => - shallow(); - - expect(() => { - makeWrapper().setProps({ - algoliaClient: client, - }); - }).not.toThrow(); + expect(wrapper.props().searchClient).toBe(newSearchClient); + expect(newSearchClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); }); it('does not throw when searchClient gets updated and does not have a `addAlgoliaAgent()` method', () => { @@ -217,13 +170,30 @@ describe('createInstantSearch', () => { ); - const { - algoliaClient, // eslint-disable-line no-shadow, no-unused-vars - searchClient, // eslint-disable-line no-unused-vars - ...propsWithoutClient - } = wrapper.props(); + // eslint-disable-next-line no-shadow, no-unused-vars + const { searchClient, ...propsWithoutClient } = wrapper.props(); expect(wrapper.props().root).toEqual(root); - expect(propsWithoutClient).toMatchSnapshot(); + expect(propsWithoutClient).toMatchInlineSnapshot(` + Object { + "children": undefined, + "createURL": undefined, + "indexName": "name", + "onSearchParameters": undefined, + "onSearchStateChange": undefined, + "refresh": false, + "resultsState": undefined, + "root": Object { + "Root": "span", + "props": Object { + "style": Object { + "flex": 1, + }, + }, + }, + "searchState": undefined, + "stalledSearchDelay": 200, + } + `); }); }); diff --git a/packages/react-instantsearch-core/src/core/createInstantSearch.js b/packages/react-instantsearch-core/src/core/createInstantSearch.js index b0769c0056..1db1477075 100644 --- a/packages/react-instantsearch-core/src/core/createInstantSearch.js +++ b/packages/react-instantsearch-core/src/core/createInstantSearch.js @@ -13,7 +13,6 @@ import version from './version'; export default function createInstantSearch(defaultAlgoliaClient, root) { return class CreateInstantSearch extends Component { static propTypes = { - algoliaClient: PropTypes.object, searchClient: PropTypes.object, appId: PropTypes.string, apiKey: PropTypes.string, @@ -47,23 +46,15 @@ export default function createInstantSearch(defaultAlgoliaClient, root) { super(...args); if (this.props.searchClient) { - if (this.props.appId || this.props.apiKey || this.props.algoliaClient) { + if (this.props.appId || this.props.apiKey) { throw new Error( - 'react-instantsearch:: `searchClient` cannot be used with `appId`, `apiKey` or `algoliaClient`.' + 'react-instantsearch:: `searchClient` cannot be used with `appId` and `apiKey`.' ); } } - if (this.props.algoliaClient) { - // eslint-disable-next-line no-console - console.warn( - '`algoliaClient` option was renamed `searchClient`. Please use this new option before the next major version.' - ); - } - this.client = this.props.searchClient || - this.props.algoliaClient || defaultAlgoliaClient(this.props.appId, this.props.apiKey, { _useRequestCache: true, }); @@ -79,8 +70,6 @@ export default function createInstantSearch(defaultAlgoliaClient, root) { if (nextProps.searchClient) { this.client = nextProps.searchClient; - } else if (nextProps.algoliaClient) { - this.client = nextProps.algoliaClient; } else if ( props.appId !== nextProps.appId || props.apiKey !== nextProps.apiKey @@ -104,7 +93,6 @@ export default function createInstantSearch(defaultAlgoliaClient, root) { onSearchParameters={this.props.onSearchParameters} root={this.props.root} searchClient={this.client} - algoliaClient={this.client} refresh={this.props.refresh} resultsState={this.props.resultsState} > diff --git a/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js b/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js index bc268d02ce..98a4ed3d74 100644 --- a/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js +++ b/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js @@ -102,38 +102,6 @@ describe('createInstantSearchServer', () => { expect(wrapper.props().searchClient).toBe(searchClient); }); - it('uses the provided algoliaClient', () => { - const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}); - - const { InstantSearch } = createInstantSearchServer(); - - const algoliaClient = { - ...createSearchClient(), - addAlgoliaAgent: jest.fn(), - }; - - const props = { - ...requiredProps, - algoliaClient, - }; - - const wrapper = shallow(); - - expect(algoliaClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); - expect(algoliaClient.addAlgoliaAgent).toHaveBeenCalledWith( - `react (${React.version})` - ); - expect(algoliaClient.addAlgoliaAgent).toHaveBeenCalledWith( - `react-instantsearch (${version})` - ); - expect(wrapper.props().algoliaClient).toBe(algoliaClient); - expect(warnSpy.mock.calls[0][0]).toMatchInlineSnapshot( - `"\`algoliaClient\` option was renamed \`searchClient\`. Please use this new option before the next major version."` - ); - - warnSpy.mockRestore(); - }); - it('does not throw if searchClient does not have a `addAlgoliaAgent()` method', () => { const { InstantSearch } = createInstantSearchServer(); @@ -147,41 +115,6 @@ describe('createInstantSearchServer', () => { expect(() => trigger()).not.toThrow(); }); - it('does not throw if algoliaClient does not have a `addAlgoliaAgent()` method', () => { - const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}); - const { InstantSearch } = createInstantSearchServer(); - - const props = { - ...requiredProps, - algoliaClient: createSearchClient(), - }; - - const trigger = () => shallow(); - - expect(() => trigger()).not.toThrow(); - expect(warnSpy.mock.calls[0][0]).toMatchInlineSnapshot( - `"\`algoliaClient\` option was renamed \`searchClient\`. Please use this new option before the next major version."` - ); - warnSpy.mockRestore(); - }); - - it('throws if algoliaClient is given with searchClient', () => { - const { InstantSearch } = createInstantSearchServer(); - - const props = { - ...requiredProps, - searchClient: createSearchClient(), - algoliaClient: createSearchClient(), - }; - - const trigger = () => - shallow(); - - expect(() => trigger()).toThrowErrorMatchingInlineSnapshot( - `"react-instantsearch:: \`searchClient\` cannot be used with \`appId\`, \`apiKey\` or \`algoliaClient\`."` - ); - }); - it('throws if appId is given with searchClient', () => { const { InstantSearch } = createInstantSearchServer(); @@ -194,7 +127,7 @@ describe('createInstantSearchServer', () => { const trigger = () => shallow(); expect(() => trigger()).toThrowErrorMatchingInlineSnapshot( - `"react-instantsearch:: \`searchClient\` cannot be used with \`appId\`, \`apiKey\` or \`algoliaClient\`."` + `"react-instantsearch:: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` ); }); @@ -210,7 +143,7 @@ describe('createInstantSearchServer', () => { const trigger = () => shallow(); expect(() => trigger()).toThrowErrorMatchingInlineSnapshot( - `"react-instantsearch:: \`searchClient\` cannot be used with \`appId\`, \`apiKey\` or \`algoliaClient\`."` + `"react-instantsearch:: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` ); }); }); diff --git a/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js b/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js index 788f621c9d..d35290a1ea 100644 --- a/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js +++ b/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js @@ -133,7 +133,6 @@ const createInstantSearchServer = algoliasearch => { class CreateInstantSearchServer extends Component { static propTypes = { - algoliaClient: PropTypes.object, searchClient: PropTypes.object, appId: PropTypes.string, apiKey: PropTypes.string, @@ -145,23 +144,15 @@ const createInstantSearchServer = algoliasearch => { super(...args); if (this.props.searchClient) { - if (this.props.appId || this.props.apiKey || this.props.algoliaClient) { + if (this.props.appId || this.props.apiKey) { throw new Error( - 'react-instantsearch:: `searchClient` cannot be used with `appId`, `apiKey` or `algoliaClient`.' + 'react-instantsearch:: `searchClient` cannot be used with `appId` and `apiKey`.' ); } } - if (this.props.algoliaClient) { - // eslint-disable-next-line no-console - console.warn( - '`algoliaClient` option was renamed `searchClient`. Please use this new option before the next major version.' - ); - } - client = this.props.searchClient || - this.props.algoliaClient || algoliasearch(this.props.appId, this.props.apiKey); if (typeof client.addAlgoliaAgent === 'function') { From 00122847f3852d5cdc5b3c5d54beb9721a66aebd Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 17 Apr 2019 12:38:14 +0200 Subject: [PATCH 02/48] chore(error): remove duplicate colon --- .../src/core/__tests__/createInstantSearch.js | 74 +++++++++---------- .../src/core/createInstantSearch.js | 2 +- .../__tests__/createInstantSearchServer.js | 4 +- .../src/core/createInstantSearchServer.js | 2 +- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js b/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js index 9ca756740b..e9496e97a8 100644 --- a/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js +++ b/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js @@ -30,21 +30,21 @@ describe('createInstantSearch', () => { expect(wrapper.is(InstantSearch)).toBe(true); expect(wrapper.props().searchClient).toBe(searchClient); expect(propsWithoutClient).toMatchInlineSnapshot(` - Object { - "children": undefined, - "createURL": undefined, - "indexName": "name", - "onSearchParameters": undefined, - "onSearchStateChange": undefined, - "refresh": false, - "resultsState": undefined, - "root": Object { - "Root": "div", - }, - "searchState": undefined, - "stalledSearchDelay": 200, - } - `); + Object { + "children": undefined, + "createURL": undefined, + "indexName": "name", + "onSearchParameters": undefined, + "onSearchStateChange": undefined, + "refresh": false, + "resultsState": undefined, + "root": Object { + "Root": "div", + }, + "searchState": undefined, + "stalledSearchDelay": 200, + } + `); }); it('creates an algolia client using the provided factory', () => { @@ -75,7 +75,7 @@ describe('createInstantSearch', () => { ); expect(() => trigger()).toThrowErrorMatchingInlineSnapshot( - `"react-instantsearch:: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` + `"react-instantsearch: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` ); }); @@ -90,7 +90,7 @@ describe('createInstantSearch', () => { ); expect(() => trigger()).toThrowErrorMatchingInlineSnapshot( - `"react-instantsearch:: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` + `"react-instantsearch: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` ); }); @@ -175,25 +175,25 @@ describe('createInstantSearch', () => { expect(wrapper.props().root).toEqual(root); expect(propsWithoutClient).toMatchInlineSnapshot(` - Object { - "children": undefined, - "createURL": undefined, - "indexName": "name", - "onSearchParameters": undefined, - "onSearchStateChange": undefined, - "refresh": false, - "resultsState": undefined, - "root": Object { - "Root": "span", - "props": Object { - "style": Object { - "flex": 1, - }, - }, - }, - "searchState": undefined, - "stalledSearchDelay": 200, - } - `); + Object { + "children": undefined, + "createURL": undefined, + "indexName": "name", + "onSearchParameters": undefined, + "onSearchStateChange": undefined, + "refresh": false, + "resultsState": undefined, + "root": Object { + "Root": "span", + "props": Object { + "style": Object { + "flex": 1, + }, + }, + }, + "searchState": undefined, + "stalledSearchDelay": 200, + } + `); }); }); diff --git a/packages/react-instantsearch-core/src/core/createInstantSearch.js b/packages/react-instantsearch-core/src/core/createInstantSearch.js index 1db1477075..a176aa9df7 100644 --- a/packages/react-instantsearch-core/src/core/createInstantSearch.js +++ b/packages/react-instantsearch-core/src/core/createInstantSearch.js @@ -48,7 +48,7 @@ export default function createInstantSearch(defaultAlgoliaClient, root) { if (this.props.searchClient) { if (this.props.appId || this.props.apiKey) { throw new Error( - 'react-instantsearch:: `searchClient` cannot be used with `appId` and `apiKey`.' + 'react-instantsearch: `searchClient` cannot be used with `appId` and `apiKey`.' ); } } diff --git a/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js b/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js index 98a4ed3d74..09b6d18d14 100644 --- a/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js +++ b/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js @@ -127,7 +127,7 @@ describe('createInstantSearchServer', () => { const trigger = () => shallow(); expect(() => trigger()).toThrowErrorMatchingInlineSnapshot( - `"react-instantsearch:: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` + `"react-instantsearch: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` ); }); @@ -143,7 +143,7 @@ describe('createInstantSearchServer', () => { const trigger = () => shallow(); expect(() => trigger()).toThrowErrorMatchingInlineSnapshot( - `"react-instantsearch:: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` + `"react-instantsearch: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` ); }); }); diff --git a/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js b/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js index d35290a1ea..7d67985195 100644 --- a/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js +++ b/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js @@ -146,7 +146,7 @@ const createInstantSearchServer = algoliasearch => { if (this.props.searchClient) { if (this.props.appId || this.props.apiKey) { throw new Error( - 'react-instantsearch:: `searchClient` cannot be used with `appId` and `apiKey`.' + 'react-instantsearch: `searchClient` cannot be used with `appId` and `apiKey`.' ); } } From 6deac03ddedd6e94c53ff46ce32c6dfba9da5f0a Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 17 Apr 2019 13:41:05 +0200 Subject: [PATCH 03/48] docs(examples): use searchClient everywhere --- examples/autocomplete/src/App-Mentions.js | 12 +++--- examples/autocomplete/src/App-Multi-Index.js | 12 +++--- examples/geo-search/src/App.js | 9 +++- examples/multi-index/src/App.js | 12 +++--- examples/next/components/app.js | 9 +++- .../react-native-query-suggestions/App.js | 9 +++- examples/react-native/src/Categories.js | 9 +++- examples/react-native/src/Filters.js | 9 +++- examples/react-native/src/Home.js | 9 +++- examples/react-native/src/Price.js | 9 +++- examples/react-native/src/Rating.js | 9 +++- examples/react-native/src/Type.js | 9 +++- examples/react-router-v3/src/App.js | 9 +++- examples/react-router/src/App.js | 9 +++- .../server-side-rendering/src/app/index.js | 9 +++- .../src/components/Index.tsx | 9 +++- .../src/connectors/connectHighlight.js | 9 +++- .../src/connectors/connectHits.js | 8 +++- .../src/connectors/connectStateResults.js | 9 +++- .../src/widgets/Configure.js | 9 +++- .../src/widgets/Breadcrumb.js | 9 +++- .../src/widgets/ClearRefinements.js | 8 +++- .../src/widgets/CurrentRefinements.js | 9 +++- .../src/widgets/HierarchicalMenu.js | 9 +++- .../src/widgets/Highlight.js | 9 +++- .../src/widgets/Hits.js | 8 +++- .../src/widgets/HitsPerPage.js | 9 +++- .../src/widgets/InfiniteHits.js | 9 +++- .../src/widgets/Menu.js | 9 +++- .../src/widgets/MenuSelect.js | 10 ++++- .../src/widgets/NumericMenu.js | 9 +++- .../src/widgets/Pagination.js | 9 +++- .../src/widgets/Panel.js | 9 +++- .../src/widgets/PoweredBy.js | 9 +++- .../src/widgets/RangeInput.js | 9 +++- .../src/widgets/RatingMenu.js | 9 +++- .../src/widgets/RefinementList.js | 9 +++- .../src/widgets/ScrollTo.js | 9 +++- .../src/widgets/SearchBox.js | 9 +++- .../src/widgets/Snippet.js | 9 +++- .../src/widgets/SortBy.js | 9 +++- .../src/widgets/Stats.js | 9 +++- .../src/widgets/ToggleRefinement.js | 9 +++- stories/InstantSearch.stories.js | 26 ++++-------- stories/MultiIndex.stories.js | 42 ++++++------------- stories/util.js | 11 ++++- website/examples/default-theme/App.js | 9 +++- website/examples/e-commerce-infinite/App.js | 12 +++--- website/examples/e-commerce/App.js | 9 +++- website/examples/material-ui/App.js | 9 +++- website/examples/media/App.js | 9 +++- website/examples/tourism/App.js | 9 +++- 52 files changed, 371 insertions(+), 159 deletions(-) diff --git a/examples/autocomplete/src/App-Mentions.js b/examples/autocomplete/src/App-Mentions.js index 3cd866124d..19f96c5ca1 100644 --- a/examples/autocomplete/src/App-Mentions.js +++ b/examples/autocomplete/src/App-Mentions.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import Mention from 'antd/lib/mention'; +import algoliasearch from 'algoliasearch/lite'; import { InstantSearch, connectAutoComplete } from 'react-instantsearch-dom'; import 'antd/lib/mention/style/css'; @@ -22,12 +23,13 @@ AsyncMention.propTypes = { const ConnectedAsyncMention = connectAutoComplete(AsyncMention); +const searchClient = algoliasearch( + 'latency', + '6be0576ff61c053d5f9a3225e2a90f76' +); + const App = () => ( - + ); diff --git a/examples/autocomplete/src/App-Multi-Index.js b/examples/autocomplete/src/App-Multi-Index.js index c51aa56f4a..a06957ff98 100644 --- a/examples/autocomplete/src/App-Multi-Index.js +++ b/examples/autocomplete/src/App-Multi-Index.js @@ -8,13 +8,15 @@ import { Highlight, connectAutoComplete, } from 'react-instantsearch-dom'; +import algoliasearch from 'algoliasearch/lite'; + +const searchClient = algoliasearch( + 'latency', + '6be0576ff61c053d5f9a3225e2a90f76' +); const App = () => ( - + diff --git a/examples/geo-search/src/App.js b/examples/geo-search/src/App.js index 48d3c92fe6..06827755c1 100644 --- a/examples/geo-search/src/App.js +++ b/examples/geo-search/src/App.js @@ -1,5 +1,6 @@ import qs from 'qs'; import React, { Component, Fragment } from 'react'; +import algoliasearch from 'algoliasearch/lite'; import { InstantSearch, SearchBox, Configure } from 'react-instantsearch-dom'; import { GoogleMapsLoader, @@ -8,6 +9,11 @@ import { Marker, } from 'react-instantsearch-dom-maps'; +const searchClient = algoliasearch( + 'latency', + '6be0576ff61c053d5f9a3225e2a90f76' +); + const updateAfter = 700; const searchStateToUrl = searchState => searchState ? `${window.location.pathname}?${qs.stringify(searchState)}` : ''; @@ -72,8 +78,7 @@ class App extends Component { return ( ( - +

Results in first dataset

diff --git a/examples/next/components/app.js b/examples/next/components/app.js index 93eb90b132..6353e91e92 100644 --- a/examples/next/components/app.js +++ b/examples/next/components/app.js @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import algoliasearch from 'algoliasearch/lite'; import { RefinementList, SearchBox, @@ -10,6 +11,11 @@ import { } from 'react-instantsearch-dom'; import { InstantSearch } from './instantsearch'; +const searchClient = algoliasearch( + 'latency', + '6be0576ff61c053d5f9a3225e2a90f76' +); + const HitComponent = ({ hit }) => (
@@ -48,8 +54,7 @@ export default class extends React.Component { render() { return ( diff --git a/packages/react-instantsearch-core/src/components/Index.tsx b/packages/react-instantsearch-core/src/components/Index.tsx index 1e581c74a1..e928a34b3f 100644 --- a/packages/react-instantsearch-core/src/components/Index.tsx +++ b/packages/react-instantsearch-core/src/components/Index.tsx @@ -32,12 +32,17 @@ type State = { * @propType {{ Root: string|function, props: object }} [root] - Use this to customize the root element. Default value: `{ Root: 'div' }` * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, Index, SearchBox, Hits, Configure } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * diff --git a/packages/react-instantsearch-core/src/connectors/connectHighlight.js b/packages/react-instantsearch-core/src/connectors/connectHighlight.js index 34a346bc14..370d9284fe 100644 --- a/packages/react-instantsearch-core/src/connectors/connectHighlight.js +++ b/packages/react-instantsearch-core/src/connectors/connectHighlight.js @@ -26,8 +26,14 @@ const highlight = ({ * @providedPropType {function} highlight - function to retrieve and parse an attribute from a hit. It takes a configuration object with 3 attributes: `highlightProperty` which is the property that contains the highlight structure from the records, `attribute` which is the name of the attribute (it can be either a string or an array of strings) to look for and `hit` which is the hit from Algolia. It returns an array of objects `{value: string, isHighlighted: boolean}`. If the element that corresponds to the attribute is an array of strings, it will return a nested array of objects. * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, SearchBox, Hits, connectHighlight } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const CustomHighlight = connectHighlight( * ({ highlight, attribute, hit, highlightProperty }) => { * const highlights = highlight({ @@ -52,8 +58,7 @@ const highlight = ({ * * const App = () => ( * * diff --git a/packages/react-instantsearch-core/src/connectors/connectHits.js b/packages/react-instantsearch-core/src/connectors/connectHits.js index 002d8be2e6..77cbe3d3bb 100644 --- a/packages/react-instantsearch-core/src/connectors/connectHits.js +++ b/packages/react-instantsearch-core/src/connectors/connectHits.js @@ -19,8 +19,13 @@ import { addAbsolutePositions, addQueryID } from '../core/utils'; * @providedPropType {array.} hits - the records that matched the search state * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, Highlight, connectHits } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); * const CustomHits = connectHits(({ hits }) => ( *
* {hits.map(hit => @@ -33,8 +38,7 @@ import { addAbsolutePositions, addQueryID } from '../core/utils'; * * const App = () => ( * * diff --git a/packages/react-instantsearch-core/src/connectors/connectStateResults.js b/packages/react-instantsearch-core/src/connectors/connectStateResults.js index a42635600f..3e46686500 100644 --- a/packages/react-instantsearch-core/src/connectors/connectStateResults.js +++ b/packages/react-instantsearch-core/src/connectors/connectStateResults.js @@ -17,8 +17,14 @@ import { getResults } from '../core/indexUtils'; * @providedPropType {object} props - component props. * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, SearchBox, Hits, connectStateResults } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const Content = connectStateResults(({ searchState, searchResults }) => { * const hasResults = searchResults && searchResults.nbHits !== 0; * @@ -36,8 +42,7 @@ import { getResults } from '../core/indexUtils'; * * const App = () => ( * * diff --git a/packages/react-instantsearch-core/src/widgets/Configure.js b/packages/react-instantsearch-core/src/widgets/Configure.js index 6991966318..ac3f90368f 100644 --- a/packages/react-instantsearch-core/src/widgets/Configure.js +++ b/packages/react-instantsearch-core/src/widgets/Configure.js @@ -16,12 +16,17 @@ import connectConfigure from '../connectors/connectConfigure'; * @kind widget * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, Configure, Hits } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/Breadcrumb.js b/packages/react-instantsearch-dom/src/widgets/Breadcrumb.js index ff2c2a6380..11fed1a9f7 100644 --- a/packages/react-instantsearch-dom/src/widgets/Breadcrumb.js +++ b/packages/react-instantsearch-dom/src/widgets/Breadcrumb.js @@ -59,12 +59,17 @@ import Breadcrumb from '../components/Breadcrumb'; * @translationKey rootLabel - The root's label. Accepts a string * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { Breadcrumb, InstantSearch, HierarchicalMenu } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/CurrentRefinements.js b/packages/react-instantsearch-dom/src/widgets/CurrentRefinements.js index c45df9a53c..1b7bed25dd 100644 --- a/packages/react-instantsearch-dom/src/widgets/CurrentRefinements.js +++ b/packages/react-instantsearch-dom/src/widgets/CurrentRefinements.js @@ -23,12 +23,17 @@ import CurrentRefinements from '../components/CurrentRefinements'; * @translationKey clearFilter - the remove filter button label * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, CurrentRefinements, RefinementList } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/HierarchicalMenu.js b/packages/react-instantsearch-dom/src/widgets/HierarchicalMenu.js index 2d0a369179..2574c9c8b4 100644 --- a/packages/react-instantsearch-dom/src/widgets/HierarchicalMenu.js +++ b/packages/react-instantsearch-dom/src/widgets/HierarchicalMenu.js @@ -69,12 +69,17 @@ import HierarchicalMenu from '../components/HierarchicalMenu'; * @translationKey showMore - The label of the show more button. Accepts one parameter, a boolean that is true if the values are expanded * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, HierarchicalMenu } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * ( @@ -25,10 +26,14 @@ import Highlight from '../components/Highlight'; *
* ); * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/Hits.js b/packages/react-instantsearch-dom/src/widgets/Hits.js index 1b968953da..4f5a0f3a33 100644 --- a/packages/react-instantsearch-dom/src/widgets/Hits.js +++ b/packages/react-instantsearch-dom/src/widgets/Hits.js @@ -17,12 +17,16 @@ import Hits from '../components/Hits'; * @themeKey ais-Hits-item - the hit list item * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, Hits } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/HitsPerPage.js b/packages/react-instantsearch-dom/src/widgets/HitsPerPage.js index 43a7e344c3..2eece79f93 100644 --- a/packages/react-instantsearch-dom/src/widgets/HitsPerPage.js +++ b/packages/react-instantsearch-dom/src/widgets/HitsPerPage.js @@ -18,12 +18,17 @@ import HitsPerPage from '../components/HitsPerPage'; * @themeKey ais-HitsPerPage-option - the select option * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, HitsPerPage, Hits } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/Menu.js b/packages/react-instantsearch-dom/src/widgets/Menu.js index c1240e137b..3e162eccf2 100644 --- a/packages/react-instantsearch-dom/src/widgets/Menu.js +++ b/packages/react-instantsearch-dom/src/widgets/Menu.js @@ -34,12 +34,17 @@ import Menu from '../components/Menu'; * @translationkey noResults - The label of the no results text when no search for facet values results are found. * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, Menu } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/MenuSelect.js b/packages/react-instantsearch-dom/src/widgets/MenuSelect.js index a902d90055..1e45cc7ad5 100644 --- a/packages/react-instantsearch-dom/src/widgets/MenuSelect.js +++ b/packages/react-instantsearch-dom/src/widgets/MenuSelect.js @@ -20,12 +20,18 @@ import MenuSelect from '../components/MenuSelect'; * @translationkey seeAllOption - The label of the option to select to remove the refinement * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, MenuSelect } from 'react-instantsearch-dom'; + + * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); * * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/NumericMenu.js b/packages/react-instantsearch-dom/src/widgets/NumericMenu.js index c5b9c9f5ae..227e59e4f4 100644 --- a/packages/react-instantsearch-dom/src/widgets/NumericMenu.js +++ b/packages/react-instantsearch-dom/src/widgets/NumericMenu.js @@ -23,12 +23,17 @@ import NumericMenu from '../components/NumericMenu'; * @translationkey all - The label of the largest range added automatically by react instantsearch * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, NumericMenu } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/Panel.js b/packages/react-instantsearch-dom/src/widgets/Panel.js index 49692d16bb..0c46ac7ab9 100644 --- a/packages/react-instantsearch-dom/src/widgets/Panel.js +++ b/packages/react-instantsearch-dom/src/widgets/Panel.js @@ -17,12 +17,17 @@ import Panel from '../components/Panel'; * @themeKey ais-Panel-footer - the footer of the Panel (optional) * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, Panel, RefinementList } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/PoweredBy.js b/packages/react-instantsearch-dom/src/widgets/PoweredBy.js index e92dd87349..0f1e7ad7c2 100644 --- a/packages/react-instantsearch-dom/src/widgets/PoweredBy.js +++ b/packages/react-instantsearch-dom/src/widgets/PoweredBy.js @@ -15,11 +15,16 @@ import PoweredBy from '../components/PoweredBy'; * @example * import React from 'react'; * import { InstantSearch, PoweredBy } from 'react-instantsearch-dom'; + * import algoliasearch from 'algoliasearch/lite'; + * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); * * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/RangeInput.js b/packages/react-instantsearch-dom/src/widgets/RangeInput.js index 62df5a6b77..cb16db2a80 100644 --- a/packages/react-instantsearch-dom/src/widgets/RangeInput.js +++ b/packages/react-instantsearch-dom/src/widgets/RangeInput.js @@ -27,12 +27,17 @@ import RangeInput from '../components/RangeInput'; * @translationKey separator - Label value for the input separator * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, RangeInput } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/RatingMenu.js b/packages/react-instantsearch-dom/src/widgets/RatingMenu.js index a5e58657ca..8114dcd9ae 100644 --- a/packages/react-instantsearch-dom/src/widgets/RatingMenu.js +++ b/packages/react-instantsearch-dom/src/widgets/RatingMenu.js @@ -33,12 +33,17 @@ import RatingMenu from '../components/RatingMenu'; * @translationKey ratingLabel - Label value for the rating link * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, RatingMenu } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/RefinementList.js b/packages/react-instantsearch-dom/src/widgets/RefinementList.js index ef72c8698b..bbbd54cad3 100644 --- a/packages/react-instantsearch-dom/src/widgets/RefinementList.js +++ b/packages/react-instantsearch-dom/src/widgets/RefinementList.js @@ -37,12 +37,17 @@ import RefinementList from '../components/RefinementList'; * the [dashboard](https://www.algolia.com/explorer/display/) or using the [API](https://www.algolia.com/doc/guides/searching/faceting/#search-for-facet-values). * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, RefinementList } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/ScrollTo.js b/packages/react-instantsearch-dom/src/widgets/ScrollTo.js index d255678c2b..05d1bf86c7 100644 --- a/packages/react-instantsearch-dom/src/widgets/ScrollTo.js +++ b/packages/react-instantsearch-dom/src/widgets/ScrollTo.js @@ -12,12 +12,17 @@ import ScrollTo from '../components/ScrollTo'; * @themeKey ais-ScrollTo - the root div of the widget * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, ScrollTo, Hits } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/SearchBox.js b/packages/react-instantsearch-dom/src/widgets/SearchBox.js index dc20e36e1f..1897cd304a 100644 --- a/packages/react-instantsearch-dom/src/widgets/SearchBox.js +++ b/packages/react-instantsearch-dom/src/widgets/SearchBox.js @@ -30,12 +30,17 @@ import SearchBox from '../components/SearchBox'; * @translationkey placeholder - The label of the input placeholder * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, SearchBox } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/Snippet.js b/packages/react-instantsearch-dom/src/widgets/Snippet.js index a7dba9cbae..8de800d833 100644 --- a/packages/react-instantsearch-dom/src/widgets/Snippet.js +++ b/packages/react-instantsearch-dom/src/widgets/Snippet.js @@ -20,8 +20,14 @@ import Snippet from '../components/Snippet'; * @themeKey ais-Snippet-nonHighlighted - the normal text * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, SearchBox, Hits, Snippet } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const Hit = ({ hit }) => ( *
* @@ -30,8 +36,7 @@ import Snippet from '../components/Snippet'; * * const App = () => ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/SortBy.js b/packages/react-instantsearch-dom/src/widgets/SortBy.js index e44abeff27..9f772519cb 100644 --- a/packages/react-instantsearch-dom/src/widgets/SortBy.js +++ b/packages/react-instantsearch-dom/src/widgets/SortBy.js @@ -15,12 +15,17 @@ import SortBy from '../components/SortBy'; * @themeKey ais-SortBy-option - the select option * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, SortBy } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * ( * * diff --git a/packages/react-instantsearch-dom/src/widgets/ToggleRefinement.js b/packages/react-instantsearch-dom/src/widgets/ToggleRefinement.js index 9f352edd82..d83302e4d0 100644 --- a/packages/react-instantsearch-dom/src/widgets/ToggleRefinement.js +++ b/packages/react-instantsearch-dom/src/widgets/ToggleRefinement.js @@ -22,12 +22,17 @@ import ToggleRefinement from '../components/ToggleRefinement'; * @themeKey ais-ToggleRefinement-labelText - the label text of each toggle item * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, ToggleRefinement } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * ', module); stories .add('default', () => ( @@ -18,8 +20,10 @@ stories )) .add('with custom root', () => ( )) - .add('with algolia search client', () => ( - - - - - )) .add('with custom search client', () => ( ', module); stories .add('MultiHits', () => ( - + @@ -68,11 +70,7 @@ stories )) .add('AutoComplete', () => ( - + @@ -82,11 +80,7 @@ stories )) .add('with SortBy nested in same Index as Root', () => ( - +
@@ -123,11 +117,7 @@ stories )) .add('with conditional rendering', () => ( - +
@@ -167,11 +157,7 @@ stories )) .add('with Hits & Configure', () => ( - + @@ -185,11 +171,7 @@ stories )) .add('with custom root', () => ( - + diff --git a/stories/util.js b/stories/util.js index 97ee268333..2bccbb4f82 100644 --- a/stories/util.js +++ b/stories/util.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { linkTo } from '@storybook/addon-links'; +import algoliasearch from 'algoliasearch/lite'; import { InstantSearch, ClearRefinements, @@ -50,7 +51,10 @@ Hits.propTypes = { export const CustomHits = connectHits(Hits); export const Wrap = ({ appId, apiKey, indexName, children }) => ( - + {children} ); @@ -112,7 +116,10 @@ export const WrapWithHits = ({ }; return ( - +
{children}
diff --git a/website/examples/default-theme/App.js b/website/examples/default-theme/App.js index b517e89deb..28437dd51c 100644 --- a/website/examples/default-theme/App.js +++ b/website/examples/default-theme/App.js @@ -16,13 +16,18 @@ import { Configure, connectStateResults, } from 'react-instantsearch-dom'; +import algoliasearch from 'algoliasearch/lite'; import withURLSync from './URLSync'; import './App.css'; +const searchClient = algoliasearch( + 'latency', + '6be0576ff61c053d5f9a3225e2a90f76' +); + const App = props => ( +
diff --git a/website/examples/e-commerce/App.js b/website/examples/e-commerce/App.js index ab725a328f..01aeac3475 100644 --- a/website/examples/e-commerce/App.js +++ b/website/examples/e-commerce/App.js @@ -16,13 +16,18 @@ import { connectHits, connectStateResults, } from 'react-instantsearch-dom'; +import algoliasearch from 'algoliasearch/lite'; import withURLSync from './URLSync'; import './App.css'; +const searchClient = algoliasearch( + 'latency', + '6be0576ff61c053d5f9a3225e2a90f76' +); + const App = props => ( ( @@ -43,8 +49,7 @@ const App = props => ( const isMobile = window.innerWidth < 450; const MaterialUiExample = props => ( ( ( Date: Wed, 17 Apr 2019 13:54:47 +0200 Subject: [PATCH 04/48] feat(searchClient): remove other options --- .../src/components/InstantSearch.tsx | 11 +-- .../src/core/__tests__/createInstantSearch.js | 67 +------------------ .../src/core/createInstantSearch.js | 29 +------- .../__tests__/createInstantSearchServer.js | 63 ----------------- .../src/core/createInstantSearchServer.js | 14 +--- 5 files changed, 14 insertions(+), 170 deletions(-) diff --git a/packages/react-instantsearch-core/src/components/InstantSearch.tsx b/packages/react-instantsearch-core/src/components/InstantSearch.tsx index f651b4368e..dce6064a10 100644 --- a/packages/react-instantsearch-core/src/components/InstantSearch.tsx +++ b/packages/react-instantsearch-core/src/components/InstantSearch.tsx @@ -81,8 +81,6 @@ type State = { * @name * @requirements You will need to have an Algolia account to be able to use this widget. * [Create one now](https://www.algolia.com/users/sign_up). - * @propType {string} appId - Your Algolia application id. - * @propType {string} apiKey - Your Algolia search-only API key. * @propType {string} indexName - Main index in which to search. * @propType {boolean} [refresh=false] - Flag to activate when the cache needs to be cleared so that the front-end is updated when a change occurs in the index. * @propType {object} [searchClient] - Provide a custom search client. @@ -94,12 +92,17 @@ type State = { * @propType {{ Root: string|function, props: object }} [root] - Use this to customize the root element. Default value: `{ Root: 'div' }` * @example * import React from 'react'; + * import algoliasearch from 'algoliasearch/lite'; * import { InstantSearch, SearchBox, Hits } from 'react-instantsearch-dom'; * + * const searchClient = algoliasearch( + * 'latency', + * '6be0576ff61c053d5f9a3225e2a90f76' + * ); + * * const App = () => ( * * diff --git a/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js b/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js index e9496e97a8..f2d249b67f 100644 --- a/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js +++ b/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js @@ -21,11 +21,10 @@ describe('createInstantSearch', () => { it('wraps InstantSearch', () => { const wrapper = shallow( - + ); - // eslint-disable-next-line no-shadow - const { searchClient, ...propsWithoutClient } = wrapper.props(); + const { searchClient: _, ...propsWithoutClient } = wrapper.props(); expect(wrapper.is(InstantSearch)).toBe(true); expect(wrapper.props().searchClient).toBe(searchClient); @@ -47,66 +46,6 @@ describe('createInstantSearch', () => { `); }); - it('creates an algolia client using the provided factory', () => { - shallow(); - - expect(searchClientFactory).toHaveBeenCalledTimes(1); - expect(searchClientFactory).toHaveBeenCalledWith('app', 'key', { - _useRequestCache: true, - }); - - expect(searchClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); - expect(searchClient.addAlgoliaAgent).toHaveBeenCalledWith( - `react-instantsearch (${version})` - ); - expect(searchClient.addAlgoliaAgent).toHaveBeenCalledWith( - `react (${React.version})` - ); - }); - - it('throws if appId is given with searchClient', () => { - const trigger = () => - shallow( - - ); - - expect(() => trigger()).toThrowErrorMatchingInlineSnapshot( - `"react-instantsearch: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` - ); - }); - - it('throws if apiKey is given with searchClient', () => { - const trigger = () => - shallow( - - ); - - expect(() => trigger()).toThrowErrorMatchingInlineSnapshot( - `"react-instantsearch: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` - ); - }); - - it('updates the searchClient when appId or apiKey changes', () => { - const wrapper = shallow( - - ); - - wrapper.setProps({ appId: 'app2', apiKey: 'key' }); - wrapper.setProps({ appId: 'app', apiKey: 'key2' }); - - expect(searchClientFactory).toHaveBeenCalledTimes(3); - expect(searchClientFactory.mock.calls[1]).toEqual(['app2', 'key']); - expect(searchClientFactory.mock.calls[2]).toEqual(['app', 'key2']); - }); - it('uses the provided searchClient', () => { const wrapper = shallow( @@ -167,7 +106,7 @@ describe('createInstantSearch', () => { }; const wrapper = shallow( - + ); // eslint-disable-next-line no-shadow, no-unused-vars diff --git a/packages/react-instantsearch-core/src/core/createInstantSearch.js b/packages/react-instantsearch-core/src/core/createInstantSearch.js index a176aa9df7..b35aa61d6c 100644 --- a/packages/react-instantsearch-core/src/core/createInstantSearch.js +++ b/packages/react-instantsearch-core/src/core/createInstantSearch.js @@ -13,9 +13,7 @@ import version from './version'; export default function createInstantSearch(defaultAlgoliaClient, root) { return class CreateInstantSearch extends Component { static propTypes = { - searchClient: PropTypes.object, - appId: PropTypes.string, - apiKey: PropTypes.string, + searchClient: PropTypes.object.isRequired, children: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.node), PropTypes.node, @@ -45,19 +43,7 @@ export default function createInstantSearch(defaultAlgoliaClient, root) { constructor(...args) { super(...args); - if (this.props.searchClient) { - if (this.props.appId || this.props.apiKey) { - throw new Error( - 'react-instantsearch: `searchClient` cannot be used with `appId` and `apiKey`.' - ); - } - } - - this.client = - this.props.searchClient || - defaultAlgoliaClient(this.props.appId, this.props.apiKey, { - _useRequestCache: true, - }); + this.client = this.props.searchClient; if (typeof this.client.addAlgoliaAgent === 'function') { this.client.addAlgoliaAgent(`react (${React.version})`); @@ -66,16 +52,7 @@ export default function createInstantSearch(defaultAlgoliaClient, root) { } componentWillReceiveProps(nextProps) { - const props = this.props; - - if (nextProps.searchClient) { - this.client = nextProps.searchClient; - } else if ( - props.appId !== nextProps.appId || - props.apiKey !== nextProps.apiKey - ) { - this.client = defaultAlgoliaClient(nextProps.appId, nextProps.apiKey); - } + this.client = nextProps.searchClient; if (typeof this.client.addAlgoliaAgent === 'function') { this.client.addAlgoliaAgent(`react (${React.version})`); diff --git a/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js b/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js index 09b6d18d14..1c0ba9044d 100644 --- a/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js +++ b/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js @@ -56,37 +56,6 @@ describe('createInstantSearchServer', () => { }; describe('props', () => { - it('uses the provided factory', () => { - const searchClient = { - ...createSearchClient(), - addAlgoliaAgent: jest.fn(), - }; - - const createSearchClientMock = jest.fn(() => searchClient); - - const { InstantSearch } = createInstantSearchServer( - createSearchClientMock - ); - - const props = { - ...requiredProps, - appId: 'appId', - apiKey: 'apiKey', - }; - - shallow(); - - expect(createSearchClientMock).toHaveBeenCalledTimes(1); - expect(createSearchClientMock).toHaveBeenCalledWith('appId', 'apiKey'); - expect(searchClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); - expect(searchClient.addAlgoliaAgent).toHaveBeenCalledWith( - `react (${React.version})` - ); - expect(searchClient.addAlgoliaAgent).toHaveBeenCalledWith( - `react-instantsearch (${version})` - ); - }); - it('uses the provided searchClient', () => { const { InstantSearch } = createInstantSearchServer(); @@ -114,38 +83,6 @@ describe('createInstantSearchServer', () => { expect(() => trigger()).not.toThrow(); }); - - it('throws if appId is given with searchClient', () => { - const { InstantSearch } = createInstantSearchServer(); - - const props = { - ...requiredProps, - appId: 'appId', - searchClient: createSearchClient(), - }; - - const trigger = () => shallow(); - - expect(() => trigger()).toThrowErrorMatchingInlineSnapshot( - `"react-instantsearch: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` - ); - }); - - it('throws if apiKey is given with searchClient', () => { - const { InstantSearch } = createInstantSearchServer(); - - const props = { - ...requiredProps, - apiKey: 'apiKey', - searchClient: createSearchClient(), - }; - - const trigger = () => shallow(); - - expect(() => trigger()).toThrowErrorMatchingInlineSnapshot( - `"react-instantsearch: \`searchClient\` cannot be used with \`appId\` and \`apiKey\`."` - ); - }); }); describe('single index', () => { diff --git a/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js b/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js index 7d67985195..45e16fe036 100644 --- a/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js +++ b/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js @@ -134,8 +134,6 @@ const createInstantSearchServer = algoliasearch => { class CreateInstantSearchServer extends Component { static propTypes = { searchClient: PropTypes.object, - appId: PropTypes.string, - apiKey: PropTypes.string, indexName: PropTypes.string.isRequired, resultsState: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), }; @@ -143,17 +141,7 @@ const createInstantSearchServer = algoliasearch => { constructor(...args) { super(...args); - if (this.props.searchClient) { - if (this.props.appId || this.props.apiKey) { - throw new Error( - 'react-instantsearch: `searchClient` cannot be used with `appId` and `apiKey`.' - ); - } - } - - client = - this.props.searchClient || - algoliasearch(this.props.appId, this.props.apiKey); + client = this.props.searchClient; if (typeof client.addAlgoliaAgent === 'function') { client.addAlgoliaAgent(`react (${React.version})`); From 7677f02bae9a378c317fec233024421b353e24cd Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 17 Apr 2019 14:50:20 +0200 Subject: [PATCH 05/48] adds back user agent tests & remove defaultAlgoliaClient --- .../src/core/__tests__/createInstantSearch.js | 19 +++++++++++---- .../src/core/createInstantSearch.js | 2 +- .../__tests__/createInstantSearchServer.js | 24 +++++++++++++++++++ .../src/core/createInstantSearchServer.js | 4 ++-- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js b/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js index f2d249b67f..224eeeef62 100644 --- a/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js +++ b/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js @@ -9,14 +9,12 @@ Enzyme.configure({ adapter: new Adapter() }); describe('createInstantSearch', () => { const searchClient = { addAlgoliaAgent: jest.fn() }; - const searchClientFactory = jest.fn(() => searchClient); - const CustomInstantSearch = createInstantSearch(searchClientFactory, { + const CustomInstantSearch = createInstantSearch({ Root: 'div', }); beforeEach(() => { searchClient.addAlgoliaAgent.mockClear(); - searchClientFactory.mockClear(); }); it('wraps InstantSearch', () => { @@ -51,8 +49,15 @@ describe('createInstantSearch', () => { ); - expect(searchClientFactory).toHaveBeenCalledTimes(0); expect(searchClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); + + expect(searchClient.addAlgoliaAgent).toHaveBeenCalledWith( + `react-instantsearch (${version})` + ); + expect(searchClient.addAlgoliaAgent).toHaveBeenCalledWith( + `react (${React.version})` + ); + expect(wrapper.props().searchClient).toBe(searchClient); }); @@ -81,6 +86,12 @@ describe('createInstantSearch', () => { expect(wrapper.props().searchClient).toBe(newSearchClient); expect(newSearchClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); + expect(newSearchClient.addAlgoliaAgent).toHaveBeenCalledWith( + `react-instantsearch (${version})` + ); + expect(newSearchClient.addAlgoliaAgent).toHaveBeenCalledWith( + `react (${React.version})` + ); }); it('does not throw when searchClient gets updated and does not have a `addAlgoliaAgent()` method', () => { diff --git a/packages/react-instantsearch-core/src/core/createInstantSearch.js b/packages/react-instantsearch-core/src/core/createInstantSearch.js index b35aa61d6c..2be71f626e 100644 --- a/packages/react-instantsearch-core/src/core/createInstantSearch.js +++ b/packages/react-instantsearch-core/src/core/createInstantSearch.js @@ -10,7 +10,7 @@ import version from './version'; * @param {object} root - the defininition of the root of an InstantSearch sub tree. * @returns {object} an InstantSearch root */ -export default function createInstantSearch(defaultAlgoliaClient, root) { +export default function createInstantSearch(root) { return class CreateInstantSearch extends Component { static propTypes = { searchClient: PropTypes.object.isRequired, diff --git a/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js b/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js index 1c0ba9044d..cff415d2b2 100644 --- a/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js +++ b/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js @@ -56,6 +56,30 @@ describe('createInstantSearchServer', () => { }; describe('props', () => { + it('adds expected user agents', () => { + const searchClient = { + ...createSearchClient(), + addAlgoliaAgent: jest.fn(), + }; + + const { InstantSearch } = createInstantSearchServer(); + + const props = { + ...requiredProps, + searchClient, + }; + + shallow(); + + expect(searchClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); + expect(searchClient.addAlgoliaAgent).toHaveBeenCalledWith( + `react (${React.version})` + ); + expect(searchClient.addAlgoliaAgent).toHaveBeenCalledWith( + `react-instantsearch (${version})` + ); + }); + it('uses the provided searchClient', () => { const { InstantSearch } = createInstantSearchServer(); diff --git a/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js b/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js index 45e16fe036..3708caeee5 100644 --- a/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js +++ b/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js @@ -94,8 +94,8 @@ const multiIndexSearch = ( ); }; -const createInstantSearchServer = algoliasearch => { - const InstantSearch = createInstantSearch(algoliasearch, { +const createInstantSearchServer = () => { + const InstantSearch = createInstantSearch({ Root: 'div', props: { className: 'ais-InstantSearch__root', From 7e81f7f1a50291f37bed92a08dd2214608efeadb Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 17 Apr 2019 14:53:02 +0200 Subject: [PATCH 06/48] remove algoliasearch from dependencies --- packages/react-instantsearch-dom/package.json | 1 - packages/react-instantsearch-native/package.json | 1 - yarn.lock | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/react-instantsearch-dom/package.json b/packages/react-instantsearch-dom/package.json index 99f3b6d8c0..5104ed18de 100644 --- a/packages/react-instantsearch-dom/package.json +++ b/packages/react-instantsearch-dom/package.json @@ -41,7 +41,6 @@ }, "dependencies": { "@babel/runtime": "^7.1.2", - "algoliasearch": "^3.27.1", "algoliasearch-helper": "^2.26.0", "classnames": "^2.2.5", "lodash": "^4.17.4", diff --git a/packages/react-instantsearch-native/package.json b/packages/react-instantsearch-native/package.json index 8fd12d95c4..58e9120b17 100644 --- a/packages/react-instantsearch-native/package.json +++ b/packages/react-instantsearch-native/package.json @@ -39,7 +39,6 @@ }, "dependencies": { "@babel/runtime": "^7.1.2", - "algoliasearch": "^3.27.1", "react-instantsearch-core": "^5.4.0" }, "peerDependencies": { diff --git a/yarn.lock b/yarn.lock index ea4d722d2c..6a2216f4f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3824,7 +3824,7 @@ algoliasearch-helper@^2.26.0: qs "^6.5.1" util "^0.10.3" -algoliasearch@3.32.1, algoliasearch@^3.27.1: +algoliasearch@3.32.1: version "3.32.1" resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.32.1.tgz#605f8a2c17ab8da2af4456110f4d0a02b384e3d0" integrity sha512-NaaHMboU9tKwrU3aim7LlzSDqKb+1TGaC+Lx3NOttSnuMHbPpaf+7LtJL4KlosbRWEwqb9t5wSYMVDrPTH2dNA== From 0ec315f0c8420425ac30f797764909021561b1ed Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 17 Apr 2019 15:07:35 +0200 Subject: [PATCH 07/48] remove algoliasearch usage --- .../react-instantsearch-core/src/core/createInstantSearch.js | 3 +-- packages/react-instantsearch-dom/src/server.js | 4 +--- packages/react-instantsearch-dom/src/widgets/InstantSearch.js | 3 +-- .../react-instantsearch-native/src/widgets/InstantSearch.js | 3 +-- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/packages/react-instantsearch-core/src/core/createInstantSearch.js b/packages/react-instantsearch-core/src/core/createInstantSearch.js index 2be71f626e..a6119a50e8 100644 --- a/packages/react-instantsearch-core/src/core/createInstantSearch.js +++ b/packages/react-instantsearch-core/src/core/createInstantSearch.js @@ -5,8 +5,7 @@ import version from './version'; /** * Creates a specialized root InstantSearch component. It accepts - * an algolia client and a specification of the root Element. - * @param {function} defaultAlgoliaClient - a function that builds an Algolia client + * a specification of the root Element. * @param {object} root - the defininition of the root of an InstantSearch sub tree. * @returns {object} an InstantSearch root */ diff --git a/packages/react-instantsearch-dom/src/server.js b/packages/react-instantsearch-dom/src/server.js index 61064b462a..6a7ba35f41 100644 --- a/packages/react-instantsearch-dom/src/server.js +++ b/packages/react-instantsearch-dom/src/server.js @@ -1,5 +1,3 @@ -import algoliasearch from 'algoliasearch/lite'; import createInstantSearchServer from './core/createInstantSearchServer'; -export const createInstantSearch = () => - createInstantSearchServer(algoliasearch); +export const createInstantSearch = createInstantSearchServer; diff --git a/packages/react-instantsearch-dom/src/widgets/InstantSearch.js b/packages/react-instantsearch-dom/src/widgets/InstantSearch.js index e9d85d6ef8..75a9c0aac0 100644 --- a/packages/react-instantsearch-dom/src/widgets/InstantSearch.js +++ b/packages/react-instantsearch-dom/src/widgets/InstantSearch.js @@ -1,7 +1,6 @@ -import algoliasearch from 'algoliasearch/lite'; import { createInstantSearch } from 'react-instantsearch-core'; -const InstantSearch = createInstantSearch(algoliasearch, { +const InstantSearch = createInstantSearch({ Root: 'div', props: { className: 'ais-InstantSearch__root', diff --git a/packages/react-instantsearch-native/src/widgets/InstantSearch.js b/packages/react-instantsearch-native/src/widgets/InstantSearch.js index 9a453ce8af..a86d3fd669 100644 --- a/packages/react-instantsearch-native/src/widgets/InstantSearch.js +++ b/packages/react-instantsearch-native/src/widgets/InstantSearch.js @@ -1,8 +1,7 @@ -import algoliasearch from 'algoliasearch/reactnative'; import { View } from 'react-native'; import { createInstantSearch } from 'react-instantsearch-core'; -const InstantSearch = createInstantSearch(algoliasearch, { +const InstantSearch = createInstantSearch({ Root: View, }); From 0453b9decd034d05b0818ecdf6564fe7fe387331 Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 17 Apr 2019 15:41:30 +0200 Subject: [PATCH 08/48] chore: update max size --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index a20c0ed4c0..47d48b7136 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,7 @@ "bundlesize": [ { "path": "packages/react-instantsearch/dist/umd/Core.min.js", - "maxSize": "7.75 kB" + "maxSize": "6.50 kB" }, { "path": "packages/react-instantsearch/dist/umd/Connectors.min.js", @@ -133,7 +133,7 @@ }, { "path": "packages/react-instantsearch/dist/umd/Dom.min.js", - "maxSize": "63.75 kB" + "maxSize": "51.75 kB" }, { "path": "packages/react-instantsearch-core/dist/umd/ReactInstantSearchCore.min.js", @@ -141,7 +141,7 @@ }, { "path": "packages/react-instantsearch-dom/dist/umd/ReactInstantSearchDOM.min.js", - "maxSize": "64.25 kB" + "maxSize": "53 kB" }, { "path": "packages/react-instantsearch-dom-maps/dist/umd/ReactInstantSearchDOMMaps.min.js", From 4953745e60119356d6f9b514284b2e1edf2d5115 Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 17 Apr 2019 18:13:50 +0200 Subject: [PATCH 09/48] refactor(root): remove createIndex & createInstantSearch - remove root div (replaced by just the provider) - move logic for user agents to instantSearchManager TODO: make a new createInstantSearch which allows injection of user agents (useful for native) TODO: global search of usage & test of these factories BREAKING CHANGE: removal of the factories BREAKING CHANGE: DOM no longer has a div around root --- .../src/components/Index.tsx | 60 +++++--------- .../src/components/InstantSearch.tsx | 23 +----- .../src/core/createIndex.js | 40 ---------- .../src/core/createInstantSearch.js | 80 ------------------- .../src/core/createInstantSearchManager.js | 4 + .../src/core/{utils.js => utils.ts} | 9 +++ .../react-instantsearch-core/src/index.js | 4 +- packages/react-instantsearch-dom/src/index.js | 4 +- .../src/widgets/Index.js | 10 --- .../src/widgets/InstantSearch.js | 10 --- .../react-instantsearch-native/src/index.js | 6 +- 11 files changed, 43 insertions(+), 207 deletions(-) delete mode 100644 packages/react-instantsearch-core/src/core/createIndex.js delete mode 100644 packages/react-instantsearch-core/src/core/createInstantSearch.js rename packages/react-instantsearch-core/src/core/{utils.js => utils.ts} (81%) delete mode 100644 packages/react-instantsearch-dom/src/widgets/Index.js delete mode 100644 packages/react-instantsearch-dom/src/widgets/InstantSearch.js diff --git a/packages/react-instantsearch-core/src/components/Index.tsx b/packages/react-instantsearch-core/src/components/Index.tsx index e928a34b3f..95866103b7 100644 --- a/packages/react-instantsearch-core/src/components/Index.tsx +++ b/packages/react-instantsearch-core/src/components/Index.tsx @@ -7,13 +7,15 @@ import { IndexContext, } from '../core/context'; +function getIndexContext(props: Props): IndexContext { + return { + targetedIndex: props.indexId || props.indexName, + }; +} + type Props = { indexName: string; - indexId: string; - root: { - Root: ReactType; - props: {}; - }; + indexId?: string; }; type InnerProps = Props & { contextValue: InstantSearchContext }; @@ -29,7 +31,6 @@ type State = { * @kind widget * @name * @propType {string} indexName - index in which to search. - * @propType {{ Root: string|function, props: object }} [root] - Use this to customize the root element. Default value: `{ Root: 'div' }` * @example * import React from 'react'; * import algoliasearch from 'algoliasearch/lite'; @@ -58,27 +59,18 @@ type State = { */ class Index extends Component { static propTypes = { - // @TODO: These props are currently constant. indexName: PropTypes.string.isRequired, - indexId: PropTypes.string.isRequired, + indexId: PropTypes.string, children: PropTypes.node, - root: PropTypes.shape({ - Root: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.func, - PropTypes.object, - ]), - props: PropTypes.object, - }).isRequired, }; - unregisterWidget?: () => void; + static getDerivedStateFromProps(props: InnerProps) { + return { + indexContext: getIndexContext(props), + }; + } - state = { - indexContext: { - targetedIndex: this.props.indexId, - }, - }; + unregisterWidget?: () => void; constructor(props: InnerProps) { super(props); @@ -87,7 +79,7 @@ class Index extends Component { this.getSearchParameters.bind(this), { ais: this.props.contextValue, - multiIndexContext: this.state.indexContext, + multiIndexContext: getIndexContext(props), }, this.props ); @@ -99,17 +91,10 @@ class Index extends Component { ); } - componentWillReceiveProps(nextProps: InnerProps) { - if (this.props.indexName !== nextProps.indexName) { + componentDidUpdate(prevProps: InnerProps) { + if (this.props.indexName !== prevProps.indexName) { this.props.contextValue.widgetsManager.update(); } - if (this.props.indexId !== nextProps.indexId) { - this.setState({ - indexContext: { - targetedIndex: nextProps.indexId, - }, - }); - } } componentWillUnmount() { @@ -118,7 +103,7 @@ class Index extends Component { } } - getSearchParameters(searchParameters, props) { + getSearchParameters(searchParameters, props: InnerProps) { return searchParameters.setIndex( this.props ? this.props.indexName : props.indexName ); @@ -126,16 +111,13 @@ class Index extends Component { render() { const childrenCount = Children.count(this.props.children); - const { Root, props } = this.props.root; if (childrenCount === 0) { return null; } return ( - - - {this.props.children} - - + + {this.props.children} + ); } } diff --git a/packages/react-instantsearch-core/src/components/InstantSearch.tsx b/packages/react-instantsearch-core/src/components/InstantSearch.tsx index dce6064a10..1ae9c34810 100644 --- a/packages/react-instantsearch-core/src/components/InstantSearch.tsx +++ b/packages/react-instantsearch-core/src/components/InstantSearch.tsx @@ -61,10 +61,6 @@ type Props = { searchState: SearchState ) => void; stalledSearchDelay?: number; - root: { - Root: ReactType; - props: {}; - }; resultsState: SearchResults | { [indexId: string]: SearchResults }; }; @@ -132,16 +128,6 @@ class InstantSearch extends Component { resultsState: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), children: PropTypes.node, - - root: PropTypes.shape({ - Root: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.func, - PropTypes.object, - ]), - props: PropTypes.object, - }).isRequired, - stalledSearchDelay: PropTypes.number, }; @@ -255,16 +241,13 @@ class InstantSearch extends Component { render() { const childrenCount = Children.count(this.props.children); - const { Root, props } = this.props.root; if (childrenCount === 0) { return null; } return ( - - - {this.props.children} - - + + {this.props.children} + ); } } diff --git a/packages/react-instantsearch-core/src/core/createIndex.js b/packages/react-instantsearch-core/src/core/createIndex.js deleted file mode 100644 index 28d123b40d..0000000000 --- a/packages/react-instantsearch-core/src/core/createIndex.js +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import Index from '../components/Index'; - -/** - * Creates a specialized root Index component. It accepts - * a specification of the root Element. - * @param {object} defaultRoot - the definition of the root of an Index sub tree. - * @return {object} a Index root - */ -const createIndex = defaultRoot => { - const CreateIndex = ({ indexName, indexId, root, children }) => ( - - {children} - - ); - - CreateIndex.propTypes = { - indexName: PropTypes.string.isRequired, - // @MAJOR: indexId must be required - indexId: PropTypes.string, - root: PropTypes.shape({ - Root: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.func, - PropTypes.object, - ]).isRequired, - props: PropTypes.object, - }), - children: PropTypes.node, - }; - - CreateIndex.defaultProps = { - root: defaultRoot, - }; - - return CreateIndex; -}; - -export default createIndex; diff --git a/packages/react-instantsearch-core/src/core/createInstantSearch.js b/packages/react-instantsearch-core/src/core/createInstantSearch.js deleted file mode 100644 index a6119a50e8..0000000000 --- a/packages/react-instantsearch-core/src/core/createInstantSearch.js +++ /dev/null @@ -1,80 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import InstantSearch from '../components/InstantSearch'; -import version from './version'; - -/** - * Creates a specialized root InstantSearch component. It accepts - * a specification of the root Element. - * @param {object} root - the defininition of the root of an InstantSearch sub tree. - * @returns {object} an InstantSearch root - */ -export default function createInstantSearch(root) { - return class CreateInstantSearch extends Component { - static propTypes = { - searchClient: PropTypes.object.isRequired, - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node, - ]), - indexName: PropTypes.string.isRequired, - createURL: PropTypes.func, - searchState: PropTypes.object, - refresh: PropTypes.bool.isRequired, - onSearchStateChange: PropTypes.func, - onSearchParameters: PropTypes.func, - resultsState: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), - root: PropTypes.shape({ - Root: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.func, - PropTypes.object, - ]).isRequired, - props: PropTypes.object, - }), - }; - - static defaultProps = { - refresh: false, - root, - }; - - constructor(...args) { - super(...args); - - this.client = this.props.searchClient; - - if (typeof this.client.addAlgoliaAgent === 'function') { - this.client.addAlgoliaAgent(`react (${React.version})`); - this.client.addAlgoliaAgent(`react-instantsearch (${version})`); - } - } - - componentWillReceiveProps(nextProps) { - this.client = nextProps.searchClient; - - if (typeof this.client.addAlgoliaAgent === 'function') { - this.client.addAlgoliaAgent(`react (${React.version})`); - this.client.addAlgoliaAgent(`react-instantsearch (${version})`); - } - } - - render() { - return ( - - {this.props.children} - - ); - } - }; -} diff --git a/packages/react-instantsearch-core/src/core/createInstantSearchManager.js b/packages/react-instantsearch-core/src/core/createInstantSearchManager.js index ab36df2ba7..d40fa0b896 100644 --- a/packages/react-instantsearch-core/src/core/createInstantSearchManager.js +++ b/packages/react-instantsearch-core/src/core/createInstantSearchManager.js @@ -4,6 +4,7 @@ import createWidgetsManager from './createWidgetsManager'; import createStore from './createStore'; import { HIGHLIGHT_TAGS } from './highlight'; import { hasMultipleIndices } from './indexUtils'; +import { addAlgoliaAgents } from './utils'; const isMultiIndexContext = widget => hasMultipleIndices(widget.context); const isTargetedIndexEqualIndex = (widget, indexId) => @@ -36,6 +37,8 @@ export default function createInstantSearchManager({ ...HIGHLIGHT_TAGS, }); + addAlgoliaAgents(searchClient); + helper .on('search', handleNewSearch) .on('result', handleSearchSuccess({ indexId: indexName })) @@ -62,6 +65,7 @@ export default function createInstantSearchManager({ } function updateClient(client) { + addAlgoliaAgents(client); helper.setClient(client); search(); } diff --git a/packages/react-instantsearch-core/src/core/utils.js b/packages/react-instantsearch-core/src/core/utils.ts similarity index 81% rename from packages/react-instantsearch-core/src/core/utils.js rename to packages/react-instantsearch-core/src/core/utils.ts index e97e4b8c7e..2b743a3fd0 100644 --- a/packages/react-instantsearch-core/src/core/utils.js +++ b/packages/react-instantsearch-core/src/core/utils.ts @@ -1,4 +1,13 @@ import { isEmpty, isPlainObject } from 'lodash'; +import { version as ReactVersion } from 'react'; +import version from './version'; + +export function addAlgoliaAgents(searchClient) { + if (typeof searchClient.addAlgoliaAgent === 'function') { + searchClient.addAlgoliaAgent(`react (${ReactVersion})`); + searchClient.addAlgoliaAgent(`react-instantsearch (${version})`); + } +} // From https://github.com/reactjs/react-redux/blob/master/src/utils/shallowEqual.js export const shallowEqual = (objA, objB) => { diff --git a/packages/react-instantsearch-core/src/index.js b/packages/react-instantsearch-core/src/index.js index af41f40014..fddeef060d 100644 --- a/packages/react-instantsearch-core/src/index.js +++ b/packages/react-instantsearch-core/src/index.js @@ -1,6 +1,4 @@ // Core -export { default as createInstantSearch } from './core/createInstantSearch'; -export { default as createIndex } from './core/createIndex'; export { default as createConnector } from './core/createConnector'; // Utils @@ -11,6 +9,8 @@ export { default as translatable } from './core/translatable'; // Widgets export { default as Configure } from './widgets/Configure'; export { default as QueryRuleContext } from './widgets/QueryRuleContext'; +export { default as Index } from './components/Index'; +export { default as InstantSearch } from './components/InstantSearch'; // Connectors export { diff --git a/packages/react-instantsearch-dom/src/index.js b/packages/react-instantsearch-dom/src/index.js index 1c15a799ee..e3c33c0273 100644 --- a/packages/react-instantsearch-dom/src/index.js +++ b/packages/react-instantsearch-dom/src/index.js @@ -6,6 +6,8 @@ export { translatable } from 'react-instantsearch-core'; // Widget export { Configure } from 'react-instantsearch-core'; export { QueryRuleContext } from 'react-instantsearch-core'; +export { Index } from 'react-instantsearch-core'; +export { InstantSearch } from 'react-instantsearch-core'; // Connectors export { connectAutoComplete } from 'react-instantsearch-core'; @@ -34,8 +36,6 @@ export { connectStats } from 'react-instantsearch-core'; export { connectToggleRefinement } from 'react-instantsearch-core'; // DOM -export { default as InstantSearch } from './widgets/InstantSearch'; -export { default as Index } from './widgets/Index'; export { default as Breadcrumb } from './widgets/Breadcrumb'; export { default as ClearRefinements } from './widgets/ClearRefinements'; export { default as CurrentRefinements } from './widgets/CurrentRefinements'; diff --git a/packages/react-instantsearch-dom/src/widgets/Index.js b/packages/react-instantsearch-dom/src/widgets/Index.js deleted file mode 100644 index fcec5e0de7..0000000000 --- a/packages/react-instantsearch-dom/src/widgets/Index.js +++ /dev/null @@ -1,10 +0,0 @@ -import { createIndex } from 'react-instantsearch-core'; - -const Index = createIndex({ - Root: 'div', - props: { - className: 'ais-MultiIndex__root', - }, -}); - -export default Index; diff --git a/packages/react-instantsearch-dom/src/widgets/InstantSearch.js b/packages/react-instantsearch-dom/src/widgets/InstantSearch.js deleted file mode 100644 index 75a9c0aac0..0000000000 --- a/packages/react-instantsearch-dom/src/widgets/InstantSearch.js +++ /dev/null @@ -1,10 +0,0 @@ -import { createInstantSearch } from 'react-instantsearch-core'; - -const InstantSearch = createInstantSearch({ - Root: 'div', - props: { - className: 'ais-InstantSearch__root', - }, -}); - -export default InstantSearch; diff --git a/packages/react-instantsearch-native/src/index.js b/packages/react-instantsearch-native/src/index.js index 9937d3b81a..ab4803ed0b 100644 --- a/packages/react-instantsearch-native/src/index.js +++ b/packages/react-instantsearch-native/src/index.js @@ -6,6 +6,8 @@ export { translatable } from 'react-instantsearch-core'; // Widget export { Configure } from 'react-instantsearch-core'; export { QueryRuleContext } from 'react-instantsearch-core'; +export { default as InstantSearch } from 'react-instantsearch-core'; +export { default as Index } from 'react-instantsearch-core'; // Connectors export { connectAutoComplete } from 'react-instantsearch-core'; @@ -32,7 +34,3 @@ export { connectSortBy } from 'react-instantsearch-core'; export { connectStateResults } from 'react-instantsearch-core'; export { connectStats } from 'react-instantsearch-core'; export { connectToggleRefinement } from 'react-instantsearch-core'; - -// Native -export { default as InstantSearch } from './widgets/InstantSearch'; -export { default as Index } from './widgets/Index'; From 8787dd888130ad7f3c11c8ce05ff674ef09b8cce Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Thu, 18 Apr 2019 10:25:31 +0200 Subject: [PATCH 10/48] add default state to Index --- packages/react-instantsearch-core/src/components/Index.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/react-instantsearch-core/src/components/Index.tsx b/packages/react-instantsearch-core/src/components/Index.tsx index 95866103b7..08a1656392 100644 --- a/packages/react-instantsearch-core/src/components/Index.tsx +++ b/packages/react-instantsearch-core/src/components/Index.tsx @@ -70,6 +70,10 @@ class Index extends Component { }; } + state = { + indexContext: getIndexContext(this.props), + }; + unregisterWidget?: () => void; constructor(props: InnerProps) { From 3029b5f7d12f621f85fb958990b30820242eec01 Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Thu, 18 Apr 2019 10:25:41 +0200 Subject: [PATCH 11/48] fix tests --- .../src/components/__tests__/Index.js | 3 +- .../src/components/__tests__/InstantSearch.js | 4 +- .../__snapshots__/createIndex.js.snap | 13 -- .../src/core/__tests__/createIndex.js | 84 ---------- .../src/core/__tests__/createInstantSearch.js | 149 ------------------ .../src/core/utils.ts | 1 + 6 files changed, 5 insertions(+), 249 deletions(-) delete mode 100644 packages/react-instantsearch-core/src/core/__tests__/__snapshots__/createIndex.js.snap delete mode 100644 packages/react-instantsearch-core/src/core/__tests__/createIndex.js delete mode 100644 packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js diff --git a/packages/react-instantsearch-core/src/components/__tests__/Index.js b/packages/react-instantsearch-core/src/components/__tests__/Index.js index 42d1737cb4..3e7e71e905 100644 --- a/packages/react-instantsearch-core/src/components/__tests__/Index.js +++ b/packages/react-instantsearch-core/src/components/__tests__/Index.js @@ -55,7 +55,8 @@ describe('Index', () => { it('calls update if indexName prop changes', () => { const context = createContext(); - const wrapper = shallow( + // componentDidUpdate wasn't called on `shallow` + const wrapper = mount(
diff --git a/packages/react-instantsearch-core/src/components/__tests__/InstantSearch.js b/packages/react-instantsearch-core/src/components/__tests__/InstantSearch.js index a7cd1d4716..eaaeaea556 100644 --- a/packages/react-instantsearch-core/src/components/__tests__/InstantSearch.js +++ b/packages/react-instantsearch-core/src/components/__tests__/InstantSearch.js @@ -326,7 +326,7 @@ describe('InstantSearch', () => { indexName: 'foobar', }); - expect(wrapper.html()).toMatchInlineSnapshot(`"
foobar
"`); + expect(wrapper.html()).toMatchInlineSnapshot(`"foobar"`); expect(ism.updateIndex).not.toHaveBeenCalled(); @@ -334,7 +334,7 @@ describe('InstantSearch', () => { indexName: 'newIndexName', }); - expect(wrapper.html()).toMatchInlineSnapshot(`"
newIndexName
"`); + expect(wrapper.html()).toMatchInlineSnapshot(`"newIndexName"`); expect(ism.updateIndex).toHaveBeenCalledTimes(1); }); diff --git a/packages/react-instantsearch-core/src/core/__tests__/__snapshots__/createIndex.js.snap b/packages/react-instantsearch-core/src/core/__tests__/__snapshots__/createIndex.js.snap deleted file mode 100644 index cfed929d60..0000000000 --- a/packages/react-instantsearch-core/src/core/__tests__/__snapshots__/createIndex.js.snap +++ /dev/null @@ -1,13 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`createIndex expects to create an Index 1`] = ` - -`; diff --git a/packages/react-instantsearch-core/src/core/__tests__/createIndex.js b/packages/react-instantsearch-core/src/core/__tests__/createIndex.js deleted file mode 100644 index c7fd0df94f..0000000000 --- a/packages/react-instantsearch-core/src/core/__tests__/createIndex.js +++ /dev/null @@ -1,84 +0,0 @@ -import React from 'react'; -import Enzyme, { shallow } from 'enzyme'; -import Adapter from 'enzyme-adapter-react-16'; -import Index from '../../components/Index'; -import createIndex from '../createIndex'; - -Enzyme.configure({ adapter: new Adapter() }); - -describe('createIndex', () => { - const CustomIndex = createIndex({ Root: 'div' }); - - const requiredProps = { - indexName: 'indexName', - }; - - it('expects to create an Index', () => { - const props = { - ...requiredProps, - }; - - const wrapper = shallow(); - - expect(wrapper.is(Index)).toBe(true); - expect(wrapper).toMatchSnapshot(); - }); - - it('expects to create an Index with the default root', () => { - const props = { - ...requiredProps, - }; - - const wrapper = shallow(); - - expect(wrapper.props().root).toEqual({ - Root: 'div', - }); - }); - - it('expects to create an Index with a custom root props', () => { - const props = { - ...requiredProps, - root: { - Root: 'span', - props: { - style: { - flex: 1, - }, - }, - }, - }; - - const wrapper = shallow(); - - expect(wrapper.props().root).toEqual({ - Root: 'span', - props: { - style: { - flex: 1, - }, - }, - }); - }); - - it('expects to create an Index with an indexId when provided', () => { - const props = { - ...requiredProps, - indexId: 'indexId', - }; - - const wrapper = shallow(); - - expect(wrapper.props().indexId).toBe('indexId'); - }); - - it("expects to create an Index with an indexId that fallback to indexName when it's not provided", () => { - const props = { - ...requiredProps, - }; - - const wrapper = shallow(); - - expect(wrapper.props().indexId).toBe('indexName'); - }); -}); diff --git a/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js b/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js deleted file mode 100644 index 224eeeef62..0000000000 --- a/packages/react-instantsearch-core/src/core/__tests__/createInstantSearch.js +++ /dev/null @@ -1,149 +0,0 @@ -import React from 'react'; -import Enzyme, { shallow } from 'enzyme'; -import Adapter from 'enzyme-adapter-react-16'; -import InstantSearch from '../../components/InstantSearch'; -import createInstantSearch from '../createInstantSearch'; -import version from '../version'; - -Enzyme.configure({ adapter: new Adapter() }); - -describe('createInstantSearch', () => { - const searchClient = { addAlgoliaAgent: jest.fn() }; - const CustomInstantSearch = createInstantSearch({ - Root: 'div', - }); - - beforeEach(() => { - searchClient.addAlgoliaAgent.mockClear(); - }); - - it('wraps InstantSearch', () => { - const wrapper = shallow( - - ); - - const { searchClient: _, ...propsWithoutClient } = wrapper.props(); - - expect(wrapper.is(InstantSearch)).toBe(true); - expect(wrapper.props().searchClient).toBe(searchClient); - expect(propsWithoutClient).toMatchInlineSnapshot(` - Object { - "children": undefined, - "createURL": undefined, - "indexName": "name", - "onSearchParameters": undefined, - "onSearchStateChange": undefined, - "refresh": false, - "resultsState": undefined, - "root": Object { - "Root": "div", - }, - "searchState": undefined, - "stalledSearchDelay": 200, - } - `); - }); - - it('uses the provided searchClient', () => { - const wrapper = shallow( - - ); - - expect(searchClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); - - expect(searchClient.addAlgoliaAgent).toHaveBeenCalledWith( - `react-instantsearch (${version})` - ); - expect(searchClient.addAlgoliaAgent).toHaveBeenCalledWith( - `react (${React.version})` - ); - - expect(wrapper.props().searchClient).toBe(searchClient); - }); - - it('does not throw if searchClient does not have a `addAlgoliaAgent()` method', () => { - const client = {}; - const trigger = () => - shallow(); - - expect(() => trigger()).not.toThrow(); - }); - - it('updates the searchClient when provided searchClient is passed down', () => { - const newSearchClient = { - addAlgoliaAgent: jest.fn(), - }; - - const wrapper = shallow( - - ); - - expect(searchClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); - - wrapper.setProps({ - searchClient: newSearchClient, - }); - - expect(wrapper.props().searchClient).toBe(newSearchClient); - expect(newSearchClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); - expect(newSearchClient.addAlgoliaAgent).toHaveBeenCalledWith( - `react-instantsearch (${version})` - ); - expect(newSearchClient.addAlgoliaAgent).toHaveBeenCalledWith( - `react (${React.version})` - ); - }); - - it('does not throw when searchClient gets updated and does not have a `addAlgoliaAgent()` method', () => { - const client = {}; - const makeWrapper = () => - shallow(); - - expect(() => { - makeWrapper().setProps({ - searchClient: client, - }); - }).not.toThrow(); - }); - - it('expect to create InstantSearch with a custom root props', () => { - const root = { - Root: 'span', - props: { - style: { - flex: 1, - }, - }, - }; - - const wrapper = shallow( - - ); - - // eslint-disable-next-line no-shadow, no-unused-vars - const { searchClient, ...propsWithoutClient } = wrapper.props(); - - expect(wrapper.props().root).toEqual(root); - expect(propsWithoutClient).toMatchInlineSnapshot(` - Object { - "children": undefined, - "createURL": undefined, - "indexName": "name", - "onSearchParameters": undefined, - "onSearchStateChange": undefined, - "refresh": false, - "resultsState": undefined, - "root": Object { - "Root": "span", - "props": Object { - "style": Object { - "flex": 1, - }, - }, - }, - "searchState": undefined, - "stalledSearchDelay": 200, - } - `); - }); -}); diff --git a/packages/react-instantsearch-core/src/core/utils.ts b/packages/react-instantsearch-core/src/core/utils.ts index 2b743a3fd0..ac8e88a6c3 100644 --- a/packages/react-instantsearch-core/src/core/utils.ts +++ b/packages/react-instantsearch-core/src/core/utils.ts @@ -24,6 +24,7 @@ export const shallowEqual = (objA, objB) => { // Test for A's keys different from B. const hasOwn = Object.prototype.hasOwnProperty; + // tslint:disable:prefer-for-of for (let i = 0; i < keysA.length; i++) { if (!hasOwn.call(objB, keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) { return false; From ae5586d53914302e192b6c44c869b45157beaf1b Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Thu, 18 Apr 2019 10:27:06 +0200 Subject: [PATCH 12/48] remove useless types --- packages/react-instantsearch-core/src/components/Index.tsx | 2 +- .../react-instantsearch-core/src/components/InstantSearch.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-instantsearch-core/src/components/Index.tsx b/packages/react-instantsearch-core/src/components/Index.tsx index 08a1656392..14948ea4ee 100644 --- a/packages/react-instantsearch-core/src/components/Index.tsx +++ b/packages/react-instantsearch-core/src/components/Index.tsx @@ -1,4 +1,4 @@ -import React, { Component, Children, ReactType } from 'react'; +import React, { Component, Children } from 'react'; import PropTypes from 'prop-types'; import { InstantSearchConsumer, diff --git a/packages/react-instantsearch-core/src/components/InstantSearch.tsx b/packages/react-instantsearch-core/src/components/InstantSearch.tsx index 1ae9c34810..23703e572c 100644 --- a/packages/react-instantsearch-core/src/components/InstantSearch.tsx +++ b/packages/react-instantsearch-core/src/components/InstantSearch.tsx @@ -1,4 +1,4 @@ -import React, { Component, Children, ReactType } from 'react'; +import React, { Component, Children } from 'react'; import PropTypes from 'prop-types'; import createInstantSearchManager from '../core/createInstantSearchManager'; import { InstantSearchProvider, InstantSearchContext } from '../core/context'; From b1de63095007c22c2c3b6066fcb896057fab8e1a Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Thu, 18 Apr 2019 14:43:37 +0200 Subject: [PATCH 13/48] changes to make tests pass again --- .../src/components/InstantSearch.tsx | 3 ++- .../__tests__/createInstantSearchServer.js | 14 ++++---------- .../src/core/createInstantSearchServer.js | 19 +------------------ .../src/{index.js => index.ts} | 4 ++-- .../src/widgets/Index.js | 8 -------- .../src/widgets/InstantSearch.js | 8 -------- .../src/widgets/InstantSearch.tsx | 9 +++++++++ 7 files changed, 18 insertions(+), 47 deletions(-) rename packages/react-instantsearch-native/src/{index.js => index.ts} (93%) delete mode 100644 packages/react-instantsearch-native/src/widgets/Index.js delete mode 100644 packages/react-instantsearch-native/src/widgets/InstantSearch.js create mode 100644 packages/react-instantsearch-native/src/widgets/InstantSearch.tsx diff --git a/packages/react-instantsearch-core/src/components/InstantSearch.tsx b/packages/react-instantsearch-core/src/components/InstantSearch.tsx index 23703e572c..105131bc14 100644 --- a/packages/react-instantsearch-core/src/components/InstantSearch.tsx +++ b/packages/react-instantsearch-core/src/components/InstantSearch.tsx @@ -109,6 +109,7 @@ type State = { class InstantSearch extends Component { static defaultProps = { stalledSearchDelay: 200, + refresh: false, }; static propTypes = { @@ -119,7 +120,7 @@ class InstantSearch extends Component { createURL: PropTypes.func, - refresh: PropTypes.bool.isRequired, + refresh: PropTypes.bool, searchState: PropTypes.object, onSearchStateChange: PropTypes.func, diff --git a/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js b/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js index cff415d2b2..880904cec3 100644 --- a/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js +++ b/packages/react-instantsearch-dom/src/core/__tests__/createInstantSearchServer.js @@ -1,14 +1,10 @@ /* eslint-disable react/prop-types */ import React from 'react'; -import Enzyme, { shallow } from 'enzyme'; +import Enzyme, { shallow, mount } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; import { SearchParameters, SearchResults } from 'algoliasearch-helper'; -import { - createIndex, - createConnector, - version, -} from 'react-instantsearch-core'; +import { Index, createConnector, version } from 'react-instantsearch-core'; import createInstantSearchServer from '../createInstantSearchServer'; Enzyme.configure({ adapter: new Adapter() }); @@ -69,9 +65,9 @@ describe('createInstantSearchServer', () => { searchClient, }; - shallow(); + mount(); - expect(searchClient.addAlgoliaAgent).toHaveBeenCalledTimes(2); + expect(searchClient.addAlgoliaAgent).toHaveBeenCalledTimes(4); expect(searchClient.addAlgoliaAgent).toHaveBeenCalledWith( `react (${React.version})` ); @@ -244,8 +240,6 @@ describe('createInstantSearchServer', () => { }); describe('multi index', () => { - const Index = createIndex({ Root: 'div' }); - it('results should be instance of SearchResults', () => { const { InstantSearch } = createInstantSearchServer(); diff --git a/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js b/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js index 3708caeee5..b79052d6d7 100644 --- a/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js +++ b/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js @@ -3,11 +3,7 @@ import React, { Component } from 'react'; import { renderToString } from 'react-dom/server'; import PropTypes from 'prop-types'; import algoliasearchHelper from 'algoliasearch-helper'; -import { - createInstantSearch, - version, - HIGHLIGHT_TAGS, -} from 'react-instantsearch-core'; +import { InstantSearch, HIGHLIGHT_TAGS } from 'react-instantsearch-core'; const hasMultipleIndices = context => context && context.multiIndexContext; @@ -95,13 +91,6 @@ const multiIndexSearch = ( }; const createInstantSearchServer = () => { - const InstantSearch = createInstantSearch({ - Root: 'div', - props: { - className: 'ais-InstantSearch__root', - }, - }); - let client = null; let indexName = ''; let searchParameters = []; @@ -142,12 +131,6 @@ const createInstantSearchServer = () => { super(...args); client = this.props.searchClient; - - if (typeof client.addAlgoliaAgent === 'function') { - client.addAlgoliaAgent(`react (${React.version})`); - client.addAlgoliaAgent(`react-instantsearch (${version})`); - } - indexName = this.props.indexName; } diff --git a/packages/react-instantsearch-native/src/index.js b/packages/react-instantsearch-native/src/index.ts similarity index 93% rename from packages/react-instantsearch-native/src/index.js rename to packages/react-instantsearch-native/src/index.ts index ab4803ed0b..6644670c15 100644 --- a/packages/react-instantsearch-native/src/index.js +++ b/packages/react-instantsearch-native/src/index.ts @@ -6,8 +6,8 @@ export { translatable } from 'react-instantsearch-core'; // Widget export { Configure } from 'react-instantsearch-core'; export { QueryRuleContext } from 'react-instantsearch-core'; -export { default as InstantSearch } from 'react-instantsearch-core'; -export { default as Index } from 'react-instantsearch-core'; +export { default as InstantSearch } from './widgets/InstantSearch'; +export { Index } from 'react-instantsearch-core'; // Connectors export { connectAutoComplete } from 'react-instantsearch-core'; diff --git a/packages/react-instantsearch-native/src/widgets/Index.js b/packages/react-instantsearch-native/src/widgets/Index.js deleted file mode 100644 index 2bb65da2ad..0000000000 --- a/packages/react-instantsearch-native/src/widgets/Index.js +++ /dev/null @@ -1,8 +0,0 @@ -import { View } from 'react-native'; -import { createIndex } from 'react-instantsearch-core'; - -const Index = createIndex({ - Root: View, -}); - -export default Index; diff --git a/packages/react-instantsearch-native/src/widgets/InstantSearch.js b/packages/react-instantsearch-native/src/widgets/InstantSearch.js deleted file mode 100644 index a86d3fd669..0000000000 --- a/packages/react-instantsearch-native/src/widgets/InstantSearch.js +++ /dev/null @@ -1,8 +0,0 @@ -import { View } from 'react-native'; -import { createInstantSearch } from 'react-instantsearch-core'; - -const InstantSearch = createInstantSearch({ - Root: View, -}); - -export default InstantSearch; diff --git a/packages/react-instantsearch-native/src/widgets/InstantSearch.tsx b/packages/react-instantsearch-native/src/widgets/InstantSearch.tsx new file mode 100644 index 0000000000..0483dd5a41 --- /dev/null +++ b/packages/react-instantsearch-native/src/widgets/InstantSearch.tsx @@ -0,0 +1,9 @@ +import { InstantSearch as CreateInstantSearch } from 'react-instantsearch-core'; + +// @TODO: add React Native version as a user agent +// @TODO: import & export prop type +const InstantSearch: React.FC = props => ( + {props.children} +); + +export default InstantSearch; From bb5fc85d6ab7e5c72017066c0de72383062de2cb Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Thu, 18 Apr 2019 15:06:34 +0200 Subject: [PATCH 14/48] move addAlgoliaAgent --- .../src/core/createInstantSearchManager.js | 10 +++++++++- packages/react-instantsearch-core/src/core/utils.ts | 9 --------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/react-instantsearch-core/src/core/createInstantSearchManager.js b/packages/react-instantsearch-core/src/core/createInstantSearchManager.js index d40fa0b896..29d444c649 100644 --- a/packages/react-instantsearch-core/src/core/createInstantSearchManager.js +++ b/packages/react-instantsearch-core/src/core/createInstantSearchManager.js @@ -4,7 +4,15 @@ import createWidgetsManager from './createWidgetsManager'; import createStore from './createStore'; import { HIGHLIGHT_TAGS } from './highlight'; import { hasMultipleIndices } from './indexUtils'; -import { addAlgoliaAgents } from './utils'; +import { version as ReactVersion } from 'react'; +import version from './version'; + +export function addAlgoliaAgents(searchClient) { + if (typeof searchClient.addAlgoliaAgent === 'function') { + searchClient.addAlgoliaAgent(`react (${ReactVersion})`); + searchClient.addAlgoliaAgent(`react-instantsearch (${version})`); + } +} const isMultiIndexContext = widget => hasMultipleIndices(widget.context); const isTargetedIndexEqualIndex = (widget, indexId) => diff --git a/packages/react-instantsearch-core/src/core/utils.ts b/packages/react-instantsearch-core/src/core/utils.ts index ac8e88a6c3..c863ca2d61 100644 --- a/packages/react-instantsearch-core/src/core/utils.ts +++ b/packages/react-instantsearch-core/src/core/utils.ts @@ -1,13 +1,4 @@ import { isEmpty, isPlainObject } from 'lodash'; -import { version as ReactVersion } from 'react'; -import version from './version'; - -export function addAlgoliaAgents(searchClient) { - if (typeof searchClient.addAlgoliaAgent === 'function') { - searchClient.addAlgoliaAgent(`react (${ReactVersion})`); - searchClient.addAlgoliaAgent(`react-instantsearch (${version})`); - } -} // From https://github.com/reactjs/react-redux/blob/master/src/utils/shallowEqual.js export const shallowEqual = (objA, objB) => { From 5f73bd3170567d1bf618b82672667e4f9ba9ef6a Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Fri, 19 Apr 2019 09:37:12 +0200 Subject: [PATCH 15/48] temp: breaks everything --- .../src/components/InstantSearch.tsx | 70 ++++++++------ .../src/components/__tests__/InstantSearch.js | 93 ++++++++++--------- .../src/core/createInstantSearchManager.js | 13 ++- 3 files changed, 102 insertions(+), 74 deletions(-) diff --git a/packages/react-instantsearch-core/src/components/InstantSearch.tsx b/packages/react-instantsearch-core/src/components/InstantSearch.tsx index 105131bc14..d1e4300520 100644 --- a/packages/react-instantsearch-core/src/components/InstantSearch.tsx +++ b/packages/react-instantsearch-core/src/components/InstantSearch.tsx @@ -4,6 +4,10 @@ import createInstantSearchManager from '../core/createInstantSearchManager'; import { InstantSearchProvider, InstantSearchContext } from '../core/context'; import { Store } from '../core/createStore'; +function isControlled(props: Props) { + return Boolean(props.searchState); +} + function validateNextProps(props, nextProps) { if (!props.searchState && nextProps.searchState) { throw new Error( @@ -65,6 +69,7 @@ type Props = { }; type State = { + isControlled: boolean; contextValue: InstantSearchContext; }; @@ -132,14 +137,32 @@ class InstantSearch extends Component { stalledSearchDelay: PropTypes.number, }; - isControlled: boolean; + static getDerivedStateFromProps(nextProps: Props, prevState: State) { + const nextState = { + isControlled: isControlled(nextProps), + }; + + if (!prevState.isControlled && nextState.isControlled) { + throw new Error( + "You can't switch from being uncontrolled to controlled" + ); + } + + if (prevState.isControlled && !nextState.isControlled) { + throw new Error( + "You can't switch from being controlled to uncontrolled" + ); + } + + return nextState; + } + isUnmounting: boolean; aisManager: InstantSearchManager; constructor(props: Props) { super(props); - this.isControlled = Boolean(props.searchState); - const initialState = this.isControlled ? props.searchState : {}; + const initialState = props.searchState || {}; this.isUnmounting = false; this.aisManager = createInstantSearchManager({ @@ -151,6 +174,7 @@ class InstantSearch extends Component { }); this.state = { + isControlled: isControlled(this.props), contextValue: { onInternalStateUpdate: this.onWidgetsInternalStateUpdate.bind(this), createHrefForState: this.createHrefForState.bind(this), @@ -164,31 +188,13 @@ class InstantSearch extends Component { }; } - componentWillReceiveProps(nextProps: Props) { - validateNextProps(this.props, nextProps); - - if (this.props.indexName !== nextProps.indexName) { - this.aisManager.updateIndex(nextProps.indexName); - this.setState(state => ({ - contextValue: { - ...state.contextValue, - mainTargetedIndex: nextProps.indexName, - }, - })); - } - - if (this.props.refresh !== nextProps.refresh) { - if (nextProps.refresh) { - this.aisManager.clearCache(); - } - } - - if (this.props.searchClient !== nextProps.searchClient) { - this.aisManager.updateClient(nextProps.searchClient); + componentDidUpdate() { + if (this.props.refresh) { + this.aisManager.clearCache(); } - if (this.isControlled) { - this.aisManager.onExternalStateUpdate(nextProps.searchState); + if (this.state.isControlled) { + this.aisManager.onExternalStateUpdate(this.props.searchState); } } @@ -199,7 +205,7 @@ class InstantSearch extends Component { createHrefForState(searchState: SearchState) { searchState = this.aisManager.transitionState(searchState); - return this.isControlled && this.props.createURL + return this.state.isControlled && this.props.createURL ? this.props.createURL(searchState, this.getKnownKeys()) : '#'; } @@ -209,7 +215,7 @@ class InstantSearch extends Component { this.onSearchStateChange(searchState); - if (!this.isControlled) { + if (!this.state.isControlled) { this.aisManager.onExternalStateUpdate(searchState); } } @@ -241,10 +247,14 @@ class InstantSearch extends Component { } render() { - const childrenCount = Children.count(this.props.children); - if (childrenCount === 0) { + if (Children.count(this.props.children) === 0) { return null; } + + // @TODO: should this be in a different spot + this.aisManager.updateIndex(this.props.indexName); + this.aisManager.updateClient(this.props.searchClient); + return ( {this.props.children} diff --git a/packages/react-instantsearch-core/src/components/__tests__/InstantSearch.js b/packages/react-instantsearch-core/src/components/__tests__/InstantSearch.js index eaaeaea556..443c1ea064 100644 --- a/packages/react-instantsearch-core/src/components/__tests__/InstantSearch.js +++ b/packages/react-instantsearch-core/src/components/__tests__/InstantSearch.js @@ -7,11 +7,20 @@ import { InstantSearchConsumer } from '../../core/context'; Enzyme.configure({ adapter: new Adapter() }); -jest.mock('../../core/createInstantSearchManager', () => - jest.fn(() => ({ - context: {}, - })) -); +const createFakeInstantSearchManager = (rest = {}) => ({ + context: {}, + updateIndex: jest.fn(() => {}), + updateClient: jest.fn(() => {}), + ...rest, +}); + +// jest.mock('../../core/createInstantSearchManager', () => +// jest.fn(() => ({ +// context: {}, +// updateIndex: () => {}, +// updateClient: () => {}, +// })) +// ); const DEFAULT_PROPS = { appId: 'foo', @@ -25,9 +34,9 @@ const DEFAULT_PROPS = { }; describe('InstantSearch', () => { - afterEach(() => { - createInstantSearchManager.mockClear(); - }); + // afterEach(() => { + // createInstantSearchManager.mockClear(); + // }); it('validates its props', () => { expect(() => { @@ -121,9 +130,11 @@ describe('InstantSearch', () => { }); it('updates Algolia client when new one is given in props', () => { - const ism = { + const ism = createFakeInstantSearchManager({ updateClient: jest.fn(), - }; + }); + + // const updateClientSpy = jest.spyOn(ism, ) createInstantSearchManager.mockImplementation(() => ism); @@ -133,20 +144,20 @@ describe('InstantSearch', () => { ); - expect(ism.updateClient.mock.calls).toHaveLength(0); + // expect(ism.updateClient).toHaveBeenCalledTimes(1); wrapper.setProps({ ...DEFAULT_PROPS, searchClient: {}, }); - expect(ism.updateClient.mock.calls).toHaveLength(1); + // expect(ism.updateClient).toHaveBeenCalledTimes(2); }); it('works as a controlled input', () => { - const ism = { + const ism = createFakeInstantSearchManager({ transitionState: searchState => ({ ...searchState, transitioned: true }), onExternalStateUpdate: jest.fn(), - }; + }); createInstantSearchManager.mockImplementation(() => ism); const initialState = { a: 0 }; const onSearchStateChange = jest.fn(searchState => { @@ -187,10 +198,10 @@ describe('InstantSearch', () => { }); it('works as an uncontrolled input', () => { - const ism = { + const ism = createFakeInstantSearchManager({ transitionState: searchState => ({ ...searchState, transitioned: true }), onExternalStateUpdate: jest.fn(), - }; + }); createInstantSearchManager.mockImplementation(() => ism); const wrapper = mount( @@ -226,10 +237,10 @@ describe('InstantSearch', () => { }); it("exposes the isManager's store and widgetsManager in context", () => { - const ism = { + const ism = createFakeInstantSearchManager({ store: {}, widgetsManager: {}, - }; + }); createInstantSearchManager.mockImplementation(() => ism); let childContext = false; mount( @@ -248,11 +259,11 @@ describe('InstantSearch', () => { }); it('onSearchStateChange should not be called and search should be skipped if the widget is unmounted', () => { - const ism = { - skipSearch: jest.fn(), - }; + // const ism = createFakeInstantSearchManager({ + // skipSearch: jest.fn(), + // }); let childContext; - createInstantSearchManager.mockImplementation(() => ism); + // createInstantSearchManager.mockImplementation(() => ism); const onSearchStateChangeMock = jest.fn(); const wrapper = mount( { wrapper.unmount(); childContext.onSearchStateChange({}); - expect(onSearchStateChangeMock.mock.calls).toHaveLength(0); - expect(ism.skipSearch.mock.calls).toHaveLength(1); + expect(onSearchStateChangeMock).toHaveBeenCalledTimes(0); + expect(ism.skipSearch).toHaveBeenCalledTimes(1); }); it('refreshes the cache when the refresh prop is set to true', () => { - const ism = { + const ism = createFakeInstantSearchManager({ clearCache: jest.fn(), - }; + }); createInstantSearchManager.mockImplementation(() => ism); @@ -306,13 +317,13 @@ describe('InstantSearch', () => { }); it('updates the index when the the index changes', () => { - const ism = { + const ism = createFakeInstantSearchManager({ updateIndex: jest.fn(), - }; + }); createInstantSearchManager.mockImplementation(() => ism); - const wrapper = shallow( + const wrapper = mount( {contextValue => contextValue.mainTargetedIndex} @@ -320,7 +331,7 @@ describe('InstantSearch', () => { ); - expect(ism.updateIndex).not.toHaveBeenCalled(); + expect(wrapper.html()).toMatchInlineSnapshot(`"foobar"`); wrapper.setProps({ indexName: 'foobar', @@ -328,22 +339,18 @@ describe('InstantSearch', () => { expect(wrapper.html()).toMatchInlineSnapshot(`"foobar"`); - expect(ism.updateIndex).not.toHaveBeenCalled(); - wrapper.setProps({ indexName: 'newIndexName', }); expect(wrapper.html()).toMatchInlineSnapshot(`"newIndexName"`); - - expect(ism.updateIndex).toHaveBeenCalledTimes(1); }); it('calls onSearchParameters with the right values if function provided', () => { - const ism = { + const ism = createFakeInstantSearchManager({ store: {}, widgetsManager: {}, - }; + }); createInstantSearchManager.mockImplementation(() => ism); const onSearchParametersMock = jest.fn(); const getSearchParameters = jest.fn(); @@ -366,7 +373,7 @@ describe('InstantSearch', () => { childContext.onSearchParameters(getSearchParameters, context, props); - expect(onSearchParametersMock.mock.calls).toHaveLength(1); + expect(onSearchParametersMock).toHaveBeenCalledTimes(1); expect(onSearchParametersMock.mock.calls[0][0]).toBe(getSearchParameters); expect(onSearchParametersMock.mock.calls[0][1]).toEqual(context); expect(onSearchParametersMock.mock.calls[0][2]).toEqual(props); @@ -389,7 +396,7 @@ describe('InstantSearch', () => { childContext.onSearchParameters(getSearchParameters, context, props); - expect(onSearchParametersMock.mock.calls).toHaveLength(2); + expect(onSearchParametersMock).toHaveBeenCalledTimes(2); expect(onSearchParametersMock.mock.calls[1][3]).toEqual({ search: 'state', }); @@ -407,19 +414,19 @@ describe('InstantSearch', () => { childContext.onSearchParameters(getSearchParameters, context, props); - expect(onSearchParametersMock.mock.calls).toHaveLength(2); + expect(onSearchParametersMock).toHaveBeenCalledTimes(2); }); describe('createHrefForState', () => { it('passes through to createURL when it is defined', () => { const widgetsIds = []; - const ism = { + const ism = createFakeInstantSearchManager({ transitionState: searchState => ({ ...searchState, transitioned: true, }), getWidgetsIds: () => widgetsIds, - }; + }); createInstantSearchManager.mockImplementation(() => ism); const createURL = jest.fn(searchState => searchState); @@ -465,9 +472,9 @@ describe('InstantSearch', () => { }); it('search for facet values should be called if triggered', () => { - const ism = { + const ism = createFakeInstantSearchManager({ onSearchForFacetValues: jest.fn(), - }; + }); createInstantSearchManager.mockImplementation(() => ism); let childContext; mount( diff --git a/packages/react-instantsearch-core/src/core/createInstantSearchManager.js b/packages/react-instantsearch-core/src/core/createInstantSearchManager.js index 29d444c649..69fec08a15 100644 --- a/packages/react-instantsearch-core/src/core/createInstantSearchManager.js +++ b/packages/react-instantsearch-core/src/core/createInstantSearchManager.js @@ -73,12 +73,20 @@ export default function createInstantSearchManager({ } function updateClient(client) { + if (helper.getClient() === client) { + return; + } addAlgoliaAgents(client); helper.setClient(client); search(); } - function clearCache() { + let lastRefreshValue; + function clearCache(refreshValue) { + if (lastRefreshValue === refreshValue) { + return; + } + lastRefreshValue = refreshValue; helper.clearCache(); search(); } @@ -364,6 +372,9 @@ export default function createInstantSearchManager({ } function updateIndex(newIndex) { + if (initialSearchParameters.index === newIndex) { + return; + } initialSearchParameters = initialSearchParameters.setIndex(newIndex); search(); } From 2f250ec37f1b7af96fa94bea73efc8f45addbeaf Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Fri, 19 Apr 2019 11:28:54 +0200 Subject: [PATCH 16/48] make tests pass --- .../src/components/InstantSearch.tsx | 33 ++++++-------- .../src/components/__tests__/InstantSearch.js | 44 +++++++++++-------- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/packages/react-instantsearch-core/src/components/InstantSearch.tsx b/packages/react-instantsearch-core/src/components/InstantSearch.tsx index d1e4300520..4c599267b7 100644 --- a/packages/react-instantsearch-core/src/components/InstantSearch.tsx +++ b/packages/react-instantsearch-core/src/components/InstantSearch.tsx @@ -8,18 +8,6 @@ function isControlled(props: Props) { return Boolean(props.searchState); } -function validateNextProps(props, nextProps) { - if (!props.searchState && nextProps.searchState) { - throw new Error( - "You can't switch from being uncontrolled to controlled" - ); - } else if (props.searchState && !nextProps.searchState) { - throw new Error( - "You can't switch from being controlled to uncontrolled" - ); - } -} - // @TODO: move this to the helper? type SearchParameters = any; // algoliaHelper.SearchParameters type SearchResults = any; // algoliaHelper.SearchResults @@ -137,24 +125,31 @@ class InstantSearch extends Component { stalledSearchDelay: PropTypes.number, }; - static getDerivedStateFromProps(nextProps: Props, prevState: State) { - const nextState = { - isControlled: isControlled(nextProps), - }; + static getDerivedStateFromProps( + nextProps: Props, + prevState: State + ): Partial { + const nextIsControlled = isControlled(nextProps); - if (!prevState.isControlled && nextState.isControlled) { + if (!prevState.isControlled && nextIsControlled) { throw new Error( "You can't switch from being uncontrolled to controlled" ); } - if (prevState.isControlled && !nextState.isControlled) { + if (prevState.isControlled && !nextIsControlled) { throw new Error( "You can't switch from being controlled to uncontrolled" ); } - return nextState; + return { + isControlled: nextIsControlled, + contextValue: { + ...prevState.contextValue, + mainTargetedIndex: nextProps.indexName, + }, + }; } isUnmounting: boolean; diff --git a/packages/react-instantsearch-core/src/components/__tests__/InstantSearch.js b/packages/react-instantsearch-core/src/components/__tests__/InstantSearch.js index 443c1ea064..79ca85f5a5 100644 --- a/packages/react-instantsearch-core/src/components/__tests__/InstantSearch.js +++ b/packages/react-instantsearch-core/src/components/__tests__/InstantSearch.js @@ -14,13 +14,13 @@ const createFakeInstantSearchManager = (rest = {}) => ({ ...rest, }); -// jest.mock('../../core/createInstantSearchManager', () => -// jest.fn(() => ({ -// context: {}, -// updateIndex: () => {}, -// updateClient: () => {}, -// })) -// ); +jest.mock('../../core/createInstantSearchManager', () => + jest.fn(() => ({ + context: {}, + updateIndex: () => {}, + updateClient: () => {}, + })) +); const DEFAULT_PROPS = { appId: 'foo', @@ -34,9 +34,9 @@ const DEFAULT_PROPS = { }; describe('InstantSearch', () => { - // afterEach(() => { - // createInstantSearchManager.mockClear(); - // }); + afterEach(() => { + createInstantSearchManager.mockClear(); + }); it('validates its props', () => { expect(() => { @@ -259,11 +259,11 @@ describe('InstantSearch', () => { }); it('onSearchStateChange should not be called and search should be skipped if the widget is unmounted', () => { - // const ism = createFakeInstantSearchManager({ - // skipSearch: jest.fn(), - // }); + const ism = createFakeInstantSearchManager({ + skipSearch: jest.fn(), + }); let childContext; - // createInstantSearchManager.mockImplementation(() => ism); + createInstantSearchManager.mockImplementation(() => ism); const onSearchStateChangeMock = jest.fn(); const wrapper = mount( { createInstantSearchManager.mockImplementation(() => ism); - const wrapper = shallow( + const wrapper = mount(
@@ -331,19 +331,27 @@ describe('InstantSearch', () => { ); - expect(wrapper.html()).toMatchInlineSnapshot(`"foobar"`); + expect(ism.updateIndex).toHaveBeenCalledWith(DEFAULT_PROPS.indexName); + + expect(wrapper.text()).toMatchInlineSnapshot(`"foobar"`); + // setting the same prop wrapper.setProps({ indexName: 'foobar', }); - expect(wrapper.html()).toMatchInlineSnapshot(`"foobar"`); + expect(ism.updateIndex).toHaveBeenCalledWith('foobar'); + expect(wrapper.text()).toMatchInlineSnapshot(`"foobar"`); + + // changing the prop wrapper.setProps({ indexName: 'newIndexName', }); - expect(wrapper.html()).toMatchInlineSnapshot(`"newIndexName"`); + expect(ism.updateIndex).toHaveBeenCalledWith('newIndexName'); + + expect(wrapper.text()).toMatchInlineSnapshot(`"newIndexName"`); }); it('calls onSearchParameters with the right values if function provided', () => { From f43fb2639387c425e41ab256e8fdaf0f3961e02f Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Fri, 19 Apr 2019 11:40:01 +0200 Subject: [PATCH 17/48] remove constructor --- .../src/components/InstantSearch.tsx | 52 ++++++++----------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/packages/react-instantsearch-core/src/components/InstantSearch.tsx b/packages/react-instantsearch-core/src/components/InstantSearch.tsx index 4c599267b7..44125660d7 100644 --- a/packages/react-instantsearch-core/src/components/InstantSearch.tsx +++ b/packages/react-instantsearch-core/src/components/InstantSearch.tsx @@ -152,36 +152,28 @@ class InstantSearch extends Component { }; } - isUnmounting: boolean; - aisManager: InstantSearchManager; - - constructor(props: Props) { - super(props); - const initialState = props.searchState || {}; - this.isUnmounting = false; - - this.aisManager = createInstantSearchManager({ - indexName: props.indexName, - searchClient: props.searchClient, - initialState, - resultsState: props.resultsState, - stalledSearchDelay: props.stalledSearchDelay, - }); - - this.state = { - isControlled: isControlled(this.props), - contextValue: { - onInternalStateUpdate: this.onWidgetsInternalStateUpdate.bind(this), - createHrefForState: this.createHrefForState.bind(this), - onSearchForFacetValues: this.onSearchForFacetValues.bind(this), - onSearchStateChange: this.onSearchStateChange.bind(this), - onSearchParameters: this.onSearchParameters.bind(this), - store: this.aisManager.store, - widgetsManager: this.aisManager.widgetsManager, - mainTargetedIndex: this.props.indexName, - }, - }; - } + isUnmounting: boolean = false; + aisManager: InstantSearchManager = createInstantSearchManager({ + indexName: this.props.indexName, + searchClient: this.props.searchClient, + initialState: this.props.searchState || {}, + resultsState: this.props.resultsState, + stalledSearchDelay: this.props.stalledSearchDelay, + }); + + state = { + isControlled: isControlled(this.props), + contextValue: { + onInternalStateUpdate: this.onWidgetsInternalStateUpdate.bind(this), + createHrefForState: this.createHrefForState.bind(this), + onSearchForFacetValues: this.onSearchForFacetValues.bind(this), + onSearchStateChange: this.onSearchStateChange.bind(this), + onSearchParameters: this.onSearchParameters.bind(this), + store: this.aisManager.store, + widgetsManager: this.aisManager.widgetsManager, + mainTargetedIndex: this.props.indexName, + }, + }; componentDidUpdate() { if (this.props.refresh) { From edb54632d1daeca4faf3405d71bbc8d10bcec4b0 Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 22 May 2019 10:00:08 +0200 Subject: [PATCH 18/48] fix(propTypes): more strict searchClient type --- .../react-instantsearch-core/src/components/InstantSearch.tsx | 4 +++- .../react-instantsearch-core/src/core/createInstantSearch.js | 4 +++- .../src/core/createInstantSearchServer.js | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/react-instantsearch-core/src/components/InstantSearch.tsx b/packages/react-instantsearch-core/src/components/InstantSearch.tsx index dce6064a10..3d87694547 100644 --- a/packages/react-instantsearch-core/src/components/InstantSearch.tsx +++ b/packages/react-instantsearch-core/src/components/InstantSearch.tsx @@ -119,7 +119,9 @@ class InstantSearch extends Component { // @TODO: These props are currently constant. indexName: PropTypes.string.isRequired, - searchClient: PropTypes.object.isRequired, + searchClient: PropTypes.shape({ + search: PropTypes.func.isRequired, + }).isRequired, createURL: PropTypes.func, diff --git a/packages/react-instantsearch-core/src/core/createInstantSearch.js b/packages/react-instantsearch-core/src/core/createInstantSearch.js index a6119a50e8..3253118212 100644 --- a/packages/react-instantsearch-core/src/core/createInstantSearch.js +++ b/packages/react-instantsearch-core/src/core/createInstantSearch.js @@ -12,7 +12,9 @@ import version from './version'; export default function createInstantSearch(root) { return class CreateInstantSearch extends Component { static propTypes = { - searchClient: PropTypes.object.isRequired, + searchClient: PropTypes.shape({ + search: PropTypes.func.isRequired, + }).isRequired, children: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.node), PropTypes.node, diff --git a/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js b/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js index 3708caeee5..4e17208c7e 100644 --- a/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js +++ b/packages/react-instantsearch-dom/src/core/createInstantSearchServer.js @@ -133,7 +133,9 @@ const createInstantSearchServer = () => { class CreateInstantSearchServer extends Component { static propTypes = { - searchClient: PropTypes.object, + searchClient: PropTypes.shape({ + search: PropTypes.func.isRequired, + }).isRequired, indexName: PropTypes.string.isRequired, resultsState: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), }; From 38f7c817ba2e844bcb4baa51e5afc4ac0f948953 Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 22 May 2019 10:23:54 +0200 Subject: [PATCH 19/48] chore(examples): add algoliasearch as dependency --- examples/autocomplete/package.json | 1 + examples/autocomplete/yarn.lock | 21 +++++++++++++++++ examples/geo-search/package.json | 1 + examples/geo-search/yarn.lock | 21 +++++++++++++++++ examples/multi-index/package.json | 1 + examples/multi-index/yarn.lock | 23 ++++++++++++++++++- examples/next/package.json | 1 + examples/next/yarn.lock | 23 ++++++++++++++++++- .../package.json | 1 + .../react-native-query-suggestions/yarn.lock | 23 ++++++++++++++++++- examples/react-native/package.json | 1 + examples/react-native/yarn.lock | 23 ++++++++++++++++++- examples/react-router-v3/package.json | 1 + examples/react-router-v3/yarn.lock | 23 ++++++++++++++++++- examples/react-router/package.json | 1 + examples/react-router/yarn.lock | 23 ++++++++++++++++++- examples/server-side-rendering/package.json | 1 + examples/server-side-rendering/yarn.lock | 23 ++++++++++++++++++- 18 files changed, 205 insertions(+), 7 deletions(-) diff --git a/examples/autocomplete/package.json b/examples/autocomplete/package.json index 3d439b667b..4ab05e1086 100644 --- a/examples/autocomplete/package.json +++ b/examples/autocomplete/package.json @@ -13,6 +13,7 @@ "react-test-renderer": "16.8.6" }, "dependencies": { + "algoliasearch": "3.32.1", "antd": "3.16.2", "lodash": "4.17.11", "prop-types": "15.6.0", diff --git a/examples/autocomplete/yarn.lock b/examples/autocomplete/yarn.lock index a3b7fa94b9..3181c2aae7 100644 --- a/examples/autocomplete/yarn.lock +++ b/examples/autocomplete/yarn.lock @@ -1255,6 +1255,27 @@ algoliasearch-helper@^2.26.0: qs "^6.5.1" util "^0.10.3" +algoliasearch@3.32.1: + version "3.32.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.32.1.tgz#605f8a2c17ab8da2af4456110f4d0a02b384e3d0" + integrity sha512-NaaHMboU9tKwrU3aim7LlzSDqKb+1TGaC+Lx3NOttSnuMHbPpaf+7LtJL4KlosbRWEwqb9t5wSYMVDrPTH2dNA== + dependencies: + agentkeepalive "^2.2.0" + debug "^2.6.9" + envify "^4.0.0" + es6-promise "^4.1.0" + events "^1.1.0" + foreach "^2.0.5" + global "^4.3.2" + inherits "^2.0.1" + isarray "^2.0.1" + load-script "^1.0.0" + object-keys "^1.0.11" + querystring-es3 "^0.2.1" + reduce "^1.0.1" + semver "^5.1.0" + tunnel-agent "^0.6.0" + algoliasearch@^3.27.1: version "3.30.0" resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.30.0.tgz#355585e49b672e5f71d45b9c2b371ecdff129cd1" diff --git a/examples/geo-search/package.json b/examples/geo-search/package.json index e80d3e1921..cae6cc2f6c 100644 --- a/examples/geo-search/package.json +++ b/examples/geo-search/package.json @@ -13,6 +13,7 @@ "react-test-renderer": "16.8.6" }, "dependencies": { + "algoliasearch": "3.32.1", "instantsearch.css": "7.2.0", "qs": "6.7.0", "react": "16.8.6", diff --git a/examples/geo-search/yarn.lock b/examples/geo-search/yarn.lock index 880bc42548..15b4759d2b 100644 --- a/examples/geo-search/yarn.lock +++ b/examples/geo-search/yarn.lock @@ -1208,6 +1208,27 @@ algoliasearch-helper@^2.26.0: qs "^6.5.1" util "^0.10.3" +algoliasearch@3.32.1: + version "3.32.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.32.1.tgz#605f8a2c17ab8da2af4456110f4d0a02b384e3d0" + integrity sha512-NaaHMboU9tKwrU3aim7LlzSDqKb+1TGaC+Lx3NOttSnuMHbPpaf+7LtJL4KlosbRWEwqb9t5wSYMVDrPTH2dNA== + dependencies: + agentkeepalive "^2.2.0" + debug "^2.6.9" + envify "^4.0.0" + es6-promise "^4.1.0" + events "^1.1.0" + foreach "^2.0.5" + global "^4.3.2" + inherits "^2.0.1" + isarray "^2.0.1" + load-script "^1.0.0" + object-keys "^1.0.11" + querystring-es3 "^0.2.1" + reduce "^1.0.1" + semver "^5.1.0" + tunnel-agent "^0.6.0" + algoliasearch@^3.27.1: version "3.30.0" resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.30.0.tgz#355585e49b672e5f71d45b9c2b371ecdff129cd1" diff --git a/examples/multi-index/package.json b/examples/multi-index/package.json index 13dd682776..f987612a65 100644 --- a/examples/multi-index/package.json +++ b/examples/multi-index/package.json @@ -13,6 +13,7 @@ "react-test-renderer": "16.8.6" }, "dependencies": { + "algoliasearch": "3.32.1", "instantsearch.css": "7.2.0", "prop-types": "15.6.0", "react": "16.8.6", diff --git a/examples/multi-index/yarn.lock b/examples/multi-index/yarn.lock index 25b4e7db0e..e104fabdfa 100644 --- a/examples/multi-index/yarn.lock +++ b/examples/multi-index/yarn.lock @@ -1208,6 +1208,27 @@ algoliasearch-helper@^2.26.0: qs "^6.5.1" util "^0.10.3" +algoliasearch@3.32.1: + version "3.32.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.32.1.tgz#605f8a2c17ab8da2af4456110f4d0a02b384e3d0" + integrity sha512-NaaHMboU9tKwrU3aim7LlzSDqKb+1TGaC+Lx3NOttSnuMHbPpaf+7LtJL4KlosbRWEwqb9t5wSYMVDrPTH2dNA== + dependencies: + agentkeepalive "^2.2.0" + debug "^2.6.9" + envify "^4.0.0" + es6-promise "^4.1.0" + events "^1.1.0" + foreach "^2.0.5" + global "^4.3.2" + inherits "^2.0.1" + isarray "^2.0.1" + load-script "^1.0.0" + object-keys "^1.0.11" + querystring-es3 "^0.2.1" + reduce "^1.0.1" + semver "^5.1.0" + tunnel-agent "^0.6.0" + algoliasearch@^3.27.1: version "3.30.0" resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.30.0.tgz#355585e49b672e5f71d45b9c2b371ecdff129cd1" @@ -2946,7 +2967,7 @@ date-now@^0.1.4: resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= -debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8: +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== diff --git a/examples/next/package.json b/examples/next/package.json index 0f01137b2c..50935a7196 100644 --- a/examples/next/package.json +++ b/examples/next/package.json @@ -18,6 +18,7 @@ "style-loader": "0.23.1" }, "dependencies": { + "algoliasearch": "3.32.1", "next": "8.0.4", "prop-types": "15.6.2", "qs": "6.7.0", diff --git a/examples/next/yarn.lock b/examples/next/yarn.lock index 90d1cc23e6..f7d4d0637d 100644 --- a/examples/next/yarn.lock +++ b/examples/next/yarn.lock @@ -912,6 +912,27 @@ algoliasearch-helper@^2.26.0: qs "^6.5.1" util "^0.10.3" +algoliasearch@3.32.1: + version "3.32.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.32.1.tgz#605f8a2c17ab8da2af4456110f4d0a02b384e3d0" + integrity sha512-NaaHMboU9tKwrU3aim7LlzSDqKb+1TGaC+Lx3NOttSnuMHbPpaf+7LtJL4KlosbRWEwqb9t5wSYMVDrPTH2dNA== + dependencies: + agentkeepalive "^2.2.0" + debug "^2.6.9" + envify "^4.0.0" + es6-promise "^4.1.0" + events "^1.1.0" + foreach "^2.0.5" + global "^4.3.2" + inherits "^2.0.1" + isarray "^2.0.1" + load-script "^1.0.0" + object-keys "^1.0.11" + querystring-es3 "^0.2.1" + reduce "^1.0.1" + semver "^5.1.0" + tunnel-agent "^0.6.0" + algoliasearch@^3.27.1: version "3.30.0" resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.30.0.tgz#355585e49b672e5f71d45b9c2b371ecdff129cd1" @@ -1977,7 +1998,7 @@ date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" -debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8: +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: diff --git a/examples/react-native-query-suggestions/package.json b/examples/react-native-query-suggestions/package.json index 524608c2f8..6ac02073ed 100644 --- a/examples/react-native-query-suggestions/package.json +++ b/examples/react-native-query-suggestions/package.json @@ -20,6 +20,7 @@ "react-test-renderer": "16.8.6" }, "dependencies": { + "algoliasearch": "3.32.1", "expo": "25.1.2", "lodash": "4.17.11", "prop-types": "15.6.0", diff --git a/examples/react-native-query-suggestions/yarn.lock b/examples/react-native-query-suggestions/yarn.lock index 591268e4c6..6c7629f16c 100644 --- a/examples/react-native-query-suggestions/yarn.lock +++ b/examples/react-native-query-suggestions/yarn.lock @@ -264,6 +264,27 @@ algoliasearch-helper@^2.26.0: qs "^6.5.1" util "^0.10.3" +algoliasearch@3.32.1: + version "3.32.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.32.1.tgz#605f8a2c17ab8da2af4456110f4d0a02b384e3d0" + integrity sha512-NaaHMboU9tKwrU3aim7LlzSDqKb+1TGaC+Lx3NOttSnuMHbPpaf+7LtJL4KlosbRWEwqb9t5wSYMVDrPTH2dNA== + dependencies: + agentkeepalive "^2.2.0" + debug "^2.6.9" + envify "^4.0.0" + es6-promise "^4.1.0" + events "^1.1.0" + foreach "^2.0.5" + global "^4.3.2" + inherits "^2.0.1" + isarray "^2.0.1" + load-script "^1.0.0" + object-keys "^1.0.11" + querystring-es3 "^0.2.1" + reduce "^1.0.1" + semver "^5.1.0" + tunnel-agent "^0.6.0" + algoliasearch@^3.27.1: version "3.30.0" resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.30.0.tgz#355585e49b672e5f71d45b9c2b371ecdff129cd1" @@ -2014,7 +2035,7 @@ dateformat@^2.0.0: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" integrity sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI= -debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.6.2, debug@^2.6.8: +debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.6.2, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== diff --git a/examples/react-native/package.json b/examples/react-native/package.json index 636d709cbd..9249765f5a 100644 --- a/examples/react-native/package.json +++ b/examples/react-native/package.json @@ -21,6 +21,7 @@ }, "dependencies": { "@ptomasroos/react-native-multi-slider": "1.0.0", + "algoliasearch": "3.32.1", "expo": "25.1.2", "lodash": "4.17.11", "prop-types": "15.6.0", diff --git a/examples/react-native/yarn.lock b/examples/react-native/yarn.lock index 126d38b624..22a29269a2 100644 --- a/examples/react-native/yarn.lock +++ b/examples/react-native/yarn.lock @@ -269,6 +269,27 @@ algoliasearch-helper@^2.26.0: qs "^6.5.1" util "^0.10.3" +algoliasearch@3.32.1: + version "3.32.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.32.1.tgz#605f8a2c17ab8da2af4456110f4d0a02b384e3d0" + integrity sha512-NaaHMboU9tKwrU3aim7LlzSDqKb+1TGaC+Lx3NOttSnuMHbPpaf+7LtJL4KlosbRWEwqb9t5wSYMVDrPTH2dNA== + dependencies: + agentkeepalive "^2.2.0" + debug "^2.6.9" + envify "^4.0.0" + es6-promise "^4.1.0" + events "^1.1.0" + foreach "^2.0.5" + global "^4.3.2" + inherits "^2.0.1" + isarray "^2.0.1" + load-script "^1.0.0" + object-keys "^1.0.11" + querystring-es3 "^0.2.1" + reduce "^1.0.1" + semver "^5.1.0" + tunnel-agent "^0.6.0" + algoliasearch@^3.27.1: version "3.30.0" resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.30.0.tgz#355585e49b672e5f71d45b9c2b371ecdff129cd1" @@ -2015,7 +2036,7 @@ dateformat@^2.0.0: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" integrity sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI= -debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.6.2, debug@^2.6.3, debug@^2.6.8: +debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.6.2, debug@^2.6.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== diff --git a/examples/react-router-v3/package.json b/examples/react-router-v3/package.json index d337b29dfa..979feb6922 100644 --- a/examples/react-router-v3/package.json +++ b/examples/react-router-v3/package.json @@ -13,6 +13,7 @@ "react-test-renderer": "16.8.6" }, "dependencies": { + "algoliasearch": "3.32.1", "instantsearch.css": "7.2.0", "lodash": "4.17.11", "prop-types": "15.6.0", diff --git a/examples/react-router-v3/yarn.lock b/examples/react-router-v3/yarn.lock index 67a92982cd..2c9711fbc1 100644 --- a/examples/react-router-v3/yarn.lock +++ b/examples/react-router-v3/yarn.lock @@ -1208,6 +1208,27 @@ algoliasearch-helper@^2.26.0: qs "^6.5.1" util "^0.10.3" +algoliasearch@3.32.1: + version "3.32.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.32.1.tgz#605f8a2c17ab8da2af4456110f4d0a02b384e3d0" + integrity sha512-NaaHMboU9tKwrU3aim7LlzSDqKb+1TGaC+Lx3NOttSnuMHbPpaf+7LtJL4KlosbRWEwqb9t5wSYMVDrPTH2dNA== + dependencies: + agentkeepalive "^2.2.0" + debug "^2.6.9" + envify "^4.0.0" + es6-promise "^4.1.0" + events "^1.1.0" + foreach "^2.0.5" + global "^4.3.2" + inherits "^2.0.1" + isarray "^2.0.1" + load-script "^1.0.0" + object-keys "^1.0.11" + querystring-es3 "^0.2.1" + reduce "^1.0.1" + semver "^5.1.0" + tunnel-agent "^0.6.0" + algoliasearch@^3.27.1: version "3.30.0" resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.30.0.tgz#355585e49b672e5f71d45b9c2b371ecdff129cd1" @@ -2955,7 +2976,7 @@ date-now@^0.1.4: resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= -debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8: +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== diff --git a/examples/react-router/package.json b/examples/react-router/package.json index 13fde59708..a29c5722f1 100644 --- a/examples/react-router/package.json +++ b/examples/react-router/package.json @@ -14,6 +14,7 @@ "react-test-renderer": "16.8.6" }, "dependencies": { + "algoliasearch": "3.32.1", "instantsearch.css": "7.2.0", "lodash": "4.17.11", "prop-types": "15.6.0", diff --git a/examples/react-router/yarn.lock b/examples/react-router/yarn.lock index 26bb24c1b3..4d100681da 100644 --- a/examples/react-router/yarn.lock +++ b/examples/react-router/yarn.lock @@ -1208,6 +1208,27 @@ algoliasearch-helper@^2.26.0: qs "^6.5.1" util "^0.10.3" +algoliasearch@3.32.1: + version "3.32.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.32.1.tgz#605f8a2c17ab8da2af4456110f4d0a02b384e3d0" + integrity sha512-NaaHMboU9tKwrU3aim7LlzSDqKb+1TGaC+Lx3NOttSnuMHbPpaf+7LtJL4KlosbRWEwqb9t5wSYMVDrPTH2dNA== + dependencies: + agentkeepalive "^2.2.0" + debug "^2.6.9" + envify "^4.0.0" + es6-promise "^4.1.0" + events "^1.1.0" + foreach "^2.0.5" + global "^4.3.2" + inherits "^2.0.1" + isarray "^2.0.1" + load-script "^1.0.0" + object-keys "^1.0.11" + querystring-es3 "^0.2.1" + reduce "^1.0.1" + semver "^5.1.0" + tunnel-agent "^0.6.0" + algoliasearch@^3.27.1: version "3.30.0" resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.30.0.tgz#355585e49b672e5f71d45b9c2b371ecdff129cd1" @@ -2954,7 +2975,7 @@ date-now@^0.1.4: resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= -debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8: +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== diff --git a/examples/server-side-rendering/package.json b/examples/server-side-rendering/package.json index f326e89163..fe6bfbd6a4 100644 --- a/examples/server-side-rendering/package.json +++ b/examples/server-side-rendering/package.json @@ -25,6 +25,7 @@ "webpack-node-externals": "1.7.2" }, "dependencies": { + "algoliasearch": "3.32.1", "express": "4.16.4", "prop-types": "15.6.0", "react": "16.8.6", diff --git a/examples/server-side-rendering/yarn.lock b/examples/server-side-rendering/yarn.lock index 6be3313c61..f25f2a32bb 100644 --- a/examples/server-side-rendering/yarn.lock +++ b/examples/server-side-rendering/yarn.lock @@ -272,6 +272,27 @@ algoliasearch-helper@^2.26.0: qs "^6.5.1" util "^0.10.3" +algoliasearch@3.32.1: + version "3.32.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.32.1.tgz#605f8a2c17ab8da2af4456110f4d0a02b384e3d0" + integrity sha512-NaaHMboU9tKwrU3aim7LlzSDqKb+1TGaC+Lx3NOttSnuMHbPpaf+7LtJL4KlosbRWEwqb9t5wSYMVDrPTH2dNA== + dependencies: + agentkeepalive "^2.2.0" + debug "^2.6.9" + envify "^4.0.0" + es6-promise "^4.1.0" + events "^1.1.0" + foreach "^2.0.5" + global "^4.3.2" + inherits "^2.0.1" + isarray "^2.0.1" + load-script "^1.0.0" + object-keys "^1.0.11" + querystring-es3 "^0.2.1" + reduce "^1.0.1" + semver "^5.1.0" + tunnel-agent "^0.6.0" + algoliasearch@^3.27.1: version "3.30.0" resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.30.0.tgz#355585e49b672e5f71d45b9c2b371ecdff129cd1" @@ -2037,7 +2058,7 @@ date-now@^0.1.4: resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= -debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8: +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== From 18e454952faa876dcb1940a9401b948551448030 Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 22 May 2019 14:52:25 +0200 Subject: [PATCH 20/48] chore(stories): memoize search client --- stories/InstantSearch.stories.js | 18 +++++++---------- stories/util.js | 33 ++++++-------------------------- 2 files changed, 13 insertions(+), 38 deletions(-) diff --git a/stories/InstantSearch.stories.js b/stories/InstantSearch.stories.js index a7218293b5..01df349bda 100644 --- a/stories/InstantSearch.stories.js +++ b/stories/InstantSearch.stories.js @@ -5,25 +5,21 @@ import { InstantSearch, SearchBox, Hits } from 'react-instantsearch-dom'; const stories = storiesOf('', module); +const searchClient = algoliasearch( + 'latency', + '6be0576ff61c053d5f9a3225e2a90f76' +); + stories .add('default', () => ( - + )) .add('with custom root', () => ( ( - - {children} - -); - -Wrap.propTypes = { - children: PropTypes.node.isRequired, - appId: PropTypes.string, - apiKey: PropTypes.string, - indexName: PropTypes.string, -}; - -Wrap.defaultProps = { - appId: 'latency', - apiKey: '6be0576ff61c053d5f9a3225e2a90f76', - indexName: 'instant_search', -}; - export const WrapWithHits = ({ searchParameters: askedSearchParameters = {}, children, @@ -84,6 +62,10 @@ export const WrapWithHits = ({ indexName, hitsElement, }) => { + const searchClient = useMemo(() => { + return algoliasearch(appId, apiKey); + }, [appId, apiKey]); + const sourceCodeUrl = `https://github.com/algolia/react-instantsearch/tree/master/stories/${linkedStoryGroup}.stories.js`; const playgroundLink = hasPlayground ? (