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(plugins): introduce Query Suggestions plugin #360

Merged
merged 2 commits into from
Nov 9, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
9 changes: 6 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@ aliases:
mkdir -p packages/autocomplete-shared/dist
mkdir -p packages/autocomplete-core/dist
mkdir -p packages/autocomplete-js/dist
mkdir -p packages/autocomplete-plugin-recent-searches/dist
mkdir -p packages/autocomplete-preset-algolia/dist
mkdir -p packages/autocomplete-plugin-recent-searches/dist
mkdir -p packages/autocomplete-plugin-query-suggestions/dist

cp -R /tmp/workspace/packages/autocomplete-shared/dist packages/autocomplete-shared
cp -R /tmp/workspace/packages/autocomplete-core/dist packages/autocomplete-core
cp -R /tmp/workspace/packages/autocomplete-js/dist packages/autocomplete-js
cp -R /tmp/workspace/packages/autocomplete-plugin-recent-searches/dist packages/autocomplete-plugin-recent-searches
cp -R /tmp/workspace/packages/autocomplete-preset-algolia/dist packages/autocomplete-preset-algolia
cp -R /tmp/workspace/packages/autocomplete-plugin-recent-searches/dist packages/autocomplete-plugin-recent-searches
cp -R /tmp/workspace/packages/autocomplete-plugin-query-suggestions/dist packages/autocomplete-plugin-query-suggestions

defaults: &defaults
working_directory: ~/autocomplete
Expand Down Expand Up @@ -72,8 +74,9 @@ jobs:
cp -R packages/autocomplete-shared/dist /tmp/workspace/packages/autocomplete-shared
cp -R packages/autocomplete-core/dist /tmp/workspace/packages/autocomplete-core
cp -R packages/autocomplete-js/dist /tmp/workspace/packages/autocomplete-js
cp -R packages/autocomplete-plugin-recent-searches/dist /tmp/workspace/packages/autocomplete-plugin-recent-searches
cp -R packages/autocomplete-preset-algolia/dist /tmp/workspace/packages/autocomplete-preset-algolia
cp -R packages/autocomplete-plugin-recent-searches/dist /tmp/workspace/packages/autocomplete-plugin-recent-searches
cp -R packages/autocomplete-plugin-query-suggestions/dist /tmp/workspace/packages/autocomplete-plugin-query-suggestions
- persist_to_workspace:
root: *workspace_root
paths:
Expand Down
4 changes: 4 additions & 0 deletions bundlesize.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
},
{
"path": "packages/autocomplete-plugin-recent-searches/dist/umd/index.js",
"maxSize": "2.5 kB"
},
{
"path": "packages/autocomplete-plugin-query-suggestions/dist/umd/index.js",
"maxSize": "2.25 kB"
}
]
Expand Down
83 changes: 12 additions & 71 deletions examples/js/app.ts
Original file line number Diff line number Diff line change
@@ -1,87 +1,28 @@
import { Hit } from '@algolia/client-search';
import algoliasearch from 'algoliasearch/lite';
import {
autocomplete,
AutocompleteSource,
getAlgoliaHits,
reverseHighlightHit,
} from '@algolia/autocomplete-js';
import { autocomplete } from '@algolia/autocomplete-js';
import { createLocalStorageRecentSearchesPlugin } from '@algolia/autocomplete-plugin-recent-searches';
import { createQuerySuggestionsPlugin } from '@algolia/autocomplete-plugin-query-suggestions';

const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);

type QuerySuggestionHit = { query: string };

const recentSearches = createLocalStorageRecentSearchesPlugin({
key: 'recent',
limit: 3,
});

autocomplete<Hit<QuerySuggestionHit>>({
container: '#autocomplete',
debug: true,
openOnFocus: true,
// dropdownPlacement: 'start',
plugins: [recentSearches],
getSources({ query }) {
return getAlgoliaHits<QuerySuggestionHit>({
searchClient,
queries: [
{
indexName: 'instant_search_demo_query_suggestions',
query,
params: {
hitsPerPage: recentSearches.data.getAlgoliaQuerySuggestionsHitsPerPage(
10
),
facetFilters: [
...recentSearches.data.getAlgoliaQuerySuggestionsFacetFilters(),
],
},
},
],
}).then(([hits]) => {
return [
{
getItemInputValue({ item }) {
return item.query;
},
getItems() {
return hits;
},
templates: {
item({ item }) {
return `
<div class="aa-ItemContent">
<div class="aa-ItemSourceIcon">${searchIcon}</div>
<div class="aa-ItemTitle">
${reverseHighlightHit<Hit<QuerySuggestionHit>>({
hit: item,
attribute: 'query',
})}
</div>
</div>
`;
},
},
} as AutocompleteSource<Hit<QuerySuggestionHit>>,
];
});
const querySuggestions = createQuerySuggestionsPlugin({
searchClient,
indexName: 'instant_search_demo_query_suggestions',
getSearchParams() {
return recentSearches.data.getAlgoliaSearchParams();
},
});

const searchIcon = `
<svg width="20" height="20" viewBox="0 0 20 20">
<path
d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"
stroke="currentColor"
fill="none"
fillRule="evenodd"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
`;
autocomplete({
container: '#autocomplete',
openOnFocus: true,
plugins: [recentSearches, querySuggestions],
Copy link
Contributor

Choose a reason for hiding this comment

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

the main example should probably still show results as well as query suggestions, to show more of the full api, wdyt?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah eventually we'll have examples in other places, that's used for dev only for now—so not too much of a deal!

});
2 changes: 1 addition & 1 deletion examples/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"dependencies": {
"@algolia/autocomplete-js": "1.0.0-alpha.34",
"@algolia/autocomplete-plugin-recent-searches": "1.0.0-alpha.34",
"@algolia/client-search": "4.5.1",
"@algolia/autocomplete-plugin-query-suggestions": "1.0.0-alpha.34",
"algoliasearch": "4.5.1"
},
"devDependencies": {
Expand Down
10 changes: 3 additions & 7 deletions packages/autocomplete-core/src/getDefaultProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,10 @@ export function getDefaultProps<TItem>(
});
},
getSources(options) {
const getSourcesFromPlugins = plugins
.map((plugin) => plugin.getSources)
.filter((getSources) => getSources !== undefined);

return Promise.all(
[...getSourcesFromPlugins, props.getSources].map((getSources) =>
getNormalizedSources(getSources!, options)
)
[...plugins.map((plugin) => plugin.getSources), props.getSources]
.filter(Boolean)
.map((getSources) => getNormalizedSources(getSources!, options))
)
.then((nested) => flatten(nested))
.then((sources) =>
Expand Down
2 changes: 1 addition & 1 deletion packages/autocomplete-core/src/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ export interface AutocompleteOptions<TItem> {
/**
* The sources to get the suggestions from.
*/
getSources(
getSources?(
params: GetSourcesParams<TItem>
): MaybePromise<Array<AutocompleteSource<TItem>>>;
/**
Expand Down
4 changes: 2 additions & 2 deletions packages/autocomplete-core/src/types/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ export type AutocompletePlugin<TItem, TData = unknown> = Partial<
* The subscribed properties are properties that are called when other sources
* are interacted with.
*/
subscribed: {
subscribed?: {
onSelect: AutocompleteSource<TItem>['onSelect'];
};
/**
* An extra plugin specific object to store variables and functions
*/
data: TData;
data?: TData;
};
16 changes: 10 additions & 6 deletions packages/autocomplete-core/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { MaybePromise } from '@algolia/autocomplete-shared';

import {
InternalAutocompleteOptions,
InternalAutocompleteSource,
AutocompleteState,
AutocompleteCollection,
AutocompleteOptions,
AutocompleteSource,
AutocompleteState,
GetSourcesParams,
InternalAutocompleteOptions,
InternalAutocompleteSource,
} from './types';

export const noop = () => {};
Expand Down Expand Up @@ -45,8 +47,10 @@ function normalizeSource<TItem>(
}

export function getNormalizedSources<TItem>(
getSources: AutocompleteOptions<TItem>['getSources'],
options
getSources: (
params: GetSourcesParams<TItem>
) => MaybePromise<Array<AutocompleteSource<TItem>>>,
options: GetSourcesParams<TItem>
): Promise<Array<InternalAutocompleteSource<TItem>>> {
return Promise.resolve(getSources(options)).then((sources) =>
Promise.all(
Expand Down
11 changes: 11 additions & 0 deletions packages/autocomplete-plugin-query-suggestions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# @algolia/autocomplete-plugin-query-suggestions

A plugin to add Query Suggestions to Algolia Autocomplete.

Copy link
Contributor

Choose a reason for hiding this comment

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

add some info here to link to the query suggestions feature?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep, we'll work on an exhaustive doc with Maria so we'll wait for this content before changing this doc multiple times if you don't mind.

## Installation

```sh
yarn add @algolia/autocomplete-plugin-query-suggestions@alpha
# or
npm install @algolia/autocomplete-plugin-query-suggestions@alpha
```
francoischalifour marked this conversation as resolved.
Show resolved Hide resolved
45 changes: 45 additions & 0 deletions packages/autocomplete-plugin-query-suggestions/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "@algolia/autocomplete-plugin-query-suggestions",
"description": "A plugin to add query suggestions to Algolia Autocomplete.",
"version": "1.0.0-alpha.34",
"license": "MIT",
"homepage": "https://github.com/algolia/autocomplete.js",
"repository": "algolia/autocomplete.js",
"author": {
"name": "Algolia, Inc.",
"url": "https://www.algolia.com"
},
"source": "src/index.ts",
"types": "dist/esm/index.d.ts",
"module": "dist/esm/index.js",
"main": "dist/umd/index.js",
"umd:main": "dist/umd/index.js",
"unpkg": "dist/umd/index.js",
"jsdelivr": "dist/umd/index.js",
"sideEffects": false,
"files": [
"dist/"
],
"scripts": {
"build:clean": "rm -rf ./dist",
"build:esm": "babel src --root-mode upward --extensions '.ts,.tsx' --out-dir dist/esm --ignore '**/*/__tests__/'",
"build:types": "tsc -p ./tsconfig.declaration.json --outDir ./dist/esm",
"build:umd": "rollup --config",
"build": "rm -rf ./dist && yarn build:umd && yarn build:esm && yarn build:types",
"on:change": "concurrently \"yarn build:esm\" \"yarn build:types\"",
"prepare": "yarn run build:esm",
"watch": "watch \"yarn on:change\" --ignoreDirectoryPattern \"/dist/\""
},
"dependencies": {
"@algolia/autocomplete-core": "1.0.0-alpha.34",
"@algolia/autocomplete-js": "1.0.0-alpha.34"
},
"devDependencies": {
"@algolia/client-search": "4.5.1",
"algoliasearch": "4.5.1"
},
"peerDependencies": {
"@algolia/client-search": "^4.5.1",
"algoliasearch": "^4.5.1"
}
}
16 changes: 16 additions & 0 deletions packages/autocomplete-plugin-query-suggestions/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { plugins } from '../../rollup.base.config';
import { getBundleBanner } from '../../scripts/getBundleBanner';

import pkg from './package.json';

export default {
input: 'src/index.ts',
output: {
file: 'dist/umd/index.js',
format: 'umd',
sourcemap: true,
name: pkg.name,
banner: getBundleBanner(pkg),
},
plugins,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { AutocompletePlugin } from '@algolia/autocomplete-core';
import { getAlgoliaHits, SourceTemplates } from '@algolia/autocomplete-js';
import { SearchOptions } from '@algolia/client-search';
import { SearchClient } from 'algoliasearch/lite';

import {
getTemplates as defaultGetTemplates,
GetTemplatesParams,
} from './getTemplates';
import { QuerySuggestionsHit } from './types';

export type CreateQuerySuggestionsPluginParams<
TItem extends QuerySuggestionsHit
> = {
searchClient: SearchClient;
indexName: string;
getSearchParams?(): SearchOptions;
getTemplates?(
params: GetTemplatesParams<TItem>
): SourceTemplates<TItem>['templates'];
};

export function createQuerySuggestionsPlugin<
TItem extends QuerySuggestionsHit
>({
searchClient,
indexName,
getSearchParams = () => ({}),
getTemplates = defaultGetTemplates,
}: CreateQuerySuggestionsPluginParams<TItem>): AutocompletePlugin<
TItem,
undefined
> {
return {
getSources({ query, setQuery, refresh }) {
return [
{
getItemInputValue({ item }) {
return item.query;
},
getItems() {
return getAlgoliaHits<TItem>({
searchClient,
queries: [
{
indexName,
query,
params: getSearchParams(),
},
],
});
},
templates: getTemplates({
onTapAhead(item) {
setQuery(item.query);
refresh();
},
}),
},
];
},
};
}
Loading