Data Inspector
A Vue query workbench for live server-side objects: register data sources, then compose jora queries in the owning process.
Package: @devframes/plugin-data-inspector · Vue + Vite

Query workbench with results and data shape panel

Query data with advanced Jora syntax
What it does
- Query workbench — a CodeMirror jora editor with server-computed autocomplete; queries auto-run as you type, state in the URL hash.
- Auto rerun — optional poller (
auto rerun every N seconds). - Result viewer — normalizes to strict JSON (circulars →
$ref; Maps, Sets, class instances, functions, Dates get type badges) plus per-query stats. - Expansion, shape & filters — deep nodes fetch lazily via
load deeper; a shape panel shows a one-level skeleton; filters drop functions and_/$properties. - Saved queries — recipes (
query+ title/description + filters) in the workspace scope (committable) and the project scope (per-checkout).
A built-in example source registers by default; opt out with exampleSource: false (--no-example; DEVFRAME_DATA_INSPECTOR_EXAMPLE=0 when injected).
Providing data sources
The registry is process-global — register anywhere, before or after mount.
import { registerDataSource } from '@devframes/plugin-data-inspector/registry'
registerDataSource({
id: 'my-plugin:store', // namespace with your devframe id
title: 'My plugin store',
description: 'The live state store',
icon: 'i-ph:database-duotone',
data: () => store,
queries: [
{ title: 'Active sessions', query: 'sessions.mapEntries().value.[active]' },
{ title: 'Config (data only)', query: 'config', excludeFunctions: true },
],
})data is a plain value or sync/async factory; static: true resolves it once; queries show read-only beside saved ones; registerDataSource returns an unregister callback. Zero-dependency devframes register through the typed context service ctx.services.whenAvailable('devframes:plugin:data-inspector:sources', …).
Deep linking
Workbench state lives in the URL hash (#source=<id>&query=<jora>, filters); the handshake token rides the query string (?devframe_auth_token=), scrubbed on read.
In a hub, another dock jumps to a source via dock activation — rpc.call('hub:docks:activate', { dockId: 'devframes:plugin:data-inspector', params: { sourceId } }) (waits for registration).
Standalone
pnpx @devframes/plugin-data-inspector # the example source
pnpx @devframes/plugin-data-inspector stats.json log.jsonl # one static source per data file
pnpx @devframes/plugin-data-inspector build stats.json # self-contained static export
pnpx @devframes/plugin-data-inspector attach # attach to a process running the inject endpoint.json parses whole; .jsonl / .ndjson as a record array. build embeds the dataset in a static site.
Mount into a Vite host
For Vite DevTools:
// vite.config.ts
import createDataInspectorDevframe from '@devframes/plugin-data-inspector'
import { createPluginFromDevframe } from '@vitejs/devtools-kit/node'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
createPluginFromDevframe(createDataInspectorDevframe()),
],
})Register sources with registerDataSource, or mount via devframeVite(createDataInspectorDevframe()) from @devframes/vite/single.
Programmatic
import { createDataInspectorDevframe } from '@devframes/plugin-data-inspector'
export default createDataInspectorDevframe({
exampleSource: false,
})Attach to another Node process
The target starts the inject endpoint:
import { exposeDataInspector } from '@devframes/plugin-data-inspector/inject'
await exposeDataInspector({
sources: [{ id: 'app:store', title: 'App store', data: () => store }],
})sources pre-registers entries; call it empty to expose whatever's registered. Or code-free:
DEVFRAME_DATA_INSPECTOR=1 node --import @devframes/plugin-data-inspector/inject server.jsThis auto-registers a globalThis source:
// somewhere in the running process
globalThis.store = store
globalThis.cache = cacheIt reads globalThis at query time, so later assignments appear next run (opt out: DEVFRAME_DATA_INSPECTOR_GLOBAL=0).
The inject endpoint binds 127.0.0.1, requires the trust handshake with a per-run token, and advertises itself in node_modules/.data-inspector/discovery.json, which attach reads (or pass ws://… + --token).
RPC
All devframes:plugin:data-inspector:*:
| Function | Type | Returns |
|---|---|---|
sources | query | Every registered source (meta, suggested queries). |
query | query | Runs a jora query; normalized result with stats. |
queryPath | query | Depth-limited subtree slice (lazy expansion). |
skeleton | query | A source's type skeleton, honoring filters. |
suggest | query | Autocomplete candidates at the cursor. |
saved:list / saved:save / saved:delete | query / action | Saved-query recipes (workspace, project). |