prompt.ts 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import { create } from "zustand";
  2. import { persist } from "zustand/middleware";
  3. import JsSearch from "js-search";
  4. export interface Prompt {
  5. id?: number;
  6. shortcut: string;
  7. title: string;
  8. content: string;
  9. }
  10. export interface PromptStore {
  11. latestId: number;
  12. prompts: Map<number, Prompt>;
  13. add: (prompt: Prompt) => number;
  14. remove: (id: number) => void;
  15. search: (text: string) => Prompt[];
  16. }
  17. export const PROMPT_KEY = "prompt-store";
  18. export const SearchService = {
  19. ready: false,
  20. progress: 0, // 0 - 1, 1 means ready
  21. engine: new JsSearch.Search("prompts"),
  22. deleted: new Set<number>(),
  23. async init(prompts: PromptStore["prompts"]) {
  24. this.engine.addIndex("id");
  25. this.engine.addIndex("shortcut");
  26. this.engine.addIndex("title");
  27. const n = prompts.size;
  28. let count = 0;
  29. for await (const prompt of prompts.values()) {
  30. this.engine.addDocument(prompt);
  31. count += 1;
  32. this.progress = count / n;
  33. }
  34. this.ready = true;
  35. },
  36. remove(id: number) {
  37. this.deleted.add(id);
  38. },
  39. add(prompt: Prompt) {
  40. this.engine.addDocument(prompt);
  41. },
  42. search(text: string) {
  43. const results = this.engine.search(text) as Prompt[];
  44. return results.filter((v) => !v.id || !this.deleted.has(v.id));
  45. },
  46. };
  47. export const usePromptStore = create<PromptStore>()(
  48. persist(
  49. (set, get) => ({
  50. latestId: 0,
  51. prompts: new Map(),
  52. add(prompt) {
  53. const prompts = get().prompts;
  54. prompt.id = get().latestId + 1;
  55. prompts.set(prompt.id, prompt);
  56. set(() => ({
  57. latestId: prompt.id!,
  58. prompts: prompts,
  59. }));
  60. return prompt.id!;
  61. },
  62. remove(id) {
  63. const prompts = get().prompts;
  64. prompts.delete(id);
  65. SearchService.remove(id);
  66. set(() => ({
  67. prompts,
  68. }));
  69. },
  70. search(text) {
  71. return SearchService.search(text) as Prompt[];
  72. },
  73. }),
  74. {
  75. name: PROMPT_KEY,
  76. version: 1,
  77. }
  78. )
  79. );