Refactored search initialization

This commit is contained in:
squidfunk 2021-02-07 17:18:10 +01:00
parent ae867d484b
commit 4744d5f3f0
12 changed files with 52 additions and 108 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,8 @@
{
"assets/javascripts/bundle.js": "assets/javascripts/bundle.0168bc18.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.0168bc18.min.js.map",
"assets/javascripts/vendor.js": "assets/javascripts/vendor.2c98d838.min.js",
"assets/javascripts/vendor.js.map": "assets/javascripts/vendor.2c98d838.min.js.map",
"assets/javascripts/bundle.js": "assets/javascripts/bundle.5c26acfa.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.5c26acfa.min.js.map",
"assets/javascripts/vendor.js": "assets/javascripts/vendor.250c9a34.min.js",
"assets/javascripts/vendor.js.map": "assets/javascripts/vendor.250c9a34.min.js.map",
"assets/javascripts/worker/search.js": "assets/javascripts/worker/search.cc7c7442.min.js",
"assets/javascripts/worker/search.js.map": "assets/javascripts/worker/search.cc7c7442.min.js.map",
"assets/stylesheets/main.css": "assets/stylesheets/main.9c987ffa.min.css",

View File

@ -216,8 +216,8 @@
</script>
{% endblock %}
{% block scripts %}
<script src="{{ 'assets/javascripts/vendor.2c98d838.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.0168bc18.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/vendor.250c9a34.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.5c26acfa.min.js' | url }}"></script>
{% for path in config["extra_javascript"] %}
<script src="{{ path | url }}"></script>
{% endfor %}

View File

@ -20,45 +20,12 @@
* IN THE SOFTWARE.
*/
import {
Observable,
Subject,
combineLatest,
fromEvent,
merge,
defer
} from "rxjs"
import {
delay,
distinctUntilChanged,
distinctUntilKeyChanged,
finalize,
map,
startWith,
takeLast,
takeUntil,
tap
} from "rxjs/operators"
import { Observable, merge } from "rxjs"
import { filter, sample, take } from "rxjs/operators"
import {
resetSearchQueryPlaceholder,
setSearchQueryPlaceholder
} from "~/actions"
import {
getElementOrThrow,
setElementFocus,
setToggle,
watchElementFocus
} from "~/browser"
import {
SearchTransformFn,
defaultTransform,
SearchWorker,
SearchQueryMessage,
SearchMessageType,
setupSearchWorker,
} from "~/integrations"
import { configuration } from "~/_"
import { getElementOrThrow } from "~/browser"
import { isSearchQueryMessage, isSearchReadyMessage, setupSearchWorker } from "~/integrations"
import { Component } from "../../_"
import { mountSearchQuery, SearchQuery } from "../query"
@ -80,10 +47,15 @@ export type Search =
* ------------------------------------------------------------------------- */
/**
* Fetch search index
*
* @param url - Search index URL
*
* @return Promise resolving with search index
*/
function fetchSearchIndex() {
function fetchSearchIndex(url: string) {
return __search?.index || fetch(url, { credentials: "same-origin" })
.then(res => res.json())
}
/* ----------------------------------------------------------------------------
@ -100,48 +72,29 @@ function fetchSearchIndex() {
export function mountSearch(
el: HTMLElement
): Observable<Component<Search>> {
const searchQueryEl = getElementOrThrow<HTMLInputElement>("[data-md-component=search-query]", el)
const searchResultEl = getElementOrThrow("[data-md-component=search-result]", el)
const config = configuration()
const worker = setupSearchWorker(config.search, fetchSearchIndex(
`${config.base}/search/search_index.json`
))
// TODO: determine correct BASE URL -> may change on instant loading!
const index$ = defer(() => fetch(`${config.base}/search/search_index.json`, {
credentials: "same-origin"
}).then(res => res.json()))
// TODO: shouldnt be necessary, as it's done from config?
const worker$ = setupSearchWorker(config.search, {
index$
})
// TODO: hand transformFn to
// __search.transform -> search transform
// __search.index -> search index
const query$ = mountSearchQuery(searchQueryEl, worker$)
const result$ = mountSearchResult(searchResultEl, worker$, { query$ })
/* Re-emit query when search is ready */
const { tx$, rx$ } = worker
tx$
.pipe(
filter(isSearchQueryMessage),
sample(rx$.pipe(filter(isSearchReadyMessage))),
take(1)
)
.subscribe(tx$.next.bind(tx$))
/* Obtain search query and result elements */
const query = getElementOrThrow("[data-md-component=search-query]", el)
const result = getElementOrThrow("[data-md-component=search-result]", el)
/* Create and return component */
const query$ = mountSearchQuery(query as HTMLInputElement, worker)
return merge(
query$,
result$
// /* Search query */
// ...getElements("[data-md-component=search-query]", el)
// .map(child => mountSearchQuery(child, worker$)),
// /* Search result */
// ...getElements("[data-md-component=search-query]", el)
// .map(child => mountSearchResult(child, worker$)),
mountSearchResult(result, worker, { query$ })
)
// /* Create and return component */
// return watchSearchQuery(el, transform)
// .pipe(
// tap(internal$),
// finalize(() => internal$.complete()),
// map(state => ({ ref: el, ...state }))
// )
}

View File

@ -82,6 +82,9 @@ setupClipboardJS()
// TODO: watchElements + general mount function that takes a factory...
// + a toggle function (optionally)
// TODO: catch errors on all components when mounting, so one error doesn't
// take down the whole site.
const app$ = merge(
/* Content */

View File

@ -20,8 +20,8 @@
* IN THE SOFTWARE.
*/
import { Observable, Subject, asyncScheduler } from "rxjs"
import { map, observeOn, share } from "rxjs/operators"
import { Subject, asyncScheduler, from } from "rxjs"
import { delay, map, observeOn, share } from "rxjs/operators"
import { configuration, translation } from "~/_"
import { WorkerHandler, watchWorker } from "~/browser"
@ -43,17 +43,6 @@ import {
*/
export type SearchWorker = WorkerHandler<SearchMessage>
/* ----------------------------------------------------------------------------
* Helper types
* ------------------------------------------------------------------------- */
/**
* Setup options
*/
interface SetupOptions {
index$: Observable<SearchIndex> /* Search index observable */
}
/* ----------------------------------------------------------------------------
* Helper functions
* ------------------------------------------------------------------------- */
@ -100,12 +89,12 @@ function setupSearchIndex(
* enable hacks like _localsearch_ via search index embedding as JSON.
*
* @param url - Worker URL
* @param options - Options
* @param index - Promise resolving with search index
*
* @return Search worker
*/
export function setupSearchWorker(
url: string, { index$ }: SetupOptions
url: string, index: Promise<SearchIndex>
): SearchWorker {
const config = configuration()
const worker = new Worker(url)
@ -126,13 +115,12 @@ export function setupSearchWorker(
)
/* Set up search index */
index$
from(index)
.pipe(
map<SearchIndex, SearchSetupMessage>(data => ({
type: SearchMessageType.SETUP,
data: setupSearchIndex(data)
})),
observeOn(asyncScheduler)
}))
)
.subscribe(tx$.next.bind(tx$))