docs
Docs / docs (push) Successful in 26s
Playwright Tests / test-playwright (1, 2) (push) Failing after 4m7s
Playwright Tests / test-playwright (2, 2) (push) Failing after 2m30s
pre-commit / pre-commit (push) Failing after 2m42s
Test Backend / test-backend (push) Failing after 3m3s
Compose Smoke Test / test-compose (push) Successful in 32s
Playwright Tests / merge-reports (push) Successful in 1m51s
Docs / docs (push) Successful in 26s
Playwright Tests / test-playwright (1, 2) (push) Failing after 4m7s
Playwright Tests / test-playwright (2, 2) (push) Failing after 2m30s
pre-commit / pre-commit (push) Failing after 2m42s
Test Backend / test-backend (push) Failing after 3m3s
Compose Smoke Test / test-compose (push) Successful in 32s
Playwright Tests / merge-reports (push) Successful in 1m51s
This commit is contained in:
+99
-127
@@ -1,177 +1,149 @@
|
||||
# The flow editor
|
||||
|
||||
The canvas is where most of the work happens. It floats its chrome over a
|
||||
full-bleed graph, so what you are looking at is always the flow.
|
||||
Build a flow by naming its messages and configuring its nodes. Fluksio draws
|
||||
the connections and arranges the canvas for you.
|
||||
|
||||
## The canvas
|
||||
|
||||
Nodes are laid out for you, left to right on a desktop and top to bottom on a
|
||||
phone, and the arrangement is recomputed as the graph changes. There is
|
||||
nothing to drag and nothing to tidy.
|
||||
The graph runs left to right on desktop and top to bottom on phones.
|
||||
|
||||
The edges come from message names, so there is no layout to store or to merge
|
||||
when two people edit the same flow.
|
||||
- **Nodes** show their execution status.
|
||||
- **Edges** pulse when values pass through. Click one to inspect its payload.
|
||||
- **Endpoints** show flow inputs, dashboard widgets and nodes in other flows
|
||||
that exchange messages with this flow.
|
||||
|
||||
What is drawn:
|
||||
|
||||
- **Your nodes**, with a status dot — running, succeeded, failed, or nothing at
|
||||
all when idle. Status is always named in words too, never colour alone.
|
||||
- **Edges**, which pulse when a value goes down them. Click one to inspect it.
|
||||
- **Endpoints** — anything wired into this flow that is not a node in it: a
|
||||
dashboard control writing a message, a tile reading one, a node in another
|
||||
flow on the far side of a dotted name. Drawn as labelled boxes at the
|
||||
boundary, so a value never appears to come from nowhere.
|
||||
|
||||
Values are live. The editor holds a websocket to the engine, and the connection
|
||||
banner tells you when it is not.
|
||||
Values update over a websocket. A connection banner tells you when the editor
|
||||
cannot reach the engine.
|
||||
|
||||
## Adding a node
|
||||
|
||||
**Add node** on the dock, or ⌘P / Ctrl-P for the command palette, which also
|
||||
jumps between flows and offers your shared nodes. Pick a type and it appears on
|
||||
the canvas with its panel open.
|
||||
Choose **Add node** in the bottom dock, or use ⌘P / Ctrl-P. The command palette
|
||||
also jumps between flows and offers reusable nodes. Select a type to add it
|
||||
and open its settings.
|
||||
|
||||
## The node panel
|
||||
|
||||
Floats on the right; a full-screen sheet on a phone.
|
||||
**Consumes** and **Provides** declare the node's ports. Each has a port name,
|
||||
payload type, bound message and delivery interval. Outputs also have a
|
||||
streaming toggle.
|
||||
|
||||
**Consumes** and **Provides** are the ports. Each port has two lines: its name
|
||||
and payload type (a `list` also says what its items are), then the message it
|
||||
is bound to, how often at most it is delivered, and, on an output, a
|
||||
*streaming* toggle for ports that publish repeatedly during one execution. The
|
||||
message field suggests messages already in the flow, which is usually how you
|
||||
wire something: type the name that already exists.
|
||||
Message fields suggest existing names. Matching an output's message is how
|
||||
you connect an input.
|
||||
|
||||
A port is named after its message until you name it yourself. Its name field
|
||||
then stays empty and shows the name it follows. A name typed there stays when
|
||||
the message changes, which is how a port is bound to a message called
|
||||
something else, as a [`wren`](../reference/node-types.md#wren) target is;
|
||||
clear it to follow the message again. The name is what the node's code sees,
|
||||
so it is letters, digits and `_`, not starting with a digit, and no two inputs
|
||||
or two outputs of a node share one. The field keeps the name it had otherwise.
|
||||
A blank port-name field follows the message's last segment. Set a port name
|
||||
to keep the argument name fixed while changing its message binding. Names use
|
||||
letters, digits and `_`, cannot start with a digit, and must be unique among
|
||||
the node's inputs or outputs.
|
||||
|
||||
Renaming an output renames the message everywhere it is read. Inputs are not
|
||||
renamed, because an input is more often re-pointed at a different message than
|
||||
renamed.
|
||||
Renaming an output's message updates its consumers in the flow. Changing an
|
||||
input binding points that input at a different message.
|
||||
|
||||
**Settings** is generated from the node type's parameter schema, so an MQTT
|
||||
node shows broker, topic and QoS, and an ntfy node shows server, topic and
|
||||
priority. A field marked as a credential renders as a picker over your stored
|
||||
[secrets](operations.md) instead of a text box. A setting holding JSON, such as
|
||||
a Switch node's rules, shows one line of it; click it to edit the whole value
|
||||
in a larger editor, which saves only once the text parses. Escape or Cancel
|
||||
leaves the setting as it was. An inject's payload and a flow input's starting
|
||||
value of type `json`, `record` or `list` open the same editor, which also holds
|
||||
the shape (a `record` is an object, a `list` an array); emptying it leaves no
|
||||
value.
|
||||
### Settings
|
||||
|
||||
A Function node gets a second settings section where you add your own: a
|
||||
setting is a constant of this node's code and arrives as an argument beside its
|
||||
Built-in nodes show forms for their configuration. Credential fields offer
|
||||
stored [secrets](operations.md#secrets). JSON settings open a larger editor
|
||||
and save only when the value parses.
|
||||
|
||||
Function nodes also let you add settings passed as arguments alongside the
|
||||
ports. See [Where a node's values come from](../concepts/values.md).
|
||||
|
||||
**Timeout** (Function nodes) is how many seconds the code may be *silent*
|
||||
before it is stopped: it measures silence, not duration, so a node that yields
|
||||
every few seconds can run for hours under a timeout of 300. Left empty there is
|
||||
no limit, which is the default. Set one where a node going quiet means it is
|
||||
stuck rather than working. A `0` says so explicitly.
|
||||
**Timeout** on a Function node limits silence, not total duration. A node
|
||||
yielding regularly can run longer than its timeout. Empty or `0` means no
|
||||
limit, the default.
|
||||
|
||||
**Code** is the editor. It saves as you type and applies on ⌘S; the node
|
||||
reloads without the flow stopping. A node file defines `process(...)`; if it
|
||||
defines exactly one public function under another name, that one is used
|
||||
instead.
|
||||
**Resources** selects a shared worker pool, a named flavor or custom CPU,
|
||||
memory and GPU requirements. Placement by `device` and `device_policy` is
|
||||
configured through the API or flow JSON; see [Remote workers](../code/workers.md).
|
||||
|
||||
Code runs as the engine, so changing it is a superuser's. Anyone else sees the
|
||||
editor read-only, a Command node's settings disabled, and no Function, Command
|
||||
or reusable nodes to add.
|
||||
### Code and reuse
|
||||
|
||||
**Shared** turns a node's code into a library entry other flows can reuse.
|
||||
Editing a shared node edits the copy every flow using it runs, which is the
|
||||
point and also the caution.
|
||||
Define `process(...)` in **Code**. If the file instead contains exactly one
|
||||
public function, Fluksio uses that function.
|
||||
|
||||
!!! note "Not in the panel yet"
|
||||
Code saves as you type. ⌘S / Ctrl-S in the code editor saves immediately;
|
||||
**Publish** applies ordinary node code to the running flow. Generated code
|
||||
from `fluksio sync` is read-only: edit its source repository and sync again.
|
||||
|
||||
`device` and `device_policy`, which machine a node's code runs on, are set
|
||||
through the API rather than the panel, with `PUT /flows/{name}`. See
|
||||
[Remote workers](../code/workers.md).
|
||||
Only superusers can add or edit code-running nodes. Other users can read code
|
||||
and configure permitted built-in nodes.
|
||||
|
||||
**Reuse** shares node code as a library entry. Saving shared code takes effect
|
||||
immediately in every flow using it, so check its users before changing it.
|
||||
|
||||
## The flow panel
|
||||
|
||||
Click the canvas title to open the flow's own settings.
|
||||
Open **Flow settings** from the pencil button in the dock.
|
||||
|
||||
- **Running** — the switch that starts and stops the flow. Stopped means none
|
||||
of its subscriptions, schedules or webhooks exist.
|
||||
- **Mode** — `live` or `batch`. Live reacts to what arrives; batch only runs
|
||||
when a run asks it to. See [Runs](../concepts/runs.md).
|
||||
- **Inputs** — messages the flow takes from outside, with the value each starts
|
||||
from. For a batch flow these are also the run's parameters.
|
||||
- **Outputs** (batch only) — which messages a run reports as its result.
|
||||
- **Contents** — a reminder that this flow's name namespaces every message
|
||||
inside it.
|
||||
| Setting | Purpose |
|
||||
|---|---|
|
||||
| **Running** | starts or stops the published live flow's subscriptions, schedules and webhooks |
|
||||
| **Mode** | chooses continuous `live` operation or requested `batch` runs |
|
||||
| **Inputs** | declares external messages and starting values; batch inputs become run parameters |
|
||||
| **Result** | selects batch output messages |
|
||||
| **Contents** | shows the node count and message namespace |
|
||||
|
||||
For live inputs, **Publish this value now** sends the starting value immediately.
|
||||
Changing a stored starting value alone does not replace an existing message.
|
||||
|
||||
## Inspecting an edge
|
||||
|
||||
Click a wire. You get the last payload that went down it, when, and a sparkline
|
||||
of its recent numeric history. You can also republish that value from the node
|
||||
that produced it, which re-runs everything downstream. It is the fastest way to
|
||||
test a change without waiting for the real sensor.
|
||||
Click an edge to see its latest payload, timestamp and recent numeric history.
|
||||
Republish its value from the producer to run downstream nodes without waiting
|
||||
for the next sensor reading.
|
||||
|
||||
## The dock
|
||||
|
||||
Along the bottom, floating over the canvas.
|
||||
|
||||
| Control | What it does |
|
||||
| Control | Action |
|
||||
|---|---|
|
||||
| **Add node** | opens the palette |
|
||||
| **Fit** | returns to the view the flow opened with |
|
||||
| **Run** | injects a value by hand; on a batch flow, opens the parameters dialog |
|
||||
| **Pause / Resume** | holds messages instead of running them |
|
||||
| **Step** | releases exactly one held message |
|
||||
| **Publish** | puts the draft live |
|
||||
| **Discard** | throws the draft away |
|
||||
| **Issues** | what is stopping this flow from running, per node |
|
||||
| **Logs** | what the nodes printed, filterable |
|
||||
| **Add node** | opens the command palette |
|
||||
| **Fit to screen** | fits the graph; desktop only |
|
||||
| **Run** | executes the current live flow once; for batch flows, asks for run parameters |
|
||||
| **Pause / Resume** | holds or releases pending work while values still arrive |
|
||||
| **Step** | releases one held item while paused |
|
||||
| **Flow settings** | opens the flow panel |
|
||||
| **Publish** | puts the saved draft live |
|
||||
| **Discard** | removes unpublished changes |
|
||||
| **Issues** | lists problems by node |
|
||||
| **Logs** | shows filterable node output |
|
||||
|
||||
Pause and step together are how you test a flow before it moves anything
|
||||
physical: pause it, inject a value, step it through, watch the values appear on
|
||||
the edges, then publish.
|
||||
**Run** uses the current draft when one exists without publishing it. It
|
||||
executes real node code, including device and network actions. To try a single
|
||||
value in a live flow, publish it from a flow input or edge inspector.
|
||||
|
||||
Pause and step are useful for inspecting held work. They do not make a draft
|
||||
run a simulation.
|
||||
|
||||
## Shortcuts
|
||||
|
||||
| Chord | Action |
|
||||
Use ⌘ on macOS and Ctrl elsewhere.
|
||||
|
||||
| Shortcut | Action |
|
||||
|---|---|
|
||||
| ⌘P / Ctrl-P | command palette |
|
||||
| ⌘S / Ctrl-S | publish the flow — or, with focus in the code editor, apply the code |
|
||||
| ⌘Z / ⌘⇧Z | undo / redo (the flow; the code editor has its own) |
|
||||
| ⌘C / ⌘V | copy and paste nodes, including between flows |
|
||||
| ⌘S / Ctrl-S | publish the flow; inside the code editor, save code |
|
||||
| ⌘Z / Ctrl-Z | undo a graph edit |
|
||||
| ⌘⇧Z / Ctrl-Shift-Z | redo a graph edit |
|
||||
| ⌘C / Ctrl-C | copy selected nodes |
|
||||
| ⌘V / Ctrl-V | paste nodes, including into another flow |
|
||||
|
||||
## Drafts and publishing
|
||||
Text fields and the code editor keep their own undo and clipboard behavior.
|
||||
|
||||
Saving writes a draft; the engine keeps running what was published. Publishing
|
||||
promotes it and reloads.
|
||||
## Drafts, conflicts and issues
|
||||
|
||||
If someone else saved the same flow while you were working, publishing answers
|
||||
with a conflict rather than overwriting them. The Flows list offers **Publish
|
||||
all changes** when several flows are sitting on drafts.
|
||||
Edits are saved as drafts. The engine keeps running the published version until
|
||||
you publish; shared code follows the exception above. **Discard** returns to
|
||||
the published version. Delete a never-published flow to remove it.
|
||||
|
||||
## Issues
|
||||
If another editor saved the same flow, a stale save or publish returns a
|
||||
conflict. Reload and review their changes before retrying.
|
||||
|
||||
The canvas validates as you edit and marks the node each issue belongs to:
|
||||
|
||||
- a port that needs a message nothing in reach provides
|
||||
- a message that exists but has never held a value
|
||||
- a dependency cycle
|
||||
- a node reading a message it also writes, with nothing to start it from
|
||||
- code that did not load
|
||||
- a webhook with no shared secret (advisory — it does not stop the flow)
|
||||
- a node that loaded but reports itself down, such as a connector that cannot
|
||||
reach its device
|
||||
|
||||
A flow with any of these except the last two does not run, and the health
|
||||
summary on Home counts it. The last one clears on its own once the node reports
|
||||
itself well again.
|
||||
The canvas reports unconnected inputs, missing starting values, cycles and
|
||||
code-load errors. These prevent the affected flow from running. Unauthenticated
|
||||
webhooks are advisory; runtime node-health problems clear when the node
|
||||
recovers. See [Flow issues](../concepts/flows.md#when-a-flow-needs-attention).
|
||||
|
||||
## See also
|
||||
|
||||
- [Flows, nodes and messages](../concepts/flows.md) — the model behind the canvas
|
||||
- [Node types](../reference/node-types.md) — everything the palette offers
|
||||
- [Writing node code](../code/nodes.md) — what goes in the editor
|
||||
- [Flows, nodes and messages](../concepts/flows.md)
|
||||
- [Node types](../reference/node-types.md)
|
||||
- [Writing node code](../code/nodes.md)
|
||||
|
||||
Reference in New Issue
Block a user