feat: #920 migrate id to nanoid

This commit is contained in:
Yidadaa
2023-07-09 19:37:42 +08:00
parent 98ac7ee277
commit 8e4743e719
14 changed files with 189 additions and 92 deletions

View File

@@ -16,18 +16,19 @@ import { api, RequestMessage } from "../client/api";
import { ChatControllerPool } from "../client/controller";
import { prettyObject } from "../utils/format";
import { estimateTokenLength } from "../utils/token";
import { nanoid } from "nanoid";
export type ChatMessage = RequestMessage & {
date: string;
streaming?: boolean;
isError?: boolean;
id?: number;
id: string;
model?: ModelType;
};
export function createMessage(override: Partial<ChatMessage>): ChatMessage {
return {
id: Date.now(),
id: nanoid(),
date: new Date().toLocaleString(),
role: "user",
content: "",
@@ -42,7 +43,7 @@ export interface ChatStat {
}
export interface ChatSession {
id: number;
id: string;
topic: string;
memoryPrompt: string;
@@ -63,7 +64,7 @@ export const BOT_HELLO: ChatMessage = createMessage({
function createEmptySession(): ChatSession {
return {
id: Date.now() + Math.random(),
id: nanoid(),
topic: DEFAULT_TOPIC,
memoryPrompt: "",
messages: [],
@@ -82,7 +83,6 @@ function createEmptySession(): ChatSession {
interface ChatStore {
sessions: ChatSession[];
currentSessionIndex: number;
globalId: number;
clearSessions: () => void;
moveSession: (from: number, to: number) => void;
selectSession: (index: number) => void;
@@ -139,7 +139,6 @@ export const useChatStore = create<ChatStore>()(
(set, get) => ({
sessions: [createEmptySession()],
currentSessionIndex: 0,
globalId: 0,
clearSessions() {
set(() => ({
@@ -182,9 +181,6 @@ export const useChatStore = create<ChatStore>()(
newSession(mask) {
const session = createEmptySession();
set(() => ({ globalId: get().globalId + 1 }));
session.id = get().globalId;
if (mask) {
const config = useAppConfig.getState();
const globalModelConfig = config.modelConfig;
@@ -300,7 +296,6 @@ export const useChatStore = create<ChatStore>()(
// get recent messages
const recentMessages = get().getMessagesWithMemory();
const sendMessages = recentMessages.concat(userMessage);
const sessionIndex = get().currentSessionIndex;
const messageIndex = get().currentSession().messages.length + 1;
// save user's and bot's message
@@ -334,10 +329,7 @@ export const useChatStore = create<ChatStore>()(
botMessage.content = message;
get().onNewMessage(botMessage);
}
ChatControllerPool.remove(
sessionIndex,
botMessage.id ?? messageIndex,
);
ChatControllerPool.remove(session.id, botMessage.id);
},
onError(error) {
const isAborted = error.message.includes("aborted");
@@ -354,7 +346,7 @@ export const useChatStore = create<ChatStore>()(
session.messages = session.messages.concat();
});
ChatControllerPool.remove(
sessionIndex,
session.id,
botMessage.id ?? messageIndex,
);
@@ -363,7 +355,7 @@ export const useChatStore = create<ChatStore>()(
onController(controller) {
// collect controller for stop/retry
ChatControllerPool.addController(
sessionIndex,
session.id,
botMessage.id ?? messageIndex,
controller,
);
@@ -556,11 +548,13 @@ export const useChatStore = create<ChatStore>()(
modelConfig.sendMemory
) {
api.llm.chat({
messages: toBeSummarizedMsgs.concat({
role: "system",
content: Locale.Store.Prompt.Summarize,
date: "",
}),
messages: toBeSummarizedMsgs.concat(
createMessage({
role: "system",
content: Locale.Store.Prompt.Summarize,
date: "",
}),
),
config: { ...modelConfig, stream: true },
onUpdate(message) {
session.memoryPrompt = message;
@@ -597,13 +591,12 @@ export const useChatStore = create<ChatStore>()(
}),
{
name: StoreKey.Chat,
version: 2,
version: 3,
migrate(persistedState, version) {
const state = persistedState as any;
const newState = JSON.parse(JSON.stringify(state)) as ChatStore;
if (version < 2) {
newState.globalId = 0;
newState.sessions = [];
const oldSessions = state.sessions;
@@ -618,6 +611,14 @@ export const useChatStore = create<ChatStore>()(
}
}
if (version < 3) {
// migrate id to nanoid
newState.sessions.forEach((s) => {
s.id = nanoid();
s.messages.forEach((m) => (m.id = nanoid()));
});
}
return newState;
},
},

View File

@@ -5,9 +5,11 @@ import { getLang, Lang } from "../locales";
import { DEFAULT_TOPIC, ChatMessage } from "./chat";
import { ModelConfig, useAppConfig } from "./config";
import { StoreKey } from "../constant";
import { nanoid } from "nanoid";
export type Mask = {
id: number;
id: string;
createdAt: number;
avatar: string;
name: string;
hideContext?: boolean;
@@ -19,25 +21,23 @@ export type Mask = {
};
export const DEFAULT_MASK_STATE = {
masks: {} as Record<number, Mask>,
globalMaskId: 0,
masks: {} as Record<string, Mask>,
};
export type MaskState = typeof DEFAULT_MASK_STATE;
type MaskStore = MaskState & {
create: (mask?: Partial<Mask>) => Mask;
update: (id: number, updater: (mask: Mask) => void) => void;
delete: (id: number) => void;
update: (id: string, updater: (mask: Mask) => void) => void;
delete: (id: string) => void;
search: (text: string) => Mask[];
get: (id?: number) => Mask | null;
get: (id?: string) => Mask | null;
getAll: () => Mask[];
};
export const DEFAULT_MASK_ID = 1145141919810;
export const DEFAULT_MASK_AVATAR = "gpt-bot";
export const createEmptyMask = () =>
({
id: DEFAULT_MASK_ID,
id: nanoid(),
avatar: DEFAULT_MASK_AVATAR,
name: DEFAULT_TOPIC,
context: [],
@@ -45,6 +45,7 @@ export const createEmptyMask = () =>
modelConfig: { ...useAppConfig.getState().modelConfig },
lang: getLang(),
builtin: false,
createdAt: Date.now(),
} as Mask);
export const useMaskStore = create<MaskStore>()(
@@ -53,9 +54,8 @@ export const useMaskStore = create<MaskStore>()(
...DEFAULT_MASK_STATE,
create(mask) {
set(() => ({ globalMaskId: get().globalMaskId + 1 }));
const id = get().globalMaskId;
const masks = get().masks;
const id = nanoid();
masks[id] = {
...createEmptyMask(),
...mask,
@@ -87,7 +87,7 @@ export const useMaskStore = create<MaskStore>()(
},
getAll() {
const userMasks = Object.values(get().masks).sort(
(a, b) => b.id - a.id,
(a, b) => b.createdAt - a.createdAt,
);
const config = useAppConfig.getState();
if (config.hideBuiltinMasks) return userMasks;
@@ -109,7 +109,18 @@ export const useMaskStore = create<MaskStore>()(
}),
{
name: StoreKey.Mask,
version: 2,
version: 3,
migrate(state, version) {
const newState = JSON.parse(JSON.stringify(state)) as MaskState;
// migrate mask id to nanoid
if (version < 3) {
Object.values(newState.masks).forEach((m) => (m.id = nanoid()));
}
return newState as any;
},
},
),
);

View File

@@ -3,24 +3,25 @@ import { persist } from "zustand/middleware";
import Fuse from "fuse.js";
import { getLang } from "../locales";
import { StoreKey } from "../constant";
import { nanoid } from "nanoid";
export interface Prompt {
id?: number;
id: string;
isUser?: boolean;
title: string;
content: string;
createdAt: number;
}
export interface PromptStore {
counter: number;
latestId: number;
prompts: Record<number, Prompt>;
prompts: Record<string, Prompt>;
add: (prompt: Prompt) => number;
get: (id: number) => Prompt | undefined;
remove: (id: number) => void;
add: (prompt: Prompt) => string;
get: (id: string) => Prompt | undefined;
remove: (id: string) => void;
search: (text: string) => Prompt[];
update: (id: number, updater: (prompt: Prompt) => void) => void;
update: (id: string, updater: (prompt: Prompt) => void) => void;
getUserPrompts: () => Prompt[];
}
@@ -46,7 +47,7 @@ export const SearchService = {
this.ready = true;
},
remove(id: number) {
remove(id: string) {
this.userEngine.remove((doc) => doc.id === id);
},
@@ -70,8 +71,9 @@ export const usePromptStore = create<PromptStore>()(
add(prompt) {
const prompts = get().prompts;
prompt.id = get().latestId + 1;
prompt.id = nanoid();
prompt.isUser = true;
prompt.createdAt = Date.now();
prompts[prompt.id] = prompt;
set(() => ({
@@ -105,11 +107,13 @@ export const usePromptStore = create<PromptStore>()(
getUserPrompts() {
const userPrompts = Object.values(get().prompts ?? {});
userPrompts.sort((a, b) => (b.id && a.id ? b.id - a.id : 0));
userPrompts.sort((a, b) =>
b.id && a.id ? b.createdAt - a.createdAt : 0,
);
return userPrompts;
},
update(id: number, updater) {
update(id, updater) {
const prompt = get().prompts[id] ?? {
title: "",
content: "",
@@ -134,7 +138,18 @@ export const usePromptStore = create<PromptStore>()(
}),
{
name: StoreKey.Prompt,
version: 1,
version: 3,
migrate(state, version) {
const newState = JSON.parse(JSON.stringify(state)) as PromptStore;
if (version < 3) {
Object.values(newState.prompts).forEach((p) => (p.id = nanoid()));
}
return newState;
},
onRehydrateStorage(state) {
const PROMPT_URL = "./prompts.json";
@@ -152,9 +167,10 @@ export const usePromptStore = create<PromptStore>()(
return promptList.map(
([title, content]) =>
({
id: Math.random(),
id: nanoid(),
title,
content,
createdAt: Date.now(),
} as Prompt),
);
},