diff --git a/CHANGELOG.md b/CHANGELOG.md index 16e96f3e..7ab0b505 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# 3.1.1 + +- Version number is now correct in splash and `/health` when running as a node module +- Fixed an issue with setting `minWorkers` and `maxWorkers` as CLI arguments +- Fixed issues with page resets between exports causing exceptions +- Fixed an issue with width settings causing bad exports if set to a percentage or a `px` suffixed width +- Fixed an issue with SVG exports in the UI + # 3.1.0 - Fixed an issue with SVG base 64 exports diff --git a/lib/chart.js b/lib/chart.js index a8e5e645..d2724731 100644 --- a/lib/chart.js +++ b/lib/chart.js @@ -203,7 +203,7 @@ export const findChartSize = (options) => { scale = roundNumber(scale, 2); // Find chart size and scale - return { + const size = { height: options.export?.height || exporting?.sourceHeight || @@ -222,6 +222,13 @@ export const findChartSize = (options) => { 600, scale }; + + // Get rid of potential px and % + for (var [param, value] of Object.entries(size)) { + size[param] = + typeof value === 'string' ? +value.replace(/px|%/gi, '') : value; + } + return size; }; /** diff --git a/lib/export.js b/lib/export.js index c9d02198..45ad250c 100644 --- a/lib/export.js +++ b/lib/export.js @@ -57,7 +57,7 @@ const getClipRegion = (page) => * @returns {string} - A string representation of a screenshot. */ const createImage = async (page, type, encoding, clip, rasterizationTimeout) => - await Promise.race([ + Promise.race([ page.screenshot({ type, encoding, @@ -67,7 +67,7 @@ const createImage = async (page, type, encoding, clip, rasterizationTimeout) => // the expected type format is PNG omitBackground: type == 'png' }), - new Promise((resolve, reject) => + new Promise((_resolve, reject) => setTimeout( () => reject(new Error('Rasterization timeout')), rasterizationTimeout || 1500 @@ -425,16 +425,20 @@ export default async (page, chart, options) => { // Destroy old charts after the export is done await page.evaluate(() => { - // eslint-disable-next-line no-undef - const oldCharts = Highcharts.charts; - - // Check in any already existing charts - if (oldCharts.length) { - // Destroy old charts - for (const oldChart of oldCharts) { - oldChart && oldChart.destroy(); - // eslint-disable-next-line no-undef - Highcharts.charts.shift(); + // We are not guaranteed that Highcharts is loaded, e,g, when doing SVG + // exports + if (typeof Highcharts !== 'undefined') { + // eslint-disable-next-line no-undef + const oldCharts = Highcharts.charts; + + // Check in any already existing charts + if (Array.isArray(oldCharts) && oldCharts.length) { + // Destroy old charts + for (const oldChart of oldCharts) { + oldChart && oldChart.destroy(); + // eslint-disable-next-line no-undef + Highcharts.charts.shift(); + } } } }); diff --git a/lib/pool.js b/lib/pool.js index 9c970a2e..f8cbd307 100644 --- a/lib/pool.js +++ b/lib/pool.js @@ -101,7 +101,7 @@ const factory = { } // Clear page - await clearPage(workerHandle.page, false); + await clearPage(workerHandle.page, true); return true; }, @@ -161,13 +161,17 @@ export const init = async (config) => { attachProcessExitListeners(); } + if (parseInt(poolConfig.minWorkers) > parseInt(poolConfig.maxWorkers)) { + poolConfig.minWorkers = poolConfig.maxWorkers; + } + try { // Create a pool along with a minimal number of resources pool = new Pool({ // Get the create/validate/destroy/log functions ...factory, - min: poolConfig.minWorkers, - max: poolConfig.maxWorkers, + min: parseInt(poolConfig.minWorkers), + max: parseInt(poolConfig.maxWorkers), acquireTimeoutMillis: poolConfig.acquireTimeout, createTimeoutMillis: poolConfig.createTimeout, destroyTimeoutMillis: poolConfig.destroyTimeout, diff --git a/lib/server/routes/health.js b/lib/server/routes/health.js index 52ff3e24..2c8e61bb 100644 --- a/lib/server/routes/health.js +++ b/lib/server/routes/health.js @@ -15,7 +15,14 @@ See LICENSE file in root for details. import cache from '../../cache.js'; import pool from '../../pool.js'; -const packageVersion = process.env.npm_package_version; +import { readFileSync } from 'fs'; +import { __dirname } from './../../utils.js'; +import { join as pather } from 'path'; + +const pkgFile = JSON.parse( + readFileSync(pather(__dirname, 'package.json')) + ); + const serverStartTime = new Date(); /** @@ -32,7 +39,7 @@ export default (app) => Math.floor( (new Date().getTime() - serverStartTime.getTime()) / 1000 / 60 ) + ' minutes', - version: packageVersion, + version: pkgFile.version, highchartsVersion: cache.version(), averageProcessingTime: pool.averageTime(), performedExports: pool.processedWorkCount(), diff --git a/lib/utils.js b/lib/utils.js index 7a5922de..d391ddd2 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -14,6 +14,7 @@ See LICENSE file in root for details. import { readFileSync } from 'fs'; import { fileURLToPath } from 'url'; +import { join as pather } from 'path'; import { defaultConfig } from '../lib/schemas/config.js'; import { log } from './logger.js'; @@ -280,10 +281,9 @@ export const optionsStringify = (options, allowFunctions) => { */ export const printLogo = (noLogo) => { // Get package version either from env or from package.json - const packageVersion = - process.env.npm_package_version || - JSON.parse(readFileSync(new URL('../package.json', import.meta.url))) - .version; + const packageVersion = JSON.parse( + readFileSync(pather(__dirname, 'package.json')) + ).version; // Print text only if (noLogo) { diff --git a/package.json b/package.json index e05009c3..c6e5b674 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "author": "Highsoft AS (http://www.highcharts.com/about)", "license": "MIT", "type": "module", - "version": "3.1.0", + "version": "3.1.1", "main": "dist/index.esm.js", "exports": { ".": { diff --git a/public/js/main.js b/public/js/main.js index f29cdedc..374b9875 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -68,7 +68,8 @@ const highexp = {}; preview.innerHTML = ''; } else if (format.value === 'image/svg+xml') { - preview.innerHTML = data; + preview.innerHTML = + ''; } else if (format.value === 'application/pdf') { preview.innerHTML = ''; try {