Guide

ProtoNodes Guide

Complete reference for configuring nodes, dependencies, and loading actions correctly.

When to use SINGLE / MULTI / LIST / COMPLEX

TypeWhen to use itExample
SINGLESingle value (string, number, boolean, simple object).qty, price, note
MULTIChoice among options (select/combobox).region, province, city
LISTDynamic collection of repeated elements.Order lines, contact list
COMPLEXObject composed of multiple fields.customer with first name/last name/address

ProtoNode structure

PropertyTypeMeaningWhen to use it
namestringLogical node name.Always.
pathstringPath in the serialized payload.Always.
typestringSINGLE MULTI LIST COMPLEXAlways.
depNodeDependency[]Dependencies from other nodes.Always (even empty).
laLoadingActionHow the node gets its value.Always.
defaultValueanyInitial value.When an initial bootstrap value is needed.
protoProtoNodeChild blueprint.LIST only.
protosProtoNode[]Child fields.COMPLEX only.

LoadingAction (la)

PropertyMeaningRuntime detail
typeLoading typeUSER_SELECTION, HTTP verbs, CUSTOM_FUNCTION.
addrRelative endpointSupports placeholders like {region}.
serviceNameService nameResolved from extApis map.
headersNode headersMerged with service headers.
bodyTypeBody formatJSON_OBJECT or MULTI_PART_FORM_DATA.
functionNameCustom function nameName registered in customFunctions.

la.type options

  • USER_SELECTION: value set by UI/code.
  • GET/POST/PUT/PATCH/DELETE: value fetched from backend.
  • CUSTOM_FUNCTION: value computed locally.

Dependencies (dep)

PropertyMeaningEffect
nodeNameSource nodeNode from which to read value.
parameterNameParameter nameMapping for URL/query/body/custom function.
isOptionalOptionalityIf false, node waits for that value.
onUpdateInvalidationIf true: emits null then recalculates.
typeTransport channelPATH_VARIABLE, REQUEST_PARAMETER, BODY.
namingResolvingRuleNaming ruleUseful in nested/list scenarios.

Practical effect of onUpdate

  • onUpdate: true: when dependency changes, node goes to null then recalculates.
  • onUpdate: false: direct recalculation without null transition.

Runtime examples after defining nodes

GET with two query parameters

Show example
{
  "name": "myTablesPaged",
  "path": "/myTablesPaged",
  "type": "SINGLE",
  "dep": [
    {
      "nodeName": "page",
      "parameterName": "page",
      "isOptional": true,
      "onUpdate": true,
      "type": "REQUEST_PARAMETER"
    },
    {
      "nodeName": "size",
      "parameterName": "size",
      "isOptional": true,
      "onUpdate": true,
      "type": "REQUEST_PARAMETER"
    }
  ],
  "la": {
    "type": "GET",
    "addr": "/mytables",
    "serviceName": "api"
  }
}

SINGLE + USER_SELECTION

Show example
(wb.getNodeByName("qty") as any).next(3);

MULTI + GET

Show example
const region = wb.getNodeByNameAndType("region", "MULTI") as any;
region.setSelection(0);

CUSTOM_FUNCTION

Show example
const wb2 = new WaveBinder(LICENSE, PROTO_NODES, extApis, [
  { name: "toLabel", implementation: (v) => (v ? `Label:${v}` : null) }
]);
wb2.tangleNodes();

Custom Function: correct form

Show example
// Registration
const customFunctions = [
  { name: "toLabel", implementation: (province) => (province ? `Province:${province}` : null) }
];

// Node
{
  "name": "provinceLabel",
  "path": "/provinceLabel",
  "type": "SINGLE",
  "dep": [
    {
      "nodeName": "province",
      "parameterName": "province",
      "isOptional": true,
      "onUpdate": true,
      "type": "BODY"
    }
  ],
  "la": {
    "type": "CUSTOM_FUNCTION",
    "functionName": "toLabel"
  }
}

Custom Function: delay node cascade

Show example
          
// Registration
const wb = new WaveBinder(LICENSE, PROTO_NODES, extApis, [
    {
        name: "delayCascade",
        // When calling a custom function, a snapshot of the current node is passed as an optional argument
        implementation: (value, nodeSnapshot) => {
            if(!value) {
             return null
            }
            setTimeout(() => {
                wb.getNodeByName(nodeSnapshot.node.name).next(value);
            }, 300);
        }
    }
]);

// Initiate
wb.getNodeByName("node-0").next(value);

// Nodes
[
  {
    "name": "node-0",
    "type": "SINGLE",
    "path": "/node-0",
    "la": {
      "type": "USER_SELECTION"
    },
    "dep": []
  },
  {
    "name": "node-1",
    "type": "SINGLE",
    "path": "/node-1",
    "la": {
      "type": "CUSTOM_FUNCTION",
      "functionName": "delayCascade"
    },
    "dep": [
      {
        "nodeName": "node-0",
        "isOptional": false,
        "onUpdate": true
      }
    ]
  },
  {
    "name": "node-2",
    "type": "SINGLE",
    "path": "/node-2",
    "la": {
      "type": "CUSTOM_FUNCTION",
      "functionName": "delayCascade"
    },
    "dep": [
      {
        "nodeName": "node-1",
        "isOptional": false,
        "onUpdate": true
      }
    ]
  }
]
          
        

The library tries parameter-name mapping first; if unreliable (for example minify), it falls back to dependency order.

Best practice: align function argument names with dependency parameterName values. It is not strictly mandatory (fallback by dependency order exists), but strongly recommended to avoid ambiguity in minified/transpiled builds.