This adjusts the tests to have a longer await time and removes the click portion of the test. These tests should only pass if the timer has triggered hydration.
PR Close#60254
In the case that a route was lazy loaded, some triggers would never properly finish hydrating due to things firing before the route finished resolving.
This will find the topmost parent defer block and ensure the registry knows about it before trying to hydrate.
In the case that the registry does not yet know, just the affected triggers await app stability before initializing.
fixes#59997
PR Close#60203
In this commit, we check whether the application is destroyed before initializing event replay. The application may be destroyed before it becomes stable, so when the `whenStable` resolves, the injector might already be in a destroyed state. As a result, calling `injector.get` would throw an error indicating that the injector has already been destroyed.
PR Close#59789
In some rare cases with directives, it is possible that the stash function might be called on a comment node. This actually verifies that the node is an element and exits otherwise.
fixes: #60070
PR Close#60130
This updates the event replay tests to make them share the structure and utility functions used by hydration tests. This also resolves some soft errors in the event replay tests.
PR Close#60130
There are cases where resources fail to fetch or the DOM has changed due to an if block. This should clean up the remaining promises and any registry references to those blocks in that case.
PR Close#59740
This extends the test timeout for the two timer tests while shortening the actual hydrate on timer. This hopefully should result in more reliable CI.
PR Close#59945
In this commit, we check whether the application is destroyed before printing hydration stats. The application may be destroyed before it becomes stable, so when the `whenStableWithTimeout` resolves, the injector might already be in a destroyed state. As a result, calling `injector.get` would throw an error indicating that the injector has already been destroyed.
PR Close#59716
This change refactor how the dynamically created component
deals with attributes in order to reuse the existing
setupStaticAttributes logic (instead of having specific
and similar code).
PR Close#59572
This commit updates a test setup to define a global `ngServerMode` correctly for a test that was emulating client-only behavior. The flag could've been set by prior tests and depending on its state, the test was acting differently.
PR Close#59584
This commit updates testing setup logic to apply correct `document` reference, which should be used by the runtime. Previously, the timing of that operation was less predictable and in some cases led to reusing document state from previous tests.
PR Close#59579
In this commit, we delete `_ejsa` when the app is destroyed, ensuring that no elements are still captured in the global list and are not prevented from being garbage collected.
PR Close#59492
For `afterRender`/`afterNextRender` calls associated with a particular
view, ensure that they are not registered until after the first time the
view is rendered.
Co-authored-by: Alex Rickabaugh <alxhub@users.noreply.github.com>
PR Close#58250
This commit updates the timeout used in the incremental hydration tests from `101` -> `10` ms, which allows to speed up tests by ~20% (12.5 -> 10 seconds locally).
PR Close#59275
This commit updates defer block logic to avoid triggering `on idle` and `on timer` on the server for regular SSR mode (when incremental hydration is not enabled). Triggering the mentioned condition resulted in invoking `setTimeout` calls, which delayed serialization on the server during SSR (the process was waiting for the timeouts to clear).
PR Close#59177
There were type mismatches and or unintended any types that were preventing nested timers from accessing the delay value during hydration annotation processing.
PR Close#59173
This can happen if server providers are provided more than twice. We detect it on the state transfer phase by flagging app id as transferred in a set.
Resolves#58531
PR Close#58935
This cleans up the triggering code base and consolidates it down to one
function that outlines the logic. This also resolves the `hydrate when`
behavior issue.
fixes: #58709
PR Close#58833
This commit removes a custom `whenStable` util in favor of standard `ApplicationRef.whenStable` API.
There is also an important different between the custom `whenStable` function and `ApplicationRef.whenStable` implementation: the `whenStable` was caching the "stable" promise on per-ApplicationRef basis, which resulted in unexpected behavior with zoneless, when some code ended up getting a stale resolved promise, when an application was not stable yet, this causing order of operations issues. This commit also has an extra test that covers that case.
PR Close#58834
When hydrating a tree of blocks, this prevents cleanup from firing more than once per tree. It also ensures the cleanup happens after hydration has finished.
fixes: #58690
PR Close#58722
If a defer block is nested inside control flow while also being nested
underneath a defer block all using incremental hydration, timing issues
prevented the child nodes from being properly hydrated. This ensures
hydration happens on next render.
PR Close#58644
Fixes an edge case where a control flow node that has non-projectable nodes followed by an element node at the end would cause the entire control flow node to be project. For example if we have a projection target of `Main: <ng-content/> Slot: <ng-content select="[foo]"/>`, inserting a node of `@if (true) {Hello <span foo>world</span>}` would project the entire `Hello world` into the `[foo]` slot.
In the process of working on the issue, I also found that `@let` declarations at the root of the control flow node would prevent content projection as well.
PR Close#58607
This commit addresses a problem with tests that use the `fit` function to focus on individual test cases. While these tests run successfully in the full suite, they fail when focused individually using `fit`.
The issue lies in the behavior of `withEventReply` and other hydration-related functions (i.e., `provideX`, `withX`). These functions return platform-specific providers based on the `ngServerMode` setting, causing inconsistencies between server and browser environments. As a result, provider instances cannot be reused across server and browser applications.
**Example of problematic code:**
```ts
const hydrationFeatures = [withEventReply()];
const html = await ssr(SimpleComponent, { hydrationFeatures });
// Expected behavior ...
const appRef = await prepareEnvironmentAndHydrate(doc, html, SimpleComponent, {
hydrationFeatures,
});
// Expected behavior ...
```
**Solution:**
To address this, we define `hydrationFeatures` as a function instead of a static array. This ensures that a new instance of `withEventReply` is created separately for each environment, eliminating platform-specific mismatches between server and browser contexts:
```typescript
const hydrationFeatures = () => [withEventReply()]; // Define as a function
const html = await ssr(SimpleComponent, { hydrationFeatures: hydrationFeatures() });
// Expected behavior ...
const appRef = await prepareEnvironmentAndHydrate(doc, html, SimpleComponent, {
hydrationFeatures: hydrationFeatures(),
});
// Expected behavior ...
```
PR Close#58538
This commit adds the `ngServerMode` as global, which allows for the tree-shaking of server-only code from the bundles. When this flag is unset at runtime, server-specific code will be excluded by Closure, optimizing bundle size.
**Internal Angular Flag:** This is an internal Angular flag (not a public API), avoid relying on it in application code.
PR Close#58386
hydrate triggers were firing in CSR cases and attempting to find parent defer blocks. This prevents that from happening. In these cases, the defer block id will be empty.
fixes: #58359
PR Close#58366
By removing the standalone feature, we reduce the amount of code generated for components but at the cost of including the `StandaloneService` in the main bundle even if no standalone components are included in it.
PR Close#58288
This re-organizes the hydration tests to make it easier to add new tests. Incremental hydration can have tests in a separate file after this groundwork is landed.
PR Close#58196
The `bootstrap()` phase might fail e.g. due to an rejected promise in some `APP_INIIALIZER`.
If `PlatformRef` is not destroyed, then the main app's injector is not destroyed and therefore `ngOnDestroy` hooks of singleton services is not called on the end (failure) of SSR.
This could lead to possible memory leaks in custom SSR apps, if their singleton services' `ngOnDestroy` hooks contained an important teardown logic (e.g. unsubscribing from RxJS observable).
Note: I needed to fix by the way another thing too: now we destroy `moduleRef` when `platformInjector` is destroyed - by setting a `PLATFORM_DESTROY_LISTENER`
fixes#58111
PR Close#58112
With the newly-added `RenderMode` config for routes, some of the routes may have the `RenderMode.Client` mode enabled, while also having `provideClientHydration()` function in provider list at bootstrap. As a result, there was a false-positive warning in a console, notifying developers about hydration misconfiguration.
This commit adds extra logic to handle this situation and avoid such warnings.
Note: there is a change required on the CLI side to add an extra marker, which would activate the logic added in this commit.
PR Close#58004
Before this commit, `@let` decleration with an array where mistaken for a component in the lView and throwing an unexpected error.
This commit fixes this.
PR Close#57816
These should only fire if the target is the same as the targetElement. Also, delete an out of date test since capture/non-capture tests are separately covered.
PR Close#57476