feat: plugin load await

This commit is contained in:
JellyBrick
2023-11-29 18:04:37 +09:00
parent 5db759150c
commit bbff0a6bc2
6 changed files with 90 additions and 95 deletions

View File

@ -49,35 +49,33 @@ export const forceUnloadMainPlugin = async (
const plugin = loadedPluginMap[id]; const plugin = loadedPluginMap[id];
if (!plugin) return; if (!plugin) return;
return new Promise<void>((resolve, reject) => { try {
try { const hasStopped = await stopPlugin(id, plugin, {
const hasStopped = stopPlugin(id, plugin, { ctx: 'backend',
ctx: 'backend', context: createContext(id, win),
context: createContext(id, win), });
}); if (
if ( hasStopped ||
hasStopped || (
( hasStopped === null &&
hasStopped === null && typeof plugin.backend !== 'function' && plugin.backend
typeof plugin.backend !== 'function' && plugin.backend )
) ) {
) { delete loadedPluginMap[id];
delete loadedPluginMap[id]; console.log(LoggerPrefix, `"${id}" plugin is unloaded`);
console.log(LoggerPrefix, `"${id}" plugin is unloaded`); return;
resolve(); } else {
} else { console.log(
console.log( LoggerPrefix,
LoggerPrefix, `Cannot unload "${id}" plugin`,
`Cannot unload "${id}" plugin`, );
); return Promise.reject();
reject();
return;
}
} catch (err) {
console.log(LoggerPrefix, `Cannot unload "${id}" plugin: ${String(err)}`);
reject(err);
} }
}); } catch (err) {
console.error(LoggerPrefix, `Cannot unload "${id}" plugin`);
console.trace(err);
return Promise.reject(err);
}
}; };
export const forceLoadMainPlugin = async ( export const forceLoadMainPlugin = async (
@ -87,34 +85,31 @@ export const forceLoadMainPlugin = async (
const plugin = mainPlugins[id]; const plugin = mainPlugins[id];
if (!plugin) return; if (!plugin) return;
return new Promise<void>((resolve, reject) => { try {
try { const hasStarted = await startPlugin(id, plugin, {
const hasStarted = startPlugin(id, plugin, { ctx: 'backend',
ctx: 'backend', context: createContext(id, win),
context: createContext(id, win), });
}); if (
if ( hasStarted ||
hasStarted || (
( hasStarted === null &&
hasStarted === null && typeof plugin.backend !== 'function' && plugin.backend
typeof plugin.backend !== 'function' && plugin.backend )
) ) {
) { loadedPluginMap[id] = plugin;
loadedPluginMap[id] = plugin; } else {
resolve(); console.log(LoggerPrefix, `Cannot load "${id}" plugin`);
} else { return Promise.reject();
console.log(LoggerPrefix, `Cannot load "${id}" plugin`);
reject();
}
} catch (err) {
console.error(
LoggerPrefix,
`Cannot initialize "${id}" plugin: `,
);
console.trace(err);
reject(err);
} }
}); } catch (err) {
console.error(
LoggerPrefix,
`Cannot initialize "${id}" plugin: `,
);
console.trace(err);
return Promise.reject(err);
}
}; };
export const loadAllMainPlugins = async (win: BrowserWindow) => { export const loadAllMainPlugins = async (win: BrowserWindow) => {
@ -134,9 +129,9 @@ export const loadAllMainPlugins = async (win: BrowserWindow) => {
await Promise.allSettled(queue); await Promise.allSettled(queue);
}; };
export const unloadAllMainPlugins = (win: BrowserWindow) => { export const unloadAllMainPlugins = async (win: BrowserWindow) => {
for (const id of Object.keys(loadedPluginMap)) { for (const id of Object.keys(loadedPluginMap)) {
forceUnloadMainPlugin(id, win); await forceUnloadMainPlugin(id, win);
} }
}; };

View File

@ -20,10 +20,10 @@ const createContext = (id: string): PreloadContext<PluginConfig> => ({
}, },
}); });
export const forceUnloadPreloadPlugin = (id: string) => { export const forceUnloadPreloadPlugin = async (id: string) => {
if (!loadedPluginMap[id]) return; if (!loadedPluginMap[id]) return;
const hasStopped = stopPlugin(id, loadedPluginMap[id], { const hasStopped = await stopPlugin(id, loadedPluginMap[id], {
ctx: 'preload', ctx: 'preload',
context: createContext(id), context: createContext(id),
}); });
@ -41,12 +41,12 @@ export const forceUnloadPreloadPlugin = (id: string) => {
} }
}; };
export const forceLoadPreloadPlugin = (id: string) => { export const forceLoadPreloadPlugin = async (id: string) => {
try { try {
const plugin = preloadPlugins[id]; const plugin = preloadPlugins[id];
if (!plugin) return; if (!plugin) return;
const hasStarted = startPlugin(id, plugin, { const hasStarted = await startPlugin(id, plugin, {
ctx: 'preload', ctx: 'preload',
context: createContext(id), context: createContext(id),
}); });
@ -71,25 +71,25 @@ export const forceLoadPreloadPlugin = (id: string) => {
} }
}; };
export const loadAllPreloadPlugins = () => { export const loadAllPreloadPlugins = async () => {
const pluginConfigs = config.plugins.getPlugins(); const pluginConfigs = config.plugins.getPlugins();
for (const [pluginId, pluginDef] of Object.entries(preloadPlugins)) { for (const [pluginId, pluginDef] of Object.entries(preloadPlugins)) {
const config = deepmerge(pluginDef.config ?? { enable: false }, pluginConfigs[pluginId] ?? {}) ; const config = deepmerge(pluginDef.config ?? { enable: false }, pluginConfigs[pluginId] ?? {});
if (config.enabled) { if (config.enabled) {
forceLoadPreloadPlugin(pluginId); await forceLoadPreloadPlugin(pluginId);
} else { } else {
if (loadedPluginMap[pluginId]) { if (loadedPluginMap[pluginId]) {
forceUnloadPreloadPlugin(pluginId); await forceUnloadPreloadPlugin(pluginId);
} }
} }
} }
}; };
export const unloadAllPreloadPlugins = () => { export const unloadAllPreloadPlugins = async () => {
for (const id of Object.keys(loadedPluginMap)) { for (const id of Object.keys(loadedPluginMap)) {
forceUnloadPreloadPlugin(id); await forceUnloadPreloadPlugin(id);
} }
}; };

View File

@ -31,7 +31,7 @@ export const createContext = <Config extends PluginConfig>(id: string): Renderer
}, },
}); });
export const forceUnloadRendererPlugin = (id: string) => { export const forceUnloadRendererPlugin = async (id: string) => {
unregisterStyleMap[id]?.forEach((unregister) => unregister()); unregisterStyleMap[id]?.forEach((unregister) => unregister());
delete unregisterStyleMap[id]; delete unregisterStyleMap[id];
@ -40,7 +40,7 @@ export const forceUnloadRendererPlugin = (id: string) => {
const plugin = rendererPlugins[id]; const plugin = rendererPlugins[id];
if (!plugin) return; if (!plugin) return;
const hasStopped = stopPlugin(id, plugin, { ctx: 'renderer', context: createContext(id) }); const hasStopped = await stopPlugin(id, plugin, { ctx: 'renderer', context: createContext(id) });
if (plugin?.stylesheets) { if (plugin?.stylesheets) {
document.querySelector(`style#plugin-${id}`)?.remove(); document.querySelector(`style#plugin-${id}`)?.remove();
} }
@ -57,11 +57,11 @@ export const forceUnloadRendererPlugin = (id: string) => {
} }
}; };
export const forceLoadRendererPlugin = (id: string) => { export const forceLoadRendererPlugin = async (id: string) => {
const plugin = rendererPlugins[id]; const plugin = rendererPlugins[id];
if (!plugin) return; if (!plugin) return;
const hasEvaled = startPlugin(id, plugin, { const hasEvaled = await startPlugin(id, plugin, {
ctx: 'renderer', ctx: 'renderer',
context: createContext(id), context: createContext(id),
}); });
@ -93,25 +93,25 @@ export const forceLoadRendererPlugin = (id: string) => {
} }
}; };
export const loadAllRendererPlugins = () => { export const loadAllRendererPlugins = async () => {
const pluginConfigs = window.mainConfig.plugins.getPlugins(); const pluginConfigs = window.mainConfig.plugins.getPlugins();
for (const [pluginId, pluginDef] of Object.entries(rendererPlugins)) { for (const [pluginId, pluginDef] of Object.entries(rendererPlugins)) {
const config = deepmerge(pluginDef.config, pluginConfigs[pluginId] ?? {}) ; const config = deepmerge(pluginDef.config, pluginConfigs[pluginId] ?? {}) ;
if (config.enabled) { if (config.enabled) {
forceLoadRendererPlugin(pluginId); await forceLoadRendererPlugin(pluginId);
} else { } else {
if (loadedPluginMap[pluginId]) { if (loadedPluginMap[pluginId]) {
forceUnloadRendererPlugin(pluginId); await forceUnloadRendererPlugin(pluginId);
} }
} }
} }
}; };
export const unloadAllRendererPlugins = () => { export const unloadAllRendererPlugins = async () => {
for (const id of Object.keys(loadedPluginMap)) { for (const id of Object.keys(loadedPluginMap)) {
forceUnloadRendererPlugin(id); await forceUnloadRendererPlugin(id);
} }
}; };

View File

@ -11,11 +11,11 @@ import {
loadAllPreloadPlugins(); loadAllPreloadPlugins();
ipcRenderer.on('plugin:unload', (_, id: string) => { ipcRenderer.on('plugin:unload', async (_, id: string) => {
forceUnloadPreloadPlugin(id); await forceUnloadPreloadPlugin(id);
}); });
ipcRenderer.on('plugin:enable', (_, id: string) => { ipcRenderer.on('plugin:enable', async (_, id: string) => {
forceLoadPreloadPlugin(id); await forceLoadPreloadPlugin(id);
}); });
contextBridge.exposeInMainWorld('mainConfig', config); contextBridge.exposeInMainWorld('mainConfig', config);

View File

@ -14,10 +14,10 @@ import type { YoutubePlayer } from '@/types/youtube-player';
let api: (Element & YoutubePlayer) | null = null; let api: (Element & YoutubePlayer) | null = null;
function listenForApiLoad() { async function listenForApiLoad() {
api = document.querySelector('#movie_player'); api = document.querySelector('#movie_player');
if (api) { if (api) {
onApiLoaded(); await onApiLoaded();
return; return;
} }
@ -53,7 +53,7 @@ async function onApiLoaded() {
const audioSource = audioContext.createMediaElementSource(video); const audioSource = audioContext.createMediaElementSource(video);
audioSource.connect(audioContext.destination); audioSource.connect(audioContext.destination);
for (const [id, plugin] of Object.entries(getAllLoadedRendererPlugins())) { for await (const [id, plugin] of Object.entries(getAllLoadedRendererPlugins())) {
if (typeof plugin.renderer !== 'function') { if (typeof plugin.renderer !== 'function') {
await plugin.renderer?.onPlayerApiReady?.call(plugin.renderer, api!, createContext(id)); await plugin.renderer?.onPlayerApiReady?.call(plugin.renderer, api!, createContext(id));
} }
@ -126,23 +126,23 @@ async function onApiLoaded() {
} }
} }
(() => { (async () => {
loadAllRendererPlugins(); await loadAllRendererPlugins();
window.ipcRenderer.on( window.ipcRenderer.on(
'plugin:unload', 'plugin:unload',
(_event, id: string) => { async (_event, id: string) => {
forceUnloadRendererPlugin(id); await forceUnloadRendererPlugin(id);
}, },
); );
window.ipcRenderer.on( window.ipcRenderer.on(
'plugin:enable', 'plugin:enable',
(_event, id: string) => { async (_event, id: string) => {
forceLoadRendererPlugin(id); await forceLoadRendererPlugin(id);
if (api) { if (api) {
const plugin = getLoadedRendererPlugin(id); const plugin = getLoadedRendererPlugin(id);
if (plugin && typeof plugin.renderer !== 'function') { if (plugin && typeof plugin.renderer !== 'function') {
plugin.renderer?.onPlayerApiReady?.call(plugin.renderer, api, createContext(id)); await plugin.renderer?.onPlayerApiReady?.call(plugin.renderer, api, createContext(id));
} }
} }
}, },
@ -159,7 +159,7 @@ async function onApiLoaded() {
); );
// Wait for complete load of YouTube api // Wait for complete load of YouTube api
listenForApiLoad(); await listenForApiLoad();
// Blocks the "Are You Still There?" popup by setting the last active time to Date.now every 15min // Blocks the "Are You Still There?" popup by setting the last active time to Date.now every 15min
setInterval(() => (window._lact = Date.now()), 900_000); setInterval(() => (window._lact = Date.now()), 900_000);

View File

@ -69,7 +69,7 @@ type Options<Config extends PluginConfig> =
| { ctx: 'preload'; context: PreloadContext<Config> } | { ctx: 'preload'; context: PreloadContext<Config> }
| { ctx: 'renderer'; context: RendererContext<Config> }; | { ctx: 'renderer'; context: RendererContext<Config> };
export const startPlugin = <Config extends PluginConfig>( export const startPlugin = async <Config extends PluginConfig>(
id: string, id: string,
def: PluginDef<unknown, unknown, unknown, Config>, def: PluginDef<unknown, unknown, unknown, Config>,
options: Options<Config>, options: Options<Config>,
@ -99,7 +99,7 @@ export const startPlugin = <Config extends PluginConfig>(
const start = performance.now(); const start = performance.now();
lifecycle?.call( await lifecycle?.call(
defContext, defContext,
options.context as Config & typeof options.context, options.context as Config & typeof options.context,
); );
@ -118,7 +118,7 @@ export const startPlugin = <Config extends PluginConfig>(
} }
}; };
export const stopPlugin = <Config extends PluginConfig>( export const stopPlugin = async <Config extends PluginConfig>(
id: string, id: string,
def: PluginDef<unknown, unknown, unknown, Config>, def: PluginDef<unknown, unknown, unknown, Config>,
options: Options<Config>, options: Options<Config>,
@ -132,7 +132,7 @@ export const stopPlugin = <Config extends PluginConfig>(
try { try {
const stop = defCtx.stop; const stop = defCtx.stop;
const start = performance.now(); const start = performance.now();
stop.call( await stop.call(
def[options.ctx], def[options.ctx],
options.context as Config & typeof options.context, options.context as Config & typeof options.context,
); );