mirror of
https://github.com/ThatGuySam/doesitarm.git
synced 2026-05-18 06:44:46 -07:00
194 lines
5.7 KiB
JavaScript
194 lines
5.7 KiB
JavaScript
|
|
import { isString } from '~/helpers/check-types.js'
|
|
|
|
import {
|
|
storkIndexRelativeURL,
|
|
storkScriptURL
|
|
} from '~/helpers/stork/config.js'
|
|
|
|
|
|
export function makeHighlightedMarkup ( options = {} ) {
|
|
const {
|
|
text,
|
|
highlight_ranges,
|
|
withElipsis = true,
|
|
} = options
|
|
|
|
if ( highlight_ranges.length === 0 ) return [ text ]
|
|
|
|
const highlighted_text = highlight_ranges.map( range => {
|
|
const {
|
|
beginning,
|
|
end
|
|
} = range
|
|
|
|
const before = text.slice( 0, beginning )
|
|
const target = text.slice( beginning, end + 1 )
|
|
const after = text.slice( end + 1 )
|
|
|
|
// console.log({
|
|
// before,
|
|
// target,
|
|
// after
|
|
// })
|
|
|
|
// `<span class="stork-highlighted-text">${ highlighted_text }</span>`
|
|
|
|
return [
|
|
withElipsis ? '...' : '',
|
|
before.trim(),
|
|
/* html */` <span class="stork-highlighted-text font-bold bg-green-800 rounded px-1">${ target.trim() }</span> `,
|
|
after.trim(),
|
|
withElipsis ? '...' : '',
|
|
].join('')
|
|
} )
|
|
|
|
return highlighted_text
|
|
}
|
|
|
|
export function makeHighlightedResultTitle ( result ) {
|
|
const [ highlightedTitleMarkup ] = makeHighlightedMarkup({
|
|
text: result.entry.title,
|
|
highlight_ranges: result.title_highlight_ranges,
|
|
withElipsis: false
|
|
})
|
|
|
|
console.log('highlightedTitleMarkup', highlightedTitleMarkup)
|
|
console.log('result', result)
|
|
|
|
if ( !isString( highlightedTitleMarkup ) ) throw new Error('highlightedTitleMarkup is not a string')
|
|
|
|
return highlightedTitleMarkup
|
|
}
|
|
|
|
export class StorkClient {
|
|
constructor ( options = {} ) {
|
|
|
|
this.name = options.name || 'index'
|
|
this.url = options.url || storkIndexRelativeURL
|
|
|
|
// Configuration Reference - https://stork-search.net/docs/js-ref#showProgress
|
|
// Example - https://github.com/jameslittle230/stork/blob/ff49f163db06734e18ab690c188b45a3c68442ae/js/config.ts#L4
|
|
this.config = {
|
|
minimumQueryLength: 1,
|
|
showScores: true,
|
|
...options.config || {}
|
|
}
|
|
|
|
// Stork instance
|
|
this.stork = options.stork || null
|
|
}
|
|
|
|
setupState = 'not-setup'
|
|
|
|
get isSetup () {
|
|
return this.setupState === 'complete'
|
|
}
|
|
|
|
search ( query ) {
|
|
if ( !this.isSetup ) throw new Error('Not setup')
|
|
|
|
// search() - https://github.com/jameslittle230/stork/blob/ff49f163db06734e18ab690c188b45a3c68442ae/js/main.ts#L55
|
|
return this.stork.search( this.name, query )
|
|
}
|
|
|
|
// Loads the Stork WASM and Index into the browser on first query
|
|
// so that we don't have to load them initially.
|
|
async lazyQuery ( query ) {
|
|
if ( !this.isSetup ) await this.setup()
|
|
|
|
return this.search( query )
|
|
}
|
|
|
|
waitForSetup () {
|
|
return new Promise( resolve => {
|
|
if ( this.isSetup ) resolve()
|
|
|
|
// Start timer to check for setup
|
|
const timer = setInterval( () => {
|
|
if ( this.isSetup ) {
|
|
clearInterval( timer )
|
|
resolve()
|
|
}
|
|
}, 50 )
|
|
})
|
|
}
|
|
|
|
loadStorkScript () {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
if ( !!this.stork ) resolve()
|
|
|
|
if ( !!window.stork ) {
|
|
this.stork = window.stork
|
|
resolve()
|
|
}
|
|
|
|
const s = document.createElement('script')
|
|
let r = false
|
|
s.type = 'text/javascript'
|
|
s.src = storkScriptURL
|
|
s.async = true
|
|
s.onerror = function(err) {
|
|
reject(err, s)
|
|
}
|
|
|
|
s.onload = s.onreadystatechange = () => {
|
|
// console.log(this.readyState); // uncomment this line to see which ready states are called.
|
|
if (!r && (!this.readyState || this.readyState == 'complete')) {
|
|
r = true
|
|
|
|
this.stork = window.stork
|
|
|
|
// console.log('window.stork', typeof window.stork)
|
|
resolve()
|
|
}
|
|
}
|
|
|
|
const t = document.getElementsByTagName('script')[0]
|
|
t.parentElement.insertBefore(s, t)
|
|
})
|
|
}
|
|
|
|
// https://github.com/jameslittle230/stork/blob/ff49f163db06734e18ab690c188b45a3c68442ae/js/main.ts#L40
|
|
async setup () {
|
|
// Prevent multiple setups
|
|
if ( this.setupState !== 'not-setup' ) {
|
|
await this.waitForSetup()
|
|
return
|
|
}
|
|
|
|
// We're the first to setup
|
|
// so let's set the state to prevent duplicates
|
|
this.setupState = 'pending'
|
|
|
|
// Load Stork Script
|
|
if ( !this.stork ) {
|
|
// console.log('Loading stork script...')
|
|
await this.loadStorkScript()
|
|
}
|
|
|
|
const {
|
|
initialize,
|
|
downloadIndex,
|
|
} = this.stork
|
|
|
|
// Stork JavaScript Reference - https://stork-search.net/docs/js-ref
|
|
|
|
// initialize() - https://github.com/jameslittle230/stork/blob/ff49f163db06734e18ab690c188b45a3c68442ae/js/main.ts#L14
|
|
const initPromise = initialize()
|
|
|
|
// downloadIndex() - https://github.com/jameslittle230/stork/blob/ff49f163db06734e18ab690c188b45a3c68442ae/js/main.ts#L20
|
|
const downloadPromise = downloadIndex( this.name, this.url, this.config )
|
|
|
|
// This silly `then` call turns a [(void), (void)] into a (void), which is
|
|
// only necessary to make Typescript happy.
|
|
// You begin to wonder if you write Typescript code, or if Typescript code writes you.
|
|
await Promise.all([ initPromise, downloadPromise ])
|
|
|
|
// Mark setup as complete
|
|
this.setupState = 'complete'
|
|
|
|
return
|
|
}
|
|
}
|