Documentation

Live Graph

Status: true differential IVM — point rows, N-table equi-JOIN chains, multi-row join bags, inequality/LIKE bag filters — + scrub UI + causal resume + wire fail-closed
Thesis: In LukeLang you never fetch, never invalidate, never subscribe, never diff. You declare dependencies once, and change finds its own way from row to pixel.

One graph

DB row  →  server cell  →  [wire]  →  client cell  →  pixel   └────────────── one dependency graph, compiler-known ──────────────┘

Mainstream stacks glue three separate worlds (DB / server / client) with queries, cache invalidation, refetching, subscriptions, and diffing. LukeLang's reactive engine already answers "when X changes, what needs to update?" inside the client. The Live Graph answers it for the whole stack.

This release

Piece Role
WATCH … FROM db WHERE … Declares a DB-backed reactive cell
Trigger IVM cache (luke_ivm_*) Maintained TEXT snapshot
Differential triggers Single-table id = N: NEW.col / OLD — no full group_concat rewrite
Keyed join differential JOIN … ON a.x = b.y WHERE a.x = NWHEN NEW on both tables + partner probe
N-table join chains Equality closure on ON keys → WHEN NEW.<bound> = lit + NEW-pinned SELECT (live_graph_join3)
Multi-row JOIN cards luke_ivm_jbag_* keyed by hop rowids; publish group_concat (live_graph_join_filter, live_graph_join_multi)
Bag aggregates Any NEW./OLD.-qualifiable filter (=, >, LIKE, …) — bag I/U/D, no base re-scan (live_graph_agg, live_graph_agg_range)
Causal log (luke_ivm_log_*) Append on each pushed change
Last-Event-ID Parsed on the request; PUSH WATCH replays log rows with seq > id
Wire hardening SSE send failure aborts the stream; LUKE_SSE_ORIGIN; scoped PUSH requires user
Scrub UI Client-buffered history + Back / Forward / Live (live_graph_scrub.luke)
data_version gate Idle beats skip even the cache read
Wall app examples/deploy/wall — one deployable DB→pixel binary + Caddy

Acceptance: external UPDATE → pixel with region=1; reconnect resumes from the log; watch_queries stays bounded; join / join-multi / filter / bag / range proofs stay green in make test-build.

War cry surface

raw "# server"watch user from db where "id = 1"push watch user on req for 50 beats every 50 msraw "# client"signal user = ""bind("name", user)watch user from "http://127.0.0.1:8798/watch"

Differential shapes (not recompute):

watch card from db as "SELECT u.name || ' · ' || p.title FROM users u JOIN profiles p ON u.id = p.user_id WHERE u.id = 1"watch card from db as "SELECT u.name || ' · ' || p.title FROM users u JOIN profiles p ON u.id = p.user_id WHERE u.status = 'active'"watch adults from db as "SELECT name FROM people WHERE age > 30"watch feed from db as "SELECT body FROM notes WHERE status = 'open'"

Prior tiers

  1. Spike — hand-rolled CDC poll → region=1
  2. Server WATCH / PUSH WATCH surface
  3. PRAGMA data_version gate
  4. Trigger-maintained cache (group_concat)
  5. NEW/OLD differential triggers + event-log resume
  6. Multi-join cache recompute + client scrub UI beachhead
  7. Keyed equi-join differential + wire fail-closed + wall deploy proof
  8. Partner EXISTS / 3+ chains / equality bag
  9. Now: multi-row join bags + inequality bag filters (true Execution A+)

What falls out next

  1. Free multicore parallelism — independent reactions; compiler schedules without races
  2. Server+client scrub by log seq — wire DevTools to luke_ivm_log_* (client buffer shipped)
  3. Broader SQL shapes — LEFT JOIN, non-equi ON, expression-only SELECT lists