docs(logic): document panel-logic array locals
Document array-valued local variables (statevar type=array with elem/sizing/capacity), the value-polymorphic expression engine and array functions, the array.* mutation nodes, accumulate/export unification, and index-aligned CSV export in TECHNICAL_SPEC §3.8. Note in TODO that panel-logic (Phase 1) array support is complete while the server-side control-logic port (Phase 2) remains pending. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -98,6 +98,7 @@
|
|||||||
- [x] Implement live / debug mode where value are evaluated online and visualized at human speed (e.g. 0.5s) — editor spins up a second client-side `LogicEngine` in new `dryRun` mode (real writes/config/dialogs suppressed) loaded with the edited graph; per-node values polled into the shared badges; the view-mode singleton is untouched
|
- [x] Implement live / debug mode where value are evaluated online and visualized at human speed (e.g. 0.5s) — editor spins up a second client-side `LogicEngine` in new `dryRun` mode (real writes/config/dialogs suppressed) loaded with the edited graph; per-node values polled into the shared badges; the view-mode singleton is untouched
|
||||||
- add full suppor to local array values: dynamic, dynamic but capped max, fixed size etc:
|
- add full suppor to local array values: dynamic, dynamic but capped max, fixed size etc:
|
||||||
- array functions should work with new local array
|
- array functions should work with new local array
|
||||||
|
- NOTE: **Phase 1 (panel logic, client-side TS) is DONE** — array statevars (dynamic/capped/fixed), value-polymorphic expression engine with indexing + array functions, `action.array.*` mutation nodes (legacy accumulate/export/clear unified + auto-migrated), panel-XML round-trip, editor declaration form, and widget array modes (plot/table/multi-LED). Box stays unchecked until **Phase 2** (server-side `internal/controllogic` Go port, see below) lands.
|
||||||
- [ ] Control loop:
|
- [ ] Control loop:
|
||||||
- [x] Implement live / debug mode where value are evaluated online and visualized at human speed (e.g. 0.5s) — server pushes per-node events over the WS (`debugSubscribe`/`debugNode`) via a new `DebugObserver` on the engine (lock-free `atomic.Value`, gated by a per-graph watch set) + `internal/server/debughub.go` (drop-on-full fan-out). Two modes share one message shape: **Live** observes the running enabled graph; **Simulate** dry-runs the unsaved edits in a throwaway sandbox (`StartSimulate`, side effects suppressed). Live/Sim sub-toggle in the editor
|
- [x] Implement live / debug mode where value are evaluated online and visualized at human speed (e.g. 0.5s) — server pushes per-node events over the WS (`debugSubscribe`/`debugNode`) via a new `DebugObserver` on the engine (lock-free `atomic.Value`, gated by a per-graph watch set) + `internal/server/debughub.go` (drop-on-full fan-out). Two modes share one message shape: **Live** observes the running enabled graph; **Simulate** dry-runs the unsaved edits in a throwaway sandbox (`StartSimulate`, side effects suppressed). Live/Sim sub-toggle in the editor
|
||||||
- add full support to server side array values
|
- add full support to server side array values
|
||||||
|
|||||||
+31
-1
@@ -346,10 +346,40 @@ mount and `clear()` on unmount. The engine subscribes to every referenced signal
|
|||||||
cache, then on each trigger activation walks the wired graph (gates, if/loop, actions),
|
cache, then on each trigger activation walks the wired graph (gates, if/loop, actions),
|
||||||
evaluating expression fields via a small safe recursive-descent evaluator (no `eval`).
|
evaluating expression fields via a small safe recursive-descent evaluator (no `eval`).
|
||||||
Triggers include button/threshold/change/timer/loop and On-open/On-close lifecycle; actions
|
Triggers include button/threshold/change/timer/loop and On-open/On-close lifecycle; actions
|
||||||
include signal writes, delay, log, in-memory data arrays (accumulate/export-CSV/clear) and
|
include signal writes, delay, log, array mutations (see below) and
|
||||||
user dialogs (info/error/set-point). The engine runs entirely in the browser — no backend
|
user dialogs (info/error/set-point). The engine runs entirely in the browser — no backend
|
||||||
component.
|
component.
|
||||||
|
|
||||||
|
**Array-valued local variables.** Panel-local variables (`<statevar>`) may be declared with
|
||||||
|
`type="array"`. An array statevar carries `elem` (`number`|`bool`|`array`, the element kind —
|
||||||
|
`array` gives a 2-D array), `sizing`, and `capacity`. The three sizing policies
|
||||||
|
(`web/src/lib/arraypolicy.ts`) are: **dynamic** (unbounded up to `ARRAY_MAX = 1_000_000`,
|
||||||
|
oldest dropped past the cap), **capped** (length kept ≤ `capacity`, oldest dropped FIFO), and
|
||||||
|
**fixed** (exactly `capacity` elements — truncated or zero-padded). Sizing is enforced only at
|
||||||
|
store time (`writeLocalState` → `applySizing`); expressions themselves are pure and produce
|
||||||
|
unbounded values. The value model is the tagged union `ArrVal = number | ArrVal[]` with
|
||||||
|
booleans represented as `1`/`0` at the leaves.
|
||||||
|
|
||||||
|
The expression evaluator (`web/src/lib/expr.ts`) is value-polymorphic: `evalValue` returns an
|
||||||
|
`ArrVal`, while `evalExpr` returns a `number` (`NaN` if the result is an array). It supports
|
||||||
|
array literals `[a, b, c]`, indexing `a[i]` (negative indices count from the end), and a table
|
||||||
|
of array functions: `len`, `sum`, `mean`, `slice`, `concat`, `reverse`, `sort`, `scale`, `add`,
|
||||||
|
`sub`, `push`, `set`, `insert`, `remove`, `pop`, `shift`, `indexOf`, `contains`, `fill` (plus
|
||||||
|
`min`/`max`, which accept either scalars or an array). These are pure — they return new values
|
||||||
|
and never mutate a stored variable.
|
||||||
|
|
||||||
|
Array mutation nodes write back to a declared array statevar: `action.array.push`, `…set`,
|
||||||
|
`…remove`, `…pop`, and `…clear`. The legacy `action.accumulate` and `action.clear` nodes are
|
||||||
|
retained as aliases over `action.array.push` / `action.array.clear`, and legacy graphs are
|
||||||
|
auto-migrated to declare their backing arrays on load (`ensureArrayDecls`). `action.export`
|
||||||
|
now produces **index-aligned** CSV: each configured array becomes a column (custom per-column
|
||||||
|
labels supported), rows aligned by element index. Array statevars and all array nodes
|
||||||
|
round-trip through the panel XML (`<statevar type="array" elem=… sizing=… capacity=…>`).
|
||||||
|
|
||||||
|
> **Note:** This is Phase 1 (panel logic, client-side TypeScript). The equivalent array
|
||||||
|
> support in the server-side control-logic engine (`internal/controllogic`) is a separate
|
||||||
|
> Phase 2 effort and is not yet implemented.
|
||||||
|
|
||||||
### 3.9 Control Logic Engine
|
### 3.9 Control Logic Engine
|
||||||
|
|
||||||
Control logic is server-side (`internal/controllogic`): always-on flow graphs that run under
|
Control logic is server-side (`internal/controllogic`): always-on flow graphs that run under
|
||||||
|
|||||||
Reference in New Issue
Block a user