Skip to content

Commit

Permalink
feat(recommend): introduce Recommend API client (#1280)
Browse files Browse the repository at this point in the history
feat(recommend): introduce Recommend API client

feat(personalization): deprecate client-recommendation (#1278)
  • Loading branch information
francoischalifour committed Jun 23, 2021
1 parent 831a3de commit 97ebde6
Show file tree
Hide file tree
Showing 57 changed files with 1,426 additions and 100 deletions.
4 changes: 3 additions & 1 deletion .eslintrc.js
Expand Up @@ -61,10 +61,12 @@ module.exports = {
['@algolia/client-account', './packages/client-account/src'],
['@algolia/client-analytics', './packages/client-analytics/src'],
['@algolia/client-common', './packages/client-common/src'],
['@algolia/client-search', './packages/client-search/src'],
['@algolia/client-personalization', './packages/client-personalization/src'],
['@algolia/client-recommendation', './packages/client-recommendation/src'],
['@algolia/client-search', './packages/client-search/src'],
['@algolia/logger-common', './packages/logger-common/src'],
['@algolia/logger-console', './packages/logger-console/src'],
['@algolia/recommend', './packages/recommend/src'],
['@algolia/requester-browser-xhr', './packages/requester-browser-xhr/src'],
['@algolia/requester-common', './packages/requester-common/src'],
['@algolia/requester-node-http', './packages/requester-node-http/src'],
Expand Down
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -9,7 +9,7 @@
<a href="https://npmjs.org/package/algoliasearch"><img src="https://img.shields.io/npm/v/algoliasearch.svg?style=flat-square" alt="NPM version"></img></a>
<a href="http://npm-stat.com/charts.html?package=algoliasearch"><img src="https://img.shields.io/npm/dm/algoliasearch.svg?style=flat-square" alt="NPM downloads"></a>
<a href="https://www.jsdelivr.com/package/npm/algoliasearch"><img src="https://data.jsdelivr.com/v1/package/npm/algoliasearch/badge" alt="jsDelivr Downloads"></img></a>
<a href="LICENSE.txt"><img src="https://img.shields.io/badge/license-MIT-green.svg?style=flat-square" alt="License"></a>
<a href="LICENSE.md"><img src="https://img.shields.io/badge/license-MIT-green.svg?style=flat-square" alt="License"></a>
</p>
</p>

Expand Down Expand Up @@ -88,4 +88,4 @@ Encountering an issue? Before reaching out to support, we recommend heading to o

## 📄 License

Algolia JavaScript API Client is an open-sourced software licensed under the [MIT license](LICENSE.txt).
Algolia JavaScript API Client is an open-sourced software licensed under the [MIT license](LICENSE.md).
8 changes: 6 additions & 2 deletions package.json
@@ -1,7 +1,7 @@
{
"version": "4.9.3",
"private": true,
"license": "MIT",
"version": "4.9.3",
"workspaces": [
"packages/*"
],
Expand Down Expand Up @@ -98,11 +98,15 @@
"bundlesize": [
{
"path": "packages/algoliasearch/dist/algoliasearch.umd.js",
"maxSize": "7.85KB"
"maxSize": "7.95KB"
},
{
"path": "packages/algoliasearch/dist/algoliasearch-lite.umd.js",
"maxSize": "4.35KB"
},
{
"path": "packages/recommend/dist/recommend.umd.js",
"maxSize": "4.1KB"
}
]
}
4 changes: 2 additions & 2 deletions packages/algoliasearch/README.md
Expand Up @@ -9,7 +9,7 @@
<a href="https://npmjs.org/package/algoliasearch"><img src="https://img.shields.io/npm/v/algoliasearch.svg?style=flat-square" alt="NPM version"></img></a>
<a href="http://npm-stat.com/charts.html?package=algoliasearch"><img src="https://img.shields.io/npm/dm/algoliasearch.svg?style=flat-square" alt="NPM downloads"></a>
<a href="https://www.jsdelivr.com/package/npm/algoliasearch"><img src="https://data.jsdelivr.com/v1/package/npm/algoliasearch/badge" alt="jsDelivr Downloads"></img></a>
<a href="LICENSE.txt"><img src="https://img.shields.io/badge/license-MIT-green.svg?style=flat-square" alt="License"></a>
<a href="LICENSE.md"><img src="https://img.shields.io/badge/license-MIT-green.svg?style=flat-square" alt="License"></a>
</p>
</p>

Expand Down Expand Up @@ -79,4 +79,4 @@ For full documentation, visit the **[online documentation](https://www.algolia.c

## 📄 License

Algolia JavaScript API Client is an open-sourced software licensed under the [MIT license](LICENSE.txt).
Algolia JavaScript API Client is an open-sourced software licensed under the [MIT license](LICENSE.md).
2 changes: 1 addition & 1 deletion packages/algoliasearch/package.json
Expand Up @@ -31,7 +31,7 @@
"@algolia/client-account": "4.9.3",
"@algolia/client-analytics": "4.9.3",
"@algolia/client-common": "4.9.3",
"@algolia/client-recommendation": "4.9.3",
"@algolia/client-personalization": "4.9.3",
"@algolia/client-search": "4.9.3",
"@algolia/logger-common": "4.9.3",
"@algolia/logger-console": "4.9.3",
Expand Down
30 changes: 15 additions & 15 deletions packages/algoliasearch/src/__tests__/default.test.ts
Expand Up @@ -83,7 +83,7 @@ describe('default preset', () => {

expect(client.transporter.requestsCache).not.toBe(cache);
expect(customClient.transporter.requestsCache).toBe(cache);
expect(customClient.initRecommendation().transporter.requestsCache).not.toBe(cache);
expect(customClient.initPersonalization().transporter.requestsCache).not.toBe(cache);
expect(customClient.initAnalytics({ requestsCache: cache }).transporter.requestsCache).toBe(
cache
);
Expand All @@ -92,7 +92,7 @@ describe('default preset', () => {
read: 46,
write: 47,
});
expect(customClient.initRecommendation().transporter.timeouts).toEqual({
expect(customClient.initPersonalization().transporter.timeouts).toEqual({
connect: testing.isBrowser() ? 1 : 2,
read: testing.isBrowser() ? 2 : 5,
write: 30,
Expand All @@ -110,7 +110,7 @@ describe('default preset', () => {
expect(customClient.transporter.hosts).toEqual([createStatelessHost({ url: 'foo.com' })]);

expect(customClient.initAnalytics().transporter.queryParameters).toEqual({});
expect(customClient.initRecommendation().transporter.headers).toEqual({
expect(customClient.initPersonalization().transporter.headers).toEqual({
'content-type': 'application/json',
'x-algolia-application-id': 'appId',
'x-algolia-api-key': 'apiKey',
Expand All @@ -119,31 +119,31 @@ describe('default preset', () => {
createStatelessHost({ url: 'foo.com' }),
]);

expect(customClient.initRecommendation().transporter.queryParameters).not.toEqual({
expect(customClient.initPersonalization().transporter.queryParameters).not.toEqual({
queryParameter: 'bar',
});

expect(customClient.initRecommendation().transporter.headers).toEqual({
expect(customClient.initPersonalization().transporter.headers).toEqual({
'content-type': 'application/json',
'x-algolia-application-id': 'appId',
'x-algolia-api-key': 'apiKey',
});
expect(customClient.initRecommendation().transporter.hosts).not.toEqual([
expect(customClient.initPersonalization().transporter.hosts).not.toEqual([
createStatelessHost({ url: 'foo.com' }),
]);
});

test('shared implementations between clients', () => {
const analytics = client.initAnalytics();
const recommendation = client.initRecommendation();
const personalization = client.initPersonalization();

expect(analytics.transporter).not.toBe(client.transporter);
expect(analytics.transporter.hostsCache).toBe(client.transporter.hostsCache);
expect(analytics.transporter.userAgent).toBe(client.transporter.userAgent);

expect(recommendation.transporter).not.toBe(client.transporter);
expect(recommendation.transporter.hostsCache).toBe(client.transporter.hostsCache);
expect(recommendation.transporter.userAgent).toBe(client.transporter.userAgent);
expect(personalization.transporter).not.toBe(client.transporter);
expect(personalization.transporter.hostsCache).toBe(client.transporter.hostsCache);
expect(personalization.transporter.userAgent).toBe(client.transporter.userAgent);
});

test('allows clients to override credentials', () => {
Expand All @@ -154,12 +154,12 @@ describe('default preset', () => {
const analytics = clientWithOptions.initAnalytics({
apiKey: 'analytics',
});
const recommendation = clientWithOptions.initRecommendation({
apiKey: 'recommendation',
const personalization = clientWithOptions.initPersonalization({
apiKey: 'personalization',
});

expect(analytics.transporter.headers['x-algolia-api-key']).toBe('analytics');
expect(recommendation.transporter.headers['x-algolia-api-key']).toBe('recommendation');
expect(personalization.transporter.headers['x-algolia-api-key']).toBe('personalization');
});

test('allows clients to keep default credentials', () => {
Expand All @@ -168,10 +168,10 @@ describe('default preset', () => {
expect(clientWithOptions.transporter.headers['x-algolia-api-key']).toBe('apiKey');

const analytics = clientWithOptions.initAnalytics();
const recommendation = clientWithOptions.initRecommendation();
const personalization = clientWithOptions.initPersonalization();

expect(analytics.transporter.headers['x-algolia-api-key']).toBe('apiKey');
expect(recommendation.transporter.headers['x-algolia-api-key']).toBe('apiKey');
expect(personalization.transporter.headers['x-algolia-api-key']).toBe('apiKey');
});

it('can be destroyed', () => {
Expand Down
55 changes: 37 additions & 18 deletions packages/algoliasearch/src/builds/browser.ts
Expand Up @@ -19,14 +19,14 @@ import {
} from '@algolia/client-analytics';
import { version, WaitablePromise } from '@algolia/client-common';
import {
createRecommendationClient,
createPersonalizationClient,
getPersonalizationStrategy,
GetPersonalizationStrategyResponse,
PersonalizationClient as BasePersonalizationClient,
PersonalizationStrategy,
RecommendationClient as BaseRecommendationClient,
setPersonalizationStrategy,
SetPersonalizationStrategyResponse,
} from '@algolia/client-recommendation';
} from '@algolia/client-personalization';
import {
addApiKey,
AddApiKeyOptions,
Expand Down Expand Up @@ -192,7 +192,7 @@ import { createConsoleLogger } from '@algolia/logger-console';
import { createBrowserXhrRequester } from '@algolia/requester-browser-xhr';
import { createUserAgent, RequestOptions } from '@algolia/transporter';

import { AlgoliaSearchOptions, InitAnalyticsOptions, InitRecommendationOptions } from '../types';
import { AlgoliaSearchOptions, InitAnalyticsOptions, InitPersonalizationOptions } from '../types';

export default function algoliasearch(
appId: string,
Expand All @@ -219,10 +219,22 @@ export default function algoliasearch(
}),
userAgent: createUserAgent(version).add({ segment: 'Browser' }),
};
const searchClientOptions = { ...commonOptions, ...options };
const initPersonalization = () => (
clientOptions?: InitPersonalizationOptions
): PersonalizationClient => {
return createPersonalizationClient({
...commonOptions,
...clientOptions,
methods: {
getPersonalizationStrategy,
setPersonalizationStrategy,
},
});
};

return createSearchClient({
...commonOptions,
...options,
...searchClientOptions,
methods: {
search: multipleQueries,
searchForFacetValues: multipleSearchForFacetValues,
Expand Down Expand Up @@ -319,17 +331,15 @@ export default function algoliasearch(
},
});
},
initPersonalization,
initRecommendation: () => (
clientOptions?: InitRecommendationOptions
): RecommendationClient => {
return createRecommendationClient({
...commonOptions,
...clientOptions,
methods: {
getPersonalizationStrategy,
setPersonalizationStrategy,
},
});
clientOptions?: InitPersonalizationOptions
): PersonalizationClient => {
searchClientOptions.logger.info(
'The `initRecommendation` method is deprecated. Use `initPersonalization` instead.'
);

return initPersonalization()(clientOptions);
},
},
});
Expand All @@ -338,7 +348,7 @@ export default function algoliasearch(
// eslint-disable-next-line functional/immutable-data
algoliasearch.version = version;

export type RecommendationClient = BaseRecommendationClient & {
export type PersonalizationClient = BasePersonalizationClient & {
readonly getPersonalizationStrategy: (
requestOptions?: RequestOptions
) => Readonly<Promise<GetPersonalizationStrategyResponse>>;
Expand All @@ -348,6 +358,11 @@ export type RecommendationClient = BaseRecommendationClient & {
) => Readonly<Promise<SetPersonalizationStrategyResponse>>;
};

/**
* @deprecated Use `PersonalizationClient` instead.
*/
export type RecommendationClient = PersonalizationClient;

export type AnalyticsClient = BaseAnalyticsClient & {
readonly addABTest: (
abTest: ABTest,
Expand Down Expand Up @@ -663,7 +678,11 @@ export type SearchClient = BaseSearchClient & {
requestOptions?: RequestOptions
) => Readonly<Promise<TaskStatusResponse>>;
readonly initAnalytics: (options?: InitAnalyticsOptions) => AnalyticsClient;
readonly initRecommendation: (options?: InitRecommendationOptions) => RecommendationClient;
readonly initPersonalization: (options?: InitPersonalizationOptions) => PersonalizationClient;
/**
* @deprecated Use `initPersonalization` instead.
*/
readonly initRecommendation: (options?: InitPersonalizationOptions) => PersonalizationClient;
};

export * from '../types';
55 changes: 37 additions & 18 deletions packages/algoliasearch/src/builds/node.ts
Expand Up @@ -18,14 +18,14 @@ import {
} from '@algolia/client-analytics';
import { destroy, version, WaitablePromise } from '@algolia/client-common';
import {
createRecommendationClient,
createPersonalizationClient,
getPersonalizationStrategy,
GetPersonalizationStrategyResponse,
PersonalizationClient as BasePersonalizationClient,
PersonalizationStrategy,
RecommendationClient as BaseRecommendationClient,
setPersonalizationStrategy,
SetPersonalizationStrategyResponse,
} from '@algolia/client-recommendation';
} from '@algolia/client-personalization';
import {
addApiKey,
AddApiKeyOptions,
Expand Down Expand Up @@ -194,7 +194,7 @@ import { Destroyable } from '@algolia/requester-common';
import { createNodeHttpRequester } from '@algolia/requester-node-http';
import { createUserAgent, RequestOptions } from '@algolia/transporter';

import { AlgoliaSearchOptions, InitAnalyticsOptions, InitRecommendationOptions } from '../types';
import { AlgoliaSearchOptions, InitAnalyticsOptions, InitPersonalizationOptions } from '../types';

export default function algoliasearch(
appId: string,
Expand All @@ -219,10 +219,22 @@ export default function algoliasearch(
version: process.versions.node,
}),
};
const searchClientOptions = { ...commonOptions, ...options };
const initPersonalization = () => (
clientOptions?: InitPersonalizationOptions
): PersonalizationClient => {
return createPersonalizationClient({
...commonOptions,
...clientOptions,
methods: {
getPersonalizationStrategy,
setPersonalizationStrategy,
},
});
};

return createSearchClient({
...commonOptions,
...options,
...searchClientOptions,
methods: {
search: multipleQueries,
searchForFacetValues: multipleSearchForFacetValues,
Expand Down Expand Up @@ -322,17 +334,15 @@ export default function algoliasearch(
},
});
},
initPersonalization,
initRecommendation: () => (
clientOptions?: InitRecommendationOptions
): RecommendationClient => {
return createRecommendationClient({
...commonOptions,
...clientOptions,
methods: {
getPersonalizationStrategy,
setPersonalizationStrategy,
},
});
clientOptions?: InitPersonalizationOptions
): PersonalizationClient => {
searchClientOptions.logger.info(
'The `initRecommendation` method is deprecated. Use `initPersonalization` instead.'
);

return initPersonalization()(clientOptions);
},
},
});
Expand All @@ -341,7 +351,7 @@ export default function algoliasearch(
// eslint-disable-next-line functional/immutable-data
algoliasearch.version = version;

export type RecommendationClient = BaseRecommendationClient & {
export type PersonalizationClient = BasePersonalizationClient & {
readonly getPersonalizationStrategy: (
requestOptions?: RequestOptions
) => Readonly<Promise<GetPersonalizationStrategyResponse>>;
Expand All @@ -351,6 +361,11 @@ export type RecommendationClient = BaseRecommendationClient & {
) => Readonly<Promise<SetPersonalizationStrategyResponse>>;
};

/**
* @deprecated Use `PersonalizationClient` instead.
*/
export type RecommendationClient = PersonalizationClient;

export type AnalyticsClient = BaseAnalyticsClient & {
readonly addABTest: (
abTest: ABTest,
Expand Down Expand Up @@ -671,7 +686,11 @@ export type SearchClient = BaseSearchClient & {
requestOptions?: RequestOptions
) => Readonly<Promise<TaskStatusResponse>>;
readonly initAnalytics: (options?: InitAnalyticsOptions) => AnalyticsClient;
readonly initRecommendation: (options?: InitRecommendationOptions) => RecommendationClient;
readonly initPersonalization: (options?: InitPersonalizationOptions) => PersonalizationClient;
/**
* @deprecated Use `initPersonalization` instead.
*/
readonly initRecommendation: (options?: InitPersonalizationOptions) => PersonalizationClient;
} & Destroyable;

export * from '../types';

0 comments on commit 97ebde6

Please sign in to comment.