sercrod

*global

Summary

*global executes one or more JavaScript statements with side effects that write into Sercrod’s shared data or the JavaScript global object. Unlike *let, it does not create a local scope for children; instead, it updates existing data or globalThis and then continues rendering.

Use *global when you need to:

Important points:

Basic example

Set an app title in shared data or global scope:

<serc-rod id="app" data='{"message": "Hello"}'>
  <h1 *print="appTitle || 'Default title'"></h1>

  <!-- If appTitle exists in data, update it there; otherwise create window.appTitle -->
  <div *global="appTitle = 'Sercrod Demo'"></div>
</serc-rod>

Behavior:

Behavior

Key differences from *let:

The attribute is not removed:

Expression model

The value of *global is treated as one or more JavaScript statements, not as a special Sercrod grammar.

Examples:

<div *global="
  appTitle = 'Sercrod Demo';
  settings.ready = true;
"></div>
<div *global="
  // Update a known data field
  profile.name = 'Taro';
"></div>

Notes:

Data and global write targets

*global uses a clear policy for writes:

In simplified terms:

Practical consequences:

Scope and special helpers

Before evaluating the *global expression, Sercrod enriches the scope:

Children of the element:

Evaluation timing

*global participates in the non-structural phase of the render pipeline.

For each element processed by Sercrod:

  1. Non-structural directives (no return, can be applied multiple times):
    • *let is evaluated first.
    • *global is evaluated next, using the current effective scope.
  2. Structural directives (returning a specialized render result) follow:
    • *if / *elseif / *else chain, if present.
    • *switch, if present.
    • *each and *for, which control repetition.
  3. Other bindings and directives on children are evaluated during child rendering.

Consequences:

Execution model

Conceptually, when Sercrod encounters *global on an element:

  1. It builds an evaluation scope (scope) that includes:

    • Current data, including $data, $root, $parent.
    • Methods from configuration.
    • Sercrod’s internal helper methods.
  2. It wraps this scope in a Proxy that:

    • Always reports true from has so that with(scope){ ... } sees every identifier as present.
    • On get:
      • Returns values from scope if available.
      • Otherwise, returns from globalThis if available.
      • Otherwise, returns a special placeholder made by _makehole_scoped() that records the access path.
    • On set:
      • Converts the property key to a string.
      • If SERCROD data already has that key, writes into data.
      • Otherwise writes to globalThis.
  3. It executes:

    • Function("scope","el","$event", "with(scope){ " + expr + " }")(sandbox, el, null);
  4. After execution, it calls _schedule_update() if available to ensure any changes to data are picked up by the reactive update loop.

Error handling:

Use with conditionals, loops, and events

Conditionals on the same element:

Loops:

Events:

Best practices

Additional examples

Update an existing data key or create a global fallback:

<serc-rod id="app" data='{"settings": { "theme": "light" }}'>
  <div *global="
    if(settings.theme === 'light'){
      settings.theme = 'dark';
    }
  "></div>
</serc-rod>

Bridge with a global analytics object:

// External script
window.Analytics = {
  trackPage(name){
    console.log("Tracking page:", name);
  }
};
<serc-rod id="page" data='{"title": "Home"}'>
  <div *global="Analytics.trackPage(title)"></div>
</serc-rod>

Write root-level counters:

<serc-rod id="app" data='{"counter": 0}'>
  <button
    @click="counter++"
    *global="totalClicks = (totalClicks || 0) + 1"
  >
    Click
  </button>
</serc-rod>

Notes