feat: Add search functionality for documents
This commit is contained in:
parent
66bd48e55e
commit
9526b1ae9d
@ -12,7 +12,6 @@ import { Dialog, DialogPanel } from "terracotta";
|
|||||||
import { useDebounce } from "@/hooks/useDebounce";
|
import { useDebounce } from "@/hooks/useDebounce";
|
||||||
import { Highlighter } from "solid-highlight-words";
|
import { Highlighter } from "solid-highlight-words";
|
||||||
import { navigate } from "vike/client/router";
|
import { navigate } from "vike/client/router";
|
||||||
import { onSearch } from "./Search.telefunc";
|
|
||||||
import { useId } from "@/hooks/useId";
|
import { useId } from "@/hooks/useId";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
|
||||||
@ -270,6 +269,15 @@ export function Search() {
|
|||||||
|
|
||||||
const debouncedQuery = useDebounce(query, 300);
|
const debouncedQuery = useDebounce(query, 300);
|
||||||
|
|
||||||
|
const onSearch = async (query: string) => {
|
||||||
|
const response = await fetch(`/search?query=${query}`);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Network response was not ok");
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
const platform = navigator.userAgentData?.platform || navigator.platform;
|
const platform = navigator.userAgentData?.platform || navigator.platform;
|
||||||
setModifierKey(/(Mac|iPhone|iPod|iPad)/i.test(platform) ? "⌘" : "Ctrl ");
|
setModifierKey(/(Mac|iPhone|iPod|iPad)/i.test(platform) ? "⌘" : "Ctrl ");
|
||||||
@ -288,9 +296,7 @@ export function Search() {
|
|||||||
|
|
||||||
onSearch(query)
|
onSearch(query)
|
||||||
.then(setResults)
|
.then(setResults)
|
||||||
.finally(() => {
|
.finally(() => setIsLoading(false));
|
||||||
setIsLoading(false);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -2,15 +2,14 @@ import type { readingTime } from "reading-time-estimator";
|
|||||||
import type { TableOfContents } from "./remarkHeadingId";
|
import type { TableOfContents } from "./remarkHeadingId";
|
||||||
|
|
||||||
import { createHandler } from "@universal-middleware/fastify";
|
import { createHandler } from "@universal-middleware/fastify";
|
||||||
import { telefuncHandler } from "./server/telefunc-handler";
|
|
||||||
import { vikeHandler } from "./server/vike-handler";
|
import { vikeHandler } from "./server/vike-handler";
|
||||||
import { createDevMiddleware } from "vike/server";
|
import { createDevMiddleware } from "vike/server";
|
||||||
import { docCache } from "./services/DocCache";
|
import { docCache } from "./services/DocCache";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
|
import { search } from "./libs/search";
|
||||||
import { dirname } from "node:path";
|
import { dirname } from "node:path";
|
||||||
import { config } from "./config";
|
import { config } from "./config";
|
||||||
import Fastify from "fastify";
|
import Fastify from "fastify";
|
||||||
import { buildFlexSearch } from "./services/FlexSearchService";
|
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
@ -60,7 +59,17 @@ async function startServer() {
|
|||||||
app.use(devMiddleware);
|
app.use(devMiddleware);
|
||||||
}
|
}
|
||||||
|
|
||||||
app.post<{ Body: string }>("/_telefunc", createHandler(telefuncHandler)());
|
app.get("/search", async (request, reply) => {
|
||||||
|
const { query } = request.query as { query: string };
|
||||||
|
if (!query) {
|
||||||
|
reply.status(400).send("Query parameter is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = search(query);
|
||||||
|
|
||||||
|
reply.status(200).send(results);
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vike route
|
* Vike route
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
|
import { search } from "./libs/search";
|
||||||
import { dirname } from "node:path";
|
import { dirname } from "node:path";
|
||||||
import { config } from "./config";
|
import { config } from "./config";
|
||||||
import Fastify from "fastify";
|
import Fastify from "fastify";
|
||||||
@ -31,6 +32,18 @@ async function startServer() {
|
|||||||
reply.type("text/html").send(stream);
|
reply.type("text/html").send(stream);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.get("/search", async (request, reply) => {
|
||||||
|
const { query } = request.query as { query: string };
|
||||||
|
if (!query) {
|
||||||
|
reply.status(400).send("Query parameter is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = search(query);
|
||||||
|
|
||||||
|
reply.status(200).send(results);
|
||||||
|
});
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,3 +57,5 @@ app.listen({ port: config.PORT, host: "0.0.0.0" }, (error, address) => {
|
|||||||
|
|
||||||
console.log(`Server listening on ${address}`);
|
console.log(`Server listening on ${address}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default app;
|
||||||
|
|||||||
9
app/libs/search.ts
Normal file
9
app/libs/search.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { buildFlexSearch } from "@/services/FlexSearchService";
|
||||||
|
import { docCache } from "@/services/DocCache";
|
||||||
|
|
||||||
|
export function search(query: string) {
|
||||||
|
const docs = docCache.fetchDocs();
|
||||||
|
const search = buildFlexSearch(docs);
|
||||||
|
|
||||||
|
return search(query, 5);
|
||||||
|
}
|
||||||
@ -23,5 +23,5 @@ export default {
|
|||||||
|
|
||||||
prerender: true,
|
prerender: true,
|
||||||
|
|
||||||
extends: vikeSolid,
|
extends: [vikeSolid],
|
||||||
} satisfies Config;
|
} satisfies Config;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user