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

fix(recommend): provide insights query parameters to recommend queries #6123

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
440e9cc
chore: update algoliasearch version
dhayab Mar 28, 2024
81b4400
feat(helper): add methods to request and retrieve recommendations
dhayab Mar 28, 2024
0eac184
add tests
dhayab Mar 29, 2024
98018d8
emit placeholder change event and test events better
dhayab Mar 29, 2024
84937b3
Merge branch 'master' into feat/helper-recommend-methods
dhayab Mar 29, 2024
6f064f8
bump bundle sizes
dhayab Mar 29, 2024
9469f26
Merge branch 'master' into feat/helper-recommend-methods
dhayab Apr 2, 2024
2cc4743
retrieve recommend queries on all index widgets through derived helpers
dhayab Apr 3, 2024
2a70204
add tests for derived helper
dhayab Apr 3, 2024
2518d91
bump bundlesize
dhayab Apr 3, 2024
7ab1436
feat(recommend): add FBT to instantsearch-ui-components
raed667 Apr 3, 2024
d326cab
fix: split component files to fix type errors
raed667 Apr 4, 2024
60f8c9c
fix babel spread issue
raed667 Apr 4, 2024
ab5dd33
replace classes auc with ais
raed667 Apr 4, 2024
e8544c6
fix: address feedback
raed667 Apr 4, 2024
7ade025
fix: address feedback by adding tests and TS types
raed667 Apr 4, 2024
e041a2f
wip: map recommend results to widgets
aymeric-giraudet Apr 4, 2024
8813c64
remove comment
raed667 Apr 4, 2024
60a9ef6
Merge branch 'feat/map-recommend-results' into feat-recommend-fbt-ui-…
raed667 Apr 5, 2024
ad70293
feat(recommend): add FBT to connector
raed667 Apr 5, 2024
60f052b
fix: results
aymeric-giraudet Apr 5, 2024
c90ef99
fix: typescript
aymeric-giraudet Apr 5, 2024
418cffb
fix types
aymeric-giraudet Apr 5, 2024
5c69418
bundlesize
aymeric-giraudet Apr 5, 2024
46c2531
Merge branch 'master' into feat/map-recommend-results
aymeric-giraudet Apr 5, 2024
bd942b4
Merge branch 'feat-recommend-fbt-ui-component' into feat/recommend-fb…
raed667 Apr 5, 2024
deab535
Merge branch 'feat/map-recommend-results' into feat-recommend-fbt-ui-…
raed667 Apr 5, 2024
c65c703
wip: map recommend results to widgets
aymeric-giraudet Apr 4, 2024
859c5ba
fix: results
aymeric-giraudet Apr 5, 2024
3785724
fix: typescript
aymeric-giraudet Apr 5, 2024
ea2259d
fix types
aymeric-giraudet Apr 5, 2024
6eab8a3
bundlesize
aymeric-giraudet Apr 5, 2024
61ba925
Merge branch 'master' into feat/map-recommend-results
aymeric-giraudet Apr 5, 2024
49f9efe
fix
aymeric-giraudet Apr 5, 2024
6c1dc58
Merge branch 'feat/map-recommend-results' into feat-recommend-fbt-ui-…
raed667 Apr 5, 2024
cbe9d9a
Merge branch 'feat-recommend-fbt-ui-component' into feat/recommend-fb…
raed667 Apr 5, 2024
41ec195
fix linit issue
raed667 Apr 5, 2024
f1eb001
fix linit issue
raed667 Apr 5, 2024
2baed0e
Merge branch 'feat-recommend-fbt-ui-component' into feat/recommend-fb…
raed667 Apr 5, 2024
02de7c2
bundlesize
raed667 Apr 5, 2024
e945286
fix(recommend): provide insights query parameters to recommend queries
dhayab Apr 8, 2024
b057a43
test query with existing queryParameters
dhayab Apr 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ scripts/*/CHANGELOG.md
# private files
.env
.idea/
.vscode/

# Caches
.eslintcache
Expand Down
3 changes: 3 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ module.exports = (api) => {
// false positive (babel doesn't know types)
// this is actually only called on arrays
'String.prototype.includes',

// false positive (spread)
'Object.getOwnPropertyDescriptors',
];
if (defaultShouldInject && !exclude.includes(name)) {
throw new Error(
Expand Down
14 changes: 7 additions & 7 deletions bundlesize.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,35 @@
"files": [
{
"path": "packages/algoliasearch-helper/dist/algoliasearch.helper.js",
"maxSize": "40.25 kB"
"maxSize": "40.5 kB"
},
{
"path": "packages/algoliasearch-helper/dist/algoliasearch.helper.min.js",
"maxSize": "12.75 kB"
"maxSize": "13 kB"
},
{
"path": "./packages/instantsearch.js/dist/instantsearch.production.min.js",
"maxSize": "77.5 kB"
"maxSize": "77.75 kB"
},
{
"path": "./packages/instantsearch.js/dist/instantsearch.development.js",
"maxSize": "170.75 kB"
"maxSize": "171.2 kB"
},
{
"path": "packages/react-instantsearch-core/dist/umd/ReactInstantSearchCore.min.js",
"maxSize": "47.25 kB"
"maxSize": "47.5 kB"
},
{
"path": "packages/react-instantsearch/dist/umd/ReactInstantSearch.min.js",
"maxSize": "59.25 kB"
},
{
"path": "packages/vue-instantsearch/vue2/umd/index.js",
"maxSize": "66.25 kB"
"maxSize": "67 kB"
},
{
"path": "packages/vue-instantsearch/vue3/umd/index.js",
"maxSize": "66.75 kB"
"maxSize": "67 kB"
},
{
"path": "packages/vue-instantsearch/vue2/cjs/index.js",
Expand Down
23 changes: 11 additions & 12 deletions examples/js/getting-started/src/app.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import algoliasearch from 'algoliasearch/lite';
import instantsearch from 'instantsearch.js';
import { connectFrequentlyBoughtTogether } from 'instantsearch.js/es/connectors';
import {
configure,
hits,
// hits,
pagination,
panel,
refinementList,
Expand All @@ -20,21 +21,19 @@ const search = instantsearch({
insights: true,
});

const mySuperWidget = connectFrequentlyBoughtTogether(
({ items, widgetParams }) => {
// eslint-disable-next-line no-console
console.log('FrequentlyBoughtTogether', { items, widgetParams });
}
);

search.addWidgets([
searchBox({
container: '#searchbox',
}),
hits({
container: '#hits',
templates: {
item: (hit, { html, components }) => html`
<article>
<h1>${components.Highlight({ hit, attribute: 'name' })}</h1>
<p>${components.Highlight({ hit, attribute: 'description' })}</p>
</article>
`,
},
}),
mySuperWidget({ container: '#hits', objectID: '5723538' }),

configure({
hitsPerPage: 8,
}),
Expand Down
23 changes: 19 additions & 4 deletions packages/algoliasearch-helper/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
RelatedProductsQuery as RecommendRelatedProductsQuery,
TrendingFacetsQuery as RecommendTrendingFacetsQuery,
TrendingItemsQuery as RecommendTrendingItemsQuery,
RecommendQueriesResponse,
} from '@algolia/recommend';

/**
Expand All @@ -42,7 +43,7 @@ declare namespace algoliasearchHelper {
state: SearchParameters;
recommendState: RecommendParameters;
lastResults: SearchResults | null;
lastRecommendResults: unknown | null; // TODO: Define type in dedicated PR
lastRecommendResults: RecommendResults | null;
derivedHelpers: DerivedHelper[];

on(
Expand Down Expand Up @@ -402,15 +403,15 @@ declare namespace algoliasearchHelper {
event: 'recommend:result',
cb: (res: {
recommend: {
results: unknown | null; // TODO: Define type in dedicated PR
results: RecommendResults | null;
state: RecommendParameters;
};
}) => void
): this;
on(event: 'error', cb: (res: { error: Error }) => void): this;

lastResults: SearchResults | null;
lastRecommendResults: unknown | null; // TODO: Define type in dedicated PR
lastRecommendResults: RecommendResults | null;
detach(): void;
getModifiedState(): SearchParameters;
getModifiedRecommendState(): RecommendParameters;
Expand Down Expand Up @@ -1525,7 +1526,7 @@ declare namespace algoliasearchHelper {
export type RecommendParametersWithId<
T extends PlainRecommendParameters = PlainRecommendParameters
> = T & {
$$id: string;
$$id: number;
};

export type RecommendParametersOptions = {
Expand Down Expand Up @@ -1553,6 +1554,20 @@ declare namespace algoliasearchHelper {
params: RecommendParametersWithId<LookingSimilarQuery>
): RecommendParameters;
}

type RecommendResponse<TObject> =
RecommendQueriesResponse<TObject>['results'];

type RecommendResultItem<TObject = any> = RecommendResponse<TObject>[0];

export class RecommendResults<T = any> {
constructor(state: RecommendParameters, results: RecommendResponse<T>);

_state: RecommendParameters;
_rawResults: RecommendResponse<T>;

[index: number]: RecommendResultItem<T>;
}
}

export = algoliasearchHelper;
28 changes: 28 additions & 0 deletions packages/algoliasearch-helper/src/RecommendResults/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

/**
* Constructor for SearchResults
* @class
* @classdesc SearchResults contains the results of a query to Algolia using the
* {@link AlgoliaSearchHelper}.
* @param {RecommendParameters} state state that led to the response
* @param {Record<string,RecommendResultItem>} results the results from algolia client
**/
function RecommendResults(state, results) {
this._state = state;
this._rawResults = results;

// eslint-disable-next-line consistent-this
var self = this;

state.params.forEach(function (param) {
var id = param.$$id;
self[id] = results[id];
});
}

RecommendResults.prototype = {
constructor: RecommendResults,
};

module.exports = RecommendResults;
43 changes: 36 additions & 7 deletions packages/algoliasearch-helper/src/algoliasearch.helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var merge = require('./functions/merge');
var objectHasKeys = require('./functions/objectHasKeys');
var omit = require('./functions/omit');
var RecommendParameters = require('./RecommendParameters');
var RecommendResults = require('./RecommendResults');
var requestBuilder = require('./requestBuilder');
var SearchParameters = require('./SearchParameters');
var SearchResults = require('./SearchResults');
Expand Down Expand Up @@ -1577,6 +1578,9 @@ AlgoliaSearchHelper.prototype._recommend = function () {
var recommendState = this.recommendState;
var index = this.getIndex();
var states = [{ state: recommendState, index: index, helper: this }];
var ids = recommendState.params.map(function (param) {
return param.$$id;
});

this.emit('fetch', {
recommend: {
Expand All @@ -1603,6 +1607,20 @@ AlgoliaSearchHelper.prototype._recommend = function () {
helper: derivedHelper,
});

ids = Array.prototype.concat.apply(
ids,
derivedState.params.map(function (param) {
return param.$$id;
})
);

ids = Array.prototype.concat.apply(
ids,
derivedState.params.map(function (param) {
return param.$$id;
})
);

derivedHelper.emit('fetch', {
recommend: {
state: derivedState,
Expand All @@ -1613,10 +1631,16 @@ AlgoliaSearchHelper.prototype._recommend = function () {
return derivedState._buildQueries(derivedIndex);
});

var queries = Array.prototype.concat.apply(
this.recommendState._buildQueries(index),
derivedQueries
);
var queries = Array.prototype.concat
.apply(this.recommendState._buildQueries(index), derivedQueries)
.map(function (query) {
return Object.assign(query, {
queryParameters: Object.assign(query.queryParameters || {}, {
clickAnalytics: searchState.clickAnalytics,
userToken: searchState.userToken,
Comment on lines +1638 to +1640
Copy link
Contributor

Choose a reason for hiding this comment

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

Q: If the client passes queryParameters to the recommend widget, do they "lose" automatic event collection ?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is augmented thanks to Object.assign(), but it's a good idea to have a specific test for that, I'll add it to the PR.

}),
});
});

if (queries.length === 0) {
return;
Expand All @@ -1639,7 +1663,7 @@ AlgoliaSearchHelper.prototype._recommend = function () {
try {
this.client
.getRecommendations(queries)
.then(this._dispatchRecommendResponse.bind(this, queryId, states))
.then(this._dispatchRecommendResponse.bind(this, queryId, states, ids))
.catch(this._dispatchRecommendError.bind(this, queryId));
} catch (error) {
// If we reach this part, we're in an internal error state
Expand Down Expand Up @@ -1713,6 +1737,7 @@ AlgoliaSearchHelper.prototype._dispatchAlgoliaResponse = function (
AlgoliaSearchHelper.prototype._dispatchRecommendResponse = function (
queryId,
states,
ids,
content
) {
// @TODO remove the number of outdated queries discarded instead of just one
Expand All @@ -1728,7 +1753,11 @@ AlgoliaSearchHelper.prototype._dispatchRecommendResponse = function (

if (this._currentNbRecommendQueries === 0) this.emit('recommendQueueEmpty');

var results = content.results.slice();
var results = {};
content.results.forEach(function (result, index) {
var id = ids[index];
results[id] = result;
});

states.forEach(function (s) {
var state = s.state;
Expand All @@ -1744,7 +1773,7 @@ AlgoliaSearchHelper.prototype._dispatchRecommendResponse = function (
return;
}

helper.lastRecommendResults = results;
helper.lastRecommendResults = new RecommendResults(state, results);

// eslint-disable-next-line no-warning-comments
// TODO: emit "result" event when events for Recommend are implemented
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,12 @@ function getData() {
var recommendParams = new RecommendParameters({
params: [
{
$$id: '1',
$$id: 1,
objectID: 'A0E20000000279B',
model: 'bought-together',
},
{
$$id: '2',
$$id: 2,
facetName: 'brand',
model: 'trending-facets',
},
Expand Down