P11.3 + P11.4: BaseNodeAdapter query.units + wikiGen Unit column
P11.3 BaseNodeAdapter auto-wires query.units:
Implicit query.units topic registered if subclass commands don't
already declare one. Returns {node, units: {topic → {measure,
default, accepted: [...]}}} via convert.possibilities. Subclass
query.units overrides. 17/17 tests; BaseNodeAdapter.js 211 lines.
P11.4 wikiGen Unit column:
Auto-generated topic-contract table grows a Unit column showing
`<measure> (default <unit>)` for topics with units, '—' otherwise.
Effect column now uses descriptor.description when present (P11.2
field), falls back to generic per-prefix sentence. wikiGen.js 303
→ 315 lines. WIKI_TEMPLATE.md §5 sample updated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,9 +18,36 @@ const ConfigManager = require('../configs/index.js');
|
||||
const OutputUtils = require('../helper/outputUtils.js');
|
||||
const { createRegistry } = require('./commandRegistry.js');
|
||||
const { StatusUpdater } = require('./statusUpdater.js');
|
||||
const convert = require('../convert');
|
||||
|
||||
const REGISTRATION_DELAY_MS = 100;
|
||||
|
||||
function _buildImplicitUnitsCommand(getCommands, getNodeName) {
|
||||
return {
|
||||
topic: 'query.units',
|
||||
payloadSchema: { type: 'any' },
|
||||
description: 'Returns the unit spec (measure, default, accepted) for every topic that declares units.',
|
||||
handler: (source, msg, ctx) => {
|
||||
const units = {};
|
||||
for (const d of getCommands()) {
|
||||
if (!d.units) continue;
|
||||
const accepted = (convert && typeof convert.possibilities === 'function')
|
||||
? convert.possibilities(d.units.measure) : [];
|
||||
units[d.topic] = {
|
||||
measure: d.units.measure,
|
||||
default: d.units.default,
|
||||
accepted,
|
||||
};
|
||||
}
|
||||
const reply = Object.assign({}, msg, {
|
||||
topic: 'query.units',
|
||||
payload: { node: getNodeName(), units },
|
||||
});
|
||||
if (ctx && typeof ctx.send === 'function') ctx.send([reply, null, null]);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
class BaseNodeAdapter {
|
||||
constructor(uiConfig, RED, nodeInstance, nameOfNode) {
|
||||
const ctor = this.constructor;
|
||||
@@ -56,7 +83,15 @@ class BaseNodeAdapter {
|
||||
this.node.source = this.source;
|
||||
|
||||
this._output = new OutputUtils();
|
||||
this._commands = createRegistry(ctor.commands, { logger: this.source?.logger });
|
||||
const userHasUnitsQuery = ctor.commands.some(
|
||||
(c) => c && (c.topic === 'query.units' || (Array.isArray(c.aliases) && c.aliases.includes('query.units'))));
|
||||
const mergedCommands = userHasUnitsQuery
|
||||
? ctor.commands
|
||||
: ctor.commands.concat([_buildImplicitUnitsCommand(
|
||||
() => this._commands.list(),
|
||||
() => this.name,
|
||||
)]);
|
||||
this._commands = createRegistry(mergedCommands, { logger: this.source?.logger });
|
||||
|
||||
this._tickInterval = null;
|
||||
this._outputChangedListener = null;
|
||||
|
||||
Reference in New Issue
Block a user