Packets (dynamic objects)
Where nodes are static, packets (packets) are the
dynamic objects: the payloads that move from one node to
another. You declare them once in the packets root array, then you
animate them by their id with the move action.
A single packet can be moved multiple times in the timeline (forward, then back, then transferred...): it is the exact same visual entity traveling.
kind — the packet nature
The kind determines the appearance and available content fields:
kind | Represents | Content field |
|---|---|---|
http_packet | An HTTP request/response | packet_content |
sql_request | A SQL query | request_content |
sql_response | A SQL result | response_content |
simple_node | A traveling text box | body / language |
complex_node | A traveling header + body | header / body / language |
subicon | A traveling tech badge | icon |
http_packet — packet_content
An envelope with a header (header, e.g., the request line) and an
optional body (body). The body accepts text (with optional syntax
highlighting) or an image.
{
id: 'req',
kind: 'http_packet',
packet_content: {
header: 'GET /users',
body: { type: 'text', value: 'Accept: application/json' },
},
}
For a response, we reuse the same shape with a highlighted body:
{
id: 'res',
kind: 'http_packet',
packet_content: {
header: '200 OK',
body: { type: 'text', value: '[{ "id": 1 }]', language: 'json' },
},
}
sql_request — request_content
The simplest: a string representing the query. It is displayed inside the packet as it moves to the database.
{
id: 'sql',
kind: 'sql_request',
request_content: 'SELECT id, name FROM users',
}
sql_response — response_content
The result returned by the database. It specifies the number of rows (rows), an
optional header (header), and a body (body) which can be text
or a table:
{
id: 'rows',
kind: 'sql_response',
response_content: {
header: '2 rows',
body: {
type: 'table',
columns: ['id', 'name'],
rows_data: [
[1, 'Alice'],
[2, 'Bob'],
],
},
},
}
rows vs bodyrows is a simple counter displayed in the header; body carries the actual
rendered content (text or table). A sql_response without a body only
displays its header.
simple_node / complex_node — a node that travels
The text panel node types double as packet kinds: declare a packet
with kind: 'simple_node' or kind: 'complex_node' and it carries the same
content fields as the node — body, plus header for complex_node, optionally
syntax-highlighted via language. No nested *_content object: it is the node,
but it moves.
{
id: 'msg',
kind: 'simple_node',
body: 'enqueue(job)',
language: 'js',
}
complex_node adds the header line, just like the static node — handy when you
already use that node type in the scene and want the matching payload to fly:
{
id: 'login',
kind: 'complex_node',
header: 'POST /login',
body: '{ "user": "alice" }',
language: 'json',
}
complex_node vs http_packetBoth render a header above a body. Reach for complex_node when you want the packet
to look exactly like a complex_node node already on stage (same box, same
body/header/language API); keep http_packet for its dedicated
packet_content shape (typed body, image bodies).
subicon — a tech badge that travels
The node subicon — the small corner badge naming a technology —
doubles as a packet kind: declare a packet with kind: 'subicon' and an icon, and
the badge travels on its own. icon takes the same values as the node's: a known
technology (react, postgres…), a registered icon, or short free text (v2, API).
{
id: 'lib',
kind: 'subicon',
icon: 'react',
}
It is resolved by the same getSubIcon as the node badge — any name your nodes
already use works here too — and the moving wrapper renders as a round badge.
Setting a packet in motion
Declaring a packet does not display it: it only appears during a move.
timeline: [
{ type: 'move', object: 'req', from: 'browser', to: 'api' },
{ type: 'move', object: 'sql', from: 'api', to: 'db' },
],
See Action types → move for durations,
the bidirectional lane offset and persistence.