Skip to content
This repository has been archived by the owner on Dec 30, 2022. It is now read-only.

feat(context): migrate core [STEP 1] #2178

Merged
merged 28 commits into from
Apr 15, 2019
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7610079
feat(context): migrate core [STEP 1]
Haroenv Mar 18, 2019
ce9d955
chore: remove context cache
Haroenv Mar 18, 2019
9c33619
chore(tslint): add back accidentally removed prettier
Haroenv Mar 18, 2019
57d7406
fix(connector): call gPP with correct "this"
Haroenv Mar 18, 2019
30df9f3
chore(TS): ReactType for Root
Haroenv Mar 18, 2019
b63fff3
test(connector): swap mount for shallow where possible
Haroenv Mar 25, 2019
9389fab
chore(InstantSearch): refactor branch
Haroenv Mar 25, 2019
cf8e92c
test(InstantSearch): avoid mutation
Haroenv Mar 25, 2019
b4d7808
chore(connector): remove unused
Haroenv Mar 25, 2019
b5bfbed
chore(createConnector): warn on creation instead of mount
Haroenv Mar 25, 2019
eac69e0
fix(connector): remove unused variable
Haroenv Mar 25, 2019
b81001d
chore(connector): consistent if
Haroenv Mar 25, 2019
4deb399
chore(store): simplify typing
Haroenv Mar 25, 2019
0377ef4
chore(stories): better display name
Haroenv Mar 25, 2019
632e6ea
chore(TS): fix typing of results
Haroenv Mar 26, 2019
9ae17c2
chore: remove useless comments
Haroenv Mar 26, 2019
eed09d2
consistent naming
Haroenv Mar 26, 2019
f88284c
fix(InstantSearch): update index name when it changes
Haroenv Mar 26, 2019
72f5750
prettier
Haroenv Mar 26, 2019
c141197
chore: remove old comment
Haroenv Apr 8, 2019
24dd2f5
chore: fix merge
Haroenv Apr 9, 2019
a7b317e
ci: remove no-empty rule
Haroenv Apr 9, 2019
50bc90c
fix: make TS work in new connectors
Haroenv Apr 9, 2019
db9e3ca
chore: fix bundlesize
Haroenv Apr 9, 2019
6445075
feedback from review (remove comments & warning)
Haroenv Apr 12, 2019
daa6016
more review comments
Haroenv Apr 12, 2019
04e70fa
Update packages/react-instantsearch-core/src/components/InstantSearch…
samouss Apr 13, 2019
508c033
feat(context): migrate base connector [STEP 2] (#2179)
Haroenv Apr 15, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,15 @@
},
{
"path": "packages/react-instantsearch/dist/umd/Connectors.min.js",
"maxSize": "40.50 kB"
"maxSize": "40.75 kB"
},
{
"path": "packages/react-instantsearch/dist/umd/Dom.min.js",
"maxSize": "63.75 kB"
},
{
"path": "packages/react-instantsearch-core/dist/umd/ReactInstantSearchCore.min.js",
"maxSize": "41.50 kB"
"maxSize": "41.75 kB"
},
{
"path": "packages/react-instantsearch-dom/dist/umd/ReactInstantSearchDOM.min.js",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { Component, Children } from 'react';
import React, { Component, Children, ReactType } from 'react';
import PropTypes from 'prop-types';
import createInstantSearchManager from '../core/createInstantSearchManager';
import { InstantSearchProvider, InstantSearchContext } from '../core/context';
import { Store } from '../core/createStore';

function validateNextProps(props, nextProps) {
if (!props.searchState && nextProps.searchState) {
Expand All @@ -14,6 +16,62 @@ function validateNextProps(props, nextProps) {
}
}

// @TODO: move this to the helper?
type SearchParameters = any; // algoliaHelper.SearchParameters
type SearchResults = any; // algoliaHelper.SearchResults

// @TODO: move to createInstantSearchManager when it's TS
type InstantSearchManager = {
store: Store;
widgetsManager: any;
getWidgetsIds: any;
getSearchParameters: (
...args: any[]
) => {
mainParameters: SearchParameters;
derivedParameters: SearchParameters;
};
onSearchForFacetValues: (...args: any[]) => any;
onExternalStateUpdate: (...args: any[]) => any;
transitionState: any;
updateClient: any;
updateIndex: any;
clearCache: () => void;
skipSearch: any;
};

type SearchClient = {
search: (requests: Array<{}>) => Promise<{}>;
searchForFacetValues: (requests: Array<{}>) => Promise<{}>;
};

type SearchState = any;
Haroenv marked this conversation as resolved.
Show resolved Hide resolved

type Props = {
refresh: boolean;
indexName: string;
searchClient: SearchClient;
createURL?: (searchState: SearchState, knownKeys: any) => string;
onSearchStateChange?: (searchState: SearchState) => void;
searchState?: SearchState;
onSearchParameters?: (
getSearchParameters: (...args: any) => any,
context: any,
props: any,
searchState: SearchState
) => void;
stalledSearchDelay?: number;
root: {
Root: ReactType;
props: {};
};
resultsState: SearchResults | { [indexId: string]: SearchResults };
};

type State = {
contextValue: InstantSearchContext;
};

/**
* @description
* `<InstantSearch>` is the root component of all React InstantSearch implementations.
Expand Down Expand Up @@ -50,8 +108,46 @@ function validateNextProps(props, nextProps) {
* </InstantSearch>
* );
*/
class InstantSearch extends Component {
constructor(props) {
class InstantSearch extends Component<Props, State> {
static defaultProps = {
stalledSearchDelay: 200,
};

static propTypes = {
// @TODO: These props are currently constant.
indexName: PropTypes.string.isRequired,

searchClient: PropTypes.object.isRequired,

createURL: PropTypes.func,

refresh: PropTypes.bool.isRequired,
Haroenv marked this conversation as resolved.
Show resolved Hide resolved

searchState: PropTypes.object,
onSearchStateChange: PropTypes.func,

onSearchParameters: PropTypes.func,
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,
};

isControlled: boolean;
isUnmounting: boolean;
aisManager: InstantSearchManager;

constructor(props: Props) {
super(props);
this.isControlled = Boolean(props.searchState);
Haroenv marked this conversation as resolved.
Show resolved Hide resolved
const initialState = this.isControlled ? props.searchState : {};
Expand All @@ -64,13 +160,32 @@ class InstantSearch extends Component {
resultsState: props.resultsState,
stalledSearchDelay: props.stalledSearchDelay,
});

this.state = {
Haroenv marked this conversation as resolved.
Show resolved Hide resolved
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,
},
};
}

componentWillReceiveProps(nextProps) {
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) {
Expand All @@ -93,39 +208,14 @@ class InstantSearch extends Component {
this.aisManager.skipSearch();
}

getChildContext() {
// If not already cached, cache the bound methods so that we can forward them as part
// of the context.
if (!this._aisContextCache) {
this._aisContextCache = {
ais: {
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),
},
};
}

return {
ais: {
...this._aisContextCache.ais,
store: this.aisManager.store,
widgetsManager: this.aisManager.widgetsManager,
mainTargetedIndex: this.props.indexName,
},
};
}

createHrefForState(searchState) {
createHrefForState(searchState: SearchState) {
searchState = this.aisManager.transitionState(searchState);
return this.isControlled && this.props.createURL
? this.props.createURL(searchState, this.getKnownKeys())
: '#';
}

onWidgetsInternalStateUpdate(searchState) {
onWidgetsInternalStateUpdate(searchState: SearchState) {
searchState = this.aisManager.transitionState(searchState);

this.onSearchStateChange(searchState);
Expand Down Expand Up @@ -164,48 +254,17 @@ class InstantSearch extends Component {
render() {
const childrenCount = Children.count(this.props.children);
const { Root, props } = this.props.root;
if (childrenCount === 0) return null;
else return <Root {...props}>{this.props.children}</Root>;
if (childrenCount === 0) {
return null;
}
return (
<Root {...props}>
<InstantSearchProvider value={this.state.contextValue}>
{this.props.children}
</InstantSearchProvider>
</Root>
);
}
}

InstantSearch.defaultProps = {
stalledSearchDelay: 200,
};

InstantSearch.propTypes = {
// @TODO: These props are currently constant.
indexName: PropTypes.string.isRequired,

searchClient: PropTypes.object.isRequired,

createURL: PropTypes.func,

refresh: PropTypes.bool.isRequired,

searchState: PropTypes.object,
onSearchStateChange: PropTypes.func,

onSearchParameters: PropTypes.func,
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,
};

InstantSearch.childContextTypes = {
// @TODO: more precise widgets manager propType
ais: PropTypes.object.isRequired,
};

export default InstantSearch;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Index from '../Index';

Enzyme.configure({ adapter: new Adapter() });

describe('Index', () => {
describe.skip('Index', () => {
const createContext = () => ({
ais: {
onSearchParameters: jest.fn(),
Expand Down
Loading