Skip to content

refactor(devtools): type-check devtools hook method names across runtime and eval bridge - #8824

Open
Aejkatappaja wants to merge 3 commits into
QwikDev:mainfrom
Aejkatappaja:refactor/typed-eval-bridge
Open

refactor(devtools): type-check devtools hook method names across runtime and eval bridge#8824
Aejkatappaja wants to merge 3 commits into
QwikDev:mainfrom
Aejkatappaja:refactor/typed-eval-bridge

Conversation

@Aejkatappaja

Copy link
Copy Markdown
Member

Problem

The browser extension reads page data through JS string templates passed to chrome.devtools.inspectedWindow.eval(). Those templates referenced the devtools hook method names (getComponentDetail, setSignalValue, highlightNode, ...) as untyped string literals, so a typo or a renamed hook method broke silently at runtime with no compile-time, lint, or test signal.

Note: the data-extraction logic itself already lives in compiled, type-checked, unit-tested modules (installers.ts __qwik_install_hook_runtime__ / __qwik_install_vnode_runtime__, injected as web-accessible resources, covered by hook-runtime.unit.ts / vnode-runtime.unit.ts). This PR closes the remaining gap: the untyped method-name references on the eval bridge.

Solution

Type-check the hook method names on both sides of the bridge.

  • Consumer: route the extension's eval accessors through a hookCall(method, ...args) helper whose method is constrained to keyof QwikDevtoolsHookExtended, plus a readHookJson wrapper. A typo or rename is now a compile error.
  • Producer: export QwikDevtoolsHookExtended from kit and type both hook-assignment sites in installers.ts against it (satisfies on the base hook object, a cast on the vnode-bridge hook). A rename on the runtime side is now a compile error too. These annotations are erased at build, so the stringified injected runtime is byte-identical.

Why eval is not removed

A devtools panel can only reach the inspected page's main world via chrome.devtools.inspectedWindow.eval; the content-script/port channel is isolated-world and cannot read window.__QWIK_DEVTOOLS__. So eval is the correct RPC channel here (subscriptions already use the port where it fits). The fix is to make the eval surface type-checked, not to remove it.

Verification

  • kit and plugin build; installers.ts type-checks against the interface (satisfies + cast).
  • The generated injected runtime is byte-identical (annotations erased); exec-testing it against a stubbed window shows component tree, component-detail lookup, and signal editing behave as before.
  • 46 runtime unit tests and 7 extension eval-bridge unit tests pass; extension tsc is clean (only two pre-existing wxt TS2742 errors); eslint passes on the touched files.

References

QwikDev project board, card "p1 Eval Bridge Is Untested and String-Based": https://github.com/orgs/QwikDev/projects/6/views/1

…ime and eval bridge

The extension read page data through raw-JS eval strings that referenced hook
method names as untyped literals, so a typo or a renamed hook method broke
silently at runtime.

- Route the extension eval accessors through a typed hookCall(method, ...args)
  helper whose method name is constrained to the hook contract.
- Export QwikDevtoolsHookExtended from kit and type both hook-assignment sites in
  installers.ts against it (satisfies + cast, erased at build), so a rename on the
  producer side is now a compile error too.

No runtime change: the stringified injected runtime is byte-identical.
@Aejkatappaja
Aejkatappaja requested a review from a team as a code owner July 12, 2026 23:31
@changeset-bot

changeset-bot Bot commented Jul 12, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9638882

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@qwik.dev/devtools Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 12, 2026

Copy link
Copy Markdown

Open in StackBlitz

@qwik.dev/core

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/core@8824

@qwik.dev/router

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/router@8824

eslint-plugin-qwik

npm i https://pkg.pr.new/QwikDev/qwik/eslint-plugin-qwik@8824

create-qwik

npm i https://pkg.pr.new/QwikDev/qwik/create-qwik@8824

@qwik.dev/optimizer

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/optimizer@8824

@qwik.dev/devtools

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/devtools@8824

commit: 9638882

@github-actions

github-actions Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor
built with Refined Cloudflare Pages Action

⚡ Cloudflare Pages Deployment

Name Status Preview Last Commit
qwik-docs ✅ Ready (View Log) Visit Preview 7cbe18d

@wmertens
wmertens changed the base branch from build/v2 to main July 16, 2026 14:50
@JerryWu1234

Copy link
Copy Markdown
Contributor

done @wmertens

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants