feat: NativeScript support (native overlay, example app, standalone server fixes) - #16
Draft
NathanWalker wants to merge 4 commits into
Draft
NathanWalker wants to merge 4 commits into
NathanWalker wants to merge 4 commits into
Conversation
The component tree, signal graph, injector tree and NgRx collectors now live in overlay-core and read the host tree through a small adapter (children, id, tag name, selector), so an overlay for a platform without a DOM only has to describe its hosts. The DOM overlay keeps its exports and its behaviour. Two fixes fell out of the move. Injector nodes take their id from the host instead of drawing a new random one on every report, so a selection in the DI panel survives the next refresh. The injector walk also dedupes by host rather than by injector object, since Angular returns a fresh NodeInjector from every getInjector call, and it looks through hosts that bring no injector of their own instead of stopping at them.
A NativeScript Angular app has no DOM, so the browser overlay cannot run in it. The new `@santoshyadavdev/ng-devtools/overlay-nativescript` entry walks the native view tree from the root component host through the shared collectors and reports over a WebSocket to a devtools server on the developer's machine: component tree, a signal graph merged across every component, the injector tree with the environment injectors and their providers above it, NgRx state, and the highlight event, which outlines the native view. The runtime needs a few things a browser has for free. A WebSocket global must come from the app (for example @valor/nativescript-websockets), and `location` and `navigator` are shimmed for devframe's client. Angular only wires its injector profiler, which backs the DI panel, when `window` exists as the platform is created, so a `window` is defined until core publishes `getComponent` and removed then; the sentinel is that property rather than the `ng` object itself because provideRouter() publishes its own utilities onto that object earlier. The devframe client has no reconnect, and the server and the app restart independently, so a failed or dropped session is replaced after a pause. The two new files import their siblings without a `.ts` extension: the app's own TypeScript compiles them, and a `.ts` specifier is an error there unless the app's tsconfig opts in.
…build Two things kept `ng-devtools dev` from showing anything. The UI always looked for its connection at /__ng-devtools/, which is where the Vite bridge and the Express mount put it, while the standalone server serves it next to the page; the UI now tries its own base first and falls back to /__ng-devtools/. And the server resolves the built UI from the devframe definition's package, which did not depend on the assets package, so it fell back to fetching an unpublished version from a CDN and served nothing. The assets package is now a workspace devDependency of the devtools package, and the assets build is refreshed with the UI change.
`app-nativescript/` is an `ns create --ng` project wired to the NativeScript overlay: the WebSocket polyfill in polyfills.ts, the overlay started in main.ts before the app runs, plain-HTTP allowances for the simulator and emulator, and a showcase component with a signal, two computeds, an effect, an input and a component-level provider so every panel has something to show. The app maps the devtools package through tsconfig `paths` rather than importing it from node_modules. TypeScript never emits `.ts` sources it resolved through node_modules, so the linked package compiled to an empty module under @nativescript/webpack; that constraint applies to any webpack consumer of the package's TypeScript sources. `pnpm devtools:nativescript` starts the devtools server scanning the app's sources. Generated directories are left out of the Prettier check.
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueComment |
Contributor
|
That looks like a real badass idea |
Contributor
|
I had an idea to make this devtools work for Capacitor Angular apps as well but this is beyond my wildest dreams. Just watched the video so cool |
This was referenced Sep 25, 2026
Author
|
hey thanks @erkamyaman - these devtools are great - @edusperoni also has great ideas here. |
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.
Summary
Lets the devtools run against a NativeScript Angular app. A NativeScript app has no DOM, so this adds a second overlay that walks the native view tree through Angular's
ngdebug API and reports over a WebSocket to a devtools server on the developer's machine. The component tree, signal graph, injector tree, highlight tool, MCP tools and resources, and the source scanners all work against the included example app.What's in here
refactor(overlay)– the collectors (component tree, signal graph, injector tree, NgRx) move intooverlay-core.tsand read the host tree through a small adapter, so the DOM overlay and the NativeScript overlay only differ in how hosts are named and how children are listed. The browser overlay keeps its exports. Two fixes came with it: injector nodes get a stable id (a selection in the DI panel no longer resets every 3s), and the injector walk dedupes by host and looks through injector-less hosts.feat(overlay)–@santoshyadavdev/ng-devtools/overlay-nativescript. Beyond the tree walk it handles what the runtime lacks:WebSocketmust come from the app (@valor/nativescript-websockets),location/navigatorare shimmed for devframe's client, and reconnection is built in because devframe's client has none and the app and server restart independently. The DI panel needs Angular's injector profiler, which Angular only wires whenwindowexists during platform creation; the overlay provides awindowuntil core publishesng.getComponent(the sentinel has to be that property, sinceprovideRouter()publishes ontongearlier). The signal graph is merged across every component, and environment injectors with their providers sit above the element tree.fix(ui)– two things keptng-devtools devfrom showing anything, on any platform: the UI always looked for its connection at/__ng-devtools/and never at its own base, and the server could not resolve the built assets package (it is now a workspace devDependency ofpackages/ng-devtools). The assets build is refreshed.feat–app-nativescript/, anns create --ngproject wired up, with a showcase component (signal, computeds, effect, input, component-level provider).pnpm devtools:nativescriptstarts the server scanning its sources.Try it
Open
http://localhost:9999/; the badge turns to Connected once the app reports. Tap the showcase card and the Signals tab updates.ng-devtools_highlightover MCP outlines the native view.Verified
ns-app, signal graph with live values and epochs, injector tree with platform + app environment injectors and the showcase'sTapCounter, highlight over MCP, reconnect after a server restart.pnpm format:check,pnpm test(Node 24.15),pnpm test:devtools(135 tests, 12 new for the NativeScript walker, merge, injector dedupe and environment chain),pnpm build,pnpm devtools:build,node bin.mjs --help.Notes and follow-ups
extension/uiwas not rebuilt; the extension passes?baseURL=and is unaffected by the UI fix.tryGetInputsstill dumps every non-function field of a component (as before); on NativeScript that includes renderer internals ofListView. Restricting it to declared inputs viagetDirectiveMetadatawould help both platforms.ns-ng-devtools.mp4