feat: data-inspector plugin (jora live-query workbench), ctx.services, storage scopes#101
Open
antfubot wants to merge 11 commits into
Open
feat: data-inspector plugin (jora live-query workbench), ctx.services, storage scopes#101antfubot wants to merge 11 commits into
antfubot wants to merge 11 commits into
Conversation
…very viewer) Validates the live-query data-viewer architecture end to end: server-side jora over live registered objects (incl. the ViteDevServer serving the page), result normalizer, devframe RPC round-trip, remote stat-mode autocomplete, and a themed discovery struct view in devframe-style chrome. Stage-1 node spike passes 13/13 checks; findings and hazards documented in the prototype README. Throwaway code — lives on this spike branch as a primary source, not for merging into main.
✅ Deploy Preview for devfra ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
… source contract, saved queries
Renames the spike to data-inspector and reworks it along the agreed
direction:
- data sources follow { id, title, description?, getData(), static? }
with dynamic register/unregister + change listeners; static sources
memoize getData()
- saved queries (title/description, id-keyed) persisted per scope:
user -> node_modules/.data-inspector, project -> .devframe/data-inspector
(committable, shared with the team)
- SPA rebuilt as Vue 3 + @antfu/design on the canonical uno preset:
split-pane workbench, debounced auto-run, client-side jora syntax gate,
non-destructive errors (last good result stays), stats bar with query
time + payload size, remote suggestions, synced dark mode
Full e2e verified in-browser; spike still 13/13. Findings captured in
the prototype README.
…ush padding - empty query now runs $ so every source lands on its entire object - query settings (ignore functions / _-prefixed / $-prefixed keys), persisted client-side and applied to both results and the skeleton - 'available data' panel: query-independent type skeleton of the active source (ancestor-path cycle detection keeps shared refs expanded) - manual re-run button in the stats bar - left column sections (editor, skeleton, saved queries) resize via the same @antfu/design LayoutSplitPane setup as the outer split - discovery page padding zeroed via --discovery-page-padding-*
…badges, URL state
- FilterOptions { excludeFunctions, excludeUnderscoreProps, excludeDollarProps }
replace the old settings names; saved queries become source-agnostic
recipes { query, title?, description?, ...FilterOptions } with title
optional (untitled ids derive from a stable query hash)
- data sources can provide suggested queries ({ queries?: Query[] }),
listed read-only next to saved ones; loading any recipe applies its
filter options
- save query now opens an OverlayModal dialog (query preview, active
filters, title/description, scope)
- discovery struct annotations badge exotic values: Function, Map(n),
Set(n), Date, class names, circular refs
- source, query, and filters persist in the URL (shareable/restorable)
…panel, modal filters - query drafts persist in localStorage per data source; switching sources restores (or resets) the draft, and a query arriving via the URL seeds the draft for its source so shared links win - SkeletonPanel replaced by DataSourceInfoPanel: source title/description plus a one-level data shape in a plain code block (no discovery); clicking a prop sets it as the query and runs - the save-query modal always shows all three filter options with their on/off state
- display transform strips $class/$type meta before rendering: class
instances show only real props, function stubs collapse to {}, Map/Set
wrappers unwrap to their entries/values, Date/RegExp/BigInt/... render
as bare values; badges carry the type info instead, via WeakMap
side-tables (object identity for objects, parent+key for primitives)
- discovery's built-in query actions are enabled: the struct value-actions
popup now offers 'Create a subquery from the path' (pipes the path onto
the query) and 'Append path to current query' (textual append), both
emitting up to set the editor and re-run
…nified query list - executions (auto-run included) no longer clear the suggestion dropdown; it closes on accept, Escape, blur, or source switch - the popover gets an explicit solid surface (white / #1e1e1e) with stronger elevation so nothing reads through it in either scheme - suggested and saved queries render through one unified list (resolves the TODO), with per-entry icon, filter markers, scope/suggested badge, and delete only for saved entries
Promotes the data-inspector spike to a real plugin and lands the two core
primitives it design-required:
devframe core:
- ctx.services — typed, namespaced cross-plugin service registry
(provide/get/whenAvailable, augmentable DevframeServicesRegistry,
DF0037 on duplicate providers); whenAvailable absorbs setup-order
differences between provider and consumer
- getStorageDir scopes become workspace/project/global: workspace is the
committable .devframe/ dir (team-shared), project is the per-checkout
node_modules dir (the old 'workspace'), global stays per-user; all
hosts and call sites migrated (settings and dock prefs now persist
under 'project')
@devframes/plugin-data-inspector:
- process-global source registry (globalThis Symbol store): sources are
{ id, title, description?, icon?, data: value | (async) factory,
static?, queries? }; registerDataSource() needs no context, the same
store is provided as the 'devframes:plugin:data-inspector:sources'
context service, and changes broadcast to connected UIs
- isomorphic engine (normalize/skeleton/jora bridges) — the Map/Set
methods duck-type live collections AND their normalized tags, so
saved queries stay portable between live and static modes
- Vue + @antfu/design SPA with discovery's CodeMirror jora editor
(remote stat-mode suggestions), struct viewer with type badges,
shape panel, filters, per-source drafts, URL state, saved queries
(workspace/project scopes via the new storage classes)
- standalone CLI: inspect .json/.jsonl files, attach to a process
running the in-process agent (loopback + pre-shared-token auth by
default, discovery file handshake), and build self-contained static
exports that run the engine client-side
- unit tests for registry/engine/saved-queries/file loaders; core
services tests; API snapshots updated
The prototype example is replaced by the plugin; the minimal Vite hub
dogfoods it with the live ViteDevServer registered as a source.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Adds @devframes/plugin-data-inspector — an interactive jora query workbench over live server-side objects — together with the two core primitives its design required. Grew out of the in-PR spike (kept in history; the prototype example is replaced by the real plugin).
Devframe core
ctx.services— typed, namespaced cross-plugin service registry (provide/get/whenAvailable, augmentableDevframeServicesRegistry,DF0037on duplicate providers).whenAvailableabsorbs setup-order differences, giving every plugin pair a dependency-free communication channel.getStorageDirnow takes'workspace' | 'project' | 'global': workspace is the committable.devframe/dir (team-shared), project the per-checkoutnode_modulesdir (previous 'workspace' semantics), global per-user. All hosts and call sites migrated.The plugin
globalThisSymbol store) —registerDataSource({ id, title, data: value | (async) factory, static?, queries?, icon? })works with no context from anywhere (plugins, hosts, CLIs, agents); also exposed as a typed context service; registry changes push to connected UIs.devframe-data-inspector stats.json trace.jsonl(one static source per file),attach(connect the UI to another process running the in-process agent — loopback + pre-shared-token auth by default, discovery-file handshake),build(self-contained static export; the isomorphic engine runs queries client-side, so saved recipes stay portable).@devframes/plugin-data-inspector/agent— explicit import orDEVFRAME_DATA_INSPECTOR=1 node --import …for zero-code-change attach. Documented as eval-grade access; treat like a debugger port.Verification
716/716 tests (new units for registry, engine incl. static-portability, saved queries, file loaders; core services tests), API snapshots updated, lint/typecheck/build green, CLI file-mode smoke-tested in a browser end to end. The minimal Vite hub example dogfoods the plugin with the live
ViteDevServerregistered as a source.Created with the help of an agent.