Skip to content

Commit

Permalink
feat: add entities
Browse files Browse the repository at this point in the history
  • Loading branch information
2214962083 committed Nov 4, 2024
1 parent 92f1194 commit b2abd7e
Show file tree
Hide file tree
Showing 56 changed files with 892 additions and 167 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { logger } from '@extension/logger'
import {
import type {
AIModel,
type AIModelFeature,
type AIProvider,
type AIProviderType
} from '@shared/utils/ai-providers'
AIModelFeature,
AIProvider,
AIProviderType
} from '@shared/entities'

import { aiModelDB } from '../lowdb/ai-model-db'
import { Controller } from '../types'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AIProvider } from '@shared/utils/ai-providers'
import type { AIProvider } from '@shared/entities'

import { aiProviderDB } from '../lowdb/ai-provider-db'
import { Controller } from '../types'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { aidePaths } from '@extension/file-utils/paths'
import { VsCodeFS } from '@extension/file-utils/vscode-fs'
import { logger } from '@extension/logger'
import type { ChatSession } from '@shared/entities'
import type { ChatContext, Conversation } from '@shared/types/chat-context'
import { convertChatContextToChatSession } from '@shared/utils/convert-chat-context-to-chat-session'

import { ChatSession, chatSessionsDB } from '../lowdb/chat-sessions-db'
import { chatSessionsDB } from '../lowdb/chat-sessions-db'
import { Controller } from '../types'

export class ChatSessionController extends Controller {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ export class DocController extends Controller {
this.disposeResources(request.id)
}

async removeDocSites(request: { ids: string[] }) {
await docSitesDB.batchRemove(request.ids)
request.ids.forEach(id => this.disposeResources(id))
}

async *crawlDocs(request: {
id: string
options?: Partial<CrawlerOptions>
Expand Down
27 changes: 27 additions & 0 deletions src/extension/webview-api/controllers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Controller } from '../types'
import { AIModelController } from './ai-model-controller'
import { AIProviderController } from './ai-provider-controller'
import { ApplyController } from './apply-controller'
import { ChatController } from './chat-controller'
import { ChatSessionController } from './chat-session-controller'
import { CodebaseController } from './codebase-controller'
import { DocController } from './doc-controller'
import { FileController } from './file-controller'
import { GitController } from './git-controller'
import { SettingsController } from './settings-controller'
import { SystemController } from './system-controller'

export const controllers = [
ChatController,
CodebaseController,
FileController,
GitController,
SystemController,
DocController,
ChatSessionController,
ApplyController,
SettingsController,
AIProviderController,
AIModelController
] as const satisfies (typeof Controller)[]
export type Controllers = typeof controllers
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SettingKey, SettingValue } from '@shared/utils/settings-config'
import type { SettingKey, SettingValue } from '@shared/entities'

import { globalSettingsDB, workspaceSettingsDB } from '../lowdb/settings-db'
import { Controller } from '../types'
Expand Down
27 changes: 1 addition & 26 deletions src/extension/webview-api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,7 @@ import findFreePorts from 'find-free-ports'
import { Server } from 'socket.io'
import * as vscode from 'vscode'

import { AIModelController } from './controllers/ai-model.controller'
import { AIProviderController } from './controllers/ai-provider.controller'
import { ApplyController } from './controllers/apply.controller'
import { ChatSessionController } from './controllers/chat-session.controller'
import { ChatController } from './controllers/chat.controller'
import { CodebaseController } from './controllers/codebase.controller'
import { DocController } from './controllers/doc.controller'
import { FileController } from './controllers/file.controller'
import { GitController } from './controllers/git.controller'
import { SettingsController } from './controllers/settings.controller'
import { SystemController } from './controllers/system.controller'
import { controllers } from './controllers'
import type {
Controller,
ControllerClass,
Expand Down Expand Up @@ -122,21 +112,6 @@ class APIManager {
}
}

export const controllers = [
ChatController,
CodebaseController,
FileController,
GitController,
SystemController,
DocController,
ChatSessionController,
ApplyController,
SettingsController,
AIProviderController,
AIModelController
] as const
export type Controllers = typeof controllers

export const setupWebviewAPIManager = async (
context: vscode.ExtensionContext,
panel: WebviewPanel,
Expand Down
13 changes: 11 additions & 2 deletions src/extension/webview-api/lowdb/ai-model-db.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import path from 'path'
import { aidePaths } from '@extension/file-utils/paths'
import { AIModel } from '@shared/utils/ai-providers'
import { AIModelEntity, type AIModel } from '@shared/entities/ai-model-entity'

import { BaseDB } from './base-db'

class AIModelDB extends BaseDB<AIModel> {
static readonly schemaVersion = 1

constructor() {
super(path.join(aidePaths.getGlobalLowdbPath(), 'ai-models.json'))
// Use entity's defaults
const defaults = new AIModelEntity().getDefaults()

super(
path.join(aidePaths.getGlobalLowdbPath(), 'ai-models.json'),
defaults,
AIModelDB.schemaVersion
)
}
}

Expand Down
31 changes: 22 additions & 9 deletions src/extension/webview-api/lowdb/ai-provider-db.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import path from 'path'
import { aidePaths } from '@extension/file-utils/paths'
import { AIModelEntity, type AIModel } from '@shared/entities/ai-model-entity'
import {
AIProvider,
AIProviderEntity,
AIProviderType,
getDefaultAIModel,
type AIModel
} from '@shared/utils/ai-providers'
type AIProvider
} from '@shared/entities/ai-provider-entity'

import { aiModelDB } from './ai-model-db'
import { BaseDB } from './base-db'
Expand All @@ -26,12 +26,27 @@ const findNewModel = async (
// Filter out models that don't exist yet
return modelsName
.filter(name => !existingModelSet.has(name))
.map(name => getDefaultAIModel(name, providerOrBaseUrl))
.map(
name =>
new AIModelEntity({
name,
providerOrBaseUrl
})
)
}

class AIProviderDB extends BaseDB<AIProvider> {
static readonly schemaVersion = 1

constructor() {
super(path.join(aidePaths.getGlobalLowdbPath(), 'ai-providers.json'))
// Use entity's defaults
const defaults = new AIProviderEntity().getDefaults()

super(
path.join(aidePaths.getGlobalLowdbPath(), 'ai-providers.json'),
defaults,
AIProviderDB.schemaVersion
)
}

async add(
Expand All @@ -53,9 +68,7 @@ class AIProviderDB extends BaseDB<AIProvider> {
)

// Add models one by one to avoid type error
for (const model of newModels) {
await aiModelDB.add(model)
}
await aiModelDB.batchAdd(newModels)

return await super.add(item)
}
Expand Down
71 changes: 63 additions & 8 deletions src/extension/webview-api/lowdb/base-db.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,58 @@
import type { IBaseEntity } from '@shared/entities/base-entity'
import { Low } from 'lowdb'
import { JSONFile } from 'lowdb/node'
import { v4 as uuidv4 } from 'uuid'

export interface BaseItem {
id: string
}
export class BaseDB<T extends IBaseEntity> {
protected db: Low<{ items: T[]; schemaVersion?: number }>

protected currentVersion: number = 1

export class BaseDB<T extends BaseItem> {
protected db: Low<{ items: T[] }>
protected defaults: Partial<T> = {}

constructor(filePath: string) {
const adapter = new JSONFile<{ items: T[] }>(filePath)
constructor(
filePath: string,
defaults: Partial<T> = {},
currentVersion: number = 1
) {
const adapter = new JSONFile<{ items: T[]; schemaVersion?: number }>(
filePath
)
this.db = new Low(adapter, { items: [] })
this.defaults = defaults
this.currentVersion = currentVersion
}

protected async load() {
await this.db.read()
this.db.data ||= { items: [] }
this.db.data ||= { items: [], schemaVersion: this.currentVersion }

if (this.db.data.schemaVersion !== this.currentVersion) {
await this.migrateData()
}

this.db.data.items = this.db.data.items.map(item => ({
...this.defaults,
...item
}))
}

protected async migrateData() {
const currentVersion = this.db.data.schemaVersion || 1

if (currentVersion < this.currentVersion) {
for (let v = currentVersion; v < this.currentVersion; v++) {
await this.applyMigration(v)
}
}

this.db.data.schemaVersion = this.currentVersion
await this.db.write()
}

// eslint-disable-next-line unused-imports/no-unused-vars
protected async applyMigration(fromVersion: number) {
// Override this method in derived classes to implement specific migrations
}

async getAll(): Promise<T[]> {
Expand All @@ -32,12 +68,31 @@ export class BaseDB<T extends BaseItem> {
return newItem
}

async batchAdd(items: (Omit<T, 'id'> & { id?: string })[]): Promise<T[]> {
await this.load()
const newItems = items.map(item => ({
...item,
id: item.id || uuidv4()
})) as T[]
this.db.data.items.push(...newItems)
await this.db.write()
return newItems
}

async remove(id: string): Promise<void> {
await this.load()
this.db.data.items = this.db.data.items.filter(item => item.id !== id)
await this.db.write()
}

async batchRemove(ids: string[]): Promise<void> {
await this.load()
this.db.data.items = this.db.data.items.filter(
item => !ids.includes(item.id)
)
await this.db.write()
}

async update(id: string, updates: Partial<T>): Promise<T | null> {
await this.load()
const item = this.db.data.items.find(i => i.id === id)
Expand Down
25 changes: 15 additions & 10 deletions src/extension/webview-api/lowdb/chat-sessions-db.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
import path from 'path'
import { aidePaths } from '@extension/file-utils/paths'
import { ChatContextType } from '@shared/types/chat-context'
import {
ChatSessionEntity,
type ChatSession
} from '@shared/entities/chat-session-entity'

import { BaseDB, BaseItem } from './base-db'

export interface ChatSession extends BaseItem {
type: ChatContextType
createdAt: number
updatedAt: number
title: string
}
import { BaseDB } from './base-db'

class ChatSessionsDB extends BaseDB<ChatSession> {
static readonly schemaVersion = 1

constructor() {
super(path.join(aidePaths.getWorkspaceLowdbPath(), 'sessions.json'))
// Use entity's defaults
const defaults = new ChatSessionEntity().getDefaults()

super(
path.join(aidePaths.getWorkspaceLowdbPath(), 'sessions.json'),
defaults,
ChatSessionsDB.schemaVersion
)
}

async search(query: string): Promise<ChatSession[]> {
Expand Down
35 changes: 21 additions & 14 deletions src/extension/webview-api/lowdb/doc-sites-db.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
import path from 'path'
import { aidePaths } from '@extension/file-utils/paths'
import { DocSiteEntity, type DocSite } from '@shared/entities/doc-site-entity'

import { BaseDB, BaseItem } from './base-db'

export interface DocSite extends BaseItem {
name: string
url: string
isCrawled: boolean
isIndexed: boolean
}
import { BaseDB } from './base-db'

class DocSitesDB extends BaseDB<DocSite> {
static readonly schemaVersion = 1

constructor() {
super(path.join(aidePaths.getGlobalLowdbPath(), 'doc-sites.json'))
const defaults = new DocSiteEntity().getDefaults()
super(
path.join(aidePaths.getGlobalLowdbPath(), 'doc-sites.json'),
defaults,
DocSitesDB.schemaVersion
)
}

async add(
item: Omit<DocSite, 'id' | 'isCrawled' | 'isIndexed'> & {
id?: string
}
): Promise<DocSite> {
return super.add({
...item,
isCrawled: false,
isIndexed: false
})
const docSite = new DocSiteEntity(item)
return super.add(docSite)
}

async batchAdd(
items: (Omit<DocSite, 'id' | 'isCrawled' | 'isIndexed'> & {
id?: string
})[]
): Promise<DocSite[]> {
const docSites = items.map(item => new DocSiteEntity(item))
return super.batchAdd(docSites)
}

async updateStatus(
Expand Down
Loading

0 comments on commit b2abd7e

Please sign in to comment.