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

97 lines
2.0 KiB
TypeScript
Raw Normal View History

2023-03-27 16:30:12 +00:00
import { create } from "zustand";
import { persist } from "zustand/middleware";
import JsSearch from "js-search";
export interface Prompt {
id?: number;
shortcut: string;
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,
progress: 0, // 0 - 1, 1 means ready
engine: new JsSearch.Search("prompts"),
deleted: new Set<number>(),
async init(prompts: PromptStore["prompts"]) {
this.engine.addIndex("id");
this.engine.addIndex("shortcut");
this.engine.addIndex("title");
const n = prompts.size;
let count = 0;
for await (const prompt of prompts.values()) {
this.engine.addDocument(prompt);
count += 1;
this.progress = count / n;
}
this.ready = true;
},
remove(id: number) {
this.deleted.add(id);
},
add(prompt: Prompt) {
this.engine.addDocument(prompt);
},
search(text: string) {
const results = this.engine.search(text) as Prompt[];
return results.filter((v) => !v.id || !this.deleted.has(v.id));
},
};
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) {
return SearchService.search(text) as Prompt[];
},
}),
{
name: PROMPT_KEY,
version: 1,
}
)
);