Files
youtube-music/src/loader/preload.ts
2023-12-02 05:01:29 +09:00

115 lines
2.8 KiB
TypeScript

import { deepmerge } from 'deepmerge-ts';
import { allPlugins, preloadPlugins } from 'virtual:plugins';
import { LoggerPrefix, startPlugin, stopPlugin } from '@/utils';
import config from '@/config';
import { t } from '@/i18n';
import type { PreloadContext } from '@/types/contexts';
import type { PluginConfig, PluginDef } from '@/types/plugins';
const loadedPluginMap: Record<
string,
PluginDef<unknown, unknown, unknown>
> = {};
const createContext = (id: string): PreloadContext<PluginConfig> => ({
getConfig: () =>
deepmerge(
allPlugins[id].config ?? { enabled: false },
config.get(`plugins.${id}`) ?? {},
) as PluginConfig,
setConfig: (newConfig) => {
config.setPartial(`plugins.${id}`, newConfig, allPlugins[id].config);
},
});
export const forceUnloadPreloadPlugin = async (id: string) => {
if (!loadedPluginMap[id]) return;
const hasStopped = await stopPlugin(id, loadedPluginMap[id], {
ctx: 'preload',
context: createContext(id),
});
if (hasStopped || (hasStopped === null && loadedPluginMap[id].preload)) {
console.log(
LoggerPrefix,
t('common.console.plugins.unloaded', { pluginName: id }),
);
delete loadedPluginMap[id];
} else {
console.error(
LoggerPrefix,
t('common.console.plugins.unload-failed', { pluginName: id }),
);
}
};
export const forceLoadPreloadPlugin = async (id: string) => {
try {
const plugin = preloadPlugins[id];
if (!plugin) return;
const hasStarted = await startPlugin(id, plugin, {
ctx: 'preload',
context: createContext(id),
});
if (
hasStarted ||
(hasStarted === null &&
typeof plugin.preload !== 'function' &&
plugin.preload)
) {
loadedPluginMap[id] = plugin;
}
console.log(
LoggerPrefix,
t('common.console.plugins.loaded', { pluginName: id }),
);
} catch (err) {
console.error(
LoggerPrefix,
t('common.console.plugins.initialize-failed', { pluginName: id }),
);
console.trace(err);
}
};
export const loadAllPreloadPlugins = () => {
const pluginConfigs = config.plugins.getPlugins();
for (const [pluginId, pluginDef] of Object.entries(preloadPlugins)) {
const config = deepmerge(
pluginDef.config ?? { enable: false },
pluginConfigs[pluginId] ?? {},
);
if (config.enabled) {
forceLoadPreloadPlugin(pluginId);
} else {
if (loadedPluginMap[pluginId]) {
forceUnloadPreloadPlugin(pluginId);
}
}
}
};
export const unloadAllPreloadPlugins = async () => {
for (const id of Object.keys(loadedPluginMap)) {
await forceUnloadPreloadPlugin(id);
}
};
export const getLoadedPreloadPlugin = (
id: string,
): PluginDef<unknown, unknown, unknown> | undefined => {
return loadedPluginMap[id];
};
export const getAllLoadedPreloadPlugins = () => {
return loadedPluginMap;
};