From b465c067d9fc4424ffb27e7e91301f68d042b6e6 Mon Sep 17 00:00:00 2001 From: cupcakearmy Date: Wed, 22 Dec 2021 23:33:58 +0100 Subject: [PATCH] search --- src/lib/gql/gen.ts | 29 ++++++++++++++++++ src/lib/gql/root.graphql | 18 +++++++++++ src/routes/api/search.json.ts | 56 +++++++++++------------------------ src/routes/search.svelte | 8 ++--- 4 files changed, 68 insertions(+), 43 deletions(-) diff --git a/src/lib/gql/gen.ts b/src/lib/gql/gen.ts index da0dc31..8577367 100644 --- a/src/lib/gql/gen.ts +++ b/src/lib/gql/gen.ts @@ -9219,6 +9219,11 @@ export type GQLPostsOneQueryVariables = Exact<{ export type GQLPostsOneQuery = { readonly __typename?: 'RootQuery', readonly post: { readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } } }; +export type GQLSearchQueryVariables = Exact<{ [key: string]: never; }>; + + +export type GQLSearchQuery = { readonly __typename?: 'RootQuery', readonly posts: { readonly __typename?: 'RootQueryToPostConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> }, readonly projects: { readonly __typename?: 'RootQueryToProjectConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Project', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly project: { readonly __typename?: 'Project_Project', readonly date: string, readonly link: string, readonly description: string } }> }, readonly works: { readonly __typename?: 'RootQueryToWorkConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Work', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly work: { readonly __typename?: 'Work_Work', readonly date: string, readonly link: string, readonly role: string, readonly image: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> } }; + export const BasePageFragmentDoc = gql` fragment BasePage on Page { id @@ -9362,6 +9367,27 @@ export const PostsOneDocument = gql` } } ${BasePostFragmentDoc}`; +export const SearchDocument = gql` + query Search { + posts(first: 100) { + nodes { + ...BasePost + } + } + projects(first: 100) { + nodes { + ...BaseProject + } + } + works(first: 100) { + nodes { + ...BaseWork + } + } +} + ${BasePostFragmentDoc} +${BaseProjectFragmentDoc} +${BaseWorkFragmentDoc}`; export type SdkFunctionWrapper = (action: (requestHeaders?:Record) => Promise, operationName: string) => Promise; @@ -9399,6 +9425,9 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = }, PostsOne(variables: GQLPostsOneQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { return withWrapper((wrappedRequestHeaders) => client.request(PostsOneDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'PostsOne'); + }, + Search(variables?: GQLSearchQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { + return withWrapper((wrappedRequestHeaders) => client.request(SearchDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'Search'); } }; } diff --git a/src/lib/gql/root.graphql b/src/lib/gql/root.graphql index eb50de3..5dd47b4 100644 --- a/src/lib/gql/root.graphql +++ b/src/lib/gql/root.graphql @@ -125,3 +125,21 @@ query PostsOne($slug: ID!) { ...BasePost } } + +query Search { + posts(first: 100) { + nodes { + ...BasePost + } + } + projects(first: 100) { + nodes { + ...BaseProject + } + } + works(first: 100) { + nodes { + ...BaseWork + } + } +} diff --git a/src/routes/api/search.json.ts b/src/routes/api/search.json.ts index 2985592..c7a5cd2 100644 --- a/src/routes/api/search.json.ts +++ b/src/routes/api/search.json.ts @@ -1,51 +1,29 @@ +import { SDK } from '$lib/gql' +import type { GQLBasePageFragment } from '$lib/gql/gen' import lunr from 'lunr' -// import { BaseAttributes, Call, gql, Page } from '$lib/api' -// function removeHTML(s: string) { -// return s.replace(/<.*?>|\s+|&#\d+;/g, ' ').trim() -// } +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>(gql` -// query { -// posts(first: 1000) { -// nodes { -// ${BaseAttributes} -// } -// } -// projects(first: 1000) { -// nodes { -// ${BaseAttributes} -// } -// } -// works(first: 1000) { -// nodes { -// ${BaseAttributes} -// } -// } -// } -// `) -// return all -// } +function convertForIdx(type: string, items: GQLBasePageFragment[]) { + const keys: (keyof GQLBasePageFragment)[] = ['title', 'content', 'slug'] + return items.map((item) => ({ + url: `${type}/${item.slug}`, + data: keys.map((field) => removeHTML(item[field] ?? '')).join(' '), + })) +} export const get = async () => { - // const all = await getAll() - // const converted = Object.entries(all) - // .map(([type, data]) => convertForIdx(type, data.nodes)) - // .flat() + const { __typename, ...all } = await SDK.Search() + 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)) + converted.forEach((doc) => this.add(doc)) }) return { body: idx } diff --git a/src/routes/search.svelte b/src/routes/search.svelte index 9fff572..3adf416 100644 --- a/src/routes/search.svelte +++ b/src/routes/search.svelte @@ -21,6 +21,7 @@ export let prebuilt: any let needle: string | null = null let results: SearchResultItem[] = [] + let input: HTMLInputElement const idx = lunr.Index.load(prebuilt) @@ -34,7 +35,7 @@ } } - $: if (needle) { + $: if (needle !== null) { if (typeof window !== 'undefined') { window.history.replaceState(null, '', `/search?q=${needle ?? ''}`) } @@ -43,19 +44,18 @@ onMount(() => { needle = new URLSearchParams(window.location.search).get('q') + input.focus() }) - + {#if needle}
    {#each results as result (result.ref)} {/each}
- {:else} -

Start typing...

{/if}