velxio/frontend
a2nr ea82602102 feat: add EmbedBridge PostMessage protocol for LMS iframe integration
Implement bidirectional PostMessage bridge (EmbedBridge.ts) enabling
Velxio to be embedded as iframe in Elemes LMS. Supports: load_code,
load_circuit, get_source_code, get_serial_log, get_wires, set_embed_mode,
stop, ping. EditorPage/Toolbar hide auth UI in embed mode.
2026-04-09 09:44:49 +07:00
..
public feat: implement ESP32 QEMU backend manager and frontend simulation interface 2026-04-01 22:41:52 -03:00
scripts feat: enhance build scripts and add SEO prerendering; improve touch interactions for wire creation 2026-03-25 00:08:46 -03:00
src feat: add EmbedBridge PostMessage protocol for LMS iframe integration 2026-04-09 09:44:49 +07:00
.env.production feat: add support for RP2040 board, including simulator and compilation enhancements 2026-03-04 19:28:33 -03:00
.gitignore feat: Update .gitignore to include data directory and remove example sketch.ino 2026-03-07 19:31:16 -03:00
Dockerfile feat: add support for RP2040 board, including simulator and compilation enhancements 2026-03-04 19:28:33 -03:00
README.md Merge doc/ into docs/ — eliminate duplicate documentation folders 2026-03-11 17:03:51 +00:00
eslint.config.js feat: Implement Arduino Simulator with component management and simulation features 2026-03-03 00:20:49 -03:00
esp32 plan.md feat: implement user authentication and project management features 2026-03-06 10:14:50 -03:00
index.html feat: add About link to navigation in index.html and Velxio2Page 2026-03-28 22:43:53 -03:00
nginx.conf perf: optimize hero image for faster load times 2026-03-28 20:33:40 +01:00
package-lock.json feat: add CodeBlock component with syntax highlighting and update dependencies 2026-03-16 14:39:49 -03:00
package.json feat: enhance build scripts and add SEO prerendering; improve touch interactions for wire creation 2026-03-25 00:08:46 -03:00
tsconfig.app.json feat: Implement Arduino Simulator with component management and simulation features 2026-03-03 00:20:49 -03:00
tsconfig.json feat: Implement Arduino Simulator with component management and simulation features 2026-03-03 00:20:49 -03:00
tsconfig.node.json feat: Implement Arduino Simulator with component management and simulation features 2026-03-03 00:20:49 -03:00
vite.config.ts feat: add EmbedBridge PostMessage protocol for LMS iframe integration 2026-04-09 09:44:49 +07:00

README.md

Arduino Emulator - Frontend

React + TypeScript + Vite frontend for the Arduino emulator with visual simulator and code editor.

Features

  • Monaco Code Editor - Full VSCode-like Arduino code editing experience
  • Dynamic Component System - 48+ wokwi-elements components with search and categories
  • Visual Simulator Canvas - Interactive drag-and-drop circuit builder
  • Component Property Dialog - Single-click component interaction (rotate, delete, view pins)
  • Segment-Based Wire Editing - Drag wire segments perpendicular to orientation (like Wokwi)
  • Real AVR8 Emulation - Actual ATmega328p emulation using avr8js
  • Pin Management - Automatic pin mapping and state synchronization
  • Grid Snapping - 20px grid alignment for clean circuit layouts

Tech Stack

  • React 18 - UI framework
  • TypeScript - Static typing
  • Vite 5 - Build tool and dev server
  • Monaco Editor - Code editor (VSCode engine)
  • Zustand - State management
  • Axios - HTTP client for backend API
  • avr8js - AVR8 CPU emulator (local clone)
  • @wokwi/elements - Electronic web components (local clone)

Development

Prerequisites

Install Dependencies

npm install

Run Development Server

npm run dev

The app will be available at http://localhost:5173

Build for Production

npm run build

Output will be in the dist/ directory.

Lint

npm run lint

Project Structure

frontend/
├── src/
│   ├── components/
│   │   ├── components-wokwi/     # React wrappers for wokwi-elements
│   │   ├── editor/               # Monaco Editor components
│   │   │   ├── CodeEditor.tsx
│   │   │   └── EditorToolbar.tsx
│   │   └── simulator/            # Simulation canvas components
│   │       ├── SimulatorCanvas.tsx
│   │       ├── WireLayer.tsx
│   │       ├── WireRenderer.tsx
│   │       ├── PinOverlay.tsx
│   │       ├── ComponentPropertyDialog.tsx
│   │       ├── ComponentPickerModal.tsx
│   │       └── ComponentPalette.tsx
│   ├── simulation/
│   │   ├── AVRSimulator.ts       # AVR8 CPU wrapper
│   │   └── PinManager.ts         # Pin mapping and callbacks
│   ├── store/
│   │   ├── useEditorStore.ts     # Code editor state
│   │   └── useSimulatorStore.ts  # Simulation state
│   ├── services/
│   │   ├── api.ts                # Backend API client
│   │   └── ComponentRegistry.ts  # Component metadata
│   ├── types/                    # TypeScript definitions
│   ├── utils/
│   │   ├── hexParser.ts          # Intel HEX parser
│   │   ├── wirePathGenerator.ts  # Wire SVG path generation
│   │   └── wireSegments.ts       # Segment-based wire editing
│   ├── App.tsx                   # Main app component
│   └── main.tsx                  # Entry point
├── public/                       # Static assets
├── vite.config.ts               # Vite configuration
└── package.json

Key Architecture Patterns

State Management (Zustand)

Two main stores:

  • useEditorStore - Code content, theme, compilation state
  • useSimulatorStore - Simulation running state, components, wires, compiled hex

Local Wokwi Libraries

Vite aliases point to local clones instead of npm packages:

resolve: {
  alias: {
    'avr8js': path.resolve(__dirname, '../wokwi-libs/avr8js/dist/esm'),
    '@wokwi/elements': path.resolve(__dirname, '../wokwi-libs/wokwi-elements/dist/esm'),
  },
}

AVR Simulation Loop

  • Runs at ~60 FPS using requestAnimationFrame
  • Executes ~267,000 CPU cycles per frame (16MHz / 60fps)
  • Port listeners fire when GPIO registers change
  • PinManager routes pin states to component callbacks

Component System

Components are Web Components from wokwi-elements:

  1. React wrappers in components-wokwi/
  2. Dynamic loading via ComponentRegistry
  3. Pin info extracted from component metadata
  4. State updates via refs and callbacks

Wire Editing System

Segment-based editing (like Wokwi):

  • Wires consist of orthogonal segments (horizontal/vertical)
  • Drag segments perpendicular to orientation:
    • Horizontal segments: move up/down (ns-resize)
    • Vertical segments: move left/right (ew-resize)
  • Local preview state during drag (requestAnimationFrame)
  • Store update only on mouse up with grid snapping (20px)

Performance Optimizations

  • requestAnimationFrame for smooth wire dragging
  • Local state for real-time previews
  • Memoized path generation and segment computation
  • Store updates batched at interaction completion

API Integration

Backend endpoints (http://localhost:8001):

  • POST /api/compile - Compile Arduino code to .hex
  • GET /api/compile/status/{task_id} - Check compilation status
  • GET /api/compile/download/{filename} - Download compiled .hex

See backend documentation for API details.

Component Development

Adding a New Component Type

  1. Check if wokwi-elements has the component:

    ls ../wokwi-libs/wokwi-elements/src/
    
  2. Create React wrapper in src/components/components-wokwi/:

    import React, { useRef, useEffect } from 'react';
    
    export const WokwiMyComponent: React.FC<Props> = ({ ... }) => {
      const elementRef = useRef<any>(null);
    
      useEffect(() => {
        if (elementRef.current) {
          elementRef.current.setAttribute('prop', value);
        }
      }, [value]);
    
      return <wokwi-my-component ref={elementRef} />;
    };
    
  3. Add to ComponentRegistry metadata

  4. Use in SimulatorCanvas or make available in ComponentPalette

Troubleshooting

Monaco Editor Not Loading

  • Check if monaco-editor is installed
  • Verify Vite worker configuration in vite.config.ts

Components Not Rendering

  • Ensure wokwi-elements is built: cd ../wokwi-libs/wokwi-elements && npm run build
  • Check browser console for Web Component registration errors
  • Verify Vite alias paths in vite.config.ts

Wire Editing Performance Issues

  • Ensure requestAnimationFrame is being used
  • Check that store updates only happen on mouse up, not during drag
  • Verify no unnecessary re-renders with React DevTools

Pin Alignment Issues

  • Pin coordinates from wokwi-elements are in CSS pixels
  • Do NOT multiply by MM_TO_PX conversion factor
  • Verify component position + pin offset calculation

Compilation Fails

  • Check backend is running at http://localhost:8001
  • Verify arduino-cli is installed and arduino:avr core is available
  • Check CORS configuration in backend

References