Import from stackprof to convenient in-memory format

This commit is contained in:
Jamie Wong 2017-11-22 00:00:31 -08:00
commit f82733d0ef
11 changed files with 58516 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
dist

58
index.html Normal file
View File

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>SpeedScope</title>
<style>
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
</style>
</head>
<body>
<div id="root"></div>
<script src="dist/speedscope.js"></script>
</body>
</html>

33
index.tsx Normal file
View File

@ -0,0 +1,33 @@
import {h, render, Component} from 'preact'
import {StyleSheet, css} from 'aphrodite'
import {importFromStackprof} from './stackprof'
class Application extends Component<{}, void> {
onDrop = (ev: DragEvent) => {
const reader = new FileReader
reader.addEventListener('loadend', () => {
console.log(importFromStackprof(reader.result))
})
reader.readAsText(ev.dataTransfer.files.item(0))
ev.preventDefault()
}
onDragOver = (ev: DragEvent) => {
ev.preventDefault()
}
render() {
return <div onDrop={this.onDrop} onDragOver={this.onDragOver} className={css(style.root)}>
</div>
}
}
const style = StyleSheet.create({
root: {
width: '100vw',
height: '100vw'
}
})
render(<Application />, document.body)

845
package-lock.json generated Normal file
View File

@ -0,0 +1,845 @@
{
"name": "speedscope",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/aphrodite": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/@types/aphrodite/-/aphrodite-0.5.6.tgz",
"integrity": "sha512-HbnzjThUoJmTT64yC1Z8xeabgVYlhWQq6GjdZoztFzvfe7LclRNUHcChZQ8abFRApLkEC2GA/eJXZuncJlK/LQ==",
"dev": true,
"requires": {
"@types/react": "16.0.25"
}
},
"@types/node": {
"version": "8.0.53",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.53.tgz",
"integrity": "sha512-54Dm6NwYeiSQmRB1BLXKr5GELi0wFapR1npi8bnZhEcu84d/yQKqnwwXQ56hZ0RUbTG6L5nqDZaN3dgByQXQRQ==",
"dev": true
},
"@types/react": {
"version": "16.0.25",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.0.25.tgz",
"integrity": "sha512-K79zMwWRzQ2db+nPoKpi3gA/KmLo6ZQgT4iO2QPEUdBO7as0PcgrmU9KHYzIO3V6lbD7gRjOM0/nUch6xBfOvQ==",
"dev": true
},
"@types/react-dom": {
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.0.3.tgz",
"integrity": "sha512-xAvZiGhQlEhjStoKktoai8CelXVFBaSN6JX4vy1UQioRba3c2vum1TGzR0thHoEauZtIwzWg8mos0AHu2ne4jw==",
"dev": true,
"requires": {
"@types/node": "8.0.53",
"@types/react": "16.0.25"
}
},
"acorn": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz",
"integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==",
"dev": true
},
"aphrodite": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/aphrodite/-/aphrodite-1.2.5.tgz",
"integrity": "sha1-g1jDbIC7A67puXFlqqcBhiJbSYM=",
"dev": true,
"requires": {
"asap": "2.0.6",
"inline-style-prefixer": "3.0.8",
"string-hash": "1.1.3"
}
},
"arr-diff": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
"integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
"dev": true,
"requires": {
"arr-flatten": "1.1.0"
}
},
"arr-flatten": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
"dev": true
},
"array-unique": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
"integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
"dev": true
},
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
"dev": true
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
"bowser": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/bowser/-/bowser-1.8.1.tgz",
"integrity": "sha512-NMPaR8ILtdLSWzxQtEs16XbxMcY8ohWGQ5V+TZSJS3fNUt/PBAGkF6YWO9B/4qWE23bK3o0moQKq8UyFEosYkA==",
"dev": true
},
"brace-expansion": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
"integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
"dev": true,
"requires": {
"balanced-match": "1.0.0",
"concat-map": "0.0.1"
}
},
"braces": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
"integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
"dev": true,
"requires": {
"expand-range": "1.8.2",
"preserve": "0.2.0",
"repeat-element": "1.1.2"
}
},
"browser-resolve": {
"version": "1.11.2",
"resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz",
"integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=",
"dev": true,
"requires": {
"resolve": "1.1.7"
},
"dependencies": {
"resolve": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
"integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
"dev": true
}
}
},
"buffer-es6": {
"version": "4.9.3",
"resolved": "https://registry.npmjs.org/buffer-es6/-/buffer-es6-4.9.3.tgz",
"integrity": "sha1-8mNHuC33b9N+GLy1KIxJcM/VxAQ=",
"dev": true
},
"builtin-modules": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
"dev": true
},
"compare-versions": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-2.0.1.tgz",
"integrity": "sha1-Htwfk2h/2XoyXFn1XkWgfbEGrKY=",
"dev": 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
},
"core-js": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=",
"dev": true
},
"css-in-js-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz",
"integrity": "sha512-yuWmPMD9FLi50Xf3k8W8oO3WM1eVnxEGCldCLyfusQ+CgivFk0s23yst4ooW6tfxMuSa03S6uUEga9UhX6GRrA==",
"dev": true,
"requires": {
"hyphenate-style-name": "1.0.2"
}
},
"encoding": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
"dev": true,
"requires": {
"iconv-lite": "0.4.19"
}
},
"estree-walker": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.5.0.tgz",
"integrity": "sha512-/bEAy+yKAZQrEWUhGmS3H9XpGqSDBtRzX0I2PgMw9kA2n1jN22uV5B5p7MFdZdvWdXCRJztXAfx6ZeRfgkEETg==",
"dev": true
},
"expand-brackets": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
"integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
"dev": true,
"requires": {
"is-posix-bracket": "0.1.1"
}
},
"expand-range": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
"integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
"dev": true,
"requires": {
"fill-range": "2.2.3"
}
},
"extglob": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
"integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
"dev": true,
"requires": {
"is-extglob": "1.0.0"
}
},
"fbjs": {
"version": "0.8.16",
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz",
"integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=",
"dev": true,
"requires": {
"core-js": "1.2.7",
"isomorphic-fetch": "2.2.1",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
"promise": "7.3.1",
"setimmediate": "1.0.5",
"ua-parser-js": "0.7.17"
}
},
"filename-regex": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
"integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
"dev": true
},
"fill-range": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
"integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
"dev": true,
"requires": {
"is-number": "2.1.0",
"isobject": "2.1.0",
"randomatic": "1.1.7",
"repeat-element": "1.1.2",
"repeat-string": "1.6.1"
}
},
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
"dev": true
},
"for-own": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
"integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
"dev": true,
"requires": {
"for-in": "1.0.2"
}
},
"glob-base": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
"integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
"dev": true,
"requires": {
"glob-parent": "2.0.0",
"is-glob": "2.0.1"
}
},
"glob-parent": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
"integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
"dev": true,
"requires": {
"is-glob": "2.0.1"
}
},
"hyphenate-style-name": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz",
"integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es=",
"dev": true
},
"iconv-lite": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==",
"dev": true
},
"inline-style-prefixer": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz",
"integrity": "sha1-hVG45bTVcyROZqNLBPfTIHaitTQ=",
"dev": true,
"requires": {
"bowser": "1.8.1",
"css-in-js-utils": "2.0.0"
}
},
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"dev": true
},
"is-dotfile": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
"integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
"dev": true
},
"is-equal-shallow": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
"integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
"dev": true,
"requires": {
"is-primitive": "2.0.0"
}
},
"is-extendable": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
"dev": true
},
"is-extglob": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
"integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
"dev": true
},
"is-glob": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
"integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
"dev": true,
"requires": {
"is-extglob": "1.0.0"
}
},
"is-module": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
"dev": true
},
"is-number": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
"integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
"dev": true,
"requires": {
"kind-of": "3.2.2"
}
},
"is-posix-bracket": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
"integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
"dev": true
},
"is-primitive": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
"integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
"dev": true
},
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"dev": true
},
"isobject": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
"integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
"dev": true,
"requires": {
"isarray": "1.0.0"
}
},
"isomorphic-fetch": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
"dev": true,
"requires": {
"node-fetch": "1.7.3",
"whatwg-fetch": "2.0.3"
}
},
"js-tokens": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
"dev": true
},
"kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true,
"requires": {
"is-buffer": "1.1.6"
}
},
"loose-envify": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
"integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
"dev": true,
"requires": {
"js-tokens": "3.0.2"
}
},
"magic-string": {
"version": "0.22.4",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.4.tgz",
"integrity": "sha512-kxBL06p6iO2qPBHsqGK2b3cRwiRGpnmSuVWNhwHcMX7qJOUr1HvricYP1LZOCdkQBUp0jiWg2d6WJwR3vYgByw==",
"dev": true,
"requires": {
"vlq": "0.2.3"
}
},
"micromatch": {
"version": "2.3.11",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
"integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
"dev": true,
"requires": {
"arr-diff": "2.0.0",
"array-unique": "0.2.1",
"braces": "1.8.5",
"expand-brackets": "0.1.5",
"extglob": "0.3.2",
"filename-regex": "2.0.1",
"is-extglob": "1.0.0",
"is-glob": "2.0.1",
"kind-of": "3.2.2",
"normalize-path": "2.1.1",
"object.omit": "2.0.1",
"parse-glob": "3.0.4",
"regex-cache": "0.4.4"
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "1.1.8"
}
},
"node-fetch": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
"dev": true,
"requires": {
"encoding": "0.1.12",
"is-stream": "1.1.0"
}
},
"normalize-path": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
"dev": true,
"requires": {
"remove-trailing-separator": "1.1.0"
}
},
"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
},
"object.omit": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
"integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
"dev": true,
"requires": {
"for-own": "0.1.5",
"is-extendable": "0.1.1"
}
},
"parse-glob": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
"integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
"dev": true,
"requires": {
"glob-base": "0.3.0",
"is-dotfile": "1.0.3",
"is-extglob": "1.0.0",
"is-glob": "2.0.1"
}
},
"path-parse": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
"integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
"dev": true
},
"preact": {
"version": "8.2.6",
"resolved": "https://registry.npmjs.org/preact/-/preact-8.2.6.tgz",
"integrity": "sha1-ACi0Ju+Y/Mp0Gjxhf/W4E7mpR8c=",
"dev": true
},
"preserve": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
"integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
"dev": true
},
"process-es6": {
"version": "0.11.6",
"resolved": "https://registry.npmjs.org/process-es6/-/process-es6-0.11.6.tgz",
"integrity": "sha1-xrs4n5qVH4K9TrFpYAEFvS/5x3g=",
"dev": true
},
"promise": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
"dev": true,
"requires": {
"asap": "2.0.6"
}
},
"prop-types": {
"version": "15.6.0",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
"integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
"dev": true,
"requires": {
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1"
}
},
"randomatic": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
"integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==",
"dev": true,
"requires": {
"is-number": "3.0.0",
"kind-of": "4.0.0"
},
"dependencies": {
"is-number": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
"dev": true,
"requires": {
"kind-of": "3.2.2"
},
"dependencies": {
"kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true,
"requires": {
"is-buffer": "1.1.6"
}
}
}
},
"kind-of": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
"integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
"dev": true,
"requires": {
"is-buffer": "1.1.6"
}
}
}
},
"react": {
"version": "16.1.1",
"resolved": "https://registry.npmjs.org/react/-/react-16.1.1.tgz",
"integrity": "sha512-FQfiFfk2z2Fk87OngNJHT05KyC9DOVn8LPeB7ZX+9u5+yU1JK6o5ozRlU3PeOMr0IFkWNvgn9jU8/IhRxR1F0g==",
"dev": true,
"requires": {
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
"prop-types": "15.6.0"
}
},
"react-dom": {
"version": "16.1.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.1.1.tgz",
"integrity": "sha512-q06jiwST8SEPAMIEkAsu7BgynEZtqF87VrTc70XsW7nxVhWEu2Y4MF5UfxxHQO/mNtQHQWP0YcFxmwm9oMrMaQ==",
"dev": true,
"requires": {
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
"prop-types": "15.6.0"
}
},
"regex-cache": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
"integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
"dev": true,
"requires": {
"is-equal-shallow": "0.1.3"
}
},
"remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
"dev": true
},
"repeat-element": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
"integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
"dev": true
},
"repeat-string": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
"dev": true
},
"resolve": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz",
"integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==",
"dev": true,
"requires": {
"path-parse": "1.0.5"
}
},
"rollup": {
"version": "0.51.8",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-0.51.8.tgz",
"integrity": "sha512-e7FwWxqb4vhdonmwRH06nqC9wR6h1kZojK2D+lN1xjiB8FDtAKgy7o+r8fCXVzQZ1ZCdcVlls3mTq5g6u38Jew==",
"dev": true
},
"rollup-plugin-commonjs": {
"version": "8.2.6",
"resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-8.2.6.tgz",
"integrity": "sha512-qK0+uhktmnAgZkHkqFuajNmPw93fjrO7+CysDaxWE5jrUR9XSlSvuao5ZJP+XizxA8weakhgYYBtbVz9SGBpjA==",
"dev": true,
"requires": {
"acorn": "5.2.1",
"estree-walker": "0.5.0",
"magic-string": "0.22.4",
"resolve": "1.5.0",
"rollup-pluginutils": "2.0.1"
}
},
"rollup-plugin-node-globals": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-node-globals/-/rollup-plugin-node-globals-1.1.0.tgz",
"integrity": "sha1-fv2NYR0TJzeCnoBOn1H1CWKvRR8=",
"dev": true,
"requires": {
"acorn": "4.0.13",
"buffer-es6": "4.9.3",
"estree-walker": "0.2.1",
"magic-string": "0.16.0",
"process-es6": "0.11.6",
"rollup-pluginutils": "1.5.2"
},
"dependencies": {
"acorn": {
"version": "4.0.13",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
"integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
"dev": true
},
"estree-walker": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.2.1.tgz",
"integrity": "sha1-va/oCVOD2EFNXcLs9MkXO225QS4=",
"dev": true
},
"magic-string": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.16.0.tgz",
"integrity": "sha1-lw67DacZMwEoX7GqZQ85vdgetFo=",
"dev": true,
"requires": {
"vlq": "0.2.3"
}
},
"rollup-pluginutils": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz",
"integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=",
"dev": true,
"requires": {
"estree-walker": "0.2.1",
"minimatch": "3.0.4"
}
}
}
},
"rollup-plugin-node-resolve": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.0.0.tgz",
"integrity": "sha1-i4l8TDAw1QASd7BRSyXSygloPuA=",
"dev": true,
"requires": {
"browser-resolve": "1.11.2",
"builtin-modules": "1.1.1",
"is-module": "1.0.0",
"resolve": "1.5.0"
}
},
"rollup-plugin-replace": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-replace/-/rollup-plugin-replace-2.0.0.tgz",
"integrity": "sha512-pK9mTd/FNrhtBxcTBXoh0YOwRIShV0gGhv9qvUtNcXHxIMRZMXqfiZKVBmCRGp8/2DJRy62z2JUE7/5tP6WxOQ==",
"dev": true,
"requires": {
"magic-string": "0.22.4",
"minimatch": "3.0.4",
"rollup-pluginutils": "2.0.1"
}
},
"rollup-plugin-typescript": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/rollup-plugin-typescript/-/rollup-plugin-typescript-0.8.1.tgz",
"integrity": "sha1-L/fuzCHPa7K0P8J+W2iJUs5xkko=",
"dev": true,
"requires": {
"compare-versions": "2.0.1",
"object-assign": "4.1.1",
"rollup-pluginutils": "1.5.2",
"tippex": "2.3.1",
"typescript": "1.8.10"
},
"dependencies": {
"estree-walker": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.2.1.tgz",
"integrity": "sha1-va/oCVOD2EFNXcLs9MkXO225QS4=",
"dev": true
},
"rollup-pluginutils": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz",
"integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=",
"dev": true,
"requires": {
"estree-walker": "0.2.1",
"minimatch": "3.0.4"
}
},
"typescript": {
"version": "1.8.10",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-1.8.10.tgz",
"integrity": "sha1-tHXW4N/wv1DyluXKbvn7tccyDx4=",
"dev": true
}
}
},
"rollup-pluginutils": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.0.1.tgz",
"integrity": "sha1-fslbNXP2VDpGpkYb2afFRFJdD8A=",
"dev": true,
"requires": {
"estree-walker": "0.3.1",
"micromatch": "2.3.11"
},
"dependencies": {
"estree-walker": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.3.1.tgz",
"integrity": "sha1-5rGlHPcpJSTnI3wxLl/mZgwc4ao=",
"dev": true
}
}
},
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
"dev": true
},
"string-hash": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz",
"integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=",
"dev": true
},
"tippex": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tippex/-/tippex-2.3.1.tgz",
"integrity": "sha1-ov1bcIfXy/sgyYBqbBYQjCwPr9o=",
"dev": true
},
"typescript": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.1.tgz",
"integrity": "sha1-7znN6ierrAtQAkLWcmq5DgyEZjE=",
"dev": true
},
"ua-parser-js": {
"version": "0.7.17",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
"integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==",
"dev": true
},
"vlq": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz",
"integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==",
"dev": true
},
"whatwg-fetch": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",
"integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=",
"dev": true
}
}
}

27
package.json Normal file
View File

@ -0,0 +1,27 @@
{
"name": "speedscope",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"watch": "rollup -c --watch",
"build": "rollup -c"
},
"author": "",
"license": "MIT",
"devDependencies": {
"@types/aphrodite": "^0.5.6",
"@types/react-dom": "^16.0.3",
"aphrodite": "^1.2.5",
"preact": "^8.2.6",
"react": "^16.1.1",
"react-dom": "^16.1.1",
"rollup": "^0.51.5",
"rollup-plugin-commonjs": "^8.2.6",
"rollup-plugin-node-globals": "^1.1.0",
"rollup-plugin-node-resolve": "^3.0.0",
"rollup-plugin-replace": "^2.0.0",
"rollup-plugin-typescript": "^0.8.1",
"typescript": "^2.6.1"
}
}

106
profile.ts Normal file
View File

@ -0,0 +1,106 @@
export interface Frame {
key: string | number
// Name of the frame. May be a method name, e.g.
// "ActiveRecord##to_hash"
name: string
// File path of the code corresponding to this
// call stack frame.
file?: string
// Line in the given file where this frame occurs
line?: number
// Column in the file
col?: number
// Color, if specified, to associate with this frame.
// If unspecified, will be generated.
color?: string
}
export class CallTreeNode {
children = new Map<Frame, CallTreeNode>()
private selfTime = 0
private totalTime = 0
getSelfTime() { return this.selfTime }
getTotalTime() { return this.totalTime }
addToTotalTime(delta: number) { this.totalTime += delta }
addToSelfTime(delta: number) { this.selfTime += delta }
constructor(readonly frame: Frame, readonly parent: CallTreeNode | null) {}
}
export interface ProfilingEvent {
// Name of the event, e.g. "SQL Query"
name: string
// Details (e.g. the SQL query)
details?: string
// Bottom of the stack of the call-tree
stack: CallTreeNode
// Elapsed time since the start of the profile,
// in microseconds
start: number
end: number
// Color, if specified to associate with this event.
// If unspecified, will be generated based on the name.
color?: string
}
function getOrInsert<K, V>(map: Map<K, V>, k: K, v: V): V {
if (!map.has(k)) map.set(k, v)
return map.get(k)!
}
export class Profile {
// Duration of the entire profile, in microseconds
duration: number
frames = new Map<string | number, Frame>()
calltreeRoots = new Map<Frame, CallTreeNode>()
// List of references to CallTreeNodes at the top of the
// stack at the time of the sample.
samples: CallTreeNode[] = []
// List of time elapsed since the preceding sample was taken.
// The first elements it the time elapsed since the beginning
// of recording that the sample was taken.
// Times are in microseconds.
// This array should be the same length as the "samples" array.
timeDeltas: number[] = []
// List of events recorded in parallel with the call
// stack samples. Useful for overlaying IO events on
// the same time axis as the sampling profile.
events: ProfilingEvent[] = []
constructor(duration: number) {
this.duration = duration
}
appendSample(stack: Frame[], timeDelta: number) {
let node: CallTreeNode | null = null
let children = this.calltreeRoots
for (let frame of stack) {
frame = getOrInsert(this.frames, frame.key, frame)
node = getOrInsert(children, frame, new CallTreeNode(frame, node))
node.addToTotalTime(timeDelta)
children = node.children
}
if (node) {
node.addToSelfTime(timeDelta)
this.samples.push(node)
this.timeDeltas.push(timeDelta)
}
}
}

37
rollup.config.js Normal file
View File

@ -0,0 +1,37 @@
import commonjs from 'rollup-plugin-commonjs';
import nodeResolve from 'rollup-plugin-node-resolve';
import typescript from 'rollup-plugin-typescript';
import replace from 'rollup-plugin-replace';
import nodeGlobals from 'rollup-plugin-node-globals';
const plugins = [
typescript({
typescript: require('typescript')
}),
nodeResolve({
jsnext: true,
main: true
}),
commonjs({
include: 'node_modules/**',
namedExports: {
'aphrodite': ['StyleSheet', 'css'],
'react-dom': ['render'],
'react': ['Component', 'createElement']
},
ignore: [ 'domain' ]
}),
replace({
'process.env.NODE_ENV': JSON.stringify('development')
}),
nodeGlobals()
]
export default [{
input: 'index.tsx',
output: {
file: 'dist/speedscope.js',
format: 'iife'
},
plugins: plugins
}]

57125
sample/ruby-stackprof.json Normal file

File diff suppressed because it is too large Load Diff

227
serveit Executable file
View File

@ -0,0 +1,227 @@
#!/usr/bin/env ruby
# Copyright (c) 2015 Gary Bernhardt
#
# MIT License
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
require "find"
require "webrick"
require "open3"
require "optparse"
class ServeIt
VERSION = [0, 0, 2]
def self.main
serve_dir, ignored_paths, command = parse_opts
serve_dir = File.expand_path(serve_dir)
Server.new(serve_dir, ignored_paths, command).serve
end
def self.parse_opts
options = {:serve_dir => ".",
:ignored_paths => []}
parser = OptionParser.new do |opts|
opts.banner = "Usage: #{$PROGRAM_NAME} [options] command"
opts.on_tail("-s", "--serve-dir DIR", "Root directory for server") do |dir|
options[:serve_dir] = dir
end
opts.on_tail("-i", "--ignore PATH", "Ignore changes to file or directory") do |path|
options[:ignored_paths] << path
end
opts.on_tail("--version", "Show version") do |dir|
puts ServeIt::VERSION.join('.')
exit
end
end
begin
parser.parse!(ARGV)
rescue OptionParser::InvalidOption => e
$stderr.puts e
$stderr.puts parser
exit 1
end
if ARGV.count == 0
command = nil
elsif ARGV.count == 1
command = ARGV.fetch(0)
else
$stderr.write parser.to_s
exit 1
end
[options.fetch(:serve_dir), options.fetch(:ignored_paths), command]
end
class Server
def initialize(serve_dir, ignored_paths, command)
@mutex = Mutex.new
@serve_dir = serve_dir
@command = command
@rebuilder = Rebuilder.new(@command, ignored_paths) if @command
end
def serve
port = 8000
puts "Starting server at http://localhost:#{port}"
server = WEBrick::HTTPServer.new(:Port => port)
server.mount_proc '/' do |req, res|
relative_path = req.path.sub(/^\//, '')
local_abs_path = File.absolute_path(relative_path, @serve_dir)
if relative_path == "favicon.ico"
respond_to_favicon(res)
else
respond_to_path(res, relative_path, local_abs_path)
end
end
trap 'INT' do server.shutdown end
server.start
end
def respond_to_favicon(res)
res.status = 404
end
def respond_to_path(res, relative_path, local_abs_path)
begin
rebuild_if_needed
rescue Rebuilder::RebuildFailed => e
return respond_to_error(res, e.to_s)
end
if File.directory?(local_abs_path)
respond_to_dir(res, relative_path, local_abs_path)
else
# We're building a file
respond_to_file(res, local_abs_path)
end
end
def respond_to_error(res, message)
res.content_type = "text/html"
res.body = "<pre>" + message + "</pre>"
end
def respond_to_dir(res, rel_path, local_abs_path)
res.content_type = "text/html"
res.body = (
"<p><h3>Listing for /#{rel_path}</h3></p>\n" +
Dir.entries(local_abs_path).select do |child|
child != "."
end.sort.map do |child|
full_child_path_on_server = File.join("/", rel_path, child)
%{<a href="#{full_child_path_on_server}">#{child}</a><br>}
end.join("\n")
)
end
def respond_to_file(res, local_abs_path)
res.body = File.read(local_abs_path)
res.content_type = guess_content_type(local_abs_path)
end
def guess_content_type(path)
extension = File.extname(path).sub(/^\./, '')
WEBrick::HTTPUtils::DefaultMimeTypes.fetch(extension) do
"application/octet-stream"
end
end
def rebuild_if_needed
# Webrick is multi-threaded; guard against concurrent builds
@mutex.synchronize do
if @rebuilder
@rebuilder.rebuild_if_needed
end
end
end
end
class Rebuilder
def initialize(command, ignored_paths)
@command = command
@ignored_paths = ignored_paths
@last_disk_state = nil
end
def rebuild_if_needed
if disk_state != @last_disk_state
stdout_and_stderr, success = rebuild
if !success
message = "Failed to build! Command output:\n\n" + stdout_and_stderr
raise RebuildFailed.new(message)
end
# Get a new post-build disk state so we don't pick up changes made during
# the build.
@last_disk_state = disk_state
[stdout_and_stderr, success]
end
end
def rebuild
puts "Running command: #{@command}"
puts " begin build".rjust(80, "=")
start_time = Time.now
stdout_and_stderr, status = Open3.capture2e(@command)
print stdout_and_stderr
puts (" built in %.03fs" % (Time.now - start_time)).rjust(80, "=")
[stdout_and_stderr, status.success?]
end
def disk_state
start_time = Time.now
paths = []
Find.find(".") do |path|
if ignore_path?(path)
Find.prune
else
paths << path
end
end
paths.map do |path|
[path, File.stat(path).mtime.to_s]
end.sort.tap do
puts (" scanned in %.03fs" % (Time.now - start_time)).rjust(80, "=")
end
end
def ignore_path?(path)
@ignored_paths.any? do |ignored_path|
File.absolute_path(path) == File.absolute_path(ignored_path)
end
end
class RebuildFailed < RuntimeError; end
end
end
if __FILE__ == $PROGRAM_NAME
ServeIt.main
end

47
stackprof.ts Normal file
View File

@ -0,0 +1,47 @@
// https://github.com/tmm1/stackprof
import {Profile, Frame} from './profile'
interface StackprofFrame {
name: string
file?: string
line?: number
}
export interface StackprofProfile {
frames: {[number: string]: StackprofFrame}
raw: number[]
raw_timestamp_deltas: number[]
}
export function importFromStackprof(contents: string): Profile {
const stackprofProfile = JSON.parse(contents) as StackprofProfile
const duration = stackprofProfile.raw_timestamp_deltas.reduce((a, b) => a + b, 0)
const profile = new Profile(duration)
const {frames, raw, raw_timestamp_deltas} = stackprofProfile
let sampleIndex = 0
for (let i = 0; i < raw.length;) {
const stackHeight = raw[i++]
const stack: Frame[] = []
for (let j = 0; j < stackHeight; j++) {
const id = raw[i++]
stack.push({
key: id,
...frames[id]
})
}
const nSamples = raw[i++]
let sampleDuration = 0
for (let j = 0; j < nSamples; j++) {
sampleDuration += raw_timestamp_deltas[sampleIndex++]
}
profile.appendSample(stack, sampleDuration)
}
return profile
}

9
tsconfig.json Normal file
View File

@ -0,0 +1,9 @@
{
"compilerOptions": {
"module": "commonjs",
"strict": true,
"jsx": "react",
"jsxFactory": "h",
"target": "es2015"
}
}