diff --git a/bun.lock b/bun.lock index e62fb33..b15057d 100644 --- a/bun.lock +++ b/bun.lock @@ -4,22 +4,35 @@ "": { "name": "bun-react-template", "dependencies": { + "@codemirror/view": "^6.38.3", "@lezer/generator": "^1.8.0", "bun-plugin-tailwind": "^0.0.15", - "react": "^19", - "react-dom": "^19", + "codemirror": "^6.0.2", + "hono": "^4.9.8", "tailwindcss": "^4.1.11", }, "devDependencies": { "@lezer/highlight": "^1.2.1", "@lezer/lr": "^1.4.2", "@types/bun": "latest", - "@types/react": "^19", - "@types/react-dom": "^19", }, }, }, "packages": { + "@codemirror/autocomplete": ["@codemirror/autocomplete@6.19.0", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0" } }, "sha512-61Hfv3cF07XvUxNeC3E7jhG8XNi1Yom1G0lRC936oLnlF+jrbrv8rc/J98XlYzcsAoTVupfsf5fLej1aI8kyIg=="], + + "@codemirror/commands": ["@codemirror/commands@6.8.1", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.4.0", "@codemirror/view": "^6.27.0", "@lezer/common": "^1.1.0" } }, "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw=="], + + "@codemirror/language": ["@codemirror/language@6.11.3", "", { "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.23.0", "@lezer/common": "^1.1.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0", "style-mod": "^4.0.0" } }, "sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA=="], + + "@codemirror/lint": ["@codemirror/lint@6.8.5", "", { "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.35.0", "crelt": "^1.0.5" } }, "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA=="], + + "@codemirror/search": ["@codemirror/search@6.5.11", "", { "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.0.0", "crelt": "^1.0.5" } }, "sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA=="], + + "@codemirror/state": ["@codemirror/state@6.5.2", "", { "dependencies": { "@marijn/find-cluster-break": "^1.0.0" } }, "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA=="], + + "@codemirror/view": ["@codemirror/view@6.38.3", "", { "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-x2t87+oqwB1mduiQZ6huIghjMt4uZKFEdj66IcXw7+a5iBEvv9lh7EWDRHI7crnD4BMGpnyq/RzmCGbiEZLcvQ=="], + "@lezer/common": ["@lezer/common@1.2.3", "", {}, "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA=="], "@lezer/generator": ["@lezer/generator@1.8.0", "", { "dependencies": { "@lezer/common": "^1.1.0", "@lezer/lr": "^1.3.0" }, "bin": { "lezer-generator": "src/lezer-generator.cjs" } }, "sha512-/SF4EDWowPqV1jOgoGSGTIFsE7Ezdr7ZYxyihl5eMKVO5tlnpIhFcDavgm1hHY5GEonoOAEnJ0CU0x+tvuAuUg=="], @@ -28,30 +41,34 @@ "@lezer/lr": ["@lezer/lr@1.4.2", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA=="], + "@marijn/find-cluster-break": ["@marijn/find-cluster-break@1.0.2", "", {}, "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g=="], + "@types/bun": ["@types/bun@1.2.22", "", { "dependencies": { "bun-types": "1.2.22" } }, "sha512-5A/KrKos2ZcN0c6ljRSOa1fYIyCKhZfIVYeuyb4snnvomnpFqC0tTsEkdqNxbAgExV384OETQ//WAjl3XbYqQA=="], "@types/node": ["@types/node@24.5.2", "", { "dependencies": { "undici-types": "~7.12.0" } }, "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ=="], "@types/react": ["@types/react@19.1.13", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ=="], - "@types/react-dom": ["@types/react-dom@19.1.9", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ=="], - "bun-plugin-tailwind": ["bun-plugin-tailwind@0.0.15", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-qtAXMNGG4R0UGGI8zWrqm2B7BdXqx48vunJXBPzfDOHPA5WkRUZdTSbE7TFwO4jLhYqSE23YMWsM9NhE6ovobw=="], "bun-types": ["bun-types@1.2.22", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-hwaAu8tct/Zn6Zft4U9BsZcXkYomzpHJX28ofvx7k0Zz2HNz54n1n+tDgxoWFGB4PcFvJXJQloPhaV2eP3Q6EA=="], + "codemirror": ["codemirror@6.0.2", "", { "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/commands": "^6.0.0", "@codemirror/language": "^6.0.0", "@codemirror/lint": "^6.0.0", "@codemirror/search": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.0.0" } }, "sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw=="], + + "crelt": ["crelt@1.0.6", "", {}, "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g=="], + "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], - "react": ["react@19.1.1", "", {}, "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ=="], + "hono": ["hono@4.9.8", "", {}, "sha512-JW8Bb4RFWD9iOKxg5PbUarBYGM99IcxFl2FPBo2gSJO11jjUDqlP1Bmfyqt8Z/dGhIQ63PMA9LdcLefXyIasyg=="], - "react-dom": ["react-dom@19.1.1", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.1" } }, "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw=="], - - "scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="], + "style-mod": ["style-mod@4.1.2", "", {}, "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="], "tailwindcss": ["tailwindcss@4.1.13", "", {}, "sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w=="], "typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="], "undici-types": ["undici-types@7.12.0", "", {}, "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ=="], + + "w3c-keyname": ["w3c-keyname@2.2.8", "", {}, "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="], } } diff --git a/package.json b/package.json index 79a3263..1535fb4 100644 --- a/package.json +++ b/package.json @@ -4,22 +4,21 @@ "private": true, "type": "module", "scripts": { - "dev": "bun --hot src/server.tsx", + "serve": "bun --hot src/server/server.tsx", "generate-parser": "lezer-generator src/parser/shrimp.grammar --typeScript -o src/parser/shrimp.ts" }, "dependencies": { + "@codemirror/view": "^6.38.3", + "@lezer/generator": "^1.8.0", "bun-plugin-tailwind": "^0.0.15", - "react": "^19", - "react-dom": "^19", - "tailwindcss": "^4.1.11", - "@lezer/generator": "^1.8.0" + "codemirror": "^6.0.2", + "hono": "^4.9.8", + "tailwindcss": "^4.1.11" }, "devDependencies": { "@lezer/highlight": "^1.2.1", "@lezer/lr": "^1.4.2", - "@types/bun": "latest", - "@types/react": "^19", - "@types/react-dom": "^19" + "@types/bun": "latest" }, "prettier": { "semi": false, diff --git a/src/app.tsx b/src/app.tsx deleted file mode 100644 index b76db42..0000000 --- a/src/app.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export const App = () => { - return ( -
- HI! -
- ); -} \ No newline at end of file diff --git a/src/index.css b/src/index.css deleted file mode 100644 index 9addc76..0000000 --- a/src/index.css +++ /dev/null @@ -1,50 +0,0 @@ -@import "tailwindcss"; - -@layer base { - :root { - @apply text-[rgba(255,255,255,0.87)] bg-[#242424] font-sans; - } - - body { - @apply grid place-items-center min-w-[320px] min-h-screen relative m-0; - } -} - -body::before { - content: ""; - position: fixed; - inset: 0; - z-index: -1; - opacity: 0.05; - background: url("./logo.svg"); - background-size: 256px; - transform: rotate(-12deg) scale(1.35); - animation: slide 30s linear infinite; - pointer-events: none; -} - -@keyframes slide { - from { - background-position: 0 0; - } - to { - background-position: 256px 224px; - } -} - -@keyframes spin { - from { - transform: rotate(0); - } - to { - transform: rotate(360deg); - } -} - -@media (prefers-reduced-motion) { - *, - ::before, - ::after { - animation: none !important; - } -} diff --git a/src/server.tsx b/src/server.tsx deleted file mode 100644 index 3fd46e7..0000000 --- a/src/server.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { serve } from "bun"; -import index from "./index.html"; - -const server = serve({ - routes: { - "/*": index, - - "/api/hello": { - async GET(req) { - return Response.json({ - message: "Hello, world!", - method: "GET", - }); - }, - async PUT(req) { - return Response.json({ - message: "Hello, world!", - method: "PUT", - }); - }, - }, - }, - - development: process.env.NODE_ENV !== "production" && { - hmr: true, - console: true, - }, -}); - -console.log(`🚀 Server running at ${server.url}`); diff --git a/src/server/app.tsx b/src/server/app.tsx new file mode 100644 index 0000000..2a45247 --- /dev/null +++ b/src/server/app.tsx @@ -0,0 +1,14 @@ +import { Editor } from '@/server/editor' +import { render } from 'hono/jsx/dom' +import './index.css' + +const App = () => { + return ( +
+ +
+ ) +} + +const root = document.getElementById('root')! +render(, root) diff --git a/src/server/editor.tsx b/src/server/editor.tsx new file mode 100644 index 0000000..0dcff77 --- /dev/null +++ b/src/server/editor.tsx @@ -0,0 +1,24 @@ +import { basicSetup } from 'codemirror' +import { EditorView } from '@codemirror/view' +import { editorTheme } from './editorTheme' + +export const Editor = () => { + return ( +
{ + if (ref?.querySelector('.cm-editor')) return + + console.log('init editor') + new EditorView({ + doc: '', + parent: ref, + extensions: [basicSetup, editorTheme], + }) + }} + /> + ) +} + +export const Output = ({ children }: { children: string }) => { + return
{children}
+} diff --git a/src/server/editorTheme.tsx b/src/server/editorTheme.tsx new file mode 100644 index 0000000..2fd53f9 --- /dev/null +++ b/src/server/editorTheme.tsx @@ -0,0 +1,37 @@ +import { EditorView } from '@codemirror/view' + +export const editorTheme = EditorView.theme( + { + '&': { + color: '#7C70DA', + backgroundColor: '#40318D', + fontFamily: '"Pixeloid Mono", "Courier New", monospace', + fontSize: '18px', + height: '100%', + }, + '.cm-content': { + caretColor: '#7C70DA', + padding: '0px', + minHeight: '100px', + borderBottom: '3px solid #7C70DA', + }, + '.cm-activeLine': { + backgroundColor: 'transparent', + }, + '&.cm-focused .cm-cursor': { + borderLeftColor: '#7C70DA', + }, + '&.cm-focused .cm-selectionBackground, ::selection': { + backgroundColor: '#5A4FCF', + }, + '.cm-gutters': { + display: 'none', + }, + '.cm-editor': { + border: 'none', + outline: 'none', + height: '100%', + }, + }, + { dark: true } +) diff --git a/src/server/index.css b/src/server/index.css new file mode 100644 index 0000000..15afa43 --- /dev/null +++ b/src/server/index.css @@ -0,0 +1,32 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + background: #40318D; + color: #7C70DA; + font-family: 'Pixeloid Mono', 'Courier New', monospace; + font-size: 18px; + height: 100vh; + overflow: hidden; +} + +#root { + height: 100vh; + background: #40318D; + display: flex; + flex-direction: column; +} + +.terminal-output { + flex: 1; + background: #40318D; + color: #7C70DA; + padding: 20px; + overflow-y: auto; + white-space: pre-wrap; + font-family: 'Pixeloid Mono', 'Courier New', monospace; + font-size: 18px; +} \ No newline at end of file diff --git a/src/index.html b/src/server/index.html similarity index 75% rename from src/index.html rename to src/server/index.html index 2460d2d..2f4d226 100644 --- a/src/index.html +++ b/src/server/index.html @@ -1,4 +1,4 @@ - + @@ -7,6 +7,6 @@
- + diff --git a/src/server/server.tsx b/src/server/server.tsx new file mode 100644 index 0000000..094b732 --- /dev/null +++ b/src/server/server.tsx @@ -0,0 +1,29 @@ +import index from './index.html' + +const server = Bun.serve({ + routes: { + '/*': index, + + '/api/hello': { + async GET(req) { + return Response.json({ + message: 'Hello, world!', + method: 'GET', + }) + }, + async PUT(req) { + return Response.json({ + message: 'Hello, world!', + method: 'PUT', + }) + }, + }, + }, + + development: process.env.NODE_ENV !== 'production' && { + hmr: true, + console: true, + }, +}) + +console.log(`🚀 Server running at ${server.url}`) diff --git a/tsconfig.json b/tsconfig.json index 632a36f..a0eb694 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "module": "Preserve", "moduleDetection": "force", "jsx": "react-jsx", + "jsxImportSource": "hono/jsx", "allowJs": true, // Bundler mode