Skip to content

Add a debugger workflow for vue-remote #13

Description

@cmath10

Summary

Add a debugger workflow for @omnicajs/vue-remote that makes remote rendering visible in real time.

The initial goal is to provide a developer-facing debugging layer that can:

  • observe the Channel action stream;
  • inspect remote and received trees;
  • show invoke requests/results/errors;
  • surface ordering and latency information for host/remote synchronization;
  • integrate with Vue DevTools in a host-first way.

This issue is intentionally focused on debugging and instrumentation.
Transport strategy and transport alternatives are out of scope here.

Problem

Today debugging is spread across logs, tests, and manual reproduction.
When something goes wrong in remote rendering flows, it is hard to answer basic questions quickly:

  • what triggered the update;
  • in what order actions arrived;
  • whether invoke resolved or failed;
  • how remote and host trees diverged;
  • where latency or reordering started to become visible.

This becomes more painful as contracts become stricter and more behavior moves across the host/remote boundary.

Right now the main problem is simple: the remote side is effectively invisible in DevTools.
Before adding deeper diagnostics, we first need "eyes" into what the remote layer is doing.

Goals

  • Add an opt-in debugging layer for host/remote synchronization.
  • Make Channel actions visible in real time.
  • Make invoke activity inspectable.
  • Provide tree inspection for remote and received nodes.
  • Surface basic performance/debugging metrics.
  • Keep runtime behavior unchanged when debugging is disabled.
  • Prefer a host-first integration path that is compatible with current architecture.

Non-Goals

  • Reworking transport architecture.
  • Introducing breaking API changes.
  • Making tracing always-on in production.
  • Full time-travel restore in the first iteration.
  • Solving every remote DevTools integration edge up front.

Proposed baseline

The recommended starting point is a host-first debugger design with three pieces:

  1. Debug adapter in runtime
  • Wraps receiver.receive and, where useful, remote-side channel operations.
  • Emits structured debug events.
  • Has zero or near-zero impact when disabled.
  1. Debug state/model
  • Stores a timeline of actions and invoke results.
  • Stores snapshots or diffs of remote/received trees.
  • Tracks session metadata and lightweight metrics.
  1. Debugger UI
  • Starts as a standalone debug surface.
  • Can later be exposed through Vue DevTools custom inspector integration.
  • Focuses on observability first, not on controlling the runtime.

Initial feature set

Timeline

Show ordered events such as:

  • mount
  • insert-child
  • remove-child
  • update-text
  • update-properties
  • invoke
  • invoke-result

Each entry should include enough metadata to understand:

  • timestamp;
  • side (host / remote / debug bridge if applicable internally);
  • node/action identifiers;
  • payload preview;
  • session identifier.

Tree inspector

Provide an inspector for:

  • current received tree;
  • remote tree snapshots when available;
  • diffs between previous and current state.

Invoke inspector

For each invoke, show:

  • request metadata;
  • arguments preview;
  • resolved or rejected result;
  • correlation with the target node and timeline entry.

Basic metrics

Show lightweight diagnostic metrics such as:

  • action throughput;
  • basic latency measurements;
  • visible ordering anomalies or suspicious gaps.

Suggested event model

A good minimum event model is:

  • channel-action
  • invoke-result
  • tree-snapshot

The exact shape can evolve, but the model should support:

  • correlation by event id / invoke id;
  • timestamps;
  • session ids;
  • side metadata;
  • structured payloads suitable for redaction/truncation.

Integration direction

Recommended first step: host-first Vue DevTools integration

Start with a host-side custom inspector rather than trying to attach the remote Vue app directly to DevTools.

Why:

  • lower compatibility risk;
  • easier to ship incrementally;
  • easier to keep aligned with the current host/receiver architecture.

This does not need to be the final shape.
It is simply the most practical baseline.

Proposed phases

Phase 0: Instrumentation foundation

  • Introduce an internal debug bus.
  • Add optional instrumentation around the receiver/channel path.
  • Ensure no behavior changes when debug mode is off.

Phase 1: Standalone debugger surface

  • Build a minimal debugger UI.
  • Add timeline view.
  • Add tree inspector.
  • Add invoke/result inspection.
  • Add basic metrics.

Phase 2: Vue DevTools integration

  • Add a custom inspector for received/remote tree state.
  • Link timeline entries to inspected nodes when possible.

API direction

Public API should remain backward compatible.
A good direction is to make debugging opt-in through additional options or helpers, for example:

  • createReceiver({ debug })
  • createRemoteRoot(channel, { ..., debug })
  • or an explicit wrapper/helper around the debug bus.

The exact surface can be decided during implementation, but the key requirement is:

  • no breaking changes for existing users;
  • easy enable/disable behavior;
  • no required debugger setup for normal runtime usage.

Risks

  • overhead on the hot path if instrumentation is too eager;
  • payloads becoming too large or too noisy;
  • leaking sensitive values into debug output;
  • turning the debugger into a transport-design project instead of a debugging project.

Mitigations

  • keep the whole system opt-in;
  • prefer lazy serialization and payload truncation;
  • support redaction hooks for sensitive data;
  • keep the first iteration focused on observability, not transport expansion.

Acceptance criteria

  • In debug mode, the full action stream can be observed in real time.
  • invoke request/result/error flows are visible.
  • A developer can inspect the current tree state from a dedicated debug surface.
  • Basic latency/ordering signals are available.
  • Disabling debug mode preserves current behavior.
  • The initial implementation can be extended later without redesigning the public API.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions