@lobehub/chat 1.36.46 → 1.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/README.ja-JP.md +8 -8
- package/README.md +8 -8
- package/README.zh-CN.md +8 -8
- package/changelog/v1.json +18 -0
- package/next.config.mjs +4 -1
- package/package.json +5 -3
- package/scripts/migrateClientDB/compile-migrations.ts +14 -0
- package/src/app/(main)/(mobile)/me/(home)/layout.tsx +2 -0
- package/src/app/(main)/chat/_layout/Desktop/index.tsx +3 -2
- package/src/app/(main)/chat/_layout/Mobile.tsx +5 -3
- package/src/app/(main)/chat/features/Migration/DBReader.ts +290 -0
- package/src/app/(main)/chat/features/Migration/UpgradeButton.tsx +4 -8
- package/src/app/(main)/chat/features/Migration/index.tsx +26 -15
- package/src/app/(main)/settings/_layout/Desktop/index.tsx +2 -0
- package/src/app/loading/Client/Content.tsx +11 -1
- package/src/app/loading/Client/Error.tsx +27 -0
- package/src/app/loading/stage.ts +8 -0
- package/src/components/FullscreenLoading/index.tsx +4 -3
- package/src/const/version.ts +1 -0
- package/src/database/client/db.test.ts +172 -0
- package/src/database/client/db.ts +246 -0
- package/src/database/client/migrations.json +289 -0
- package/src/features/InitClientDB/EnableModal.tsx +111 -0
- package/src/features/InitClientDB/ErrorResult.tsx +125 -0
- package/src/features/InitClientDB/InitIndicator.tsx +124 -0
- package/src/features/InitClientDB/PGliteSVG.tsx +22 -0
- package/src/features/InitClientDB/index.tsx +37 -0
- package/src/hooks/useCheckPluginsIsInstalled.ts +2 -2
- package/src/hooks/useFetchInstalledPlugins.ts +2 -2
- package/src/hooks/useFetchMessages.ts +2 -2
- package/src/hooks/useFetchSessions.ts +2 -2
- package/src/hooks/useFetchThreads.ts +2 -2
- package/src/hooks/useFetchTopics.ts +2 -2
- package/src/layout/GlobalProvider/StoreInitialization.tsx +2 -2
- package/src/services/baseClientService/index.ts +9 -0
- package/src/services/debug.ts +32 -34
- package/src/services/file/{client.test.ts → _deprecated.test.ts} +1 -1
- package/src/services/file/index.ts +6 -2
- package/src/services/file/pglite.test.ts +198 -0
- package/src/services/file/pglite.ts +84 -0
- package/src/services/file/type.ts +4 -3
- package/src/services/github.ts +17 -0
- package/src/services/import/index.ts +6 -2
- package/src/services/import/pglite.test.ts +997 -0
- package/src/services/import/pglite.ts +34 -0
- package/src/services/message/{client.test.ts → _deprecated.test.ts} +1 -1
- package/src/services/message/{client.ts → _deprecated.ts} +2 -0
- package/src/services/message/index.ts +6 -2
- package/src/services/message/pglite.test.ts +430 -0
- package/src/services/message/pglite.ts +118 -0
- package/src/services/message/server.ts +9 -9
- package/src/services/message/type.ts +3 -4
- package/src/services/plugin/{client.test.ts → _deprecated.test.ts} +1 -1
- package/src/services/plugin/index.ts +6 -2
- package/src/services/plugin/pglite.test.ts +175 -0
- package/src/services/plugin/pglite.ts +51 -0
- package/src/services/session/{client.test.ts → _deprecated.test.ts} +1 -1
- package/src/services/session/{client.ts → _deprecated.ts} +1 -1
- package/src/services/session/index.ts +6 -2
- package/src/services/session/pglite.test.ts +411 -0
- package/src/services/session/pglite.ts +184 -0
- package/src/services/session/type.ts +14 -1
- package/src/services/topic/client.test.ts +1 -1
- package/src/services/topic/index.ts +6 -3
- package/src/services/topic/pglite.test.ts +212 -0
- package/src/services/topic/pglite.ts +85 -0
- package/src/services/user/{client.test.ts → _deprecated.test.ts} +1 -2
- package/src/services/user/index.ts +8 -2
- package/src/services/user/pglite.test.ts +98 -0
- package/src/services/user/pglite.ts +92 -0
- package/src/store/chat/slices/builtinTool/action.test.ts +4 -5
- package/src/store/global/actions/clientDb.ts +51 -0
- package/src/store/global/initialState.ts +13 -0
- package/src/store/global/selectors.ts +24 -3
- package/src/store/global/store.ts +3 -1
- package/src/store/session/slices/sessionGroup/reducer.test.ts +6 -6
- package/src/store/user/slices/common/action.test.ts +1 -1
- package/src/store/user/slices/common/action.ts +2 -4
- package/src/types/clientDB.ts +29 -0
- package/src/types/importer.ts +17 -5
- package/src/types/meta.ts +0 -9
- package/src/types/session/sessionGroup.ts +3 -3
- package/src/services/message/index.test.ts +0 -48
- /package/src/services/file/{client.ts → _deprecated.ts} +0 -0
- /package/src/services/import/{client.ts → _deprecated.ts} +0 -0
- /package/src/services/plugin/{client.ts → _deprecated.ts} +0 -0
- /package/src/services/topic/{client.ts → _deprecated.ts} +0 -0
- /package/src/services/user/{client.ts → _deprecated.ts} +0 -0
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,56 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.37.1](https://github.com/lobehub/lobe-chat/compare/v1.37.0...v1.37.1)
|
6
|
+
|
7
|
+
<sup>Released on **2024-12-22**</sup>
|
8
|
+
|
9
|
+
#### ♻ Code Refactoring
|
10
|
+
|
11
|
+
- **misc**: Refactor the client service to deprecated.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### Code refactoring
|
19
|
+
|
20
|
+
- **misc**: Refactor the client service to deprecated, closes [#5132](https://github.com/lobehub/lobe-chat/issues/5132) ([e603234](https://github.com/lobehub/lobe-chat/commit/e603234))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
30
|
+
## [Version 1.37.0](https://github.com/lobehub/lobe-chat/compare/v1.36.46...v1.37.0)
|
31
|
+
|
32
|
+
<sup>Released on **2024-12-22**</sup>
|
33
|
+
|
34
|
+
#### ✨ Features
|
35
|
+
|
36
|
+
- **misc**: Support to use pglite as client db.
|
37
|
+
|
38
|
+
<br/>
|
39
|
+
|
40
|
+
<details>
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
42
|
+
|
43
|
+
#### What's improved
|
44
|
+
|
45
|
+
- **misc**: Support to use pglite as client db, closes [#4873](https://github.com/lobehub/lobe-chat/issues/4873) ([4131f20](https://github.com/lobehub/lobe-chat/commit/4131f20))
|
46
|
+
|
47
|
+
</details>
|
48
|
+
|
49
|
+
<div align="right">
|
50
|
+
|
51
|
+
[](#readme-top)
|
52
|
+
|
53
|
+
</div>
|
54
|
+
|
5
55
|
### [Version 1.36.46](https://github.com/lobehub/lobe-chat/compare/v1.36.45...v1.36.46)
|
6
56
|
|
7
57
|
<sup>Released on **2024-12-21**</sup>
|
package/README.ja-JP.md
CHANGED
@@ -263,14 +263,14 @@ LobeChat のプラグインエコシステムは、そのコア機能の重要
|
|
263
263
|
|
264
264
|
<!-- PLUGIN LIST -->
|
265
265
|
|
266
|
-
| 最近追加 | 説明
|
267
|
-
| ------------------------------------------------------------------------------------------------------------------------------------ |
|
268
|
-
| [
|
269
|
-
| [
|
270
|
-
| [
|
271
|
-
| [
|
272
|
-
|
273
|
-
> 📊 Total plugins: [<kbd>**
|
266
|
+
| 最近追加 | 説明 |
|
267
|
+
| ------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
268
|
+
| [PortfolioMeta](https://lobechat.com/discover/plugin/StockData)<br/><sup>By **portfoliometa** on **2024-12-22**</sup> | 株を分析し、包括的なリアルタイムの投資データと分析を取得します。<br/>`stock` |
|
269
|
+
| [Google CSE](https://lobechat.com/discover/plugin/google-cse)<br/><sup>By **vsnthdev** on **2024-12-02**</sup> | 公式の CSE API を通じて Google を検索します。<br/>`ウェブ` `検索` |
|
270
|
+
| [話す](https://lobechat.com/discover/plugin/speak)<br/><sup>By **speak** on **2024-12-02**</sup> | Speak は、AI パワードの言語チューターで、他の言語で何でも言う方法を学ぶことができます。<br/>`教育` `言語` |
|
271
|
+
| [Tongyi Wanxiang 画像生成器](https://lobechat.com/discover/plugin/alps-tongyi-image)<br/><sup>By **YoungTx** on **2024-08-09**</sup> | このプラグインは、Alibaba の Tongyi Wanxiang モデルを使用して、テキストプロンプトに基づいて画像を生成します。<br/>`画像` `トンギ` `ワンシャン` |
|
272
|
+
|
273
|
+
> 📊 Total plugins: [<kbd>**48**</kbd>](https://lobechat.com/discover/plugins)
|
274
274
|
|
275
275
|
<!-- PLUGIN LIST -->
|
276
276
|
|
package/README.md
CHANGED
@@ -280,14 +280,14 @@ In addition, these plugins are not limited to news aggregation, but can also ext
|
|
280
280
|
|
281
281
|
<!-- PLUGIN LIST -->
|
282
282
|
|
283
|
-
| Recent Submits | Description
|
284
|
-
| ----------------------------------------------------------------------------------------------------------------------------------------- |
|
285
|
-
| [
|
286
|
-
| [
|
287
|
-
| [
|
288
|
-
| [
|
289
|
-
|
290
|
-
> 📊 Total plugins: [<kbd>**
|
283
|
+
| Recent Submits | Description |
|
284
|
+
| ----------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
285
|
+
| [PortfolioMeta](https://lobechat.com/discover/plugin/StockData)<br/><sup>By **portfoliometa** on **2024-12-22**</sup> | Analyze stocks and get comprehensive real-time investment data and analytics.<br/>`stock` |
|
286
|
+
| [Google CSE](https://lobechat.com/discover/plugin/google-cse)<br/><sup>By **vsnthdev** on **2024-12-02**</sup> | Searches Google through their official CSE API.<br/>`web` `search` |
|
287
|
+
| [Speak](https://lobechat.com/discover/plugin/speak)<br/><sup>By **speak** on **2024-12-02**</sup> | Learn how to say anything in another language with Speak, your AI-powered language tutor.<br/>`education` `language` |
|
288
|
+
| [Tongyi wanxiang Image Generator](https://lobechat.com/discover/plugin/alps-tongyi-image)<br/><sup>By **YoungTx** on **2024-08-09**</sup> | This plugin uses Alibaba's Tongyi Wanxiang model to generate images based on text prompts.<br/>`image` `tongyi` `wanxiang` |
|
289
|
+
|
290
|
+
> 📊 Total plugins: [<kbd>**48**</kbd>](https://lobechat.com/discover/plugins)
|
291
291
|
|
292
292
|
<!-- PLUGIN LIST -->
|
293
293
|
|
package/README.zh-CN.md
CHANGED
@@ -273,14 +273,14 @@ LobeChat 的插件生态系统是其核心功能的重要扩展,它极大地
|
|
273
273
|
|
274
274
|
<!-- PLUGIN LIST -->
|
275
275
|
|
276
|
-
| 最近新增 | 描述
|
277
|
-
| ---------------------------------------------------------------------------------------------------------------------------- |
|
278
|
-
| [
|
279
|
-
| [
|
280
|
-
| [
|
281
|
-
| [
|
282
|
-
|
283
|
-
> 📊 Total plugins: [<kbd>**
|
276
|
+
| 最近新增 | 描述 |
|
277
|
+
| ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
|
278
|
+
| [PortfolioMeta](https://lobechat.com/discover/plugin/StockData)<br/><sup>By **portfoliometa** on **2024-12-22**</sup> | 分析股票并获取全面的实时投资数据和分析。<br/>`股票` |
|
279
|
+
| [谷歌自定义搜索引擎](https://lobechat.com/discover/plugin/google-cse)<br/><sup>By **vsnthdev** on **2024-12-02**</sup> | 通过他们的官方自定义搜索引擎 API 搜索谷歌。<br/>`网络` `搜索` |
|
280
|
+
| [Speak](https://lobechat.com/discover/plugin/speak)<br/><sup>By **speak** on **2024-12-02**</sup> | 使用 Speak,您的 AI 语言导师,学习如何用另一种语言说任何事情。<br/>`教育` `语言` |
|
281
|
+
| [通义万象图像生成器](https://lobechat.com/discover/plugin/alps-tongyi-image)<br/><sup>By **YoungTx** on **2024-08-09**</sup> | 此插件使用阿里巴巴的通义万象模型根据文本提示生成图像。<br/>`图像` `通义` `万象` |
|
282
|
+
|
283
|
+
> 📊 Total plugins: [<kbd>**48**</kbd>](https://lobechat.com/discover/plugins)
|
284
284
|
|
285
285
|
<!-- PLUGIN LIST -->
|
286
286
|
|
package/changelog/v1.json
CHANGED
@@ -1,4 +1,22 @@
|
|
1
1
|
[
|
2
|
+
{
|
3
|
+
"children": {
|
4
|
+
"improvements": [
|
5
|
+
"Refactor the client service to deprecated."
|
6
|
+
]
|
7
|
+
},
|
8
|
+
"date": "2024-12-22",
|
9
|
+
"version": "1.37.1"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"children": {
|
13
|
+
"features": [
|
14
|
+
"Support to use pglite as client db."
|
15
|
+
]
|
16
|
+
},
|
17
|
+
"date": "2024-12-22",
|
18
|
+
"version": "1.37.0"
|
19
|
+
},
|
2
20
|
{
|
3
21
|
"children": {
|
4
22
|
"improvements": [
|
package/next.config.mjs
CHANGED
@@ -6,6 +6,7 @@ import ReactComponentName from 'react-scan/react-component-name/webpack';
|
|
6
6
|
const isProd = process.env.NODE_ENV === 'production';
|
7
7
|
const buildWithDocker = process.env.DOCKER === 'true';
|
8
8
|
const enableReactScan = !!process.env.REACT_SCAN_MONITOR_API_KEY;
|
9
|
+
const isUsePglite = process.env.NEXT_PUBLIC_CLIENT_DB === 'pglite';
|
9
10
|
|
10
11
|
// if you need to proxy the api endpoint to remote server
|
11
12
|
const API_PROXY_ENDPOINT = process.env.API_PROXY_ENDPOINT || '';
|
@@ -26,6 +27,7 @@ const nextConfig = {
|
|
26
27
|
'gpt-tokenizer',
|
27
28
|
'chroma-js',
|
28
29
|
],
|
30
|
+
serverComponentsExternalPackages: ['@electric-sql/pglite'],
|
29
31
|
webVitalsAttribution: ['CLS', 'LCP'],
|
30
32
|
},
|
31
33
|
|
@@ -180,7 +182,8 @@ const nextConfig = {
|
|
180
182
|
layers: true,
|
181
183
|
};
|
182
184
|
|
183
|
-
|
185
|
+
// 开启该插件会导致 pglite 的 fs bundler 被改表
|
186
|
+
if (enableReactScan && !isUsePglite) {
|
184
187
|
config.plugins.push(ReactComponentName({}));
|
185
188
|
}
|
186
189
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.37.1",
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
5
5
|
"keywords": [
|
6
6
|
"framework",
|
@@ -32,7 +32,8 @@
|
|
32
32
|
"build-sitemap": "tsx ./scripts/buildSitemapIndex/index.ts",
|
33
33
|
"build:analyze": "ANALYZE=true next build",
|
34
34
|
"build:docker": "DOCKER=true next build && npm run build-sitemap",
|
35
|
-
"db:generate": "drizzle-kit generate",
|
35
|
+
"db:generate": "drizzle-kit generate && npm run db:generate-client",
|
36
|
+
"db:generate-client": "tsx ./scripts/migrateClientDB/compile-migrations.ts",
|
36
37
|
"db:migrate": "MIGRATION_DB=1 tsx ./scripts/migrateServerDB/index.ts",
|
37
38
|
"db:push": "drizzle-kit push",
|
38
39
|
"db:push-test": "NODE_ENV=test drizzle-kit push",
|
@@ -117,6 +118,7 @@
|
|
117
118
|
"@clerk/themes": "^2.1.37",
|
118
119
|
"@codesandbox/sandpack-react": "^2.19.9",
|
119
120
|
"@cyntler/react-doc-viewer": "^1.17.0",
|
121
|
+
"@electric-sql/pglite": "0.2.13",
|
120
122
|
"@google/generative-ai": "^0.21.0",
|
121
123
|
"@huggingface/inference": "^2.8.1",
|
122
124
|
"@icons-pack/react-simple-icons": "9.6.0",
|
@@ -307,7 +309,7 @@
|
|
307
309
|
"vitest": "~1.2.2",
|
308
310
|
"vitest-canvas-mock": "^0.3.3"
|
309
311
|
},
|
310
|
-
"packageManager": "pnpm@9.15.
|
312
|
+
"packageManager": "pnpm@9.15.1",
|
311
313
|
"publishConfig": {
|
312
314
|
"access": "public",
|
313
315
|
"registry": "https://registry.npmjs.org"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { readMigrationFiles } from 'drizzle-orm/migrator';
|
2
|
+
import { writeFileSync } from 'node:fs';
|
3
|
+
import { join } from 'node:path';
|
4
|
+
|
5
|
+
const dbBase = join(__dirname, '../../src/database');
|
6
|
+
const migrationsFolder = join(dbBase, './migrations');
|
7
|
+
const migrations = readMigrationFiles({ migrationsFolder: migrationsFolder });
|
8
|
+
|
9
|
+
writeFileSync(
|
10
|
+
join(dbBase, './client/migrations.json'),
|
11
|
+
JSON.stringify(migrations, null, 2), // null, 2 adds indentation for better readability
|
12
|
+
);
|
13
|
+
|
14
|
+
console.log('🏁 client migrations.json compiled!');
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
2
2
|
|
3
3
|
import MobileContentLayout from '@/components/server/MobileNavLayout';
|
4
|
+
import InitClientDB from '@/features/InitClientDB';
|
4
5
|
|
5
6
|
import Header from './features/Header';
|
6
7
|
|
@@ -8,6 +9,7 @@ const Layout = ({ children }: PropsWithChildren) => {
|
|
8
9
|
return (
|
9
10
|
<MobileContentLayout header={<Header />} withNav>
|
10
11
|
{children}
|
12
|
+
<InitClientDB />
|
11
13
|
</MobileContentLayout>
|
12
14
|
);
|
13
15
|
};
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import { Flexbox } from 'react-layout-kit';
|
2
2
|
|
3
|
-
import
|
3
|
+
import InitClientDB from '@/features/InitClientDB';
|
4
|
+
|
4
5
|
import { LayoutProps } from '../type';
|
5
6
|
import SessionPanel from './SessionPanel';
|
6
7
|
|
@@ -18,7 +19,7 @@ const Layout = ({ children, session }: LayoutProps) => {
|
|
18
19
|
{children}
|
19
20
|
</Flexbox>
|
20
21
|
</Flexbox>
|
21
|
-
<
|
22
|
+
<InitClientDB bottom={60} />
|
22
23
|
{/* ↓ cloud slot ↓ */}
|
23
24
|
|
24
25
|
{/* ↑ cloud slot ↑ */}
|
@@ -1,10 +1,10 @@
|
|
1
1
|
'use client';
|
2
2
|
|
3
3
|
import { createStyles } from 'antd-style';
|
4
|
-
import { memo } from 'react';
|
4
|
+
import { Suspense, memo } from 'react';
|
5
5
|
import { Flexbox } from 'react-layout-kit';
|
6
6
|
|
7
|
-
import
|
7
|
+
import InitClientDB from '@/features/InitClientDB';
|
8
8
|
import { useQuery } from '@/hooks/useQuery';
|
9
9
|
|
10
10
|
import { LayoutProps } from './type';
|
@@ -39,7 +39,9 @@ const Layout = memo<LayoutProps>(({ children, session }) => {
|
|
39
39
|
>
|
40
40
|
{children}
|
41
41
|
</Flexbox>
|
42
|
-
<
|
42
|
+
<Suspense fallback={null}>
|
43
|
+
<InitClientDB bottom={100} />
|
44
|
+
</Suspense>
|
43
45
|
</>
|
44
46
|
);
|
45
47
|
});
|
@@ -0,0 +1,290 @@
|
|
1
|
+
import {
|
2
|
+
ImportMessage,
|
3
|
+
ImportSession,
|
4
|
+
ImportSessionGroup,
|
5
|
+
ImportTopic,
|
6
|
+
ImporterEntryData,
|
7
|
+
} from '@/types/importer';
|
8
|
+
|
9
|
+
interface V2DB_File {
|
10
|
+
/**
|
11
|
+
* create Time
|
12
|
+
*/
|
13
|
+
createdAt: number;
|
14
|
+
/**
|
15
|
+
* file data array buffer
|
16
|
+
*/
|
17
|
+
data: ArrayBuffer;
|
18
|
+
/**
|
19
|
+
* file type
|
20
|
+
* @example 'image/png'
|
21
|
+
*/
|
22
|
+
fileType: string;
|
23
|
+
id: string;
|
24
|
+
metadata: any;
|
25
|
+
/**
|
26
|
+
* file name
|
27
|
+
* @example 'test.png'
|
28
|
+
*/
|
29
|
+
name: string;
|
30
|
+
/**
|
31
|
+
* the mode database save the file
|
32
|
+
* local mean save the raw file into data
|
33
|
+
* url mean upload the file to a cdn and then save the url
|
34
|
+
*/
|
35
|
+
saveMode: 'local' | 'url';
|
36
|
+
/**
|
37
|
+
* file size
|
38
|
+
*/
|
39
|
+
size: number;
|
40
|
+
/**
|
41
|
+
* file url if saveMode is url
|
42
|
+
*/
|
43
|
+
url: string;
|
44
|
+
}
|
45
|
+
|
46
|
+
interface V2DB_MESSAGE {
|
47
|
+
content: string;
|
48
|
+
createdAt: number;
|
49
|
+
error?: any;
|
50
|
+
favorite: 0 | 1;
|
51
|
+
files?: string[];
|
52
|
+
fromModel?: string;
|
53
|
+
fromProvider?: string;
|
54
|
+
id: string;
|
55
|
+
observationId?: string;
|
56
|
+
// foreign keys
|
57
|
+
parentId?: string;
|
58
|
+
plugin?: any;
|
59
|
+
pluginError?: any;
|
60
|
+
pluginState?: any;
|
61
|
+
|
62
|
+
quotaId?: string;
|
63
|
+
role: string;
|
64
|
+
sessionId?: string;
|
65
|
+
tool_call_id?: string;
|
66
|
+
tools?: object[];
|
67
|
+
topicId?: string;
|
68
|
+
|
69
|
+
traceId?: string;
|
70
|
+
translate?: object | false;
|
71
|
+
tts?: any;
|
72
|
+
updatedAt: number;
|
73
|
+
}
|
74
|
+
|
75
|
+
interface DB_Plugin {
|
76
|
+
createdAt: number;
|
77
|
+
id: string;
|
78
|
+
identifier: string;
|
79
|
+
manifest?: object;
|
80
|
+
settings?: object;
|
81
|
+
type: 'plugin' | 'customPlugin';
|
82
|
+
updatedAt: number;
|
83
|
+
}
|
84
|
+
|
85
|
+
interface DB_Session {
|
86
|
+
config: object;
|
87
|
+
createdAt: number;
|
88
|
+
group?: string;
|
89
|
+
// 原 Agent 类型
|
90
|
+
id: string;
|
91
|
+
meta: object;
|
92
|
+
pinned?: number;
|
93
|
+
type?: 'agent' | 'group';
|
94
|
+
updatedAt: number;
|
95
|
+
}
|
96
|
+
|
97
|
+
interface DB_SessionGroup {
|
98
|
+
createdAt: number;
|
99
|
+
id: string;
|
100
|
+
name: string;
|
101
|
+
sort?: number;
|
102
|
+
updatedAt: number;
|
103
|
+
}
|
104
|
+
|
105
|
+
interface DB_Topic {
|
106
|
+
createdAt: number;
|
107
|
+
favorite?: number;
|
108
|
+
id: string;
|
109
|
+
sessionId?: string;
|
110
|
+
title: string;
|
111
|
+
updatedAt: number;
|
112
|
+
}
|
113
|
+
|
114
|
+
interface DB_User {
|
115
|
+
avatar?: string;
|
116
|
+
createdAt: number;
|
117
|
+
id: string;
|
118
|
+
settings: object;
|
119
|
+
updatedAt: number;
|
120
|
+
uuid: string;
|
121
|
+
}
|
122
|
+
|
123
|
+
interface MigrationData {
|
124
|
+
files: V2DB_File[];
|
125
|
+
messages: V2DB_MESSAGE[];
|
126
|
+
plugins: DB_Plugin[];
|
127
|
+
sessionGroups: DB_SessionGroup[];
|
128
|
+
sessions: DB_Session[];
|
129
|
+
topics: DB_Topic[];
|
130
|
+
users: DB_User[];
|
131
|
+
}
|
132
|
+
|
133
|
+
const LOBE_CHAT_LOCAL_DB_NAME = 'LOBE_CHAT_DB';
|
134
|
+
|
135
|
+
const V2DB_LASET_SCHEMA_VERSION = 7;
|
136
|
+
export class V2DBReader {
|
137
|
+
private dbName: string = LOBE_CHAT_LOCAL_DB_NAME;
|
138
|
+
private storeNames: string[];
|
139
|
+
|
140
|
+
constructor(storeNames: string[]) {
|
141
|
+
this.storeNames = storeNames;
|
142
|
+
}
|
143
|
+
|
144
|
+
/**
|
145
|
+
* 读取所有数据
|
146
|
+
*/
|
147
|
+
async readAllData(): Promise<MigrationData> {
|
148
|
+
try {
|
149
|
+
// 打开数据库连接
|
150
|
+
const db = await this.openDB();
|
151
|
+
|
152
|
+
// 并行读取所有表的数据
|
153
|
+
const results = await Promise.all(
|
154
|
+
this.storeNames.map((storeName) => this.readStore(db, storeName)),
|
155
|
+
);
|
156
|
+
|
157
|
+
// 构建返回结果
|
158
|
+
const migrationData = this.storeNames.reduce((acc, storeName, index) => {
|
159
|
+
// @ts-expect-error
|
160
|
+
acc[storeName] = results[index];
|
161
|
+
return acc;
|
162
|
+
}, {} as MigrationData);
|
163
|
+
|
164
|
+
// 关闭数据库连接
|
165
|
+
db.close();
|
166
|
+
|
167
|
+
return migrationData;
|
168
|
+
} catch (error) {
|
169
|
+
console.error('读取数据库失败:', error);
|
170
|
+
throw error;
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
async convertToImportData(data: MigrationData): Promise<ImporterEntryData> {
|
175
|
+
// 转换 messages
|
176
|
+
const messages = data.messages.map(
|
177
|
+
(msg): ImportMessage => ({
|
178
|
+
// 使用原有的 id
|
179
|
+
content: msg.content,
|
180
|
+
createdAt: msg.createdAt,
|
181
|
+
// 处理 error
|
182
|
+
error: msg.error || msg.pluginError,
|
183
|
+
|
184
|
+
// 处理额外信息
|
185
|
+
extra: {
|
186
|
+
fromModel: msg.fromModel,
|
187
|
+
fromProvider: msg.fromProvider,
|
188
|
+
translate: msg.translate as any,
|
189
|
+
tts: msg.tts,
|
190
|
+
},
|
191
|
+
|
192
|
+
files: msg.files,
|
193
|
+
id: msg.id,
|
194
|
+
|
195
|
+
// 复制原有字段
|
196
|
+
observationId: msg.observationId,
|
197
|
+
parentId: msg.parentId,
|
198
|
+
plugin: msg.plugin,
|
199
|
+
pluginState: msg.pluginState,
|
200
|
+
quotaId: msg.quotaId,
|
201
|
+
role: msg.role as any,
|
202
|
+
sessionId: msg.sessionId,
|
203
|
+
tool_call_id: msg.tool_call_id,
|
204
|
+
tools: msg.tools as any,
|
205
|
+
|
206
|
+
topicId: msg.topicId,
|
207
|
+
|
208
|
+
traceId: msg.traceId,
|
209
|
+
|
210
|
+
updatedAt: msg.updatedAt,
|
211
|
+
}),
|
212
|
+
);
|
213
|
+
|
214
|
+
// 转换 sessionGroups
|
215
|
+
const sessionGroups = data.sessionGroups.map(
|
216
|
+
(group): ImportSessionGroup => ({
|
217
|
+
createdAt: group.createdAt,
|
218
|
+
id: group.id,
|
219
|
+
// 使用原有的 id
|
220
|
+
name: group.name,
|
221
|
+
sort: group.sort || null,
|
222
|
+
updatedAt: group.updatedAt,
|
223
|
+
}),
|
224
|
+
);
|
225
|
+
|
226
|
+
// 转换 sessions
|
227
|
+
const sessions = data.sessions.map(
|
228
|
+
(session): ImportSession => ({
|
229
|
+
// 使用原有的 id
|
230
|
+
config: session.config as any,
|
231
|
+
createdAt: new Date(session.createdAt).toString(),
|
232
|
+
group: session.group,
|
233
|
+
id: session.id,
|
234
|
+
meta: session.meta as any,
|
235
|
+
pinned: session.pinned ? true : undefined,
|
236
|
+
type: session.type || 'agent',
|
237
|
+
updatedAt: new Date(session.updatedAt).toString(),
|
238
|
+
}),
|
239
|
+
);
|
240
|
+
|
241
|
+
const topics = data.topics.map(
|
242
|
+
(topic): ImportTopic => ({
|
243
|
+
...topic,
|
244
|
+
favorite: topic.favorite ? true : undefined,
|
245
|
+
}),
|
246
|
+
);
|
247
|
+
|
248
|
+
return {
|
249
|
+
messages,
|
250
|
+
sessionGroups,
|
251
|
+
sessions,
|
252
|
+
topics,
|
253
|
+
version: V2DB_LASET_SCHEMA_VERSION,
|
254
|
+
};
|
255
|
+
}
|
256
|
+
|
257
|
+
/**
|
258
|
+
* 打开数据库
|
259
|
+
*/
|
260
|
+
private openDB(): Promise<IDBDatabase> {
|
261
|
+
return new Promise((resolve, reject) => {
|
262
|
+
const request = indexedDB.open(this.dbName);
|
263
|
+
|
264
|
+
// eslint-disable-next-line unicorn/prefer-add-event-listener
|
265
|
+
request.onerror = () => {
|
266
|
+
reject(request.error);
|
267
|
+
};
|
268
|
+
request.onsuccess = () => resolve(request.result);
|
269
|
+
});
|
270
|
+
}
|
271
|
+
|
272
|
+
/**
|
273
|
+
* 读取单个存储对象的所有数据
|
274
|
+
*/
|
275
|
+
private readStore(db: IDBDatabase, storeName: string): Promise<any[]> {
|
276
|
+
return new Promise((resolve, reject) => {
|
277
|
+
try {
|
278
|
+
const transaction = db.transaction(storeName, 'readonly');
|
279
|
+
const store = transaction.objectStore(storeName);
|
280
|
+
const request = store.getAll();
|
281
|
+
|
282
|
+
// eslint-disable-next-line unicorn/prefer-add-event-listener
|
283
|
+
request.onerror = () => reject(request.error);
|
284
|
+
request.onsuccess = () => resolve(request.result);
|
285
|
+
} catch (error) {
|
286
|
+
reject(error);
|
287
|
+
}
|
288
|
+
});
|
289
|
+
}
|
290
|
+
}
|
@@ -1,14 +1,12 @@
|
|
1
1
|
import { Button } from 'antd';
|
2
|
-
import { createStore, set } from 'idb-keyval';
|
3
2
|
import { ReactNode, memo } from 'react';
|
4
3
|
import { useTranslation } from 'react-i18next';
|
5
4
|
|
6
|
-
import { Migration } from '@/migrations';
|
7
5
|
import { configService } from '@/services/config';
|
8
6
|
import { useChatStore } from '@/store/chat';
|
9
7
|
import { useSessionStore } from '@/store/session';
|
10
8
|
|
11
|
-
import {
|
9
|
+
import { MigrationError, UpgradeStatus } from './const';
|
12
10
|
|
13
11
|
export interface UpgradeButtonProps {
|
14
12
|
children?: ReactNode;
|
@@ -31,21 +29,19 @@ const UpgradeButton = memo<UpgradeButtonProps>(
|
|
31
29
|
|
32
30
|
const upgrade = async () => {
|
33
31
|
try {
|
34
|
-
const data = Migration.migrate({ state, version: 1 });
|
35
|
-
|
36
32
|
setUpgradeStatus(UpgradeStatus.UPGRADING);
|
37
33
|
|
38
34
|
await configService.importConfigState({
|
39
35
|
exportType: 'sessions',
|
40
|
-
state:
|
41
|
-
version:
|
36
|
+
state: state,
|
37
|
+
version: 7,
|
42
38
|
});
|
43
39
|
|
44
40
|
await refreshSession();
|
45
41
|
await refreshMessages();
|
46
42
|
await refreshTopic();
|
47
43
|
|
48
|
-
|
44
|
+
localStorage.setItem('V2DB_IS_MIGRATED', '1');
|
49
45
|
|
50
46
|
setUpgradeStatus(UpgradeStatus.UPGRADED);
|
51
47
|
|