Back to Reactotron

reactotron-core-contract

lib/reactotron-core-contract/README.md

3.3.89.3 KB
Original Source

reactotron-core-contract

TypeScript contracts for WebSocket messages between reactotron-core-server and reactotron-core-client.

This package provides the type definitions and command enums that ensure type-safe communication between Reactotron clients, plugins, and servers.

Installation

bash
npm install reactotron-core-contract
# or
yarn add reactotron-core-contract

What's Included

Command Types Enum

The CommandType object contains all available command type strings as constants:

typescript
import { CommandType } from "reactotron-core-contract"

CommandType.Log // "log"
CommandType.ApiResponse // "api.response"
CommandType.Benchmark // "benchmark.report"
CommandType.Display // "display"
CommandType.Image // "image"
// ... and many more

Payload Types

Each command has a corresponding payload type that defines its structure:

typescript
import type {
  LogPayload,
  ApiResponsePayload,
  BenchmarkReportPayload,
  DisplayPayload,
  ImagePayload,
  StateActionCompletePayload,
  // ... and more
} from "reactotron-core-contract"

Command Interface

The base Command interface that all messages follow:

typescript
import type { Command, CommandTypeKey } from "reactotron-core-contract"

interface Command<Type extends CommandTypeKey, Payload> {
  type: CommandTypeKey
  connectionId: number
  clientId?: string
  date: Date
  deltaTime: number
  important: boolean
  messageId: number
  payload: Payload
  diff?: any
}

Usage in Clients

Clients use the contract types to send properly typed commands to the server:

typescript
import { CommandType } from "reactotron-core-contract"
import type { LogPayload, ApiResponsePayload, DisplayPayload } from "reactotron-core-contract"

// Sending a log command
const logPayload: LogPayload = {
  level: "debug",
  message: "Hello, Reactotron!",
}
client.send(CommandType.Log, logPayload)

// Sending an API response
const apiPayload: ApiResponsePayload = {
  request: {
    url: "https://api.example.com/users",
    method: "GET",
    data: null,
    headers: { Accept: "application/json" },
    params: {},
  },
  response: {
    body: '{"users": [...]}',
    status: 200,
    headers: { "Content-Type": "application/json" },
  },
  duration: 245,
}
client.send(CommandType.ApiResponse, apiPayload)

// Sending a custom display event
const displayPayload: DisplayPayload = {
  name: "User Login",
  value: { userId: 123, username: "steve" },
  preview: "Steve logged in successfully",
}
client.send(CommandType.Display, displayPayload, true) // marked important

Usage in Plugins

Plugins import payload types to ensure they're sending properly structured data:

Example: API Response Plugin

typescript
import type { ApiResponsePayload } from "reactotron-core-contract"
import type { ReactotronCore, Plugin } from "reactotron-core-client"

const apiResponse = () => (reactotron: ReactotronCore) => {
  return {
    features: {
      apiResponse: (
        request: ApiResponsePayload["request"],
        response: ApiResponsePayload["response"],
        duration: number
      ) => {
        reactotron.send("api.response", { request, response, duration })
      },
    },
  } satisfies Plugin<ReactotronCore>
}

Example: Benchmark Plugin

typescript
import type { BenchmarkReportPayload } from "reactotron-core-contract"
import type { ReactotronCore, Plugin } from "reactotron-core-client"

const benchmark = () => (reactotron: ReactotronCore) => {
  const benchmark = (title: string) => {
    const steps: BenchmarkReportPayload["steps"] = []

    const step = (stepTitle: string) => {
      steps.push({
        title: stepTitle,
        time: performance.now(),
        delta: 0,
      })
    }

    const stop = () => {
      reactotron.send("benchmark.report", { title, steps })
    }

    return { step, stop }
  }

  return {
    features: { benchmark },
  } satisfies Plugin<ReactotronCore>
}

Example: Handling Server Commands

Plugins can also handle commands from the server by checking the command type:

typescript
import { CommandType } from "reactotron-core-contract"
import type { StateValuesRequestPayload } from "reactotron-core-contract"

const myPlugin = () => (reactotron) => {
  return {
    onCommand: (command) => {
      // Type-safe command handling
      if (command.type === CommandType.StateValuesRequest) {
        const payload = command.payload as StateValuesRequestPayload
        const { path } = payload
        // Handle the request...
      }
    },
  }
}

Available Command Types & Payloads

Client → Server Commands

Command TypePayload TypeDescription
CommandType.LogLogPayloadLog messages, warnings, and errors
CommandType.ApiResponseApiResponsePayloadHTTP request/response information
CommandType.BenchmarkBenchmarkReportPayloadPerformance benchmark results
CommandType.ClientIntroClientIntroPayloadClient connection information
CommandType.DisplayDisplayPayloadCustom display events
CommandType.ImageImagePayloadImage data with metadata
CommandType.SagaTaskCompleteSagaTaskCompletePayloadRedux-saga task completion data
CommandType.StateActionCompleteStateActionCompletePayloadState action completion
CommandType.StateValuesChangeStateValuesChangePayloadState value change notifications
CommandType.StateKeysResponseStateKeysResponsePayloadResponse with state keys
CommandType.StateValuesResponseStateValuesResponsePayloadResponse with state values
CommandType.StateBackupResponseStateBackupResponsePayloadState backup data
CommandType.AsyncStorageMutationAsyncStorageMutationPayloadAsyncStorage changes
CommandType.CustomCommandRegisterCustomCommandRegisterPayloadRegister a custom command
CommandType.CustomCommandUnregisterCustomCommandUnregisterPayloadUnregister a custom command
CommandType.ReplLsResponseReplLsResponsePayloadREPL list response
CommandType.ReplExecuteResponseReplExecuteResponsePayloadREPL execution result

Server → Client Commands

Command TypePayload TypeDescription
CommandType.StateValuesRequestStateValuesRequestPayloadRequest state values at path
CommandType.StateKeysRequestStateKeysRequestPayloadRequest state keys at path
CommandType.StateValuesSubscribeStateValuesSubscribePayloadSubscribe to state changes
CommandType.StateActionDispatchStateActionDispatchPayloadDispatch an action
CommandType.StateBackupRequestStateBackupRequestPayloadRequest state backup
CommandType.StateRestoreRequestStateRestoreRequestPayloadRestore state from backup
CommandType.ClearundefinedClear the timeline

React Native Specific

Command TypeDescription
CommandType.DevtoolsOpenOpen React Native DevTools
CommandType.DevtoolsReloadReload the React Native app
CommandType.EditorOpenOpen a file in the editor
CommandType.StorybookToggle Storybook
CommandType.OverlayToggle overlay

For Plugin Authors

When creating a Reactotron plugin:

  1. Import the relevant payload types from reactotron-core-contract
  2. Use CommandType enum for command type strings
  3. Type your plugin functions with the payload types
  4. Return a plugin object that satisfies the Plugin<ReactotronCore> interface

Example plugin structure:

typescript
import type { MyPayloadType } from "reactotron-core-contract"
import type { ReactotronCore, Plugin } from "reactotron-core-client"

export default (config = {}) =>
  (reactotron: ReactotronCore) => {
    return {
      // Handle server commands
      onCommand: (command) => {
        // Check command.type and handle accordingly
      },

      // Add features to Reactotron instance
      features: {
        myFeature: (data: MyPayloadType) => {
          reactotron.send("my.command", data)
        },
      },

      // Lifecycle hooks
      onConnect: () => {
        /* ... */
      },
      onDisconnect: () => {
        /* ... */
      },
    } satisfies Plugin<ReactotronCore>
  }

Learn More