Skip to content

Commit

Permalink
v2.0.0
Browse files Browse the repository at this point in the history
## Version 2.0.0

### Breaking Changes
- Upgraded search-headless dependency to V2. This means re-exported interfaces related to static filters and direct answers stems from search-headless V1 have been changed or removed in headless-react V2.
  - for more details, see the breaking changes listed in V2 [release notes](https://github.com/yext/search-headless/releases/tag/v2.0.0) and [documentation](https://github.com/yext/search-headless/blob/main/docs/search-headless.md) of search-headless
- `SearchHeadlessProvider` now takes in a `SearchHeadless` instance instead of a `SearchConfig` object. `SearchHeadlessProvider` will also no longer set vertical key, session tracking, and session id for the `SearchHeadless` instance. Users will need to create and initialize a Headless instance themselves. For more context, this change is made to prevent potential memory leaks, per Redux's recommendation that redux store (i.e. `SearchHeadless` instance) should not be instantiated within a render function. (#156)
- All exports marked as `@deprecated` in previous publish as part of the rebranding process, as well as `subscribeToStateUpdates`, is now removed in V2 (#153  )
  - for more details, the deprecated identifiers are listed in [v1.3 release notes](https://github.com/yext/search-headless-react/releases/tag/v1.3.0)
  • Loading branch information
yen-tt committed Sep 8, 2022
2 parents 233b24f + e85b1d1 commit addb3a7
Show file tree
Hide file tree
Showing 13 changed files with 77 additions and 253 deletions.
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,19 @@ npm install @yext/search-headless-react

## Getting Started - `SearchHeadlessProvider`

Search Headless React includes an `<SearchHeadlessProvider />` component, which instantiates an SearchHeadless instance and makes it available to the rest of your app.
Search Headless React includes an `<SearchHeadlessProvider />` component, which takes in a `SearchHeadless` instance and makes it available to the rest of your app. `SearchHeadless` instance is created using `provideHeadless(...)` with the appropriate credentials:

```tsx
import { SearchHeadlessProvider } from '@yext/search-headless-react';
import { provideHeadless, SearchHeadlessProvider } from '@yext/search-headless-react';
import SearchBar from './SearchBar';
import MostRecentSearch from './MostRecentSearch';
import UniversalResults from './UniversalResults';

const searcher = provideHeadless(config);

function MyApp() {
return (
<SearchHeadlessProvider
apiKey='your api key'
experienceKey='your experience key'
locale='en'
>
<SearchHeadlessProvider searcher={searcher}>
{/* Add components that use Search as children */}
<SearchBar/>
<MostRecentSearch/>
Expand Down
4 changes: 2 additions & 2 deletions THIRD-PARTY-NOTICES
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ SOFTWARE.

The following NPM package may be included in this product:

- @yext/search-core@1.9.0
- @yext/search-core@2.0.0

This package contains the following license and notice below:

Expand Down Expand Up @@ -106,7 +106,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The following NPM package may be included in this product:

- @yext/search-headless@1.4.0
- @yext/search-headless@2.0.0

This package contains the following license and notice below:

Expand Down
34 changes: 17 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "@yext/search-headless-react",
"version": "1.4.0",
"version": "2.0.0",
"description": "The official React UI Bindings layer for Search Headless",
"main": "./lib/esm/src/index.js",
"main": "./lib/esm/index.js",
"license": "BSD-3-Clause",
"types": "./lib/esm/src/index.d.ts",
"types": "./lib/esm/index.d.ts",
"keywords": [
"search",
"react",
Expand All @@ -13,16 +13,16 @@
"yext"
],
"exports": {
"import": "./lib/esm/src/index.js",
"require": "./lib/commonjs/src/index.js"
"import": "./lib/esm/index.js",
"require": "./lib/commonjs/index.js"
},
"files": [
"lib",
"src",
"THIRD-PARTY-NOTICES"
],
"scripts": {
"build": "rm -rf lib/** && npm run build:esm && npm run build:cjs",
"build": "rm -rf lib/** && npm run build:esm && npm run build:cjs && npm run generate-notices",
"build:esm": "tsc -p tsconfig.esm.json",
"build:cjs": "tsc -p tsconfig.cjs.json",
"prepublishOnly": "npm run build",
Expand All @@ -32,7 +32,7 @@
"generate-notices": "generate-license-file --input package.json --output THIRD-PARTY-NOTICES --overwrite"
},
"dependencies": {
"@yext/search-headless": "^1.4.0",
"@yext/search-headless": "^2.0.0",
"use-sync-external-store": "^1.1.0"
},
"devDependencies": {
Expand Down
27 changes: 4 additions & 23 deletions src/SearchHeadlessProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,14 @@
import { PropsWithChildren } from 'react';
import { provideHeadless, SearchHeadless, HeadlessConfig } from '@yext/search-headless';
import { SearchHeadless } from '@yext/search-headless';
import { SearchHeadlessContext } from './SearchHeadlessContext';
import acquireSessionId from './utils/acquireSessionId';
import packageJson from '../package.json';

const { version } = packageJson;

type Props = HeadlessConfig & {
verticalKey?: string,
sessionTrackingEnabled?: boolean
};
type Props = { searcher: SearchHeadless };

export function SearchHeadlessProvider(props: PropsWithChildren<Props>): JSX.Element {
const { children, verticalKey, sessionTrackingEnabled=true, ...answersConfig } = props;
const additionalHttpHeaders = {
'Client-SDK': {
ANSWERS_HEADLESS_REACT: version
}
};
const answers: SearchHeadless = provideHeadless(answersConfig, additionalHttpHeaders);
const { children, searcher } = props;

verticalKey && answers.setVertical(verticalKey);
answers.setSessionTrackingEnabled(sessionTrackingEnabled);
if (sessionTrackingEnabled) {
const sessionId = acquireSessionId();
sessionId && answers.setSessionId(sessionId);
}
return (
<SearchHeadlessContext.Provider value={answers}>
<SearchHeadlessContext.Provider value={searcher}>
{children}
</SearchHeadlessContext.Provider>
);
Expand Down
51 changes: 0 additions & 51 deletions src/deprecated.ts

This file was deleted.

3 changes: 0 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import { useSearchActions, SearchActions } from './useSearchActions';
import { useSearchState, StateSelector } from './useSearchState';
import { useSearchUtilities, SearchUtilities } from './useSearchUtilities';
import { subscribeToStateUpdates } from './subscribeToStateUpdates';
import { SearchHeadlessProvider } from './SearchHeadlessProvider';
import { SearchHeadlessContext } from './SearchHeadlessContext';

export * from '@yext/search-headless';
export * from './deprecated';
export {
SearchHeadlessContext,
subscribeToStateUpdates,
useSearchActions,
useSearchState,
useSearchUtilities,
Expand Down
52 changes: 0 additions & 52 deletions src/subscribeToStateUpdates.tsx

This file was deleted.

22 changes: 0 additions & 22 deletions src/utils/acquireSessionId.ts

This file was deleted.

33 changes: 21 additions & 12 deletions tests/SearchHeadlessProvider.test.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
import { SearchHeadlessProvider, SandboxEndpoints } from '../src';
import { SearchHeadlessProvider } from '../src';
import { render } from '@testing-library/react';
import { provideHeadless } from '@yext/search-headless';
import { provideHeadless, SearchHeadless } from '@yext/search-headless';

jest.mock('@yext/search-headless', () => ({
provideHeadless: jest.fn(() => ({
setSessionTrackingEnabled: jest.fn(),
setSessionId: jest.fn()
}))
provideHeadless: jest.fn(() => { return {}; })
}));

it('correctly passes through an answers config with sandbox endpoints', () => {
it('Provider does not invoke any methods or attributes of the Searcher', () => {
const config = {
apiKey: '<apiKey>',
experienceKey: '<experienceKey>',
locale: 'en',
endpoints: SandboxEndpoints
locale: 'en'
};
const searcher: SearchHeadless = provideHeadless(config);

render(<SearchHeadlessProvider {...config}/>);
expect(provideHeadless).toHaveBeenCalledTimes(1);
expect(provideHeadless).toHaveBeenCalledWith(config, expect.anything());
expect(
() => render(<SearchHeadlessProvider searcher={searcher}></SearchHeadlessProvider>)).not.toThrowError();
});

it('Provider does decorate any methods in the Searcher', () => {
const config = {
apiKey: '<apiKey>',
experienceKey: '<experienceKey>',
locale: 'en'
};
const searcher: SearchHeadless = provideHeadless(config);
const searcherProxy = new Proxy(searcher, { set() { throw new Error(); } });

expect(() => render(
<SearchHeadlessProvider searcher={searcherProxy}></SearchHeadlessProvider>)).not.toThrowError();
});
Loading

0 comments on commit addb3a7

Please sign in to comment.