chore: maintain electron build

This commit is contained in:
Louis 2025-03-27 15:21:13 +07:00
parent a0c00d660e
commit 68d7dec23b
No known key found for this signature in database
GPG Key ID: 44FA9F4D33C37DE2
10 changed files with 59 additions and 39 deletions

View File

@ -13,7 +13,11 @@ const executeOnMain: (extension: string, method: string, ...args: any[]) => Prom
extension, extension,
method, method,
...args ...args
) => globalThis.core?.api?.invokeExtensionFunc(extension, method, ...args) ) => {
if ('electronAPI' in window && window.electronAPI)
return globalThis.core?.api?.invokeExtensionFunc(extension, method, ...args)
return () => {}
}
/** /**
* Gets Jan's data folder path. * Gets Jan's data folder path.

View File

@ -8,7 +8,7 @@ import {
normalizeFilePath, normalizeFilePath,
getJanDataFolderPath, getJanDataFolderPath,
} from '../../helper' } from '../../helper'
import { readdirSync } from 'fs' import { readdirSync, readFileSync } from 'fs'
export class App implements Processor { export class App implements Processor {
observer?: Function observer?: Function
@ -26,8 +26,8 @@ export class App implements Processor {
/** /**
* Joins multiple paths together, respect to the current OS. * Joins multiple paths together, respect to the current OS.
*/ */
joinPath(args: any[]) { joinPath(args: any) {
return join(...args) return join(...('args' in args ? args.args : args))
} }
/** /**
@ -86,6 +86,16 @@ export class App implements Processor {
return readdirSync(themesPath) return readdirSync(themesPath)
} }
/**
* Read theme.json
* @param theme
* @returns
*/
readTheme({ theme }: { theme: string }) {
const themePath = join(getJanDataFolderPath(), 'themes', theme, 'theme.json')
return readFileSync(themePath, { encoding: 'utf-8' })
}
async updateAppConfiguration(args: any) { async updateAppConfiguration(args: any) {
await updateAppConfiguration(args) await updateAppConfiguration(args)
} }

View File

@ -21,18 +21,21 @@ export class FileSystem implements Processor {
return import(FileSystem.moduleName).then((mdl) => return import(FileSystem.moduleName).then((mdl) =>
mdl[route]( mdl[route](
...args.map((arg: any, index: number) => { ...args.map((arg: any, index: number) => {
if(index !== 0) { const arg0 = args[0]
if ('args' in arg0) arg = arg0.args
if (Array.isArray(arg)) arg = arg[0]
if (index !== 0) {
return arg return arg
} }
if (index === 0 && typeof arg !== 'string') { if (index === 0 && typeof arg !== 'string') {
throw new Error(`Invalid argument ${JSON.stringify(args)}`) throw new Error(`Invalid argument ${JSON.stringify(args)}`)
} }
const path = const path =
(arg.startsWith(`file:/`) || arg.startsWith(`file:\\`)) arg.startsWith(`file:/`) || arg.startsWith(`file:\\`)
? join(getJanDataFolderPath(), normalizeFilePath(arg)) ? join(getJanDataFolderPath(), normalizeFilePath(arg))
: arg : arg
if(path.startsWith(`http://`) || path.startsWith(`https://`)) { if (path.startsWith(`http://`) || path.startsWith(`https://`)) {
return path return path
} }
const absolutePath = resolve(path) const absolutePath = resolve(path)
@ -88,5 +91,4 @@ export class FileSystem implements Processor {
}) })
}) })
} }
} }

View File

@ -18,9 +18,7 @@ export const getAppConfigurations = (): AppConfiguration => {
if (!fs.existsSync(configurationFile)) { if (!fs.existsSync(configurationFile)) {
// create default app config if we don't have one // create default app config if we don't have one
console.debug( console.debug(`App config not found, creating default config at ${configurationFile}`)
`App config not found, creating default config at ${configurationFile}`
)
fs.writeFileSync(configurationFile, JSON.stringify(appDefaultConfiguration)) fs.writeFileSync(configurationFile, JSON.stringify(appDefaultConfiguration))
return appDefaultConfiguration return appDefaultConfiguration
} }
@ -31,28 +29,23 @@ export const getAppConfigurations = (): AppConfiguration => {
) )
return appConfigurations return appConfigurations
} catch (err) { } catch (err) {
console.error( console.error(`Failed to read app config, return default config instead! Err: ${err}`)
`Failed to read app config, return default config instead! Err: ${err}`
)
return defaultAppConfig() return defaultAppConfig()
} }
} }
const getConfigurationFilePath = () => const getConfigurationFilePath = () =>
join( join(
global.core?.appPath() || global.core?.appPath() || process.env[process.platform == 'win32' ? 'USERPROFILE' : 'HOME'],
process.env[process.platform == 'win32' ? 'USERPROFILE' : 'HOME'],
configurationFileName configurationFileName
) )
export const updateAppConfiguration = ( export const updateAppConfiguration = ({
configuration,
}: {
configuration: AppConfiguration configuration: AppConfiguration
): Promise<void> => { }): Promise<void> => {
const configurationFile = getConfigurationFilePath() const configurationFile = getConfigurationFilePath()
console.debug(
'updateAppConfiguration, configurationFile: ',
configurationFile
)
fs.writeFileSync(configurationFile, JSON.stringify(configuration)) fs.writeFileSync(configurationFile, JSON.stringify(configuration))
return Promise.resolve() return Promise.resolve()
@ -87,14 +80,11 @@ export const getJanExtensionsPath = (): string => {
*/ */
export const defaultAppConfig = (): AppConfiguration => { export const defaultAppConfig = (): AppConfiguration => {
const { app } = require('electron') const { app } = require('electron')
const defaultJanDataFolder = join( const defaultJanDataFolder = join(app?.getPath('userData') ?? os?.homedir() ?? '', 'data')
app?.getPath('userData') ?? os?.homedir() ?? '',
'data'
)
return { return {
data_folder: data_folder:
process.env.CI === 'e2e' process.env.CI === 'e2e'
? (process.env.APP_CONFIG_PATH ?? resolve('./test-data')) ? process.env.APP_CONFIG_PATH ?? resolve('./test-data')
: defaultJanDataFolder, : defaultJanDataFolder,
quick_ask: false, quick_ask: false,
} }

View File

@ -52,6 +52,7 @@ export enum AppRoute {
systemInformation = 'systemInformation', systemInformation = 'systemInformation',
showToast = 'showToast', showToast = 'showToast',
getThemes = 'getThemes', getThemes = 'getThemes',
readTheme = 'readTheme'
} }
export enum AppEvent { export enum AppEvent {

View File

@ -52,7 +52,7 @@ export default class JanEngineManagementExtension extends EngineManagementExtens
*/ */
async onLoad() { async onLoad() {
// Symlink Engines Directory // Symlink Engines Directory
// await executeOnMain(NODE, 'symlinkEngines') await executeOnMain(NODE, 'symlinkEngines')
// Update default local engine // Update default local engine
this.updateDefaultEngine() this.updateDefaultEngine()

View File

@ -129,6 +129,8 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
) )
if (!Number.isNaN(threads_number)) this.cpu_threads = threads_number if (!Number.isNaN(threads_number)) this.cpu_threads = threads_number
await executeOnMain(NODE, 'run')
this.subscribeToEvents() this.subscribeToEvents()
window.addEventListener('beforeunload', () => { window.addEventListener('beforeunload', () => {
@ -140,6 +142,7 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
console.log('Clean up cortex.cpp services') console.log('Clean up cortex.cpp services')
this.shouldReconnect = false this.shouldReconnect = false
this.clean() this.clean()
await executeOnMain(NODE, 'dispose')
super.onUnload() super.onUnload()
} }

View File

@ -120,6 +120,20 @@ pub fn get_themes(app_handle: tauri::AppHandle) -> Vec<String> {
themes themes
} }
#[tauri::command]
pub fn read_theme(app_handle: tauri::AppHandle, theme_name: String) -> Result<String, String> {
let themes_path = get_jan_data_folder_path(app_handle)
.join("themes")
.join(theme_name.clone())
.join("theme.json");
if themes_path.exists() {
let content = fs::read_to_string(themes_path).map_err(|e| e.to_string())?;
Ok(content)
} else {
Err(format!("Theme {} not found", theme_name.clone()))
}
}
#[tauri::command] #[tauri::command]
pub fn get_configuration_file_path(app_handle: tauri::AppHandle) -> PathBuf { pub fn get_configuration_file_path(app_handle: tauri::AppHandle) -> PathBuf {
let app_path = app_handle.path().app_data_dir().unwrap_or_else(|err| { let app_path = app_handle.path().app_data_dir().unwrap_or_else(|err| {

View File

@ -2,8 +2,6 @@ import { useCallback, useEffect } from 'react'
import { useTheme } from 'next-themes' import { useTheme } from 'next-themes'
import { fs, joinPath } from '@janhq/core'
import { useAtom } from 'jotai' import { useAtom } from 'jotai'
import cssVars from '@/utils/jsonToCssVariables' import cssVars from '@/utils/jsonToCssVariables'
@ -59,13 +57,12 @@ export const useLoadTheme = () => {
setThemeOptions(themesOptions) setThemeOptions(themesOptions)
if (!selectedIdTheme.length) return setSelectedIdTheme('joi-light') if (!selectedIdTheme.length) return setSelectedIdTheme('joi-light')
const filePath = await joinPath([
'file://themes',
selectedIdTheme,
'theme.json',
])
const theme: Theme = JSON.parse(await fs.readFileSync(filePath, 'utf-8')) const theme: Theme = JSON.parse(
await window.core.api.readTheme({
theme: selectedIdTheme,
})
)
setThemeData(theme) setThemeData(theme)
setNativeTheme(theme.nativeTheme) setNativeTheme(theme.nativeTheme)

View File

@ -9,7 +9,6 @@ import {
Model, Model,
ConversationalExtension, ConversationalExtension,
EngineManager, EngineManager,
ToolManager,
ThreadAssistantInfo, ThreadAssistantInfo,
InferenceEngine, InferenceEngine,
} from '@janhq/core' } from '@janhq/core'