@yoltra/devtools-protocol

Browse the API reference โ†’

Shared protocol types, message definitions, and utilities for the Yoltra DevTools suite.

@yoltra/devtools-protocol is the foundational vocabulary package for the entire DevTools ecosystem. It defines the wire format, message types, capability negotiation, and JSON Patch utilities that all other DevTools packages depend on.


#Installation

bash
npm install @yoltra/devtools-protocol

#What's Inside

#Protocol Version

A semver string used during handshake negotiation. The hub rejects connections with an incompatible major version.

typescript
import { PROTOCOL_VERSION } from "@yoltra/devtools-protocol";

console.log(PROTOCOL_VERSION); // "0.1.0"

#Roles

An enum identifying the three participants in the DevTools protocol:

typescript
import { DevtoolsRole } from "@yoltra/devtools-protocol";

DevtoolsRole.STORE; // A Yoltra store instance
DevtoolsRole.EXTENSION; // A DevTools UI (browser panel, CLI, VSCode)
DevtoolsRole.HUB; // The central message broker

#Message Types

All messages are discriminated on a type field for type-safe routing:

DirectionMessageDescription
Store โ†’ ExtensionsSTORE_EVENTEvent with JSON Patch delta, committed, and for an event that did not commit, optional reason and vetoedBy
Store โ†’ ExtensionsSTATE_SNAPSHOTFull state tree at a version
Store โ†’ ExtensionsSTORE_METRICSPerformance counters
Store โ†’ ExtensionsSTORE_SUBSCRIPTIONSReducer/effect/middleware inventory
Hub โ†’ ExtensionsSTORE_CONNECTEDA store completed handshake
Hub โ†’ ExtensionsSTORE_DISCONNECTEDA store disconnected
Hub โ†’ ExtensionsSTORE_REGISTRYFull registry snapshot
Extension โ†’ StoreREQUEST_STATERequest a state snapshot
Extension โ†’ StoreREQUEST_METRICSRequest performance metrics
Extension โ†’ StoreREQUEST_SUBSCRIPTIONSRequest subscription info
Extension โ†’ StoreTIME_TRAVELJump store to a specific state
Extension โ†’ StoreEVENT_REPLAYReplay events through reducers
Extension โ†’ StoreEMIT_TO_STOREInject a synthetic event

#Capabilities

Stores, extensions, and the hub advertise capabilities during handshake:

typescript
import type { StoreCapabilities, ExtensionCapabilities } from "@yoltra/devtools-protocol";

const storeCaps: StoreCapabilities = {
  replay: true,
  stateSnapshot: true,
  emit: false,
};

#JSON Patch Utilities

Convert Yoltra change-detection output into RFC 6902 JSON Patch operations:

typescript
import { computePatches, getAtPath } from "@yoltra/devtools-protocol";

const prev = { counter: { value: 1 } };
const next = { counter: { value: 2 } };

const patches = computePatches(prev, next, ["counter.value"]);
// [{ op: "replace", path: "/counter/value", value: 2 }]

getAtPath(next, "counter.value"); // 2

#Type-Safe Message Handling

typescript
import type { DevtoolsMessage } from "@yoltra/devtools-protocol";

function handle(msg: DevtoolsMessage) {
  switch (msg.type) {
    case "STORE_EVENT":
      console.log("Patches:", msg.patches);
      break;
    case "STATE_SNAPSHOT":
      console.log("State:", msg.state, "v" + msg.version);
      break;
    case "STORE_CONNECTED":
      console.log("Store joined:", msg.store.name);
      break;
    // TypeScript enforces exhaustive handling
  }
}

#How the Store Connection Works

The store agent connects through ReconnectingWsClient, which owns the handshake, the send buffer and the reconnection loop. The agent only injects the socket as a DevtoolsSocketFactory, so this package imports no transport. Nothing goes out before a successful HANDSHAKE_RESPONSE: until then frames wait in a bounded FIFO buffer, and an overflow drops the oldest frame and reports it through onBackpressure. The panel side (HubProvider in @yoltra/devtools-ui) has its own connection code and does not use this client.

ReconnectingWsClient connection lifecycle. The client opens a socket through the injected factory, sends a handshake, flushes its buffer once accepted, and reconnects with backoff after a close. Frames sent earlier wait in a FIFO buffer that drops the oldest.ReconnectingWsClient connection lifecycle. The client opens a socket through the injected factory, sends a handshake, flushes its buffer once accepted, and reconnects with backoff after a close. Frames sent earlier wait in a FIFO buffer that drops the oldest.

#Handshake Flow

ts
Client (Store/Extension)              Hub
  โ”‚                                     โ”‚
  โ”œโ”€ HANDSHAKE_REQUEST โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚
  โ”‚  { role, protocolVersion, ... }     โ”‚
  โ”‚                                     โ”‚
  โ”‚ โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ HANDSHAKE_RESPONSE โ”‚
  โ”‚  { success, negotiatedVersion }     โ”‚
  โ”‚                                     โ”‚
  โ”‚  (if store) Hub broadcasts          โ”‚
  โ”‚  STORE_CONNECTED to all extensions  โ”‚
  โ”‚                                     โ”‚
  โ”‚  (if extension) Hub sends           โ”‚
  โ”‚  STORE_REGISTRY + buffered events   โ”‚

The same exchange with every outcome the hub produces. A client is registered only after the token, the major version and the role's id all pass; any failure ends with close code 1008, and so does a client that sends no HANDSHAKE_REQUEST within 5 seconds.

Hub handshake outcomes. The hub rejects a client with close code 1008 for a bad token, a different major version or a missing role id, and on success announces a store to panels or sends a new panel the registry and buffered events.Hub handshake outcomes. The hub rejects a client with close code 1008 for a bad token, a different major version or a missing role id, and on success announces a store to panels or sends a new panel the registry and buffered events.

#Technical Docs

TypeDoc auto-generated documentation.

#API Reference

#Constants

ExportDescription
PROTOCOL_VERSIONCurrent protocol version string ("0.1.0")
DevtoolsRoleEnum of protocol participant roles

#Functions

ExportDescription
computePatches(prev, next, paths)Convert changed paths to JSON Patch operations
getAtPath(obj, dottedPath)Read a value from an object by dotted path

#Types

ExportDescription
DevtoolsMessageDiscriminated union of all message types
StoreCapabilitiesStore capability flags
ExtensionCapabilitiesExtension capability flags
HubCapabilitiesHub capability flags
HandshakeRequestHandshake request payload
HandshakeResponseHandshake response payload
JsonPatchSingle RFC 6902 patch operation
BaseMessageCommon fields on all messages


#License

MIT: Free to use in commercial and open-source projects.

Report a problem with this page