Chapter 9: Realtime Rendering
This chapter shows how to render timeline data into the DOM. The pattern is: store structured data on a timeline, derive HTML, then mount it.
Scenario
Imagine a small weather widget. The model or another data source writes a weather object, and the UI updates automatically.
Step 1: Define Object and HTML Timelines
const weather = useTimeline<WeatherData>({ name: 'weather' });
useTimeline<string>({
name: 'weather-html',
fill: reactionFrame({
triggers: { weather },
compute({ weather }) {
if (!weather?.value) return '';
return renderToHtml(weather.value);
},
}),
});
The object timeline is the source. The HTML timeline is a derived view.
Step 2: Mount to the DOM
import { DomMountFeature } from '@chronoai/toolkit/dom-mount';
agent.use(DomMountFeature, {
mounts: [
{
timeline: 'weather-html',
target: '#weather',
mode: 'html',
},
],
});
When weather-html changes, the target element updates.
Step 3: Write Data
await agent.write('weather', {
city: 'Shanghai',
temperature: 26,
condition: 'Cloudy',
});
The write triggers the derived HTML timeline and then the DOM mount.
DomMountFeature Configuration
Mount Entry
A mount entry usually contains:
| Field | Meaning |
|---|---|
timeline | Source timeline to observe |
target | CSS selector or element resolver |
mode | Render mode, such as text or html |
Write Modes
Use text mode for plain strings and HTML mode for trusted rendered HTML.
{ timeline: 'status', target: '#status', mode: 'text' }
{ timeline: 'panel-html', target: '#panel', mode: 'html' }
Multiple Mounts
agent.use(DomMountFeature, {
mounts: [
{ timeline: 'title', target: '#title', mode: 'text' },
{ timeline: 'body-html', target: '#body', mode: 'html' },
],
});
Streaming Updates
If a timeline receives streaming frames, the mounted UI can update as chunks arrive.
Complete Example
const WeatherFeature = defineFeature('weather', () => {
const weather = useTimeline<WeatherData>({ name: 'weather' });
useTimeline<string>({
name: 'weather-html',
fill: reactionFrame({
triggers: { weather },
compute({ weather }) {
if (!weather?.value) return '<p>No weather data.</p>';
return `<strong>${weather.value.city}</strong>: ${weather.value.temperature}C`;
},
}),
});
});
agent.use(WeatherFeature);
agent.use(DomMountFeature, {
mounts: [{ timeline: 'weather-html', target: '#weather', mode: 'html' }],
});
Summary
- Keep structured data on timelines.
- Derive presentation strings or HTML through reactions.
- Mount rendered timelines with
DomMountFeature. - Streaming frames can update the UI progressively.
Next
Continue with Chapter 10: Streaming.