KloradDocs

The scene and its events

The one place world state changes, and the ordered stream of events every change becomes.

A Scene holds the Scene Objects of one twin and the readings that describe them. It is the only way to change world state: add, update, remove and observe are the four writes, and everything else reads.

Every change is one event

Each write emits exactly one SceneEvent with a scene wide sequence number seq, starting at 1 and strictly increasing, and the instant it happened on the scene's clock. Subscribers see the same events in the same order: a React component, a renderer and an audit log never disagree about what happened first.

scene-objects.ts
import { createScene, type DigitalShadow } from "@klorad/api/world";

const scene = createScene({ coordinateSystem: { origin: { lat: 40.62637, lon: 22.94838 } } });

// A Digital Object: no physical counterpart is synchronised.
const hall = scene.add({
  id: "hall",
  name: "Exhibition hall",
  position: { east: 0, north: 0 },
  geometry: { kind: "box", width: 24, depth: 14, height: 7 },
});

// A Digital Shadow: one-way, timestamped flow from a physical sensor.
const entrance: DigitalShadow = scene.add({
  id: "entrance",
  name: "Entrance counter",
  position: { lat: 40.62629, lon: 22.94857 },
  geometry: { kind: "cylinder", radius: 2, height: 4 },
  correspondence: "shadow",
  binding: { source: "gateway", entity: "entrance-01" },
});

scene.update("hall", { orientation: { heading: 30 }, properties: { floor: 0 } });

const log: string[] = [];
const stop = scene.subscribe((event) => log.push(`#${event.seq} ${event.type}`));

export { hall, entrance, stop, log };
EventEmitted when
object.addedAn object is added. Carries the object.
object.updatedAn object changes. Carries the new object and the previous one.
object.removedAn object is removed, with its readings.
observationA reading is accepted. latest says whether it became the current state.
actionAn Action was requested, with its outcome, allowed or not.
animationA Behaviour asked renderers to show a change.

A reading seen twice emits nothing; an update that throws emits nothing. If a subscriber throws, the others still receive the event and the change still stands: pass onListenerError to createScene to hear about it.

Objects are values

A Scene Object is a frozen value. update does not mutate it; it builds a new object and emits the old and the new one. objects() and readings(id) return the same reference until something changes, so React can compare by reference and skip work.

An update merges properties and replaces everything else it names. How an object corresponds to the physical world (its correspondence and binding) cannot be patched: remove the object and add it again, which makes the change explicit in the event stream.

Ids

Give objects stable ids of your own ("hall", "entrance") when other code refers to them: bindings, Worlds and alert rules all do. If you omit id, the scene assigns o1, o2 and so on. Adding an id twice throws.

Run it liveSandbox: Scene ObjectsDigital Objects, Shadows and Twins added, moved and removed; every change is one ordered event.

Something wrong or unclear? Tell your contact at Prieston Technologies.