diff --git a/package.json b/package.json index 05dcd5d9..30c27bbe 100644 --- a/package.json +++ b/package.json @@ -136,7 +136,6 @@ "dependencies": { "@cliqz/adblocker-electron": "1.26.11", "@cliqz/adblocker-electron-preload": "1.26.11", - "@fastify/deepmerge": "1.3.0", "@ffmpeg.wasm/core-mt": "0.12.0", "@ffmpeg.wasm/main": "0.12.0", "@foobar404/wave": "2.0.4", @@ -157,6 +156,7 @@ "electron-unhandled": "4.0.1", "electron-updater": "6.1.4", "fast-average-color": "9.4.0", + "fast-equals": "^5.0.1", "filenamify": "6.0.0", "howler": "2.2.4", "html-to-text": "9.0.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index abc95b1e..6fe005dc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,9 +19,6 @@ dependencies: '@cliqz/adblocker-electron-preload': specifier: 1.26.11 version: 1.26.11(electron@27.0.4) - '@fastify/deepmerge': - specifier: 1.3.0 - version: 1.3.0 '@ffmpeg.wasm/core-mt': specifier: 0.12.0 version: 0.12.0 @@ -82,6 +79,9 @@ dependencies: fast-average-color: specifier: 9.4.0 version: 9.4.0 + fast-equals: + specifier: ^5.0.1 + version: 5.0.1 filenamify: specifier: 6.0.0 version: 6.0.0 @@ -793,10 +793,6 @@ packages: engines: {node: '>=14'} dev: false - /@fastify/deepmerge@1.3.0: - resolution: {integrity: sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==} - dev: false - /@ffmpeg.wasm/core-mt@0.12.0: resolution: {integrity: sha512-M9pjL7JQX4AYl3WI8vGcPGPTz/O7JmhW8ac/fHA3oXTxoRAPwYSY/OsY1N9C0XahIM0+fxa1QSLN9Ekz8sBM/Q==} dev: false @@ -3082,6 +3078,11 @@ packages: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} dev: true + /fast-equals@5.0.1: + resolution: {integrity: sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==} + engines: {node: '>=6.0.0'} + dev: false + /fast-glob@3.3.1: resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} engines: {node: '>=8.6.0'} diff --git a/src/config/index.ts b/src/config/index.ts index d88c23d8..a618d0ae 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,6 +1,5 @@ import Store from 'electron-store'; - -import { deepmerge as createDeepmerge } from '@fastify/deepmerge'; +import { deepmerge } from 'deepmerge-ts'; import defaultConfig from './defaults'; import plugins from './plugins'; @@ -8,14 +7,13 @@ import store from './store'; import { restart } from '../providers/app-controls'; -const deepmerge = createDeepmerge(); - const set = (key: string, value: unknown) => { store.set(key, value); }; const setPartial = (key: string, value: object) => { - deepmerge(store.get(key) ?? {}, value); - store.set(value); + const newValue = deepmerge(store.get(key) ?? {}, value); + console.log('sival', key, value, newValue); + store.set(newValue); }; function setMenuOption(key: string, value: unknown) { @@ -53,9 +51,8 @@ export default { setPartial, setMenuOption, edit: () => store.openInEditor(), - watch(cb: Parameters[1]) { - store.onDidChange('options', cb); - store.onDidChange('plugins', cb); + watch(cb: Parameters[0]) { + store.onDidAnyChange(cb); }, plugins, }; diff --git a/src/index.ts b/src/index.ts index db4cdf53..a109d396 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,8 +9,8 @@ import unhandled from 'electron-unhandled'; import { autoUpdater } from 'electron-updater'; import electronDebug from 'electron-debug'; import { parse } from 'node-html-parser'; - -import { deepmerge as createDeepmerge } from '@fastify/deepmerge'; +import { deepmerge } from 'deepmerge-ts'; +import { deepEqual } from 'fast-equals'; import config from './config'; @@ -31,8 +31,6 @@ import youtubeMusicCSS from './youtube-music.css?inline'; import type { MainPlugin, PluginBaseConfig, MainPluginContext, MainPluginFactory } from './plugins/utils/builder'; -const deepmerge = createDeepmerge(); - // Catch errors and log them unhandled({ logger: console.error, @@ -106,14 +104,19 @@ const initHook = (win: BrowserWindow) => { ipcMain.handle('get-config', (_, id: keyof PluginBuilderList) => deepmerge(pluginBuilders[id].config, config.get(`plugins.${id}`) ?? {}) as PluginBuilderList[typeof id]['config']); ipcMain.handle('set-config', (_, name: string, obj: object) => config.setPartial(`plugins.${name}`, obj)); - config.watch((newValue) => { - const value = newValue as Record; - const id = Object.keys(pluginBuilders).find((id) => id in value); + config.watch((newValue, oldValue) => { + const newPluginConfigList = (newValue?.plugins ?? {}) as Record; + const oldPluginConfigList = (oldValue?.plugins ?? {}) as Record; - if (id) { - win.webContents.send('config-changed', id, value[id]); - // console.log('config-changed', id, value[id]); - } + Object.entries(newPluginConfigList).forEach(([id, newPluginConfig]) => { + const isEqual = deepEqual(oldPluginConfigList[id], newPluginConfig); + + console.log('check', id, isEqual, ';', oldPluginConfigList[id], newPluginConfig); + if (!isEqual) { + win.webContents.send('config-changed', id, newPluginConfig); + console.log('config-changed', id, newPluginConfig); + } + }); }); }; @@ -148,7 +151,7 @@ async function loadPlugins(win: BrowserWindow) { Key extends keyof PluginBuilderList, Config extends PluginBaseConfig = PluginBuilderList[Key]['config'], >(name: Key): MainPluginContext => ({ - getConfig: () => deepmerge(pluginBuilders[name].config, config.get(`plugins.${name}`) ?? {}) as Config, + getConfig: () => deepmerge(pluginBuilders[name].config, config.get(`plugins.${name}`) ?? {}) as unknown as Config, setConfig: (newConfig) => { config.setPartial(`plugins.${name}`, newConfig); }, diff --git a/src/menu.ts b/src/menu.ts index 314ca8e0..d270d9d9 100644 --- a/src/menu.ts +++ b/src/menu.ts @@ -1,8 +1,7 @@ import is from 'electron-is'; import { app, BrowserWindow, clipboard, dialog, Menu } from 'electron'; import prompt from 'custom-electron-prompt'; - -import { deepmerge as createDeepmerge } from '@fastify/deepmerge'; +import { deepmerge } from 'deepmerge-ts'; import { restart } from './providers/app-controls'; import config from './config'; @@ -24,8 +23,6 @@ const inAppMenuActive = config.plugins.isEnabled('in-app-menu'); const betaPlugins = ['crossfade', 'lumiastream']; -const deepmerge = createDeepmerge(); - const pluginEnabledMenu = (plugin: string, label = '', hasSubmenu = false, refreshMenu: (() => void ) | undefined = undefined): Electron.MenuItemConstructorOptions => ({ label: label || plugin, type: 'checkbox', @@ -56,7 +53,7 @@ export const mainMenuTemplate = async (win: BrowserWindow): Promise(name: Key): MenuPluginContext => ({ - getConfig: () => deepmerge(pluginBuilders[name].config, config.get(`plugins.${name}`) ?? {}) as Config, + getConfig: () => deepmerge(pluginBuilders[name].config, config.get(`plugins.${name}`) ?? {}) as unknown as Config, setConfig: (newConfig) => { config.setPartial(`plugins.${name}`, newConfig); }, diff --git a/src/plugins/ambient-mode/renderer.ts b/src/plugins/ambient-mode/renderer.ts index d1c3728a..105b9a24 100644 --- a/src/plugins/ambient-mode/renderer.ts +++ b/src/plugins/ambient-mode/renderer.ts @@ -84,6 +84,7 @@ export default builder.createRenderer(async ({ getConfig }) => { blurCanvas.style.setProperty('--top', `${-1 * topOffset}px`); blurCanvas.style.setProperty('--blur', `${blur}px`); blurCanvas.style.setProperty('--opacity', `${opacity}`); + console.log('updated!!!'); }; update = applyVideoAttributes; diff --git a/src/preload.ts b/src/preload.ts index 733d697a..5f6ac5d0 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -3,7 +3,7 @@ import is from 'electron-is'; import { pluginBuilders } from 'virtual:PluginBuilders'; -import { deepmerge as createDeepmerge } from '@fastify/deepmerge'; +import { deepmerge } from 'deepmerge-ts'; import config from './config'; @@ -11,13 +11,11 @@ import config from './config'; import { preloadPlugins } from 'virtual:PreloadPlugins'; import { PluginBaseConfig, PluginContext, PreloadPluginFactory } from './plugins/utils/builder'; -const deepmerge = createDeepmerge(); - const createContext = < Key extends keyof PluginBuilderList, Config extends PluginBaseConfig = PluginBuilderList[Key]['config'], >(name: Key): PluginContext => ({ - getConfig: () => deepmerge(pluginBuilders[name].config, config.get(`plugins.${name}`) ?? {}) as Config, + getConfig: () => deepmerge(pluginBuilders[name].config, config.get(`plugins.${name}`) ?? {}) as unknown as Config, setConfig: (newConfig) => { config.setPartial(`plugins.${name}`, newConfig); }, @@ -28,7 +26,12 @@ const preloadedPluginList = []; const pluginConfig = config.plugins.getPlugins(); Object.entries(preloadPlugins) - .filter(([id]) => deepmerge(pluginBuilders[id as keyof PluginBuilderList].config, pluginConfig[id as keyof PluginBuilderList] ?? {}).enabled) + .filter(([id]) => { + const typedId = id as keyof PluginBuilderList; + const config = deepmerge(pluginBuilders[typedId].config, pluginConfig[typedId] ?? {}); + + return config.enabled; + }) .forEach(async ([id]) => { if (Object.hasOwn(preloadPlugins, id)) { const factory = (preloadPlugins as Record>)[id]; diff --git a/src/renderer.ts b/src/renderer.ts index 5a9d122a..603dd21b 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -2,18 +2,16 @@ // eslint-disable-next-line import/order import { rendererPlugins } from 'virtual:RendererPlugins'; -import { deepmerge as createDeepmerge } from '@fastify/deepmerge'; - import { pluginBuilders } from 'virtual:PluginBuilders'; +import { deepmerge } from 'deepmerge-ts'; + import { PluginBaseConfig, RendererPluginContext, RendererPluginFactory } from './plugins/utils/builder'; import { startingPages } from './providers/extracted-data'; import { setupSongControls } from './providers/song-controls-front'; import setupSongInfo from './providers/song-info-front'; -const deepmerge = createDeepmerge(); - let api: Element | null = null; function listenForApiLoad() { @@ -125,7 +123,12 @@ const createContext = < const rendererPluginList = Object.entries(rendererPlugins); const rendererPluginResult = await Promise.allSettled( rendererPluginList - .filter(([id]) => deepmerge(pluginBuilders[id as keyof PluginBuilderList].config, pluginConfig[id as keyof PluginBuilderList] ?? {}).enabled) + .filter(([id]) => { + const typedId = id as keyof PluginBuilderList; + const config = deepmerge(pluginBuilders[typedId].config, pluginConfig[typedId] ?? {}); + + return config.enabled; + }) .map(async ([id, builder]) => { const context = createContext(id as keyof PluginBuilderList); return [id, await (builder as RendererPluginFactory)(context)] as const;