fix: stack error caused by spread operator with large arrays

This commit is contained in:
Nick Krecklow 2021-05-31 01:27:20 -05:00
parent 539740d38a
commit 8a4ec554e2
No known key found for this signature in database
GPG Key ID: 5F149FDE156FFA94
4 changed files with 40 additions and 12 deletions

@ -8,7 +8,7 @@ export class RelativeScale {
const scale = Math.pow(10, factor) const scale = Math.pow(10, factor)
const scaledMin = min - (min % scale) const scaledMin = min - (min % scale)
let scaledMax = max + (max % scale === 0 ? 0 : (scale - (max % scale))) let scaledMax = max + (max % scale === 0 ? 0 : scale - (max % scale))
// Prevent min/max from being equal (and generating 0 ticks) // Prevent min/max from being equal (and generating 0 ticks)
// This happens when all data points are products of scale value // This happens when all data points are products of scale value
@ -32,9 +32,20 @@ export class RelativeScale {
} }
static scaleMatrix (data, tickCount, maxFactor) { static scaleMatrix (data, tickCount, maxFactor) {
const max = Math.max(...data.flat().filter(val => val !== null)) const nonNullData = data.flat().filter((val) => val !== null)
return RelativeScale.scale([0, RelativeScale.isFiniteOrZero(max)], tickCount, maxFactor) // when used with the spread operator large nonNullData/data arrays can reach the max call stack size
// use reduce calls to safely determine min/max values for any size of array
// https://stackoverflow.com/questions/63705432/maximum-call-stack-size-exceeded-when-using-the-dots-operator/63706516#63706516
const max = nonNullData.reduce((a, b) => {
return Math.max(a, b)
})
return RelativeScale.scale(
[0, RelativeScale.isFiniteOrZero(max)],
tickCount,
maxFactor
)
} }
static generateTicks (min, max, step) { static generateTicks (min, max, step) {
@ -52,8 +63,17 @@ export class RelativeScale {
max: 0 max: 0
} }
} else { } else {
const min = Math.min(...data.filter(val => val !== null)) const nonNullData = data.filter((val) => val !== null)
const max = Math.max(...data.filter(val => val !== null))
// when used with the spread operator large nonNullData/data arrays can reach the max call stack size
// use reduce calls to safely determine min/max values for any size of array
// https://stackoverflow.com/questions/63705432/maximum-call-stack-size-exceeded-when-using-the-dots-operator/63706516#63706516
const min = nonNullData.reduce((a, b) => {
return Math.min(a, b)
})
const max = nonNullData.reduce((a, b) => {
return Math.max(a, b)
})
return { return {
min: RelativeScale.isFiniteOrZero(min), min: RelativeScale.isFiniteOrZero(min),

@ -1,3 +1,11 @@
**5.5.9** *(May 31 20201)*
- Added configuration option to enable/disable ping failure logging.
- Fixed a rendering error when the primary historical graph has too many data points.
- Fixed sqlite3 errors from being ignored (now always logged).
- Fixed Minecraft session server URL (sessionserver.mojang.com -> session.minecraft.net)
- Updated to use parcel2
- Updated various dependencies.
**5.5.8** *(August 1 2020)* **5.5.8** *(August 1 2020)*
- Adds daily database copies. This is mostly for use by Minetrack Data for automated exports. By setting `createDailyDatabaseCopy: true` in `config.json`, Minetrack will lazily create a copy of `database.sql` for each day, automatically rolling over to a new file each day. The database file is named in the format of `database_copy_(day)-(month)-(year).sql`. Daily database copies do not contain indexes or previous records. Pings are inserted into the daily database copy as they occur, Minetrack will not retroactively insert previous pings from `database.sql`. - Adds daily database copies. This is mostly for use by Minetrack Data for automated exports. By setting `createDailyDatabaseCopy: true` in `config.json`, Minetrack will lazily create a copy of `database.sql` for each day, automatically rolling over to a new file each day. The database file is named in the format of `database_copy_(day)-(month)-(year).sql`. Daily database copies do not contain indexes or previous records. Pings are inserted into the daily database copy as they occur, Minetrack will not retroactively insert previous pings from `database.sql`.
- Bump lodash from 4.17.15 to 4.17.19 - Bump lodash from 4.17.15 to 4.17.19

4
package-lock.json generated

@ -1,12 +1,12 @@
{ {
"name": "minetrack", "name": "minetrack",
"version": "5.5.8", "version": "5.5.9",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "minetrack", "name": "minetrack",
"version": "5.5.8", "version": "5.5.9",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"finalhandler": "^1.1.2", "finalhandler": "^1.1.2",

@ -1,6 +1,6 @@
{ {
"name": "minetrack", "name": "minetrack",
"version": "5.5.8", "version": "5.5.9",
"description": "A Minecraft server tracker that lets you focus on the basics.", "description": "A Minecraft server tracker that lets you focus on the basics.",
"dependencies": { "dependencies": {
"finalhandler": "^1.1.2", "finalhandler": "^1.1.2",
@ -30,11 +30,11 @@
"node": ">=12.4.0" "node": ">=12.4.0"
}, },
"targets": { "targets": {
"main": { "main": {
"engines": { "engines": {
"browsers": "defaults" "browsers": "defaults"
}
} }
}
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.10.2", "@babel/core": "^7.10.2",