Skip to content

Commit

Permalink
🚧 wip: pglite instance
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Dec 3, 2024
1 parent 3814853 commit 57d00de
Show file tree
Hide file tree
Showing 9 changed files with 364 additions and 35 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"build-sitemap": "tsx ./scripts/buildSitemapIndex/index.ts",
"build:analyze": "ANALYZE=true next build",
"build:docker": "DOCKER=true next build && npm run build-sitemap",
"db:generate": "drizzle-kit generate",
"db:generate": "drizzle-kit generate && npm run db:generate-client",
"db:generate-client": "bun ./scripts/migrateClientDB/compile-migrations.ts",
"db:migrate": "MIGRATION_DB=1 tsx ./scripts/migrateServerDB/index.ts",
"db:push": "drizzle-kit push",
"db:push-test": "NODE_ENV=test drizzle-kit push",
Expand Down Expand Up @@ -117,6 +118,7 @@
"@clerk/themes": "^2.1.37",
"@codesandbox/sandpack-react": "^2.19.9",
"@cyntler/react-doc-viewer": "^1.17.0",
"@electric-sql/pglite": "^0.2.14",
"@google/generative-ai": "^0.21.0",
"@huggingface/inference": "^2.8.1",
"@icons-pack/react-simple-icons": "9.6.0",
Expand Down
12 changes: 12 additions & 0 deletions scripts/migrateClientDB/compile-migrations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { readMigrationFiles } from 'drizzle-orm/migrator';
import { join } from 'node:path';

const dbBase = join(__dirname, '../../src/database');
const migrationsFolder = join(dbBase, './migrations');

const migrations = readMigrationFiles({ migrationsFolder: migrationsFolder });

// eslint-disable-next-line no-undef
await Bun.write(join(dbBase, './client/migrations.json'), JSON.stringify(migrations));

console.log('🏁Migrations compiled!');
13 changes: 13 additions & 0 deletions src/database/client/db.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { IdbFs, PGlite } from '@electric-sql/pglite';
import { vector } from '@electric-sql/pglite/vector';
import { drizzle } from 'drizzle-orm/pglite';

import * as schema from '../schemas';

const client = new PGlite({
extensions: { vector },
fs: new IdbFs('lobechat'),
relaxedDurability: true,
});

export const clientDB = drizzle({ client, schema });
14 changes: 14 additions & 0 deletions src/database/client/migrate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { MigrationConfig } from 'drizzle-orm/migrator';

import { clientDB } from './db';
import migrations from './migrations.json';

export const migrate = async () => {
// refs: https://github.com/drizzle-team/drizzle-orm/discussions/2532
// @ts-ignore
clientDB.dialect.migrate(migrations, clientDB.session, {
migrationsTable: 'drizzle_migrations',
} satisfies Omit<MigrationConfig, 'migrationsFolder'>);

return clientDB;
};
281 changes: 281 additions & 0 deletions src/database/client/migrations.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions src/layout/GlobalProvider/StoreInitialization.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next';
import { createStoreUpdater } from 'zustand-utils';

import { LOBE_URL_IMPORT_NAME } from '@/const/url';
import { migrate } from '@/database/client/migrate';
import { useIsMobile } from '@/hooks/useIsMobile';
import { useEnabledDataSync } from '@/hooks/useSyncData';
import { useAgentStore } from '@/store/agent';
Expand Down Expand Up @@ -90,6 +91,11 @@ const StoreInitialization = memo(() => {
}
}, [router, mobile]);

useEffect(() => {
migrate().then(() => {
console.log('migrate success!');
});
}, []);
return null;
});

Expand Down
58 changes: 34 additions & 24 deletions src/services/topic/client.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { TopicModel } from '@/database/_deprecated/models/topic';
import { clientDB } from '@/database/client/db';
import { TopicModel } from '@/database/server/models/topic';
import { useUserStore } from '@/store/user';
import { userProfileSelectors } from '@/store/user/selectors';
import { ChatTopic } from '@/types/topic';

import { CreateTopicParams, ITopicService, QueryTopicParams } from './type';

export class ClientService implements ITopicService {
private topicModel: TopicModel;
constructor() {
const userId = userProfileSelectors.userId(useUserStore.getState())!;

this.topicModel = new TopicModel(clientDB as any, userId);
}

async createTopic(params: CreateTopicParams): Promise<string> {
const item = await TopicModel.create(params as any);
const item = await this.topicModel.create(params as any);

if (!item) {
throw new Error('topic create Error');
Expand All @@ -15,56 +25,56 @@ export class ClientService implements ITopicService {
}

async batchCreateTopics(importTopics: ChatTopic[]) {
return TopicModel.batchCreate(importTopics as any);
const data = await this.topicModel.batchCreate(importTopics as any);

return { added: data.length, ids: [], skips: [], success: true };
}

async cloneTopic(id: string, newTitle?: string) {
return TopicModel.duplicateTopic(id, newTitle);
const data = await this.topicModel.duplicate(id, newTitle);
return data.topic.id;
}

async getTopics(params: QueryTopicParams): Promise<ChatTopic[]> {
return TopicModel.query(params);
async getTopics(params: QueryTopicParams) {
console.log('get', params);
const data = await this.topicModel.query(params);
console.log('topic:', data);
return data as unknown as Promise<ChatTopic[]>;
}

async searchTopics(keyword: string, sessionId?: string) {
return TopicModel.queryByKeyword(keyword, sessionId);
}
const data = await this.topicModel.queryByKeyword(keyword, sessionId);

async getAllTopics() {
return TopicModel.queryAll();
return data as unknown as Promise<ChatTopic[]>;
}

async countTopics() {
return TopicModel.count();
}
async getAllTopics() {
const data = await this.topicModel.queryAll();

async updateTopicFavorite(id: string, favorite?: boolean) {
return this.updateTopic(id, { favorite });
return data as unknown as Promise<ChatTopic[]>;
}

async updateTopicTitle(id: string, text: string) {
return this.updateTopic(id, { title: text });
async countTopics() {
return this.topicModel.count();
}

async updateTopic(id: string, data: Partial<ChatTopic>) {
const favorite = typeof data.favorite !== 'undefined' ? (data.favorite ? 1 : 0) : undefined;

return TopicModel.update(id, { ...data, favorite });
return this.topicModel.update(id, data as any);
}

async removeTopic(id: string) {
return TopicModel.delete(id);
return this.topicModel.delete(id);
}

async removeTopics(sessionId: string) {
return TopicModel.batchDeleteBySessionId(sessionId);
return this.topicModel.batchDeleteBySessionId(sessionId);
}

async batchRemoveTopics(topics: string[]) {
return TopicModel.batchDelete(topics);
return this.topicModel.batchDelete(topics);
}

async removeAllTopic() {
return TopicModel.clearTable();
return this.topicModel.deleteAll();
}
}
9 changes: 0 additions & 9 deletions src/types/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,10 @@ export const LobeMetaDataSchema = z.object({
export type MetaData = z.infer<typeof LobeMetaDataSchema>;

export interface BaseDataModel {
/**
* @deprecated
*/
createAt?: number;

createdAt: number;

id: string;
meta: MetaData;

/**
* @deprecated
*/
updateAt?: number;
updatedAt: number;
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
}
]
},
"exclude": ["node_modules", "public/sw.js"],
"exclude": ["node_modules", "public/sw.js", "scripts/migrateClientDB/compile-migrations.ts"],
"include": [
"next-env.d.ts",
"vitest.config.ts",
Expand Down

0 comments on commit 57d00de

Please sign in to comment.