Commit graph

115 commits

Author SHA1 Message Date
AleksanderBodurri
ecfcaba3b1 feat(devtools): Use "App Root" as name for root of router tree.
Previously '/' could cause confusion with other routes that use a path here. I think because this node is unique in that it is not actually a "Route" we should make it clear with the label that is simply the App Root.
2025-10-27 09:22:33 +01:00
Matthieu Riegler
7ad02b9805 refactor(devtools): fix parameter matching. (#64260)
Adding some typing to infer the expected types and drop the usages of `arguments` which isn't really typesafe.

The argument mis-match didn't result in an issue because they didn't end up being used futher down the line.

fix 63973

PR Close #64260
2025-10-10 06:40:43 -07:00
AleksanderBodurri
32ed78bcbe fix(devtools): optimize object sanitization logic (#64234)
Previously this would take ~3500ms adev.

This updated logic avoids the constant JSON.stringify implementation and instead checks for serializable values directly.

After this change this code path for adev takes less than 20ms.

(Benchmarks taken on an M1 Macbook Pro)

PR Close #64234
2025-10-06 15:00:19 -04:00
Taygan Caldwell
6169fa5888 fix(devtools): stop second component tree traversal, if devtools metadata is placed on the body tag (#64161)
Stop multiple component tree traversals if the app root is the body tag. This caused the devtools ui to duplicate the component information, if the app root was the body tag

PR Close #64161
2025-10-02 07:46:56 -07:00
Matthieu Riegler
a10eb38f76 feat(devtools): Add possibility to log directive instances and their prop values (#64143)
The improves debug possibilties via the Angular devtools

fixes #62235

PR Close #64143
2025-09-30 10:30:58 -04:00
Alan Agius
fc643c9044 build: adopt moduleResolution: "bundler" (#64125)
This commit updates the TypeScript configuration across the project to use `moduleResolution: "bundler"`. This modernizes our module resolution strategy to align with current TypeScript best practices and bundler behaviors.

The following changes are included:
- Updated `tsconfig.json` files to set `moduleResolution` to `"bundler"`.
- Updated the `rules_angular` bazel dependency to a version compatible with these changes.
- Adjusted related test files and golden files to reflect the new module resolution strategy.

PR Close #64125
2025-09-29 14:20:23 -04:00
Matthieu Riegler
44d2ec5a05 refactor(devtools): guard value reads in the serializer (#64096)
Some properties (like gets) might throw when we try to read them.
With this commit we fail gracefuly and show a warning message for the property that can't be read.

fixes #56755

PR Close #64096
2025-09-29 13:08:11 -04:00
AleksanderBodurri
d006721f30 feat(devtools): clean up router tree for stable release (#63081)
Addresses some cleanup items for the router tree:

- No longer loads router ng global APIs as a side effect of importing the router. Rather this is now a runtime step that occurs when provideRouter is called.
- No longer depends on router.navigateByUrl in Angular DevTools. There is now a dedicated global util for this
- Router instance logic no longer depends on token name
- Prevents navigating to lazy or redirect routes (these don't have an associated component)

PR Close #63081
2025-09-02 20:59:15 -07:00
Hongxu Xu
1f4c5f72aa refactor(bazel): reduce build deps (#63348)
clean up deps in bazel build scripts

PR Close #63348
2025-08-28 09:16:10 -07:00
Joey Perrott
3df1dccebe refactor: various build and import specificer fixes for strict deps (#63323)
Change direct deps in bazel targets and import specifiers within files to maintain strict deps requirements ahead of enabling strict deps tests in the repo

PR Close #63323
2025-08-22 14:45:00 -07:00
Matthieu Riegler
c3c9a9eed3 refactor(devtools): fix renamed function. (#63268)
`getRoots` was renamed `getAppRoots` in a prior commit.

PR Close #63268
2025-08-20 09:24:43 +00:00
hawkgs
863401b858 refactor(devtools): add property show graph button (#62853)
Add "Show graph" button to the signal properties in the side pane only for Angular apps. This required storing the signal graph in a separate service.

PR Close #62853
2025-08-20 09:04:24 +00:00
AleksanderBodurri
5115050928 fix(devtools): DOM traversal bug (#62719)
Previously, Angular devtools would mistakenly traverse the same DOM elements multiple times while doing traversal for the component tree explorer. This error case would occur when more than 1 Angular application root component was present on the same page and in distinct DOM branches.

Some example cases that did work previously:

```html
<app-root>
...
</app-root>
```

```html
<app-root>
...
<app-root-2></app-root-2>
...
</app-root>
```

An example of where it would enter the irregular behaviour

```html
<app-root>
...
</app-root>
<app-root-2>
...
</app-root-2>
```

Now, we properly ignore duplicate DOM paths when looking for application and non-application root component to begin the Angular DevTools component discovery logic.

PR Close #62719
2025-08-18 15:43:09 +00:00
Matthieu Riegler
4b183c7708 refactor(devtools): add explicit error message when ng is not available (#63008)
This makes the error more explicit in the console.

PR Close #63008
2025-08-05 18:14:12 +02:00
Joey Perrott
cbc258eec8 build: remove ts_project_interop infrastructure (#62908)
Remove the interop macros and final usages

PR Close #62908
2025-07-31 09:12:58 +00:00
Hryhorii Avcharov
a2f366f629 feat(devtools): add transfer state tab (#62465)
Add transfer state tab, which is taking transfer state script by using APP_ID. Created internal api ɵgetTransferState to retrieve transfer state value from app into devtools app.

PR Close #62465
2025-07-22 08:41:10 -04:00
Milo
2e6c2ff52c refactor(devtools): disable view source button if source function is not available (#62678)
if there is no debuggableFn, we shouldn't allow users to click the view source button

PR Close #62678
2025-07-17 13:28:35 -04:00
Joey Perrott
5eeb9f3e7e build: move all rule/macro loading into devtools/defaults.bzl (#62627)
Move all of our loading into a local defaults.bzl file instead of mixed loading via tools/defaults and devtolls/defaults

PR Close #62627
2025-07-14 15:47:05 -07:00
Milo
1de7ab28b4 fix(devtools): fix some build errors from g3 typescript (#62412)
this avoids some issues with casting types

PR Close #62412
2025-07-11 10:35:22 -07:00
Matthieu Riegler
69531668bf refactor(devtools): remove unused imports (#62530)
Import had no purpose and was also invalid.

PR Close #62530
2025-07-08 12:12:22 -07:00
Matthieu Riegler
4f25a8a756 fix(devtools): do not emit a route object with functions (#62254)
In the case where a Route has title defined as a function, it eventually throw when it reaches `window.postMessage`

fixes #60595

PR Close #62254
2025-07-08 11:28:27 -07:00
Joey Perrott
85b3ae2e3e build: migrate devtools to use packaged version of @angular/* packages (#62413)
Use the packaged versions of the packages instead of the local ts_project dependencies to prevent multiple versions of the deps to enter test bundles

PR Close #62413
2025-07-02 16:10:25 +00:00
Matthieu Riegler
d283595bfa fix(devtools): sanitize route data. (#62339)
The serialization of route data does not support cyclic data objects. We sanitize nested route data object by replacing invalid values with a placeholder string.

PR Close #62339
2025-06-30 09:31:18 +00:00
Joey Perrott
b84859073b build: migrate to use web test runner rules (#62292)
Migrate karma tests throughout the repo to use the new web test runner based rule instead

PR Close #62292
2025-06-26 17:19:10 +00:00
lilbeqiri
85fe323c4e refactor(devtools): inject number and symbol values with injection tokens (#56898)
Handle injecting number and symbol values with injection tokens and update contributing file

PR Close #56898
2025-06-25 17:02:54 +00:00
AleksanderBodurri
f30bd26b0a fix(devtools): implement signal read error handling in DevTools (#61911)
Fixes: #61900

Previously in DevTools we would read signal values to display preview values in the UI without safely catching any errors thrown in their evaluations.

Now those signal functions are run in a safe context, their errors are caught and handled in the UI as well as replayed in the console.

PR Close #61911
2025-06-19 10:15:39 +02:00
Milo
b9141da6fc refactor(devtools): use import type to improve performance (#61966)
fixes a few lint errors when including devtools in g3

PR Close #61966
2025-06-10 14:43:46 -07:00
Milo
fd2fca8bce refactor(devtools): check if signal graph is supported (#61915)
add a new devtools field in SupportedApis to check if the
getSignalGraphApi exists

PR Close #61915
2025-06-09 09:43:51 -07:00
Milo
0576724225 feat(devtools): add getSignalNestedProperties (#61917)
this enables devtools to preview and expand signal values as trees

PR Close #61917
2025-06-06 10:57:09 +02:00
Milo
4fa1dca72a feat(devtools): add getSignalGraph api to devtools protocol (#61548)
add a new devtools backend api getSignalGraph that emits a
latestSignalGraph to the devtools frontend

PR Close #61548
2025-06-03 10:47:57 -04:00
Sumit Arora
582fedd726 refactor(devtools): fixing PR comments and adding unit tests (#59999)
- Update code to fix PR comments and cleanup code
- Add unit tests for the new code

PR Close #59999
2025-05-30 09:48:12 -04:00
Sumit Arora
280119fec0 refactor(devtools): adding route details panel for selected route (#59999)
On clicking a route in the router tree, the route details panel is displayed.
- The panel shows the details of the selected route, including the path, component, providers, guards etc.
- Clicking on a chip will navigate to the corresponding source file in the editor.
- Clicking on the path will navigate to the corresponding route in the router tree.

Demo Application Source: https://github.com/sumitarora/angular-routes-demo
Demo Application Deployed: https://sumitarora.github.io/angular-routes-demo/#/

PR Close #59999
2025-05-30 09:48:12 -04:00
Joey Perrott
ae0ad878eb build: rename devtools ts_library to ts_project (#61317)
Rename ts_library to ts_project throughout devtools

PR Close #61317
2025-05-14 08:51:21 -07:00
Joey Perrott
31efc4bd24 build: migrate devtools to use ng-project (#61317)
Migrate devtools to use ng-project

PR Close #61317
2025-05-14 08:51:20 -07:00
Joey Perrott
e2c763a12c build: migrate adev devtools package to use ts_project (#61210)
Migrate usages to ts_project

PR Close #61210
2025-05-08 09:38:30 -07:00
Matthieu Riegler
eda8909772 fix(devtools): support defer blocks in IdentityTracker (#61139)
This reverts the fix of #61080 which wasn't adequate.

PR Close #61139
2025-05-06 13:44:37 -07:00
Matthieu Riegler
d47d6720e7 fix(devtools): fix profiler support with @defer blocks (#61080)
Prior to this change, the devtools profile logged warnings "Unable to find parent node for ...".

PR Close #61080
2025-05-01 14:58:21 -07:00
Matthieu Riegler
e6a34277fc feat(devtools): defer blocks support (#60629)
This commit adds the support for defer block in the Angular DevTools.

@defer block are now visible in the directive tree and give access to defer & hydration details.

This feature also brings support of incrementation hydration.

PR Close #60629
2025-04-29 22:07:47 -07:00
Matthieu Riegler
2df00c9b4b build(devtools): cleanup dependencies (#60936)
Removing `platform-browser-dynamic` because we don't need it anymore.

PR Close #60936
2025-04-29 12:16:16 -07:00
Doug Parker
6ce7c4cb4b fix(devtools): call ng.getDirectiveMetadata with the component instance (#60991)
`ng.getDirectiveMetadata` receives the component instance, not the raw DOM element.

This assumes that `ng.getComponent` is implemented in all environments and that the root element itself is a component.

PR Close #60991
2025-04-23 14:34:33 -07:00
hawkgs
cebb9d2c1e refactor(devtools): disable unsupported features (#60585)
Prepare the app for Wiz & ACX and handle unsupported features by disabling their respective UI.

PR Close #60585
2025-04-22 21:29:04 +02:00
hawkgs
7c1a16db26 refactor(devtools): create highlight overlay on node selection (#60744)
Currently, highlighting works only when a directive explorer node is hovered. The change enables this feature on node selection as well.

PR Close #60744
2025-04-14 09:20:24 -04:00
Doug Parker
96f36d62c8 refactor(devtools): use ng.getDirectiveMetadata for component name (#60475)
This reads the component name from `ng.getDirectiveMetadata`.

PR Close #60475
2025-03-27 20:26:12 +00:00
Doug Parker
d639a8d1f9 refactor(devtools): display directive metadata from Wiz and ACX (#60475)
This updates the DevTools protocol to send Wiz/ACX metadata in addition to Angular metadata. Fortunately we don't need to worry about backwards compatibility here (`framework` is required for example), but the design roughly mirrors `DirectiveDebugMetadata` in `@angular/core`.

Beyond that, this is mostly plumbing through an extra data slice in the form of `props` provided by Wiz. An earlier version implemented `events` as their own slice as well, but was removed as there is currently no generic way to disambiguate events from any other form of callback passed in as a prop. Instead, event callbacks are visualized as functions under the "Props" category.

Working with `DirectiveMetadata` as a union is unfortunately a bit annoying since it requires casting to more specific `{Angular,Acx,Wiz}DirectiveMetadata` types for TS to allow property access, even when the properties are optional anyways.

This commit is mostly for adding Wiz, but does add a bit of ACX functionality which is not fully tested.

PR Close #60475
2025-03-27 20:26:12 +00:00
Doug Parker
ebf6516190 refactor(devtools): make component-only properties on DirectiveMetadata optional (#60475)
This type was incorrect, as only components have `encapsulation` and `onPush` values. `ng.getDirectiveMetadata` does not return these properties for directive inputs.

Unfortunately the `| Partial<AngularComponentDebugMetadata>` is necessary to reference these properties or else TypeScript will reject their usage.

PR Close #60475
2025-03-27 20:26:12 +00:00
Doug Parker
d47cf58f10 refactor(core): update ng.getDirectiveMetadata to support Wiz and ACX (#60475)
This allows `ng.getDirectiveMetadata` to be implemented by Wiz and ACX with subtly different shapes to match the nuances of those frameworks.

Existing usage of `{Component,Directive}DebugMetadata` was moved over to `Angular{Component,Directive}DebugMetadata` as appropriate, since the implementation of `ng` in `@angular/core` is specific to Angular. Only the types support Wiz and ACX.

I opted to merge `ComponentDebugMetadata` and `DirectiveDebugMetadata` into a single type of all the frameworks including both components and directives (recall that components extend directives). The reasoning for this is because Wiz does not support directives (you can kind of think of "Wiz Directive" as an abstract class extended by "Wiz Components"). I felt that a `DirectiveDebugMetadata` containing only Angular and ACX types would be a bit of a trap and lead to bugs when used. It's safer to just have the single type containing all the possible results from `ng.getDirectiveMetadata`.

I also chose to leave the `ng` type as is internally, since `@angular/core` implements a specific concrete version of it narrowed to Angular types. Separately I defined an expanded `FrameworkAgnosticGlobalUtils` which redefines `ng.getDirectiveMetadata` to include Wiz and ACX. We want this type to exist in the Angular GitHub repo so it can be referenced as a common primitive across all three frameworks. This is sufficient for now, however longer term we will likely want to actually manually define the function types in this framework-agnostic interface and make Angular's version properly implement it rather than extend and overwrite Angular's type.

PR Close #60475
2025-03-27 20:26:12 +00:00
Doug Parker
4930ed3fed refactor(devtools): add support for mutating objects inside signals (#60381)
Angular DevTools now supports mutating objects underneath signals in the property explorer view.

This is done by performing an "immutable update" by recursively copying objects underneath a signal and overwriting the one property specified. For example, if the user attempted to set `foo.bar.baz[2].hello = 'world'` and `bar` was a signal, this would effectively become:

```typescript
foo.bar.set({
  ...foo.bar(),
  baz: [
    ...foo.bar().baz.slice(0, 2),
    {
      ...foo.bar().baz[2],
      hello: 'world',
    },
    ...foo.bar().baz.slice(3),
  ],
})
```

The motivation for immutable updates is because signals and Angular change detection don't really like interior mutability of signal values. If we didn't do this, any kind of comparison or dirty check would prevent the UI from updating. If an application attempts to change a deeply nested property inside a signal, it doesn't work today. DevTools should generally be limited to operations an application could do itself, and the recommended approach to make such a change like this is an immutable update. Creating entirely new objects intentionally breaks referential equality such that the application can properly react to the change.

Unfortunately, it is not possible to make immutable updates in a truly generic sense. You can't just copy a class for instance `({...new MyFoo()}).doSomething()`. We could do something fancier like manually copying over the prototype or something like that, but there is no way to do this without breaking class semantics (ex. the class might reasonably rely on the constructor being called). Therefore we instead reject any mutations to non-primitive objects. In the future, we might expand the set of "primitives" to include other built-ins and well-known objects like `URL` or `Element`, but those are out of scope for now.

I opted to ban mutating the result of a readonly/computed signal. While the mutation is likely to succeed, a subsequent rerun of the `computed` will immediately drop the change. However, I opted to allow mutating the result of a getter property. This has a similar problem because it might be returning a synthetic object which will be invalidated on the next execution, but it is possible and reasonable for a getter to return the same object multiple times such that a mutation may reasonably survive other updates. DevTools can't easily know whether a getter actually will return the same object on each execution or not, so we optimistically assume the reference is stable. If it isn't, the mutation will be lost whenever the getter is re-executed.

PR Close #60381
2025-03-18 10:22:46 +01:00
Doug Parker
3104e43b74 refactor(devtools): fix reading resolutionPath (#60403)
Sometimes `forest` can be empty if the provided roots are empty, and was leading to a "Cannot read `resolutionPath` of `undefined`" error. Now we check the forest has a tree in it before looking up `resolutionPath`.

There might be a separate issue with the fact that the backend script likely shouldn't be emitting an empty forest in the first place. However we already check that a resolution path exists at all, so I think it's fair to also check that a tree was provided. We can separately look into making sure the backend is emitting valid data.

PR Close #60403
2025-03-18 10:19:51 +01:00
Matthieu Riegler
a94c912a3a refactor(devtools): Make every ng function optional in the typings (#60208)
This will help in the future guarding against old apps what don't have the new APIs implemented

PR Close #60208
2025-03-10 09:24:12 -07:00
Doug Parker
6ea0318df6 refactor(devtools): ignore getDirectives when it is not supported (#60209)
Previously, if `ng.getDirectives` was not implemented, Angular DevTools won't throw when attempting to load the component tree. Now it safely ignores the function and assumes no directives exist on the page.

PR Close #60209
2025-03-05 13:42:40 -08:00