Blockly ts - #2354
Open
GermanBluefox wants to merge 29 commits into
Open
Conversation
# Conflicts: # README.md # admin/assets/mf-entry-bootstrap-0-425e1f28.js # admin/assets/mf-entry-bootstrap-0-44cbc963.js # admin/assets/mf-entry-bootstrap-0-c61f5911.js # admin/mf-stats.json # admin/tab.html
- TriggerMessage: starts a rule from onMessage(), so a rule can be called from outside via messageTo(). Adds STANDARD_FUNCTION_MESSAGE(_ONCHANGE) and a getReplacesInText branch, so %s in the actions is the payload. - ConditionFunction: a condition written in JavaScript, the counterpart to the "User function" action. The code is a function body and must return. - ActionNotification: registerNotification(), optionally as an alert. - ActionToggleState: switches a state between two arbitrary values. The current value is compared as text and written typed, so a number state recognises its own first value. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
TriggerFile subscribes with onFile() and starts the rule when a file of an object is written or deleted - a new camera image, an edited vis project. Both the object and the file name may contain *, the way the sandbox reads them. The file content is deliberately not requested: a rule cannot use it, and asking would read every changed file from disk for nothing. In the texts of the actions %s is the file name and %id the object it belongs to. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- TriggerObject (onObject): reacts to the object itself instead of its value, so a rule can notice a datapoint appearing or disappearing. A deletion arrives without `obj`, which the "React on" filter uses. - TriggerLog (onLog): reacts to entries in the ioBroker log. The sandbox drops this script's own output while the handler runs synchronously, so the plain case cannot loop; the text filter covers the rest. - TriggerOnStop (onStop): runs the rule once more while it is stopped, for cleanup. Unlike the other hooks the adapter waits for this one, so the template is a plain function that reports back through `_done` instead of an async one - otherwise every stop would sit out its full timeout. The timeout is configurable, since the actions have to fit into it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The rule editor emits a JavaScript script that nothing ever parses - a block with a stray quote or a broken comment takes the rule down at runtime, with an error pointing at code the user never wrote. The blockly generator next door has golden files for exactly that; the rules had nothing. 33 cases compile real rules with the real blocks and check the result twice: that it parses (wrapped in the async IIFE `createVM` puts around every script), and that the pieces carrying the meaning are in it - the %s substitutions, the object/log/file filters, the typed literals of the toggle, and that `onStop` reaches its done callback on the error path too. Verified by mutation: dropping the escaping in ActionToggleState.literal fails exactly the two tests that cover it, both on the parse check. vitest.config.ts had to repeat the "@" alias - it does not read vite.config.ts, and StandardBlocks imports through the alias. Note that no workflow runs `vitest` yet, so this suite - and the 13 AiChat ones next to it - only run when started by hand in src-editor. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The editor is its own package, and the root "npm test" is declarations plus mocha - so nothing ever started its 486 vitest tests. They only ran when somebody remembered to run them by hand in src-editor. A job of its own rather than a step in "build": a failing test should not be reported as a broken build, and it runs in parallel instead of in front of the adapter tests. "auto-merge" now waits for it too, otherwise a red editor test would still merge. Only the editor's own dependencies are installed - a scan over all 167 source files confirms every package they import is declared in src-editor's package.json, so nothing falls back to the root node_modules. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ActionHTTPCall emitted `request(url)`. That was a global back when the adapter bundled the package of that name; it is gone, and the VM context is exactly the sandbox object (`runInNewContext(sandbox, ...)` in main.ts), so every rule using this block ended in "ReferenceError: request is not defined" - and took the rest of the rule down with it. It now calls `httpGet`, which the sandbox does provide. Called back rather than awaited, so the rule carries on while the request runs, the way the block behaved while it still worked. The callback reports the status code, or the error, back to the editor's debug view; the sandbox logs a failed request by itself, so the block does not log it twice. The URL is now written with JSON.stringify instead of quoting by hand, which also covers a backslash, and the comment line no longer takes a line break from the URL. Four tests cover it, one of them asserting that `request(` is gone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- TriggerEnumMembers (onEnumMembers): starts the rule when any state of a room or function changes. The state trigger needs one block per datapoint, which does not survive "any window on the ground floor"; this follows the enum, so a device added to the room later is included without touching the rule. Its callback is an ordinary state subscription, so it reuses the state templates and joins that branch of getReplacesInText - %s and %id mean there what they mean everywhere else. - ActionMessageTo (messageTo): the other half of the "On message" trigger. Rules could be called by a script but could never call one, so a rule could not be used as a building block by another rule. - ActionSetStateChanged (setStateChangedAsync): writes only when the value differs. Every write is an event, and a rule on a schedule writing the same value every minute keeps history, logging and every subscriber busy for nothing. The last one derives from ActionSetState rather than copying its 350 lines of object picker and type aware value field - the difference is one call in compile(). For that, ActionSetState now passes `new.target` to the base constructor instead of hardcoding itself, so a derived block describes itself with its own name and icon. A test covers exactly that. 14 tests, all against the real blocks; suite is at 50 for the rule editor. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The surface under the rule was a photograph with a flat colour laid over it, and every theme had to pick its own opacity for that overlay. In the blue themes the overlay was #ffffff00 - fully transparent - so the photo simply was the background: a saturated navy-to-cyan diagonal behind translucent cards. Each theme now names its own background instead, as one token holding the whole value, so a theme can be flat or a gradient without the stylesheet caring. The gradients travel little and sit at 160deg, deliberately not aligned with the horizontal bands, so they do not read as a fourth band and the 6% rail washes stay visible - they were drowned by the photo before. Contrast of the card text, composited through the translucent card onto both gradient stops: blue 6.9-7.5:1, dark 5.8-6.0:1, modernDark 14.9:1, modernLight 17.6:1. The blue theme measured 7.7-10.2:1 over the photo, so it gives up some headroom at the bright end and gets one predictable value instead of a range that depended on where a card happened to sit. The image was referenced from this one rule only, so src/Components/assets is rid of it. public/back.jpg and its build copy are untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
# Conflicts: # admin/assets/AiChatPanel-BcMfnHrz.js # admin/assets/AiChatPanel-C4kuqP2U.js # admin/assets/AiChatPanel-M1b4cNWQ.js # admin/assets/RulesEditor-ByjgEaVo.js # admin/assets/index-BvPVHv3P.js # admin/assets/mf-entry-bootstrap-0-425e1f28.js # admin/assets/mf-entry-bootstrap-0-a03ecebd.js # admin/assets/mf-entry-bootstrap-0-e7c9e343.js # admin/mf-stats.json # admin/tab.html # src-editor/src/Components/RulesEditor/components/StandardBlocks/index.tsx # src-editor/src/Components/RulesEditor/helpers/MaterialDynamicIcon.tsx # src-editor/src/i18n/de.json # src-editor/src/i18n/en.json # src-editor/src/i18n/es.json # src-editor/src/i18n/fr.json # src-editor/src/i18n/it.json # src-editor/src/i18n/nl.json # src-editor/src/i18n/pl.json # src-editor/src/i18n/pt.json # src-editor/src/i18n/ru.json # src-editor/src/i18n/uk.json # src-editor/src/i18n/zh-cn.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.