@lobehub/chat 1.47.2 → 1.47.4

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 CHANGED
@@ -2,6 +2,48 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.47.4](https://github.com/lobehub/lobe-chat/compare/v1.47.3...v1.47.4)
6
+
7
+ <sup>Released on **2025-01-18**</sup>
8
+
9
+ <br/>
10
+
11
+ <details>
12
+ <summary><kbd>Improvements and Fixes</kbd></summary>
13
+
14
+ </details>
15
+
16
+ <div align="right">
17
+
18
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
19
+
20
+ </div>
21
+
22
+ ### [Version 1.47.3](https://github.com/lobehub/lobe-chat/compare/v1.47.2...v1.47.3)
23
+
24
+ <sup>Released on **2025-01-18**</sup>
25
+
26
+ #### 🐛 Bug Fixes
27
+
28
+ - **misc**: Fix hydration error.
29
+
30
+ <br/>
31
+
32
+ <details>
33
+ <summary><kbd>Improvements and Fixes</kbd></summary>
34
+
35
+ #### What's fixed
36
+
37
+ - **misc**: Fix hydration error, closes [#5502](https://github.com/lobehub/lobe-chat/issues/5502) ([cbe469a](https://github.com/lobehub/lobe-chat/commit/cbe469a))
38
+
39
+ </details>
40
+
41
+ <div align="right">
42
+
43
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
44
+
45
+ </div>
46
+
5
47
  ### [Version 1.47.2](https://github.com/lobehub/lobe-chat/compare/v1.47.1...v1.47.2)
6
48
 
7
49
  <sup>Released on **2025-01-17**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,18 @@
1
1
  [
2
+ {
3
+ "children": {},
4
+ "date": "2025-01-18",
5
+ "version": "1.47.4"
6
+ },
7
+ {
8
+ "children": {
9
+ "fixes": [
10
+ "Fix hydration error."
11
+ ]
12
+ },
13
+ "date": "2025-01-18",
14
+ "version": "1.47.3"
15
+ },
2
16
  {
3
17
  "children": {
4
18
  "fixes": [
package/next.config.ts CHANGED
@@ -165,8 +165,8 @@ const nextConfig: NextConfig = {
165
165
  source: '/welcome',
166
166
  },
167
167
  ],
168
- serverExternalPackages: ['@electric-sql/pglite', 'sharp'],
169
-
168
+ // when external packages in dev mode with turbopack, this config will lead to bundle error
169
+ serverExternalPackages: isProd ? ['@electric-sql/pglite'] : undefined,
170
170
  transpilePackages: ['pdfjs-dist', 'mermaid'],
171
171
 
172
172
  webpack(config) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.47.2",
3
+ "version": "1.47.4",
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",
@@ -39,7 +39,7 @@
39
39
  "db:push-test": "NODE_ENV=test drizzle-kit push",
40
40
  "db:studio": "drizzle-kit studio",
41
41
  "db:z-pull": "drizzle-kit introspect",
42
- "dev": "next dev --turbo -p 3010",
42
+ "dev": "next dev --turbopack -p 3010",
43
43
  "docs:i18n": "lobe-i18n md && npm run lint:md && npm run lint:mdx",
44
44
  "docs:seo": "lobe-seo && npm run lint:mdx",
45
45
  "i18n": "npm run workflow:i18n && lobe-i18n",
@@ -1,4 +1,4 @@
1
- import type { PgliteDatabase } from 'drizzle-orm/pglite';
1
+ import { PgliteDatabase, drizzle } from 'drizzle-orm/pglite';
2
2
  import { Md5 } from 'ts-md5';
3
3
 
4
4
  import { ClientDBLoadingProgress, DatabaseLoadingState } from '@/types/clientDB';
@@ -28,6 +28,12 @@ export class DatabaseManager {
28
28
  private static WASM_CDN_URL =
29
29
  'https://registry.npmmirror.com/@electric-sql/pglite/0.2.13/files/dist/postgres.wasm';
30
30
 
31
+ private static FSBUNDLER_CDN_URL =
32
+ 'https://registry.npmmirror.com/@electric-sql/pglite/0.2.13/files/dist/postgres.data';
33
+
34
+ private static VECTOR_CDN_URL =
35
+ 'https://registry.npmmirror.com/@electric-sql/pglite/0.2.13/files/dist/vector.tar.gz';
36
+
31
37
  private constructor() {}
32
38
 
33
39
  static getInstance() {
@@ -88,6 +94,12 @@ export class DatabaseManager {
88
94
  return WebAssembly.compile(wasmBytes);
89
95
  }
90
96
 
97
+ private fetchFsBundle = async () => {
98
+ const res = await fetch(DatabaseManager.FSBUNDLER_CDN_URL);
99
+
100
+ return await res.blob();
101
+ };
102
+
91
103
  // 异步加载 PGlite 相关依赖
92
104
  private async loadDependencies() {
93
105
  const start = Date.now();
@@ -100,7 +112,7 @@ export class DatabaseManager {
100
112
  PGlite: m.PGlite,
101
113
  })),
102
114
  import('@electric-sql/pglite/vector'),
103
- import('drizzle-orm/pglite'),
115
+ this.fetchFsBundle(),
104
116
  ];
105
117
 
106
118
  let loaded = 0;
@@ -125,9 +137,9 @@ export class DatabaseManager {
125
137
  });
126
138
 
127
139
  // @ts-ignore
128
- const [{ PGlite, IdbFs, MemoryFS }, { vector }, { drizzle }] = results;
140
+ const [{ PGlite, IdbFs, MemoryFS }, { vector }, fsBundle] = results;
129
141
 
130
- return { IdbFs, MemoryFS, PGlite, drizzle, vector };
142
+ return { IdbFs, MemoryFS, PGlite, fsBundle, vector };
131
143
  }
132
144
 
133
145
  // 数据库迁移方法
@@ -177,17 +189,34 @@ export class DatabaseManager {
177
189
  this.callbacks?.onStateChange?.(DatabaseLoadingState.Initializing);
178
190
 
179
191
  // 加载依赖
180
- const { PGlite, vector, drizzle, IdbFs, MemoryFS } = await this.loadDependencies();
192
+ const { fsBundle, PGlite, MemoryFS, IdbFs, vector } = await this.loadDependencies();
181
193
 
182
194
  // 加载并编译 WASM 模块
183
195
  const wasmModule = await this.loadWasmModule();
184
196
 
185
- const db = new PGlite({
186
- extensions: { vector },
187
- fs: typeof window === 'undefined' ? new MemoryFS('lobechat') : new IdbFs('lobechat'),
188
- relaxedDurability: true,
189
- wasmModule,
190
- });
197
+ const { initPgliteWorker } = await import('./pglite');
198
+
199
+ let db: typeof PGlite;
200
+
201
+ const dbName = 'lobechat';
202
+
203
+ // make db as web worker if worker is available
204
+ if (typeof Worker !== 'undefined') {
205
+ db = await initPgliteWorker({
206
+ dbName,
207
+ fsBundle: fsBundle as Blob,
208
+ vectorBundlePath: DatabaseManager.VECTOR_CDN_URL,
209
+ wasmModule,
210
+ });
211
+ } else {
212
+ // in edge runtime or test runtime, we don't have worker
213
+ db = new PGlite({
214
+ extensions: { vector },
215
+ fs: typeof window === 'undefined' ? new MemoryFS(dbName) : new IdbFs(dbName),
216
+ relaxedDurability: true,
217
+ wasmModule,
218
+ });
219
+ }
191
220
 
192
221
  this.dbInstance = drizzle({ client: db, schema });
193
222
 
@@ -210,6 +239,8 @@ export class DatabaseManager {
210
239
  name: error.name,
211
240
  stack: error.stack,
212
241
  });
242
+
243
+ console.error(error);
213
244
  throw error;
214
245
  }
215
246
  })();
@@ -0,0 +1,17 @@
1
+ import { PGliteWorker } from '@electric-sql/pglite/worker';
2
+
3
+ import { InitMeta } from './type';
4
+
5
+ export const initPgliteWorker = async (meta: InitMeta) => {
6
+ const worker = await PGliteWorker.create(
7
+ new Worker(new URL('pglite.worker.ts', import.meta.url)),
8
+ { meta },
9
+ );
10
+
11
+ // 监听 worker 状态变化
12
+ worker.onLeaderChange(() => {
13
+ console.log('Worker leader changed, isLeader:', worker?.isLeader);
14
+ });
15
+
16
+ return worker as PGliteWorker;
17
+ };
@@ -0,0 +1,25 @@
1
+ import { worker } from '@electric-sql/pglite/worker';
2
+
3
+ import { InitMeta } from './type';
4
+
5
+ worker({
6
+ async init(options) {
7
+ const { wasmModule, fsBundle, vectorBundlePath, dbName } = options.meta as InitMeta;
8
+ const { PGlite } = await import('@electric-sql/pglite');
9
+
10
+ return new PGlite({
11
+ dataDir: `idb://${dbName}`,
12
+ extensions: {
13
+ vector: {
14
+ name: 'pgvector',
15
+ setup: async (pglite, options) => {
16
+ return { bundlePath: new URL(vectorBundlePath), options };
17
+ },
18
+ },
19
+ },
20
+ fsBundle,
21
+ relaxedDurability: true,
22
+ wasmModule,
23
+ });
24
+ },
25
+ });
@@ -0,0 +1,6 @@
1
+ export interface InitMeta {
2
+ dbName: string;
3
+ fsBundle: Blob;
4
+ vectorBundlePath: string;
5
+ wasmModule: WebAssembly.Module;
6
+ }
@@ -4,8 +4,7 @@ import urlJoin from 'url-join';
4
4
  import { INBOX_SESSION_ID } from '@/const/session';
5
5
  import { useIsMobile } from '@/hooks/useIsMobile';
6
6
  import { useQueryRoute } from '@/hooks/useQueryRoute';
7
- import { useGlobalStore } from '@/store/global';
8
- import { ChatSettingsTabs, SettingsTabs, SidebarTabKey } from '@/store/global/initialState';
7
+ import { ChatSettingsTabs, SettingsTabs } from '@/store/global/initialState';
9
8
  import { useSessionStore } from '@/store/session';
10
9
 
11
10
  export const useOpenChatSettings = (tab: ChatSettingsTabs = ChatSettingsTabs.Meta) => {
@@ -15,9 +14,6 @@ export const useOpenChatSettings = (tab: ChatSettingsTabs = ChatSettingsTabs.Met
15
14
 
16
15
  return useMemo(() => {
17
16
  if (activeId === INBOX_SESSION_ID) {
18
- useGlobalStore.setState({
19
- sidebarKey: SidebarTabKey.Setting,
20
- });
21
17
  return () => router.push(urlJoin('/settings', SettingsTabs.Agent));
22
18
  }
23
19
  if (mobile) {
@@ -2,8 +2,6 @@ import { createTRPCClient, httpBatchLink } from '@trpc/client';
2
2
  import { createTRPCReact } from '@trpc/react-query';
3
3
  import superjson from 'superjson';
4
4
 
5
- import { fetchErrorNotification } from '@/components/Error/fetchErrorNotification';
6
- import { loginRequired } from '@/components/Error/loginRequiredNotification';
7
5
  import { ModelProvider } from '@/libs/agent-runtime';
8
6
  import type { LambdaRouter } from '@/server/routers/lambda';
9
7
 
@@ -17,6 +15,9 @@ const links = [
17
15
 
18
16
  const errorRes: ErrorResponse = await response.clone().json();
19
17
 
18
+ const { loginRequired } = await import('@/components/Error/loginRequiredNotification');
19
+ const { fetchErrorNotification } = await import('@/components/Error/fetchErrorNotification');
20
+
20
21
  errorRes.forEach((item) => {
21
22
  const errorData = item.error.json;
22
23