Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
actions-user committed Jan 18, 2025
2 parents f24ff56 + 8c02412 commit 4ca373f
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 14 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@

# Changelog

### [Version 1.47.4](https://github.com/lobehub/lobe-chat/compare/v1.47.3...v1.47.4)

<sup>Released on **2025-01-18**</sup>

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>

### [Version 1.47.3](https://github.com/lobehub/lobe-chat/compare/v1.47.2...v1.47.3)

<sup>Released on **2025-01-18**</sup>
Expand Down
5 changes: 5 additions & 0 deletions changelog/v1.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
[
{
"children": {},
"date": "2025-01-18",
"version": "1.47.4"
},
{
"children": {
"fixes": ["Fix hydration error."]
Expand Down
4 changes: 2 additions & 2 deletions next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ const nextConfig: NextConfig = {
source: '/welcome',
},
],
serverExternalPackages: ['@electric-sql/pglite', 'sharp'],

// when external packages in dev mode with turbopack, this config will lead to bundle error
serverExternalPackages: isProd ? ['@electric-sql/pglite'] : undefined,
transpilePackages: ['pdfjs-dist', 'mermaid'],

webpack(config) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lobehub/chat",
"version": "1.47.3",
"version": "1.47.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.",
"keywords": [
"framework",
Expand Down
53 changes: 42 additions & 11 deletions src/database/client/db.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { PgliteDatabase } from 'drizzle-orm/pglite';
import { PgliteDatabase, drizzle } from 'drizzle-orm/pglite';
import { Md5 } from 'ts-md5';

import { ClientDBLoadingProgress, DatabaseLoadingState } from '@/types/clientDB';
Expand Down Expand Up @@ -28,6 +28,12 @@ export class DatabaseManager {
private static WASM_CDN_URL =
'https://registry.npmmirror.com/@electric-sql/pglite/0.2.13/files/dist/postgres.wasm';

private static FSBUNDLER_CDN_URL =
'https://registry.npmmirror.com/@electric-sql/pglite/0.2.13/files/dist/postgres.data';

private static VECTOR_CDN_URL =
'https://registry.npmmirror.com/@electric-sql/pglite/0.2.13/files/dist/vector.tar.gz';

private constructor() {}

static getInstance() {
Expand Down Expand Up @@ -88,6 +94,12 @@ export class DatabaseManager {
return WebAssembly.compile(wasmBytes);
}

private fetchFsBundle = async () => {
const res = await fetch(DatabaseManager.FSBUNDLER_CDN_URL);

return await res.blob();
};

// 异步加载 PGlite 相关依赖
private async loadDependencies() {
const start = Date.now();
Expand All @@ -100,7 +112,7 @@ export class DatabaseManager {
PGlite: m.PGlite,
})),
import('@electric-sql/pglite/vector'),
import('drizzle-orm/pglite'),
this.fetchFsBundle(),
];

let loaded = 0;
Expand All @@ -125,9 +137,9 @@ export class DatabaseManager {
});

// @ts-ignore
const [{ PGlite, IdbFs, MemoryFS }, { vector }, { drizzle }] = results;
const [{ PGlite, IdbFs, MemoryFS }, { vector }, fsBundle] = results;

return { IdbFs, MemoryFS, PGlite, drizzle, vector };
return { IdbFs, MemoryFS, PGlite, fsBundle, vector };
}

// 数据库迁移方法
Expand Down Expand Up @@ -177,17 +189,34 @@ export class DatabaseManager {
this.callbacks?.onStateChange?.(DatabaseLoadingState.Initializing);

// 加载依赖
const { PGlite, vector, drizzle, IdbFs, MemoryFS } = await this.loadDependencies();
const { fsBundle, PGlite, MemoryFS, IdbFs, vector } = await this.loadDependencies();

// 加载并编译 WASM 模块
const wasmModule = await this.loadWasmModule();

const db = new PGlite({
extensions: { vector },
fs: typeof window === 'undefined' ? new MemoryFS('lobechat') : new IdbFs('lobechat'),
relaxedDurability: true,
wasmModule,
});
const { initPgliteWorker } = await import('./pglite');

let db: typeof PGlite;

const dbName = 'lobechat';

// make db as web worker if worker is available
if (typeof Worker !== 'undefined') {
db = await initPgliteWorker({
dbName,
fsBundle: fsBundle as Blob,
vectorBundlePath: DatabaseManager.VECTOR_CDN_URL,
wasmModule,
});
} else {
// in edge runtime or test runtime, we don't have worker
db = new PGlite({
extensions: { vector },
fs: typeof window === 'undefined' ? new MemoryFS(dbName) : new IdbFs(dbName),
relaxedDurability: true,
wasmModule,
});
}

this.dbInstance = drizzle({ client: db, schema });

Expand All @@ -210,6 +239,8 @@ export class DatabaseManager {
name: error.name,
stack: error.stack,
});

console.error(error);
throw error;
}
})();
Expand Down
17 changes: 17 additions & 0 deletions src/database/client/pglite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { PGliteWorker } from '@electric-sql/pglite/worker';

import { InitMeta } from './type';

export const initPgliteWorker = async (meta: InitMeta) => {
const worker = await PGliteWorker.create(
new Worker(new URL('pglite.worker.ts', import.meta.url)),
{ meta },
);

// 监听 worker 状态变化
worker.onLeaderChange(() => {
console.log('Worker leader changed, isLeader:', worker?.isLeader);
});

return worker as PGliteWorker;
};
25 changes: 25 additions & 0 deletions src/database/client/pglite.worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { worker } from '@electric-sql/pglite/worker';

import { InitMeta } from './type';

worker({
async init(options) {
const { wasmModule, fsBundle, vectorBundlePath, dbName } = options.meta as InitMeta;
const { PGlite } = await import('@electric-sql/pglite');

return new PGlite({
dataDir: `idb://${dbName}`,
extensions: {
vector: {
name: 'pgvector',
setup: async (pglite, options) => {
return { bundlePath: new URL(vectorBundlePath), options };
},
},
},
fsBundle,
relaxedDurability: true,
wasmModule,
});
},
});
6 changes: 6 additions & 0 deletions src/database/client/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface InitMeta {
dbName: string;
fsBundle: Blob;
vectorBundlePath: string;
wasmModule: WebAssembly.Module;
}

0 comments on commit 4ca373f

Please sign in to comment.