UNPKG

3.57 kBPlain TextView Raw
1import * as Handlebars from 'handlebars';
2import * as path from 'path';
3
4import { decode } from 'html-entities';
5
6import { MAX_SIZE_FILE_CHEERIO_PARSING, MAX_SIZE_FILE_SEARCH_INDEX } from '../../utils/constants';
7
8import { logger } from '../../utils/logger';
9import Configuration from '../configuration';
10import FileEngine from './file.engine';
11
12const lunr: any = require('lunr');
13const cheerio: any = require('cheerio');
14
15export class SearchEngine {
16 public searchIndex: any;
17 private searchDocuments = [];
18 public documentsStore: Object = {};
19 public indexSize: number;
20 public amountOfMemory = 0;
21
22 private static instance: SearchEngine;
23 private constructor() {}
24 public static getInstance() {
25 if (!SearchEngine.instance) {
26 SearchEngine.instance = new SearchEngine();
27 }
28 return SearchEngine.instance;
29 }
30
31 public indexPage(page) {
32 let text;
33 this.amountOfMemory += page.rawData.length;
34 if (this.amountOfMemory < MAX_SIZE_FILE_CHEERIO_PARSING) {
35 let indexStartContent = page.rawData.indexOf('<!-- START CONTENT -->');
36 let indexEndContent = page.rawData.indexOf('<!-- END CONTENT -->');
37
38 let $ = cheerio.load(page.rawData.substring(indexStartContent + 1, indexEndContent));
39
40 text = $('.content').html();
41 text = decode(text);
42 text = text.replace(/(<([^>]+)>)/gi, '');
43
44 page.url = page.url.replace(Configuration.mainData.output, '');
45
46 let doc = {
47 url: page.url,
48 title: page.infos.context + ' - ' + page.infos.name,
49 body: text
50 };
51
52 if (
53 !this.documentsStore.hasOwnProperty(doc.url) &&
54 doc.body.length < MAX_SIZE_FILE_SEARCH_INDEX
55 ) {
56 this.documentsStore[doc.url] = doc;
57 this.searchDocuments.push(doc);
58 }
59 }
60 }
61
62 public generateSearchIndexJson(outputFolder: string): Promise<void> {
63 let that = this;
64 let searchIndex = lunr(function () {
65 /* tslint:disable:no-invalid-this */
66 this.ref('url');
67 this.field('title');
68 this.field('body');
69 this.pipeline.remove(lunr.stemmer);
70
71 let i = 0;
72 let len = that.searchDocuments.length;
73 for (i; i < len; i++) {
74 this.add(that.searchDocuments[i]);
75 }
76 });
77 return FileEngine.get(__dirname + '/../src/templates/partials/search-index.hbs').then(
78 data => {
79 let template: any = Handlebars.compile(data);
80 let result = template({
81 index: JSON.stringify(searchIndex),
82 store: JSON.stringify(this.documentsStore)
83 });
84 let testOutputDir = outputFolder.match(process.cwd());
85 if (testOutputDir && testOutputDir.length > 0) {
86 outputFolder = outputFolder.replace(process.cwd() + path.sep, '');
87 }
88
89 return FileEngine.write(
90 outputFolder + path.sep + '/js/search/search_index.js',
91 result
92 ).catch(err => {
93 logger.error('Error during search index file generation ', err);
94 return Promise.reject(err);
95 });
96 },
97 err => Promise.reject('Error during search index generation')
98 );
99 }
100}
101
102export default SearchEngine.getInstance();