Skip to content

Repository files navigation

devtools logo

@prsm/devtools

Express middleware that provides a live dashboard for observing prsm infrastructure at runtime. Most views are read-only; a few panels expose actions (release a lock, run a cron job, manage an auth account). Pass your instances and mount the router to get a full UI.

realtime records view

workflow executions view

Installation

npm install @prsm/devtools

Quick Start

importexpressfrom'express'import{RealtimeServer}from'@prsm/realtime'importQueuefrom'@prsm/queue'import{Cron}from'@prsm/cron'import{slidingWindow}from'@prsm/limit'importWorkflowEnginefrom'@prsm/workflow'import{createGraph}from'@prsm/cells'import{prsmDevtools}from'@prsm/devtools'constapp=express()constrealtime=newRealtimeServer({redis: {host: '127.0.0.1',port: 6379}})constqueue=newQueue({concurrency: 5})constcron=newCron()constapiLimiter=slidingWindow({max: 100,window: '1m'})constworkflow=newWorkflowEngine()constportfolio=createGraph({prefix: 'portfolio:'})app.use('/devtools',prsmDevtools({
realtime,
queue,
cron,limit: {api: apiLimiter},
workflow,cells: { portfolio },}))app.listen(3000)// open http://localhost:3000/devtools

Everything is optional. Only pass what you have - tabs appear only for connected subsystems.

To watch several queues at once - for example one queue per namespace, each with its own concurrency - pass a named map instead of a single instance. Each queue is tracked and displayed separately under the name you give it:

constdownloads=newQueue({namespace: 'downloads',concurrency: 2})constllm=newQueue({namespace: 'llm',concurrency: 10})app.use('/devtools',prsmDevtools({queue: { downloads, llm },}))

A single queue: someQueue is shorthand for queue: { default: someQueue }.

What You See

Overview - unified event stream from all subsystems, live via SSE

Realtime - full inspector for @prsm/realtime with sub-tabs:

  • Rooms - active rooms, members, per-member presence state
  • Channels - channels with active subscribers
  • Collections - collections with subscribers, expandable resolved records per connection
  • Records - subscribed records with live-updating data view (via SSE) and subscription mode per connection
  • Metadata - detailed connection view with rooms, channels, collections, records, and presence

Includes a connection picker sidebar for filtering all views by a specific client, and a registered patterns panel showing exposed channels, records, collections, presence, and commands.

Queue - in-flight count (polled), completed/failed/retried counters (session), event log. Pass a single queue or a named map of queues - each named queue is tracked and shown separately, so a server running several queues (for example one per namespace) sees each one's depth and throughput on its own.

Cron - registered jobs with next fire times, fire/error event log

Limits - registered limiters, peek inspector (inspect a key without consuming)

Workflows - registered workflow definitions with interactive graph view, step inspector, retry/timeout metadata

Executions - workflow execution list with filters, live graph overlay showing execution progress, per-step state, output/error inspector, and journal timeline

Meter - inspector for @prsm/meter. The catalog lists every metric with its unit and aggregate. Look up a subject to see its current-period usage across all metrics, then scope any metric to a window (a calendar period like month, a rolling duration like 30 days, or an explicit date range) and check it against a quota.

Entitle - inspector for @prsm/entitle. The plan catalog shows every plan's features and limits and the default plan. Resolve a subject to see its effective plan, feature flags, and limits after overrides, and check any limit against live usage when a meter is composed in.

Auth - admin panel for @prsm/auth, bound to the object returned by createAuthContext. An overview row shows account, provider, and 2FA counts alongside 24-hour login and failure totals. The accounts table supports search and pagination; opening an account reveals its roles, status, linked OAuth providers, two-factor methods, and a detail summary. From the drawer you can grant or revoke roles, change account status (ban, lock, suspend), force a logout, change the password, or delete the account, each behind a confirmation. A separate activity tab streams the recent audit log. Password hashes and TOTP secrets never leave the server.

Cells - one or more @prsm/cells graphs with two views per graph:

  • Table - every cell in the graph with current value, dependencies, status, and last-updated time. Click a row to open a detail panel below
  • Graph - DAG visualization with topologically-laid-out nodes and live propagation flashes when values change

The detail panel shows the cell's current value (syntax-highlighted JSON), source descriptor, metadata, template body (for templated cells), recent history (for cells with history enabled), and graph relationships. Pass a single graph or a named map of graphs - the panel includes a graph picker when more than one is provided.

API

prsmDevtools(options)

Returns an Express Router. Mount it wherever you want.

app.use('/devtools',prsmDevtools(options))

Options

OptionTypeDescription
realtimeRealtimeServerA @prsm/realtime server instance
queueQueue or Object<string, Queue>A @prsm/queue instance, or a named map of queues
cronCronA @prsm/cron instance
limitObject<string, Limiter>Named limiters from @prsm/limit
workflowWorkflowEngineAn @prsm/workflow engine instance
cellsGraph or Object<string, Graph>A @prsm/cells graph instance, or a named map of graphs
meterMeter or Object<string, Meter>A @prsm/meter instance, or a named map of meters
entitleEntitlements or Object<string, Entitlements>A @prsm/entitle instance, or a named map of resolvers
authAuthContextThe object returned by @prsm/auth's createAuthContext(config)
realtimeChannelBufferSizenumberHow many recent messages to retain per realtime channel (default 100)

All options are optional. The dashboard adapts to what's provided.

Endpoints

The middleware exposes these under its mount path:

EndpointDescription
GET /api/configWhich subsystems are connected
GET /api/eventsSSE stream (queue, cron, workflow, realtime record and channel message updates)
GET /api/queueSnapshot of every registered queue, keyed by name
GET /api/queue/:nameSnapshot of one named queue
GET /api/queue/:name/historyRecent complete/retry/failed events for one named queue
GET /api/cronRegistered jobs with next fire times
GET /api/limitsList of named limiters
GET /api/limits/:name/peek/:keyPeek at a limiter key
GET /api/workflowsRegistered workflows with graph data
GET /api/workflows/describeOne workflow definition
GET /api/workflow/executionsWorkflow executions, filterable by workflow/status
GET /api/workflow/executions/:idOne workflow execution
GET /api/realtime/stateFull realtime state snapshot
GET /api/realtime/connection/:idDetailed connection info
GET /api/realtime/room/:nameRoom members with metadata and presence
GET /api/realtime/channel/:channel/messagesRecent messages observed on a channel
GET /api/realtime/record/:idFetch a record's current value
GET /api/realtime/collection/:id/recordsResolved records for a collection + connection
GET /api/cells/:graphAll cells in the named graph with values, deps, status, metadata
GET /api/cells/:graph/:name/historyRecent values for a cell (if history is enabled on it)
GET /api/meter/:name/catalogA meter's period and declared metric catalog
GET /api/meter/:name/subjects?limit=Subjects with recorded usage, most-recently-active first
GET /api/meter/:name/summary?subject=A subject's current-period usage across every metric
GET /api/meter/:name/usage?subject=&metric=&period=Windowed usage for one metric (also accepts rangeStart/rangeEnd)
GET /api/meter/:name/check?subject=&metric=&limit=Usage for one metric checked against a quota
GET /api/entitle/:name/catalogThe plan catalog, default plan, and feature/limit universes
GET /api/entitle/:name/subjects?limit=Subjects with an assignment or override, most-recently-configured first
GET /api/entitle/:name/describe?subject=A subject's effective plan, features, and limits
GET /api/entitle/:name/check?subject=&key=A subject's limit checked against live meter usage
GET /api/auth/overviewAccount/provider/2FA counts, activity stats, and the role/status/mechanism maps
GET /api/auth/accounts?limit=&offset=&search=Paginated accounts (password hashes stripped)
GET /api/auth/accounts/:idOne account with linked providers and two-factor methods (secrets stripped)
GET /api/auth/activity?limit=&accountId=Recent activity log entries
POST /api/auth/accounts/:id/statusChange account status
POST /api/auth/accounts/:id/rolesAdd or remove a role ({ role, op })
POST /api/auth/accounts/:id/force-logoutForce logout of all sessions
POST /api/auth/accounts/:id/passwordChange the account password
DELETE /api/auth/accounts/:idDelete the account and all associated data

How It Works

The middleware listens to events on the instances you pass and forwards them to connected browsers via Server-Sent Events. Realtime record updates stream live over SSE - when you expand a record in the UI, its value updates in place as it changes on the server. Polling endpoints read current state from the instances' public APIs.

The Vue SPA is pre-built at publish time and served as static files from the same mount point. No build step needed in your project.

No dependencies on any @prsm packages. The middleware reads from whatever objects you give it.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages