Skip to main content

JavaScript UDFs

This guide covers general JavaScript UDF (user-defined function) requirements, usage details, as well as limitations and supported language features.

Intoductory Example

The following example shows how to write a custom JavaScript UDF to execute an Automation when a state condition is met. This example takes advantage of some built-in functionality, such as the executeAutomation() and getState() functions.

var state = getState('office-temp');

// Execute an automation when the temperature
// is greater than 20 degrees
if (parseInt(state.value) > 20) {
executeAutomation('0181feaf-0d01-4e4f-942e-e3bbccdeee94');
}

Built-in Functions

The default JavaScript UDF environment has a number of built-in functions, however we've extended the built-in functions to include a range of functionality to interface and program different features within the Twin Engine. This can be anything from triggering an Automation to creating a new Model.

Limits & Restrictions

Below is a table of all the limitations which are applied to each UDF execution. Violation of this limits will result in either the UDF not executing or being terminated.

TypeLimitDescription
Array Length1,000The maximum number of items allowed within a single array.
Memory Allocation6MBThe maximum amount of memory a single UDF can be allocated. Exceeding this amount will result in early termination.
Recursion1,000If any loop exceeds the recusion limit, the UDF will be terminated.
Statements10,000The maximum number of declared statements. See here for more details.
Duration5 secondsThe maximum amount of time a UDF execution can last before being terminated.

Supported Features

Below is a comprehensive list of all features that are/not supported in the JavaScript UDFs.

ECMAScript 2015 (ES6)

  • ✔ ArrayBuffer
  • ✔ Arrow function expression
  • ✔ Binary and octal literals
  • ✔ Class support
  • ✔ DataView
  • ✔ Destructuring
  • ✔ Default, rest and spread
  • ✔ Enhanced object literals
  • ✔ for...of
  • ❌ Generators
  • ✔ Template strings
  • ✔ Lexical scoping of variables (let and const)
  • ✔ Map and Set
  • ✔ Modules and module loaders
  • ✔ Promises (Experimental, API is unstable)
  • ✔ Reflect
  • ✔ Proxies
  • ✔ Symbols
  • ❌ Tail calls
  • ✔ Typed arrays
  • ✔ Unicode
  • ✔ Weakmap and Weakset

ECMAScript 2016

  • ✔ Array.prototype.includes
  • ❌ await, async
  • ✔ Block-scoping of variables and functions
  • ✔ Exponentiation operator **
  • ✔ Destructuring patterns (of variables)

ECMAScript 2017

  • ✔ Object.values, Object.entries and Object.getOwnPropertyDescriptors

ECMAScript 2018

  • ✔ Promise.prototype.finally
  • ✔ Rest/spread operators for object literals (...identifier),

ECMAScript 2019

  • ✔ Array.prototype.flat, Array.prototype.flatMap
  • ✔ String.prototype.trimStart, String.prototype.trimEnd
  • ✔ Object.fromEntries
  • ✔ Symbol.description
  • ✔ Optional catch binding

ECMAScript 2020

  • ✔ BigInt
  • ❌ export * as ns from
  • ✔ for-in enhancements
  • ✔ globalThis object
  • ✔ import
  • ✔ import.meta
  • ✔ Nullish coalescing operator (??)
  • ✔ Optional chaining
  • ❌ Promise.allSettled
  • ✔ String.prototype.matchAll

ECMAScript 2021

  • ✔ Logical Assignment Operators (&&= ||= ??=)
  • ✔ Numeric Separators (1_000)
  • ✔ AggregateError
  • ❌ Promise.any
  • ✔ String.prototype.replaceAll
  • ❌ WeakRef and FinalizationRegistry

ECMAScript 2022

  • ❌ Class Fields
  • ❌ RegExp Match Indices
  • ❌ Top-level await
  • ❌ Ergonomic brand checks for Private Fields
  • ✔ .at()
  • ✔ Accessible Object.prototype.hasOwnProperty (Object.hasOwn)
  • ❌ Class Static Block
  • ✔ Error Cause

ECMAScript Stage 3

  • ✔ Array find from last
  • ✔ ShadowRealm