Expressions
Attribute values are JavaScript. Before compiling, sigmx rewrites every $name into $.name, a property of the root store proxy, and every @name( into a call on the functions object; strings, template text, comments and regular expressions are left exactly as written. The result is compiled as a strict-mode function, so all of the following are ordinary JavaScript:
$count++$user.name = 'Ada'$items.push({ done: false })$['odd-key']$ // the whole store as an object$total = $items.reduce((sum, i) => sum + i.price, 0)<div data-signals="{ items: ['tea'], draft: '' }"> <div class="row"> <input data-bind:draft placeholder="item"> <button data-on:click="if ($draft) { $items.push($draft); $draft = '' }">Add</button> <button data-on:click="$items = []">Clear</button> </div> <p data-text="$items.length + ' item(s): ' + $items.join(', ')"></p></div>Statements and return values
Section titled “Statements and return values”Directives that need a value (text, show, class, computed, …) evaluate the expression and use the value of the last statement. Directives that run code (on, init, effect, …) run the body as statements.
<span data-text="$a = 1; $b = 2; $a + $b"></span> <!-- 3 -->Arrow functions, template literals, optional chaining and anything else the browser supports are fine.
Strict mode
Section titled “Strict mode”Expressions run in strict mode. A misspelt name such as cuont = 1 throws ReferenceError instead of silently creating a global, this is undefined, and assignments to read-only properties throw. A misspelt signal, $cuont, reads as undefined like any missing store path.
Four directives take a literal instead of an expression, because their values are almost always literal text: mask (a pattern), match-media (a media query), teleport (a selector) and remove-me (a delay). Add __dynamic to any of them to write an expression instead.
What is in scope
Section titled “What is in scope”| name | meaning |
|---|---|
$name |
the signal at path name |
$ |
the root store proxy; $.user.name, Object.keys($), JSON.stringify($) |
el |
the element the attribute is on |
evt |
the event, in data-on and other event-driven directives |
patch |
the changed signals, in data-on-signal-patch |
@name(...) |
a registered function, e.g. @get('/x') |
Globals such as window, document, Math and fetch resolve normally.
Reactivity rules
Section titled “Reactivity rules”An expression that runs inside an effect subscribes to every signal it reads. Reading through $, through $.path, or by enumerating keys all count. Writing a signal inside the same effect that reads it is a loop; sigmx stops it after a bounded number of runs and reports the error.
To read without subscribing, use @peek(() => $x).
Caching
Section titled “Caching”Compiled expressions are cached by source text, so a table with a thousand data-text="$row.total" cells compiles that expression once.
Strict Content-Security-Policy
Section titled “Strict Content-Security-Policy”By default expressions compile with new Function. On pages that forbid it, pass the nonce-based compiler; see CSP.