From d30bb2ef7e3ab35ae772d38d6740377fb6659a0d Mon Sep 17 00:00:00 2001 From: Jamie Wong Date: Mon, 20 Apr 2020 08:26:59 -0700 Subject: [PATCH] Fix the build for node 13.x, make travis test 10, 12, 13, stable (#263) @JustinBeckwith pointed out in #262 that `npm install` was broken in node 13.x, and @DanielRuf pointed in #254 that test fail for node 11+ because of a change to stability of sorting. This PR seeks to address both of those. The installation issue was fixed by just regenerating `package-lock.json` without needing to bump any of the direct dependency versions. The test failure issue requires manual intervention. To fix the sort stability issue, I updated the tests to use the stable sort values (these were all the correct values, though some of the test values were incorrect). To make the suite still pass for node 10, I added a hack where I override `Array.prototype.sort` with a stable implementation that's *only* used in tests (See comments in code for a justification for why) ## Test Plan Before this PR: `npm install` on node 13.x fails & `npm run jest` results in test failures After this PR: `npm install` on node 13.x passes & `npm run jest` passes for node 10, 12, and 13. --- .travis.yml | 5 +- package-lock.json | 658 +----------------- package.json | 7 +- prettier.config.js | 3 +- src/gl/canvas-context.ts | 4 +- src/gl/flamechart-renderer.ts | 8 +- src/gl/overlay-rectangle-renderer.ts | 7 +- src/gl/rectangle-batch-renderer.ts | 9 +- src/import/__snapshots__/chrome.test.ts.snap | 184 ++--- .../__snapshots__/trace-event.test.ts.snap | 38 +- src/jest-setup.js | 51 ++ src/lib/color.ts | 18 +- src/lib/emscripten.test.ts | 17 +- src/lib/file-format.ts | 5 +- src/lib/math.test.ts | 70 +- src/lib/profile.test.ts | 95 +-- src/lib/profile.ts | 13 +- src/lib/stats.ts | 2 +- src/lib/utils.ts | 28 +- src/store/getters.ts | 37 +- src/views/application.tsx | 2 +- src/views/flamechart-detail-view.tsx | 4 +- src/views/flamechart-minimap-view.tsx | 4 +- src/views/flamechart-pan-zoom-view.tsx | 4 +- src/views/flamechart-view.tsx | 2 +- src/views/flamechart-wrapper.tsx | 2 +- src/views/profile-table-view.tsx | 4 +- 27 files changed, 368 insertions(+), 913 deletions(-) create mode 100644 src/jest-setup.js 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