Docs

Publish a public World

Make the sanitised projection of a scene that a public World shows, through a declared filter.

A public World is never the internal World. A declared filter names which objects, properties, readings and alarms are public; publicPackage keeps only those and is the only thing a public World is made from.

publish.ts
import { createScene, packScene, publicPackage, type PublicationFilter } from "@klorad/api/world";

const scene = createScene({ name: "Northgate", coordinateSystem: { origin: { lat: 40.66, lon: 22.865 } } });
scene.add({ id: "office", name: "Operations office", position: { east: 0, north: -35 }, properties: { kind: "building", tenant: "Northgate SA" } });
scene.add({ id: "gate-cam", name: "Gate camera", position: { east: 0, north: -75 }, properties: { kind: "camera" } });
scene.add({ id: "crac", name: "Server room cooling", position: { east: 5, north: -33 }, correspondence: "twin", binding: { source: "bms", entity: "p:northgate:r:crac" }, properties: { kind: "equipment" } });
scene.observe({ objectId: "crac", quantity: "temperature", value: 22.5, observedAt: Date.now(), source: "bms" });
scene.observe({ objectId: "crac", quantity: "setpoint", value: 21, observedAt: Date.now(), source: "bms" });

// Nothing is public that the filter does not name.
const filter: PublicationFilter = {
  exclude: { kind: ["camera"] },
  properties: ["kind"],
  quantities: ["temperature"],
  alarms: ["server-room-hot"],
};

export async function publicView() {
  const pub = await publicPackage(await packScene(scene), filter, "Northgate, public view");
  const objects = pub.chunks.flatMap((c) => c.objects);
  objects.map((o) => o.id); // ["office", "crac"]: the camera stays inside
  objects.find((o) => o.id === "office")?.properties; // { kind: "building" }: the tenant stays inside
  JSON.stringify(pub).includes("p:northgate"); // false: no source or device id leaves
  return pub;
}

What the projection does

  • Keeps the objects the filter admits: by layer, by class, by id, and never one whose properties match exclude.
  • Keeps only the properties named in properties.
  • Turns a shadow or a twin into a shadow bound to an anonymous source, so no source or device id leaves and nothing public can be actuated.
  • Keeps the readings of the quantities named in quantities, and drops relations to objects that are not public, provenance, assets and extensions.
  • Keeps the scene's 3D Tiles context only when externalSpaces is true.

In Klorad One

Klorad One publishes each projection as an immutable version that a CDN caches, serves it at /p/<slug> with an installable app and a push channel for the alarms the filter makes public, and hides every version at once when the World is unpublished.

Run it liveSandbox: Public WorldThe public sees only what the operator chooses to publish, and no device id ever leaves.

Something wrong or unclear? Tell us.