Skip to content

Commit 4d2febc

Browse files
committed
feat: add executable code blocks with 15+ programming languages
- Add Monaco Editor integration with VS Code experience - Support JavaScript, TypeScript, Python, Java, C++, C#, Go, Rust, PHP, Ruby, Kotlin, Swift, Bash, SQL - Implement secure backend proxy for Judge0 API (no client-side API keys) - Add real-time status updates during code execution - Support per-block theme customization (light/dark) - Add resizable code blocks with drag handles - Integrate with TipTap editor via custom NodeView extension - Add toolbar button and slash command support
1 parent 89b9aa9 commit 4d2febc

File tree

14 files changed

+1072
-5
lines changed

14 files changed

+1072
-5
lines changed

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ Get the native desktop experience with:
6464
- 💾 **Auto-save** - Real-time saving with visual indicators
6565
- 🔗 **Links & references** - Easy link insertion and management
6666
- 🧮 **Code support** - Inline code and code blocks with syntax highlighting
67+
-**Executable code blocks** - Run JavaScript, Python, Java, C++, and 10+ other languages directly in your notes
6768

6869
### 📊 Professional Status Bar
6970
- 📈 **Real-time statistics** - Word count, character count, reading time estimates
@@ -78,6 +79,20 @@ Get the native desktop experience with:
7879
- 🌐 **Cross-platform** - Responsive web app that works seamlessly on desktop, tablet, and mobile
7980
- 🖨️ **Print support** - Clean printing with proper formatting
8081

82+
### ⚡ Executable Code Blocks
83+
84+
![Execute Code Demo](https://github.com/typelets/typelets-app/blob/main/execute-code-demo.gif)
85+
86+
- 💻 **15+ Programming Languages** - JavaScript, TypeScript, Python, Java, C++, C#, Go, Rust, PHP, Ruby, Kotlin, Swift, Bash, SQL, and more
87+
- 🎨 **Monaco Editor Integration** - Professional VS Code-powered editor with IntelliSense and syntax highlighting
88+
-**One-click Execution** - Run code instantly with the play button or `Ctrl+Enter` keyboard shortcut
89+
- 📊 **Real-time Status Updates** - Live execution progress from "In Queue" → "Processing" → "Complete"
90+
- 🔄 **Resizable Code Blocks** - Drag to adjust editor height for optimal viewing
91+
- 🌙 **Theme Toggle** - Switch between light and dark Monaco editor themes
92+
- 💾 **Persistent Results** - Code output is automatically saved with your notes
93+
- 🔒 **Secure Sandboxed Execution** - Code runs in isolated environments via Judge0 API
94+
- 📋 **Error Handling** - Clear error messages and compilation details for debugging
95+
8196
## 🔒 Security First
8297

8398
Typelets uses industry-standard encryption:
@@ -146,7 +161,13 @@ VITE_APP_NAME=Typelets
146161
VITE_APP_VERSION=0.5.0
147162
```
148163

149-
Get your Clerk keys from [dashboard.clerk.com](https://dashboard.clerk.com)
164+
**Authentication Setup:**
165+
- Get your Clerk keys from [dashboard.clerk.com](https://dashboard.clerk.com)
166+
167+
**Code Execution Setup:**
168+
- Code execution is handled securely by your backend API
169+
- The backend proxy manages Judge0 API integration
170+
- No client-side API keys required for security
150171

151172
### Development Proxy
152173

@@ -374,6 +395,8 @@ typelets/
374395
- **Build Tool:** Vite 7 with development proxy
375396
- **Styling:** Tailwind CSS v4
376397
- **Editor:** TipTap with code highlighting
398+
- **Code Editor:** Monaco Editor (VS Code engine)
399+
- **Code Execution:** Judge0 API for 15+ programming languages
377400
- **Authentication:** Clerk
378401
- **UI Components:** Radix UI
379402
- **Encryption:** Web Crypto API with AES-256-GCM

assets/execute-code-demo.gif

1.87 MB
Loading

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
},
6262
"dependencies": {
6363
"@clerk/clerk-react": "^5.41.0",
64+
"@monaco-editor/react": "^4.7.0",
6465
"@radix-ui/react-alert-dialog": "^1.1.14",
6566
"@radix-ui/react-dialog": "^1.1.14",
6667
"@radix-ui/react-dropdown-menu": "^2.1.15",
@@ -90,6 +91,7 @@
9091
"highlight.js": "^11.11.1",
9192
"lowlight": "^3.3.0",
9293
"lucide-react": "^0.523.0",
94+
"monaco-editor": "^0.53.0",
9395
"react": "^19.1.1",
9496
"react-dom": "^19.1.1",
9597
"tailwind-merge": "^3.3.1",

pnpm-lock.yaml

Lines changed: 44 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import Index from '@/components/common/SEO';
1212
import { SEO_CONFIG } from '@/constants';
1313
import { api } from '@/lib/api/api.ts';
1414
import { fileService } from '@/services/fileService';
15+
import { codeExecutionService } from '@/services/codeExecutionService';
1516
import { clearUserEncryptionData } from '@/lib/encryption';
1617
import MainApp from '@/pages/MainApp';
1718

@@ -23,6 +24,7 @@ function AppContent() {
2324
useEffect(() => {
2425
api.setTokenProvider(getToken);
2526
fileService.setTokenProvider(getToken);
27+
codeExecutionService.setTokenProvider(getToken);
2628
}, [getToken]);
2729

2830
useEffect(() => {

src/components/editor/Editor/Toolbar.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
RemoveFormatting,
2525
Copy,
2626
Smile,
27+
Codesandbox,
2728
} from 'lucide-react';
2829

2930
import { Button } from '@/components/ui/button.tsx';
@@ -395,6 +396,15 @@ export function Toolbar({ editor }: ToolbarProps) {
395396
</DropdownMenuContent>
396397
</DropdownMenu>
397398

399+
<Button
400+
variant={editor.isActive('executableCodeBlock') ? 'default' : 'ghost'}
401+
size="sm"
402+
onClick={() => editor.chain().focus().setExecutableCodeBlock({ language: 'javascript', executable: true }).run()}
403+
title="Executable Code Block"
404+
>
405+
<Codesandbox className="h-4 w-4" />
406+
</Button>
407+
398408
<Button
399409
variant={editor.isActive('blockquote') ? 'default' : 'ghost'}
400410
size="sm"

src/components/editor/config/editor-config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Color from '@tiptap/extension-color';
1010
import TextStyle from '@tiptap/extension-text-style';
1111
import { TableOfContents } from '../extensions/TableOfContents';
1212
import { ResizableImage } from '../extensions/ResizableImage';
13+
import { ExecutableCodeBlock } from '../extensions/ExecutableCodeBlock';
1314
import StarterKit from '@tiptap/starter-kit';
1415
import bash from 'highlight.js/lib/languages/bash';
1516
import cpp from 'highlight.js/lib/languages/cpp';
@@ -56,6 +57,12 @@ export function createEditorExtensions() {
5657
horizontalRule: false,
5758
dropcursor: false,
5859
}),
60+
ExecutableCodeBlock.configure({
61+
defaultLanguage: 'javascript',
62+
HTMLAttributes: {
63+
class: 'executable-code-block',
64+
},
65+
}),
5966
CodeBlockLowlight.configure({
6067
lowlight,
6168
defaultLanguage: 'plaintext',

0 commit comments

Comments
 (0)