mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-13 11:21:46 +00:00
feat: reimplement inject css, fix types
This commit is contained in:
62
.eslintrc.js
62
.eslintrc.js
@ -1,8 +1,8 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
extends: [
|
extends: [
|
||||||
'plugin:import/typescript',
|
|
||||||
'eslint:recommended',
|
'eslint:recommended',
|
||||||
'plugin:import/recommended',
|
'plugin:import/recommended',
|
||||||
|
'plugin:import/typescript',
|
||||||
'plugin:@typescript-eslint/eslint-recommended',
|
'plugin:@typescript-eslint/eslint-recommended',
|
||||||
'plugin:@typescript-eslint/recommended',
|
'plugin:@typescript-eslint/recommended',
|
||||||
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
||||||
@ -13,51 +13,30 @@ module.exports = {
|
|||||||
project: './tsconfig.json',
|
project: './tsconfig.json',
|
||||||
tsconfigRootDir: __dirname,
|
tsconfigRootDir: __dirname,
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
ecmaVersion: 'latest',
|
ecmaVersion: 'latest'
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
'arrow-parens': ['error', 'always'],
|
'arrow-parens': ['error', 'always'],
|
||||||
'object-curly-spacing': ['error', 'always'],
|
'object-curly-spacing': ['error', 'always'],
|
||||||
'@typescript-eslint/no-floating-promises': 'off',
|
'@typescript-eslint/no-floating-promises': 'off',
|
||||||
'@typescript-eslint/no-misused-promises': [
|
'@typescript-eslint/no-misused-promises': ['off', { checksVoidReturn: false }],
|
||||||
'off',
|
|
||||||
{ checksVoidReturn: false },
|
|
||||||
],
|
|
||||||
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
|
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
|
||||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
"@typescript-eslint/no-non-null-assertion": "off",
|
||||||
'@typescript-eslint/no-unsafe-assignment': 'off',
|
|
||||||
'import/first': 'error',
|
'import/first': 'error',
|
||||||
'import/newline-after-import': 'error',
|
'import/newline-after-import': 'error',
|
||||||
'import/no-default-export': 'off',
|
'import/no-default-export': 'off',
|
||||||
'import/no-duplicates': 'error',
|
'import/no-duplicates': 'error',
|
||||||
'import/no-unresolved': [
|
'import/no-unresolved': ['error', { ignore: ['^virtual:', '\\?inline$', '\\?raw$', '\\?asset&asarUnpack'] }],
|
||||||
'error',
|
|
||||||
{
|
|
||||||
ignore: [
|
|
||||||
'^virtual:',
|
|
||||||
'\\?inline$',
|
|
||||||
'\\?raw$',
|
|
||||||
'\\?asset&asarUnpack',
|
|
||||||
'^youtubei.js$',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'import/order': [
|
'import/order': [
|
||||||
'error',
|
'error',
|
||||||
{
|
{
|
||||||
groups: [
|
'groups': ['builtin', 'external', ['internal', 'index', 'sibling'], 'parent', 'type'],
|
||||||
'builtin',
|
|
||||||
'external',
|
|
||||||
['internal', 'index', 'sibling'],
|
|
||||||
'parent',
|
|
||||||
'type',
|
|
||||||
],
|
|
||||||
'newlines-between': 'always-and-inside-groups',
|
'newlines-between': 'always-and-inside-groups',
|
||||||
alphabetize: { order: 'ignore', caseInsensitive: false },
|
'alphabetize': {order: 'ignore', caseInsensitive: false}
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
'import/prefer-default-export': 'off',
|
'import/prefer-default-export': 'off',
|
||||||
camelcase: ['error', { properties: 'never' }],
|
'camelcase': ['error', {properties: 'never'}],
|
||||||
'class-methods-use-this': 'off',
|
'class-methods-use-this': 'off',
|
||||||
'lines-around-comment': [
|
'lines-around-comment': [
|
||||||
'error',
|
'error',
|
||||||
@ -70,21 +49,17 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
'max-len': 'off',
|
'max-len': 'off',
|
||||||
'no-mixed-operators': 'error',
|
'no-mixed-operators': 'error',
|
||||||
'no-multi-spaces': ['error', { ignoreEOLComments: true }],
|
'no-multi-spaces': ['error', {ignoreEOLComments: true}],
|
||||||
'no-tabs': 'error',
|
'no-tabs': 'error',
|
||||||
'no-void': 'error',
|
'no-void': 'error',
|
||||||
'no-empty': 'off',
|
'no-empty': 'off',
|
||||||
'prefer-promise-reject-errors': 'off',
|
'prefer-promise-reject-errors': 'off',
|
||||||
quotes: [
|
'quotes': ['error', 'single', {
|
||||||
'error',
|
avoidEscape: true,
|
||||||
'single',
|
allowTemplateLiterals: false,
|
||||||
{
|
}],
|
||||||
avoidEscape: true,
|
|
||||||
allowTemplateLiterals: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'quote-props': ['error', 'consistent'],
|
'quote-props': ['error', 'consistent'],
|
||||||
semi: ['error', 'always'],
|
'semi': ['error', 'always'],
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
browser: true,
|
browser: true,
|
||||||
@ -95,12 +70,11 @@ module.exports = {
|
|||||||
root: true,
|
root: true,
|
||||||
settings: {
|
settings: {
|
||||||
'import/parsers': {
|
'import/parsers': {
|
||||||
'@typescript-eslint/parser': ['.ts', '.tsx'],
|
'@typescript-eslint/parser': ['.ts']
|
||||||
},
|
},
|
||||||
'import/resolver': {
|
'import/resolver': {
|
||||||
typescript: {
|
typescript: {},
|
||||||
alwaysTryTypes: true,
|
exports: {},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -157,7 +157,6 @@
|
|||||||
"electron-store": "8.1.0",
|
"electron-store": "8.1.0",
|
||||||
"electron-unhandled": "4.0.1",
|
"electron-unhandled": "4.0.1",
|
||||||
"electron-updater": "6.1.4",
|
"electron-updater": "6.1.4",
|
||||||
"eslint-import-resolver-typescript": "^3.6.1",
|
|
||||||
"fast-average-color": "9.4.0",
|
"fast-average-color": "9.4.0",
|
||||||
"fast-equals": "^5.0.1",
|
"fast-equals": "^5.0.1",
|
||||||
"filenamify": "6.0.0",
|
"filenamify": "6.0.0",
|
||||||
@ -180,7 +179,7 @@
|
|||||||
"@types/electron-localshortcut": "3.1.3",
|
"@types/electron-localshortcut": "3.1.3",
|
||||||
"@types/howler": "2.2.11",
|
"@types/howler": "2.2.11",
|
||||||
"@types/html-to-text": "9.0.4",
|
"@types/html-to-text": "9.0.4",
|
||||||
"@typescript-eslint/eslint-plugin": "6.10.0",
|
"@typescript-eslint/eslint-plugin": "6.12.0",
|
||||||
"bufferutil": "4.0.8",
|
"bufferutil": "4.0.8",
|
||||||
"builtin-modules": "^3.3.0",
|
"builtin-modules": "^3.3.0",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
@ -189,7 +188,9 @@
|
|||||||
"electron-builder": "24.6.4",
|
"electron-builder": "24.6.4",
|
||||||
"electron-devtools-installer": "3.2.0",
|
"electron-devtools-installer": "3.2.0",
|
||||||
"electron-vite": "1.0.28",
|
"electron-vite": "1.0.28",
|
||||||
"eslint": "8.53.0",
|
"eslint": "8.54.0",
|
||||||
|
"eslint-import-resolver-exports": "1.0.0-beta.5",
|
||||||
|
"eslint-import-resolver-typescript": "3.6.1",
|
||||||
"eslint-plugin-import": "2.29.0",
|
"eslint-plugin-import": "2.29.0",
|
||||||
"eslint-plugin-prettier": "5.0.1",
|
"eslint-plugin-prettier": "5.0.1",
|
||||||
"glob": "10.3.10",
|
"glob": "10.3.10",
|
||||||
|
|||||||
268
pnpm-lock.yaml
generated
268
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,9 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
||||||
import { BrowserWindow, ipcMain } from 'electron';
|
import { BrowserWindow, ipcMain } from 'electron';
|
||||||
|
|
||||||
import { deepmerge } from 'deepmerge-ts';
|
import { deepmerge } from 'deepmerge-ts';
|
||||||
import { mainPlugins } from 'virtual:plugins';
|
import { mainPlugins } from 'virtual:plugins';
|
||||||
|
|
||||||
import { PluginDef } from '@/types/plugins';
|
import { PluginConfig, PluginDef } from '@/types/plugins';
|
||||||
import { BackendContext } from '@/types/contexts';
|
import { BackendContext } from '@/types/contexts';
|
||||||
import config from '@/config';
|
import config from '@/config';
|
||||||
import { startPlugin, stopPlugin } from '@/utils';
|
import { startPlugin, stopPlugin } from '@/utils';
|
||||||
@ -14,35 +12,37 @@ const loadedPluginMap: Record<string, PluginDef> = {};
|
|||||||
|
|
||||||
const createContext = (id: string, win: BrowserWindow): BackendContext => ({
|
const createContext = (id: string, win: BrowserWindow): BackendContext => ({
|
||||||
getConfig: () =>
|
getConfig: () =>
|
||||||
// @ts-expect-error ts dum dum
|
|
||||||
deepmerge(
|
deepmerge(
|
||||||
mainPlugins[id].config,
|
mainPlugins[id].config,
|
||||||
config.get(`plugins.${id}`) ?? { enabled: false },
|
config.get(`plugins.${id}`) ?? { enabled: false },
|
||||||
),
|
) as PluginConfig,
|
||||||
setConfig: (newConfig) => {
|
setConfig: (newConfig) => {
|
||||||
config.setPartial(`plugins.${id}`, newConfig);
|
config.setPartial(`plugins.${id}`, newConfig);
|
||||||
},
|
},
|
||||||
|
|
||||||
send: (event: string, ...args: unknown[]) => {
|
ipc: {
|
||||||
win.webContents.send(event, ...args);
|
send: (event: string, ...args: unknown[]) => {
|
||||||
},
|
win.webContents.send(event, ...args);
|
||||||
// @ts-expect-error ts dum dum
|
},
|
||||||
handle: (event: string, listener) => {
|
handle: (event: string, listener: CallableFunction) => {
|
||||||
// @ts-expect-error ts dum dum
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
ipcMain.handle(event, (_, ...args) => listener(...(args as never)));
|
ipcMain.handle(event, (_, ...args: unknown[]) => listener(...args));
|
||||||
},
|
},
|
||||||
// @ts-expect-error ts dum dum
|
on: (event: string, listener: CallableFunction) => {
|
||||||
on: (event: string, listener) => {
|
ipcMain.on(event, (_, ...args: unknown[]) => {
|
||||||
// @ts-expect-error ts dum dum
|
listener(...args);
|
||||||
ipcMain.on(event, (_, ...args) => listener(...(args as never)));
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
window: win,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const forceUnloadMainPlugin = async (
|
export const forceUnloadMainPlugin = async (
|
||||||
id: string,
|
id: string,
|
||||||
win: BrowserWindow,
|
win: BrowserWindow,
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const plugin = loadedPluginMap[id]!;
|
const plugin = loadedPluginMap[id];
|
||||||
if (!plugin) return;
|
if (!plugin) return;
|
||||||
|
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
|||||||
@ -15,6 +15,17 @@ const createContext = (id: string): RendererContext => ({
|
|||||||
setConfig: async (newConfig) => {
|
setConfig: async (newConfig) => {
|
||||||
await window.ipcRenderer.invoke('set-config', id, newConfig);
|
await window.ipcRenderer.invoke('set-config', id, newConfig);
|
||||||
},
|
},
|
||||||
|
ipc: {
|
||||||
|
send: (event: string, ...args: unknown[]) => {
|
||||||
|
window.ipcRenderer.send(event, ...args);
|
||||||
|
},
|
||||||
|
invoke: (event: string, ...args: unknown[]) => window.ipcRenderer.invoke(event, ...args),
|
||||||
|
on: (event: string, listener: CallableFunction) => {
|
||||||
|
window.ipcRenderer.on(event, (_, ...args: unknown[]) => {
|
||||||
|
listener(...args);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const forceUnloadRendererPlugin = (id: string) => {
|
export const forceUnloadRendererPlugin = (id: string) => {
|
||||||
@ -27,7 +38,7 @@ export const forceUnloadRendererPlugin = (id: string) => {
|
|||||||
if (!plugin) return;
|
if (!plugin) return;
|
||||||
|
|
||||||
stopPlugin(id, plugin, { ctx: 'renderer', context: createContext(id) });
|
stopPlugin(id, plugin, { ctx: 'renderer', context: createContext(id) });
|
||||||
if (plugin.renderer?.stylesheet)
|
if (plugin?.stylesheets)
|
||||||
document.querySelector(`style#plugin-${id}`)?.remove();
|
document.querySelector(`style#plugin-${id}`)?.remove();
|
||||||
|
|
||||||
console.log('[YTMusic]', `"${id}" plugin is unloaded`);
|
console.log('[YTMusic]', `"${id}" plugin is unloaded`);
|
||||||
@ -42,14 +53,14 @@ export const forceLoadRendererPlugin = (id: string) => {
|
|||||||
context: createContext(id),
|
context: createContext(id),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (hasEvaled || plugin.renderer?.stylesheet) {
|
if (hasEvaled || plugin?.stylesheets) {
|
||||||
loadedPluginMap[id] = plugin;
|
loadedPluginMap[id] = plugin;
|
||||||
|
|
||||||
if (plugin.renderer?.stylesheet)
|
if (plugin?.stylesheets)
|
||||||
document.head.appendChild(
|
document.head.appendChild(
|
||||||
Object.assign(document.createElement('style'), {
|
Object.assign(document.createElement('style'), {
|
||||||
id: `plugin-${id}`,
|
id: `plugin-${id}`,
|
||||||
innerHTML: plugin.renderer?.stylesheet ?? '',
|
innerHTML: plugin?.stylesheets ?? '',
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -3,5 +3,5 @@ import style from './style.css?inline';
|
|||||||
|
|
||||||
export default createPlugin({
|
export default createPlugin({
|
||||||
name: 'Blur Navigation Bar',
|
name: 'Blur Navigation Bar',
|
||||||
renderer: { stylesheet: style },
|
renderer: { stylesheets: [style] },
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,9 +1,5 @@
|
|||||||
import { rendererPlugins } from 'virtual:plugins';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PluginBaseConfig,
|
PluginBaseConfig,
|
||||||
PluginBuilder,
|
|
||||||
RendererPluginFactory,
|
|
||||||
} from '@/plugins/utils/builder';
|
} from '@/plugins/utils/builder';
|
||||||
|
|
||||||
import { startingPages } from './providers/extracted-data';
|
import { startingPages } from './providers/extracted-data';
|
||||||
@ -81,6 +77,13 @@ function onApiLoaded() {
|
|||||||
{ passive: true },
|
{ passive: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Object.values(getAllLoadedRendererPlugins())
|
||||||
|
.forEach((plugin) => {
|
||||||
|
if (typeof plugin.renderer !== 'function') {
|
||||||
|
plugin.renderer?.onPlayerApiReady?.(api!);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
window.ipcRenderer.send('ytmd:player-api-loaded');
|
window.ipcRenderer.send('ytmd:player-api-loaded');
|
||||||
|
|
||||||
// Navigate to "Starting page"
|
// Navigate to "Starting page"
|
||||||
@ -133,6 +136,9 @@ function onApiLoaded() {
|
|||||||
forceLoadRendererPlugin(id);
|
forceLoadRendererPlugin(id);
|
||||||
if (api) {
|
if (api) {
|
||||||
const plugin = getLoadedRendererPlugin(id);
|
const plugin = getLoadedRendererPlugin(id);
|
||||||
|
if (plugin && typeof plugin.renderer !== 'function') {
|
||||||
|
plugin.renderer?.onPlayerApiReady?.(api);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -141,6 +147,9 @@ function onApiLoaded() {
|
|||||||
'config-changed',
|
'config-changed',
|
||||||
(_event, id: string, newConfig: PluginBaseConfig) => {
|
(_event, id: string, newConfig: PluginBaseConfig) => {
|
||||||
const plugin = getAllLoadedRendererPlugins()[id];
|
const plugin = getAllLoadedRendererPlugins()[id];
|
||||||
|
if (plugin && typeof plugin.renderer !== 'function') {
|
||||||
|
plugin.renderer?.onConfigChange?.(newConfig);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,33 +1,32 @@
|
|||||||
import type { IpcMain, IpcRenderer, BrowserWindow } from 'electron';
|
import type { BrowserWindow } from 'electron';
|
||||||
import type { PluginConfig } from '@/types/plugins';
|
import type { PluginConfig } from '@/types/plugins';
|
||||||
|
|
||||||
export interface BackendContext {
|
export interface BaseContext {
|
||||||
getConfig(): PluginConfig;
|
getConfig(): PluginConfig;
|
||||||
setConfig(conf: Omit<PluginConfig, 'enabled'>): void;
|
setConfig(conf: Omit<PluginConfig, 'enabled'>): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BackendContext extends BaseContext {
|
||||||
ipc: {
|
ipc: {
|
||||||
|
send: (event: string, ...args: unknown[]) => void;
|
||||||
handle: (event: string, listener: CallableFunction) => void;
|
handle: (event: string, listener: CallableFunction) => void;
|
||||||
on: (event: string, listener: CallableFunction) => void;
|
on: (event: string, listener: CallableFunction) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
win: BrowserWindow;
|
window: BrowserWindow;
|
||||||
electron: typeof import('electron');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MenuContext {
|
export interface MenuContext extends BaseContext {
|
||||||
getConfig(): PluginConfig;
|
|
||||||
setConfig(conf: Omit<PluginConfig, 'enabled'>): void;
|
|
||||||
|
|
||||||
window: BrowserWindow;
|
window: BrowserWindow;
|
||||||
refresh: () => Promise<void> | void;
|
refresh: () => Promise<void> | void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PreloadContext {
|
export interface PreloadContext extends BaseContext {}
|
||||||
getConfig(): PluginConfig;
|
|
||||||
setConfig(conf: Omit<PluginConfig, 'enabled'>): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RendererContext {
|
export interface RendererContext extends BaseContext {
|
||||||
getConfig(): PluginConfig;
|
ipc: {
|
||||||
setConfig(conf: Omit<PluginConfig, 'enabled'>): void;
|
send: (event: string, ...args: unknown[]) => void;
|
||||||
|
invoke: (event: string, ...args: unknown[]) => Promise<unknown>;
|
||||||
|
on: (event: string, listener: CallableFunction) => void;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import type { YoutubePlayer } from '@/types/youtube-player';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
BackendContext,
|
BackendContext,
|
||||||
MenuContext,
|
MenuContext,
|
||||||
@ -11,15 +13,17 @@ export type PluginConfig = {
|
|||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
} & Record<string, unknown>;
|
} & Record<string, unknown>;
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
type PluginExtra = Record<string, unknown>;
|
||||||
type PluginExtra = Record<string, any>;
|
|
||||||
|
|
||||||
type PluginLifecycle<T> =
|
export type PluginLifecycleSimple<T> = (ctx: T) => void | Promise<void>;
|
||||||
| ((ctx: T) => void | Promise<void>)
|
export type PluginLifecycleExtra<T> = {
|
||||||
| ({
|
start?: PluginLifecycleSimple<T>;
|
||||||
start?(ctx: T): void | Promise<void>;
|
stop?: PluginLifecycleSimple<T>;
|
||||||
stop?(ctx: T): void | Promise<void>;
|
onConfigChange?: (newConfig: PluginConfig) => void | Promise<void>;
|
||||||
} & PluginExtra);
|
onPlayerApiReady?: (playerApi: YoutubePlayer) => void | Promise<void>;
|
||||||
|
} & PluginExtra;
|
||||||
|
|
||||||
|
export type PluginLifecycle<T> = PluginLifecycleSimple<T> | PluginLifecycleExtra<T>;
|
||||||
|
|
||||||
export interface PluginDef {
|
export interface PluginDef {
|
||||||
name: string;
|
name: string;
|
||||||
@ -28,11 +32,10 @@ export interface PluginDef {
|
|||||||
config: PluginConfig;
|
config: PluginConfig;
|
||||||
|
|
||||||
menu?: (ctx: MenuContext) => Electron.MenuItemConstructorOptions[];
|
menu?: (ctx: MenuContext) => Electron.MenuItemConstructorOptions[];
|
||||||
|
stylesheets?: string[];
|
||||||
restartNeeded?: boolean;
|
restartNeeded?: boolean;
|
||||||
|
|
||||||
backend?: PluginLifecycle<BackendContext>;
|
backend?: PluginLifecycle<BackendContext>;
|
||||||
preload?: PluginLifecycle<PreloadContext>;
|
preload?: PluginLifecycle<PreloadContext>;
|
||||||
renderer?: PluginLifecycle<RendererContext> & {
|
renderer?: PluginLifecycle<RendererContext>;
|
||||||
stylesheet?: string;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,15 @@
|
|||||||
import {
|
import type {
|
||||||
BackendContext,
|
BackendContext,
|
||||||
PreloadContext,
|
PreloadContext,
|
||||||
RendererContext,
|
RendererContext,
|
||||||
} from '@/types/contexts';
|
} from '@/types/contexts';
|
||||||
import { PluginDef, PluginConfig } from '@/types/plugins';
|
|
||||||
|
import type {
|
||||||
|
PluginDef,
|
||||||
|
PluginConfig,
|
||||||
|
PluginLifecycleExtra,
|
||||||
|
PluginLifecycleSimple,
|
||||||
|
} from '@/types/plugins';
|
||||||
|
|
||||||
export const createPlugin = (
|
export const createPlugin = (
|
||||||
def: Omit<PluginDef, 'config'> & {
|
def: Omit<PluginDef, 'config'> & {
|
||||||
@ -17,11 +23,10 @@ type Options =
|
|||||||
| { ctx: 'renderer'; context: RendererContext };
|
| { ctx: 'renderer'; context: RendererContext };
|
||||||
|
|
||||||
export const startPlugin = (id: string, def: PluginDef, options: Options) => {
|
export const startPlugin = (id: string, def: PluginDef, options: Options) => {
|
||||||
const lifecycle: (ctx: (typeof options)['context']) => void =
|
const lifecycle =
|
||||||
typeof def[options.ctx] === 'function'
|
typeof def[options.ctx] === 'function'
|
||||||
? def[options.ctx]
|
? def[options.ctx] as PluginLifecycleSimple<Options['context']>
|
||||||
: // @ts-expect-error TS is dum dum
|
: (def[options.ctx] as PluginLifecycleExtra<Options['context']>)?.start;
|
||||||
def[options.ctx]?.start;
|
|
||||||
|
|
||||||
if (!lifecycle) return false;
|
if (!lifecycle) return false;
|
||||||
|
|
||||||
@ -29,7 +34,6 @@ export const startPlugin = (id: string, def: PluginDef, options: Options) => {
|
|||||||
const start = performance.now();
|
const start = performance.now();
|
||||||
lifecycle(options.context);
|
lifecycle(options.context);
|
||||||
|
|
||||||
// prettier-ignore
|
|
||||||
console.log(`[YTM] Executed ${id}::${options.ctx} in ${performance.now() - start} ms`);
|
console.log(`[YTM] Executed ${id}::${options.ctx} in ${performance.now() - start} ms`);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -43,15 +47,13 @@ export const stopPlugin = (id: string, def: PluginDef, options: Options) => {
|
|||||||
if (!def[options.ctx]) return false;
|
if (!def[options.ctx]) return false;
|
||||||
if (typeof def[options.ctx] === 'function') return false;
|
if (typeof def[options.ctx] === 'function') return false;
|
||||||
|
|
||||||
// @ts-expect-error TS is dum dum
|
const stop = def[options.ctx] as PluginLifecycleExtra<Options['context']>['stop'];
|
||||||
const stop: (ctx: typeof options.context) => void = def[options.ctx]?.stop;
|
|
||||||
if (!stop) return false;
|
if (!stop) return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const start = performance.now();
|
const start = performance.now();
|
||||||
stop(options.context);
|
stop(options.context);
|
||||||
|
|
||||||
// prettier-ignore
|
|
||||||
console.log(`[YTM] Executed ${id}::${options.ctx} in ${performance.now() - start} ms`);
|
console.log(`[YTM] Executed ${id}::${options.ctx} in ${performance.now() - start} ms`);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -6,13 +6,13 @@ import { Project, ts, ObjectLiteralExpression } from 'ts-morph';
|
|||||||
|
|
||||||
import type { PluginOption } from 'vite';
|
import type { PluginOption } from 'vite';
|
||||||
|
|
||||||
export default function (mode: 'backend' | 'preload' | 'renderer' | 'none') {
|
export default function (mode: 'backend' | 'preload' | 'renderer' | 'none'): PluginOption {
|
||||||
const pluginFilter = createFilter([
|
const pluginFilter = createFilter([
|
||||||
'src/plugins/*/index.{js,ts}',
|
'src/plugins/*/index.{js,ts}',
|
||||||
'src/plugins/*',
|
'src/plugins/*',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return <PluginOption>{
|
return {
|
||||||
name: 'ytm-plugin-loader',
|
name: 'ytm-plugin-loader',
|
||||||
async load(id) {
|
async load(id) {
|
||||||
if (!pluginFilter(id)) return null;
|
if (!pluginFilter(id)) return null;
|
||||||
@ -98,7 +98,6 @@ export default function (mode: 'backend' | 'preload' | 'renderer' | 'none') {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
code: src.getText(),
|
code: src.getText(),
|
||||||
ast: src,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user