sercrod

*log

Summary

*log evaluates an expression and logs its result together with the expression and a short host snippet. It is meant as a lightweight debugging helper for Sercrod templates. The alias n-log behaves the same.

Logging is side-effect free with respect to Sercrod data: *log does not modify the host’s data.

Basic example

Console logging a value:

<serc-rod id="app" data='{"user":{"name":"Alice","age":30}}'>
  <div *log="user"></div>

  <p>
    Hello,
    <span *print="user.name"></span>
  </p>
</serc-rod>

Behavior:

Using <pre *log> to display logs on the page:

<serc-rod id="debug" data='{"items":[1,2,3]}'>
  <pre *log="items"></pre>
</serc-rod>

Behavior:

Behavior

Core behavior:

Where the log is sent:

Single-shot semantics:

Expression rules

The attribute value of *log is a standard Sercrod expression:

Expression is optional:

Value formatting:

Error handling:

Evaluation timing

*log is tied to the lifecycle of the Sercrod host:

Execution model

Internally, Sercrod executes *log roughly as follows:

  1. During render, Sercrod builds an index of elements that carry *log or n-log.
  2. After the host render and index rebuild, Sercrod schedules _call_log_hooks(scope) inside requestAnimationFrame.
  3. When _call_log_hooks runs:
    • If this.log is false, it aborts immediately (global log-off for this host).
    • It takes all elements indexed under the *log flag.
  4. For each element el:
    • If el already has a +logged flag, it is skipped.
    • Otherwise, Sercrod sets the +logged flag on el.
    • Sercrod reads expr from *log or n-log.
    • It evaluates expr (if provided) in the current scope, or uses scope directly when there is no expression.
    • It computes:
      • val: the value used for console output.
      • str: the text representation (pretty JSON for objects when possible).
      • html: a compact summary of el.outerHTML, collapsed whitespace and limited to 256 characters.
  5. Depending on the element type:
    • If el.tagName === "PRE":
      • Sercrod builds a multi-line debug string with:
        • A prefix line such as [Sercrod pr].
        • The stringified value.
        • A line indicating the expression or (scope).
        • A line containing the snippet.
        • An optional line for the error message when evaluation failed.
      • Sercrod assigns this string to el.textContent.
    • Otherwise:
      • Sercrod calls console.log with a formatted block including:
        • A label [Sercrod log].
        • The value, expression (or (scope)), snippet, and optional error message.

This model guarantees that each *log node contributes at most one entry and that the entry reflects the post-render state of the DOM.

Scope and variables

*log does not introduce new variables or change existing ones.

Because *log is read-only with respect to data:

Use with conditionals and loops

*log composes naturally with other directives:

Best practices

Examples

Inspect the entire host data:

<serc-rod id="app" data='{"user":{"name":"Alice"},"debug":true}'>
  <pre *log="$data"></pre>
</serc-rod>

Inspect a subset of state:

<serc-rod id="app" data='{"state":{"step":1,"status":"idle"}}'>
  <div *log="state.status"></div>
</serc-rod>

Log per item in a list (console only):

<serc-rod id="list" data='{"items":[{"id":1},{"id":2},{"id":3}]}'>
  <ul>
    <li *for="item of items" *log="item.id">
      Item <span *print="item.id"></span>
    </li>
  </ul>
</serc-rod>

Notes