Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nadro/3799/perf #4145

Open
wants to merge 67 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
4d1bf94
chore: building out perf testing
nadr0 Sep 14, 2024
e481c0f
chore: adding my printing code for the different formats of the marks
nadr0 Sep 16, 2024
b6303ae
feat: select all text that is rendered for easy copy and paste
nadr0 Sep 17, 2024
35ea5f3
feat: adding invocation count table
nadr0 Sep 17, 2024
4dd5206
fix: markOnce iunstead
nadr0 Sep 17, 2024
1eabde1
fix: typescript additions
nadr0 Sep 18, 2024
6da7a45
fix: adding more types
nadr0 Sep 18, 2024
c830996
chore: adding telemetry panel as MVP, gonna remove the pane
nadr0 Oct 9, 2024
7b75ca3
chore: view telemetry from command bar in file route and home route
nadr0 Oct 9, 2024
3948ec6
fix: deleting unused imports
nadr0 Oct 9, 2024
c4a5150
fix: deleting some unused files
nadr0 Oct 9, 2024
79cfa79
fix: merged main, resolved conflicts
nadr0 Oct 9, 2024
197a61b
fix: auto cleanup
nadr0 Oct 9, 2024
27ed056
chore: adding other routes, these will need to be moved...
nadr0 Oct 10, 2024
bbeb079
chore: moving some printing logic around and unit testing some of it
nadr0 Oct 10, 2024
d068d41
fix: moving command init
nadr0 Oct 10, 2024
dff3220
fix: removing debugging marks
nadr0 Oct 10, 2024
ba43a7e
fix: adding some comments
nadr0 Oct 10, 2024
2d6b092
fix: fixed a bug with generating the go to page commands
nadr0 Oct 10, 2024
1384267
chore: adding will pages load within the router config
nadr0 Oct 10, 2024
6d9f9c1
chore: implementing marks for routes
nadr0 Oct 10, 2024
7811b89
fix: auto fixes and checkers
nadr0 Oct 10, 2024
aee3967
chore: implemented a route watcher at the root level...
nadr0 Oct 10, 2024
2b89e96
fix: auto fixes, removing unused code
nadr0 Oct 10, 2024
09f7600
chore: timing for syntax highlighting and auto fixes
nadr0 Oct 11, 2024
c8fb0d5
fix: didAuth issue and syntax highlighting in the packaged applicatio…
nadr0 Oct 11, 2024
41f36ec
fix: fixing typescript checks
nadr0 Oct 11, 2024
55f03de
chore: adding mag bar chart icon for telemetry
nadr0 Oct 11, 2024
6c257d1
fix: merged main, resolved conflicts
nadr0 Oct 11, 2024
9f85afd
A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
github-actions[bot] Oct 11, 2024
86bda24
A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
github-actions[bot] Oct 11, 2024
db869b3
A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)
github-actions[bot] Oct 11, 2024
fbbfaab
chore: swapped telemetry icon for stopwatch
nadr0 Oct 11, 2024
bd626e0
A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)
github-actions[bot] Oct 11, 2024
8caf9e1
Merge branch 'nadro/3799/perf' of github.com:KittyCAD/modeling-app in…
nadr0 Oct 11, 2024
2a1e780
A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
github-actions[bot] Oct 11, 2024
ce0f784
A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)
github-actions[bot] Oct 11, 2024
2c91d70
A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)
github-actions[bot] Oct 11, 2024
7f9f7b6
Merge branch 'main' into nadro/3799/perf
nadr0 Oct 11, 2024
eb082f2
A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
github-actions[bot] Oct 11, 2024
95d5501
chore: writing telemetry to disk
nadr0 Oct 17, 2024
a7348fc
fix: auto fixers
nadr0 Oct 17, 2024
ba80d5f
chore: getting args parsed for cli flags and writing telemetry file
nadr0 Oct 17, 2024
2c8cbfb
fix: merged main
nadr0 Oct 17, 2024
3c40522
A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
github-actions[bot] Oct 17, 2024
b36c1a2
chore: swapped mark for markOnce since we infinitely write marks to a…
nadr0 Oct 17, 2024
956aa14
Merge branch 'nadro/3799/perf' of github.com:KittyCAD/modeling-app in…
nadr0 Oct 17, 2024
e80063c
fix: merged main
nadr0 Oct 18, 2024
080b57b
A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
github-actions[bot] Oct 18, 2024
e3241ec
A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
github-actions[bot] Oct 18, 2024
090ec12
A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)
github-actions[bot] Oct 18, 2024
cd629b6
A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)
github-actions[bot] Oct 18, 2024
254f4b7
chore: writing raw marks to disk as well
nadr0 Oct 19, 2024
8c43e55
Merge branch 'nadro/3799/perf' of github.com:KittyCAD/modeling-app in…
nadr0 Oct 19, 2024
8b044d5
A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
github-actions[bot] Oct 19, 2024
a4d92de
A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)
github-actions[bot] Oct 19, 2024
efd5beb
A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)
github-actions[bot] Oct 19, 2024
959fc88
fix: merging main
nadr0 Oct 30, 2024
b2dcad0
A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
github-actions[bot] Oct 30, 2024
b1a4041
A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)
github-actions[bot] Oct 30, 2024
25f8ded
fix: cleaned up the testing names
nadr0 Oct 31, 2024
19f100c
fix: merged main and resolved conflicts
nadr0 Oct 31, 2024
60b1e51
A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
github-actions[bot] Oct 31, 2024
3bc0a1c
A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)
github-actions[bot] Oct 31, 2024
6524968
Merge branch 'main' into nadro/3799/perf
lf94 Nov 1, 2024
b1fb1b5
Fix fmt and codespell
lf94 Nov 1, 2024
ee36eeb
Merge branch 'main' into nadro/3799/perf
lf94 Nov 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions interface.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export interface IElectronAPI {
) => Electron.IpcRenderer
onUpdateError: (callback: (value: { error: Error }) => void) => Electron
appRestart: () => void
getArgvParsed: () => any
}

declare global {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
"vscode-languageserver-protocol": "^3.17.5",
"vscode-uri": "^3.0.8",
"web-vitals": "^3.5.2",
"xstate": "^5.17.4"
"xstate": "^5.17.4",
"yargs": "^17.7.2"
},
"scripts": {
"start": "vite",
Expand Down
4 changes: 4 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import Gizmo from 'components/Gizmo'
import { CoreDumpManager } from 'lib/coredump'
import { UnitsMenu } from 'components/UnitsMenu'
import { CameraProjectionToggle } from 'components/CameraProjectionToggle'
import { maybeWriteToDisk } from 'lib/telemetry'
maybeWriteToDisk()
.then(() => {})
.catch(() => {})

export function App() {
const { project, file } = useLoaderData() as IndexLoaderData
Expand Down
46 changes: 33 additions & 13 deletions src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from 'react-router-dom'
import { ErrorPage } from './components/ErrorPage'
import { Settings } from './routes/Settings'
import { Telemetry } from './routes/Telemetry'
import Onboarding, { onboardingRoutes } from './routes/Onboarding'
import SignIn from './routes/SignIn'
import { Auth } from './Auth'
Expand All @@ -28,6 +29,7 @@ import {
homeLoader,
onboardingRedirectLoader,
settingsLoader,
telemetryLoader,
} from 'lib/routeLoaders'
import { CommandBarProvider } from 'components/CommandBar/CommandBarProvider'
import SettingsAuthProvider from 'components/SettingsAuthProvider'
Expand All @@ -43,6 +45,7 @@ import { coreDump } from 'lang/wasm'
import { useMemo } from 'react'
import { AppStateProvider } from 'AppState'
import { reportRejection } from 'lib/trap'
import { RouteProvider } from 'components/RouteProvider'
import { ProjectsContextProvider } from 'components/ProjectsContextProvider'

const createRouter = isDesktop() ? createHashRouter : createBrowserRouter
Expand All @@ -56,19 +59,21 @@ const router = createRouter([
* inefficient re-renders, use the react profiler to see. */
element: (
<CommandBarProvider>
<SettingsAuthProvider>
<LspProvider>
<ProjectsContextProvider>
<KclContextProvider>
<AppStateProvider>
<MachineManagerProvider>
<Outlet />
</MachineManagerProvider>
</AppStateProvider>
</KclContextProvider>
</ProjectsContextProvider>
</LspProvider>
</SettingsAuthProvider>
<RouteProvider>
<SettingsAuthProvider>
<LspProvider>
<ProjectsContextProvider>
<KclContextProvider>
<AppStateProvider>
<MachineManagerProvider>
<Outlet />
</MachineManagerProvider>
</AppStateProvider>
</KclContextProvider>
</ProjectsContextProvider>
</LspProvider>
</SettingsAuthProvider>
</RouteProvider>
</CommandBarProvider>
),
errorElement: <ErrorPage />,
Expand Down Expand Up @@ -124,6 +129,16 @@ const router = createRouter([
},
],
},
{
id: PATHS.FILE + 'TELEMETRY',
loader: telemetryLoader,
children: [
{
path: makeUrlPathRelative(PATHS.TELEMETRY),
element: <Telemetry />,
},
],
},
],
},
{
Expand All @@ -149,6 +164,11 @@ const router = createRouter([
loader: settingsLoader,
element: <Settings />,
},
{
path: makeUrlPathRelative(PATHS.TELEMETRY),
loader: telemetryLoader,
element: <Telemetry />,
},
],
},
{
Expand Down
12 changes: 12 additions & 0 deletions src/commandLineArgs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import yargs from 'yargs'
import { hideBin } from 'yargs/helpers'

const argv = yargs(hideBin(process.argv))
.option('telemetry', {
alias: 't',
type: 'boolean',
description: 'Writes startup telemetry to file on disk.',
})
.parse()

export default argv
39 changes: 39 additions & 0 deletions src/components/CommandBar/CommandBarProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { createActorContext } from '@xstate/react'
import { editorManager } from 'lib/singletons'
import { commandBarMachine } from 'machines/commandBarMachine'
import { useEffect } from 'react'
import { createRouteCommands } from 'lib/commandBarConfigs/routeCommandConfig'
import { useNavigate, useLocation } from 'react-router-dom'
import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath'
import { PATHS } from 'lib/paths'

export const CommandsContext = createActorContext(
commandBarMachine.provide({
Expand Down Expand Up @@ -34,6 +38,41 @@ export const CommandBarProvider = ({
}
function CommandBarProviderInner({ children }: { children: React.ReactNode }) {
const commandBarActor = CommandsContext.useActorRef()
const location = useLocation()
const filePath = useAbsoluteFilePath()
const navigate = useNavigate()

useEffect(() => {
const { RouteTelemetryCommand, RouteHomeCommand, RouteSettingsCommand } =
createRouteCommands(navigate, location, filePath)
commandBarActor.send({
type: 'Remove commands',
data: {
commands: [
RouteTelemetryCommand,
RouteHomeCommand,
RouteSettingsCommand,
],
},
})
if (location.pathname === PATHS.HOME) {
commandBarActor.send({
type: 'Add commands',
data: { commands: [RouteTelemetryCommand, RouteSettingsCommand] },
})
} else if (location.pathname.includes(PATHS.FILE)) {
commandBarActor.send({
type: 'Add commands',
data: {
commands: [
RouteTelemetryCommand,
RouteSettingsCommand,
RouteHomeCommand,
],
},
})
}
}, [location])

useEffect(() => {
editorManager.setCommandBarSend(commandBarActor.send)
Expand Down
23 changes: 23 additions & 0 deletions src/components/CustomIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,29 @@ const CustomIconMap = {
/>
</svg>
),
stopwatch: (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M7.95705 5.99046C7.05643 6.44935 6.33654 7.19809 5.91336 8.11602C5.49019 9.03396 5.38838 10.0676 5.62434 11.0505C5.8603 12.0334 6.42029 12.9081 7.21408 13.5339C8.00787 14.1597 8.98922 14.5 10 14.5C11.0108 14.5 11.9921 14.1597 12.7859 13.5339C13.5797 12.9082 14.1397 12.0334 14.3757 11.0505C14.6116 10.0676 14.5098 9.03396 14.0866 8.11603C13.6635 7.19809 12.9436 6.44935 12.043 5.99046L12.497 5.09946C13.5977 5.66032 14.4776 6.57544 14.9948 7.69737C15.512 8.81929 15.6364 10.0827 15.348 11.2839C15.0596 12.4852 14.3752 13.5544 13.405 14.3192C12.4348 15.0841 11.2354 15.5 10 15.5C8.7646 15.5 7.56517 15.0841 6.59499 14.3192C5.6248 13.5544 4.94037 12.4852 4.65197 11.2839C4.36357 10.0827 4.488 8.81929 5.00522 7.69736C5.52243 6.57544 6.40231 5.66032 7.50306 5.09946L7.95705 5.99046Z"
fill="currentColor"
/>
<path d="M10 5.5V4M10 4H8M10 4H12" stroke="currentColor" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12.8536 7.85356L10.3536 10.3536C10.1583 10.5488 9.84171 10.5488 9.64645 10.3536C9.45118 10.1583 9.45118 9.84172 9.64645 9.64645L12.1464 7.14645L12.8536 7.85356Z"
fill="currentColor"
/>
</svg>
),
} as const

export type CustomIconName = keyof typeof CustomIconMap
Expand Down
2 changes: 2 additions & 0 deletions src/components/FileMachineProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
KclSamplesManifestItem,
} from 'lib/getKclSamplesManifest'
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
import { markOnce } from 'lib/performance'

type MachineContext<T extends AnyStateMachine> = {
state: StateFrom<T>
Expand All @@ -54,6 +55,7 @@ export const FileMachineProvider = ({
)

useEffect(() => {
markOnce('code/didLoadFile')
async function fetchKclSamples() {
setKclSamples(await getKclSamplesManifest())
}
Expand Down
17 changes: 17 additions & 0 deletions src/components/LowerRightControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,23 @@ export function LowerRightControls({
Report a bug
</Tooltip>
</a>
<Link
to={
location.pathname.includes(PATHS.FILE)
? filePath + PATHS.TELEMETRY + '?tab=project'
: PATHS.HOME + PATHS.TELEMETRY
}
data-testid="telemetry-link"
>
<CustomIcon
name="stopwatch"
className={`w-5 h-5 ${linkOverrideClassName}`}
/>
<span className="sr-only">Telemetry</span>
<Tooltip position="top" contentClassName="text-xs">
Telemetry
</Tooltip>
</Link>
<Link
to={
location.pathname.includes(PATHS.FILE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ export const KclEditorPane = () => {
closeBrackets(),
highlightActiveLine(),
highlightSelectionMatches(),
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
syntaxHighlighting(defaultHighlightStyle, {
fallback: true,
}),
rectangularSelection(),
dropCursor(),
interact({
Expand Down
33 changes: 33 additions & 0 deletions src/components/RouteProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useEffect, useState, createContext, ReactNode } from 'react'
import { useNavigation, useLocation } from 'react-router-dom'
import { PATHS } from 'lib/paths'
import { markOnce } from 'lib/performance'

export const RouteProviderContext = createContext({})

export function RouteProvider({ children }: { children: ReactNode }) {
const [first, setFirstState] = useState(true)
const navigation = useNavigation()
const location = useLocation()
useEffect(() => {
// On initialization, the react-router-dom does not send a 'loading' state event.
// it sends an idle event first.
const pathname = first ? location.pathname : navigation.location?.pathname
const isHome = pathname === PATHS.HOME
const isFile =
pathname?.includes(PATHS.FILE) &&
pathname?.substring(pathname?.length - 4) === '.kcl'
if (isHome) {
markOnce('code/willLoadHome')
} else if (isFile) {
markOnce('code/willLoadFile')
}
setFirstState(false)
}, [navigation])

return (
<RouteProviderContext.Provider value={{}}>
{children}
</RouteProviderContext.Provider>
)
}
72 changes: 72 additions & 0 deletions src/components/TelemetryExplorer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { getMarks } from 'lib/performance'

import {
printDeltaTotal,
printInvocationCount,
printMarkDownTable,
printRawMarks,
} from 'lib/telemetry'

export function TelemetryExplorer() {
const marks = getMarks()
const markdownTable = printMarkDownTable(marks)
const rawMarks = printRawMarks(marks)
const deltaTotalTable = printDeltaTotal(marks)
const invocationCount = printInvocationCount(marks)
// TODO data-telemetry-type
// TODO data-telemetry-name
return (
<div>
<h1 className="pb-4">Marks</h1>
<div className="max-w-xl max-h-64 overflow-auto select-all">
{marks.map((mark, index) => {
return (
<pre className="text-xs" key={index}>
<code key={index}>{JSON.stringify(mark, null, 2)}</code>
</pre>
)
})}
</div>
<h1 className="pb-4">Startup Performance</h1>
<div className="max-w-xl max-h-64 overflow-auto select-all">
{markdownTable.map((line, index) => {
return (
<pre className="text-xs" key={index}>
<code key={index}>{line}</code>
</pre>
)
})}
</div>
<h1 className="pb-4">Delta and Totals</h1>
<div className="max-w-xl max-h-64 overflow-auto select-all">
{deltaTotalTable.map((line, index) => {
return (
<pre className="text-xs" key={index}>
<code key={index}>{line}</code>
</pre>
)
})}
</div>
<h1 className="pb-4">Raw Marks</h1>
<div className="max-w-xl max-h-64 overflow-auto select-all">
{rawMarks.map((line, index) => {
return (
<pre className="text-xs" key={index}>
<code key={index}>{line}</code>
</pre>
)
})}
</div>
<h1 className="pb-4">Invocation Count</h1>
<div className="max-w-xl max-h-64 overflow-auto select-all">
{invocationCount.map((line, index) => {
return (
<pre className="text-xs" key={index}>
<code key={index}>{line}</code>
</pre>
)
})}
</div>
</div>
)
}
Loading
Loading