From aa888c936897fcaa792f4c5c5b7349d673b9e39c Mon Sep 17 00:00:00 2001 From: Theis Pieter Hollebeek Date: Fri, 6 Dec 2024 13:17:07 +0100 Subject: [PATCH] reorganize data; show flamegraph --- web/public/deno.jsonc | 3 +- web/public/src/data.ts | 43 +++++++++++++++++++++ web/public/src/index.ts | 82 ++++++++++++++++++----------------------- 3 files changed, 79 insertions(+), 49 deletions(-) create mode 100644 web/public/src/data.ts diff --git a/web/public/deno.jsonc b/web/public/deno.jsonc index 97a7ef2..e8da863 100644 --- a/web/public/deno.jsonc +++ b/web/public/deno.jsonc @@ -1,7 +1,6 @@ { "tasks": { - "bundle": "deno run -A bundle.ts", - "dev": "deno run --watch -A bundle.ts" + "bundle": "deno run -A bundle.ts" }, "compilerOptions": { "checkJs": false, diff --git a/web/public/src/data.ts b/web/public/src/data.ts new file mode 100644 index 0000000..e633291 --- /dev/null +++ b/web/public/src/data.ts @@ -0,0 +1,43 @@ +export type FlameGraphNode = { + fn: number; + acc: number; + parent: number; + children: FlameGraphNode[]; +}; + +export function flameGraphData(): FlameGraphNode { + return JSON.parse( + `{"fn":0,"acc":257,"parent":0,"children":[{"fn":18,"acc":251,"parent":0,"children":[{"fn":12,"acc":30,"parent":1,"children":[]}]}]}`, + ); +} + +export function codeData() { + return `\ +fn add(a, b) { + + a b +} + +let result = 0; +let i = 0; +loop { + if >= i 10 { + break; + } + result = add(result, 5); + i = + i 1; +} +`; +} + +export type CodeCovEntry = { + index: number; + line: number; + col: number; + covers: number; +}; + +export function codeCoverageData(): CodeCovEntry[] { + return JSON.parse( + `[{"index":0,"line":1,"col":1,"covers":2},{"index":28,"line":5,"col":1,"covers":1},{"index":44,"line":6,"col":1,"covers":1},{"index":55,"line":7,"col":1,"covers":1},{"index":66,"line":8,"col":5,"covers":11},{"index":104,"line":11,"col":5,"covers":10},{"index":19,"line":2,"col":5,"covers":10},{"index":133,"line":12,"col":5,"covers":10},{"index":87,"line":9,"col":9,"covers":1}]`, + ); +} diff --git a/web/public/src/index.ts b/web/public/src/index.ts index 4ca4b6b..00e35e9 100644 --- a/web/public/src/index.ts +++ b/web/public/src/index.ts @@ -1,9 +1,10 @@ -type CodeCovEntry = { - index: number; - line: number; - col: number; - covers: number; -}; +import { + CodeCovEntry, + codeCoverageData, + codeData, + flameGraphData, + FlameGraphNode, +} from "./data.ts"; function loadCodeCoverage( text: string, @@ -93,8 +94,13 @@ function loadCodeCoverage( }); } -// @ts-ignore: unsure of relevant types -function loadFlameGraph(flameGraphData, fnNames, flameGraphDiv) { +type FlameGraphFnNames = { [key: number]: string }; + +function loadFlameGraph( + flameGraphData: FlameGraphNode, + fnNames: FlameGraphFnNames, + flameGraphDiv: HTMLDivElement, +) { flameGraphDiv.innerHTML = ` @@ -120,8 +126,12 @@ function loadFlameGraph(flameGraphData, fnNames, flameGraphDiv) { const nodes: Node[] = []; - // @ts-ignore: unsure of relevant types - function calculateNodeRects(node, depth, totalAcc, offsetAcc) { + function calculateNodeRects( + node: FlameGraphNode, + depth: number, + totalAcc: FlameGraphNode["acc"], + offsetAcc: FlameGraphNode["acc"], + ) { const x = (offsetAcc / totalAcc) * canvas.width; const y = canvas.height - 30 * depth - 30; const w = ((node.acc + 1) / totalAcc) * canvas.width; @@ -132,7 +142,6 @@ function loadFlameGraph(flameGraphData, fnNames, flameGraphDiv) { nodes.push({ x, y, w, h, title, percent }); const totalChildrenAcc = node.children.reduce( - // @ts-ignore: unsure of relevant types (acc, child) => acc + child.acc, 0, ); @@ -186,30 +195,6 @@ function loadFlameGraph(flameGraphData, fnNames, flameGraphDiv) { } function main() { - const codeData = `\ -fn add(a, b) { - + a b -} - -let result = 0; -let i = 0; -loop { - if >= i 10 { - break; - } - result = add(result, 5); - i = + i 1; -} -`; - - const codeCoverageData = JSON.parse( - `[{"index":0,"line":1,"col":1,"covers":2},{"index":28,"line":5,"col":1,"covers":1},{"index":44,"line":6,"col":1,"covers":1},{"index":55,"line":7,"col":1,"covers":1},{"index":66,"line":8,"col":5,"covers":11},{"index":104,"line":11,"col":5,"covers":10},{"index":19,"line":2,"col":5,"covers":10},{"index":133,"line":12,"col":5,"covers":10},{"index":87,"line":9,"col":9,"covers":1}]`, - ); - - const flameGraphData = JSON.parse( - `{"fn":0,"acc":257,"parent":0,"children":[{"fn":18,"acc":251,"parent":0,"children":[{"fn":12,"acc":30,"parent":1,"children":[]}]}]}`, - ); - type RenderFns = { "source-code": () => void; "code-coverage": () => void; @@ -244,9 +229,9 @@ loop { "source-code": () => { const container = document.createElement("div"); container.classList.add("code-container"); - const lines = createLineElement(codeData); + const lines = createLineElement(codeData()); const code = document.createElement("pre"); - code.innerText = codeData; + code.innerText = codeData(); container.append(lines, code); view.replaceChildren(container); }, @@ -255,14 +240,24 @@ loop { container.classList.add("code-container"); const tooltip = document.createElement("div"); tooltip.id = "covers-tooltip"; + tooltip.hidden = true; const code = document.createElement("pre"); - loadCodeCoverage(codeData, codeCoverageData, code, tooltip); - const lines = createLineElement(codeData); + loadCodeCoverage(codeData(), codeCoverageData(), code, tooltip); + const lines = createLineElement(codeData()); container.append(lines, code); const view = document.querySelector("#view")!; view.replaceChildren(container, tooltip); }, - "flame-graph": () => {}, + "flame-graph": () => { + const container = document.createElement("div"); + const view = document.querySelector("#view")!; + view.replaceChildren(container); + loadFlameGraph(flameGraphData(), { + 0: "", + 12: "add", + 18: "main", + }, container); + }, }; const viewRadios: NodeListOf = document.querySelectorAll( @@ -279,13 +274,6 @@ loop { renderFunctions[value](); } } - - // loadCodeCoverage(codeData, codeCoverageData); - // loadFlameGraph(flameGraphData, { - // 0: "", - // 12: "add", - // 18: "main", - // }); } main();