Universal Object Interaction Machine: one set of verbs (REF, CALL, SEND, OBS, DROP), one security model (signed, expiring, revocable capability references), across browsers, servers, and dependency-free C.
master-server: dependency-free Node server hosting secured realms, plus the Realm Browser — a live three.js node graph of every realm, device, capability, and message athttp://localhost:8787/ui.demos/venue-control: the showcase demo — a smart venue (lights, signage, sensor, native C counter) orchestrated through one realm. Seedemos/venue-control/README.md.machine1-c-runtime: a dependency-free C HTTP runtime that hosts one UOIM object namedcounter; also joins realms with--realm.machine2-browser-client: a static browser JavaScript app that obtains a reference and executes UOIM instructions against the C runtime.uoim/: the JS and C SDKs.architecture: a language-agnostic device wrapper contract for quickly creating more UOIM devices.tools/build-prod.mjs: assembles the curatedprod/release folder (runnode tools/build-prod.mjs;prod/is generated, never edited by hand).
Quickstart for the full experience:
node master-server/server.js # realms + Realm Browser on :8787
node demos/venue-control/serve.mjs # demo pages on :8092
# open http://127.0.0.1:8092/demos/venue-control/ and http://localhost:8787/uiThe implementation demonstrates the core primitives from the specification docs:
REF: resolvecounterinto an authority-bearing reference.CALL: synchronously invokedescribe,get,increment, orreset.SEND: asynchronously submitincrementorresetand receive acceptance.OBS: observestateortrace.DROP: revoke a local reference.
Build with CMake:
cmake -S machine1-c-runtime -B machine1-c-runtime/build
cmake --build machine1-c-runtime/buildRun:
.\machine1-c-runtime\build\uoim_machine1.exeThe runtime listens on:
http://0.0.0.0:8088
From another machine, use the machine 1 LAN IP address, for example:
http://192.168.1.25:8088
If Windows Firewall blocks the connection, allow inbound TCP traffic on port 8088 for the runtime executable.
Serve the browser app from the repository root:
python -m http.server 8091
http://localhost:8091/machine2-browser-client/
Set Runtime URL to the machine 1 runtime URL, then click REF counter.
The client requests these explicit rights:
CALL:describe
CALL:get
CALL:increment
CALL:reset
OBS:state
OBS:trace
The C runtime returns a reference token such as ref-1; all subsequent instructions must present that token. Object identity alone is not accepted as authority.
Create a reference:
POST /uoim/ref
Content-Type: application/json
{
"name": "counter",
"rights": ["CALL:describe", "CALL:get", "OBS:state"]
}Call a capability:
POST /uoim/call
Content-Type: application/json
{
"ref": "ref-1",
"cap": "increment",
"args": { "delta": 1 },
"delta": 1
}Send an asynchronous instruction:
POST /uoim/send
Content-Type: application/json
{
"ref": "ref-1",
"cap": "increment",
"args": { "delta": 1 },
"delta": 1
}Observe state:
GET /uoim/observe?ref=ref-1&port=stateObserve traces:
GET /uoim/observe?ref=ref-1&port=traceDrop a reference:
POST /uoim/drop
Content-Type: application/json
{
"ref": "ref-1"
}This is intentionally small and inspectable. It is not yet a production runtime: JSON parsing is minimal, SEND is accepted and applied immediately, references are in memory, and the runtime is a single-threaded actor. Those choices keep the first implementation aligned with the UOIM model while leaving room for a real scheduler, schema registry, cryptographic references, and distributed routing later.
The reusable wrapper contract is documented in:
architecture/uoim_device_wrapper.md
Machine-readable files:
architecture/uoim_device_contract.schema.json
architecture/counter.device.json
machine1-c-runtime/device.json
machine2-browser-client/device.json
The wrapper architecture defines UoimDevice, DeviceSpec, CapabilitySpec, PortSpec, DeviceHandlers, RuntimeAdapter, shared result/error envelopes, and helper functions for fast setup across languages.
device.json is the portable device contract. The C runtime loads device.json from the executable directory first, then falls back to the current directory and architecture/counter.device.json. CMake copies machine1-c-runtime/device.json beside uoim_machine1.exe after each build, so a prebuilt executable can be shipped with a different adjacent config file.
The browser client loads machine2-browser-client/device.json and uses it for object name, default rights, descriptor labels, and shared CSS design tokens. The runtime also serves its active config at:
GET /uoim/device.json
Template rendering uses plain files:
node uoim/tools/render-device-template.mjs architecture/counter.device.json uoim/templates/device.js.tmpl generated/counter-device.js
node uoim/tools/render-device-template.mjs architecture/counter.device.json uoim/templates/device.c.tmpl generated/counter-device.c
node uoim/tools/render-device-template.mjs architecture/counter.device.json uoim/templates/design.css.tmpl generated/counter-design.cssJavaScript import:
import {
UoimHttpClient,
UoimRemoteObject,
T,
buildDevice,
capability,
device,
httpClient,
loadDeviceConfig,
port,
right,
remoteObjectFromConfig,
version,
withCapability,
withDefaultRights,
withPort,
} from "./uoim/js/index.js";Minimal browser client usage:
const counter = httpClient("http://localhost:8088").object("counter", {
rights: ["CALL:get", "CALL:increment", "OBS:state"],
});
await counter.ref();
await counter.call("increment", { delta: 1 });
const state = await counter.obs("state");Config-first browser usage:
const config = await loadDeviceConfig("./device.json");
const counter = remoteObjectFromConfig("http://localhost:8088", config);
await counter.ref();C include:
#include "uoim_device.h"For C builds, add this include directory:
uoim/c
The C wrapper includes convenience helpers for common device code:
uoim_context_init(...);
uoim_result_ok(...);
uoim_result_error(...);
uoim_json_get_string(...);
uoim_json_get_int(...);
uoim_json_escape(...);A blog-style walkthrough and runnable mini-demo are available here:
tutorials/message-tutorial/index.html
The tutorial builds a C app on machine 1 that displays received messages through uoim_device_t, and a browser JavaScript app on machine 2 that sends messages with UOIM REF, SEND, and OBS.
Runnable files:
tutorials/message-demo/machine1-message-receiver/message_receiver.c
tutorials/message-demo/machine2-message-sender/index.html
uoim/c/uoim_device.c
Serve the tutorial sender from the repository root:
python -m http.server 8091
http://localhost:8091/tutorials/message-demo/machine2-message-sender/