This commit is contained in:
2021-09-01 15:29:47 +02:00
parent 92a4fb9d94
commit deb89701f7
7 changed files with 175 additions and 7 deletions

View File

@@ -0,0 +1,53 @@
import lunr from 'lunr'
import type { RequestHandler } from '@sveltejs/kit'
import { BaseAttributes, Call, gql, Page } from '$lib/api'
function removeHTML(s: string) {
return s.replace(/<.*?>|\s+|&#\d+;/g, ' ').trim()
}
function convertForIdx(type: string, items: Page[]) {
const keys: (keyof Page)[] = ['title', 'content', 'slug']
return items.map((item) => ({
url: `${type}/${item.slug}`,
data: keys.map((field) => removeHTML(item[field] ?? '')).join(' '),
}))
}
async function getAll() {
const all = await Call<Record<'posts' | 'projects' | 'works', { nodes: Page[] }>>(gql`
query {
posts(first: 1000) {
nodes {
${BaseAttributes}
}
}
projects(first: 1000) {
nodes {
${BaseAttributes}
}
}
works(first: 1000) {
nodes {
${BaseAttributes}
}
}
}
`)
return all
}
export const get: RequestHandler = async () => {
const all = await getAll()
const converted = Object.entries(all)
.map(([type, data]) => convertForIdx(type, data.nodes))
.flat()
const idx = lunr(function () {
this.ref('url')
this.field('data')
converted.forEach((doc) => this.add(doc))
})
return { body: idx }
}

View File

@@ -20,10 +20,10 @@
</script>
<svelte:head>
<title>Works</title>
<title>Blog - {data.title}</title>
</svelte:head>
<SimplePage title={data.title}>
<SimplePage title={data.title} readable>
<PostAttributes post={data} full />
{#if data.content}
<WpAdapter content={data.content} />

View File

@@ -1,6 +1,7 @@
<script lang="ts" context="module">
import type { Load } from '@sveltejs/kit'
export const prerender = true
export const load: Load = async ({ fetch }) => {
return {
props: {

View File

@@ -1 +1,80 @@
Hello
<script lang="ts" context="module">
import type { Load } from '@sveltejs/kit'
export const load: Load = async ({ fetch }) => {
return {
props: {
prebuilt: await fetch('/api/search.json').then((r) => r.json()),
},
}
}
</script>
<script lang="ts">
import lunr from 'lunr'
import { onMount } from 'svelte'
import type { SearchResultItem } from '$lib/components/SearchResult.svelte'
import SearchResult from '$lib/components/SearchResult.svelte'
import SimplePage from '$lib/components/SimplePage.svelte'
export let prebuilt: any
let needle: string | null = null
let results: SearchResultItem[] = []
const idx = lunr.Index.load(prebuilt)
async function search(needle: string) {
if (!needle || !idx) {
results = []
} else {
let found = idx.search(needle + '~1')
if (!found.length) found = idx.search(needle + '*')
results = found.slice(0, 20)
}
}
$: if (needle) {
if (typeof window !== 'undefined') {
window.history.replaceState(null, '', `/search?q=${needle ?? ''}`)
}
search(needle)
}
onMount(() => {
needle = new URLSearchParams(window.location.search).get('q')
})
</script>
<SimplePage title="Search" expanded={false}>
<input bind:value={needle} placeholder="needle" />
{#if needle}
<ul>
{#each results as result (result.ref)}
<SearchResult {result} />
{/each}
</ul>
{:else}
<p>Start typing...</p>
{/if}
</SimplePage>
<style>
input {
appearance: none;
-webkit-appearance: none;
margin: 0;
padding: 0.5rem;
font-size: 1em;
width: 100%;
outline: none;
border: 2px solid var(--clr-primary);
border-radius: 0;
}
ul {
margin-top: 2em;
list-style: none;
padding: 0;
}
</style>