ChatGPT-Next-Web/app/store/prompt.ts

129 lines
3.0 KiB
TypeScript
Raw Normal View History

2023-03-27 16:30:12 +00:00
import { create } from "zustand";
import { persist } from "zustand/middleware";
2023-03-28 17:30:11 +00:00
import Fuse from "fuse.js";
import { getLang } from "../locales";
2023-03-27 16:30:12 +00:00
export interface Prompt {
id?: number;
title: string;
content: string;
}
export interface PromptStore {
latestId: number;
prompts: Map<number, Prompt>;
add: (prompt: Prompt) => number;
remove: (id: number) => void;
search: (text: string) => Prompt[];
}
export const PROMPT_KEY = "prompt-store";
export const SearchService = {
ready: false,
2023-03-28 17:30:11 +00:00
engine: new Fuse<Prompt>([], { keys: ["title"] }),
count: {
builtin: 0,
},
allBuiltInPrompts: [] as Prompt[],
2023-03-28 17:30:11 +00:00
init(prompts: Prompt[]) {
if (this.ready) {
return;
2023-03-27 16:30:12 +00:00
}
this.allBuiltInPrompts = prompts;
2023-03-28 17:30:11 +00:00
this.engine.setCollection(prompts);
2023-03-27 16:30:12 +00:00
this.ready = true;
},
remove(id: number) {
2023-03-28 17:30:11 +00:00
this.engine.remove((doc) => doc.id === id);
2023-03-27 16:30:12 +00:00
},
add(prompt: Prompt) {
2023-03-28 17:30:11 +00:00
this.engine.add(prompt);
2023-03-27 16:30:12 +00:00
},
search(text: string) {
2023-03-28 17:30:11 +00:00
const results = this.engine.search(text);
return results.map((v) => v.item);
2023-03-27 16:30:12 +00:00
},
};
export const usePromptStore = create<PromptStore>()(
persist(
(set, get) => ({
latestId: 0,
prompts: new Map(),
add(prompt) {
const prompts = get().prompts;
prompt.id = get().latestId + 1;
prompts.set(prompt.id, prompt);
set(() => ({
latestId: prompt.id!,
prompts: prompts,
}));
return prompt.id!;
},
remove(id) {
const prompts = get().prompts;
prompts.delete(id);
SearchService.remove(id);
set(() => ({
prompts,
}));
},
search(text) {
if (text.length === 0) {
// return all prompts
const userPrompts = get().prompts?.values?.() ?? [];
return SearchService.allBuiltInPrompts.concat([...userPrompts]);
}
2023-03-27 16:30:12 +00:00
return SearchService.search(text) as Prompt[];
},
}),
{
name: PROMPT_KEY,
version: 1,
2023-03-28 17:30:11 +00:00
onRehydrateStorage(state) {
const PROMPT_URL = "./prompts.json";
type PromptList = Array<[string, string]>;
fetch(PROMPT_URL)
.then((res) => res.json())
.then((res) => {
let fetchPrompts = [res.en, res.cn];
if (getLang() === "cn") {
fetchPrompts = fetchPrompts.reverse();
}
const builtinPrompts = fetchPrompts
2023-03-28 17:30:11 +00:00
.map((promptList: PromptList) => {
return promptList.map(
([title, content]) =>
({
title,
content,
} as Prompt),
2023-03-28 17:30:11 +00:00
);
})
.concat([...(state?.prompts?.values() ?? [])]);
2023-04-16 10:11:09 +00:00
const allPromptsForSearch = builtinPrompts
.reduce((pre, cur) => pre.concat(cur), [])
.filter((v) => !!v.title && !!v.content);
2023-03-28 17:30:11 +00:00
SearchService.count.builtin = res.en.length + res.cn.length;
SearchService.init(allPromptsForSearch);
});
},
},
),
2023-03-27 16:30:12 +00:00
);