AVL Tree Car Front is a vanilla JavaScript single-page application organized around a lightweight MVC pattern. All source code lives underDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/tutosrive/avl_tree_car_front/llms.txt
Use this file to discover all available pages before exploring further.
src/app/, which is split into purpose-specific folders. On every page load the application re-initializes its front-end state from scratch, connects to the Python backend over Socket.IO, and hands off tree-management responsibility entirely to the server.
Module layout
Thesrc/app/ directory is divided into six folders, each with a single, well-scoped responsibility:
| Folder | Role |
|---|---|
controllers/ | Orchestrate user interaction, mount HTML fragments, and coordinate between models and services. Each controller owns one “screen” or feature area. |
models/ | Plain ES-module classes that represent domain objects (AVL, Road, Obstacle, Node). They hold state and expose methods, but contain no DOM or network logic. |
services/ | Wrap external I/O. SocketService owns the Socket.IO connection; TreeService extends it with every event the app emits or receives. |
interfaces/ | Declare the shape of each model through base classes (ObstacleI, RoadI, NodeI). Models extend these to enforce a consistent property contract. |
components/ | Small, reusable HTML-rendering functions and UI widgets (menus, the tree renderer, the road game canvas). |
utils/ | Third-party vendored libraries (bootstrap, popper, socket-io) plus project-specific helpers (carlos-cuesta/, own/). |
There is no bundler or build step. The browser loads
main.mjs directly as a native ES module, so every import resolves at runtime via the file system.Initialization flow
When the browser firesDOMContentLoaded, main.mjs calls App.init(). The static method works through four synchronous or asynchronous phases before the user can interact with anything:
App.#uitlsReferences() attaches third-party helpers to window so every module can access them without explicit imports:
App.#globalVariables() makes two async calls:
- Loads
configs.jsonand stores it aswindow.configs. Setswindow.URLAPIfromconfigs.urlAPI. - Fetches
GET ${URLAPI}/data/json/obstacles_types.jsonand stores thedataarray aswindow.OBSTACLES_TYPES. This list powers theObstacle.format_values()lookup used throughout the app.
HomeController instance is created and its init() method is awaited. This mounts the main navigation HTML inside <main> and registers all button listeners.
Global window variables summary
| Variable | Type | Description |
|---|---|---|
window.configs | Object | Parsed configs.json (contains urlAPI, urlSOCKET) |
window.URLAPI | String | Base REST API URL, e.g. http://127.0.0.1:4500 |
window.OBSTACLES_TYPES | Array | List of {id, type} obstacle-type descriptors |
window.SOUND_ON | Boolean | Global sound toggle flag |
window.Helpers | Object | Utility functions (fetchJSON, fetchText, okForm, …) |
window.icons | Object | SVG icon strings keyed by name |
window.Toast | Class | Toast notification helper |
window.Modal | Class | Dialog/popup builder (Popup) |
window.Customs | Module | Shared CSS class strings and toast shortcuts |
window.Popper | Module | Popper.js (positioning engine for Bootstrap) |
Controller hierarchy
HomeController is the root of the controller tree. It is instantiated once by App.init() and never destroyed. All other controllers are created lazily — only when the user clicks the corresponding button — and cached in this.controllers:
HomeController guards each instantiation with an if (!this.controllers.X) check to prevent duplicate instances and avoid wiping existing road/tree state:
RoadController receives a reference to the shared TreeService instance created in HomeController. AVLController creates its own internal TreeService instance (this.service = new TreeService()) in its constructor, so it has a separate socket connection dedicated to AVL tree operations.
SPA navigation
There are no URL changes or<a href> navigations. Every “screen” is swapped by replacing or prepending HTML inside <main>:
HomeController.#loadHML()setsthis.containerMain.innerHTML = htmlto mount the toolbar.AVLController.__loadHTML()callsmain.insertAdjacentHTML('afterbegin', html)to prepend the SVG container, checking first that#tree-renderdoes not already exist.WatchRoadsController.__cleanMain()setsthis.main.innerHTML = htmlto replace the entire main area with the traversal view.
WatchRoadsController.__callRenderTree() re-initializes the AVLController (calling avlCtrl.init()) to re-attach the avl_tree_balanced listener and re-query the SVG containers.
State reset
Every browser reload resets all front-end state to zero: theRoad, AVL, and Obstacle model instances are garbage-collected and re-created fresh. The Python backend, however, retains its in-memory AVL tree across reloads.
To keep them in sync, HomeController.init() immediately calls this.treeService.emit_reset_avl() before loading the home HTML. This tells the backend to discard its current tree so that the front end and back end both start from an empty state: