mirror of
https://github.com/LukeHagar/unicorn-utterances.git
synced 2025-12-06 04:21:55 +00:00
fix search api imports, move unicornProfilePicMap to json fetch
This commit is contained in:
1
api/.gitignore
vendored
Normal file
1
api/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
searchIndex.json
|
||||||
1936
api/package-lock.json
generated
Normal file
1936
api/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
10
api/package.json
Normal file
10
api/package.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "unicorn-utterances-api",
|
||||||
|
"type": "module",
|
||||||
|
"devDependencies": {
|
||||||
|
"@vercel/node": "^2.9.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"fuse.js": "^6.6.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,19 +1,16 @@
|
|||||||
import type { VercelRequest, VercelResponse } from "@vercel/node";
|
import type { VercelRequest, VercelResponse } from "@vercel/node";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
import exportedIndex from "../public/searchIndex";
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
import unicornProfilePicMap from "../public/unicorn-profile-pic-map";
|
|
||||||
import Fuse from "fuse.js";
|
import Fuse from "fuse.js";
|
||||||
import type { PostInfo } from "../src/types/PostInfo";
|
import { createRequire } from "node:module";
|
||||||
|
|
||||||
const myIndex = Fuse.parseIndex(exportedIndex.index);
|
import type { PostInfo } from "types/PostInfo";
|
||||||
|
|
||||||
const posts = exportedIndex.posts;
|
const require = createRequire(import.meta.url);
|
||||||
|
const searchIndex = require("./searchIndex.json");
|
||||||
|
const index = Fuse.parseIndex(searchIndex.index);
|
||||||
|
|
||||||
const fuse = new Fuse(
|
const posts = searchIndex.posts;
|
||||||
|
|
||||||
|
const fuse = new Fuse<PostInfo>(
|
||||||
posts,
|
posts,
|
||||||
{
|
{
|
||||||
threshold: 0.3,
|
threshold: 0.3,
|
||||||
@@ -21,26 +18,18 @@ const fuse = new Fuse(
|
|||||||
includeScore: true,
|
includeScore: true,
|
||||||
ignoreFieldNorm: true,
|
ignoreFieldNorm: true,
|
||||||
},
|
},
|
||||||
myIndex
|
index
|
||||||
);
|
);
|
||||||
|
|
||||||
const unicornProfilePicObj = {};
|
|
||||||
for (const picMapItem of unicornProfilePicMap) {
|
|
||||||
unicornProfilePicObj[picMapItem.id] = picMapItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async (req: VercelRequest, res: VercelResponse) => {
|
export default async (req: VercelRequest, res: VercelResponse) => {
|
||||||
// TODO: `pickdeep` only required fields
|
// TODO: `pickdeep` only required fields
|
||||||
const searchStr = req?.query?.query as string;
|
const searchStr = req?.query?.query as string;
|
||||||
const authorStr = req?.query?.authorId as string;
|
const authorStr = req?.query?.authorId as string;
|
||||||
if (!searchStr) return [];
|
if (!searchStr) return [];
|
||||||
if (Array.isArray(searchStr)) return [];
|
if (Array.isArray(searchStr)) return [];
|
||||||
let posts = fuse.search(searchStr).map((item) => item.item as PostInfo);
|
let posts = fuse.search(searchStr).map((item) => item.item);
|
||||||
if (authorStr) {
|
if (authorStr) {
|
||||||
posts = posts.filter((post) => post.authors.includes(authorStr));
|
posts = posts.filter((post) => post.authors.includes(authorStr));
|
||||||
}
|
}
|
||||||
const unicornProfilePicMap = posts.flatMap((post) =>
|
res.send({ posts, totalPosts: posts.length });
|
||||||
post.authorsMeta.map((authorMeta) => unicornProfilePicObj[authorMeta.id])
|
|
||||||
);
|
|
||||||
res.send({ posts, totalPosts: posts.length, unicornProfilePicMap });
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,13 +40,6 @@ export const createIndex = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
createIndex().then((index) => {
|
createIndex().then((index) => {
|
||||||
const js = `const index = {
|
const json = JSON.stringify({ index, posts });
|
||||||
index: ${JSON.stringify(index)},
|
fs.writeFileSync(path.resolve(process.cwd(), "./api/searchIndex.json"), json);
|
||||||
posts: ${JSON.stringify(posts)}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default index;
|
|
||||||
`;
|
|
||||||
|
|
||||||
fs.writeFileSync(path.resolve(process.cwd(), "./public/searchIndex.js"), js);
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
"format": "prettier -w . --cache --plugin-search-dir=.",
|
"format": "prettier -w . --cache --plugin-search-dir=.",
|
||||||
"lint": "eslint . --ext .js,.ts,.astro",
|
"lint": "eslint . --ext .js,.ts,.astro",
|
||||||
"search-index": "tsx build-scripts/search-index.ts",
|
"search-index": "tsx build-scripts/search-index.ts",
|
||||||
"social-previews:prebuild": "tsc -p tsconfig.script.json",
|
"social-previews:prebuild": "tsc -p tsconfig.script.json",
|
||||||
"social-previews:build": "npm run social-previews:prebuild && node node_modules/puppeteer-core/install.js && tsx --tsconfig tsconfig.script.json build-scripts/social-previews/index.ts",
|
"social-previews:build": "npm run social-previews:prebuild && node node_modules/puppeteer-core/install.js && tsx --tsconfig tsconfig.script.json build-scripts/social-previews/index.ts",
|
||||||
"social-previews:dev": "npm run social-previews:prebuild && tsx --tsconfig tsconfig.script.json build-scripts/social-previews/live-server.ts",
|
"social-previews:dev": "npm run social-previews:prebuild && tsx --tsconfig tsconfig.script.json build-scripts/social-previews/live-server.ts",
|
||||||
"epub": "tsx --tsconfig tsconfig.script.json build-scripts/generate-epubs.ts",
|
"epub": "tsx --tsconfig tsconfig.script.json build-scripts/generate-epubs.ts",
|
||||||
|
|||||||
@@ -87,23 +87,21 @@ import SearchField from "./search-field/search-field.astro";
|
|||||||
{ signal: abortController.signal }
|
{ signal: abortController.signal }
|
||||||
)
|
)
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then(
|
.then(async (serverVal: { posts: PostInfo[]; totalPosts: number }) => {
|
||||||
(serverVal: {
|
const unicornProfilePicMap: ProfilePictureMap = await fetch(
|
||||||
posts: PostInfo[];
|
"/unicorns/unicornProfilePicMap.json",
|
||||||
totalPosts: number;
|
{ cache: "force-cache" }
|
||||||
unicornProfilePicMap: ProfilePictureMap;
|
).then((res) => res.json());
|
||||||
}) => {
|
const SearchCardHandler = createElement(SearchBarHandler, {
|
||||||
const SearchCardHandler = createElement(SearchBarHandler, {
|
unicornProfilePicMap,
|
||||||
unicornProfilePicMap: serverVal.unicornProfilePicMap,
|
posts: serverVal.posts,
|
||||||
posts: serverVal.posts,
|
totalPosts: serverVal.totalPosts,
|
||||||
totalPosts: serverVal.totalPosts,
|
});
|
||||||
});
|
render(SearchCardHandler, searchPostList);
|
||||||
render(SearchCardHandler, searchPostList);
|
loadingEl && loadingEl.remove();
|
||||||
loadingEl && loadingEl.remove();
|
loadingEl = undefined;
|
||||||
loadingEl = undefined;
|
abortController = undefined;
|
||||||
abortController = undefined;
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const debounceDoSearch = debounce(doSearch, 1000, false);
|
const debounceDoSearch = debounce(doSearch, 1000, false);
|
||||||
|
|||||||
6
src/pages/unicorns/unicornProfilePicMap.json.ts
Normal file
6
src/pages/unicorns/unicornProfilePicMap.json.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { getUnicornProfilePicMap } from "utils/get-unicorn-profile-pic-map";
|
||||||
|
|
||||||
|
export const get = async () => {
|
||||||
|
const unicornProfilePicMap = await getUnicornProfilePicMap();
|
||||||
|
return { body: JSON.stringify(unicornProfilePicMap) };
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user