- OutputUtils: new `alwaysEmit` option exempts named fields from delta
compression so steady-state values (e.g. ctrl) trace continuously.
- flattenTags now drops null/undefined/empty-string tag values, fixing
literal `category="undefined"` tags that split every Grafana series in two.
- BaseNodeAdapter wires `static alwaysEmitFields` from the subclass.
- movementManager: track position by elapsed wall-time and capture partial
progress on abort, so a fast-re-commanding parent can't freeze an actuator
at its start position.
- Tests for the above.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- src/nodered/BaseNodeAdapter.js — base class for every nodeClass.js
Lifecycle: config build → domain instantiate → child.register on
Port 2 → tick (opt-in) or 'output-changed' subscription (default
event-driven) → status updater → input dispatch via commandRegistry →
close handler with clean teardown.
- index.js — additive exports of all Phase 1 modules:
UnitPolicy, ChildRouter, LatestWinsGate, HealthStatus, BaseDomain,
statusBadge, StatusUpdater, createRegistry, CommandRegistry,
BaseNodeAdapter, stats. Existing exports unchanged.
113 unit tests pass under node:test.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>