6.8 KiB
Lua Scripting Integration
MetaBuilder now includes a real Lua interpreter powered by Fengari, allowing you to write and execute custom Lua scripts directly in the browser.
Features
✅ Real Lua Execution - Full Lua 5.3 interpreter running in the browser
✅ Context API - Access data, user info, and key-value storage from Lua
✅ Parameter System - Define typed parameters for your scripts
✅ Live Testing - Test scripts with sample data and see immediate results
✅ Workflow Integration - Use Lua scripts as nodes in visual workflows
✅ Execution Logs - Comprehensive logging with log() and print()
✅ Error Handling - Clear syntax and runtime error messages
Context API
Every Lua script has access to a context table with the following properties:
context.data
Input data passed to the script. When used in workflows, this is the output from the previous node. When testing, this contains your parameter values.
local input = context.data or {}
log("Processing: " .. input.name)
context.user
Information about the current user:
if context.user.role == "admin" then
log("Admin access granted")
end
Properties:
username- User's usernamerole- User role (user, admin, god)email- User email (if available)
context.kv
Key-value storage interface (future feature):
-- Future: Access to persistent storage
-- local value = context.kv.get("my-key")
-- context.kv.set("my-key", value)
Built-in Functions
log(...)
Log messages that appear in the execution results:
log("Starting process")
log("Value:", 42)
log("Multiple", "arguments", "supported")
print(...)
Alias for log(), works the same way:
print("Hello from Lua!")
Return Values
Scripts can return any Lua value. Tables are automatically converted to JavaScript objects/arrays:
-- Return a table
return {
success = true,
message = "Process complete",
count = 42
}
-- Return multiple values
return "result", 123, true
-- Return nil
return nil
Script Examples
Basic Hello World
log("Hello from Lua!")
return { message = "Success", timestamp = os.time() }
Data Validation
local data = context.data or {}
if not data.email then
return { valid = false, error = "Email is required" }
end
if not string.match(data.email, "@") then
return { valid = false, error = "Invalid email format" }
end
return { valid = true }
Data Transformation
local input = context.data or {}
local output = {
fullName = (input.firstName or "") .. " " .. (input.lastName or ""),
displayAge = tostring(input.age or 0) .. " years old",
status = input.isActive and "Active" or "Inactive"
}
return output
Array Processing
local data = context.data or {}
local numbers = data.numbers or {1, 2, 3, 4, 5}
local sum = 0
local max = numbers[1] or 0
for i, num in ipairs(numbers) do
sum = sum + num
if num > max then max = num end
end
return {
sum = sum,
average = sum / #numbers,
max = max
}
Conditional Logic
local data = context.data or {}
if data.score and data.score >= 80 then
return {
approved = true,
reason = "Score requirement met"
}
end
return {
approved = false,
reason = "Requirements not satisfied"
}
Using Scripts in Workflows
- Create a Script - Go to the Lua Scripts tab and create a new script
- Define Parameters - Add parameters your script needs (optional)
- Write Code - Access parameters via
context.data - Test - Use the test panel to verify your script works
- Use in Workflows - Add a "Lua" node to any workflow and select your script
Workflow Integration Example
-- This script filters items based on a threshold
local input = context.data or {}
local threshold = 10
local filtered = {}
if input.items then
for i, item in ipairs(input.items) do
if item.value > threshold then
table.insert(filtered, item)
end
end
end
log("Filtered " .. #filtered .. " items")
return { items = filtered, count = #filtered }
Best Practices
✅ Do
- Use
localfor all variables to avoid global namespace pollution - Check for nil values before using them
- Use
log()to debug and provide execution feedback - Return structured tables with clear property names
- Handle edge cases (empty arrays, missing properties)
❌ Don't
- Rely on global variables (use
local) - Create infinite loops (workflows have execution limits)
- Assume data structure - always validate input
- Use blocking operations (not applicable in browser Lua)
Lua Language Support
Fengari supports Lua 5.3 with the following features:
✅ Supported:
- All standard Lua syntax
- Tables (arrays and dictionaries)
- String manipulation (
string.*) - Math operations (
math.*) - Table operations (
table.*) - Control flow (if, for, while, etc.)
- Functions and closures
- Metatables and metamethods
- Coroutines
❌ Not Supported:
- File I/O operations (
io.*) - OS operations that don't make sense in browser
- Loading external Lua modules
- C extensions
Type Conversions
Lua → JavaScript
nil→nullboolean→booleannumber→numberstring→stringtable(array-like) →Arraytable(object-like) →Objectfunction→ not converted
JavaScript → Lua
null/undefined→nilboolean→booleannumber→numberstring→stringArray→table(1-indexed)Object→tableFunction→ not converted
Troubleshooting
Syntax Errors
Check the error message for line numbers and details. Common issues:
- Missing
endkeywords - Incorrect use of
=vs== - Forgetting
localkeyword
Runtime Errors
- "attempt to index a nil value" - Trying to access property of nil/undefined
- "attempt to call a nil value" - Function doesn't exist
- "attempt to perform arithmetic on a nil value" - Math operation on nil
Type Mismatches
Remember Lua is 1-indexed for arrays while JavaScript is 0-indexed. The conversion handles this automatically.
Performance Notes
- Scripts execute in the browser's main thread
- Large loops may block the UI temporarily
- Keep workflows reasonably sized (< 1000 operations)
- Complex calculations are fine, but avoid infinite loops
Security
- Scripts run in a sandboxed Lua VM
- No access to browser APIs directly
- No file system access
- No network access
- Cannot break out of the sandbox
For more Lua language documentation, see the official Lua manual.