diff --git a/config/index.ts b/config/index.ts index def92fb..e12a4ef 100644 --- a/config/index.ts +++ b/config/index.ts @@ -41,7 +41,8 @@ export default { "editor.bg": "", "editor.logoType": "logo", "editor.fontFamily": "Cascadia Mono, Consolas, 'Courier New', monospace", - "update.hoturl": "https://alist.xieyaxin.top/d/%E8%B5%84%E6%BA%90/%E6%B5%8B%E8%AF%95%E6%96%87%E4%BB%B6.zip?sign=eqy35CR-J1SOQZz0iUN2P3B0BiyZPdYH0362nLXbUhE=:1749085071", + "update.hoturl": + "https://alist.xieyaxin.top/d/%E8%B5%84%E6%BA%90/%E6%B5%8B%E8%AF%95%E6%96%87%E4%BB%B6.zip?sign=eqy35CR-J1SOQZz0iUN2P3B0BiyZPdYH0362nLXbUhE=:1749085071", "update.repo": "wood-desktop", "update.owner": "npmrun", "update.allowDowngrade": false, diff --git a/packages/base/event/main/index copy.ts b/packages/base/event/main/index copy.ts new file mode 100644 index 0000000..901a3e2 --- /dev/null +++ b/packages/base/event/main/index copy.ts @@ -0,0 +1,123 @@ +type FireFN = (...argu: any[]) => void + +// 监听器类型定义,支持优先级 +interface Listener { + fn: F + once: boolean + priority: number +} + +class FireEvent> { + // 使用 Map 存储事件监听器,支持 symbol 键 + private events = new Map>>() + + // 获取事件监听器列表,如果不存在则创建 + private getListeners(name: S): Array> { + if (!this.events.has(name)) { + this.events.set(name, []) + } + return this.events.get(name) as Array> + } + + // 按优先级排序监听器 + private sortListeners(name: S) { + const listeners = this.getListeners(name) + listeners.sort((a, b) => b.priority - a.priority) + } + + // 打印事件和监听器信息 + print() { + console.log("Registered Events:") + this.events.forEach((listeners, name) => { + // 显式处理 symbol 类型 + const keyType = typeof name === "symbol" ? `Symbol(${name.description || ""})` : String(name) + console.log(` ${keyType}: ${listeners.length} listeners`) + }) + } + + // 添加事件监听器,支持优先级 + on(name: S, fn: T[S], priority = 0): this { + const listeners = this.getListeners(name) + listeners.push({ fn, once: false, priority }) + this.sortListeners(name) + return this // 支持链式调用 + } + + // 触发事件 + emit(name: S, ...args: Parameters): this { + const listeners = this.getListeners(name).slice() // 创建副本以避免移除时的问题 + + for (const { fn } of listeners) { + try { + fn(...args) + } catch (error) { + console.error(`Error in event handler for ${String(name)}:`, error) + } + } + + // 移除一次性监听器 + if (listeners.some(l => l.once)) { + this.events.set( + name, + this.getListeners(name).filter(l => !l.once), + ) + } + + return this + } + + // 移除事件监听器 + off(name: S, fn?: T[S]): this { + if (!this.events.has(name)) return this + + const listeners = this.getListeners(name) + + if (!fn) { + // 移除所有监听器 + this.events.delete(name) + } else { + // 移除特定监听器 + const filtered = listeners.filter(l => l.fn !== fn) + if (filtered.length === 0) { + this.events.delete(name) + } else { + this.events.set(name, filtered) + } + } + + return this + } + + // 添加一次性事件监听器 + once(name: S, fn: T[S], priority = 0): this { + const listeners = this.getListeners(name) + listeners.push({ fn, once: true, priority }) + this.sortListeners(name) + return this + } + + // 清除所有事件监听器 + clear(): this { + this.events.clear() + return this + } + + // 获取指定事件的监听器数量 + listenerCount(name: S): number { + return this.events.get(name)?.length || 0 + } + + // 检查事件是否有监听器 + hasListeners(name: S): boolean { + return this.listenerCount(name) > 0 + } + + // 获取所有事件名称 + eventNames(): Array { + return Array.from(this.events.keys()) + } +} + +export function buildEmitter>() { + return new FireEvent() +} diff --git a/packages/base/event/main/index.ts b/packages/base/event/main/index.ts new file mode 100644 index 0000000..77949d6 --- /dev/null +++ b/packages/base/event/main/index.ts @@ -0,0 +1,51 @@ +// type FireKey = string +type FireFN = (...argu: any[]) => void + +class FireEvent> { + #events: Record = {} as any + print() { + Object.keys(this.#events).forEach(key => { + console.log(`${key}: ${this.#events[key]}\n`) + }) + } + on(name: S, fn: T[S]) { + if (!this.#events[name]) { + this.#events[name] = [] + } + this.#events[name].push(fn) + } + emit(name: S, ...argu: Parameters) { + if (this.#events[name]) { + this.#events[name].forEach(fn => { + fn(...argu) + }) + } + } + off(name: S, fn?: T[S]) { + const len = this.#events[name].length + if (!len) { + return + } + if (!fn) { + this.#events[name] = [] + } else { + for (let i = len - 1; i >= 0; i--) { + const _fn = this.#events[name][i] + if (_fn === fn) { + this.#events[name].splice(i, 1) + } + } + } + } + once(name: S, fn: T[S]) { + const _fn: any = (...argu: any[]) => { + fn(...argu) + this.off(name, _fn) + } + this.on(name, _fn) + } +} + +export function buildEmitter>() { + return new FireEvent() +} diff --git a/packages/logger/main.ts b/packages/logger/main.ts index a271fce..80d7f78 100644 --- a/packages/logger/main.ts +++ b/packages/logger/main.ts @@ -1,9 +1,10 @@ import { app, ipcMain } from "electron" import fs from "fs" import path from "path" -import setting from "setting/main" +import config from "config" import * as rfs from "rotating-file-stream" import { LogLevel, LogLevelColor, LogLevelName } from "./common" +import { emitter } from "setting/main/event" // 重置颜色的ANSI代码 const RESET_COLOR = "\x1b[0m" @@ -20,7 +21,7 @@ export interface LoggerOptions { // 默认配置 const DEFAULT_OPTIONS: LoggerOptions = { - level: setting.values("debug"), + level: config.default_config.debug, namespace: "app", console: true, file: true, @@ -259,8 +260,8 @@ export class Logger { // 默认实例 const logger = Logger.getInstance() logger.init() -setting.onChange("debug", function (n) { - logger.setLevel(n.debug) +emitter.on("update", setting => { + logger.setLevel(setting.debug) }) // 应用退出时关闭日志流 diff --git a/packages/setting/main.ts b/packages/setting/main.ts index ea35d8d..7a32fd8 100644 --- a/packages/setting/main.ts +++ b/packages/setting/main.ts @@ -228,3 +228,4 @@ const Setting = new SettingClass() export default Setting export { Setting } +export type { IConfig, IOnFunc } diff --git a/packages/setting/main/event.ts b/packages/setting/main/event.ts new file mode 100644 index 0000000..bd109ef --- /dev/null +++ b/packages/setting/main/event.ts @@ -0,0 +1,6 @@ +import { buildEmitter } from "base/event/main" +import type { IOnFunc } from "setting/main" + +export const emitter = buildEmitter<{ + update: IOnFunc +}>()