Actions

Complete reference for action definitions and step types

Overview

Actions define how your application responds to user interactions and events. Each action consists of a name and a sequence of steps that execute in order.

Action Definition

json
{
  "name": "incrementCounter",
  "steps": [
    { "do": "update", "target": "count", "operation": "increment" }
  ]
}
NameTypeRequiredDefaultDescription
namestringYes-Unique identifier for the action. Used in event handlers.
stepsActionStep[]Yes-Array of steps to execute when the action is triggered.

Set Step

Directly sets a state value.

json
{
  "do": "set",
  "target": "message",
  "value": { "expr": "lit", "value": "Hello!" }
}
NameTypeRequiredDefaultDescription
do"set"Yes-Step type identifier.
targetstringYes-State field to modify. Use dot notation for nested paths.
valueExpressionYes-Expression that evaluates to the new value.

Examples

json
// Set a simple value
{ "do": "set", "target": "name", "value": { "expr": "lit", "value": "John" } }

// Set from event parameter
{
  "do": "set",
  "target": "inputValue",
  "value": { "expr": "param", "name": "event", "path": "target.value" }
}

// Set nested property
{
  "do": "set",
  "target": "user.profile.name",
  "value": { "expr": "lit", "value": "Jane" }
}

Update Step

Applies a predefined operation to a state value.

json
{
  "do": "update",
  "target": "count",
  "operation": "increment"
}
NameTypeRequiredDefaultDescription

Operations

OperationDescriptionRequires ValueState Type
incrementAdds to a number (default: 1)No (optional value)number
decrementSubtracts from a number (default: 1)No (optional value)number
toggleFlips a boolean valueNoboolean
pushAppends to an arrayYeslist
popRemoves last element from arrayNolist
removeRemoves matching element from arrayYeslist
replaceAtReplaces element at a specific indexYes (index + value)list
insertAtInserts element at a specific indexYes (index + value)list
spliceDeletes and/or inserts at indexYes (index + deleteCount, optional value)list
mergeShallow-merges properties into an objectYesobject

Examples

json
// Increment counter
{ "do": "update", "target": "count", "operation": "increment" }

// Add item to array
{
  "do": "update",
  "target": "todos",
  "operation": "push",
  "value": { "expr": "state", "name": "newTodo" }
}

// Remove item from array
{
  "do": "update",
  "target": "items",
  "operation": "remove",
  "value": { "expr": "var", "name": "itemToRemove" }
}

// Remove last item
{ "do": "update", "target": "stack", "operation": "pop" }

toggle

Flips a boolean state value. Ideal for toggles, modals, and visibility controls.

json
{ "do": "update", "target": "isOpen", "operation": "toggle" }
NameTypeRequiredDefaultDescription
do"update"Yes-Step type identifier.
targetstringYes-State field to toggle (must be boolean).
operation"toggle"Yes-Toggle operation identifier.

merge

Shallow-merges properties into an object state. Existing properties are preserved unless overwritten.

json
{
  "do": "update",
  "target": "form",
  "operation": "merge",
  "value": { "expr": "lit", "value": { "email": "user@example.com" } }
}
NameTypeRequiredDefaultDescription
do"update"Yes-Step type identifier.
targetstringYes-State field to merge into (must be object).
operation"merge"Yes-Merge operation identifier.
valueExpressionYes-Object expression to merge into target.

Merge Example

json
// State: form = { name: "John", email: "" }
{
  "do": "update",
  "target": "form",
  "operation": "merge",
  "value": { "expr": "lit", "value": { "email": "john@example.com", "phone": "123-456" } }
}
// Result: form = { name: "John", email: "john@example.com", phone: "123-456" }

replaceAt

Replaces an element at a specific index in an array. Useful for editing list items in place.

json
{
  "do": "update",
  "target": "todos",
  "operation": "replaceAt",
  "index": { "expr": "var", "name": "index" },
  "value": { "expr": "lit", "value": { "title": "Updated", "done": true } }
}
NameTypeRequiredDefaultDescription
do"update"Yes-Step type identifier.
targetstringYes-State field (must be list).
operation"replaceAt"Yes-ReplaceAt operation identifier.
indexExpressionYes-Expression evaluating to the index to replace.
valueExpressionYes-Expression evaluating to the new value.

insertAt

Inserts an element at a specific index in an array. Elements at and after the index are shifted.

json
{
  "do": "update",
  "target": "items",
  "operation": "insertAt",
  "index": { "expr": "lit", "value": 0 },
  "value": { "expr": "state", "name": "newItem" }
}
NameTypeRequiredDefaultDescription
do"update"Yes-Step type identifier.
targetstringYes-State field (must be list).
operation"insertAt"Yes-InsertAt operation identifier.
indexExpressionYes-Expression evaluating to the index to insert at.
valueExpressionYes-Expression evaluating to the value to insert.

splice

Deletes and/or inserts items at a specific index. The most flexible list operation, mirroring JavaScript's Array.prototype.splice().

json
{
  "do": "update",
  "target": "items",
  "operation": "splice",
  "index": { "expr": "var", "name": "index" },
  "deleteCount": { "expr": "lit", "value": 1 },
  "value": { "expr": "lit", "value": ["replacement1", "replacement2"] }
}
NameTypeRequiredDefaultDescription
do"update"Yes-Step type identifier.
targetstringYes-State field (must be list).
operation"splice"Yes-Splice operation identifier.
indexExpressionYes-Expression evaluating to the start index.
deleteCountExpressionYes-Expression evaluating to the number of elements to delete.
valueExpressionNo-Expression evaluating to an array of items to insert (optional).

Fetch Step

Makes an HTTP request and handles the response.

json
{
  "do": "fetch",
  "url": { "expr": "lit", "value": "https://api.example.com/data" },
  "method": "GET",
  "result": "fetchedData",
  "onSuccess": [
    { "do": "set", "target": "isLoading", "value": { "expr": "lit", "value": false } }
  ],
  "onError": [
    { "do": "set", "target": "error", "value": { "expr": "param", "name": "error" } }
  ]
}
NameTypeRequiredDefaultDescription

HTTP Methods

MethodDescriptionTypical Use
GETRetrieve dataFetching lists, details
POSTCreate new resourceSubmitting forms, creating items
PUTUpdate existing resourceEditing items
DELETERemove resourceDeleting items

Complete Fetch Example

json
{
  "name": "loadUsers",
  "steps": [
    {
      "do": "set",
      "target": "isLoading",
      "value": { "expr": "lit", "value": true }
    },
    {
      "do": "fetch",
      "url": { "expr": "lit", "value": "https://api.example.com/users" },
      "method": "GET",
      "result": "users",
      "onSuccess": [
        {
          "do": "set",
          "target": "isLoading",
          "value": { "expr": "lit", "value": false }
        }
      ],
      "onError": [
        {
          "do": "set",
          "target": "isLoading",
          "value": { "expr": "lit", "value": false }
        },
        {
          "do": "set",
          "target": "errorMessage",
          "value": { "expr": "lit", "value": "Failed to load users" }
        }
      ]
    }
  ]
}

POST Request Example

json
{
  "name": "createTodo",
  "steps": [
    {
      "do": "fetch",
      "url": { "expr": "lit", "value": "https://api.example.com/todos" },
      "method": "POST",
      "body": {
        "expr": "state",
        "name": "newTodo"
      },
      "onSuccess": [
        {
          "do": "update",
          "target": "todos",
          "operation": "push",
          "value": { "expr": "param", "name": "result" }
        },
        {
          "do": "set",
          "target": "newTodo",
          "value": { "expr": "lit", "value": { "title": "", "completed": false } }
        }
      ]
    }
  ]
}

Combining Steps

Actions can contain multiple steps that execute sequentially:

json
{
  "name": "submitForm",
  "steps": [
    {
      "do": "set",
      "target": "isSubmitting",
      "value": { "expr": "lit", "value": true }
    },
    {
      "do": "set",
      "target": "error",
      "value": { "expr": "lit", "value": null }
    },
    {
      "do": "fetch",
      "url": { "expr": "lit", "value": "/api/submit" },
      "method": "POST",
      "body": { "expr": "state", "name": "formData" },
      "onSuccess": [
        {
          "do": "set",
          "target": "isSubmitting",
          "value": { "expr": "lit", "value": false }
        },
        {
          "do": "set",
          "target": "submitted",
          "value": { "expr": "lit", "value": true }
        }
      ],
      "onError": [
        {
          "do": "set",
          "target": "isSubmitting",
          "value": { "expr": "lit", "value": false }
        },
        {
          "do": "set",
          "target": "error",
          "value": { "expr": "param", "name": "error" }
        }
      ]
    }
  ]
}

Navigate Step

Navigates to a different URL or page.

json
{
  "do": "navigate",
  "url": { "expr": "lit", "value": "/dashboard" }
}
NameTypeRequiredDefaultDescription
do"navigate"Yes-Step type identifier.
urlExpressionYes-Expression that evaluates to the target URL.
target"_self" | "_blank"No"_self"Navigation target (same tab or new tab).
replacebooleanNofalseUse history.replaceState instead of pushState.

Examples

json
// Navigate to a page
{ "do": "navigate", "url": { "expr": "lit", "value": "/about" } }

// Open in new tab
{
  "do": "navigate",
  "url": { "expr": "lit", "value": "https://example.com" },
  "target": "_blank"
}

// Dynamic navigation
{
  "do": "navigate",
  "url": {
    "expr": "bin",
    "op": "+",
    "left": { "expr": "lit", "value": "/posts/" },
    "right": { "expr": "var", "name": "postId" }
  }
}

Storage Step

Interacts with browser localStorage or sessionStorage.

json
{
  "do": "storage",
  "operation": "get",
  "key": { "expr": "lit", "value": "theme" },
  "storage": "local",
  "result": "savedTheme"
}
NameTypeRequiredDefaultDescription
do"storage"Yes-Step type identifier.
operation"get" | "set" | "remove"Yes-Storage operation to perform.
keyExpressionYes-Expression that evaluates to the storage key.
storage"local" | "session"Yes-Storage type (localStorage or sessionStorage).
valueExpressionNo-Value to store (required for 'set' operation).
resultstringNo-Variable name to store the retrieved value (for 'get' operation).
onSuccessActionStep[]No-Steps to execute on success.
onErrorActionStep[]No-Steps to execute on error.

Storage Operations

OperationDescriptionRequires ValueRequires Result
getRetrieve value from storageNoYes (recommended)
setStore value in storageYesNo
removeRemove key from storageNoNo

Examples

json
// Save theme preference
{
  "do": "storage",
  "operation": "set",
  "key": { "expr": "lit", "value": "theme" },
  "value": { "expr": "state", "name": "theme" },
  "storage": "local"
}

// Load theme on mount
{
  "do": "storage",
  "operation": "get",
  "key": { "expr": "lit", "value": "theme" },
  "storage": "local",
  "result": "savedTheme",
  "onSuccess": [
    {
      "do": "if",
      "condition": { "expr": "var", "name": "savedTheme" },
      "then": [
        { "do": "set", "target": "theme", "value": { "expr": "var", "name": "savedTheme" } }
      ]
    }
  ]
}

// Clear user session
{
  "do": "storage",
  "operation": "remove",
  "key": { "expr": "lit", "value": "userToken" },
  "storage": "session"
}

DOM Step

Performs direct DOM manipulation operations.

json
{
  "do": "dom",
  "operation": "addClass",
  "selector": { "expr": "lit", "value": "html" },
  "value": { "expr": "lit", "value": "dark" }
}
NameTypeRequiredDefaultDescription

DOM Operations

OperationDescriptionRequires ValueRequires Attribute
addClassAdd a CSS classYesNo
removeClassRemove a CSS classYesNo
toggleClassToggle a CSS classYesNo
setAttributeSet an attributeYesYes
removeAttributeRemove an attributeNoYes

Examples

json
// Add dark mode class to html element
{
  "do": "dom",
  "operation": "addClass",
  "selector": { "expr": "lit", "value": "html" },
  "value": { "expr": "lit", "value": "dark" }
}

// Remove light mode class
{
  "do": "dom",
  "operation": "removeClass",
  "selector": { "expr": "lit", "value": "html" },
  "value": { "expr": "lit", "value": "light" }
}

// Set data attribute
{
  "do": "dom",
  "operation": "setAttribute",
  "selector": { "expr": "lit", "value": "body" },
  "attribute": "data-theme",
  "value": { "expr": "state", "name": "theme" }
}

Import Step

Dynamically imports an external JavaScript module at runtime.

json
{
  "do": "import",
  "module": "monaco-editor",
  "result": "monaco",
  "onSuccess": [
    { "do": "set", "target": "editorReady", "value": { "expr": "lit", "value": true } }
  ]
}
NameTypeRequiredDefaultDescription

Example: Loading Monaco Editor

json
{
  "externalImports": {
    "monaco-editor": "https://cdn.jsdelivr.net/npm/monaco-editor@0.52.0/+esm"
  },
  "lifecycle": {
    "onMount": "initEditor"
  },
  "actions": [{
    "name": "initEditor",
    "steps": [{
      "do": "import",
      "module": "monaco-editor",
      "result": "monaco",
      "onSuccess": [{
        "do": "call",
        "target": { "expr": "var", "name": "monaco", "path": "editor.create" },
        "args": [
          { "expr": "ref", "name": "editorContainer" },
          { "expr": "lit", "value": { "language": "json", "theme": "vs-dark" } }
        ],
        "result": "editorInstance"
      }]
    }]
  }]
}

Call Step

Calls a JavaScript function on an imported module or DOM element.

json
{
  "do": "call",
  "target": { "expr": "var", "name": "monaco", "path": "editor.create" },
  "args": [
    { "expr": "ref", "name": "container" },
    { "expr": "lit", "value": { "language": "json" } }
  ],
  "result": "editor"
}
NameTypeRequiredDefaultDescription

Examples

json
// Call a method on an imported library
{
  "do": "call",
  "target": { "expr": "state", "name": "editor", "path": "getValue" },
  "result": "editorValue"
}

// Call with arguments
{
  "do": "call",
  "target": { "expr": "state", "name": "chart", "path": "update" },
  "args": [{ "expr": "state", "name": "chartData" }]
}

Subscribe Step

Subscribes to events from an external JavaScript object.

json
{
  "do": "subscribe",
  "target": { "expr": "state", "name": "editor" },
  "event": "onDidChangeModelContent",
  "action": "onCodeChange"
}
NameTypeRequiredDefaultDescription
do"subscribe"Yes-Step type identifier.
targetExpressionYes-Expression that evaluates to an object with event methods.
eventstringYes-Event method name to subscribe to.
actionstringYes-Action name to execute when the event fires.

Example: Monaco Editor Change Events

json
{
  "actions": [
    {
      "name": "setupEditor",
      "steps": [
        {
          "do": "subscribe",
          "target": { "expr": "state", "name": "editor" },
          "event": "onDidChangeModelContent",
          "action": "onCodeChange"
        }
      ]
    },
    {
      "name": "onCodeChange",
      "steps": [
        {
          "do": "call",
          "target": { "expr": "state", "name": "editor", "path": "getValue" },
          "result": "currentCode",
          "onSuccess": [
            { "do": "set", "target": "code", "value": { "expr": "var", "name": "currentCode" } }
          ]
        }
      ]
    }
  ]
}

Dispose Step

Manually disposes of a resource (cleanup subscriptions, destroy editors, etc.).

json
{
  "do": "dispose",
  "target": { "expr": "state", "name": "editor" }
}
NameTypeRequiredDefaultDescription
do"dispose"Yes-Step type identifier.
targetExpressionYes-Expression that evaluates to an object with a dispose() method.

Example: Cleanup on Unmount

json
{
  "lifecycle": {
    "onUnmount": "cleanup"
  },
  "actions": [{
    "name": "cleanup",
    "steps": [
      { "do": "dispose", "target": { "expr": "state", "name": "subscription" } },
      { "do": "dispose", "target": { "expr": "state", "name": "editor" } }
    ]
  }]
}

If Step

Conditionally executes steps based on a condition.

json
{
  "do": "if",
  "condition": { "expr": "state", "name": "isLoggedIn" },
  "then": [
    { "do": "navigate", "url": { "expr": "lit", "value": "/dashboard" } }
  ],
  "else": [
    { "do": "navigate", "url": { "expr": "lit", "value": "/login" } }
  ]
}
NameTypeRequiredDefaultDescription
do"if"Yes-Step type identifier.
conditionExpressionYes-Expression that evaluates to a boolean.
thenActionStep[]Yes-Steps to execute when condition is true.
elseActionStep[]No-Steps to execute when condition is false.

Examples

json
// Conditional theme application
{
  "do": "if",
  "condition": { "expr": "var", "name": "savedTheme" },
  "then": [
    { "do": "set", "target": "theme", "value": { "expr": "var", "name": "savedTheme" } },
    {
      "do": "dom",
      "operation": "addClass",
      "selector": { "expr": "lit", "value": "html" },
      "value": { "expr": "var", "name": "savedTheme" }
    }
  ]
}

// Validation before submit
{
  "do": "if",
  "condition": {
    "expr": "bin",
    "op": "!=",
    "left": { "expr": "state", "name": "email" },
    "right": { "expr": "lit", "value": "" }
  },
  "then": [
    { "do": "fetch", "url": { "expr": "lit", "value": "/api/submit" }, "method": "POST" }
  ],
  "else": [
    { "do": "set", "target": "error", "value": { "expr": "lit", "value": "Email is required" } }
  ]
}