diff --git a/.travis.yml b/.travis.yml index 5e9cd47..9e8a40c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,6 @@ language: node_js node_js: - - '9' + - '10' + - '12' + - '13' + - 'node' diff --git a/package-lock.json b/package-lock.json index 4f2e80e..ac0fd30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "speedscope", - "version": "1.5.2", + "version": "1.5.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -2458,10 +2458,13 @@ "dev": true }, "bindings": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz", - "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=", - "dev": true + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "requires": { + "file-uri-to-path": "1.0.0" + } }, "bluebird": { "version": "3.5.1", @@ -2861,620 +2864,6 @@ "upath": "^1.0.5" }, "dependencies": { - "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz", - "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": "^2.1.0" - } - }, - "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", - "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", - "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.0.tgz", - "integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==", - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.0.tgz", - "integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==", - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz", - "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==", - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.10.tgz", - "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==", - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz", - "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "optional": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz", - "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==", - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", - "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", - "dev": true, - "optional": true - } - } - }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -4328,13 +3717,13 @@ "dev": true }, "deasync": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.13.tgz", - "integrity": "sha512-/6ngYM7AapueqLtvOzjv9+11N2fHDSrkxeMF1YPE20WIfaaawiBg+HZH1E5lHrcJxlKR42t6XPOEmMmqcAsU1g==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.19.tgz", + "integrity": "sha512-oh3MRktfnPlLysCPpBpKZZzb4cUC/p0aA3SyRGp15lN30juJBTo/CiD0d4fR+f1kBtUQoJj1NE9RPNWQ7BQ9Mg==", "dev": true, "requires": { - "bindings": "~1.2.1", - "nan": "^2.0.7" + "bindings": "^1.5.0", + "node-addon-api": "^1.7.1" } }, "debug": { @@ -5205,8 +4594,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true + "dev": true }, "filesize": { "version": "3.6.1", @@ -8136,12 +7524,6 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true - }, "nanomatch": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", @@ -8194,6 +7576,12 @@ "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==", "dev": true }, + "node-addon-api": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.1.tgz", + "integrity": "sha512-2+DuKodWvwRTrCfKOeR24KIc5unKjOh8mz17NCzVnHWfjAdDqbfbjqh7gUT+BkXBRQM52+xCHciKWonJ3CbJMQ==", + "dev": true + }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", @@ -10955,9 +10343,9 @@ "dev": true }, "prettier": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.12.0.tgz", - "integrity": "sha512-Wz0SMncgaglBzDcohH3ZIAi4nVpzOIEweFzCOmgVEoRSeO72b4dcKGfgxoRGVMaFlh1r7dlVaJ+f3CIHfeH6xg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.4.tgz", + "integrity": "sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w==", "dev": true }, "pretty-format": { diff --git a/package.json b/package.json index 95de461..22da719 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "parcel-bundler": "1.9.2", "preact": "8.2.7", "preact-redux": "jlfwong/preact-redux#a56dcc4", - "prettier": "1.12.0", + "prettier": "2.0.4", "protobufjs": "6.8.8", "quicktype": "15.0.209", "redux": "^4.0.0", @@ -57,6 +57,9 @@ "transform": { "^.+\\.tsx?$": "ts-jest" }, + "setupFilesAfterEnv": [ + "./src/jest-setup.js" + ], "testRegex": "\\.test\\.tsx?$", "collectCoverageFrom": [ "**/*.{ts,tsx}", @@ -73,4 +76,4 @@ "dependencies": { "opn": "5.3.0" } -} +} \ No newline at end of file diff --git a/prettier.config.js b/prettier.config.js index 814bd52..9b0317b 100644 --- a/prettier.config.js +++ b/prettier.config.js @@ -4,4 +4,5 @@ module.exports = { semi: false, singleQuote: true, trailingComma: 'all', -}; + arrowParens: 'avoid' +} diff --git a/src/gl/canvas-context.ts b/src/gl/canvas-context.ts index 98bf8f9..8af7a94 100644 --- a/src/gl/canvas-context.ts +++ b/src/gl/canvas-context.ts @@ -24,9 +24,7 @@ export class CanvasContext { const webGLInfo = this.gl.getWebGLInfo() if (webGLInfo) { console.log( - `WebGL initialized. renderer: ${webGLInfo.renderer}, vendor: ${ - webGLInfo.vendor - }, version: ${webGLInfo.version}`, + `WebGL initialized. renderer: ${webGLInfo.renderer}, vendor: ${webGLInfo.vendor}, version: ${webGLInfo.version}`, ) } ;(window as any)['testContextLoss'] = () => { diff --git a/src/gl/flamechart-renderer.ts b/src/gl/flamechart-renderer.ts index 4bce19d..b10d8b4 100644 --- a/src/gl/flamechart-renderer.ts +++ b/src/gl/flamechart-renderer.ts @@ -175,8 +175,8 @@ export class FlamechartRenderer { // and the blue channel to indicate the color bucket to render. // We add one to each so we have zero reserved for the background color. const color = new Color( - (1 + i % 255) / 256, - (1 + stackDepth % 255) / 256, + (1 + (i % 255)) / 256, + (1 + (stackDepth % 255)) / 256, (1 + this.flamechart.getColorBucketForFrame(frame.node.frame)) / 256, ) batch.addRect(configSpaceBounds, color) @@ -288,10 +288,10 @@ export class FlamechartRenderer { const configSpaceContentWidth = this.flamechart.getTotalWeight() const numAtlasEntriesPerLayer = Math.pow(2, zoomLevel) const left = Math.floor( - numAtlasEntriesPerLayer * configSpaceSrcRect.left() / configSpaceContentWidth, + (numAtlasEntriesPerLayer * configSpaceSrcRect.left()) / configSpaceContentWidth, ) const right = Math.ceil( - numAtlasEntriesPerLayer * configSpaceSrcRect.right() / configSpaceContentWidth, + (numAtlasEntriesPerLayer * configSpaceSrcRect.right()) / configSpaceContentWidth, ) const nLayers = this.flamechart.getLayers().length diff --git a/src/gl/overlay-rectangle-renderer.ts b/src/gl/overlay-rectangle-renderer.ts index 6634355..9050dee 100644 --- a/src/gl/overlay-rectangle-renderer.ts +++ b/src/gl/overlay-rectangle-renderer.ts @@ -65,7 +65,12 @@ export class ViewportRectangleRenderer { private buffer: Graphics.VertexBuffer constructor(private gl: Graphics.Context) { - const vertices = [[-1, 1], [1, 1], [-1, -1], [1, -1]] + const vertices = [ + [-1, 1], + [1, 1], + [-1, -1], + [1, -1], + ] const floats: number[] = [] for (let v of vertices) { floats.push(v[0]) diff --git a/src/gl/rectangle-batch-renderer.ts b/src/gl/rectangle-batch-renderer.ts index 5848935..ce4a61f 100644 --- a/src/gl/rectangle-batch-renderer.ts +++ b/src/gl/rectangle-batch-renderer.ts @@ -45,7 +45,14 @@ export class RectangleBatch { return this.buffer } - const corners = [[0, 0], [1, 0], [0, 1], [1, 0], [0, 1], [1, 1]] + const corners = [ + [0, 0], + [1, 0], + [0, 1], + [1, 0], + [0, 1], + [1, 1], + ] const bytes = new Uint8Array(vertexFormat.stride * corners.length * this.rects.length) const floats = new Float32Array(bytes.buffer) diff --git a/src/import/__snapshots__/chrome.test.ts.snap b/src/import/__snapshots__/chrome.test.ts.snap index 77c4b7a..c9601db 100644 --- a/src/import/__snapshots__/chrome.test.ts.snap +++ b/src/import/__snapshots__/chrome.test.ts.snap @@ -516,97 +516,6 @@ exports[`importFromChromeTimeline Chrome 69: indexToView 1`] = `0`; exports[`importFromChromeTimeline Chrome 69: profileGroup.name 1`] = `"simple.json"`; exports[`importFromChromeTimeline Workers Chrome 66 1`] = ` -Object { - "frames": Array [ - Frame { - "col": -1, - "file": "", - "key": "(program)::-1:-1", - "line": -1, - "name": "(program)", - "selfWeight": 819120, - "totalWeight": 819120, - }, - Frame { - "col": 20, - "file": "http://172.30.3.176:7777/worker.js", - "key": "onmessage:http://172.30.3.176:7777/worker.js:14:20", - "line": 14, - "name": "onmessage", - "selfWeight": 639, - "totalWeight": 857719, - }, - Frame { - "col": 14, - "file": "http://172.30.3.176:7777/worker.js", - "key": "alpha:http://172.30.3.176:7777/worker.js:8:14", - "line": 8, - "name": "alpha", - "selfWeight": 19976, - "totalWeight": 835149, - }, - Frame { - "col": 14, - "file": "http://172.30.3.176:7777/worker.js", - "key": "gamma:http://172.30.3.176:7777/worker.js:0:14", - "line": 0, - "name": "gamma", - "selfWeight": 22197, - "totalWeight": 30000, - }, - Frame { - "col": -1, - "file": "", - "key": "postMessage::-1:-1", - "line": -1, - "name": "postMessage", - "selfWeight": 1278, - "totalWeight": 21931, - }, - ], - "name": "worker.json - DedicatedWorker thread", - "stacks": Array [ - " 9.07ms", - "(program) 5.49ms", - "onmessage;alpha;gamma 3.69ms", - "onmessage;postMessage 212.00µs", - "onmessage;postMessage;(program) 3.97ms", - "onmessage;alpha;gamma 3.82ms", - "onmessage;postMessage 414.00µs", - "onmessage;postMessage;(program) 3.71ms", - "onmessage;alpha;gamma 1.13ms", - "onmessage 188.00µs", - "onmessage;alpha;gamma 2.48ms", - "onmessage;alpha;gamma;(program) 3.89ms", - "onmessage;alpha;gamma 373.00µs", - "onmessage;alpha 184.00µs", - "onmessage;alpha;gamma 3.36ms", - "onmessage;alpha;gamma;(program) 3.91ms", - "onmessage;alpha;gamma 3.94ms", - "onmessage;postMessage 205.00µs", - "onmessage;postMessage;(program) 3.91ms", - "onmessage 451.00µs", - "onmessage;alpha;gamma 566.00µs", - "onmessage;alpha 194.00µs", - "onmessage;alpha;gamma 2.09ms", - "onmessage;alpha 189.00µs", - "onmessage;alpha;gamma 746.00µs", - "onmessage;postMessage 211.00µs", - "onmessage;postMessage;(program) 4.00ms", - "onmessage;alpha 4.80ms", - "onmessage;alpha;(program) 5.28ms", - "onmessage;alpha 4.70ms", - "onmessage;postMessage 236.00µs", - "onmessage;postMessage;(program) 5.06ms", - "onmessage;alpha 5.07ms", - "onmessage;alpha;(program) 4.81ms", - "onmessage;alpha 4.84ms", - "onmessage;alpha;(program) 775.08ms", - ], -} -`; - -exports[`importFromChromeTimeline Workers Chrome 66 2`] = ` Object { "frames": Array [ Frame { @@ -913,7 +822,98 @@ Object { } `; -exports[`importFromChromeTimeline Workers Chrome 66: indexToView 1`] = `1`; +exports[`importFromChromeTimeline Workers Chrome 66 2`] = ` +Object { + "frames": Array [ + Frame { + "col": -1, + "file": "", + "key": "(program)::-1:-1", + "line": -1, + "name": "(program)", + "selfWeight": 819120, + "totalWeight": 819120, + }, + Frame { + "col": 20, + "file": "http://172.30.3.176:7777/worker.js", + "key": "onmessage:http://172.30.3.176:7777/worker.js:14:20", + "line": 14, + "name": "onmessage", + "selfWeight": 639, + "totalWeight": 857719, + }, + Frame { + "col": 14, + "file": "http://172.30.3.176:7777/worker.js", + "key": "alpha:http://172.30.3.176:7777/worker.js:8:14", + "line": 8, + "name": "alpha", + "selfWeight": 19976, + "totalWeight": 835149, + }, + Frame { + "col": 14, + "file": "http://172.30.3.176:7777/worker.js", + "key": "gamma:http://172.30.3.176:7777/worker.js:0:14", + "line": 0, + "name": "gamma", + "selfWeight": 22197, + "totalWeight": 30000, + }, + Frame { + "col": -1, + "file": "", + "key": "postMessage::-1:-1", + "line": -1, + "name": "postMessage", + "selfWeight": 1278, + "totalWeight": 21931, + }, + ], + "name": "worker.json - DedicatedWorker thread", + "stacks": Array [ + " 9.07ms", + "(program) 5.49ms", + "onmessage;alpha;gamma 3.69ms", + "onmessage;postMessage 212.00µs", + "onmessage;postMessage;(program) 3.97ms", + "onmessage;alpha;gamma 3.82ms", + "onmessage;postMessage 414.00µs", + "onmessage;postMessage;(program) 3.71ms", + "onmessage;alpha;gamma 1.13ms", + "onmessage 188.00µs", + "onmessage;alpha;gamma 2.48ms", + "onmessage;alpha;gamma;(program) 3.89ms", + "onmessage;alpha;gamma 373.00µs", + "onmessage;alpha 184.00µs", + "onmessage;alpha;gamma 3.36ms", + "onmessage;alpha;gamma;(program) 3.91ms", + "onmessage;alpha;gamma 3.94ms", + "onmessage;postMessage 205.00µs", + "onmessage;postMessage;(program) 3.91ms", + "onmessage 451.00µs", + "onmessage;alpha;gamma 566.00µs", + "onmessage;alpha 194.00µs", + "onmessage;alpha;gamma 2.09ms", + "onmessage;alpha 189.00µs", + "onmessage;alpha;gamma 746.00µs", + "onmessage;postMessage 211.00µs", + "onmessage;postMessage;(program) 4.00ms", + "onmessage;alpha 4.80ms", + "onmessage;alpha;(program) 5.28ms", + "onmessage;alpha 4.70ms", + "onmessage;postMessage 236.00µs", + "onmessage;postMessage;(program) 5.06ms", + "onmessage;alpha 5.07ms", + "onmessage;alpha;(program) 4.81ms", + "onmessage;alpha 4.84ms", + "onmessage;alpha;(program) 775.08ms", + ], +} +`; + +exports[`importFromChromeTimeline Workers Chrome 66: indexToView 1`] = `0`; exports[`importFromChromeTimeline Workers Chrome 66: profileGroup.name 1`] = `"worker.json"`; diff --git a/src/import/__snapshots__/trace-event.test.ts.snap b/src/import/__snapshots__/trace-event.test.ts.snap index 9fde686..0d31032 100644 --- a/src/import/__snapshots__/trace-event.test.ts.snap +++ b/src/import/__snapshots__/trace-event.test.ts.snap @@ -44,17 +44,8 @@ Object { "key": "A", "line": undefined, "name": "A", - "selfWeight": 1, - "totalWeight": 10, - }, - Frame { - "col": undefined, - "file": undefined, - "key": "C", - "line": undefined, - "name": "C", - "selfWeight": 3, - "totalWeight": 10, + "selfWeight": 2, + "totalWeight": 6, }, Frame { "col": undefined, @@ -62,9 +53,18 @@ Object { "key": "B", "line": undefined, "name": "B", - "selfWeight": 3, + "selfWeight": 2, "totalWeight": 4, }, + Frame { + "col": undefined, + "file": undefined, + "key": "C", + "line": undefined, + "name": "C", + "selfWeight": 2, + "totalWeight": 2, + }, Frame { "col": undefined, "file": undefined, @@ -77,12 +77,14 @@ Object { ], "name": "pid 0, tid 1", "stacks": Array [ - "A;C;B 2.00µs", - "A;C 2.00µs", - "A;C;A 1.00µs", - "A;C;A;B 1.00µs", - "A;C;A;B;C 1.00µs", - "A;C;X 3.00µs", + "A;B;C 1.00µs", + "A;B 1.00µs", + "A 1.00µs", + " 1.00µs", + "A 1.00µs", + "A;B 1.00µs", + "A;B;C 1.00µs", + "X 3.00µs", ], } `; diff --git a/src/jest-setup.js b/src/jest-setup.js new file mode 100644 index 0000000..4bb67f3 --- /dev/null +++ b/src/jest-setup.js @@ -0,0 +1,51 @@ +// Versions of node before 10 had an unstable sort. This isn't really an issue in browsers +// that speedscope supports, but for the purposes of supporting node 10, we'll polyfill +// a stable sort to make the tests pass. +// +// See: +// - https://v8.dev/features/stable-sort +// - https://v8.dev/blog/array-sort +// - https://github.com/jlfwong/speedscope/pull/254#issuecomment-575116995 +// +// Once we stop supporting node 10, this can be removed. +// +// An alternative would be to change our sort implementation to be stable by definition +// rather than relying upon native sort being stable. I don't want to do that because +// we'd take a perf hit. +// +// Because we're not going to use this in our actual build, it's okay for this +// to be inefficient. + +(function () { + const nodeVersion = process.versions.node + const versionParts = nodeVersion.split('.') + const majorVersion = parseInt(versionParts[0], 10) + + if (majorVersion > 10) { + // Don't need to do the patch for newer node versions + return + } + + const defaultCompareFunction = (a, b) => { + const sa = '' + a + const sb = '' + b + if (sa < sb) return -1 + if (sa > sb) return 1 + return 0 + } + + const originalSort = Array.prototype.sort + Array.prototype.sort = function (compareFunction) { + const arrayWithIndices = this.map((x, i) => [x, i]) + originalSort.call(arrayWithIndices, (a, b) => { + if (!compareFunction) { + compareFunction = defaultCompareFunction + } + const res = compareFunction(a[0], b[0]) + if (res !== 0) return res + return a[1] < b[1] ? -1 : 1 + }) + this.splice(0, this.length, ...arrayWithIndices.map(x => x[0])) + return this + } +})() \ No newline at end of file diff --git a/src/lib/color.ts b/src/lib/color.ts index 92dcce1..8649a8b 100644 --- a/src/lib/color.ts +++ b/src/lib/color.ts @@ -15,19 +15,19 @@ export class Color { // https://en.wikipedia.org/wiki/HSL_and_HSV#From_luma/chroma/hue const hPrime = H / 60 - const X = C * (1 - Math.abs(hPrime % 2 - 1)) + const X = C * (1 - Math.abs((hPrime % 2) - 1)) const [R1, G1, B1] = hPrime < 1 ? [C, X, 0] : hPrime < 2 - ? [X, C, 0] - : hPrime < 3 - ? [0, C, X] - : hPrime < 4 - ? [0, X, C] - : hPrime < 5 - ? [X, 0, C] - : [C, 0, X] + ? [X, C, 0] + : hPrime < 3 + ? [0, C, X] + : hPrime < 4 + ? [0, X, C] + : hPrime < 5 + ? [X, 0, C] + : [C, 0, X] const m = L - (0.3 * R1 + 0.59 * G1 + 0.11 * B1) diff --git a/src/lib/emscripten.test.ts b/src/lib/emscripten.test.ts index cd2ab94..79f434c 100644 --- a/src/lib/emscripten.test.ts +++ b/src/lib/emscripten.test.ts @@ -11,7 +11,13 @@ test('importEmscriptenSymbolMap', () => { 'c:C', ].join('\n'), ), - ).toEqual(new Map([['a', 'A'], ['b', 'B'], ['c', 'C']])) + ).toEqual( + new Map([ + ['a', 'A'], + ['b', 'B'], + ['c', 'C'], + ]), + ) // Valid symbol map with trailing newline expect( @@ -25,7 +31,14 @@ test('importEmscriptenSymbolMap', () => { '', ].join('\n'), ), - ).toEqual(new Map([['a', 'A'], ['b', 'B'], ['c', 'C'], ['d', 'D-D']])) + ).toEqual( + new Map([ + ['a', 'A'], + ['b', 'B'], + ['c', 'C'], + ['d', 'D-D'], + ]), + ) // Valid symbol map with non-alpha characters expect(importEmscriptenSymbolMap('u6:__ZN8tinyxml210XMLCommentD0Ev\n')).toEqual( diff --git a/src/lib/file-format.ts b/src/lib/file-format.ts index 237ba67..2ec5eee 100644 --- a/src/lib/file-format.ts +++ b/src/lib/file-format.ts @@ -138,7 +138,10 @@ function importSpeedscopeProfile( for (let i = 0; i < samples.length; i++) { const stack = samples[i] const weight = weights[i] - profile.appendSampleWithWeight(stack.map(n => frameInfos[n]), weight) + profile.appendSampleWithWeight( + stack.map(n => frameInfos[n]), + weight, + ) } return profile.build() diff --git a/src/lib/math.test.ts b/src/lib/math.test.ts index 3f4ec32..eca343c 100644 --- a/src/lib/math.test.ts +++ b/src/lib/math.test.ts @@ -13,9 +13,10 @@ test('clamp', () => { // Change this to jsc.integer to debug failures more easily let numericType = jsc.number -const arbitraryVec2 = jsc - .record({x: jsc.integer, y: numericType}) - .smap(v => new Vec2(v.x, v.y), v => v) +const arbitraryVec2 = jsc.record({x: jsc.integer, y: numericType}).smap( + v => new Vec2(v.x, v.y), + v => v, +) const positiveVec2 = jsc.suchthat(arbitraryVec2, v => v.x > 0 && v.y > 0) @@ -28,23 +29,25 @@ const arbitraryTransform = jsc m11: numericType, m12: numericType, }) - .smap(t => new AffineTransform(t.m00, t.m01, t.m02, t.m10, t.m11, t.m12), t => t) + .smap( + t => new AffineTransform(t.m00, t.m01, t.m02, t.m10, t.m11, t.m12), + t => t, + ) const invertibleTransform = jsc.suchthat(arbitraryTransform, t => t.det() != 0) const simpleTransform = jsc.suchthat( - jsc - .record({scale: arbitraryVec2, translation: arbitraryVec2}) - .smap( - t => AffineTransform.withScale(t.scale).withTranslation(t.translation), - t => ({scale: t.getScale(), translation: t.getTranslation()}), - ), + jsc.record({scale: arbitraryVec2, translation: arbitraryVec2}).smap( + t => AffineTransform.withScale(t.scale).withTranslation(t.translation), + t => ({scale: t.getScale(), translation: t.getTranslation()}), + ), t => t.det() != 0, ) -const arbitraryRect = jsc - .record({origin: arbitraryVec2, size: positiveVec2}) - .smap(r => new Rect(r.origin, r.size), r => r) +const arbitraryRect = jsc.record({origin: arbitraryVec2, size: positiveVec2}).smap( + r => new Rect(r.origin, r.size), + r => r, +) describe('Vec2', () => { test('constructor', () => { @@ -263,51 +266,35 @@ describe('AffineTransform', () => { expect(new AffineTransform(0, 0, 0, 0, 0, 0).inverted()).toBe(null) jsc.assertForall(invertibleTransform, t => { - return t - .inverted()! - .inverted()! - .approxEquals(t) + return t.inverted()!.inverted()!.approxEquals(t) }) }) test('translation', () => { jsc.assertForall(arbitraryTransform, arbitraryVec2, (t, v1) => { - return t - .withTranslation(v1) - .getTranslation() - .equals(v1) + return t.withTranslation(v1).getTranslation().equals(v1) }) jsc.assertForall(arbitraryTransform, arbitraryVec2, (t, v1) => { const initialTranslation = t.getTranslation() - return t - .translatedBy(v1) - .getTranslation() - .approxEquals(initialTranslation.plus(v1)) + return t.translatedBy(v1).getTranslation().approxEquals(initialTranslation.plus(v1)) }) }) test('scale', () => { jsc.assertForall(arbitraryTransform, arbitraryVec2, (t, v1) => { - return t - .withScale(v1) - .getScale() - .equals(v1) + return t.withScale(v1).getScale().equals(v1) }) }) test('transformVector', () => { // Vector transformation are translation-invariant jsc.assertForall(arbitraryVec2, arbitraryVec2, (v1, v2) => { - return AffineTransform.withTranslation(v1) - .transformVector(v2) - .approxEquals(v2) + return AffineTransform.withTranslation(v1).transformVector(v2).approxEquals(v2) }) jsc.assertForall(arbitraryVec2, arbitraryVec2, (v1, v2) => { - return AffineTransform.withScale(v1) - .transformVector(v2) - .approxEquals(v2.timesPointwise(v1)) + return AffineTransform.withScale(v1).transformVector(v2).approxEquals(v2.timesPointwise(v1)) }) }) @@ -319,15 +306,11 @@ describe('AffineTransform', () => { test('transformPosition', () => { jsc.assertForall(arbitraryVec2, arbitraryVec2, (v1, v2) => { - return AffineTransform.withTranslation(v1) - .transformPosition(v2) - .approxEquals(v2.plus(v1)) + return AffineTransform.withTranslation(v1).transformPosition(v2).approxEquals(v2.plus(v1)) }) jsc.assertForall(arbitraryVec2, arbitraryVec2, (v1, v2) => { - return AffineTransform.withScale(v1) - .transformPosition(v2) - .approxEquals(v2.timesPointwise(v1)) + return AffineTransform.withScale(v1).transformPosition(v2).approxEquals(v2.timesPointwise(v1)) }) }) @@ -359,10 +342,7 @@ describe('AffineTransform', () => { test('times', () => { jsc.assertForall(invertibleTransform, invertibleTransform, (t1, t2) => { - return t1 - .times(t2) - .times(t2.inverted()!) - .approxEquals(t1) + return t1.times(t2).times(t2.inverted()!).approxEquals(t1) }) }) }) diff --git a/src/lib/profile.test.ts b/src/lib/profile.test.ts index 8496cee..0920d11 100644 --- a/src/lib/profile.test.ts +++ b/src/lib/profile.test.ts @@ -26,19 +26,22 @@ function toStackList(profile: Profile, grouped: boolean): string[] { const curStack: (number | string)[] = [] let lastValue = 0 - function openFrame(node: CallTreeNode, value: number) { + function maybeEmit(value: number) { if (lastValue != value) { - stackList.push(curStack.map(k => `${k}`).join(';')) + stackList.push( + curStack.map(k => `${k}`).join(';') + ` ${profile.formatValue(value - lastValue)}`, + ) lastValue = value } - curStack.push(node.frame.key) + } + + function openFrame(node: CallTreeNode, value: number) { + maybeEmit(value) + curStack.push(node.frame.name) } function closeFrame(node: CallTreeNode, value: number) { - if (lastValue != value) { - stackList.push(curStack.map(k => `${k}`).join(';')) - lastValue = value - } + maybeEmit(value) curStack.pop() } @@ -82,49 +85,49 @@ function verifyProfile(profile: Profile) { expect(toStackList(profile, false)).toEqual([ // prettier-ignore - 'a', - 'a;b', - 'a;b;d', - 'a;b;c', - '', - 'a', - 'a;b', - 'a;b;b', - 'a;b;e', - 'a', + 'a 1', + 'a;b 2', + 'a;b;d 1', + 'a;b;c 1', + ' 1', + 'a 1', + 'a;b 1', + 'a;b;b 1', + 'a;b;e 1', + 'a 1', ]) expect(toStackList(profile, true)).toEqual([ // prettier-ignore - 'a;b;e', - 'a;b;b', - 'a;b;c', - 'a;b;d', - 'a;b', - 'a', + 'a;b;d 1', + 'a;b;c 1', + 'a;b;b 1', + 'a;b;e 1', + 'a;b 3', + 'a 3', ]) const flattened = profile.getProfileWithRecursionFlattened() expect(toStackList(flattened, false)).toEqual([ // prettier-ignore - 'a', - 'a;b', - 'a;b;d', - 'a;b;c', - '', - 'a', - 'a;b', - 'a;b;e', - 'a', + 'a 1', + 'a;b 2', + 'a;b;d 1', + 'a;b;c 1', + ' 1', + 'a 1', + 'a;b 2', + 'a;b;e 1', + 'a 1', ]) expect(toStackList(flattened, true)).toEqual([ // prettier-ignore - 'a;b;e', - 'a;b;c', - 'a;b;d', - 'a;b', - 'a', + 'a;b;d 1', + 'a;b;c 1', + 'a;b;e 1', + 'a;b 4', + 'a 3', ]) } @@ -259,9 +262,9 @@ test('getInvertedProfileForCallersOf', () => { expect(toStackList(inverted, false)).toEqual([ // prettier-ignore - 'b', - 'b;a', - 'b;d', + 'b 1', + 'b;a 3', + 'b;d 1', ]) }) @@ -287,10 +290,10 @@ test('getProfileForCalleesOf', () => { expect(toStackList(inverted, false)).toEqual([ // prettier-ignore - 'b', - 'b;c', - 'b;d', - 'b', + 'b 2', + 'b;c 1', + 'b;d 1', + 'b 1', ]) }) @@ -313,8 +316,8 @@ test('getProfileWithRecursionFlattened', () => { expect(toStackList(inverted, false)).toEqual([ // prettier-ignore - 'a', - 'a;b', + 'a 1', + 'a;b 3', ]) const framesInProfile = new Set() diff --git a/src/lib/profile.ts b/src/lib/profile.ts index f1db730..5852937 100644 --- a/src/lib/profile.ts +++ b/src/lib/profile.ts @@ -181,9 +181,9 @@ export class Profile { let childTime = 0 const children = [...node.children] - children.sort((a, b) => (a.getTotalWeight() > b.getTotalWeight() ? -1 : 1)) + children.sort((a, b) => -(a.getTotalWeight() - b.getTotalWeight())) - children.forEach(function(child) { + children.forEach(function (child) { visit(child, start + childTime) childTime += child.getTotalWeight() }) @@ -507,7 +507,10 @@ export class StackListProfileBuilder extends Profile { this.setValueFormatter(new RawValueFormatter()) } } - this.totalWeight = Math.max(this.totalWeight, this.weights.reduce((a, b) => a + b, 0)) + this.totalWeight = Math.max( + this.totalWeight, + this.weights.reduce((a, b) => a + b, 0), + ) return this } } @@ -557,9 +560,7 @@ export class CallTreeProfileBuilder extends Profile { this.weights.push(value - this.lastValue) } else if (delta < 0) { throw new Error( - `Samples must be provided in increasing order of cumulative value. Last sample was ${ - this.lastValue - }, this sample was ${value}`, + `Samples must be provided in increasing order of cumulative value. Last sample was ${this.lastValue}, this sample was ${value}`, ) } } diff --git a/src/lib/stats.ts b/src/lib/stats.ts index 284b5ea..a1a2dbd 100644 --- a/src/lib/stats.ts +++ b/src/lib/stats.ts @@ -53,7 +53,7 @@ export class StatsPanel { this.msPanel.update(time - this.beginTime, 200) if (time >= this.prevTime + 1000) { - this.fpsPanel.update(this.frames * 1000 / (time - this.prevTime), 100) + this.fpsPanel.update((this.frames * 1000) / (time - this.prevTime), 100) this.prevTime = time this.frames = 0 } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index b1dec30..46fc98a 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -4,7 +4,9 @@ export function lastOf(ts: T[]): T | null { export function sortBy(ts: T[], key: (t: T) => number | string): void { function comparator(a: T, b: T) { - return key(a) < key(b) ? -1 : 1 + const keyA = key(a) + const keyB = key(b) + return keyA < keyB ? -1 : keyA > keyB ? 1 : 0 } ts.sort(comparator) } @@ -178,15 +180,17 @@ export function lazyStatic(cb: () => T): () => T { } } -const base64lookupTable = lazyStatic((): Map => { - const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - const ret = new Map() - for (let i = 0; i < alphabet.length; i++) { - ret.set(alphabet.charAt(i), i) - } - ret.set('=', -1) - return ret -}) +const base64lookupTable = lazyStatic( + (): Map => { + const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + const ret = new Map() + for (let i = 0; i < alphabet.length; i++) { + ret.set(alphabet.charAt(i), i) + } + ret.set('=', -1) + return ret + }, +) // NOTE: There are probably simpler solutions to this problem, but I have this written already, so // until we run into problems with this, let's just use this. @@ -210,9 +214,7 @@ export function decodeBase64(encoded: string): Uint8Array { if (encoded.length % 4 !== 0) { throw new Error( - `Invalid length for base64 encoded string. Expected length % 4 = 0, got length = ${ - encoded.length - }`, + `Invalid length for base64 encoded string. Expected length % 4 = 0, got length = ${encoded.length}`, ) } diff --git a/src/store/getters.ts b/src/store/getters.ts index c80e908..752abee 100644 --- a/src/store/getters.ts +++ b/src/store/getters.ts @@ -49,23 +49,22 @@ export const getProfileToView = memoizeByShallowEquality( return flattenRecursion ? profile.getProfileWithRecursionFlattened() : profile }, ) -export const getFrameToColorBucket = memoizeByReference((profile: Profile): Map< - string | number, - number -> => { - const frames: Frame[] = [] - profile.forEachFrame(f => frames.push(f)) - function key(f: Frame) { - return (f.file || '') + f.name - } - function compare(a: Frame, b: Frame) { - return key(a) > key(b) ? 1 : -1 - } - frames.sort(compare) - const frameToColorBucket = new Map() - for (let i = 0; i < frames.length; i++) { - frameToColorBucket.set(frames[i].key, Math.floor(255 * i / frames.length)) - } +export const getFrameToColorBucket = memoizeByReference( + (profile: Profile): Map => { + const frames: Frame[] = [] + profile.forEachFrame(f => frames.push(f)) + function key(f: Frame) { + return (f.file || '') + f.name + } + function compare(a: Frame, b: Frame) { + return key(a) > key(b) ? 1 : -1 + } + frames.sort(compare) + const frameToColorBucket = new Map() + for (let i = 0; i < frames.length; i++) { + frameToColorBucket.set(frames[i].key, Math.floor((255 * i) / frames.length)) + } - return frameToColorBucket -}) + return frameToColorBucket + }, +) diff --git a/src/views/application.tsx b/src/views/application.tsx index ce26a31..c7b9de2 100644 --- a/src/views/application.tsx +++ b/src/views/application.tsx @@ -678,7 +678,7 @@ export class Application extends StatelessComponent {
{this.renderContent()}
{this.props.dragActive &&
} diff --git a/src/views/flamechart-detail-view.tsx b/src/views/flamechart-detail-view.tsx index 26a7ab5..30d7897 100644 --- a/src/views/flamechart-detail-view.tsx +++ b/src/views/flamechart-detail-view.tsx @@ -19,8 +19,8 @@ class StatisticsTable extends Component { render() { const total = this.props.formatter(this.props.selectedTotal) const self = this.props.formatter(this.props.selectedSelf) - const totalPerc = 100.0 * this.props.selectedTotal / this.props.grandTotal - const selfPerc = 100.0 * this.props.selectedSelf / this.props.grandTotal + const totalPerc = (100.0 * this.props.selectedTotal) / this.props.grandTotal + const selfPerc = (100.0 * this.props.selectedSelf) / this.props.grandTotal return (
diff --git a/src/views/flamechart-minimap-view.tsx b/src/views/flamechart-minimap-view.tsx index 04d3d33..acaeb03 100644 --- a/src/views/flamechart-minimap-view.tsx +++ b/src/views/flamechart-minimap-view.tsx @@ -120,9 +120,7 @@ export class FlamechartMinimapView extends Component { formatValue(weight: number) { const totalWeight = this.props.flamechart.getTotalWeight() - const percent = 100 * weight / totalWeight + const percent = (100 * weight) / totalWeight const formattedPercent = formatPercent(percent) return `${this.props.flamechart.formatValue(weight)} (${formattedPercent})` } diff --git a/src/views/flamechart-wrapper.tsx b/src/views/flamechart-wrapper.tsx index 9e27aa4..62a6642 100644 --- a/src/views/flamechart-wrapper.tsx +++ b/src/views/flamechart-wrapper.tsx @@ -34,7 +34,7 @@ export class FlamechartWrapper extends StatelessComponent { } private formatValue(weight: number) { const totalWeight = this.props.flamechart.getTotalWeight() - const percent = 100 * weight / totalWeight + const percent = (100 * weight) / totalWeight const formattedPercent = formatPercent(percent) return `${this.props.flamechart.formatValue(weight)} (${formattedPercent})` } diff --git a/src/views/profile-table-view.tsx b/src/views/profile-table-view.tsx index e292f91..1a7af8c 100644 --- a/src/views/profile-table-view.tsx +++ b/src/views/profile-table-view.tsx @@ -83,8 +83,8 @@ export class ProfileTableView extends Component { const totalWeight = frame.getTotalWeight() const selfWeight = frame.getSelfWeight() - const totalPerc = 100.0 * totalWeight / profile.getTotalNonIdleWeight() - const selfPerc = 100.0 * selfWeight / profile.getTotalNonIdleWeight() + const totalPerc = (100.0 * totalWeight) / profile.getTotalNonIdleWeight() + const selfPerc = (100.0 * selfWeight) / profile.getTotalNonIdleWeight() const selected = frame === selectedFrame