The current logic requires that standalone component always provide an array of raw imports. But such array could be dropped from the downstream tools if the component has no imports. So it is more natural to allow undefined raw imports for standalone components and treat it as empty array.
PR Close#51377
This commit updates TestBed to wait for async component metadata resolution before compiling components.
Async metadata is added by the compiler in case a component uses defer blocks, which contain deferrable
symbols.
PR Close#51182
This commit updates compiler logic to generate the `setClassMetadataAsync` calls for components that used defer blocks. The `setClassMetadataAsync` function loads deferrable dependencies and invokes the `setClassMetadata` synchronously once everything is loaded. This change is needed to avoid eager references to deferrable symbols in component metadata in generated code.
PR Close#51182
The current logic requires that standalone component always provide an array of raw imports. But such array could be dropped from the downstream tools if the component has no imports. So it is more natural to allow undefined raw imports for standalone components and treat it as empty array.
PR Close#51309
Creates unit tests for the following APIs
- setInjectorProfiler
- getInjectorProviders
- getInjectorResolutionPath
- getDependenciesFromInjectable
Modifies existing tests in
- packages/examples/core/di/ts/injector_spec.ts
- packages/core/test/render3/jit/declare_injectable_spec.ts
- packages/core/test/render3/jit/declare_factory_spec.ts
because they setup framework injector context manually.
Exports setInjectorProfilerContext in packages/core/src/core_private_export.ts in order for use
in the the modified tests above.
PR Close#48639
This includes implementation of methods getComponentDependencies and registerNgModule.
In order to correlate ng-modules with their declarations it is required to use the method registerNgModule to regiater the ng-module. However, the actual correlation will happen lazily once getComponentDependencies method is called. This lazy behaviour also allows for forward refs to be resolved.
The method getComponentDependencies will be used in local compilation mode to compute the rendering component deps in runtime.
PR Close#50980
The implementation is more or less follows the pattern in render3/jit/module.ts#transitiveScopesFor helper. A few additional helper functions also added to jit utils.
PR Close#50980
Exposes the function used to transform an input on `ComponentFactory.inputs` and `ComponentMirror.inputs`. We'll need this to support input transforms in `elements`.
PR Close#50713
The existing microbenchmarks are not widely known
and are not used to drive design / coding decissions.
At the same time those test add to the maintanance cost:
- use hand-written instructions;
- plug into runtime internals and are fragile;
- require development of mocks for the runtime internals.
Those tests are removed since they are costly to maintain
and, at the same, don't provide enough value.
PR Close#50786
Fixes an error that surfaced in #50580 where the compiler was throwing an error in JIT mode when reading the result of `compileDirectiveDeclaration`. It is caused by the fact that input transform functions were being passed around directly, instead of being wrapped in an AST node.
PR Close#50600
Both the render and update instructions live in the same file and are
only separated via a "render*" vs "refresh*" naming convention. This
commit moves these functions to completely separate files.
PR Close#50017
As described in
https://github.com/angular/angular/discussions/49681#discussioncomment-5628930,
if an `Observable` created from a signal with `toObservable` is
subscribed to in a template, it will initially have `null` as the value.
Immediately after the template is done executing, effects are flushed
and this results in the `AsyncPipe` getting a new value before the
`checkNoChanges` pass, resulting in `ExpressionChanged` error.
```
template: '{{obs$ | async}}'
...
obs$ = toObservable(signal(0));
```
Instead, this commit updates the `toObservable` to synchronously emit
the initial value to the Observable stream.
Side note here: We don't exactly encourage this pattern. Instead of
using `AsyncPipe`, the template should just read signals.
PR Close#49894
This change explicitly resets a reactive consumer before setting inputs
on directive instances. This is to assure that any potential input setters
do _not_ run in the reactive context.
PR Close#49906
This fix assures that templates functions executed in the creation mode
are run outside of the reactive context. This avoids the situation where
signal reads in a directive constructor (executed as part of the creation
mode) would mark the host component as dirty.
Fixes#49871
PR Close#49883
Angular doesn't support IE anymore. We can remove the workarounds related to IE.
Some workarounds are keep because of the support of domino but the comments related to IE are removed.
PR Close#49763
This change makes is possible to use async functions
(ones returning a promise) as effect run functions.
To make it possible, the signature of the effect function
changed: effect cleanup function is registered now
(using a dedicated callback passed to the effect creation)
instead of being returned from the effect function.
PR Close#49783
This commits updates the render to able to handle the slight differences between platform-server and platform-browser.
This is needed to eventually be able to remove `ServerRendererFactory2` and `EmulatedEncapsulationServerRenderer2` from platform-server.
PR Close#49630
Angular lifecycle hooks should never be run as part of the reactive
context: we do not expect that signal reads in lifecycle hooks
report to any consumers.
In the current Angular some of the lifecycle hooks can be flushed
early, while executting template update pass. We need to make sure
that signal reads in those lifecycle hooks do not register as part
of the effect that marks components for check.
"
PR Close#49701
`ComponentRef.setInput` internally calls `markDirtyIfOnPush` which only marks
the given view as dirty but does not mark parents dirty like `ChangeDetectorRef.markForCheck` would.
f071224720/packages/core/src/render3/instructions/shared.ts (L1018-L1024)
`markDirtyIfOnPush` has an assumption that it’s being called from the parent’s template. That is, we don’t need to mark dirty to the root, because we’ve already traversed down to it.
The function used to only be called during template execution for input
bindings but was added to `setInput` later. It's not a good fit because
it means that if you are responding to events such as an emit from an `Observable`
and call `setInput`, the view of your `ComponentRef` won't necessarily get checked
when change detection runs next. If this lives inside some `OnPush` component tree
that's not already dirty, it only gets refreshed if you also call
`ChangeDetectorRef.markForCheck` in the host component (because it will be "shielded" be a non-dirty parent).
PR Close#49711
* Prevent reads of signals during the notification process. This shouldn't
ever be triggered by user code but is more of a preventative for
internal misuse. Reading a signal during notification would/could create
glitches where the values being read are not updated to reflect the
values being updated by the notification.
* Prevent signal writes inside of computed's. These are meant to be
derived values and should not have any side-effects like writing new
values to other signals
* Prevent signal writes inside of effects by default. Writing to signal
values during the execution of an effect can lead to the
`ExpressionChangedAfterItHasBeenCheckedError` if writing to signals
that represent global state which is read in a parent component. This is
mostly just a problem for `OnPush`/`CheckAlways` components, but with
signals being new and pure signal components not even available yet,
it will be the majority for a long time.
PR Close#49631
This commit updates the `effect` primitive and significantly changes the
timing of effect execution.
Previously, effects were scheduled via the microtask queue. This commit
changes effects to run throughout the change detection process instead.
Running effects this way avoids needing additional rounds of change
detection to resolve effects, with the tradeoff that they're harder to use
for model-to-model synchronization (which can be seen as a good thing).
PR Close#49641
This commit consolidates the `RendererFactory` and `Sanitizer` properties
of `LView` onto a single object, the `LViewEnvironment`. These properties
are both set from DI when the root view is created, and not overridden when
child views are created (but inherited from the parent view).
This is a precursor commit to adding the `EffectManager` into the
`LViewEnvironment`.
PR Close#49641
This change extends the effect API surface so effects can, optionally,
return a cleanup function. Such function, if returned, is executed
prior to the subsequent effect run.
PR Close#49625
Previously, effects were queued in the global microtask queue and executed
directly. This had an undesired consequence: whichever effect scheduled
first determined the zone in which all other effects would run, *and* that
zone depended on where the signal happened to be set which triggered that
first effect. This behavior would be extremely unpredictable.
This commit adds zone awareness to the effect API. effects now capture the
current zone when they're created, and this zone is used to run the effect
callback regardless of which zone set the signal.
PR Close#49529
The `effect` implemented in the signal library is useful for testing but
does not integrate with Angular. This commit moves that code to the
actual framework package and integrates it with automatic cleanup via
`DestroyRef`. A simpler effect implementation is used in the signal tests to
test the `Watch` primitive.
Further commits will update the scheduling to tie effects together with
change detection.
PR Close#49529
`ComponentRef.setInput` currently sets the input on the component regardless
of the previous value the method was called with. This results in
different behavior from bindings in templates, which only set inputs
when the value differs in the `Object.is` check from its previous value.
BREAKING CHANGE: ComponentRef.setInput will only set the input on the
component if it is different from the previous value (based on `Object.is`
equality). If code relies on the input always being set, it should be
updated to copy objects or wrap primitives in order to ensure the input
value differs from the previous call to `setInput`.
PR Close#49607
The mentioned 2 classes have been combined since it is no longer required to have a separate `SharedStylesHost` for SSR. This changes also reduces the memory usage footprint as remove 1 Map that stores the CSS strings.
PR Close#49424
This commit updates the serialization logic to include information about templates that were used to create embedded views. The information is needed during hydration to pick a correct instance of dehydrated view (this logic will be implemented in a followup commit).
PR Close#49382
Prior to this change component styles generated on the server where removed prior to the client side component being rendered and attached it's own styles. In some cases this caused flickering. To mitigate this `initialNavigation: enabledBlocking'` was introduced which allowed the remove of server styles to be defer to a latter stage when the application has finished initialization.
This commit changes the need for this, by not removing the server generated component styles and reuse them for client side rendering.
PR Close#48253
Previously (at the early days of Ivy) a TNode used to keep an array of TViews, but the logic was changed since that time, but the `tViews` field remained on TNode interface (+ corresponding typings).
This commit renames TNode.tViews to TNode.tView and cleans up typings.
PR Close#49313
**Important note**: this is a first commit in a series of commits that will be needed
to support non-destructive hydration. Stay tuned for further updates!
This commit lays the foundation on top of which more hydration logic will be
added in follow up PRs. This PR includes:
* Initial serialization of hydration data
* Data transfer of hydration annotations from server side to client
* Accessing hydration info and populating internal data structures
* Initial APIs (currently private) that enable hydration (in a tree-shakable manner)
* Cleanup of annotations post hydration
* Initial test infrastructure and basic test cases
This commit does **not** expose any public APIs. They'll be exposed later, when
more hydration logic is implemented to a state when it can cover most common
use-cases.
Co-authored-by: Jessica Janiuk <jessicajaniuk@google.com>
Co-authored-by: Andrew Kushnir <akushnir@google.com>
PR Close#49271
This commit updates the `TNode` to include a reference to the previous sibling node. Currently, TNode has references to the next sibling and parent nodes, but in followup changes we'd need to have access to previous TNodes (to determine position of the current node).
PR Close#49223
Currently style of components using `encapsulation`, `None` or `Emulated` will not be removed from the DOM once the component get destroyed.
This change addresses this by keeping track of the number of times a component is rendered, when the component is destroyed the counter is decreased and once this reaches zero the style element is removed from the DOM.
Currently, this new behaviour is on opt-in bases, but it will be changed in the next major version.
To opt-in, set the `REMOVE_STYLES_ON_COMPONENT_DESTROY` DI token to `true`.
Example
```ts
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule
],
providers: [
{ provide: REMOVE_STYLES_ON_COMPONENT_DESTROY, useValue: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
```
Closes#16670
PR Close#48298
If tests are bundled using e.g. esbuild, the `ee` symbols may
be rewritten to `\u0275\u0275`. This breaks assertions that
rely on `Function.toString`. We can avoid this string comparison
and make it more future proof by just comparing the symbols directly.
PR Close#48521
Since we generate a `.mjs` file as entry-point for jasmine tests,
a couple of issues prevented the transitive dependencies from
bootstrap targets to be brought in (causing resolution errors):
1. The `_files` (previously `_esm2015`) targets are no longer needed,
and they also miss all the information on runfiles.
2. The aspect for computing linker mappings does not respect the
`bootstrap` attribute from the `spec_entrypoint` so we manually
add the extract ESM output targets (this rule works with the aspect
and forwards linker mappings).
PR Close#48521