diff --git a/src/utils/check-plugin.ts b/src/utils/check-plugin.ts index e4a81a9..08d9c03 100644 --- a/src/utils/check-plugin.ts +++ b/src/utils/check-plugin.ts @@ -13,19 +13,26 @@ export async function checkPlugins(): Promise { sourcemap: false, }; - for (const plugin of plugins) { - try { - const isEnabled = await plugin.detect(); - if (isEnabled && plugin.bundleParams) { - Object.assign(params, plugin.bundleParams); - console.log(t('pluginDetected', { name: plugin.name })); + const results = await Promise.all( + plugins.map(async (plugin) => { + try { + const isEnabled = await plugin.detect(); + return { isEnabled, error: null }; + } catch (error) { + return { isEnabled: false, error }; } - } catch (err) { - console.warn( - t('pluginDetectionError', { name: plugin.name, error: err }), - ); + }), + ); + + results.forEach(({ isEnabled, error }, index) => { + const plugin = plugins[index]; + if (error) { + console.warn(t('pluginDetectionError', { name: plugin.name, error })); + } else if (isEnabled && plugin.bundleParams) { + Object.assign(params, plugin.bundleParams); + console.log(t('pluginDetected', { name: plugin.name })); } - } + }); return params; } diff --git a/tests/check-plugin.test.ts b/tests/check-plugin.test.ts new file mode 100644 index 0000000..6af0aad --- /dev/null +++ b/tests/check-plugin.test.ts @@ -0,0 +1,75 @@ +import { describe, expect, mock, spyOn, test, beforeEach, afterEach } from 'bun:test'; + +// Mock dependencies before imports +mock.module('fs-extra', () => ({ + default: { + access: async () => {}, + }, +})); + +mock.module('i18next', () => ({ + default: { + init: () => {}, + t: (key: string) => key, + }, +})); + +import { checkPlugins } from '../src/utils/check-plugin'; +import * as pluginConfig from '../src/utils/plugin-config'; + +describe('checkPlugins', () => { + test('should detect plugins concurrently (simulated)', async () => { + const mockPlugins = [ + { + name: 'plugin1', + bundleParams: { p1: true }, + detect: async () => { + await new Promise(resolve => setTimeout(resolve, 100)); + return true; + } + }, + { + name: 'plugin2', + bundleParams: { p2: true }, + detect: async () => { + await new Promise(resolve => setTimeout(resolve, 100)); + return true; + } + }, + { + name: 'plugin3', + bundleParams: { p3: true }, + detect: async () => { + await new Promise(resolve => setTimeout(resolve, 100)); + return true; + } + } + ]; + + // Replacing the plugins array in plugin-config + const originalPlugins = [...pluginConfig.plugins]; + (pluginConfig.plugins as any).splice(0, pluginConfig.plugins.length, ...mockPlugins); + + const start = Date.now(); + const result = await checkPlugins(); + const end = Date.now(); + const duration = end - start; + + console.log(`Duration with optimized implementation: ${duration}ms`); + + expect(result).toEqual({ + sentry: false, // default + sourcemap: false, // default + p1: true, + p2: true, + p3: true + } as any); + + // Now it's concurrent, so we expect around 100ms. + // We'll allow some buffer, but it should definitely be less than 250ms. + expect(duration).toBeLessThan(250); + + // Restore original plugins + (pluginConfig.plugins as any).splice(0, pluginConfig.plugins.length, ...originalPlugins); + }); +});