@synergenius/flow-weaver 0.17.10 → 0.17.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast/types.d.ts +1 -1
- package/dist/cli/flow-weaver.mjs +14 -13
- package/dist/diagram/geometry.js +4 -4
- package/dist/diagram/renderer.js +6 -6
- package/dist/diagram/theme.d.ts +1 -0
- package/dist/diagram/theme.js +2 -1
- package/dist/editor-completions/annotationValues.js +1 -1
- package/dist/generated-version.d.ts +1 -1
- package/dist/generated-version.js +1 -1
- package/docs/reference/advanced-annotations.md +37 -1
- package/docs/reference/concepts.md +1 -0
- package/docs/reference/jsdoc-grammar.md +1 -1
- package/package.json +1 -1
package/dist/ast/types.d.ts
CHANGED
|
@@ -786,7 +786,7 @@ export type TNodeTagAST = {
|
|
|
786
786
|
};
|
|
787
787
|
/** Visual customization for node types */
|
|
788
788
|
export type TNodeVisualsAST = {
|
|
789
|
-
/** Theme color: blue, purple,
|
|
789
|
+
/** Theme color: blue, purple, cyan, orange, pink, green, red, yellow (teal is an alias for cyan) */
|
|
790
790
|
color?: string;
|
|
791
791
|
/** Icon preset name */
|
|
792
792
|
icon?: string;
|
package/dist/cli/flow-weaver.mjs
CHANGED
|
@@ -9671,7 +9671,7 @@ var VERSION;
|
|
|
9671
9671
|
var init_generated_version = __esm({
|
|
9672
9672
|
"src/generated-version.ts"() {
|
|
9673
9673
|
"use strict";
|
|
9674
|
-
VERSION = "0.17.
|
|
9674
|
+
VERSION = "0.17.11";
|
|
9675
9675
|
}
|
|
9676
9676
|
});
|
|
9677
9677
|
|
|
@@ -37889,7 +37889,7 @@ function darkenHex(hex, amount) {
|
|
|
37889
37889
|
const nb = Math.round(b * (1 - amount));
|
|
37890
37890
|
return `#${nr.toString(16).padStart(2, "0")}${ng.toString(16).padStart(2, "0")}${nb.toString(16).padStart(2, "0")}`;
|
|
37891
37891
|
}
|
|
37892
|
-
var DARK_PORT_COLORS, LIGHT_PORT_COLORS, DARK_FAILURE_COLOR, LIGHT_FAILURE_COLOR, NODE_VARIANT_COLORS, DARK_PALETTE, LIGHT_PALETTE, TYPE_ABBREVIATIONS, NODE_ICON_PATHS, VALID_NODE_ICONS;
|
|
37892
|
+
var DARK_PORT_COLORS, LIGHT_PORT_COLORS, DARK_FAILURE_COLOR, LIGHT_FAILURE_COLOR, NODE_DEFAULT_COLOR, NODE_VARIANT_COLORS, DARK_PALETTE, LIGHT_PALETTE, TYPE_ABBREVIATIONS, NODE_ICON_PATHS, VALID_NODE_ICONS;
|
|
37893
37893
|
var init_theme = __esm({
|
|
37894
37894
|
"src/diagram/theme.ts"() {
|
|
37895
37895
|
"use strict";
|
|
@@ -37931,6 +37931,7 @@ var init_theme = __esm({
|
|
|
37931
37931
|
};
|
|
37932
37932
|
DARK_FAILURE_COLOR = "#ff4f4f";
|
|
37933
37933
|
LIGHT_FAILURE_COLOR = "#e34646";
|
|
37934
|
+
NODE_DEFAULT_COLOR = "#334155";
|
|
37934
37935
|
NODE_VARIANT_COLORS = {
|
|
37935
37936
|
blue: { border: "#548ce3", darkBorder: "#5e9eff" },
|
|
37936
37937
|
// blue-shade-2 / blue-dark-shade-1
|
|
@@ -37938,6 +37939,8 @@ var init_theme = __esm({
|
|
|
37938
37939
|
// purple-shade-2 / purple-dark-shade-1
|
|
37939
37940
|
cyan: { border: "#63ccc4", darkBorder: "#6fe5dc" },
|
|
37940
37941
|
// cyan-shade-2 / cyan-dark-shade-1
|
|
37942
|
+
teal: { border: "#63ccc4", darkBorder: "#6fe5dc" },
|
|
37943
|
+
// alias for cyan
|
|
37941
37944
|
orange: { border: "#e3732d", darkBorder: "#ff8133" },
|
|
37942
37945
|
// orange-shade-2 / orange-dark-shade-1
|
|
37943
37946
|
pink: { border: "#e349c2", darkBorder: "#ff52da" },
|
|
@@ -37946,10 +37949,8 @@ var init_theme = __esm({
|
|
|
37946
37949
|
// green-shade-2 / green-dark-shade-1
|
|
37947
37950
|
red: { border: "#e34646", darkBorder: "#ff4f4f" },
|
|
37948
37951
|
// red-shade-2 / red-dark-shade-1
|
|
37949
|
-
yellow: { border: "#e3a82b", darkBorder: "#ffbd30" }
|
|
37952
|
+
yellow: { border: "#e3a82b", darkBorder: "#ffbd30" }
|
|
37950
37953
|
// yellow-shade-2 / yellow-dark-shade-1
|
|
37951
|
-
teal: { border: "#3db0a8", darkBorder: "#4dc7be" }
|
|
37952
|
-
// teal-shade-2 / teal-dark-shade-1
|
|
37953
37954
|
};
|
|
37954
37955
|
DARK_PALETTE = {
|
|
37955
37956
|
background: "#202139",
|
|
@@ -50852,7 +50853,7 @@ function buildDiagramGraph(ast, options = {}) {
|
|
|
50852
50853
|
diagramNodes.set("Start", {
|
|
50853
50854
|
id: "Start",
|
|
50854
50855
|
label: "Start",
|
|
50855
|
-
color:
|
|
50856
|
+
color: NODE_DEFAULT_COLOR,
|
|
50856
50857
|
icon: "startNode",
|
|
50857
50858
|
isVirtual: true,
|
|
50858
50859
|
inputs: [],
|
|
@@ -50875,7 +50876,7 @@ function buildDiagramGraph(ast, options = {}) {
|
|
|
50875
50876
|
diagramNodes.set("Exit", {
|
|
50876
50877
|
id: "Exit",
|
|
50877
50878
|
label: "Exit",
|
|
50878
|
-
color:
|
|
50879
|
+
color: NODE_DEFAULT_COLOR,
|
|
50879
50880
|
icon: "exitNode",
|
|
50880
50881
|
isVirtual: true,
|
|
50881
50882
|
inputs: exitInputs,
|
|
@@ -51181,7 +51182,7 @@ function filterNonScopedPorts(ports) {
|
|
|
51181
51182
|
return result;
|
|
51182
51183
|
}
|
|
51183
51184
|
function resolveNodeColor(color, theme = "dark") {
|
|
51184
|
-
if (!color) return
|
|
51185
|
+
if (!color) return NODE_DEFAULT_COLOR;
|
|
51185
51186
|
const variant = NODE_VARIANT_COLORS[color];
|
|
51186
51187
|
if (variant) return theme === "dark" ? variant.darkBorder : variant.border;
|
|
51187
51188
|
return color;
|
|
@@ -51890,12 +51891,12 @@ function renderScopeConnection(parts2, conn, allConnections, parentNodeId) {
|
|
|
51890
51891
|
);
|
|
51891
51892
|
}
|
|
51892
51893
|
function renderNodeBody(parts2, node, theme, indent) {
|
|
51893
|
-
const strokeColor = node.color !==
|
|
51894
|
+
const strokeColor = node.color !== NODE_DEFAULT_COLOR ? node.color : theme.nodeIconColor;
|
|
51894
51895
|
parts2.push(
|
|
51895
51896
|
`${indent}<rect x="${node.x}" y="${node.y}" width="${node.width}" height="${node.height}" rx="${BORDER_RADIUS}" fill="${theme.nodeFill}" stroke="${strokeColor}" stroke-width="2" filter="url(#node-shadow)"/>`
|
|
51896
51897
|
);
|
|
51897
51898
|
const iconPath = NODE_ICON_PATHS[node.icon] ?? NODE_ICON_PATHS.code;
|
|
51898
|
-
const iconColor = node.color !==
|
|
51899
|
+
const iconColor = node.color !== NODE_DEFAULT_COLOR ? node.color : theme.nodeIconColor;
|
|
51899
51900
|
const iconSize = 40;
|
|
51900
51901
|
const iconX = node.x + (node.width - iconSize) / 2;
|
|
51901
51902
|
const iconY = node.y + (node.height - iconSize) / 2;
|
|
@@ -51907,7 +51908,7 @@ function renderNode(node, theme, themeName, allConnections) {
|
|
|
51907
51908
|
const parts2 = [];
|
|
51908
51909
|
parts2.push(` <g data-node-id="${escapeXml(node.id)}">`);
|
|
51909
51910
|
if (node.scopeChildren && node.scopeChildren.length > 0) {
|
|
51910
|
-
const strokeColor = node.color !==
|
|
51911
|
+
const strokeColor = node.color !== NODE_DEFAULT_COLOR ? node.color : theme.nodeIconColor;
|
|
51911
51912
|
parts2.push(
|
|
51912
51913
|
` <rect x="${node.x}" y="${node.y}" width="${node.width}" height="${node.height}" rx="${BORDER_RADIUS}" fill="${theme.nodeFill}" stroke="${strokeColor}" stroke-width="2" filter="url(#node-shadow)"/>`
|
|
51913
51914
|
);
|
|
@@ -51954,7 +51955,7 @@ function renderNodeLabel(parts2, node, theme) {
|
|
|
51954
51955
|
const labelAnchor = isScoped ? "start" : "middle";
|
|
51955
51956
|
parts2.push(` <g data-label-for="${escapeXml(node.id)}">`);
|
|
51956
51957
|
parts2.push(` <rect x="${labelBgX}" y="${labelBgY}" width="${labelBgWidth}" height="${labelBgHeight}" rx="6" fill="${theme.labelBadgeFill}" opacity="0.8"/>`);
|
|
51957
|
-
parts2.push(` <text class="node-label" x="${labelTextX}" y="${labelBgY + labelBgHeight / 2 + 6}" text-anchor="${labelAnchor}" fill="${node.color !==
|
|
51958
|
+
parts2.push(` <text class="node-label" x="${labelTextX}" y="${labelBgY + labelBgHeight / 2 + 6}" text-anchor="${labelAnchor}" fill="${node.color !== NODE_DEFAULT_COLOR ? node.color : theme.labelColor}">${labelText}</text>`);
|
|
51958
51959
|
parts2.push(` </g>`);
|
|
51959
51960
|
}
|
|
51960
51961
|
function renderPortLabelsForNode(parts2, node, theme, themeName, showPortLabels) {
|
|
@@ -105876,7 +105877,7 @@ function displayInstalledPackage(pkg) {
|
|
|
105876
105877
|
// src/cli/index.ts
|
|
105877
105878
|
init_logger();
|
|
105878
105879
|
init_error_utils();
|
|
105879
|
-
var version2 = true ? "0.17.
|
|
105880
|
+
var version2 = true ? "0.17.11" : "0.0.0-dev";
|
|
105880
105881
|
var program2 = new Command();
|
|
105881
105882
|
program2.name("flow-weaver").description("Flow Weaver Annotations - Compile and validate workflow files").option("-v, --version", "Output the current version").option("--no-color", "Disable colors").option("--color", "Force colors").on("option:version", () => {
|
|
105882
105883
|
logger.banner(version2);
|
package/dist/diagram/geometry.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isExecutePort, isSuccessPort, isFailurePort, SCOPED_PORT_NAMES, isScopedStartPort, isScopedSuccessPort, isScopedFailurePort } from '../constants.js';
|
|
2
2
|
import { assignImplicitPortOrders } from '../utils/port-ordering.js';
|
|
3
|
-
import { getPortColor, NODE_VARIANT_COLORS, TYPE_ABBREVIATIONS } from './theme.js';
|
|
3
|
+
import { getPortColor, NODE_VARIANT_COLORS, NODE_DEFAULT_COLOR, TYPE_ABBREVIATIONS } from './theme.js';
|
|
4
4
|
import { layoutWorkflow } from './layout.js';
|
|
5
5
|
import { calculateOrthogonalPathSafe, TrackAllocator } from './orthogonal-router.js';
|
|
6
6
|
// ---- Constants (matching React component-node) ----
|
|
@@ -707,7 +707,7 @@ export function buildDiagramGraph(ast, options = {}) {
|
|
|
707
707
|
diagramNodes.set('Start', {
|
|
708
708
|
id: 'Start',
|
|
709
709
|
label: 'Start',
|
|
710
|
-
color:
|
|
710
|
+
color: NODE_DEFAULT_COLOR,
|
|
711
711
|
icon: 'startNode',
|
|
712
712
|
isVirtual: true,
|
|
713
713
|
inputs: [],
|
|
@@ -731,7 +731,7 @@ export function buildDiagramGraph(ast, options = {}) {
|
|
|
731
731
|
diagramNodes.set('Exit', {
|
|
732
732
|
id: 'Exit',
|
|
733
733
|
label: 'Exit',
|
|
734
|
-
color:
|
|
734
|
+
color: NODE_DEFAULT_COLOR,
|
|
735
735
|
icon: 'exitNode',
|
|
736
736
|
isVirtual: true,
|
|
737
737
|
inputs: exitInputs,
|
|
@@ -1098,7 +1098,7 @@ function filterNonScopedPorts(ports) {
|
|
|
1098
1098
|
}
|
|
1099
1099
|
function resolveNodeColor(color, theme = 'dark') {
|
|
1100
1100
|
if (!color)
|
|
1101
|
-
return
|
|
1101
|
+
return NODE_DEFAULT_COLOR;
|
|
1102
1102
|
const variant = NODE_VARIANT_COLORS[color];
|
|
1103
1103
|
if (variant)
|
|
1104
1104
|
return theme === 'dark' ? variant.darkBorder : variant.border;
|
package/dist/diagram/renderer.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getTheme, getPortColor, getPortRingColor, TYPE_ABBREVIATIONS, NODE_ICON_PATHS } from './theme.js';
|
|
1
|
+
import { getTheme, getPortColor, getPortRingColor, TYPE_ABBREVIATIONS, NODE_ICON_PATHS, NODE_DEFAULT_COLOR } from './theme.js';
|
|
2
2
|
import { PORT_RADIUS, BORDER_RADIUS, LABEL_HEIGHT, LABEL_GAP, SCOPE_PORT_COLUMN, measureText } from './geometry.js';
|
|
3
3
|
function escapeXml(str) {
|
|
4
4
|
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
@@ -113,10 +113,10 @@ function renderScopeConnection(parts, conn, allConnections, parentNodeId) {
|
|
|
113
113
|
// ---- Node rendering ----
|
|
114
114
|
/** Render node body rect + icon */
|
|
115
115
|
function renderNodeBody(parts, node, theme, indent) {
|
|
116
|
-
const strokeColor = node.color !==
|
|
116
|
+
const strokeColor = node.color !== NODE_DEFAULT_COLOR ? node.color : theme.nodeIconColor;
|
|
117
117
|
parts.push(`${indent}<rect x="${node.x}" y="${node.y}" width="${node.width}" height="${node.height}" rx="${BORDER_RADIUS}" fill="${theme.nodeFill}" stroke="${strokeColor}" stroke-width="2" filter="url(#node-shadow)"/>`);
|
|
118
118
|
const iconPath = NODE_ICON_PATHS[node.icon] ?? NODE_ICON_PATHS.code;
|
|
119
|
-
const iconColor = node.color !==
|
|
119
|
+
const iconColor = node.color !== NODE_DEFAULT_COLOR ? node.color : theme.nodeIconColor;
|
|
120
120
|
const iconSize = 40;
|
|
121
121
|
const iconX = node.x + (node.width - iconSize) / 2;
|
|
122
122
|
const iconY = node.y + (node.height - iconSize) / 2;
|
|
@@ -126,8 +126,8 @@ function renderNode(node, theme, themeName, allConnections) {
|
|
|
126
126
|
const parts = [];
|
|
127
127
|
parts.push(` <g data-node-id="${escapeXml(node.id)}">`);
|
|
128
128
|
if (node.scopeChildren && node.scopeChildren.length > 0) {
|
|
129
|
-
// Scoped node: body rect only (
|
|
130
|
-
const strokeColor = node.color !==
|
|
129
|
+
// Scoped node: body rect only (icon omitted — children occupy the inner area)
|
|
130
|
+
const strokeColor = node.color !== NODE_DEFAULT_COLOR ? node.color : theme.nodeIconColor;
|
|
131
131
|
parts.push(` <rect x="${node.x}" y="${node.y}" width="${node.width}" height="${node.height}" rx="${BORDER_RADIUS}" fill="${theme.nodeFill}" stroke="${strokeColor}" stroke-width="2" filter="url(#node-shadow)"/>`);
|
|
132
132
|
renderScopedContent(parts, node, theme, themeName, allConnections);
|
|
133
133
|
}
|
|
@@ -178,7 +178,7 @@ function renderNodeLabel(parts, node, theme) {
|
|
|
178
178
|
const labelAnchor = isScoped ? 'start' : 'middle';
|
|
179
179
|
parts.push(` <g data-label-for="${escapeXml(node.id)}">`);
|
|
180
180
|
parts.push(` <rect x="${labelBgX}" y="${labelBgY}" width="${labelBgWidth}" height="${labelBgHeight}" rx="6" fill="${theme.labelBadgeFill}" opacity="0.8"/>`);
|
|
181
|
-
parts.push(` <text class="node-label" x="${labelTextX}" y="${labelBgY + labelBgHeight / 2 + 6}" text-anchor="${labelAnchor}" fill="${node.color !==
|
|
181
|
+
parts.push(` <text class="node-label" x="${labelTextX}" y="${labelBgY + labelBgHeight / 2 + 6}" text-anchor="${labelAnchor}" fill="${node.color !== NODE_DEFAULT_COLOR ? node.color : theme.labelColor}">${labelText}</text>`);
|
|
182
182
|
parts.push(` </g>`);
|
|
183
183
|
}
|
|
184
184
|
/** Render port labels for a node if showPortLabels is enabled */
|
package/dist/diagram/theme.d.ts
CHANGED
package/dist/diagram/theme.js
CHANGED
|
@@ -26,16 +26,17 @@ const LIGHT_FAILURE_COLOR = '#e34646'; // red-shade-2
|
|
|
26
26
|
// ---- Node theme variant colors ----
|
|
27
27
|
// Dark: border = X-dark-shade-1 (base), icon = X-dark-shade-3
|
|
28
28
|
// Light: border = X-shade-2
|
|
29
|
+
export const NODE_DEFAULT_COLOR = '#334155';
|
|
29
30
|
export const NODE_VARIANT_COLORS = {
|
|
30
31
|
blue: { border: '#548ce3', darkBorder: '#5e9eff' }, // blue-shade-2 / blue-dark-shade-1
|
|
31
32
|
purple: { border: '#9f5fe3', darkBorder: '#b36bff' }, // purple-shade-2 / purple-dark-shade-1
|
|
32
33
|
cyan: { border: '#63ccc4', darkBorder: '#6fe5dc' }, // cyan-shade-2 / cyan-dark-shade-1
|
|
34
|
+
teal: { border: '#63ccc4', darkBorder: '#6fe5dc' }, // alias for cyan
|
|
33
35
|
orange: { border: '#e3732d', darkBorder: '#ff8133' }, // orange-shade-2 / orange-dark-shade-1
|
|
34
36
|
pink: { border: '#e349c2', darkBorder: '#ff52da' }, // pink-shade-2 / pink-dark-shade-1
|
|
35
37
|
green: { border: '#0ec850', darkBorder: '#10e15a' }, // green-shade-2 / green-dark-shade-1
|
|
36
38
|
red: { border: '#e34646', darkBorder: '#ff4f4f' }, // red-shade-2 / red-dark-shade-1
|
|
37
39
|
yellow: { border: '#e3a82b', darkBorder: '#ffbd30' }, // yellow-shade-2 / yellow-dark-shade-1
|
|
38
|
-
teal: { border: '#3db0a8', darkBorder: '#4dc7be' }, // teal-shade-2 / teal-dark-shade-1
|
|
39
40
|
};
|
|
40
41
|
// ---- Theme palettes (exact values from token system) ----
|
|
41
42
|
const DARK_PALETTE = {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.17.
|
|
1
|
+
export declare const VERSION = "0.17.11";
|
|
2
2
|
//# sourceMappingURL=generated-version.d.ts.map
|
|
@@ -481,7 +481,7 @@ These annotations go on `@flowWeaver nodeType` blocks:
|
|
|
481
481
|
| `@name` | Override display name | `@name MyCustomName` |
|
|
482
482
|
| `@label` | Human-readable label | `@label Fetch with Timeout` |
|
|
483
483
|
| `@description` | Node description | `@description Validates expense data` |
|
|
484
|
-
| `@color` | Custom color | `@color "#ff6b35"` |
|
|
484
|
+
| `@color` | Custom color | `@color purple` or `@color "#ff6b35"` |
|
|
485
485
|
| `@icon` | Custom icon | `@icon "database"` |
|
|
486
486
|
| `@tag` | Visual tag/badge | `@tag async` or `@tag beta "Experimental"` |
|
|
487
487
|
| `@scope` | Provides a named scope | `@scope processItem` |
|
|
@@ -491,6 +491,42 @@ These annotations go on `@flowWeaver nodeType` blocks:
|
|
|
491
491
|
|
|
492
492
|
---
|
|
493
493
|
|
|
494
|
+
## Available Colors
|
|
495
|
+
|
|
496
|
+
Named colors adapt to the diagram theme (dark/light). You can also pass any hex color directly (e.g. `@color "#ff6b35"`).
|
|
497
|
+
|
|
498
|
+
`blue` · `purple` · `cyan` · `orange` · `pink` · `green` · `red` · `yellow` · `teal` (alias for cyan)
|
|
499
|
+
|
|
500
|
+
## Available Icons
|
|
501
|
+
|
|
502
|
+
Icons render inside the node body in SVG diagrams. Names correspond to Material Symbols (outlined, weight 500).
|
|
503
|
+
|
|
504
|
+
**AI & ML:** `psychology` · `smartToy` · `autoAwesome` · `modelTraining` · `science` · `biotech`
|
|
505
|
+
|
|
506
|
+
**Data & storage:** `database` · `dataObject` · `tableChart` · `token` · `storage` · `memory`
|
|
507
|
+
|
|
508
|
+
**Cloud & network:** `api` · `webhook` · `cloudSync` · `cloudUpload` · `cloudDownload` · `dns` · `router` · `http` · `link`
|
|
509
|
+
|
|
510
|
+
**Security & auth:** `key` · `shield` · `vpnKey` · `verified` · `security` · `policy` · `adminPanelSettings`
|
|
511
|
+
|
|
512
|
+
**Logic & flow:** `altRoute` · `callSplit` · `callMerge` · `rule` · `filterAlt` · `repeat` · `sort`
|
|
513
|
+
|
|
514
|
+
**Actions & status:** `bolt` · `build` · `rocketLaunch` · `send` · `sync` · `refresh`
|
|
515
|
+
|
|
516
|
+
**Communication:** `notifications` · `email` · `campaign`
|
|
517
|
+
|
|
518
|
+
**Scheduling:** `event` · `schedule` · `timer`
|
|
519
|
+
|
|
520
|
+
**General tools:** `terminal` · `settings` · `tune` · `search` · `save` · `upload` · `download` · `edit` · `delete`
|
|
521
|
+
|
|
522
|
+
**Status:** `checkCircle` · `error` · `warning` · `info` · `help` · `visibility`
|
|
523
|
+
|
|
524
|
+
**Files:** `folder` · `description` · `attachFile`
|
|
525
|
+
|
|
526
|
+
**Structural:** `code` (default) · `flow` (workflow nodes) · `startNode` · `exitNode`
|
|
527
|
+
|
|
528
|
+
---
|
|
529
|
+
|
|
494
530
|
## Related Topics
|
|
495
531
|
|
|
496
532
|
- [Concepts](concepts) — Core workflow fundamentals
|
|
@@ -137,6 +137,7 @@ Expression nodes are pure functions where:
|
|
|
137
137
|
- Primitive/array return -> single output port
|
|
138
138
|
- Object return `{ a, b }` -> one port per property
|
|
139
139
|
- Best for: transformers, math, utilities, data mapping, async fetchers, API calls
|
|
140
|
+
- Optional `@color` and `@icon` annotations customize the node's appearance in SVG diagrams (see `advanced-annotations` for available values)
|
|
140
141
|
|
|
141
142
|
> **Start with expression mode.** Only switch to normal mode when you need to return data alongside a failure (error-with-data patterns) or for void side-effect functions. Expression nodes handle success/failure branching automatically — throw to trigger the `onFailure` path.
|
|
142
143
|
|
|
@@ -244,7 +244,7 @@ Multiple attribute brackets are allowed (zero or more). Attributes can be split
|
|
|
244
244
|
@node myAdd Add [minimized, label: "Compact"]
|
|
245
245
|
@node myAdd Add [pullExecution: trigger]
|
|
246
246
|
@node myAdd Add [size: 200 150]
|
|
247
|
-
@node myAdd Add [color: "
|
|
247
|
+
@node myAdd Add [color: "red", icon: "database"]
|
|
248
248
|
@node myAdd Add [tags: "math" "Math operation", "transform"]
|
|
249
249
|
@node myAdd Add [position: 180 0]
|
|
250
250
|
@node myAdd Add [label: "hi"] [color: "#f00"] [position: 360 0]
|
package/package.json
CHANGED