@kylincloud/flamegraph 0.35.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/CHANGELOG.md +1211 -0
  2. package/LICENSE +202 -0
  3. package/README.md +251 -0
  4. package/dist/FlameGraph/FlameGraphComponent/CheckIcon.d.ts +2 -0
  5. package/dist/FlameGraph/FlameGraphComponent/CheckIcon.d.ts.map +1 -0
  6. package/dist/FlameGraph/FlameGraphComponent/ContextMenu.d.ts +17 -0
  7. package/dist/FlameGraph/FlameGraphComponent/ContextMenu.d.ts.map +1 -0
  8. package/dist/FlameGraph/FlameGraphComponent/ContextMenuHighlight.d.ts +14 -0
  9. package/dist/FlameGraph/FlameGraphComponent/ContextMenuHighlight.d.ts.map +1 -0
  10. package/dist/FlameGraph/FlameGraphComponent/DiffLegend.d.ts +9 -0
  11. package/dist/FlameGraph/FlameGraphComponent/DiffLegend.d.ts.map +1 -0
  12. package/dist/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.d.ts +8 -0
  13. package/dist/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.d.ts.map +1 -0
  14. package/dist/FlameGraph/FlameGraphComponent/Flamegraph.d.ts +96 -0
  15. package/dist/FlameGraph/FlameGraphComponent/Flamegraph.d.ts.map +1 -0
  16. package/dist/FlameGraph/FlameGraphComponent/Flamegraph_render.d.ts +27 -0
  17. package/dist/FlameGraph/FlameGraphComponent/Flamegraph_render.d.ts.map +1 -0
  18. package/dist/FlameGraph/FlameGraphComponent/GraphVizPane.d.ts +7 -0
  19. package/dist/FlameGraph/FlameGraphComponent/GraphVizPane.d.ts.map +1 -0
  20. package/dist/FlameGraph/FlameGraphComponent/Header.d.ts +12 -0
  21. package/dist/FlameGraph/FlameGraphComponent/Header.d.ts.map +1 -0
  22. package/dist/FlameGraph/FlameGraphComponent/Highlight.d.ts +18 -0
  23. package/dist/FlameGraph/FlameGraphComponent/Highlight.d.ts.map +1 -0
  24. package/dist/FlameGraph/FlameGraphComponent/LogoLink.d.ts +2 -0
  25. package/dist/FlameGraph/FlameGraphComponent/LogoLink.d.ts.map +1 -0
  26. package/dist/FlameGraph/FlameGraphComponent/color.d.ts +20 -0
  27. package/dist/FlameGraph/FlameGraphComponent/color.d.ts.map +1 -0
  28. package/dist/FlameGraph/FlameGraphComponent/colorPalette.d.ts +11 -0
  29. package/dist/FlameGraph/FlameGraphComponent/colorPalette.d.ts.map +1 -0
  30. package/dist/FlameGraph/FlameGraphComponent/constants.d.ts +6 -0
  31. package/dist/FlameGraph/FlameGraphComponent/constants.d.ts.map +1 -0
  32. package/dist/FlameGraph/FlameGraphComponent/index.d.ts +37 -0
  33. package/dist/FlameGraph/FlameGraphComponent/index.d.ts.map +1 -0
  34. package/dist/FlameGraph/FlameGraphComponent/murmur3.d.ts +2 -0
  35. package/dist/FlameGraph/FlameGraphComponent/murmur3.d.ts.map +1 -0
  36. package/dist/FlameGraph/FlameGraphComponent/testData.d.ts +53 -0
  37. package/dist/FlameGraph/FlameGraphComponent/testData.d.ts.map +1 -0
  38. package/dist/FlameGraph/FlameGraphComponent/utils.d.ts +6 -0
  39. package/dist/FlameGraph/FlameGraphComponent/utils.d.ts.map +1 -0
  40. package/dist/FlameGraph/FlameGraphComponent/viewTypes.d.ts +2 -0
  41. package/dist/FlameGraph/FlameGraphComponent/viewTypes.d.ts.map +1 -0
  42. package/dist/FlameGraph/FlameGraphRenderer.d.ts +86 -0
  43. package/dist/FlameGraph/FlameGraphRenderer.d.ts.map +1 -0
  44. package/dist/FlameGraph/decode.d.ts +27 -0
  45. package/dist/FlameGraph/decode.d.ts.map +1 -0
  46. package/dist/FlameGraph/normalize.d.ts +6 -0
  47. package/dist/FlameGraph/normalize.d.ts.map +1 -0
  48. package/dist/FlameGraph/uniqueness.d.ts +3 -0
  49. package/dist/FlameGraph/uniqueness.d.ts.map +1 -0
  50. package/dist/FlamegraphRenderer.d.ts +19 -0
  51. package/dist/FlamegraphRenderer.d.ts.map +1 -0
  52. package/dist/Icons.d.ts +9 -0
  53. package/dist/Icons.d.ts.map +1 -0
  54. package/dist/ProfilerTable.d.ts +21 -0
  55. package/dist/ProfilerTable.d.ts.map +1 -0
  56. package/dist/SharedQueryInput.d.ts +10 -0
  57. package/dist/SharedQueryInput.d.ts.map +1 -0
  58. package/dist/Toolbar.d.ts +31 -0
  59. package/dist/Toolbar.d.ts.map +1 -0
  60. package/dist/Tooltip/FlamegraphTooltip.d.ts +59 -0
  61. package/dist/Tooltip/FlamegraphTooltip.d.ts.map +1 -0
  62. package/dist/Tooltip/LeftClickIcon.d.ts +2 -0
  63. package/dist/Tooltip/LeftClickIcon.d.ts.map +1 -0
  64. package/dist/Tooltip/RightClickIcon.d.ts +2 -0
  65. package/dist/Tooltip/RightClickIcon.d.ts.map +1 -0
  66. package/dist/Tooltip/TableTooltip.d.ts +12 -0
  67. package/dist/Tooltip/TableTooltip.d.ts.map +1 -0
  68. package/dist/Tooltip/Tooltip.d.ts +29 -0
  69. package/dist/Tooltip/Tooltip.d.ts.map +1 -0
  70. package/dist/convert/convertJaegerTraceToProfile.d.ts +3 -0
  71. package/dist/convert/convertJaegerTraceToProfile.d.ts.map +1 -0
  72. package/dist/convert/diffTwoProfiles.d.ts +3 -0
  73. package/dist/convert/diffTwoProfiles.d.ts.map +1 -0
  74. package/dist/convert/flamebearersToTree.d.ts +11 -0
  75. package/dist/convert/flamebearersToTree.d.ts.map +1 -0
  76. package/dist/convert/sandwichViewProfiles.d.ts +14 -0
  77. package/dist/convert/sandwichViewProfiles.d.ts.map +1 -0
  78. package/dist/convert/subtract.d.ts +3 -0
  79. package/dist/convert/subtract.d.ts.map +1 -0
  80. package/dist/convert/testData.d.ts +50 -0
  81. package/dist/convert/testData.d.ts.map +1 -0
  82. package/dist/convert/toGraphviz.d.ts +3 -0
  83. package/dist/convert/toGraphviz.d.ts.map +1 -0
  84. package/dist/fitMode/fitMode.d.ts +42 -0
  85. package/dist/fitMode/fitMode.d.ts.map +1 -0
  86. package/dist/format/format.d.ts +42 -0
  87. package/dist/format/format.d.ts.map +1 -0
  88. package/dist/i18n.d.ts +55 -0
  89. package/dist/i18n.d.ts.map +1 -0
  90. package/dist/index.cjs.css +792 -0
  91. package/dist/index.cjs.js +5087 -0
  92. package/dist/index.d.ts +4 -0
  93. package/dist/index.d.ts.map +1 -0
  94. package/dist/index.esm.css +792 -0
  95. package/dist/index.esm.js +5079 -0
  96. package/dist/index.node.d.ts +9 -0
  97. package/dist/index.node.d.ts.map +1 -0
  98. package/dist/logo-v3-small-T5VXIMRR.svg +32 -0
  99. package/dist/models/decode.d.ts +3 -0
  100. package/dist/models/decode.d.ts.map +1 -0
  101. package/dist/models/flamebearer.d.ts +63 -0
  102. package/dist/models/flamebearer.d.ts.map +1 -0
  103. package/dist/models/groups.d.ts +37 -0
  104. package/dist/models/groups.d.ts.map +1 -0
  105. package/dist/models/index.d.ts +8 -0
  106. package/dist/models/index.d.ts.map +1 -0
  107. package/dist/models/profile.d.ts +152 -0
  108. package/dist/models/profile.d.ts.map +1 -0
  109. package/dist/models/spyName.d.ts +8 -0
  110. package/dist/models/spyName.d.ts.map +1 -0
  111. package/dist/models/trace.d.ts +357 -0
  112. package/dist/models/trace.d.ts.map +1 -0
  113. package/dist/models/units.d.ts +6 -0
  114. package/dist/models/units.d.ts.map +1 -0
  115. package/dist/search.d.ts +2 -0
  116. package/dist/search.d.ts.map +1 -0
  117. package/dist/shims/Box.d.ts +38 -0
  118. package/dist/shims/Box.d.ts.map +1 -0
  119. package/dist/shims/Button.d.ts +26 -0
  120. package/dist/shims/Button.d.ts.map +1 -0
  121. package/dist/shims/Dropdown.d.ts +30 -0
  122. package/dist/shims/Dropdown.d.ts.map +1 -0
  123. package/dist/shims/Input.d.ts +19 -0
  124. package/dist/shims/Input.d.ts.map +1 -0
  125. package/dist/shims/LoadingSpinner.d.ts +7 -0
  126. package/dist/shims/LoadingSpinner.d.ts.map +1 -0
  127. package/dist/shims/Menu.d.ts +4 -0
  128. package/dist/shims/Menu.d.ts.map +1 -0
  129. package/dist/shims/NoData.d.ts +2 -0
  130. package/dist/shims/NoData.d.ts.map +1 -0
  131. package/dist/shims/Table.d.ts +52 -0
  132. package/dist/shims/Table.d.ts.map +1 -0
  133. package/dist/shims/Tooltip.d.ts +9 -0
  134. package/dist/shims/Tooltip.d.ts.map +1 -0
  135. package/package.json +84 -0
  136. package/src/FlameGraph/FlameGraphComponent/CheckIcon.tsx +27 -0
  137. package/src/FlameGraph/FlameGraphComponent/ContextMenu.module.scss +10 -0
  138. package/src/FlameGraph/FlameGraphComponent/ContextMenu.spec.tsx +84 -0
  139. package/src/FlameGraph/FlameGraphComponent/ContextMenu.tsx +86 -0
  140. package/src/FlameGraph/FlameGraphComponent/ContextMenuHighlight.module.css +8 -0
  141. package/src/FlameGraph/FlameGraphComponent/ContextMenuHighlight.tsx +47 -0
  142. package/src/FlameGraph/FlameGraphComponent/DiffLegend.module.css +21 -0
  143. package/src/FlameGraph/FlameGraphComponent/DiffLegend.tsx +52 -0
  144. package/src/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.module.css +40 -0
  145. package/src/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.tsx +129 -0
  146. package/src/FlameGraph/FlameGraphComponent/Flamegraph.spec.ts +552 -0
  147. package/src/FlameGraph/FlameGraphComponent/Flamegraph.ts +446 -0
  148. package/src/FlameGraph/FlameGraphComponent/Flamegraph_render.spec.tsx +233 -0
  149. package/src/FlameGraph/FlameGraphComponent/Flamegraph_render.ts +478 -0
  150. package/src/FlameGraph/FlameGraphComponent/GraphVizPane.tsx +56 -0
  151. package/src/FlameGraph/FlameGraphComponent/GraphVizPanel.module.scss +55 -0
  152. package/src/FlameGraph/FlameGraphComponent/Header.module.css +27 -0
  153. package/src/FlameGraph/FlameGraphComponent/Header.tsx +71 -0
  154. package/src/FlameGraph/FlameGraphComponent/Highlight.module.css +7 -0
  155. package/src/FlameGraph/FlameGraphComponent/Highlight.spec.tsx +53 -0
  156. package/src/FlameGraph/FlameGraphComponent/Highlight.tsx +94 -0
  157. package/src/FlameGraph/FlameGraphComponent/LogoLink.module.scss +10 -0
  158. package/src/FlameGraph/FlameGraphComponent/LogoLink.tsx +101 -0
  159. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-collapses-small-blocks-into-one-1-snap.png +0 -0
  160. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-works-with-diff-mode-1-snap.png +0 -0
  161. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-works-with-highlighted-flamegraph-1-snap.png +0 -0
  162. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-works-with-normal-flamegraph-1-snap.png +0 -0
  163. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-works-with-selected-node-1-snap.png +0 -0
  164. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-focused-also-zooms-1-snap.png +0 -0
  165. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-focused-renders-a-focused-node-in-the-beginning-1-snap.png +0 -0
  166. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-focused-renders-a-focused-node-when-node-is-not-in-the-beginning-1-snap.png +0 -0
  167. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-focused-renders-a-focused-node-zoom-top-level-1-snap.png +0 -0
  168. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-complex-flamegraph-1-snap.png +0 -0
  169. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-double-diff-flamegraph-1-snap.png +0 -0
  170. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-highlighted-double-flamegraph-1-snap.png +0 -0
  171. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-highlighted-flamegraph-1-snap.png +0 -0
  172. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-simple-flamegraph-1-snap.png +0 -0
  173. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-simple-tree-1-snap.png +0 -0
  174. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-zoomed-flamegraph-1-snap.png +0 -0
  175. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-zoomed-with-fit-mode-tail-1-snap.png +0 -0
  176. package/src/FlameGraph/FlameGraphComponent/canvas.module.css +6 -0
  177. package/src/FlameGraph/FlameGraphComponent/color.spec.ts +308 -0
  178. package/src/FlameGraph/FlameGraphComponent/color.ts +167 -0
  179. package/src/FlameGraph/FlameGraphComponent/colorPalette.ts +58 -0
  180. package/src/FlameGraph/FlameGraphComponent/constants.ts +5 -0
  181. package/src/FlameGraph/FlameGraphComponent/index.spec.tsx +291 -0
  182. package/src/FlameGraph/FlameGraphComponent/index.tsx +411 -0
  183. package/src/FlameGraph/FlameGraphComponent/murmur3.ts +97 -0
  184. package/src/FlameGraph/FlameGraphComponent/styles.module.scss +10 -0
  185. package/src/FlameGraph/FlameGraphComponent/testData.ts +427 -0
  186. package/src/FlameGraph/FlameGraphComponent/utils.ts +31 -0
  187. package/src/FlameGraph/FlameGraphComponent/viewTypes.ts +6 -0
  188. package/src/FlameGraph/FlameGraphRenderer.tsx +603 -0
  189. package/src/FlameGraph/FlamegraphRenderer.module.scss +93 -0
  190. package/src/FlameGraph/decode.ts +78 -0
  191. package/src/FlameGraph/normalize.spec.ts +76 -0
  192. package/src/FlameGraph/normalize.ts +60 -0
  193. package/src/FlameGraph/testData.json +423 -0
  194. package/src/FlameGraph/uniqueness.spec.ts +16 -0
  195. package/src/FlameGraph/uniqueness.ts +84 -0
  196. package/src/FlamegraphRenderer.tsx +61 -0
  197. package/src/Icons.tsx +74 -0
  198. package/src/ProfilerTable.tsx +527 -0
  199. package/src/SharedQueryInput.module.scss +82 -0
  200. package/src/SharedQueryInput.tsx +127 -0
  201. package/src/Toolbar.module.scss +117 -0
  202. package/src/Toolbar.spec.tsx +217 -0
  203. package/src/Toolbar.tsx +471 -0
  204. package/src/Tooltip/FlamegraphTooltip.spec.tsx +81 -0
  205. package/src/Tooltip/FlamegraphTooltip.tsx +257 -0
  206. package/src/Tooltip/LeftClickIcon.tsx +18 -0
  207. package/src/Tooltip/RightClickIcon.tsx +18 -0
  208. package/src/Tooltip/TableTooltip.spec.tsx +44 -0
  209. package/src/Tooltip/TableTooltip.tsx +145 -0
  210. package/src/Tooltip/Tooltip.module.scss +71 -0
  211. package/src/Tooltip/Tooltip.spec.tsx +395 -0
  212. package/src/Tooltip/Tooltip.tsx +336 -0
  213. package/src/__snapshots__/Toolbar.spec.tsx.snap +297 -0
  214. package/src/convert/convertJaegerTraceToProfile.ts +97 -0
  215. package/src/convert/diffTwoProfiles.ts +81 -0
  216. package/src/convert/flamebearersToTree.ts +78 -0
  217. package/src/convert/sandwichViewProfiles.spec.ts +65 -0
  218. package/src/convert/sandwichViewProfiles.ts +191 -0
  219. package/src/convert/subtract.ts +87 -0
  220. package/src/convert/testData.ts +145 -0
  221. package/src/convert/toGraphviz.ts +485 -0
  222. package/src/fitMode/fitMode.spec.ts +93 -0
  223. package/src/fitMode/fitMode.ts +122 -0
  224. package/src/format/format.spec.ts +291 -0
  225. package/src/format/format.ts +303 -0
  226. package/src/globals.d.ts +13 -0
  227. package/src/i18n.tsx +293 -0
  228. package/src/index.node.ts +19 -0
  229. package/src/index.spec.tsx +383 -0
  230. package/src/index.tsx +10 -0
  231. package/src/logo-v3-small.svg +32 -0
  232. package/src/models/decode.ts +45 -0
  233. package/src/models/flamebearer.ts +86 -0
  234. package/src/models/groups.ts +14 -0
  235. package/src/models/index.ts +7 -0
  236. package/src/models/profile.spec.ts +32 -0
  237. package/src/models/profile.ts +48 -0
  238. package/src/models/spyName.spec.ts +18 -0
  239. package/src/models/spyName.ts +32 -0
  240. package/src/models/trace.ts +45 -0
  241. package/src/models/units.spec.ts +21 -0
  242. package/src/models/units.ts +24 -0
  243. package/src/sass/_common.scss +206 -0
  244. package/src/sass/_css-variables.scss +201 -0
  245. package/src/sass/_mixins.scss +15 -0
  246. package/src/sass/_sanitize.scss +407 -0
  247. package/src/sass/_variables.scss +53 -0
  248. package/src/sass/flamegraph.scss +18 -0
  249. package/src/search.spec.ts +11 -0
  250. package/src/search.ts +4 -0
  251. package/src/shameful-any.d.ts +2 -0
  252. package/src/shims/Box.module.scss +57 -0
  253. package/src/shims/Box.tsx +105 -0
  254. package/src/shims/Button.module.scss +129 -0
  255. package/src/shims/Button.tsx +128 -0
  256. package/src/shims/Dropdown.module.scss +63 -0
  257. package/src/shims/Dropdown.tsx +96 -0
  258. package/src/shims/Input.module.scss +15 -0
  259. package/src/shims/Input.tsx +55 -0
  260. package/src/shims/LoadingSpinner.tsx +19 -0
  261. package/src/shims/Menu.tsx +9 -0
  262. package/src/shims/NoData.module.scss +6 -0
  263. package/src/shims/NoData.tsx +11 -0
  264. package/src/shims/Table.module.scss +82 -0
  265. package/src/shims/Table.spec.tsx +121 -0
  266. package/src/shims/Table.tsx +252 -0
  267. package/src/shims/Tooltip.tsx +51 -0
@@ -0,0 +1,383 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { FlamegraphRenderer } from './index';
4
+
5
+ const RawProfile = {
6
+ version: 1,
7
+ flamebearer: {
8
+ names: [
9
+ 'total',
10
+ 'runtime.mcall',
11
+ 'runtime.park_m',
12
+ 'runtime.schedule',
13
+ 'runtime.resetspinning',
14
+ 'runtime.wakep',
15
+ 'runtime.startm',
16
+ 'runtime.notewakeup',
17
+ 'runtime.futexwakeup',
18
+ 'runtime.futex',
19
+ 'runtime.findrunnable',
20
+ 'runtime.write',
21
+ 'runtime.write1',
22
+ 'runtime.stopm',
23
+ 'runtime.mput',
24
+ 'runtime.mPark',
25
+ 'runtime.notesleep',
26
+ 'runtime.futexsleep',
27
+ 'runtime.stealWork',
28
+ 'runtime.checkTimers',
29
+ 'runtime.runtimer',
30
+ 'runtime.runOneTimer',
31
+ 'time.sendTime',
32
+ 'runtime.selectnbsend',
33
+ 'runtime.chansend',
34
+ 'runtime.adjusttimers',
35
+ 'runtime.netpoll',
36
+ 'runtime.read',
37
+ 'runtime.epollwait',
38
+ 'runtime.siftdownTimer',
39
+ 'runtime.gosched_m',
40
+ 'runtime.unlockWithRank',
41
+ 'runtime.unlock2',
42
+ 'runtime.lockWithRank',
43
+ 'runtime.lock2',
44
+ 'runtime.procyield',
45
+ 'runtime.goschedImpl',
46
+ 'runtime.nanotime',
47
+ 'runtime.globrunqget',
48
+ 'runtime.(*gQueue).pop',
49
+ 'runtime.execute',
50
+ 'runtime.casgstatus',
51
+ 'runtime.gcBgMarkWorker',
52
+ 'runtime.systemstack',
53
+ 'runtime.gcBgMarkWorker.func2',
54
+ 'runtime.gcDrain',
55
+ 'runtime.spanOfUnchecked',
56
+ 'runtime.scanobject',
57
+ 'runtime.spanOf',
58
+ 'runtime.pageIndexOf',
59
+ 'runtime.markBits.isMarked',
60
+ 'runtime.greyobject',
61
+ 'runtime.findObject',
62
+ 'runtime.arenaIndex',
63
+ 'runtime.(*mspan).divideByElemSize',
64
+ 'runtime.(*gcWork).putFast',
65
+ 'runtime.heapBitsForAddr',
66
+ 'runtime.heapBits.next',
67
+ 'runtime.heapBits.bits',
68
+ 'runtime.gcFlushBgCredit',
69
+ 'runtime.bgsweep',
70
+ 'runtime.sweepone',
71
+ 'runtime.(*sweepLocked).sweep',
72
+ 'runtime.(*gcBitsArena).tryAlloc',
73
+ 'runtime.(*sweepLocker).dispose',
74
+ 'runtime.(*sweepLocker).blockCompletion',
75
+ 'net/http.(*conn).serve',
76
+ 'net/http.serverHandler.ServeHTTP',
77
+ 'net/http.HandlerFunc.ServeHTTP',
78
+ 'github.com/klauspost/compress/gzhttp.NewWrapper.func1.1',
79
+ 'github.com/gorilla/mux.(*Router).ServeHTTP',
80
+ 'github.com/pyroscope-io/pyroscope/pkg/server.(*Controller).drainMiddleware.func1',
81
+ 'github.com/pyroscope-io/pyroscope/pkg/server.ingestHandler.ServeHTTP',
82
+ 'github.com/pyroscope-io/pyroscope/pkg/structs/transporttrie.IterateRaw',
83
+ 'io.LimitReader',
84
+ 'runtime.newobject',
85
+ 'runtime.nextFreeFast',
86
+ 'io.Copy',
87
+ 'io.copyBuffer',
88
+ 'bytes.(*Buffer).ReadFrom',
89
+ 'io.(*LimitedReader).Read',
90
+ 'net/http.(*response).finishRequest',
91
+ 'bufio.(*Writer).Flush',
92
+ 'net/http.checkConnErrorWriter.Write',
93
+ 'net.(*conn).Write',
94
+ 'net.(*netFD).Write',
95
+ 'syscall.Write',
96
+ 'syscall.write',
97
+ 'syscall.Syscall',
98
+ 'github.com/pyroscope-io/pyroscope/pkg/agent/upstream/direct.(*Direct).uploadLoop',
99
+ 'github.com/pyroscope-io/pyroscope/pkg/agent/upstream/direct.(*Direct).safeUpload',
100
+ 'github.com/pyroscope-io/pyroscope/pkg/agent/upstream/direct.(*Direct).uploadProfile',
101
+ 'github.com/pyroscope-io/pyroscope/pkg/structs/transporttrie.(*Trie).Iterate',
102
+ 'runtime.growslice',
103
+ 'runtime.mallocgc',
104
+ 'github.com/pyroscope-io/pyroscope/pkg/agent.(*ProfileSession).takeSnapshots',
105
+ 'runtime.selectgo',
106
+ 'runtime.gopark',
107
+ 'runtime.(*mcache).nextFree',
108
+ 'runtime.(*mcache).refill',
109
+ 'runtime.(*mcentral).cacheSpan',
110
+ 'runtime.mapiterinit',
111
+ 'runtime.makemap_small',
112
+ 'github.com/pyroscope-io/pyroscope/pkg/agent/gospy.(*GoSpy).Snapshot',
113
+ 'runtime/pprof.writeHeap',
114
+ 'runtime/pprof.writeHeapInternal',
115
+ 'runtime/pprof.writeHeapProto',
116
+ 'runtime/pprof.(*profileBuilder).pbSample',
117
+ 'runtime/pprof.(*profileBuilder).flush',
118
+ 'compress/flate.(*Writer).Write',
119
+ 'compress/flate.(*compressor).write',
120
+ 'compress/flate.(*compressor).encSpeed',
121
+ 'compress/flate.(*deflateFast).encode',
122
+ 'compress/flate.emitLiteral',
123
+ 'runtime/pprof.(*profileBuilder).appendLocsForStack',
124
+ 'runtime/pprof.allFrames',
125
+ 'runtime.(*Frames).Next',
126
+ 'runtime.funcline1',
127
+ 'runtime.pcvalue',
128
+ 'runtime.step',
129
+ 'runtime.GC',
130
+ 'runtime.(*spanSet).push',
131
+ 'runtime.(*headTailIndex).incTail',
132
+ 'runtime.(*mheap).freeSpan',
133
+ 'runtime.(*mheap).nextSpanForSweep',
134
+ 'runtime.(*spanSet).pop',
135
+ 'github.com/pyroscope-io/pyroscope/pkg/storage/tree.(*Profile).Get',
136
+ 'github.com/pyroscope-io/pyroscope/pkg/storage/tree.FindFunctionName',
137
+ 'runtime.asyncPreempt',
138
+ 'github.com/pyroscope-io/pyroscope/pkg/storage/tree.FindLocation',
139
+ 'sort.Search',
140
+ 'github.com/pyroscope-io/pyroscope/pkg/storage/tree.FindFunction',
141
+ 'github.com/pyroscope-io/pyroscope/pkg/storage/tree.FindFunction.func1',
142
+ 'github.com/pyroscope-io/pyroscope/pkg/agent/gospy.(*GoSpy).Snapshot.func3',
143
+ 'github.com/pyroscope-io/pyroscope/pkg/agent.(*ProfileSession).takeSnapshots.func1',
144
+ 'github.com/pyroscope-io/pyroscope/pkg/structs/transporttrie.(*Trie).Insert',
145
+ 'github.com/pyroscope-io/pyroscope/pkg/structs/transporttrie.(*trieNode).findNodeAt',
146
+ 'runtime.(*mcentral).grow',
147
+ 'runtime.(*mheap).alloc',
148
+ 'runtime.(*mheap).alloc.func1',
149
+ 'runtime.(*mheap).allocSpan',
150
+ 'runtime.(*mheap).allocMSpanLocked',
151
+ 'runtime.(*fixalloc).alloc',
152
+ 'github.com/pyroscope-io/pyroscope/pkg/agent/gospy.getHeapProfile',
153
+ 'github.com/pyroscope-io/pyroscope/pkg/convert.ParsePprof',
154
+ 'google.golang.org/protobuf/proto.Unmarshal',
155
+ 'google.golang.org/protobuf/proto.UnmarshalOptions.unmarshal',
156
+ 'google.golang.org/protobuf/internal/impl.(*MessageInfo).unmarshal',
157
+ 'google.golang.org/protobuf/internal/impl.(*MessageInfo).unmarshalPointer',
158
+ 'google.golang.org/protobuf/internal/impl.consumeMessageSliceInfo',
159
+ 'github.com/pyroscope-io/pyroscope/pkg/agent.(*ProfileSession).isDueForReset',
160
+ 'time.Time.Truncate',
161
+ 'github.com/dgraph-io/badger/v2.(*levelsController).runCompactor',
162
+ 'github.com/dgraph-io/badger/v2.(*levelsController).pickCompactLevels',
163
+ 'sort.Slice',
164
+ 'github.com/dgraph-io/badger/v2.(*DB).doWrites.func1',
165
+ 'github.com/dgraph-io/badger/v2.(*DB).writeRequests',
166
+ 'github.com/dgraph-io/badger/v2.(*valueLog).write',
167
+ 'github.com/dgraph-io/badger/v2.(*logFile).encodeEntry',
168
+ 'hash/crc32.New',
169
+ 'runtime.heapBitsSetType',
170
+ 'runtime.newstack',
171
+ 'runtime.copystack',
172
+ 'runtime.memmove',
173
+ ],
174
+ levels: [
175
+ [0, 236, 0, 0],
176
+ [
177
+ 0, 1, 0, 155, 0, 1, 0, 152, 0, 29, 0, 95, 0, 1, 0, 89, 0, 3, 0, 66, 0,
178
+ 11, 0, 60, 0, 154, 0, 42, 0, 36, 0, 1,
179
+ ],
180
+ [
181
+ 0, 1, 0, 156, 0, 1, 0, 153, 0, 1, 0, 150, 0, 23, 0, 103, 0, 1, 0, 102,
182
+ 0, 1, 1, 101, 0, 1, 0, 75, 0, 2, 1, 96, 0, 1, 0, 90, 0, 1, 0, 81, 0, 2,
183
+ 0, 67, 0, 2, 2, 65, 0, 3, 3, 64, 0, 6, 3, 61, 0, 154, 0, 43, 0, 19, 0,
184
+ 30, 0, 17, 0, 2,
185
+ ],
186
+ [
187
+ 0, 1, 0, 157, 0, 1, 1, 154, 0, 1, 1, 151, 0, 1, 0, 143, 0, 12, 0, 126,
188
+ 0, 7, 0, 120, 0, 3, 0, 104, 0, 1, 0, 75, 1, 1, 0, 94, 1, 1, 1, 97, 0, 1,
189
+ 0, 91, 0, 1, 0, 82, 0, 2, 0, 68, 8, 3, 2, 62, 0, 154, 0, 44, 0, 15, 0,
190
+ 36, 0, 2, 0, 33, 0, 2, 0, 31, 0, 17, 0, 3,
191
+ ],
192
+ [
193
+ 0, 1, 0, 158, 2, 1, 0, 144, 0, 7, 0, 133, 0, 5, 0, 127, 0, 7, 1, 61, 0,
194
+ 3, 0, 105, 0, 1, 1, 94, 1, 1, 0, 98, 2, 1, 0, 92, 0, 1, 0, 83, 0, 2, 0,
195
+ 69, 10, 1, 1, 63, 0, 154, 14, 45, 0, 1, 1, 41, 0, 14, 0, 3, 0, 2, 0, 34,
196
+ 0, 2, 2, 32, 0, 16, 1, 10, 0, 1, 0, 4,
197
+ ],
198
+ [
199
+ 0, 1, 0, 159, 2, 1, 0, 145, 0, 7, 0, 134, 0, 3, 0, 131, 0, 1, 0, 129, 0,
200
+ 1, 1, 128, 1, 1, 0, 124, 0, 5, 0, 62, 0, 3, 0, 106, 2, 1, 0, 99, 2, 1,
201
+ 0, 93, 0, 1, 0, 84, 0, 2, 0, 70, 25, 1, 1, 59, 0, 7, 7, 58, 0, 5, 5, 57,
202
+ 0, 6, 6, 56, 0, 119, 61, 47, 0, 2, 2, 46, 1, 2, 1, 40, 0, 4, 0, 10, 0,
203
+ 3, 0, 33, 0, 2, 2, 37, 0, 3, 0, 31, 0, 2, 2, 35, 3, 1, 0, 19, 0, 5, 0,
204
+ 26, 0, 2, 0, 18, 0, 6, 0, 13, 0, 1, 0, 11, 0, 1, 0, 5,
205
+ ],
206
+ [
207
+ 0, 1, 0, 75, 2, 1, 0, 146, 0, 7, 0, 135, 0, 3, 2, 130, 0, 1, 1, 130, 2,
208
+ 1, 1, 125, 0, 1, 0, 123, 0, 4, 3, 121, 0, 1, 0, 114, 0, 2, 0, 107, 2, 1,
209
+ 1, 100, 2, 1, 1, 94, 0, 1, 0, 85, 0, 2, 0, 68, 105, 2, 2, 55, 0, 3, 3,
210
+ 54, 0, 1, 1, 53, 0, 17, 17, 52, 0, 3, 3, 51, 0, 5, 5, 50, 0, 11, 11, 49,
211
+ 0, 16, 16, 48, 4, 1, 1, 41, 0, 1, 1, 39, 0, 1, 1, 38, 0, 1, 1, 37, 0, 1,
212
+ 0, 26, 0, 3, 0, 34, 2, 3, 3, 32, 5, 1, 0, 20, 0, 4, 4, 28, 0, 1, 1, 27,
213
+ 0, 2, 0, 19, 0, 5, 0, 15, 0, 1, 1, 14, 0, 1, 1, 12, 0, 1, 0, 6,
214
+ ],
215
+ [
216
+ 0, 1, 0, 94, 2, 1, 0, 147, 0, 7, 6, 136, 2, 1, 1, 132, 4, 1, 0, 43, 3,
217
+ 1, 1, 122, 0, 1, 0, 115, 0, 2, 0, 108, 6, 1, 0, 86, 0, 2, 0, 71, 171, 1,
218
+ 1, 28, 0, 3, 3, 35, 10, 1, 0, 21, 5, 1, 1, 25, 0, 1, 0, 20, 0, 5, 0, 16,
219
+ 2, 1, 0, 7,
220
+ ],
221
+ [
222
+ 0, 1, 0, 160, 2, 1, 0, 148, 6, 1, 0, 94, 7, 1, 0, 33, 4, 1, 0, 116, 0,
223
+ 2, 0, 109, 6, 1, 0, 87, 0, 2, 0, 72, 185, 1, 1, 29, 6, 1, 0, 21, 0, 5,
224
+ 0, 17, 2, 1, 0, 8,
225
+ ],
226
+ [
227
+ 0, 1, 0, 161, 2, 1, 0, 149, 6, 1, 0, 98, 7, 1, 1, 34, 4, 1, 0, 117, 0,
228
+ 2, 0, 110, 6, 1, 1, 88, 0, 2, 0, 73, 192, 1, 0, 22, 0, 5, 5, 9, 2, 1, 1,
229
+ 9,
230
+ ],
231
+ [
232
+ 0, 1, 0, 162, 2, 1, 1, 148, 6, 1, 0, 99, 12, 1, 0, 118, 0, 2, 0, 111, 7,
233
+ 1, 0, 77, 0, 1, 0, 74, 192, 1, 0, 23,
234
+ ],
235
+ [
236
+ 0, 1, 1, 163, 9, 1, 0, 100, 12, 1, 1, 119, 0, 2, 1, 112, 7, 1, 0, 78, 0,
237
+ 1, 0, 75, 192, 1, 1, 24,
238
+ ],
239
+ [10, 1, 0, 137, 14, 1, 1, 113, 7, 1, 0, 79, 0, 1, 1, 76],
240
+ [10, 1, 0, 138, 22, 1, 1, 80],
241
+ [10, 1, 0, 43],
242
+ [10, 1, 0, 139],
243
+ [10, 1, 0, 140],
244
+ [10, 1, 0, 141],
245
+ [10, 1, 1, 142],
246
+ ],
247
+ numTicks: 236,
248
+ maxSelf: 61,
249
+ },
250
+ timeline: {
251
+ startTime: 1646760440,
252
+ samples: [237],
253
+ durationDelta: 10,
254
+ watermarks: {},
255
+ },
256
+ metadata: {
257
+ format: 'single' as const,
258
+ spyName: 'gospy' as const,
259
+ sampleRate: 100,
260
+ units: 'samples' as const,
261
+ name: 'pyroscope.server.cpu 2022-03-08T17:27:23Z',
262
+ appName: 'pyroscope.server.cpu',
263
+ startTime: 1646760443,
264
+ endTime: 1646760446,
265
+ query: 'pyroscope.server.cpu{}',
266
+ maxNodes: 1024,
267
+ },
268
+ };
269
+
270
+ const SimpleTree = {
271
+ topLevel: 0,
272
+ rangeMin: 0,
273
+ format: 'single' as const,
274
+ numTicks: 988,
275
+ sampleRate: 100,
276
+ names: [
277
+ 'total',
278
+ 'runtime.main',
279
+ 'main.slowFunction',
280
+ 'main.work',
281
+ 'main.main',
282
+ 'main.fastFunction',
283
+ ],
284
+ levels: [
285
+ [0, 988, 0, 0],
286
+ [0, 988, 0, 1],
287
+ [0, 214, 0, 5, 214, 3, 2, 4, 217, 771, 0, 2],
288
+ [0, 214, 214, 3, 216, 1, 1, 5, 217, 771, 771, 3],
289
+ ],
290
+
291
+ rangeMax: 1,
292
+ units: 'samples',
293
+ fitMode: 'HEAD',
294
+
295
+ spyName: 'gospy',
296
+ };
297
+
298
+ // describe.skip('Pyroscope Library', () => {
299
+ // it('should not be possible to override the pyroscope logo using props', () => {
300
+ // render(
301
+ // <FlamegraphRenderer
302
+ // flamebearer={SimpleTree}
303
+ // display="flamegraph"
304
+ // viewType="single"
305
+ // showPyroscopeLogo={false}
306
+ // />
307
+ // );
308
+ //
309
+ // expect(
310
+ // screen.getByRole('link', { name: /pyroscope/i })
311
+ // ).toBeInTheDocument();
312
+ // });
313
+ // });
314
+ //
315
+ //
316
+ // TODO a test saying going over rendering an empty flamegraph
317
+ describe.only('positions', () => {
318
+ beforeAll(() => {
319
+ window.HTMLElement.prototype.getBoundingClientRect = function () {
320
+ return {
321
+ x: 0,
322
+ y: 0,
323
+ bottom: 0,
324
+ right: 0,
325
+ toJSON: () => {},
326
+ height: 0,
327
+ top: 0,
328
+ left: 0,
329
+ width: 900,
330
+ };
331
+ };
332
+ });
333
+
334
+ describe('Allow changing visualization mode', () => {
335
+ it('should allow changing view when "onlyDisplay" is not set', () => {
336
+ const { getByTestId, queryByRole } = render(
337
+ <FlamegraphRenderer profile={RawProfile} />
338
+ );
339
+
340
+ expect(getByTestId('table-ui')).toBeInTheDocument();
341
+ expect(getByTestId('flamegraph-view')).toBeInTheDocument();
342
+ expect(getByTestId('flamegraph')).toBeInTheDocument();
343
+ expect(getByTestId('both')).toBeInTheDocument();
344
+ expect(getByTestId('table')).toBeInTheDocument();
345
+ });
346
+
347
+ it('should restrict changing view when "onlyDisplay" is set', () => {
348
+ const { getByTestId, queryByRole } = render(
349
+ <FlamegraphRenderer profile={RawProfile} onlyDisplay="both" />
350
+ );
351
+
352
+ expect(getByTestId('table-ui')).toBeInTheDocument();
353
+ expect(getByTestId('flamegraph-view')).toBeInTheDocument();
354
+ expect(queryByRole('combobox', { name: 'view' })).not.toBeInTheDocument();
355
+ });
356
+ });
357
+
358
+ it('should display only the flamegraph when specified', () => {
359
+ const { getByTestId, queryByTestId } = render(
360
+ <FlamegraphRenderer profile={RawProfile} onlyDisplay="flamegraph" />
361
+ );
362
+
363
+ expect(queryByTestId('table-ui')).not.toBeInTheDocument();
364
+ expect(getByTestId('flamegraph-view')).toBeInTheDocument();
365
+ });
366
+
367
+ it('should display only the table when specified', () => {
368
+ const { getByTestId, queryByTestId } = render(
369
+ <FlamegraphRenderer profile={RawProfile} onlyDisplay="table" />
370
+ );
371
+
372
+ expect(getByTestId('table-ui')).toBeInTheDocument();
373
+ expect(queryByTestId('flamegraph-view')).not.toBeInTheDocument();
374
+ });
375
+ });
376
+
377
+ it('should work', () => {
378
+ render(<FlamegraphRenderer flamebearer={SimpleTree as any} />);
379
+ });
380
+
381
+ it('should work with raw profile from /render endpoint', () => {
382
+ render(<FlamegraphRenderer profile={RawProfile} />);
383
+ });
package/src/index.tsx ADDED
@@ -0,0 +1,10 @@
1
+ // src/index.tsx
2
+
3
+ // 主渲染组件
4
+ export { default as FlamegraphRenderer } from './FlameGraph/FlameGraphRenderer';
5
+
6
+ // 容器组件
7
+ export { default as Box } from './shims/Box';
8
+
9
+ // i18n(包含 flamegraphZhCNMessages 等)
10
+ export * from './i18n';
@@ -0,0 +1,32 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Artboard@2x</title>
4
+ <defs>
5
+ <radialGradient cx="49.4236252%" cy="92.6627823%" fx="49.4236252%" fy="92.6627823%" r="195.066755%" gradientTransform="translate(0.494236,0.926628),scale(1.000000,0.735610),rotate(-90.000000),translate(-0.494236,-0.926628)" id="radialGradient-1">
6
+ <stop stop-color="#FFB90C" offset="0%"></stop>
7
+ <stop stop-color="#F9243A" offset="38.390924%"></stop>
8
+ <stop stop-color="#F9243A" offset="50.5405%"></stop>
9
+ <stop stop-color="#B51424" offset="73.98091%"></stop>
10
+ <stop stop-color="#B51424" offset="100%"></stop>
11
+ </radialGradient>
12
+ </defs>
13
+ <g id="Artboard" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
14
+ <g id="fire-part" transform="translate(148.516736, 0.000000)" fill-rule="nonzero">
15
+ <g id="whole-thing" transform="translate(363.983264, 495.000000) scale(-1, 1) rotate(-180.000000) translate(-363.983264, -495.000000) translate(0.483264, 0.000000)">
16
+ <g id="g70" transform="translate(-0.000091, 0.685815)" fill="url(#radialGradient-1)">
17
+ <path d="M65.3646667,571.739321 L65.4492471,571.698868 C19.5139147,505.999969 -5.32464048,424.477859 1.04305801,336.877516 L1.04305801,336.877516 C14.0321963,158.179446 159.192462,13.7596653 338.059844,1.5917266 L338.059844,1.5917266 C419.418369,-3.93888015 495.500283,17.3823334 558.456522,57.4611191 L558.456522,57.4611191 L481.301947,162.097965 C437.516468,136.521928 399.367671,129.590556 363.486536,130.155994 L363.486536,130.155994 C234.497143,130.155994 129.556988,235.032238 129.556988,363.946998 L129.556988,363.946998 C129.556988,492.865683 234.497143,597.738003 363.486536,597.738003 L363.486536,597.738003 C492.483783,597.738003 597.427864,492.865683 597.427864,363.946998 L597.427864,363.946998 C597.41276,304.634864 581.39383,255.677522 530.630465,199.668053 L607.770843,95.1329436 C680.936847,161.576603 726.932594,257.364176 726.932594,363.946998 L726.932594,363.946998 C726.932594,458.031616 691.13483,543.75602 632.416071,608.271816 L632.416071,608.271816 L632.416071,608.275741 L533.597728,748.122808 L428.601388,617.203806 L434.703262,646.563419 C459.453008,765.59222 433.664131,889.543925 363.49439,988.853335 L363.49439,988.853335 L65.3646667,571.723019 L65.3646667,571.739321 Z" id="path84"></path>
18
+ </g>
19
+ <g id="blue" transform="translate(191.447039, 191.331780)">
20
+ <g id="g88" transform="translate(-0.000063, 0.685930)">
21
+ <g id="g94" transform="translate(0.177296, 0.699054)" fill="#3EC1D3">
22
+ <path d="M171.862466,343.697728 C77.0961324,343.697728 -0.00497405932,266.647602 -0.00497405932,171.934957 C-0.00497405932,77.2182874 77.0961324,0.168162396 171.862466,0.168162396 C266.632828,0.168162396 343.741988,77.2182874 343.741988,171.934957 C343.741988,266.647602 266.632828,343.697728 171.862466,343.697728" id="path96"></path>
23
+ </g>
24
+ <g id="g98" transform="translate(29.362379, 172.629585)" fill="#FFFFFF">
25
+ <path d="M22.8397982,0 L0.671669409,0 C0.671669409,78.2496309 64.380874,141.920035 142.678189,141.920035 L142.678189,119.765407 C76.6007327,119.765407 22.8397982,66.0372141 22.8397982,0" id="path100"></path>
26
+ </g>
27
+ </g>
28
+ </g>
29
+ </g>
30
+ </g>
31
+ </g>
32
+ </svg>
@@ -0,0 +1,45 @@
1
+ import { Profile } from './profile';
2
+
3
+ // TODO: ideally this should be moved into the FlamegraphRenderer component
4
+ // but since it will require too many changes for now
5
+ function deltaDiffWrapper(
6
+ format: Profile['metadata']['format'],
7
+ levels: Profile['flamebearer']['levels']
8
+ ) {
9
+ const mutableLevels = [...levels];
10
+
11
+ function deltaDiff(
12
+ lvls: Profile['flamebearer']['levels'],
13
+ start: number,
14
+ step: number
15
+ ) {
16
+ // eslint-disable-next-line no-restricted-syntax
17
+ for (const level of lvls) {
18
+ let prev = 0;
19
+ for (let i = start; i < level.length; i += step) {
20
+ level[i] += prev;
21
+ prev = level[i] + level[i + 1];
22
+ }
23
+ }
24
+ }
25
+
26
+ if (format === 'double') {
27
+ deltaDiff(mutableLevels, 0, 7);
28
+ deltaDiff(mutableLevels, 3, 7);
29
+ } else {
30
+ deltaDiff(mutableLevels, 0, 4);
31
+ }
32
+
33
+ return mutableLevels;
34
+ }
35
+
36
+ // eslint-disable-next-line import/prefer-default-export
37
+ export function decodeFlamebearer(fb: Profile): Profile {
38
+ // TODO: make this immutable
39
+ // eslint-disable-next-line no-param-reassign
40
+ fb.flamebearer.levels = deltaDiffWrapper(
41
+ fb.metadata.format,
42
+ fb.flamebearer.levels
43
+ );
44
+ return fb;
45
+ }
@@ -0,0 +1,86 @@
1
+ import { SpyName } from './spyName';
2
+ import { Units } from './units';
3
+ /**
4
+ * @deprecated one should use the Profile model
5
+ */
6
+ export type Flamebearer = {
7
+ /**
8
+ * List of names
9
+ */
10
+ names: string[];
11
+ /**
12
+ * List of level
13
+ *
14
+ * This is NOT the same as in the flamebearer
15
+ * that we receive from the server.
16
+ * As in there are some transformations required
17
+ * (see deltaDiffWrapper)
18
+ */
19
+ levels: number[][];
20
+ numTicks: number;
21
+ maxSelf: number;
22
+
23
+ /**
24
+ * Sample Rate, used in text information
25
+ */
26
+ sampleRate: number;
27
+ units: Units;
28
+
29
+ spyName: SpyName;
30
+ // format: 'double' | 'single';
31
+ // leftTicks?: number;
32
+ // rightTicks?: number;
33
+ } & addTicks;
34
+
35
+ export type addTicks =
36
+ | { format: 'double'; leftTicks: number; rightTicks: number }
37
+ | { format: 'single' };
38
+
39
+ export const singleFF = {
40
+ format: 'single' as const,
41
+ jStep: 4,
42
+ jName: 3,
43
+ getBarOffset: (level: number[], j: number) => level[j],
44
+ getBarTotal: (level: number[], j: number) => level[j + 1],
45
+ getBarTotalDiff: (level: number[], j: number) => 0,
46
+ getBarSelf: (level: number[], j: number) => level[j + 2],
47
+ getBarSelfDiff: (level: number[], j: number) => 0,
48
+ getBarName: (level: number[], j: number) => level[j + 3],
49
+ };
50
+
51
+ export const doubleFF = {
52
+ format: 'double' as const,
53
+ jStep: 7,
54
+ jName: 6,
55
+ getBarOffset: (level: number[], j: number) => level[j] + level[j + 3],
56
+ getBarTotal: (level: number[], j: number) => level[j + 4] + level[j + 1],
57
+ getBarTotalLeft: (level: number[], j: number) => level[j + 1],
58
+ getBarTotalRght: (level: number[], j: number) => level[j + 4],
59
+ getBarTotalDiff: (level: number[], j: number) => {
60
+ return level[j + 4] - level[j + 1];
61
+ },
62
+ getBarSelf: (level: number[], j: number) => level[j + 5] + level[j + 2],
63
+ getBarSelfLeft: (level: number[], j: number) => level[j + 2],
64
+ getBarSelfRght: (level: number[], j: number) => level[j + 5],
65
+ getBarSelfDiff: (level: number[], j: number) => level[j + 5] - level[j + 2],
66
+ getBarName: (level: number[], j: number) => level[j + 6],
67
+ };
68
+
69
+ // createFF returns an accesser for flamebearer
70
+ // TODO: rename it?
71
+ export function createFF(
72
+ viewType: 'single' | 'double'
73
+ ): typeof singleFF | typeof doubleFF {
74
+ switch (viewType) {
75
+ case 'single': {
76
+ return singleFF;
77
+ }
78
+ case 'double': {
79
+ return doubleFF;
80
+ }
81
+
82
+ default: {
83
+ throw new Error(`Unsupported type: '${viewType}'`);
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,14 @@
1
+ import { z } from 'zod';
2
+
3
+ const GroupSchema = z.object({
4
+ watermark: z.object({}).optional(),
5
+ // timeline data
6
+ startTime: z.number(),
7
+ samples: z.array(z.number()),
8
+ durationDelta: z.number(),
9
+ });
10
+
11
+ export const GroupsSchema = z.record(z.string(), GroupSchema);
12
+
13
+ export type Groups = z.infer<typeof GroupsSchema>;
14
+ export type Group = z.infer<typeof GroupSchema>;
@@ -0,0 +1,7 @@
1
+ export * from './profile';
2
+ export * from './flamebearer';
3
+ export * from './trace';
4
+ export * from './groups';
5
+ export * from './decode';
6
+ export * from './spyName';
7
+ export * from './units';
@@ -0,0 +1,32 @@
1
+ import { MetadataSchema, FlamebearerSchema } from './profile';
2
+
3
+ describe('Profile', () => {
4
+ describe('FlamebearerSchema', () => {
5
+ describe('Names', () => {
6
+ it('defaults to "unknown" when name is empty', () => {
7
+ const fb = {
8
+ names: ['', ''],
9
+ levels: [],
10
+ numTicks: 100,
11
+ maxSelf: 100,
12
+ };
13
+ expect(FlamebearerSchema.parse(fb)).toStrictEqual({
14
+ names: ['unknown', 'unknown'],
15
+ levels: [],
16
+ numTicks: 100,
17
+ maxSelf: 100,
18
+ });
19
+ });
20
+
21
+ it('uses correct name when not empty', () => {
22
+ const fb = {
23
+ names: ['myname', 'myname2'],
24
+ levels: [],
25
+ numTicks: 100,
26
+ maxSelf: 100,
27
+ };
28
+ expect(FlamebearerSchema.parse(fb)).toStrictEqual(fb);
29
+ });
30
+ });
31
+ });
32
+ });
@@ -0,0 +1,48 @@
1
+ import { z } from 'zod';
2
+ import { SpyNameSchema } from './spyName';
3
+ import { UnitsSchema } from './units';
4
+
5
+ export const FlamebearerSchema = z.object({
6
+ names: z.array(
7
+ z.preprocess((n) => {
8
+ if (!n) {
9
+ return 'unknown';
10
+ }
11
+
12
+ return n;
13
+ }, z.string().min(1))
14
+ ),
15
+ levels: z.array(z.array(z.number())),
16
+ numTicks: z.number(),
17
+ maxSelf: z.number(),
18
+ });
19
+
20
+ export const MetadataSchema = z.object({
21
+ // Optional fields since adhoc may be missing them
22
+ // they are added on /render and /render-diff response
23
+ // https://github.com/pyroscope-io/pyroscope/blob/main/pkg/server/render.go#L114-L131
24
+ appName: z.string().optional(),
25
+ name: z.string().optional(),
26
+ startTime: z.number().optional(),
27
+ endTime: z.number().optional(),
28
+ query: z.string().optional(),
29
+ maxNodes: z.number().optional(),
30
+
31
+ format: z.enum(['single', 'double']),
32
+ sampleRate: z.number(),
33
+ spyName: SpyNameSchema,
34
+
35
+ units: UnitsSchema,
36
+ });
37
+
38
+ export const FlamebearerProfileSchema = z.object({
39
+ version: z.number().min(1).max(1).default(1),
40
+ flamebearer: FlamebearerSchema,
41
+ metadata: MetadataSchema,
42
+
43
+ // TODO make thee dependent on format === 'double'
44
+ leftTicks: z.number().optional(),
45
+ rightTicks: z.number().optional(),
46
+ });
47
+
48
+ export type Profile = z.infer<typeof FlamebearerProfileSchema>;
@@ -0,0 +1,18 @@
1
+ import { SpyNameSchema, AllSpyNames } from './spyName';
2
+
3
+ describe('SpyName', () => {
4
+ it('defaults to "unknown" when absent', () => {
5
+ expect(SpyNameSchema.parse('')).toBe('unknown');
6
+ });
7
+
8
+ it('defaults to "unknown" when value is not in the allowlist', () => {
9
+ expect(SpyNameSchema.parse('other')).toBe('unknown');
10
+ });
11
+
12
+ test.each(AllSpyNames.map((a) => [a, a]))(
13
+ 'parse("%s") should return "%s"',
14
+ (spyName) => {
15
+ expect(SpyNameSchema.parse(spyName)).toBe(spyName);
16
+ }
17
+ );
18
+ });