Monorepo for Aesthetic.Computer aesthetic.computer
core reports javascript-mjs-mode-feasibility.md
8.4 kB

JavaScript/MJS Mode for kidlisp.com - Feasibility Report #

Executive Summary #

Building a JavaScript/MJS editing mode for kidlisp.com is highly feasible and can reuse 70-80% of existing code. The kidlisp.com editor already uses Monaco (the VS Code editor), which has excellent built-in JavaScript/TypeScript support. The main work involves:

  1. Language mode switching (KidLisp ↔ JavaScript)
  2. Piece lifecycle integration (boot, sim, paint, act)
  3. File save/load via aesthetic.computer APIs
  4. Module resolution for imports

Current kidlisp.com Stack Analysis #

Monaco Editor (v0.52.0) #

  • Already loaded: CDN from jsDelivr
  • KidLisp language: Custom registration with syntax highlighting, bracket matching
  • Built-in JS/TS support: Monaco has first-class JavaScript support including:
    • Full IntelliSense and autocompletion
    • Error checking (via TS compiler in web worker)
    • Hover documentation
    • Go to definition (within same file)
    • Refactoring tools

Reusable Components (~70-80%) #

Component Status Reuse Level
Monaco setup ✅ 90% - just add language toggle
Theme system (light/dark) ✅ 100% - works for any language
Keyboard shortcuts ✅ 95% - extend for JS-specific
Preview iframe ✅ 80% - needs piece loader
Play/Stop/Pause controls ✅ 90% - different execution model
Tab system (Learn/List) ✅ 70% - need JS docs
History/Recent ✅ 60% - different file format
Console output ✅ 100% - already logs JS errors
Auth (Auth0) ✅ 100% - same authentication
Mobile UI/responsive ✅ 100% - layout unchanged
URL routing ✅ 80% - different path scheme
Context menu ✅ 50% - need JS docs

New Components Needed #

Component Complexity Notes
Language switcher UI Low Tab or dropdown toggle
JS documentation Medium Can use TypeScript inference
Piece loader/runner Medium Load .mjs in iframe context
File save/load API Medium Save to user's disk storage
Module bundler High For imports like "../lib/..."
LSP integration (optional) High Full IDE experience

AC Piece Architecture Analysis #

Piece Lifecycle Functions #

Every AC piece exports these optional functions:

// 📦 Boot - Called once when piece loads
export function boot(api) {
  // api contains: wipe, resolution, store, params, colon, net, ...
}

// 🎨 Paint - Called every frame for rendering
export function paint(api) {
  // api contains: wipe, ink, line, box, circle, screen, ...
}

// 🧮 Sim - Called every frame for logic (before paint)
export function sim(api) {
  // api contains: num, store, sound, ...
}

// 🎬 Act - Called on user input events
export function act(api) {
  // api.event contains: { is, pointer, key, ... }
}

The API Object #

The api object provides 200+ functions. Key categories:

  • Drawing: wipe, ink, line, box, circle, plot, paste
  • Screen: resolution, screen.width, screen.height
  • Sound: sound.synth, sound.play, sound.sample
  • Input: pen, keyboard, gamepad
  • State: store, params, colon
  • Network: net.socket, net.udp
  • System: jump, alias, download

Module Imports #

Pieces can import from the AC library:

import { getNoteColorWithOctave } from "../lib/note-colors.mjs";
import { drawMiniControllerDiagram } from "../lib/gamepad-diagram.mjs";
import * as graph from "./lib/graph.mjs";

This is the main complexity - we need import resolution.


Implementation Approaches #

Option A: In-iframe Editing (Simpler) #

Use the aesthetic.computer iframe as both editor and runtime:

kidlisp.com
├── Monaco Editor (left)
├── Preview iframe: aesthetic.computer/{piece} (right)
    └── Live reload on code change

Pros:

  • Full AC runtime available
  • All imports work naturally
  • Real piece execution

Cons:

  • Slower feedback loop (full page reload)
  • Harder to show errors inline
  • Can't use AC's worker architecture

Option B: Sandboxed Execution (More Complex, Better UX) #

Run piece code in a controlled environment:

kidlisp.com
├── Monaco Editor (left)  
├── Canvas preview (right)
    ├── Minimal AC runtime
    ├── Import map for modules
    └── HMR-style updates

Pros:

  • Instant preview updates
  • Better error handling
  • Could work offline

Cons:

  • Need to bundle/mock AC runtime
  • Import resolution complexity
  • Subset of full functionality

Start with Option A for full compatibility, add Option B features incrementally:

  1. Phase 1: Monaco + iframe reload (1-2 weeks)
  2. Phase 2: Live preview for simple pieces (2-3 weeks)
  3. Phase 3: Full import resolution via importmap (3-4 weeks)

Shared Module Architecture #

To make this reusable, extract a shared editor module:

system/public/aesthetic.computer/
├── lib/
│   └── ac-editor/
│       ├── editor-core.mjs      # Monaco setup, themes
│       ├── language-kidlisp.mjs # KidLisp syntax
│       ├── language-js.mjs      # JS/piece syntax extras
│       ├── preview-runner.mjs   # Piece execution
│       ├── file-ops.mjs         # Save/load/history
│       └── documentation.mjs    # Docs for both languages

Usage:

// kidlisp.com
import { createEditor } from "/aesthetic.computer/lib/ac-editor/editor-core.mjs";
createEditor({ language: "kidlisp" });

// code.aesthetic.computer (future)
import { createEditor } from "/aesthetic.computer/lib/ac-editor/editor-core.mjs";
createEditor({ language: "javascript", pieceMode: true });

Technical Challenges #

1. Module Resolution #

Problem: Pieces use relative imports like "../lib/note-colors.mjs"

Solutions:

  • Import maps: Native browser feature for module aliasing
  • Service worker: Intercept module requests, rewrite URLs
  • Bundler: Use esbuild-wasm to bundle on-the-fly

2. Piece API Injection #

Problem: Pieces expect api parameter with 200+ functions

Solutions:

  • Build minimal runtime that provides drawing API
  • Proxy to full AC runtime in iframe
  • Use web workers for non-DOM operations

3. File Storage #

Problem: Where to save .mjs files?

Solutions:

  • User's handle storage: /api/user/{handle}/pieces/{name}.mjs
  • Local storage with cloud sync
  • GitHub integration (oauth)

4. Error Display #

Problem: JS errors happen at runtime, not parse time

Solutions:

  • Monaco's TypeScript checker catches many errors
  • Window.onerror capture in preview iframe
  • postMessage error events back to editor

Development Estimate #

Phase Work Time
Phase 1: Language toggle + basic editing 1 week
Phase 2: Preview iframe integration 1 week
Phase 3: File save/load API 1 week
Phase 4: JS documentation in Learn tab 1 week
Phase 5: Import resolution (importmaps) 2 weeks
Phase 6: Polish + testing 1 week
Total 8 weeks

For an MVP (edit + preview + save):

  • 3-4 weeks to functional editor
  • +4 weeks for full IDE experience

Recommendations #

  1. Start with language toggle: Add "KidLisp | JavaScript" tabs, let Monaco handle JS syntax natively.

  2. Reuse preview iframe: Point to aesthetic.computer/preview with posted source code. This leverages existing piece loader.

  3. Build import map generator: Analyze imports, generate browser importmap for AC libraries.

  4. Consider code.aesthetic.computer: A dedicated subdomain for the full IDE, separate from kidlisp.com's simpler focus.

  5. API documentation: Auto-generate from JSDoc in AC source files, similar to KIDLISP_DOCS.


Conclusion #

The kidlisp.com architecture is well-suited for JavaScript mode extension. Monaco already supports JS, the preview infrastructure exists, and the UI patterns are proven. The main complexity is module resolution for imports - recommend using browser import maps as the cleanest solution.

A working prototype could be built in 2-3 weeks, with full IDE features in 8 weeks.