Skip to content

Commit 4a9175d

Browse files
committed
wip: First draft of latest/related typesense search function.
1 parent c9f3932 commit 4a9175d

File tree

3 files changed

+79
-19
lines changed

3 files changed

+79
-19
lines changed

assets/js/globals.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ export function getSidebarNodes () {
1515
export function getVersionNodes () {
1616
return window.versionNodes || []
1717
}
18+
19+
export function getSearchNodes () {
20+
return window.searchNodes || []
21+
}

assets/js/search-page.js

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import lunr from 'lunr'
44
import { qs, escapeHtmlEntities, isBlank, getQueryParamByName, getProjectNameAndVersion } from './helpers'
55
import { setSearchInputValue } from './search-bar'
66
import searchResultsTemplate from './handlebars/templates/search-results.handlebars'
7+
import { getSearchNodes } from './globals'
78

89
const EXCERPT_RADIUS = 80
910
const SEARCH_CONTAINER_SELECTOR = '#search'
@@ -27,30 +28,85 @@ function initialize () {
2728
const pathname = window.location.pathname
2829
if (pathname.endsWith('/search.html') || pathname.endsWith('/search')) {
2930
const query = getQueryParamByName('q')
30-
search(query)
31+
const queryType = getQueryParamByName('type')
32+
search(query, queryType)
3133
}
3234
}
3335

34-
async function search (value) {
36+
async function search (value, queryType) {
3537
if (isBlank(value)) {
3638
renderResults({ value })
3739
} else {
3840
setSearchInputValue(value)
3941

40-
const index = await getIndex()
41-
4242
try {
43-
// We cannot match on atoms :foo because that would be considered
44-
// a filter. So we escape all colons not preceded by a word.
45-
const fixedValue = value.replaceAll(/(\B|\\):/g, '\\:')
46-
const results = searchResultsToDecoratedSearchItems(index.search(fixedValue))
43+
let results = []
44+
const searchNodes = getSearchNodes()
45+
46+
if (['related', 'latest'].includes(queryType) && searchNodes.length > 0) {
47+
results = await remoteSearch(value, queryType, searchNodes)
48+
} else {
49+
results = await localSearch(value)
50+
}
51+
4752
renderResults({ value, results })
4853
} catch (error) {
4954
renderResults({ value, errorMessage: error.message })
5055
}
5156
}
5257
}
5358

59+
async function localSearch (value) {
60+
const index = await getIndex()
61+
62+
// We cannot match on atoms :foo because that would be considered
63+
// a filter. So we escape all colons not preceded by a word.
64+
const fixedValue = value.replaceAll(/(\B|\\):/g, '\\:')
65+
return searchResultsToDecoratedSearchItems(index.search(fixedValue))
66+
}
67+
68+
async function remoteSearch (value, queryType, searchNodes) {
69+
let filterNodes = searchNodes
70+
71+
if (queryType === 'latest') {
72+
filterNodes = searchNodes.slice(0, 1)
73+
}
74+
75+
const filters = filterNodes.map(node => `package:=${node.name}-${node.version}`).join(' || ')
76+
77+
const params = new URLSearchParams()
78+
params.set('q', value)
79+
params.set('query_by', 'title,doc')
80+
params.set('filter_by', filters)
81+
82+
const response = await fetch(`https://search.hexdocs.pm/?${params.toString()}`)
83+
const payload = await response.json()
84+
85+
if (Array.isArray(payload.hits)) {
86+
return payload.hits.map(result => {
87+
const [packageName, packageVersion] = result.document.package.split('-')
88+
89+
const doc = result.document.doc
90+
const excerpts = [doc]
91+
const metadata = {}
92+
const ref = `https://hexdocs.pm/${packageName}/${packageVersion}/${result.document.ref}`
93+
const title = result.document.title
94+
const type = result.document.type
95+
96+
return {
97+
doc,
98+
excerpts,
99+
metadata,
100+
ref,
101+
title,
102+
type
103+
}
104+
})
105+
} else {
106+
return []
107+
}
108+
}
109+
54110
function renderResults ({ value, results, errorMessage }) {
55111
const searchContainer = qs(SEARCH_CONTAINER_SELECTOR)
56112
const resultsHtml = searchResultsTemplate({ value, results, errorMessage })

0 commit comments

Comments
 (0)