Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add recent-searches plugin #316

Merged
merged 34 commits into from
Sep 24, 2020
Merged

feat: add recent-searches plugin #316

merged 34 commits into from
Sep 24, 2020

Conversation

eunjae-lee
Copy link
Contributor

@eunjae-lee eunjae-lee commented Sep 4, 2020

Summary

Here is the PoC of plugin API and the recent searches plugin on top of it.

This example is based on François' recent implementation.

Example →

import createRecentSearches from "@algolia/autocomplete-plugin-recent-searches";
const recentSearches = createRecentSearches({ limit: 5 });

autocomplete({
  // ...
  plugins: [recentSearches],
  // ...
  // ...
           facetFilters: [...recentSearches.getFacetFilters()]

These are all it takes to use the recent searches plugin.

Discussions

Batching API calls

From the perspective of autocomplete-core, it's impossible to know where a plugin is going to get sources from. If the core knows that a plugin is going to call getAlgoliaResults, then it can aggregate everything and fire a single request with multiple queries. We could change the implementation of getAlgoliaResults to request to a BatchProcessor (temp name), and when it's done, receives the result and return it. Anyway it looks like it's out of the scope of designing the plugin API.

Customizable templates

With the current API, plugins can have getSources function which returns an array of sources. I haven't found any good way to force plugins to provide a specific API to customize templates. It's going to be up to each plugin to accept a certain option as they want.

@codesandbox-ci
Copy link

codesandbox-ci bot commented Sep 4, 2020

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 1444f02:

Sandbox Source
algolia/autocomplete.js: js Configuration
algolia/autocomplete.js: js (forked) PR

@eunjae-lee eunjae-lee marked this pull request as ready for review September 10, 2020 08:13
Copy link
Member

@francoischalifour francoischalifour left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

packages/autocomplete-plugin-recent-searches/README.md Outdated Show resolved Hide resolved
packages/autocomplete-plugin-recent-searches/README.md Outdated Show resolved Hide resolved
packages/autocomplete-plugin-recent-searches/README.md Outdated Show resolved Hide resolved
packages/autocomplete-plugin-recent-searches/README.md Outdated Show resolved Hide resolved
packages/autocomplete-plugin-recent-searches/package.json Outdated Show resolved Hide resolved
packages/autocomplete-plugin-recent-searches/src/index.ts Outdated Show resolved Hide resolved
Eunjae Lee and others added 2 commits September 11, 2020 15:49
…earchesPlugin.ts

Co-authored-by: François Chalifour <francoischalifour@users.noreply.github.com>
/**
* The array of plugins.
*/
plugins?: Array<AutocompletePlugin<TItem, unknown>>;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This must be unknown, right? We cannot know what it's going to be at this point. What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep!

packages/autocomplete-core/src/getDefaultProps.ts Outdated Show resolved Hide resolved
.then((sources) =>
sources.map((source) => ({
...source,
onSelect: (payload) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use the term params here too.

)
.then((nested) =>
// same as `nested.flat()`
nested.reduce((acc, array) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to flatten sources here? (Does it reveal a data structure problem prior to this instruction?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No big deal, just to make the next iteration easier.

Eunjae Lee and others added 4 commits September 18, 2020 10:53
},
onSelect: ({ suggestion }) => {
store.add(suggestion);
const { query, objectID } = suggestion as any;
if (query && objectID) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work with non-Algolia records so we should rather store the record and fallback objectID to query.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@francoischalifour Okay, that part makes sense.

However I'm gonna have to leave if (query) condition.
For example,
image
these products (not coming from suggestion index) don't have query attribute.
In this case, is it correct that we're not storing them? Not sure how we've decided, but if it's correct, we need to keep if (query) clause. cc @Shipow

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this deserves a sync on Monday?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/algolia/autocomplete.js/blob/feat/recent-searches/packages/autocomplete-core/src/getPropGetters.ts#L323-L336

If the source has getSuggestionUrl, it doesn't reach to source.onSelect, so it naturally doesn't get to be saved in recent searches.

@eunjae-lee
Copy link
Contributor Author

While implementing this, I've realized that, for example,

  • there are 3 sources
  • there is 1 plugin (which returns 1 source)

-> then total 4 sources

Whatever source triggers onSelect, the core is going to call all the onSelect from 4 sources.
I feel like this can open a door to unexpected issues. But we can leave it as is and add more plugins and figure out later?
What do you think?

@eunjae-lee
Copy link
Contributor Author

@francoischalifour what do you think? a1e5d98

}
},
onSelect: ({ suggestion, state, source }) => {
const inputValue = source.getInputValue({ suggestion, state });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only going to work in the query-completion use case but let's scope it down to this and move forward 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're saying it won't work in case of "redirecting to a product page", right?

If so, yes. We're not thinking of the case in this PR: #316 (comment)

@eunjae-lee eunjae-lee merged commit 858637e into next Sep 24, 2020
@eunjae-lee eunjae-lee deleted the feat/recent-searches branch September 24, 2020 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants