diff --git a/lib/server-utils.ts b/lib/server-utils.ts index 5876d6d71..a20fedb92 100644 --- a/lib/server-utils.ts +++ b/lib/server-utils.ts @@ -133,7 +133,8 @@ export async function saveStaticFilesToReportDir(htmlReporter: HtmlReporter, plu copyToReportDir(destPath, ['report.min.js', 'report.min.css'], staticFolder), fs.copy(path.resolve(staticFolder, 'index.html'), path.resolve(destPath, 'index.html')), fs.copy(path.resolve(staticFolder, 'icons'), path.resolve(destPath, 'icons')), - fs.copy(require.resolve('@gemini-testing/sql.js'), path.resolve(destPath, 'sql-wasm.js')), + fs.copy(require.resolve('@gemini-testing/sql.js/dist/sql-wasm.js'), path.resolve(destPath, 'sql-wasm.js')), + fs.copy(require.resolve('@gemini-testing/sql.js/dist/sql-wasm.wasm'), path.resolve(destPath, 'sql-wasm.wasm')), copyPlugins(pluginConfig, destPath) ]); } @@ -173,7 +174,6 @@ export function urlPathNameEndsWith(currentUrl: string, searchString: string): b export async function writeDatabaseUrlsFile(destPath: string, srcPaths: string[]): Promise { const jsonUrls = srcPaths.filter(p => urlPathNameEndsWith(p, '.json')); const dbUrls = srcPaths.filter(p => urlPathNameEndsWith(p, '.db')); - const data = { dbUrls, jsonUrls diff --git a/lib/static/modules/actions.js b/lib/static/modules/actions.js index 99e562a40..62d1f3336 100644 --- a/lib/static/modules/actions.js +++ b/lib/static/modules/actions.js @@ -75,6 +75,8 @@ export const initStaticReport = () => { performance?.mark?.(performanceMarks.DBS_LOADED); + plugins.preloadAll(dataFromStaticFile.config); + fetchDbDetails = fetchDbResponses.map(({url, status, data}) => ({url, status, success: !!data})); const dataForDbs = fetchDbResponses.map(({data}) => data).filter(data => data); diff --git a/lib/static/modules/load-plugin.js b/lib/static/modules/load-plugin.js index d7500cabd..dcf115203 100644 --- a/lib/static/modules/load-plugin.js +++ b/lib/static/modules/load-plugin.js @@ -49,17 +49,23 @@ const whitelistedDeps = { // - an array with the string list of required dependencies and a function as the last item. // The function will be called with the dependencies as arguments plus `options` arg. +const loadingPlugins = {}; const pendingPlugins = {}; -export default async function loadPlugin(pluginName, pluginConfig) { +const getPluginScriptPath = pluginName => `plugins/${encodeURIComponent(pluginName)}/plugin.js`; + +export function preloadPlugin(pluginName) { + loadingPlugins[pluginName] = loadingPlugins[pluginName] || getScriptText(pluginName); +} + +export async function loadPlugin(pluginName, pluginConfig) { if (pendingPlugins[pluginName]) { return pendingPlugins[pluginName]; } - const pluginScriptPath = `plugins/${encodeURIComponent(pluginName)}/plugin.js`; + const scriptTextPromise = loadingPlugins[pluginName] || getScriptText(pluginName); - return pendingPlugins[pluginName] = Promise.resolve(pluginScriptPath) - .then(getScriptText) + return pendingPlugins[pluginName] = scriptTextPromise .then(executePluginCode) .then(plugin => initPlugin(plugin, pluginName, pluginConfig)) .then(null, err => { @@ -103,7 +109,9 @@ function executePluginCode(code) { return exec(); } -async function getScriptText(scriptUrl) { - const result = await axios.get(scriptUrl); - return result.data; +async function getScriptText(pluginName) { + const scriptUrl = getPluginScriptPath(pluginName); + const {data} = await axios.get(scriptUrl); + + return data; } diff --git a/lib/static/modules/plugins.js b/lib/static/modules/plugins.js index f039c91e4..769e4dd68 100644 --- a/lib/static/modules/plugins.js +++ b/lib/static/modules/plugins.js @@ -1,8 +1,16 @@ -import loadPlugin from './load-plugin'; +import {loadPlugin, preloadPlugin} from './load-plugin'; const plugins = Object.create(null); const loadedPluginConfigs = []; +function preloadAll(config) { + if (!config || !config.pluginsEnabled || !Array.isArray(config.plugins)) { + return; + } + + config.plugins.forEach(plugin => preloadPlugin(plugin.name)); +} + async function loadAll(config) { // if plugins are disabled, act like there are no plugins defined if (!config || !config.pluginsEnabled || !Array.isArray(config.plugins)) { @@ -49,4 +57,4 @@ function getLoadedConfigs() { return loadedPluginConfigs; } -module.exports = {loadAll, getLoadedConfigs, forEach, get}; +module.exports = {preloadAll, loadAll, getLoadedConfigs, forEach, get}; diff --git a/lib/static/template.html b/lib/static/template.html index 195650684..03fc91e82 100644 --- a/lib/static/template.html +++ b/lib/static/template.html @@ -5,7 +5,9 @@ - + + +
diff --git a/package-lock.json b/package-lock.json index 59871af13..03b36ce1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@babel/runtime": "^7.22.5", - "@gemini-testing/sql.js": "^1.0.1", + "@gemini-testing/sql.js": "^2.0.0", "axios": "^0.18.1", "better-sqlite3": "^8.5.0", "bluebird": "^3.5.3", @@ -3190,9 +3190,9 @@ "dev": true }, "node_modules/@gemini-testing/sql.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@gemini-testing/sql.js/-/sql.js-1.0.1.tgz", - "integrity": "sha512-lK78zxvQiIFHlt7erv2GmOAdg9b8rdIHC4f/NFKfmNDLbtchmLlIO3eyK4b7Rtfxi0PAAaffF4s8ncHd103y0Q==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@gemini-testing/sql.js/-/sql.js-2.0.0.tgz", + "integrity": "sha512-FoslR6S5cxObp0fNtiFkQ6TvGZ5sd7+KomY7Hm3sH51uAHxyzJSQGvpsaiw5dmO/HHYEBF/bJMXHVWEQGfot7A==" }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.10", @@ -37681,9 +37681,9 @@ "dev": true }, "@gemini-testing/sql.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@gemini-testing/sql.js/-/sql.js-1.0.1.tgz", - "integrity": "sha512-lK78zxvQiIFHlt7erv2GmOAdg9b8rdIHC4f/NFKfmNDLbtchmLlIO3eyK4b7Rtfxi0PAAaffF4s8ncHd103y0Q==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@gemini-testing/sql.js/-/sql.js-2.0.0.tgz", + "integrity": "sha512-FoslR6S5cxObp0fNtiFkQ6TvGZ5sd7+KomY7Hm3sH51uAHxyzJSQGvpsaiw5dmO/HHYEBF/bJMXHVWEQGfot7A==" }, "@humanwhocodes/config-array": { "version": "0.11.10", diff --git a/package.json b/package.json index 5eebffa78..37f3dc482 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ }, "dependencies": { "@babel/runtime": "^7.22.5", - "@gemini-testing/sql.js": "^1.0.1", + "@gemini-testing/sql.js": "^2.0.0", "axios": "^0.18.1", "better-sqlite3": "^8.5.0", "bluebird": "^3.5.3", diff --git a/test/unit/lib/static/modules/load-plugin.js b/test/unit/lib/static/modules/load-plugin.js index 8b97191fa..e895df5f9 100644 --- a/test/unit/lib/static/modules/load-plugin.js +++ b/test/unit/lib/static/modules/load-plugin.js @@ -1,7 +1,7 @@ 'use strict'; import axios from 'axios'; -import loadPlugin from 'lib/static/modules/load-plugin'; +import {loadPlugin} from 'lib/static/modules/load-plugin'; import actionNames from 'lib/static/modules/action-names'; import * as actions from 'lib/static/modules/actions'; import * as selectors from 'lib/static/modules/selectors'; diff --git a/test/unit/lib/static/modules/plugins.js b/test/unit/lib/static/modules/plugins.js index 0df8fb52a..17b02ec28 100644 --- a/test/unit/lib/static/modules/plugins.js +++ b/test/unit/lib/static/modules/plugins.js @@ -10,7 +10,7 @@ describe('static/modules/plugins', () => { beforeEach(() => { loadPluginStub = sandbox.stub(); plugins = proxyquire('lib/static/modules/plugins', { - './load-plugin': {default: loadPluginStub} + './load-plugin': {loadPlugin: loadPluginStub} }); });