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.js facade 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.

COMPONENT DEPENDENCIES — MODULE IMPORT GRAPH EDITOR ENGINE LIBS COMPOSITIONS cameleon.html Application shell — HTML + CSS Entry point — imports renderer.js renderer.js UI orchestrator — SVG rendering DOM, panels, state sync, events import * cvm.js Pure CVM engine — Petri net VM createCVM() · instantiate() operators-lib.js Catalogue façade — re-exports backward compatibility layer createCVM, instantiate std-types.js Type registry — ADR-028 typeColor · isCompatible std-controls.js Control registry — ADR-034 viewers · editors std-io-lib.js Source · Sink FileLoader · FileSaver std-struct-lib.js Fork · Join · Merge Gate · Barrier std-data-lib.js Transform · Format JSONParse · JSONStringify std-human-lib.js MessageReviewer resolveHuman() std-live-lib.js LiveSource resolveLive() isCompatible *.cm.js Topology files — pure data (nodes + connections) operator refs Legend Editor layer Engine (CVM core) Standard libraries Compositions Re-export (façade)
Fig. 21 — Component Dependencies — Module Import Graph

2. Layers

LayerDirectoryResponsibility
Editoreditor/Visual UI — HTML shell, SVG rendering, DOM interaction, user events
Engineengine/Pure CVM runtime — Petri net state machine, no DOM dependency
Libsengine/libs/Standard libraries — operator definitions, type registry, control registry
Compositionscompositions/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 :

Imports : - engine/cvm.jscreateCVM, instantiate - engine/libs/std-types.jstypeColor, TYPE_REGISTRY, isCompatible - engine/libs/std-controls.jsregistry, editors, MessageReviewControl, LiveInputControl - engine/libs/std-io-lib.jsmeta, Source, Sink, FileLoader, FileSaver - engine/libs/std-struct-lib.jsmeta, Fork, Join, Merge, Gate, Barrier - engine/libs/std-data-lib.jsmeta, Transform, Format, JSONParse, JSONStringify, Template - engine/libs/std-human-lib.jsmeta, MessageReviewer, resolveHuman - engine/libs/std-live-lib.jsmeta, 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.jsisCompatible (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.

ModuleDomainExports
std-types.jsType systemTYPE_REGISTRY, typeColor(), isCompatible(), registerType()
std-controls.jsUI controlsViewer/editor controls per type, registry, editors, registerControl()
std-io-lib.jsI/OSource, Sink, FileLoader, FileSaver
std-struct-lib.jsControl flowFork, Join, Merge, Gate, Barrier
std-data-lib.jsData transformsTransform, Format, JSONParse, JSONStringify, Template
std-human-lib.jsHuman interactionMessageReviewer, resolveHuman()
std-live-lib.jsLive interactionLiveSource, 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

  1. Editor → Engine : renderer.js imports cvm.js for the execution runtime
  2. Editor → Libs : renderer.js imports libraries directly (not via façade) for catalogue, types, and controls
  3. Engine → Libs : cvm.js imports only std-types.js (for isCompatible)
  4. Compositions → Libs : .cm.js files import operators from operators-lib.js (façade)
  5. Libs → nothing : all standard libraries are leaf modules with zero dependencies
  6. 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

ExtensionMechanismFile
New operatorAdd to existing library or create new *-lib.jsengine/libs/
New data typeregisterType(id, { color, label })std-types.js
New viewerregisterControl(type, control)std-controls.js
New editorregisterEditor(type, control)std-controls.js
Custom libraryCreate cst-*-lib.js following ODK conventionsengine/libs/

See odk/README.md for the complete Operator Development Kit guide.


6. Build Variants

VariantEntryDependencies
Developmenteditor/cameleon.htmlES modules — native browser imports
Standalone_site/demo/cameleon.htmlAll JS inlined by tools/build-doc.py — single file, zero network
Tests (Deno)engine/tests/*.test.jsDirect 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.