Contains the following minor improvements to the block entities migration:
* The migration won't be stopped anymore if it can't read a template file.
* The migration will exit early if a template doesn't contain the two characters we need to migrate.
* Reduced the amount of code that is wrapped by a try/catch to avoid suppressing errors.
PR Close#52209
DEPRECATED: NgProbeToken
The `NgProbeToken` is not used internally since the transition from View Engine to Ivy. The token has no utility and can be removed from applications and libraries.
PR Close#51396
When the `viewport` triggers were first introduced, we ended up having to use a service to keep track of them, because using the same global event handling as the other events led to some inconsistent test failures. It looks like the failures were caused by the same bug fixed#52115 so now we can switch back to the previous approach which is a bit more compact.
PR Close#52156
This fixes an issue where `ng-template` nodes were removed even when used in other places than control flow directives.
Template to migrate:
```html
<ng-template #blockUsedElsewhere><div>Block</div></ng-template>
<ng-container *ngTemplateOutlet="blockUsedElsewhere"></ng-container>
```
Before:
```html
<ng-container *ngTemplateOutlet="blockUsedElsewhere"></ng-container>
```
After:
```html
<ng-template #blockUsedElsewhere><div>Block</div></ng-template>
<ng-container *ngTemplateOutlet="blockUsedElsewhere"></ng-container>
```
PR Close#52186
This adds the support of `let index as myIndex` in `*ngFor` for the control flow migration.
Before: `@for (itm of items; track itm)`
After: `@for (itm of items; track itm; let myIndex = $index)`
PR Close#52183
This commit splits the `render3/instructions/defer.ts` file (that contained most of the runtime code) into smalle
r files that are easier to maintain.
There are no functional changes in this PR, just organizing code.
PR Close#52152
This change adjust the built-in for algorithm of dealing with embedded views
to update the repeater context (and more specifically - its index field)
only when views were added / removed "in the middle of LContainer" (in places
other than the LContainer end).
This skip iteration over the entire LContainer in most cases - and most importantly
in cases where no diff change was detected.
"
PR Close#52051
This adds a console warning to make it clear to users the migration is developer preview. It also shuffles around some code for better organization.
PR Close#52151
Currently the compiler allocates a variable slot to the `@for` loop expression which ends up unused since we don't store the result on the `LView`.
PR Close#52158
This adds `generate_api_docs` targets to all of the packages for which we publish api reference docs. One known issue here is that any type information that comes from another package (e.g. router depending on core) currently resolve to `any` because the other sources are not available in the program. This can be tackled in a follow-up commit.
This commit also updates the install patch for `@angular/build-tools` to use the local version of compiler-cli.
PR Close#52034
A runtime error will be thrown if a non-standalone component is being rendered without its NgModule loaded in the browser. This error is thrown only in dev mode and only if the Angular option `forbidOrphanComponents` is set to true. The error contains useful info to find the orphan component in the source code.
PR Close#52061
A new method `isOrphanComponent` is added to the deps tracker API to check if the NgModule declaring this component, if exists, is loaded into the browser.
PR Close#52061
The flag `forbidOrphanRendering` is only set for non-standalone components, and indicates that the dev mode runtime should through error if the component is rendered without its ngModule loaded in the browser. This runtime error can help with further debugging.
PR Close#52061
Using `afterRender` schedules long-living lifecycle hooks. Scheduling
such hooks inside reactive contexts could mean that many of the
same hooks would be scheduled, quickly piling up every time a
consumed signal changes. This is likely unintended and could degrade
application performance or result in unexpected behavior.
Additionally, scheduling `afterRender` inside a `computed` is considered
a side effect. Computed expressions are expected to be pure/ i.e. free
of side effects. We can avoid this caveat by detecting the reactive
context in development.
PR Close#52138
Using an `effect` inside a `computed` is a clear violation of
the conceptual idea of computed's being pure/ side-effect free.
Additionally, scheduling new effects from an existing actively
running effect is likely unintended as this could degrage application
performance or result in unintentional behaviors. Multiple long-living
effects would be scheduled every time the effect expressions runs.
For these reasons, we are explicitly preventing this pitfal, by
disallowing using `effect` inside reactive contexts.
PR Close#52138
Previously getDependenciesForTokenInInjector was unable to determine which node on a view serviced a specific injection. Now it is able to filter out those injections that did not come from the specific node for the NodeInjector passed into it.
Previously getInjectorMetadata was incorrectly looking up DOM elements for some directives (for example NgForOf) where an LContainer was created. Now the LContainer case is handled, and the non LContainer case uses `getFirstNativeNode` to more accurately get the element we want.
PR Close#51719
This commit cleans up the signatures of `toSignal` to better handle the
types of situations that it might be used in, and produce better type
inference results.
Fixes#50687Fixes#50591
Co-authored-by: Andrew Scott <atscott@google.com>
PR Close#51991
PR #49672 added a g3-flavored migration for compiler option removal, but g3
doesn't use those options at all. So this migration is unnecessary and we
can remove it.
PR Close#52141
Adds a check to the viewport cleanup function to prevent it from re-processing elements that have been fully cleaned up, because it can lead to the `IntersectionObserver` being destroyed even though there are still pending triggers. This can happen, because we have cleanup callbacks both for the block is loaded, but also when the placeholder view is destroyed.
Fixes#52113.
PR Close#52115
Fixes that the new block syntax was generating instructions in the wrong order which meant that pipes were being declared too early. This meant that if the block is first in the template, any pipes used in it won't be able to inject things like `ChangeDetectorRef`.
These changes update the compiler and add a bunch of tests to ensure that pipes work as expected.
Fixes#52102.
PR Close#52112
This commit updates `@defer` logic related to handling `after` and `minimum` parameters tree-shakable.
If `after` or `minimum` was used on a `@loading` or `@placeholder` blocks, compiler generates an extra argument for the `ɵɵdefer` instruction. This extra argument is a reference to a function that brings timer-related code.
PR Close#52042
The error message now contains the code location of the component. It now looks like: "Error: NG01001: Orphan component found! Trying to render the component Main (at $PROJECT_ROOT/src/main.ts:8) without first loading the NgModule ..."
PR Close#51919
The current error stringifier only includes the class name. In this change a new stringifier is added which returns a more helpful string which includes the file path and line number. Note that this is only the case with components, and for other class types (directive, pipes) it will fallback to the current stringifier. Subsequent changes can cover the case of directive and pipes as well.
PR Close#51919
A new field `debugInfo` is added to the component definition. Now the runtime ɵsetClassDebugInfo stores the debug info for components in this new field.
PR Close#51919
This commit updates the tracking of dirty child views to be a flag
rather than a counter. This is a much more simple method and less likely
to get into the same 'always-wrong' situation that could happen with the
counter (if it is off by 1 once, it's off by 1 forever and you either
get infinite change detection or your view is never refreshed).
PR Close#51515
Fixes that, depending on the matching and import order, in some cases we weren't throwing the error saying that a directive matched multiple times on the same element.
Fixes#52072.
PR Close#52073
This commit adds the code to mark newly created embedded views (that represent `@defer` block states) as dirty to indicate that the view sgould be checked during the next change detection cycle.
Resolves#52094.
PR Close#52095
This change removes the `mutate` method from the `WritableSignal` interface and
completely drops it from the public API surface.
The initial API proposal for Angular signals included the mutate method, allowing
in-place modification of JS objects, without changing their references (identity).
This was based on the reasoning that identity change on modification is not necessary
as we can send the “modified” notification through the signals graph.
Unfortunately the signal-specific change notification is lost as soon as we read
signal value outside of a reactive context (outside of a reactive graph).
In other words - any code outside of the Angular signals library can’t know
that an object is modified.
Secondly, to make the mutate method work, we’ve defaulted the signal value equality function
to the one that considers non-primitive values as always different.
This is unfortunate for people working with immutable data structures
(this is notably the case for the popular state management libraries)
as the default equality function de-optimizes memoization in computed,
making the application less performant.
Given the above reasons we prefer to remove the mutate method in the signals library -
at least for now. There are just too many sharp edges and tradeoffs that we don’t fully
understand yet.
BREAKING CHANGE:
The `mutate` method was removed from the `WritableSignal` interface and completely
dropped from the public API surface. As an alternative please use the update method and
make immutable changes to the object.
Example before:
```typescript
items.mutate(itemsArray => itemsArray.push(newItem));
```
Example after:
```typescript
items.update(itemsArray => [itemsArray, …newItem]);
```
PR Close#51986
This commit reorganizes the Angular code a bit, and moves signals into a
newly defined `@angular/core/primitives` location. This will be used inside
g3 to allow non-Angular targets to depend on the signals core without
incurring a dependency on the whole framework.
PR Close#51986
This commit refactors the signals API surface of Angular out of the
//packages/core/src/signals package. This is done in preparation of moving
the core signals package into a new 'primitives' package that's decoupled
from the public API.
PR Close#51986