Aaron SinclairandClaude ea7dadc5ae Implement self-hosted debug console and @external decorator
This commit completes the self-hosting of Ritz's debug console and
introduces the @external decorator for elegant JavaScript bridge functions.

## Major Features

### 1. Self-Hosted Debug Console (DebugConsole.py)
- Entire debug console UI written in Ritz itself
- Signal-based state management for toggle functionality
- Displays runtime stats (memory, signals, DOM nodes, logs)
- Live reactive updates when signals change in main app
- Keyboard shortcut support (Ctrl+`)

### 2. @external Decorator for JavaScript Bridges
- Pythonic decorator syntax: @external or @bridge
- Parser automatically recognizes and tracks external functions
- Codegen emits proper LLVM declarations
- No more hacky string checks (startswith("js_"))
- Clean, declarative bridge function definitions

Example:
```python
@external
def js_toggle_debug_console():
    pass

def toggle():
    js_toggle_debug_console()  # Clean call to JS bridge
```

### 3. Enhanced RitzLoader Debug Mode
- `new RitzLoader({ debug: true })` auto-loads DebugConsole.wasm
- Keyboard shortcut registration (Ctrl+` toggle)
- Runtime stats injection (memory, signals, DOM nodes)
- Automatic status element hiding when debug enabled
- Debug console isolated in separate WASM runtime

## Bug Fixes

- Fixed reactive text node scoping (prevent global name collisions)
- Fixed CSS specificity for debug console status (use #ritz-debug)
- Fixed signal cross-contamination between runtimes (scope to rootElement)
- Fixed parser to handle expression statements in function bodies
- Fixed conditional branch rendering (append children to wrapper divs)

## Infrastructure Improvements

- Added H4 and Pre elements to syntax.py
- Parser handles @external decorator on top-level functions
- Codegen pre-collects external functions before emitting declarations
- Runtime scopes querySelector to prevent cross-runtime interference
- Debug stats update reactively on every signal change

## Files Added/Modified

New files:
- examples/runtime/DebugConsole.py - Self-hosted debug UI
- examples/runtime/DebugConsole.wasm - Compiled debug console (1.8KB)
- PHASE4_CLEANUP.md - Next phase planning document

Modified:
- ritz/parser.py - @external decorator support
- ritz/llvm_codegen_signals.py - External function handling
- ritz/syntax.py - Added external/bridge decorators, H4, Pre
- examples/runtime/ritz-runtime.js - Debug mode, stats updates
- examples/runtime/styles.css - Merged debug styles
- examples/template.html - Debug mode enabled by default
- examples/highfive/HighFive.html - Simplified using template

## Known Issues (Addressed in PHASE4_CLEANUP.md)

1. Debug console shifts page RIGHT (should shift LEFT)
2. Toggle implementation un-Ritzy (calls JS to manipulate DOM)
   - Should use reactive class binding + @event decorator
   - Needs event object bridge for keyboard events
3. Missing test infrastructure

## Next Steps (Phase 4)

See PHASE4_CLEANUP.md for detailed plan:
- Implement reactive class binding (signal-driven classes)
- Add @event decorator for declarative event registration
- Build event object bridge (access event.key, event.ctrlKey)
- Create Python test mode (execute without browser)
- Add comprehensive test suite
- Update all examples to use new patterns

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-15 18:28:24 -08:00
2025-11-15 08:07:09 +00:00
2025-11-15 08:07:09 +00:00
2025-11-15 08:07:09 +00:00
2025-11-15 08:07:09 +00:00
2025-11-15 08:07:09 +00:00

Ritz Framework

A WebAssembly UI framework with Python-like syntax that compiles to high-performance WASM while remaining executable in Python for debugging.

Core Innovations

1. Python's AST Module for Parsing

No need for a custom parser! Since our components are valid Python, we use Python's own ast module to parse them. Zero parsing overhead, perfect compatibility, error messages for free.

2. Debug Python in WASM (Not JavaScript!)

Set breakpoints in Python source code, step through Python lines, inspect Python variables - all in the browser! We compile with DWARF debug symbols and source maps that map WASM → Python source.

3. Progressive Module Loading

Split apps into multiple WASM modules:

  • bootstrap.wasm (50KB) - Login only, no business logic
  • app-core.wasm (200KB) - Main app, requires auth
  • Feature modules - Lazy loaded on demand
  • Security: Unauthenticated users never receive app code!

4. Python Executable, WASM Compilable

Write components in actual Python that can run in CPython for debugging, but compile to WebAssembly for production with:

  • No virtual DOM overhead
  • Direct signal-to-DOM updates
  • 99% fewer mutations than React
  • Sub-200KB bundle sizes

Quick Start

Try the Python Prototype

# Run the example
python3 example.py

# Run tests
python3 test.py

Component Syntax

@component
def Counter():
    count = signal(0)
    
    def increment():
        count += 1
    
    with Div(class_='counter'):
        yield H1('Counter App')
        yield P(f'Count: {count}')
        yield Button('Click me', onclick=increment)

Key Features

  1. Yield-based composition - Natural Python generators for building component trees
  2. Context managers - Use with statements for nested structures
  3. Reactive signals - Fine-grained reactivity without virtual DOM
  4. Mixed content - Yield strings, components, or elements seamlessly

Files

  • RESEARCH.md - Complete technical architecture and implementation plan
  • framework.py - Python prototype implementation
  • example.py - Example components demonstrating the syntax
  • test.py - Simple test file
  • ast_parser.py - Parse components using Python's ast module!
  • debug_concept.py - Revolutionary Python-in-WASM debugging
  • module_system.py - Progressive loading & security architecture
  • compiler.py - Complete compilation pipeline concept

Architecture

The framework works in two modes:

  1. Debug Mode (Current): Runs in Python interpreter, generates HTML/IR
  2. Production Mode (TODO): Compiles to WebAssembly with LLVM

Compilation Pipeline

Python-like syntax → Parser (AST) → LLVM IR → WebAssembly → Browser

Reactive Runtime

  • Signals store values + subscriber lists in WASM memory
  • Effects track dependencies automatically
  • Direct signal-to-DOM-node mapping (no diffing)
  • Batched DOM operations across WASM/JS bridge

Next Steps

  1. ✅ Python prototype with working components
  2. ⬜ Parser for Python subset (yields, functions, decorators)
  3. ⬜ LLVM backend for WASM generation
  4. ⬜ Reactive runtime in C/Rust
  5. ⬜ DOM operation batching and JS bridge
  6. ⬜ Benchmarks against React/SolidJS

Performance Targets

Based on SolidJS and Leptos research:

  • Bundle size: < 200KB compressed
  • Startup time: < 500ms on slow 3G
  • Update performance: Within 10% of vanilla JS
  • Memory usage: 70% less than React

Why This Approach?

  1. Developer happiness - Write Python, debug Python, ship WASM
  2. Performance - Compile-time optimization, no virtual DOM
  3. Simplicity - Yield syntax is intuitive and composable
  4. Type safety - Static typing at compile time

Start with example.py to see the syntax in action!

S
Description
No description provided
Readme
4 MiB
0 Stars 1 Watchers 0 Forks
Languages
Python 100%