Added search status to observable

This commit is contained in:
squidfunk 2020-04-26 17:22:55 +02:00
parent 398cd895c3
commit b5be7d3971
5 changed files with 51 additions and 11 deletions

View File

@ -21,9 +21,20 @@
*/
import { Observable, OperatorFunction, combineLatest, pipe } from "rxjs"
import { map, switchMap } from "rxjs/operators"
import {
filter,
map,
mapTo,
startWith,
switchMap
} from "rxjs/operators"
import { SearchResult } from "integrations/search"
import { WorkerHandler } from "browser"
import {
SearchMessage,
SearchResult,
isSearchReadyMessage
} from "integrations/search"
import { SearchQuery } from "../query"
@ -31,10 +42,20 @@ import { SearchQuery } from "../query"
* Types
* ------------------------------------------------------------------------- */
/**
* Search status
*/
export type SearchStatus =
| "waiting" /* Search waiting for initialization */
| "ready" /* Search ready */
/* ------------------------------------------------------------------------- */
/**
* Search
*/
export interface Search {
status: SearchStatus /* Search status */
query: SearchQuery /* Search query */
result: SearchResult[] /* Search result list */
}
@ -59,18 +80,35 @@ interface MountOptions {
/**
* Mount search from source observable
*
* @param handler - Worker handler
* @param options - Options
*
* @return Operator function
*/
export function mountSearch(
{ rx$ }: WorkerHandler<SearchMessage>,
{ query$, reset$, result$ }: MountOptions
): OperatorFunction<HTMLElement, Search> {
return pipe(
switchMap(() => combineLatest([query$, result$, reset$])
.pipe(
map(([query, result]) => ({ query, result }))
)
)
switchMap(() => {
/* Compute search status */
const status$ = rx$
.pipe(
filter(isSearchReadyMessage),
mapTo<SearchStatus>("ready"),
startWith("waiting")
) as Observable<SearchStatus>
/* Combine into single observable */
return combineLatest([status$, query$, result$, reset$])
.pipe(
map(([status, query, result]) => ({
status,
query,
result
}))
)
})
)
}

View File

@ -78,7 +78,7 @@ export function watchSearchQuery(
/* Intercept focus events */
const focus$ = watchElementFocus(el)
/* Combine into a single observable */
/* Combine into single observable */
return combineLatest([value$, focus$])
.pipe(
map(([value, focus]) => ({ value, focus }))

View File

@ -27,6 +27,7 @@ import {
filter,
map,
pluck,
startWith,
switchMap
} from "rxjs/operators"
@ -85,7 +86,8 @@ export function mountSearchResult(
.pipe(
filter(isSearchResultMessage),
pluck("data"),
applySearchResult(el, { query$, fetch$ })
applySearchResult(el, { query$, fetch$ }),
startWith([])
)
})
)

View File

@ -119,7 +119,7 @@ export function mountTableOfContents(
applyAnchorList(els)
)
/* Combine into a single hot observable */
/* Combine into single hot observable */
return combineLatest([sidebar$, anchors$])
.pipe(
map(([sidebar, anchors]) => ({ sidebar, anchors }))

View File

@ -280,7 +280,7 @@ export function initialize(config: unknown) {
const search$ = useComponent("search")
.pipe(
mountSearch({ query$, reset$, result$ }),
mountSearch(worker, { query$, reset$, result$ }),
shareReplay(1)
)