Skip to content

Commit

Permalink
feat: Implement local search adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
3y3 committed Oct 18, 2024
1 parent 6cae881 commit 3766714
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 6 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
},
"dependencies": {
"@diplodoc/client": "^2.8.2",
"@diplodoc/search-extension": "^1.0.0",
"@diplodoc/translation": "^1.4.3",
"katex": "^0.16.9",
"shelljs": "0.8.5",
Expand Down
8 changes: 6 additions & 2 deletions src/models.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type {DocAnalytics} from '@diplodoc/client';

import {Logger} from '@diplodoc/transform/lib/log';
import {ChangelogItem} from '@diplodoc/transform/lib/plugins/changelog/types';
import {LintConfig} from '@diplodoc/transform/lib/yfmlint';
import type {DocAnalytics} from '@diplodoc/client';

import {IncludeMode, Lang, ResourceType, Stage} from './constants';
import {FileContributors, VCSConnector, VCSConnectorConfig} from './vcs-connector/connector-models';
Expand Down Expand Up @@ -84,7 +85,10 @@ interface YfmConfig {
*/
changelogs?: string | boolean;
analytics?: DocAnalytics;
useLegacyConditions: boolean;
useLegacyConditions?: boolean;
search?: {
provider: string;
} & {[prop: string]: unknown};
}

export interface YfmArgv extends YfmConfig {
Expand Down
42 changes: 42 additions & 0 deletions src/pages/search.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {join} from 'path';

import {BUNDLE_FOLDER, Lang, RTL_LANGS} from '../constants';

import manifest from '@diplodoc/client/manifest';
import {SEARCH_PAGE_DEPTH} from '../services/search';

export function generateStaticSearch(lang: Lang): string {
const isRTL = RTL_LANGS.includes(lang);

return `
<!DOCTYPE html>
<html lang="${lang}" dir="${isRTL ? 'rtl' : 'ltr'}">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="noindex"/>
<title>Search</title>
<style type="text/css">
body {
height: 100vh;
}
</style>
${manifest.search.css
.filter((file: string) => isRTL === file.includes('.rtl.css'))
.map((url: string) => join('../'.repeat(SEARCH_PAGE_DEPTH), BUNDLE_FOLDER, url))
.map((src: string) => `<link type="text/css" rel="stylesheet" href="${src}" />`)
.join('\n')}
</head>
<body class="g-root g-root_theme_light">
<div id="root"></div>
${manifest.search.js
.map((url: string) => join('../'.repeat(SEARCH_PAGE_DEPTH), BUNDLE_FOLDER, url))
.map(
(src: string) =>
`<script type="application/javascript" src="${src}"></script>`,
)
.join('\n')}
</body>
</html>
`;
}
12 changes: 9 additions & 3 deletions src/resolvers/md2html.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type {DocInnerProps} from '@diplodoc/client';

import {readFileSync, writeFileSync} from 'fs';
import {basename, dirname, join, resolve, sep} from 'path';
import {LINK_KEYS, preprocess} from '@diplodoc/client/ssr';
import {isString} from 'lodash';

import type {DocInnerProps} from '@diplodoc/client';
import transform, {Output} from '@diplodoc/transform';
import liquid from '@diplodoc/transform/lib/liquid';
import log from '@diplodoc/transform/lib/log';
Expand All @@ -13,7 +14,7 @@ import yaml from 'js-yaml';

import {Lang, PROCESSING_FINISHED} from '../constants';
import {LeadingPage, ResolverOptions, YfmToc} from '../models';
import {ArgvService, PluginService, TocService} from '../services';
import {ArgvService, PluginService, SearchService, TocService} from '../services';
import {getAssetsPublicPath, getAssetsRootPath, getVCSMetadata} from '../services/metadata';
import {
getLinksWithContentExtersion,
Expand Down Expand Up @@ -83,7 +84,7 @@ const getFileProps = async (options: ResolverOptions) => {
const pathToFileDir: string =
pathToDir === tocBase ? '' : pathToDir.replace(`${tocBase}${sep}`, '');

const {lang: configLang, langs: configLangs, analytics} = ArgvService.getConfig();
const {lang: configLang, langs: configLangs, analytics, search} = ArgvService.getConfig();
const meta = await getFileMeta(options);

const tocBaseLang = tocBase?.split('/')[0];
Expand All @@ -102,9 +103,14 @@ const getFileProps = async (options: ResolverOptions) => {
},
router: {
pathname,
depth: pathname.split('/').length,
},
lang,
langs,
search: {
...search,
...SearchService.config(lang),
},
analytics,
};

Expand Down
1 change: 1 addition & 0 deletions src/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export {default as TocService} from './tocs';
export {default as PresetService} from './preset';
export {default as ArgvService} from './argv';
export {default as LeadingService} from './leading';
export {default as SearchService} from './search';
export * as PluginService from './plugins';
export * as Includers from './includers';
124 changes: 124 additions & 0 deletions src/services/search.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import type {DocInnerProps, DocPageData} from '@diplodoc/client';
import type {Lang} from '../constants';

import {join} from 'node:path';
import {mkdirSync, writeFileSync} from 'node:fs';

import {Indexer} from '@diplodoc/search-extension/indexer';

import {ArgvService} from '.';
import {generateStaticSearch} from '../pages';
import {copyFileSync} from 'fs';

const api = require.resolve('@diplodoc/search-extension/worker');

let indexer: Indexer;

function init() {
indexer = new Indexer();
}

function add(info: DocInnerProps) {
const {search} = ArgvService.getConfig();
if (!search || search.provider !== 'local') {
return;
}

const {lang, data, router} = info;

// TODO: index leading and lpc pages
if (data.leading) {
return;
}

const base = (data.toc as {base?: string}).base || '';
const url = base + '/' + router.pathname;

indexer.add(lang, url, data as DocPageData);
}

async function release() {
const {search} = ArgvService.getConfig();
if (!search) {
return;
}

if (search.provider === 'local') {
copyFileSync(api, apiLink());
}

for (const lang of indexer.langs) {
const {index, registry} = await indexer.release(lang);
const dir = outputDir(lang);

mkdirSync(dir, {recursive: true});
writeFileSync(indexLink(lang), index, 'utf8');
writeFileSync(registryLink(lang), registry, 'utf8');
writeFileSync(pageLink(lang), generateStaticSearch(lang as Lang), 'utf8');
}
}

function outputDir(lang: string) {
const {output} = ArgvService.getConfig();
return join(output, '_search', lang);
}

function bundleDir() {
const {output} = ArgvService.getConfig();
return join(output, '_bundle');
}

function outputLink(lang: string, file: string) {
const dir = outputDir(lang);
const path = join(dir, file);

return path;
}

// <root>/_search/ru
export const SEARCH_PAGE_DEPTH = 2;

function pageLink(lang: string) {
return outputLink(lang, 'index.html');
}

function apiLink() {
const dir = bundleDir();
const path = join(dir, 'search-api.js');

return path;
}

function indexLink(lang: string) {
return outputLink(lang, 'index.json');
}

function registryLink(lang: string) {
return outputLink(lang, 'registry.json');
}

function config(lang: string) {
const {search, output} = ArgvService.getConfig();

if (!search || search.provider !== 'local') {
return {};
}

const short = (link: string, root: string) => link.replace(root, '').replace(/^\/?/, '');

return {
api: short(apiLink(), bundleDir()),
link: short(pageLink(lang), output),
resources: {
index: short(indexLink(lang), output),
registry: short(registryLink(lang), output),
},
};
}

export default {
init,
add,
release,
config,
};
4 changes: 3 additions & 1 deletion src/steps/processPages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
YfmToc,
} from '../models';
import {resolveMd2HTML, resolveMd2Md} from '../resolvers';
import {ArgvService, LeadingService, PluginService, TocService} from '../services';
import {ArgvService, LeadingService, PluginService, SearchService, TocService} from '../services';
import {generateStaticMarkup} from '~/pages/document';
import {generateStaticRedirect} from '~/pages/redirect';
import {joinSinglePageResults, logger, transformTocForSinglePage} from '../utils';
Expand Down Expand Up @@ -290,6 +290,8 @@ async function preparingPagesByOutputFormat(
case 'html': {
const resolvedFileProps = await processingFileToHtml(path, metaDataOptions);

SearchService.add(resolvedFileProps);

if (singlePage) {
savePageResultForSinglePage(resolvedFileProps, path);
}
Expand Down

0 comments on commit 3766714

Please sign in to comment.