C&C Docs
Log in
Code

The controller — state, $update, $-methods

A block's controller is its .mjs. The default export is the page state: every key is in scope for the template. $update() recomputes what derives from that state, on the server, on every request. A method whose name starts with $ runs on the server too: @click="$inc" posts the method name, its arguments and the state to the block URL, the server runs it and then $update, and the new state comes back into the page. No fetch code.

The server sends finished HTML with the state beside it. The browser takes that HTML over as it is, without redrawing it, and from then on re-renders only what changes. A controller is a whole module: plural() below comes from the app's lib/ folder, and is there on the server and in the browser.

// blocks/live.mjs
import { plural } from '../lib/format.mjs'

export default {
  count: 0,
  log: [],
  summary: '',
  nonce: 0,

  // On GET, after every $-method, and when the page calls it.
  $update() {
    this.summary = plural(this.count, 'step') + ', ' + (this.count % 2 === 0 ? 'even' : 'odd')
    this.nonce = Math.floor(Math.random() * 1e6)
    if (this.log.length > 6) this.log = this.log.slice(-6)
  },

  // @click="$inc" POSTs { method, args, state } to /live;
  // the server runs this body, then $update, and the state merges back.
  $inc() {
    this.count += 1
    this.log.push('$inc() → count=' + this.count)
  },

  // @click="$add(5)" sends args: [5].
  $add(n) {
    this.count += Number(n) || 0
    this.log.push('$add(' + n + ') → count=' + this.count)
  },

  $reset() {
    this.count = 0
    this.log.push('$reset() → count=0')
  }
}
count
0
summary
0 steps, even
nonce
777583

$update() changes nothing but the nonce: a fresh random number each time the server runs it.

  1. (no calls yet — press a button)