6.5 KiB
YAZE Web Runtime Refactoring & Optimization Plan
Date: November 25, 2025
Target Component: src/web (WASM Runtime & UI Layer)
Status: Draft
1. Executive Summary
The YAZE web runtime is a sophisticated application bridging C++ (via Emscripten) with modern Web APIs. It features advanced capabilities like PWA support, touch gestures, and a DOM-mirroring system for AI agents.
However, the current codebase suffers from initialization fragility (reliance on setInterval polling) and architectural coupling (massive inline scripts in shell.html, duplicate logic modules). This plan outlines the steps to stabilize the startup sequence, modularize the UI logic, and consolidate redundant features.
2. Current State Analysis
2.1. Strengths
- Namespace Architecture:
src/web/core/namespace.jsprovides a solid foundation for organizing globals. - Agent Readiness: The
widget_overlay.jsandagent_automation.jscomponents are forward-thinking, enabling DOM-based agents to "see" the canvas. - Performance: Excellent implementation of Service Workers (
stale-while-revalidate) and AudioWorklets.
2.2. Critical Issues
- Initialization Race Conditions: Components like
FilesystemManagerandterminal.jspoll forModulereadiness usingsetInterval. This is non-deterministic and wastes cycles. shell.htmlBloat: The main HTML file contains ~500 lines of inline JavaScript handling UI settings, menus, and AI tools. This creates circular dependencies (Terminal depends on Shell) and violates CSP best practices.- Logic Duplication:
- Collaboration:
collab_console.js(JS WebSocket) vscollaboration_ui.js(C++ Bindings). - Drag & Drop:
drop_zone.js(JS Implementation) vsWasmDropHandler(C++ Implementation).
- Collaboration:
- Global Namespace Pollution: Despite having
window.yaze, many components still attach directly towindowor rely on Emscripten's globalModule.
3. Improvement Plan
Phase 1: Stabilization (Initialization Architecture)
Goal: Replace polling with a deterministic Event/Promise chain.
- Centralize Boot Sequence:
- Modify
src/web/core/namespace.jsto expose ayaze.core.boot()Promise. - Refactor
app.jsto resolve this Promise only whenModule.onRuntimeInitializedfires.
- Modify
- Refactor Dependent Components:
- Update
FilesystemManagerto awaityaze.core.boot()instead of polling. - Update
terminal.jsto listen for theyaze:readyevent instead of checkingisModuleReadyvia interval.
- Update
Phase 2: Decoupling (Shell Extraction)
Goal: Remove inline JavaScript from shell.html.
- Extract UI Controller:
- Create
src/web/core/ui_controller.js. - Move Settings modal logic, Theme switching, and Layout toggling from
shell.htmlto this new file.
- Create
- Relocate AI Tools:
- Move the
aiToolsobject definitions fromshell.htmltosrc/web/core/agent_automation.js. - Ensure
terminal.jsreferenceswindow.yaze.aiinstead of the globalaiTools.
- Move the
- Clean
shell.html:- Replace inline
onclickhandlers with event listeners attached inui_controller.js.
- Replace inline
Phase 3: Consolidation (Redundancy Removal)
Goal: Establish "Single Sources of Truth".
- Collaboration Unification:
- Designate
components/collaboration_ui.js(C++ Bindings) as the primary implementation. - Deprecate
collab_console.jsor repurpose it strictly as a UI view for the C++ backend, removing its direct WebSocket networking code.
- Designate
- Drop Zone Cleanup:
- Modify
drop_zone.jsto act purely as a visual overlay. - Pass drop events directly to the C++
WasmDropHandlerviaModule.ccall, removing the JS-side file parsing logic unless it serves as a specific fallback.
- Modify
4. Technical Implementation Steps
Step 4.1: Create UI Controller
File: src/web/core/ui_controller.js
(function() {
'use strict';
window.yaze.ui.controller = {
init: function() {
this.bindEvents();
this.loadSettings();
},
bindEvents: function() {
// Move event listeners here
document.getElementById('settings-btn').addEventListener('click', this.showSettings);
// ...
},
// Move settings logic here
showSettings: function() { ... }
};
// Auto-init on DOM ready
document.addEventListener('DOMContentLoaded', () => window.yaze.ui.controller.init());
})();
Step 4.2: Refactor Initialization (Namespace)
File: src/web/core/namespace.js
Add a boot promise mechanism:
window.yaze.core.bootPromise = new Promise((resolve) => {
window.yaze._resolveBoot = resolve;
});
window.yaze.core.ready = function() {
return window.yaze.core.bootPromise;
};
File: src/web/app.js
Trigger the boot:
Module.onRuntimeInitialized = function() {
// ... existing initialization ...
window.yaze._resolveBoot(Module);
window.yaze.events.emit('ready', Module);
};
Step 4.3: Clean Shell HTML
Remove the <script> block at the bottom of src/web/shell.html and replace it with:
<script src="core/ui_controller.js"></script>
5. Verification Strategy
-
Startup Test:
- Load the page with Network throttling (Slow 3G).
- Verify no errors appear in the console regarding "Module not defined" or "FS not ready".
- Confirm
FilesystemManagerinitializes without retries.
-
Feature Test:
- Open "Settings" modal (verifies
ui_controller.jsmigration). - Type
/ai app-statein the terminal (verifiesaiToolsmigration). - Drag and drop a ROM file (verifies Drop Zone integration).
- Open "Settings" modal (verifies
-
Agent Test:
- Execute
window.yaze.gui.discover()in the console. - Verify it returns the JSON tree of ImGui widgets.
- Execute
6. Action Checklist
- Create
src/web/core/ui_controller.js. - Refactor
src/web/core/namespace.jsto include boot Promise. - Modify
src/web/app.jsto resolve boot Promise on init. - Move
aiToolsfromshell.htmltosrc/web/core/agent_automation.js. - Move Settings/UI logic from
shell.htmltosrc/web/core/ui_controller.js. - Clean
src/web/shell.html(remove inline scripts). - Refactor
src/web/core/filesystem_manager.jsto await boot Promise. - Update
src/web/pwa/service-worker.jsto cache newui_controller.js.