prompt.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import Fuse from "fuse.js";
  2. import { getLang } from "../locales";
  3. import { StoreKey } from "../constant";
  4. import { nanoid } from "nanoid";
  5. import { createPersistStore } from "../utils/store";
  6. export interface Prompt {
  7. id: string;
  8. isUser?: boolean;
  9. title: string;
  10. content: string;
  11. createdAt: number;
  12. }
  13. export const SearchService = {
  14. ready: false,
  15. userEngine: new Fuse<Prompt>([], {keys: [ "title" ]}),
  16. allPrompts: [] as Prompt[],
  17. init(builtinPrompts: Prompt[], userPrompts: Prompt[]) {
  18. if ( this.ready ) {
  19. return;
  20. }
  21. // 移除内置提示词支持,仅使用用户提示词
  22. this.allPrompts = userPrompts;
  23. this.userEngine.setCollection(userPrompts);
  24. this.ready = true;
  25. },
  26. remove(id: string) {
  27. this.userEngine.remove((doc) => doc.id === id);
  28. },
  29. add(prompt: Prompt) {
  30. this.userEngine.add(prompt);
  31. },
  32. search(text: string) {
  33. const userResults = this.userEngine.search(text);
  34. return userResults.map((v) => v.item);
  35. },
  36. };
  37. export const usePromptStore = createPersistStore(
  38. {
  39. counter: 0,
  40. prompts: {} as Record<string, Prompt>,
  41. },
  42. (set, get) => ({
  43. add(prompt: Prompt) {
  44. const prompts = get().prompts;
  45. prompt.id = nanoid();
  46. prompt.isUser = true;
  47. prompt.createdAt = Date.now();
  48. prompts[prompt.id] = prompt;
  49. set(() => ({
  50. prompts: prompts,
  51. }));
  52. return prompt.id!;
  53. },
  54. get(id: string) {
  55. const targetPrompt = get().prompts[id];
  56. return targetPrompt;
  57. },
  58. remove(id: string) {
  59. const prompts = get().prompts;
  60. delete prompts[id];
  61. Object.entries(prompts).some(([ key, prompt ]) => {
  62. if ( prompt.id === id ) {
  63. delete prompts[key];
  64. return true;
  65. }
  66. return false;
  67. });
  68. SearchService.remove(id);
  69. set(() => ({
  70. prompts,
  71. counter: get().counter + 1,
  72. }));
  73. },
  74. getUserPrompts() {
  75. const userPrompts = Object.values(get().prompts ?? {});
  76. userPrompts.sort((a, b) =>
  77. b.id && a.id ? b.createdAt - a.createdAt : 0,
  78. );
  79. return userPrompts;
  80. },
  81. updatePrompt(id: string, updater: (prompt: Prompt) => void) {
  82. const prompt = get().prompts[id] ?? {
  83. title: "",
  84. content: "",
  85. id,
  86. };
  87. SearchService.remove(id);
  88. updater(prompt);
  89. const prompts = get().prompts;
  90. prompts[id] = prompt;
  91. set(() => ({prompts}));
  92. SearchService.add(prompt);
  93. },
  94. search(text: string) {
  95. if ( text.length === 0 ) {
  96. // 仅返回用户提示词
  97. return this.getUserPrompts();
  98. }
  99. return SearchService.search(text) as Prompt[];
  100. },
  101. }),
  102. {
  103. name: StoreKey.Prompt,
  104. version: 3,
  105. migrate(state, version) {
  106. const newState = JSON.parse(JSON.stringify(state)) as {
  107. prompts: Record<string, Prompt>;
  108. };
  109. if ( version < 3 ) {
  110. Object.values(newState.prompts).forEach((p) => (p.id = nanoid()));
  111. }
  112. return newState as any;
  113. },
  114. onRehydrateStorage(state) {
  115. // ==============
  116. // 移除 prompts.json 自动加载
  117. // 说明:不再从前端控制提示词配置,移除内置提示词系统
  118. // ==============
  119. return (state) => {
  120. // 使用回调中的 state 参数获取用户提示词
  121. const userPrompts = state ? Object.values(state.prompts ?? {}).sort((a, b) =>
  122. b.id && a.id ? b.createdAt - a.createdAt : 0
  123. ) : [];
  124. // 仅使用用户自定义提示词,不加载内置提示词
  125. SearchService.init([], userPrompts);
  126. };
  127. },
  128. },
  129. );