Software Architecture — Component Dependencies
Version : v0.18-dev Authors : O. Cugnon de Sévricourt, C. Cugnon de Sévricourt
1. Overview
Note — This document describes the current (v0.18) module structure, where consumers import engine internals directly. ADR-036 proposes an
engine.jsfacade as the single public entry point for v0.21+, which will simplify the dependency graph significantly.
Caméléon is structured in four layers, each with a clear responsibility boundary. Dependencies flow strictly downward — no circular imports exist.
2. Layers
| Layer | Directory | Responsibility |
|---|---|---|
| Editor | editor/ | Visual UI — HTML shell, SVG rendering, DOM interaction, user events |
| Engine | engine/ | Pure CVM runtime — Petri net state machine, no DOM dependency |
| Libs | engine/libs/ | Standard libraries — operator definitions, type registry, control registry |
| Compositions | compositions/ | Topology files — pure data (nodes + connections), no logic |
3. Components
3.1 Editor Layer
cameleon.html
Application shell. Contains HTML structure, CSS styles, and a single <script type="module"> that imports renderer.js and binds its exports to window.
No logic — pure structure and presentation.
Imports : renderer.js
renderer.js
UI orchestrator. Handles all visual concerns :
- SVG graph rendering (operators, connections, plugs, badges)
- DOM panel management (catalogue, inspector, config editor, CVM log)
- CVM state synchronization and visualization
- User interaction (drag, zoom, pan, keyboard shortcuts)
- Composition persistence (localStorage)
Imports : - engine/cvm.js — createCVM, instantiate - engine/libs/std-types.js — typeColor, TYPE_REGISTRY, isCompatible - engine/libs/std-controls.js — registry, editors, MessageReviewControl, LiveInputControl - engine/libs/std-io-lib.js — meta, Source, Sink, FileLoader, FileSaver - engine/libs/std-struct-lib.js — meta, Fork, Join, Merge, Gate, Barrier - engine/libs/std-data-lib.js — meta, Transform, Format, JSONParse, JSONStringify, Template - engine/libs/std-human-lib.js — meta, MessageReviewer, resolveHuman - engine/libs/std-live-lib.js — meta, LiveSource, resolveLive - compositions/demo-pipeline.cm.js — default composition
3.2 Engine Layer
cvm.js
Pure CVM engine — the Petri net virtual machine. Stateless module exporting a factory function. No DOM, no SVG — importable in Deno, Node, or browser.
Exports : createCVM(ops, conns), instantiate(composition)
Imports : libs/std-types.js — isCompatible (for connection validation)
Public API (via createCVM) : - Firing : canFire(opId), fireable(), step(opId), execStep(opId) - Control : cancel(), resetCompleted() - Topology : addOp(op), addConn(conn), removeOp(opId), removeConn(connId) - Observation : observe(connId), currentState(), stateAt(n), opState(opId) - History : undo(), jumpTo(n), cursor, historyLength, historyLabels - Reset : reset()
operators-lib.js
Catalogue façade — re-exports all operators from their respective libraries. Provides a single import point for backward compatibility and for compositions.
Exports : all operators from std-io-lib, std-struct-lib, std-data-lib, std-human-lib, std-live-lib
Imports : all five operator libraries (re-export only, no logic)
3.3 Standard Libraries
All libraries are self-contained modules with no cross-dependencies. Each exports a meta object (library metadata) and its operator definitions.
| Module | Domain | Exports |
|---|---|---|
std-types.js | Type system | TYPE_REGISTRY, typeColor(), isCompatible(), registerType() |
std-controls.js | UI controls | Viewer/editor controls per type, registry, editors, registerControl() |
std-io-lib.js | I/O | Source, Sink, FileLoader, FileSaver |
std-struct-lib.js | Control flow | Fork, Join, Merge, Gate, Barrier |
std-data-lib.js | Data transforms | Transform, Format, JSONParse, JSONStringify, Template |
std-human-lib.js | Human interaction | MessageReviewer, resolveHuman() |
std-live-lib.js | Live interaction | LiveSource, resolveLive() |
Key property : operator libraries have zero imports. They are pure data + functions. This makes them trivially testable and portable.
3.4 Compositions
*.cm.js
Topology files — pure data describing a workflow graph. Each composition imports its operators (typically from operators-lib.js) and exports a default object with nodes and connections.
No logic, no side effects — a composition is a static description.
4. Dependency Rules
- Editor → Engine :
renderer.jsimportscvm.jsfor the execution runtime - Editor → Libs :
renderer.jsimports libraries directly (not via façade) for catalogue, types, and controls - Engine → Libs :
cvm.jsimports onlystd-types.js(forisCompatible) - Compositions → Libs :
.cm.jsfiles import operators fromoperators-lib.js(façade) - Libs → nothing : all standard libraries are leaf modules with zero dependencies
- No upward dependencies : engine never imports editor, libs never import engine
cameleon.html
│
└─▶ renderer.js
│
├─▶ cvm.js ──▶ std-types.js
│
├─▶ std-types.js
├─▶ std-controls.js
├─▶ std-io-lib.js
├─▶ std-struct-lib.js
├─▶ std-data-lib.js
├─▶ std-human-lib.js
├─▶ std-live-lib.js
│
└─▶ *.cm.js ──▶ operators-lib.js ──▶ all operator libs
5. Extension Points
| Extension | Mechanism | File |
|---|---|---|
| New operator | Add to existing library or create new *-lib.js | engine/libs/ |
| New data type | registerType(id, { color, label }) | std-types.js |
| New viewer | registerControl(type, control) | std-controls.js |
| New editor | registerEditor(type, control) | std-controls.js |
| Custom library | Create cst-*-lib.js following ODK conventions | engine/libs/ |
See odk/README.md for the complete Operator Development Kit guide.
6. Build Variants
| Variant | Entry | Dependencies |
|---|---|---|
| Development | editor/cameleon.html | ES modules — native browser imports |
| Standalone | _site/demo/cameleon.html | All JS inlined by tools/build-doc.py — single file, zero network |
| Tests (Deno) | engine/tests/*.test.js | Direct imports from engine/ — no editor dependency |
The standalone build strips import/export statements and concatenates all modules into a single <script> block, preserving dependency order.