These examples use the library shipped with the website. Include /assets/js/armapi-demo.js before executing them. None connects to the page’s existing demo automatically: each create() call makes a new model.
1. Make a change, then inspect it.
const arm = ArmAPIDemo.create();
arm.moveTo('reach');
const state = arm.grip(true);
console.assert(state.pose === 'reach');
console.assert(state.gripper === 'closed');
console.assert(state.revision === 2);The two successful mutating calls produce revision 2. The state says what the local model contains. It does not assert that an animation finished or that a physical object was grasped.
2. Observe a model without polling.
const arm = ArmAPIDemo.create();
const history = [];
const stopObserving = arm.subscribe(state => {
history.push({ pose: state.pose, revision: state.revision });
});
arm.moveTo('lift');
stopObserving();
arm.moveTo('home');
console.assert(history.length === 2);
// Initial home state, then lift. No later home notification.The initial callback is immediate. This makes it possible to render a first view and later changes through the same listener. The unsubscribe function removes that listener; it does not reset the model.
3. Handle rejected input explicitly.
const arm = ArmAPIDemo.create();
try {
arm.moveTo('unknown-pose');
} catch (error) {
if (error instanceof RangeError) {
console.log('Choose home, reach, or lift.');
} else {
throw error;
}
}
console.assert(arm.getState().revision === 0);An invalid request leaves the state unchanged. The UI should describe the supported operation rather than quietly substituting a different pose. Pass a Boolean to grip; do not rely on string or number coercion.
4. Keep experiments independent.
const first = ArmAPIDemo.create();
const second = ArmAPIDemo.create();
first.moveTo('reach');
console.assert(second.getState().pose === 'home');
const snapshot = first.getState();
snapshot.joints.shoulder = 999;
console.assert(first.getState().joints.shoulder === 18);Snapshots do not expose the model’s internal joint object. A different instance does not inherit state from a previous experiment. Reloading the page also discards all in-memory instances.
5. Render into your own text element.
<p id="arm-output" role="status">Waiting for local state.</p>
<script src="/assets/js/armapi-demo.js"></script>
<script>
const arm = ArmAPIDemo.create();
const output = document.getElementById('arm-output');
arm.subscribe(state => {
output.textContent = state.pose + ' · ' + state.gripper;
});
arm.moveTo('reach');
</script>The example writes plain text, not HTML assembled from user input. It is a static readout rather than a data-entry form. Add a renderer for your own project only after deciding which state changes it should display.
A note about timed sequences.
The playground schedules its visual sequence in the page script. It cancels remaining steps when paused, reset, or backgrounded. The library itself contains no sequence timer. A method’s return cannot tell you whether a CSS transition finished, and CSS transition completion cannot verify a real-world outcome.
Read the API reference for the full contract, then compare these examples with the visible playground controls. The simulation test guide offers a broader test-planning framework.