mirror of
https://github.com/Redocly/redoc.git
synced 2025-02-16 18:00:33 +03:00
feat: serialize search-index
This commit is contained in:
parent
8e4184b407
commit
e94f84283d
|
@ -35,12 +35,12 @@ async function init() {
|
|||
init();
|
||||
|
||||
if (module.hot) {
|
||||
const reload = (reloadStore = false) => () => {
|
||||
const reload = (reloadStore = false) => async () => {
|
||||
if (reloadStore) {
|
||||
// create a new Store
|
||||
store.dispose();
|
||||
|
||||
const state = store.toJS();
|
||||
const state = await store.toJS();
|
||||
store = AppStore.fromJS(state);
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
"webpack": "^3.10.0",
|
||||
"webpack-dev-server": "^2.9.5",
|
||||
"webpack-node-externals": "^1.6.0",
|
||||
"workerize-loader": "^1.0.1",
|
||||
"workerize-loader": "^1.0.2",
|
||||
"yaml-js": "^0.2.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
|
@ -17,6 +17,7 @@ interface StoreData {
|
|||
url: string;
|
||||
data: any;
|
||||
};
|
||||
searchIndex: any;
|
||||
options: RedocRawOptions;
|
||||
}
|
||||
|
||||
|
@ -36,9 +37,10 @@ export class AppStore {
|
|||
*/
|
||||
// TODO:
|
||||
static fromJS(state: StoreData): AppStore {
|
||||
const inst = new AppStore(state.spec.data, state.spec.url, state.options);
|
||||
const inst = new AppStore(state.spec.data, state.spec.url, state.options, false);
|
||||
inst.menu.activeItemIdx = state.menu.activeItemIdx || 0;
|
||||
inst.menu.activate(inst.menu.flatItems[inst.menu.activeItemIdx]);
|
||||
inst.search.load(state.searchIndex);
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
@ -52,7 +54,12 @@ export class AppStore {
|
|||
private scroll: ScrollService;
|
||||
private disposer;
|
||||
|
||||
constructor(spec: OpenAPISpec, specUrl?: string, options: RedocRawOptions = {}) {
|
||||
constructor(
|
||||
spec: OpenAPISpec,
|
||||
specUrl?: string,
|
||||
options: RedocRawOptions = {},
|
||||
createSearchIndex: boolean = true,
|
||||
) {
|
||||
this.rawOptions = options;
|
||||
this.options = new RedocNormalizedOptions(options);
|
||||
this.scroll = new ScrollService(this.options);
|
||||
|
@ -60,8 +67,9 @@ export class AppStore {
|
|||
this.menu = new MenuStore(this.spec, this.scroll);
|
||||
|
||||
this.search = new SearchStore();
|
||||
this.search.indexItems(this.menu.items);
|
||||
this.search.done();
|
||||
if (createSearchIndex) {
|
||||
this.search.indexItems(this.menu.items);
|
||||
}
|
||||
|
||||
this.disposer = observe(this.menu, 'activeItemIdx', change => {
|
||||
this.updateMarkOnMenu(change.newValue as number);
|
||||
|
@ -106,7 +114,7 @@ export class AppStore {
|
|||
* **SUPER HACKY AND NOT OPTIMAL IMPLEMENTATION**
|
||||
*/
|
||||
// TODO:
|
||||
toJS(): StoreData {
|
||||
async toJS(): Promise<StoreData> {
|
||||
return {
|
||||
menu: {
|
||||
activeItemIdx: this.menu.activeItemIdx,
|
||||
|
@ -115,6 +123,7 @@ export class AppStore {
|
|||
url: this.spec.parser.specUrl,
|
||||
data: this.spec.parser.spec,
|
||||
},
|
||||
searchIndex: await this.search.toJS(),
|
||||
options: this.rawOptions,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,23 +6,32 @@ export class SearchStore {
|
|||
searchWorker = new worker();
|
||||
|
||||
indexItems(groups: Array<IMenuItem | OperationModel>) {
|
||||
groups.forEach(group => {
|
||||
if (group.type !== 'group') {
|
||||
this.add(group.name, group.description || '', group.id);
|
||||
}
|
||||
this.indexItems(group.items);
|
||||
});
|
||||
const recurse = groups => {
|
||||
groups.forEach(group => {
|
||||
if (group.type !== 'group') {
|
||||
this.add(group.name, group.description || '', group.id);
|
||||
}
|
||||
recurse(group.items);
|
||||
});
|
||||
};
|
||||
|
||||
recurse(groups);
|
||||
this.searchWorker.done();
|
||||
}
|
||||
|
||||
add(title: string, body: string, ref: string) {
|
||||
this.searchWorker.add(title, body, ref);
|
||||
}
|
||||
|
||||
done() {
|
||||
this.searchWorker.done();
|
||||
}
|
||||
|
||||
search(q: string) {
|
||||
return this.searchWorker.search(q);
|
||||
}
|
||||
|
||||
async toJS() {
|
||||
return this.searchWorker.toJS();
|
||||
}
|
||||
|
||||
load(state: any) {
|
||||
this.searchWorker.load(state);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ export default class Worker {
|
|||
add = add;
|
||||
done = done;
|
||||
search = search;
|
||||
toJS = toJS;
|
||||
load = load;
|
||||
}
|
||||
|
||||
export interface SearchDocument {
|
||||
|
@ -17,7 +19,7 @@ export interface SearchResult extends SearchDocument {
|
|||
score: number;
|
||||
}
|
||||
|
||||
const store: { [id: string]: SearchDocument } = {};
|
||||
let store: { [id: string]: SearchDocument } = {};
|
||||
|
||||
let resolveIndex: (v: lunr.Index) => void;
|
||||
const index: Promise<lunr.Index> = new Promise(resolve => {
|
||||
|
@ -43,6 +45,18 @@ export async function done() {
|
|||
resolveIndex(builder.build());
|
||||
}
|
||||
|
||||
export async function toJS() {
|
||||
return {
|
||||
store: store,
|
||||
index: (await index).toJSON(),
|
||||
};
|
||||
}
|
||||
|
||||
export async function load(state: any) {
|
||||
store = state.store;
|
||||
resolveIndex(lunr.Index.load(state.index));
|
||||
}
|
||||
|
||||
export async function search(q: string): Promise<SearchResult[]> {
|
||||
if (q.trim().length === 0) {
|
||||
return [];
|
||||
|
|
Loading…
Reference in New Issue
Block a user