Home Features Docs Blog Security Examples FAQ
Releases - Part 4 of 4

djust 0.2.2: The Debug Panel Gets Real

djust Team | | 5 min read
djust debug panel showing live event history, VDOM patches, and handler inspection

Overview

The djust debug panel has existed since early releases, but 0.2.2 is the version where it actually becomes useful. Four release candidates worth of fixes turned a panel that crashed on load into one that streams live state, replays events, and traces every VDOM patch back to the handler that caused it.

This release also overhauls the JIT serialization pipeline, fixes critical VDOM rendering bugs, and refactors the codebase into focused modules. Here's what changed.

Debug Panel: From Broken to Essential

The debug panel had the right ideas but the wrong wiring. Handlers crashed because the server sent a dict and the JS expected an array. Events never appeared because the WebSocket hook targeted an object that didn't exist. Patches showed nothing because the counter updated the wrong DOM element. Each fix was small, but together they turned a non-functional panel into a real development tool.

What Works Now

Live State Updates

When DEBUG=True, every WebSocket event response now includes a _debug payload with the current view state. The panel's Variables, Handlers, and Patches tabs update after each interaction — no page refresh needed.

# This happens automatically in DEBUG mode.
# Every event response includes:
{
    "type": "patch",
    "patches": [...],
    "_debug": {
        "variables": {"count": {"value": "42", "type": "int"}},
        "handlers": {"increment": {"params": [...]}},
        "patches": [...],
        "performance": {"total_ms": 1.5}
    }
}

Event Filtering and Replay

The Events tab now has search-by-name filtering and status filtering (all, errors, success). Each event in the history has a replay button that re-sends it through the WebSocket with the original parameters. Inline feedback shows whether the replay succeeded or failed.

Network Tab

Raw WebSocket message inspection with directional color coding — amber for sent, cyan for received. Click any message to expand the full JSON payload. Copy to clipboard with one click.

Handler Discovery Matches Runtime

The Handlers tab now shows exactly what the runtime allows. Only @event_handler-decorated methods and _allowed_events appear — matching the strict-mode security policy from 0.2.1. No more showing methods that would be rejected at dispatch time.

What We Fixed

  • Script load orderdebug-panel.js now loads before client-dev.js so the panel class exists when initialization runs
  • Dict vs array — Server sends handlers as a dict, JS now normalizes with Object.entries()
  • WebSocket hook timing — Panel now retroactively hooks connections established before it loads
  • Counter DOM mismatch — Patch counter targeted 'patches' but the element ID was 'patch-count'
  • Message capture — Intercepts onmessage property setter, not just addEventListener

JIT Serialization Pipeline

The auto-serialization system that bridges Django ORM objects to Rust templates received significant fixes:

  • M2M traversal.all() calls now generate correct iteration code in codegen serializers
  • @property support — Properties are serialized via a Rust-to-Python codegen fallback
  • list[Model] optimization — Plain lists of models (not just QuerySets) now get select_related/prefetch_related JIT optimization
  • Nested dicts — Dicts containing Model or QuerySet values are deep-serialized recursively
  • {% include %} inlining — Included templates are now parsed for variable extraction, so their variables get JIT optimization too

VDOM Correctness

Several VDOM diff and patch bugs were fixed through a combination of targeted fixes and a new proptest fuzzing suite:

  • Keyed diff insert ordering — Inserts now appear in the correct position relative to existing keys
  • MoveChild resolution — Children are resolved via djust_id instead of index, fixing reorder bugs
  • Duplicate key detection — Warning emitted when multiple children share the same key
  • data-djust-replace — Fixed sibling grouping, child removal, and parent targeting for replace containers
  • Proptest fuzzing — Randomized VDOM tree generation catches edge cases humans miss

Codebase Refactoring

The monolithic files that made the codebase hard to navigate have been split into focused modules. No public API changes — this is purely internal organization:

  • live_view.py split into 7 mixins (Request, Context, JIT, Template, RustBridge, Component, Lifecycle)
  • client.js and debug-panel.js split into source modules with concat build
  • state_backend.py split into state_backends/ package
  • template_backend.py split into template/ package
  • websocket_utils.py and session_utils.py extracted from websocket.py

Other Changes

  • Context processor precedence — View context now takes precedence over Django context processors
  • {% include %} after cache restoretemplate_dirs now included in msgpack serialization
  • Numeric index paths — Template expressions like {{ posts.0.url }} no longer crash codegen
  • @event deprecated — Use @event_handler instead; @event will be removed in v0.3.0

Upgrading

pip install --upgrade djust==0.2.2

No breaking changes from 0.2.1. The debug panel improvements are automatic when DEBUG=True. If you're still using the @event decorator alias, switch to @event_handler before 0.3.0.

What's Next

With the debug panel and VDOM pipeline stabilized, the next focus areas are performance profiling, session state offloading (configurable memory/Redis/DB hybrid), and TurboNav integration. Follow the project on GitHub for updates.

Share this post

Related Posts