From f61faa6d5f79f75e3ab5f5c1c67c68ff4bf57740 Mon Sep 17 00:00:00 2001 From: Hugo Caillard <911307+hugocaillard@users.noreply.github.com> Date: Tue, 1 Oct 2024 20:23:39 +0200 Subject: [PATCH 1/2] feat: clarity-playground component --- components/code/clarinet-sdk.tsx | 184 +++++++++--------- components/search.tsx | 18 +- .../docs/stacks/clarity/basic-arithmetic.mdx | 24 ++- package.json | 2 +- 4 files changed, 122 insertions(+), 106 deletions(-) diff --git a/components/code/clarinet-sdk.tsx b/components/code/clarinet-sdk.tsx index fc0a0543b..826d216f1 100644 --- a/components/code/clarinet-sdk.tsx +++ b/components/code/clarinet-sdk.tsx @@ -1,6 +1,6 @@ "use client"; -import React from "react"; +import React, { useEffect, useLayoutEffect } from "react"; import { cn } from "@/utils/cn"; import { Button } from "@/components/ui/button"; import * as Base from "fumadocs-ui/components/codeblock"; @@ -8,121 +8,117 @@ import * as Base from "fumadocs-ui/components/codeblock"; import { initSimnet } from "@hirosystems/clarinet-sdk-browser"; import { Cl } from "@stacks/transactions"; -import { getHighlighter } from "shiki"; +import { + BundledLanguage, + BundledTheme, + getSingletonHighlighter, + HighlighterGeneric, +} from "shiki"; -// TODO: WIP: testing out new Clarinet JS SDK browser lib -export const ClarinetSDK: React.FC = () => { - const [simnet, setSimnet] = React.useState(); - const [html, setHtml] = React.useState(); - const [evaluatedResponse, setEvaluatedResponse] = React.useState(); - - async function showMe() { - const simnet = await initSimnet(); - await simnet.initEmtpySession(); +type ClarityPlaygroundProps = { + snippet: string; +}; - simnet.setEpoch("2.5"); - const result = - simnet.runSnippet(`(define-map Users uint {address: principal}) - (map-insert Users u1 { address: tx-sender }) - (map-get? Users u1) - `) as any; - - const highlighter = await getHighlighter({ - langs: ["bash", "ts", "tsx", "clarity"], - themes: ["github-light", "github-dark"], - }); - const res = highlighter.codeToHtml(Cl.prettyPrint(result, 2), { - lang: "clarity", - defaultColor: false, - themes: { - light: "github-light", - dark: "github-dark", - }, - transformers: [ - { - name: "remove-pre", - root: (root) => { - if (root.children[0].type !== "element") return; - - return { - type: "root", - children: root.children[0].children, - }; - }, +let memoizedHighlighter: HighlighterGeneric; +async function getHighlighter() { + if (memoizedHighlighter) return memoizedHighlighter; + + memoizedHighlighter = await getSingletonHighlighter({ + langs: ["clarity"], + themes: ["github-light", "github-dark"], + }); + return memoizedHighlighter; +} + +async function highlight(snippet: string) { + const highlighter = await getHighlighter(); + return highlighter.codeToHtml(snippet, { + lang: "clarity", + defaultColor: false, + themes: { + light: "github-light", + dark: "github-dark", + }, + transformers: [ + { + name: "remove-pre", + root: (root) => { + if (root.children[0].type !== "element") return; + return { + type: "root", + children: root.children[0].children, + }; }, - ], - }); - setEvaluatedResponse(res); - } + }, + ], + }); +} + +// TODO: WIP: testing out new Clarinet JS SDK browser lib +export const ClarityPlayground: React.FC = ({ + snippet, +}) => { + const [snippetValue, setSnippetValue] = React.useState(snippet); + const [snippetRows, setSnippetRows] = React.useState( + snippetValue.split("\n").length, + ); + const [snippetHTML, setSnippetHTML] = React.useState(""); + const [resultHTML, setResultHTML] = React.useState(); + + useEffect(() => { + highlight(snippetValue).then(setSnippetHTML); + setSnippetRows(snippetValue.split("\n").length); + }, [snippetValue]); async function run() { const simnet = await initSimnet(); await simnet.initEmtpySession(); simnet.setEpoch("2.5"); - const result = - simnet.runSnippet(`(define-map Users uint {address: principal}) - (map-insert Users u1 { address: tx-sender }) - (map-get? Users u1) - `) as any; - console.log(Cl.prettyPrint(result, 2)); - setSimnet(simnet); - - const codeResponse = await fetch("/scripts/hello-world.clar"); - const code = await codeResponse.text(); - - const highlighter = await getHighlighter({ - langs: ["bash", "ts", "tsx", "clarity"], - themes: ["github-light", "github-dark"], - }); - - const html = highlighter.codeToHtml(code, { - lang: "clarity", - defaultColor: false, - themes: { - light: "github-light", - dark: "github-dark", - }, - transformers: [ - { - name: "remove-pre", - root: (root) => { - if (root.children[0].type !== "element") return; - - return { - type: "root", - children: root.children[0].children, - }; - }, - }, - ], - }); - setHtml(html); - } + const { result } = simnet.execute(snippetValue); + const resultString = Cl.prettyPrint(result, 2); - React.useEffect(() => { - run(); - }, []); + highlight(resultString).then(setResultHTML); + } return ( <> +
+ {/* className="absolute font-sm t-0 b-0 l-0 r-0" */} + + + + + {/* className="absolute t-0 b-0 l-0 r-0 background-none p-2 font-sm font-mono opacity-50" */} +