Further refactoring of algolia indexing
This commit is contained in:
committed by
fabioberger
parent
f1f38fb8b0
commit
9b9ee2415d
@@ -7,7 +7,7 @@ const filter = require('unist-util-filter');
|
|||||||
const { selectAll } = require('unist-util-select');
|
const { selectAll } = require('unist-util-select');
|
||||||
const extractMdxMeta = require('extract-mdx-metadata');
|
const extractMdxMeta = require('extract-mdx-metadata');
|
||||||
|
|
||||||
function processContentTree(tree: Node[], url: string, meta: Meta, index: any): void {
|
function processContentTree(tree: Node[], url: string, meta: Meta, index: any, settings: Settings): void {
|
||||||
const filteredTree = filter(tree, () => {
|
const filteredTree = filter(tree, () => {
|
||||||
return (node: Node) => node.type === 'heading' || node.type === 'paragraph';
|
return (node: Node) => node.type === 'heading' || node.type === 'paragraph';
|
||||||
});
|
});
|
||||||
@@ -18,11 +18,12 @@ function processContentTree(tree: Node[], url: string, meta: Meta, index: any):
|
|||||||
const formattedTextNodes = formatTextNodes(textNodes);
|
const formattedTextNodes = formatTextNodes(textNodes);
|
||||||
const content = getContent(meta, url, formattedTextNodes);
|
const content = getContent(meta, url, formattedTextNodes);
|
||||||
|
|
||||||
|
setIndexSettings(index, settings);
|
||||||
pushObjectsToAlgolia(index, content);
|
pushObjectsToAlgolia(index, content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setIndexSettings(index: any, settings: Settings): void {
|
function setIndexSettings(index: any, settings: Settings): void {
|
||||||
index.setSettings(settings, (err: string) => {
|
index.setSettings(settings, (err: string) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw Error(`Error: ${err}`);
|
throw Error(`Error: ${err}`);
|
||||||
@@ -80,7 +81,7 @@ function formatTextNodes(textNodes: Node[]): FormattedNode[] {
|
|||||||
return formattedTextNodes;
|
return formattedTextNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processMdxAsync(index: any, dirName: string, fileName: string): Promise<void> {
|
async function processMdxAsync(index: any, dirName: string, fileName: string, settings: Settings): Promise<void> {
|
||||||
const filePath = `${dirName}/${fileName}`;
|
const filePath = `${dirName}/${fileName}`;
|
||||||
const { name } = path.parse(filePath); // Name without file extension
|
const { name } = path.parse(filePath); // Name without file extension
|
||||||
const url = `/docs/${dirName}/${name}`;
|
const url = `/docs/${dirName}/${name}`;
|
||||||
@@ -91,14 +92,14 @@ async function processMdxAsync(index: any, dirName: string, fileName: string): P
|
|||||||
|
|
||||||
await remark()
|
await remark()
|
||||||
.use(mdx)
|
.use(mdx)
|
||||||
.use(() => (tree: Node[]) => processContentTree(tree, url, meta, index))
|
.use(() => (tree: Node[]) => processContentTree(tree, url, meta, index, settings))
|
||||||
.process(file);
|
.process(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function indexFilesAsync(index: any, dirName: string): Promise<void> {
|
export async function indexFilesAsync(index: any, dirName: string, settings: Settings): Promise<void> {
|
||||||
fs.readdir(dirName, async (err: string, items: string[]) => {
|
fs.readdir(dirName, async (err: string, items: string[]) => {
|
||||||
for (const fileName of items) {
|
for (const fileName of items) {
|
||||||
await processMdxAsync(index, dirName, fileName);
|
await processMdxAsync(index, dirName, fileName, settings);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
21
packages/website/mdx/algolia_index.ts
Normal file
21
packages/website/mdx/algolia_index.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { adminClient, searchIndices, settings } from '../ts/utils/algolia_search';
|
||||||
|
|
||||||
|
import { indexFilesAsync } from './algolia_helpers';
|
||||||
|
|
||||||
|
// Get args after command (i.e. ts-node) and path to file (i.e. ./index.ts)
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
|
||||||
|
function processIndices(indices: string[]): void {
|
||||||
|
for (const indexName of indices) {
|
||||||
|
const index = adminClient.initIndex(searchIndices[indexName]);
|
||||||
|
indexFilesAsync(index, indexName, settings[indexName]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length > 0) {
|
||||||
|
// Use args given to process and push to algolia
|
||||||
|
processIndices(args);
|
||||||
|
} else {
|
||||||
|
// Process and push all indices
|
||||||
|
processIndices(Object.getOwnPropertyNames(searchIndices));
|
||||||
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import { adminClient, searchIndex, settings } from '../ts/utils/algolia_search';
|
|
||||||
import { indexFilesAsync, setIndexSettings } from './helpers';
|
|
||||||
|
|
||||||
const indexName = 'guides';
|
|
||||||
const index = adminClient.initIndex(searchIndex[indexName]);
|
|
||||||
|
|
||||||
setIndexSettings(index, settings[indexName]);
|
|
||||||
indexFilesAsync(index, indexName);
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import { adminClient, searchIndex, settings } from '../ts/utils/algolia_search';
|
|
||||||
import { indexFilesAsync, setIndexSettings } from './helpers';
|
|
||||||
|
|
||||||
const indexName = 'tools';
|
|
||||||
const index = adminClient.initIndex(searchIndex[indexName]);
|
|
||||||
|
|
||||||
setIndexSettings(index, settings[indexName]);
|
|
||||||
indexFilesAsync(index, indexName);
|
|
||||||
@@ -7,7 +7,7 @@ import { Link } from '@0x/react-shared';
|
|||||||
import { AutocompleteOverlay } from 'ts/components/docs/search/autocomplete_overlay';
|
import { AutocompleteOverlay } from 'ts/components/docs/search/autocomplete_overlay';
|
||||||
import { AutocompleteWrapper } from 'ts/components/docs/search/autocomplete_wrapper';
|
import { AutocompleteWrapper } from 'ts/components/docs/search/autocomplete_wrapper';
|
||||||
|
|
||||||
import { searchIndex } from 'ts/utils/algolia_search';
|
import { searchIndices } from 'ts/utils/algolia_search';
|
||||||
|
|
||||||
interface IHit {
|
interface IHit {
|
||||||
description: string;
|
description: string;
|
||||||
@@ -87,7 +87,7 @@ const CustomAutoComplete: React.FC<IAutoCompleteProps> = ({ isHome = false, hits
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderSectionTitle = (section: any): React.ReactNode => {
|
const renderSectionTitle = (section: any): React.ReactNode => {
|
||||||
const { tools, guides } = searchIndex;
|
const { tools, guides } = searchIndices;
|
||||||
|
|
||||||
const titles: { [key: string]: string } = {
|
const titles: { [key: string]: string } = {
|
||||||
[tools]: 'Tools',
|
[tools]: 'Tools',
|
||||||
|
|||||||
@@ -3,17 +3,17 @@ import { Configure, Index, InstantSearch } from 'react-instantsearch-dom';
|
|||||||
|
|
||||||
import { AutoComplete } from 'ts/components/docs/search/autocomplete';
|
import { AutoComplete } from 'ts/components/docs/search/autocomplete';
|
||||||
|
|
||||||
import { searchClient, searchIndex } from 'ts/utils/algolia_search';
|
import { searchClient, searchIndices } from 'ts/utils/algolia_search';
|
||||||
|
|
||||||
interface ISearchInputProps {
|
interface ISearchInputProps {
|
||||||
isHome?: boolean;
|
isHome?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SearchInput: React.FC<ISearchInputProps> = ({ isHome }) => (
|
export const SearchInput: React.FC<ISearchInputProps> = ({ isHome }) => (
|
||||||
<InstantSearch searchClient={searchClient} indexName={searchIndex.tools}>
|
<InstantSearch searchClient={searchClient} indexName={searchIndices.tools}>
|
||||||
<AutoComplete isHome={isHome} />
|
<AutoComplete isHome={isHome} />
|
||||||
<Configure hitsPerPage={5} distinct={true} />
|
<Configure hitsPerPage={5} distinct={true} />
|
||||||
<Index indexName={searchIndex.tools} />
|
<Index indexName={searchIndices.tools} />
|
||||||
<Index indexName={searchIndex.guides} />
|
<Index indexName={searchIndices.guides} />
|
||||||
</InstantSearch>
|
</InstantSearch>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ import { Resource } from 'ts/components/docs/resource/resource';
|
|||||||
import { Separator } from 'ts/components/docs/separator';
|
import { Separator } from 'ts/components/docs/separator';
|
||||||
import { Filters } from 'ts/components/docs/sidebar/filters';
|
import { Filters } from 'ts/components/docs/sidebar/filters';
|
||||||
|
|
||||||
import { searchClient, searchIndex } from 'ts/utils/algolia_search';
|
import { searchClient, searchIndices } from 'ts/utils/algolia_search';
|
||||||
|
|
||||||
export const DocsGuides: React.FC = () => (
|
export const DocsGuides: React.FC = () => (
|
||||||
<DocsPageLayout title="Guides">
|
<DocsPageLayout title="Guides">
|
||||||
<InstantSearch searchClient={searchClient} indexName={searchIndex.guides}>
|
<InstantSearch searchClient={searchClient} indexName={searchIndices.guides}>
|
||||||
<Columns>
|
<Columns>
|
||||||
<Filters filters={filters} />
|
<Filters filters={filters} />
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { ContentWrapper } from 'ts/components/docs/layout/content_wrapper';
|
|||||||
import { DocsPageLayout } from 'ts/components/docs/layout/docs_page_layout';
|
import { DocsPageLayout } from 'ts/components/docs/layout/docs_page_layout';
|
||||||
import { Separator } from 'ts/components/docs/separator';
|
import { Separator } from 'ts/components/docs/separator';
|
||||||
|
|
||||||
import { searchClient, searchIndex } from 'ts/utils/algolia_search';
|
import { searchClient, searchIndices } from 'ts/utils/algolia_search';
|
||||||
|
|
||||||
interface IHitsProps {
|
interface IHitsProps {
|
||||||
hits: IHit[];
|
hits: IHit[];
|
||||||
@@ -37,7 +37,7 @@ interface IHit {
|
|||||||
export const DocsTools: React.FC = () => {
|
export const DocsTools: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<DocsPageLayout title="Tools">
|
<DocsPageLayout title="Tools">
|
||||||
<InstantSearch searchClient={searchClient} indexName={searchIndex.tools}>
|
<InstantSearch searchClient={searchClient} indexName={searchIndices.tools}>
|
||||||
<Columns>
|
<Columns>
|
||||||
<Filters filters={filters} />
|
<Filters filters={filters} />
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|||||||
@@ -5,10 +5,27 @@ const ALGOLIA_CLIENT_API_KEY = '4c367b8cc6d6e175ae537cc61e4d8dfd';
|
|||||||
// @TODO: Move the following somewhere safe / out of the repo
|
// @TODO: Move the following somewhere safe / out of the repo
|
||||||
const ALGOLIA_ADMIN_API_KEY = 'ccc472dee2aa991ca4bc935975e76b5d';
|
const ALGOLIA_ADMIN_API_KEY = 'ccc472dee2aa991ca4bc935975e76b5d';
|
||||||
|
|
||||||
|
interface ISearchIndices {
|
||||||
|
[index: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ISettingsIndex {
|
||||||
|
[index: string]: Settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Settings {
|
||||||
|
distinct: boolean;
|
||||||
|
attributeForDistinct: string;
|
||||||
|
attributesForFaceting: string[];
|
||||||
|
attributesToSnippet: string[];
|
||||||
|
searchableAttributes: string[];
|
||||||
|
snippetEllipsisText: string;
|
||||||
|
}
|
||||||
|
|
||||||
export const searchClient = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_CLIENT_API_KEY);
|
export const searchClient = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_CLIENT_API_KEY);
|
||||||
export const adminClient = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_ADMIN_API_KEY);
|
export const adminClient = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_ADMIN_API_KEY);
|
||||||
|
|
||||||
export const searchIndex = {
|
export const searchIndices: ISearchIndices = {
|
||||||
guides: '0x_guides_test',
|
guides: '0x_guides_test',
|
||||||
tools: '0x_tools_test',
|
tools: '0x_tools_test',
|
||||||
};
|
};
|
||||||
@@ -21,7 +38,7 @@ const sharedSettings = {
|
|||||||
snippetEllipsisText: '…',
|
snippetEllipsisText: '…',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const settings = {
|
export const settings: ISettingsIndex = {
|
||||||
guides: {
|
guides: {
|
||||||
...sharedSettings,
|
...sharedSettings,
|
||||||
attributesForFaceting: ['topics', 'difficulty'],
|
attributesForFaceting: ['topics', 'difficulty'],
|
||||||
|
|||||||
Reference in New Issue
Block a user