Clarified that testdrive-jsui is a JavaScript library with optional backend adapters, not a Python package with JavaScript assets. Added ARCHITECTURE.md: - Core principle: JavaScript provides all functionality - Python/Ruby/Java are integration adapters only - Clear layer separation: JS library vs language adapters - Distribution models: CDN, npm, with adapters - Anti-patterns to avoid - Success metrics Added JS_FIRST_REFACTORING.md: - Phase 1: Create standalone JavaScript bundle - Phase 2: Refactor Python as thin adapter - Phase 3: Build and distribution - Concrete implementation steps with code examples - Timeline: 2-4 days of focused work Key Changes in Approach: - JavaScript does ALL rendering (using marked.js) - Backend adapters only serve assets and pass config - No HTML generation in Python/Ruby/Java - Library works completely standalone in browser This establishes foundation for true language-agnostic design. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
11 KiB
TestDrive-JSUI Architecture
Last Updated: 2025-12-16 Status: Refactoring to JavaScript-first architecture
🎯 Core Principle
TestDrive-JSUI is a JavaScript library, not a Python package.
The JavaScript code provides all functionality. Python, Ruby, Java, or other language bindings are integration adapters that help serve, configure, and test the JavaScript library - they do not provide core functionality.
📐 Architectural Layers
Layer 1: Core JavaScript Library (Functionality)
Location: /js/
Purpose: Complete standalone JavaScript UI framework
Dependencies: Only marked.js (markdown parsing)
Language: Pure JavaScript (ES6+)
js/
├── testdrive-jsui.js # Main library bundle (future)
├── core/ # Core systems
│ ├── debug-system.js # Debug infrastructure
│ └── section-manager.js # Document section management
├── components/ # UI components
│ ├── dom-renderer.js # DOM rendering engine
│ ├── debug-panel.js # Debug UI
│ └── document-controls.js # Document control UI
├── controls/ # Interactive control panels
│ ├── control-base.js # Base control class
│ ├── edit-control.js # Edit mode controls
│ ├── debug-control.js # Debug controls
│ ├── status-control.js # Status indicator
│ └── contents-control.js # Table of contents
├── widgets/ # Reusable UI widgets
├── plugins/ # Extension system
└── utils/ # Shared utilities
Key Characteristics:
- ✅ Works standalone in any browser
- ✅ No backend required (can load from file://)
- ✅ Self-contained markdown rendering
- ✅ All UI logic in JavaScript
- ✅ Configuration via JSON
Standalone Usage:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="testdrive-jsui.css">
</head>
<body>
<div id="content"></div>
<!-- Dependencies -->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<!-- TestDrive-JSUI -->
<script src="testdrive-jsui.js"></script>
<script>
// Initialize with configuration
const ui = new TestDriveJSUI({
container: '#content',
mode: 'edit',
markdown: '# Hello World\n\nEdit me!',
theme: 'github'
});
</script>
</body>
</html>
Layer 2: Language Adapters (Integration)
Purpose: Integration helpers for different backend languages Function: Serve assets, provide testing, backend integration NOT: Core functionality implementation
Python Adapter
Location: /src/testdrive_jsui/ (optional, for Python projects)
Purpose: Python project integration
# Python is just a helper to serve/test the JS library
from testdrive_jsui import TestDriveJSUIAdapter
adapter = TestDriveJSUIAdapter()
# Adapter helps with:
# 1. Asset serving
assets = adapter.get_asset_urls()
# 2. HTML template generation
html = adapter.generate_html(
markdown="# Content",
mode="edit",
config={...}
)
# 3. Testing JavaScript
test_result = adapter.run_js_tests()
Python Adapter Responsibilities:
- ✅ Asset path resolution
- ✅ HTML template generation
- ✅ Configuration serialization (Python dict → JSON)
- ✅ JavaScript test runner integration (pytest ↔ Jest)
- ✅ Development server (optional)
- ❌ NOT markdown rendering (JS does this)
- ❌ NOT UI logic (JS does this)
- ❌ NOT content transformation (JS does this)
Ruby Adapter (Future)
# Similar concept for Ruby/Rails projects
adapter = TestDriveJSUI::Adapter.new
# Generate view helper
<%= testdrive_jsui_editor(
markdown: @document.content,
mode: :edit
) %>
Java Adapter (Future)
// Similar concept for Java/Spring projects
TestDriveJSUIAdapter adapter = new TestDriveJSUIAdapter();
String html = adapter.generateHtml(markdown, "edit", config);
🔄 Data Flow
Standalone Mode (No Backend)
1. Browser loads HTML
2. HTML includes testdrive-jsui.js
3. JS initializes with config
4. JS fetches/parses markdown → marked.js
5. JS renders UI → DOM
6. User interacts → JS handles everything
7. Save via JS (localStorage, download, etc.)
With Backend Adapter (Python/Ruby/Java)
1. Backend serves HTML template
2. Backend injects config JSON
3. Backend includes JS/CSS assets
4. Browser runs JavaScript (same as standalone)
5. JS may call backend APIs for save/load
Key Point: Backend is optional and only for convenience!
🎨 Current vs Target Architecture
Current (Hybrid - Needs Refactoring)
❌ Python generates HTML structure
❌ Python does markdown fallback rendering
❌ JavaScript enhances the Python-generated HTML
❌ Tight coupling between Python and JavaScript
Target (Clean Separation)
✅ JavaScript is the complete UI library
✅ JavaScript handles all rendering (markdown → HTML → DOM)
✅ Python/Ruby/Java are thin adapters
✅ Zero coupling - JS works without any backend
📦 Distribution Models
Model 1: CDN (Simplest)
<!-- Use directly from CDN -->
<script src="https://cdn.jsdelivr.net/npm/testdrive-jsui@1.0.0/dist/testdrive-jsui.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/testdrive-jsui@1.0.0/dist/testdrive-jsui.min.css">
Model 2: npm Package
npm install testdrive-jsui
import TestDriveJSUI from 'testdrive-jsui';
Model 3: With Language Adapter
# Python projects
pip install testdrive-jsui-python
# Ruby projects
gem install testdrive-jsui
# Java projects
maven: com.testdrive:testdrive-jsui-java
Important: Language adapters are separate packages that bundle/reference the core JS library.
🧪 Testing Architecture
JavaScript Tests (Core)
Framework: Jest with jsdom
Location: /js/tests/
What: Tests the JavaScript library itself
describe('TestDriveJSUI', () => {
test('renders markdown to HTML', () => {
const ui = new TestDriveJSUI({...});
expect(ui.render('# Hello')).toContain('<h1>');
});
});
Python Integration Tests (Adapter)
Framework: pytest
Location: /tests/ (in Python adapter)
What: Tests Python ↔ JavaScript integration
def test_python_adapter_runs_js_tests():
adapter = TestDriveJSUIAdapter()
result = adapter.run_js_tests()
assert result.success
Key: Python tests verify the adapter works, not the JS functionality!
🔧 Configuration System
JavaScript Configuration (Core)
{
// Core JS library config
"mode": "edit", // 'edit' | 'view'
"theme": "github", // CSS theme
"markdown": "# Content", // Initial content
"autosave": false, // Auto-save behavior
"shortcuts": true, // Keyboard shortcuts
"sections": true, // Section management
"debug": false // Debug mode
}
Adapter Configuration (Language-specific)
# Python adapter config (separate from JS)
{
"asset_base_url": "/static", # Where to serve JS/CSS
"development_mode": True, # Dev vs production
"template_path": "...", # HTML template location
}
Separation: JS config controls the library, adapter config controls integration.
🎯 Migration Path
Phase 1: Improve Current Structure ✅ (Starting)
- ✅ Document architecture (this file)
- ⏸️ Rename Python code to clearly show it's an adapter
- ⏸️ Ensure JS can work standalone
- ⏸️ Separate JS config from adapter config
Phase 2: Pure JavaScript Rendering
- ⏸️ Move all markdown rendering to JavaScript (use marked.js)
- ⏸️ Remove Python HTML generation
- ⏸️ Make Python adapter purely serve assets + config
- ⏸️ Create standalone HTML example
Phase 3: Proper Distribution
- ⏸️ Bundle JavaScript library (
testdrive-jsui.js) - ⏸️ Publish to npm
- ⏸️ Publish to CDN
- ⏸️ Separate Python adapter package
Phase 4: Additional Adapters
- ⏸️ Ruby adapter
- ⏸️ Java adapter
- ⏸️ PHP adapter (if needed)
📚 Documentation Structure
docs/
├── javascript/ # Core JS library docs
│ ├── getting-started.md # Standalone usage
│ ├── api-reference.md # JavaScript API
│ ├── configuration.md # JS config options
│ └── examples/ # Pure JS examples
├── adapters/ # Language adapter docs
│ ├── python/
│ │ ├── installation.md
│ │ ├── django-integration.md
│ │ └── flask-integration.md
│ ├── ruby/
│ │ └── rails-integration.md
│ └── java/
│ └── spring-integration.md
└── architecture/
└── ARCHITECTURE.md # This file
🔑 Key Principles
- JavaScript First: All functionality in JavaScript
- Backend Optional: Works without any backend
- Adapters Not Implementations: Language bindings help integrate, don't implement
- Clear Boundaries: JS does UI, backend does serving/storage
- Language Agnostic: Core library works with any backend
- Zero Lock-in: Use testdrive-jsui without any specific backend framework
🚫 Anti-Patterns to Avoid
❌ Don't: Implement UI logic in Python/Ruby/Java ✅ Do: Implement UI logic in JavaScript
❌ Don't: Render markdown in backend ✅ Do: Render markdown in JavaScript (marked.js)
❌ Don't: Generate HTML structure in backend ✅ Do: Generate HTML structure in JavaScript
❌ Don't: Make JavaScript depend on backend APIs ✅ Do: Make JavaScript work standalone, optionally call APIs
❌ Don't: Create language-specific forks ✅ Do: Create thin adapters around single JS library
📈 Success Metrics
- Can use testdrive-jsui with pure HTML file (no backend)
- Can use testdrive-jsui with Python/Flask
- Can use testdrive-jsui with Ruby/Rails
- Can use testdrive-jsui with Java/Spring
- JavaScript library < 100KB minified
- Zero runtime dependencies except marked.js
- Works in all modern browsers
- Published to npm and CDN
🤝 Contributing
When contributing:
- Core functionality → JavaScript
- Integration helpers → Language adapters
- Keep adapters thin and similar across languages
- Test JavaScript with Jest
- Test adapters with language-native tools (pytest, rspec, junit)
Remember: TestDrive-JSUI is a JavaScript library with optional backend adapters, not a backend framework with JavaScript assets!