Internal events and operations
THOTH uses ATON's local EventHub for input and application commands and ATON Photon for collaboration. The stable synchronization unit is a scene operation; UI events translate user actions into those operations.
Local event API
After THOTH.Events.setup(), the application exposes:
THOTH.on("eventName", data => {
// Handle a local event.
});
THOTH.fire("eventName", data, immediate);
THOTH.fire wraps ATON.fire with an authentication check for mutating commands. It returns false and opens the sign-in UI when a protected event is fired without an authenticated user.
Model and selection commands
| Event | Payload | Effect |
|---|---|---|
addModel |
model ID string | Resolves model and artefact data, then creates a model operation. |
deleteModel |
model ID string | Marks the model for deletion. |
modelTransformPos |
{ modelName, value: { x, y, z } } |
Updates translation. |
modelTransformRot |
{ modelName, value: { x, y, z } } |
Updates rotation. |
createSelection |
optional { modelId } |
Creates and activates a selection. |
deleteSelection |
selection ID | Deletes the selection resolved by ID. |
editSelectionMetadata |
{ id, data, annotationData, prevData? } |
Updates the selection's shared annotation fields and legacy metadata value. |
renameSelection |
{ id, data, prevData? } |
Updates the name. |
Selection IDs are model-scoped in storage. Code that can access more than one model should prefer THOTH.Annotations or operations with an explicit target.model_id instead of relying on ID-only UI commands.
Measurement and semantic-annotation commands
| Event | Payload | Effect |
|---|---|---|
selectMeasure |
none | Activates Measure. |
addMeasurementPoint |
none | Adds the current surface hit. |
createMeasurement |
none for the interactive flow, or { id, data } |
Computes or commits a measurement. |
deleteMeasurement |
{ id, point1?, point2? } |
Deletes a measurement. |
renameMeasurement |
{ id, value } |
Updates its name. |
editMeasurement |
{ id, data, prevData? } |
Updates shared fields. |
toggleMeasurementVisibility |
measurement ID | Toggles visibility. |
selectSemanticAnnotation |
none | Activates the point annotation tool. |
addSemanticAnnotationPoint |
none | Starts details for the current surface hit. |
createSemanticAnnotation |
{ id, data } |
Creates the annotation. |
updateSemanticAnnotation |
{ id, data, prevData? } |
Updates it. |
deleteSemanticAnnotation |
annotation ID | Deletes it. |
toggleSemanticAnnotationVisibility |
annotation ID | Toggles visibility. |
Tool and input events
selectBrush, selectEraser, selectLasso, and selectNone change the active tool. useBrush, endBrush, useEraser, endEraser, startLasso, updateLasso, endLassoAdd, endLassoDel, and endAllToolOps drive interactive selection edits.
THOTH also emits MouseLeftDown, MouseLeftUp, MouseRightDown, MouseRightUp, MouseMove, KeyDown, and KeyUp from browser input. Keyboard payloads use KeyboardEvent.code, for example KeyB or Digit1.
Operation API
Use operations for code that must integrate with undo/redo or collaboration:
const operation = THOTH.Ops.makeOperation(
"model.update_transform",
{ model_id: "textile_01", field: "translation" },
{
translation: { x: 1, y: 0, z: 0 },
rotation: { x: 0, y: 0, z: 0 }
},
previousTransforms
);
THOTH.Ops.applyLocal(operation);
The wire shape is:
type Operation = {
type: string,
target: {
model_id?: string,
collection?: "selections" | "measurements" | "semantic_annotations",
item_id?: string | number,
field?: string
},
value: unknown,
prev_value: unknown,
user_id?: string,
timestamp?: number,
source?: "local" | "remote" | "history"
}
Supported types are:
model.create,model.delete,model.update_artefact,model.update_metadata, andmodel.update_transform;selection.create,selection.update, andselection.delete;measurement.create,measurement.update, andmeasurement.delete; andsemantic_annotation.create,semantic_annotation.update, andsemantic_annotation.delete.
applyLocal adds user_id, a millisecond timestamp, and source: "local"; applies the operation; pushes its inverse to history; and broadcasts it when collaboration is enabled. applyRemote ignores messages from the local user and does not modify local history. THOTH.Ops.invert(operation) exchanges new and previous values and swaps .create with .delete where needed.
Conflict filtering is last-timestamp-wins per model field or collection item. Timestamps are supplied by browser clocks, so deployments that require stronger ordering should add an authoritative backend protocol.
Photon messages
THOTH.onPhoton("thoth.operation", operation => {
// THOTH normally applies this automatically.
});
THOTH.firePhoton("thoth.operation", operation);
| Message | Payload | Purpose |
|---|---|---|
thoth.operation |
Operation |
Broadcast one canonical mutation. |
syncScene |
canonical scene object | Replace runtime scene state when a participant joins. |
On VRC_UserEnter, a connected participant emits syncScene with THOTH.getExportData(). Consumers should treat both Photon message names as internal protocol and keep clients on compatible THOTH versions.