mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-12 19:01:47 +00:00
175 lines
4.3 KiB
TypeScript
175 lines
4.3 KiB
TypeScript
import { t } from '@/i18n';
|
|
|
|
import type {
|
|
BackendContext,
|
|
PreloadContext,
|
|
RendererContext,
|
|
} from '@/types/contexts';
|
|
|
|
import type {
|
|
PluginDef,
|
|
PluginConfig,
|
|
PluginLifecycleExtra,
|
|
PluginLifecycleSimple,
|
|
PluginLifecycle,
|
|
RendererPluginLifecycle,
|
|
} from '@/types/plugins';
|
|
|
|
export const LoggerPrefix = '[YTMusic]';
|
|
|
|
export const createPlugin = <
|
|
BackendProperties,
|
|
PreloadProperties,
|
|
RendererProperties,
|
|
Config extends PluginConfig = PluginConfig,
|
|
>(
|
|
def: PluginDef<
|
|
BackendProperties,
|
|
PreloadProperties,
|
|
RendererProperties,
|
|
Config
|
|
> & {
|
|
config?: Omit<Config, 'enabled'> & {
|
|
enabled: boolean;
|
|
};
|
|
},
|
|
) => def;
|
|
|
|
export const createBackend = <
|
|
BackendProperties,
|
|
Config extends PluginConfig = PluginConfig,
|
|
>(
|
|
back: {
|
|
[Key in keyof BackendProperties]: BackendProperties[Key];
|
|
} & PluginLifecycle<Config, BackendContext<Config>, BackendProperties>,
|
|
) => back;
|
|
|
|
export const createPreload = <
|
|
PreloadProperties,
|
|
Config extends PluginConfig = PluginConfig,
|
|
>(
|
|
preload: {
|
|
[Key in keyof PreloadProperties]: PreloadProperties[Key];
|
|
} & PluginLifecycle<Config, PreloadContext<Config>, PreloadProperties>,
|
|
) => preload;
|
|
|
|
export const createRenderer = <
|
|
RendererProperties,
|
|
Config extends PluginConfig = PluginConfig,
|
|
>(
|
|
renderer: {
|
|
[Key in keyof RendererProperties]: RendererProperties[Key];
|
|
} & RendererPluginLifecycle<
|
|
Config,
|
|
RendererContext<Config>,
|
|
RendererProperties
|
|
>,
|
|
) => renderer;
|
|
|
|
type Options<Config extends PluginConfig> =
|
|
| { ctx: 'backend'; context: BackendContext<Config> }
|
|
| { ctx: 'preload'; context: PreloadContext<Config> }
|
|
| { ctx: 'renderer'; context: RendererContext<Config> };
|
|
|
|
export const startPlugin = async <Config extends PluginConfig>(
|
|
id: string,
|
|
def: PluginDef<unknown, unknown, unknown, Config>,
|
|
options: Options<Config>,
|
|
) => {
|
|
const lifecycle =
|
|
typeof def[options.ctx] === 'function'
|
|
? (def[options.ctx] as PluginLifecycleSimple<Config, unknown>)
|
|
: (
|
|
def[options.ctx] as PluginLifecycleExtra<
|
|
Config,
|
|
typeof options.context,
|
|
unknown
|
|
>
|
|
)?.start;
|
|
|
|
try {
|
|
// HACK: for bind 'this' to context
|
|
const defContext = def[options.ctx];
|
|
if (defContext && typeof defContext !== 'function') {
|
|
Object.entries(defContext).forEach(([key, value]) => {
|
|
if (typeof value === 'function') {
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
defContext[key as keyof typeof defContext] = value.bind(defContext);
|
|
}
|
|
});
|
|
}
|
|
|
|
const start = performance.now();
|
|
|
|
await lifecycle?.call(
|
|
defContext,
|
|
options.context as Config & typeof options.context,
|
|
);
|
|
|
|
console.log(
|
|
LoggerPrefix,
|
|
t('common.console.plugins.executed-at-ms', {
|
|
pluginName: id,
|
|
contextName: options.ctx,
|
|
ms: (performance.now() - start).toFixed(2),
|
|
}),
|
|
);
|
|
|
|
return lifecycle ? true : null;
|
|
} catch (err) {
|
|
console.error(
|
|
LoggerPrefix,
|
|
t('common.console.plugins.execute-failed', {
|
|
pluginName: id,
|
|
contextName: options.ctx,
|
|
}),
|
|
);
|
|
console.trace(err);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
export const stopPlugin = async <Config extends PluginConfig>(
|
|
id: string,
|
|
def: PluginDef<unknown, unknown, unknown, Config>,
|
|
options: Options<Config>,
|
|
) => {
|
|
if (!def || !def[options.ctx]) return false;
|
|
if (typeof def[options.ctx] === 'function') return false;
|
|
|
|
const defCtx = def[options.ctx] as
|
|
| { stop: PluginLifecycleSimple<Config, unknown> }
|
|
| undefined;
|
|
if (!defCtx?.stop) return null;
|
|
|
|
try {
|
|
const stop = defCtx.stop;
|
|
const start = performance.now();
|
|
await stop.call(
|
|
def[options.ctx],
|
|
options.context as Config & typeof options.context,
|
|
);
|
|
|
|
console.log(
|
|
LoggerPrefix,
|
|
t('common.console.plugins.executed-at-ms', {
|
|
pluginName: id,
|
|
contextName: options.ctx,
|
|
ms: performance.now() - start,
|
|
}),
|
|
);
|
|
|
|
return true;
|
|
} catch (err) {
|
|
console.error(
|
|
LoggerPrefix,
|
|
t('common.console.plugins.execute-failed', {
|
|
pluginName: id,
|
|
contextName: options.ctx,
|
|
}),
|
|
);
|
|
console.trace(err);
|
|
return false;
|
|
}
|
|
};
|