This commit bumps up the stability status of the linkedSignal
to developer preview - clearly expressing our highier confidence
in this API.
PR Close#58684
This commit updates the code of the incremental hydration feature to make the `DeferBlockRegistry` class tree-shakable. The class is only needed for hydration cases and it should not be included into client bundles for client-only apps.
PR Close#58424
For scroll-blocking events like 'touchstart', 'touchmove', 'wheel' and 'mousewheel',
if passive option is not specified when adding the event listener, browser may give
a violation warning.
This PR allows us to set the passive option when calling event lib's addEvent().
PR Close#58316
This commit adds an operator to help rxjs observables important for rendering
keep the application unstable (and prevent serialization) until there is
an event (observable emits, completes, or errors, or the subscription is
unsubscribed). This helps with SSR for zoneless and also helps for when
operations are intentionally executed outside the Angular Zone but are
still important for SSR (i.e. angularfire and the zoneWrap helper hacks).
PR Close#56533
Angular DevTools is working on developing signal debugging support. This commit is a step in the direction of making available debug information to the framework that will allow Angular DevTools to provide users with more accurate information regarding the usage of signals in their applications.
Follow up PRs that will use this arg will:
- Develop a typescript transform that will detect usages of signal functions and attempt to add a debugName without the user needing to specify one directly
- Develop debug APIs for discovering signal graphs within Angular applications (using debugName as a way to label nodes on the graph)
PR Close#57073
add helper functions provideAppInitializer, provideEnvironmentInitializer & providePlatformInitializer
to respectively simplify and replace the use of APP_INITIALIZER, ENVIRONMENT_INITIALIZER, PLATFORM_INITIALIZER
add a migration for the three initialiers
PR Close#53152
Implementations of two rxjs-interop APIs which produce `Resource`s from
RxJS Observables. `rxResource()` is a flavor of `resource()` which uses a
projection to an `Observable` as its loader (like `switchMap`).
PR Close#58255
Implement a new experimental API, called `resource()`. Resources are
asynchronous dependencies that are managed and delivered through the signal
graph. Resources are defined by their reactive request function and their
asynchronous loader, which retrieves the value of the resource for a given
request value. For example, a "current user" resource may retrieve data for
the current user, where the request function derives the API call to make
from a signal of the current user id.
Resources are represented by the `Resource<T>` type, which includes signals
for the resource's current value as well as its state. `WritableResource<T>`
extends that type to allow for local mutations of the resource through its
`value` signal (which is therefore two-way bindable).
PR Close#58255
This change introduces the new reactive primitive: linkedSignal.
A linkedSignal represents state (hence the signal in the name)
that is reset based on the provided computation. Conceptually
it is a state that is maintained / valid only in the context of
another source signal (context is deteremined by a computation).
Closes#55673
PR Close#58189
This commit exposes the new producerMarkClean utility that
makes it possible to mark a reactive node as clean following
changes to the node's value. In practice it resets the dirty
flag and all other internal flags as need. Prior to this change
the cleanup code was duplicated.
The new utility will be used in the linkedSignal implementation.
PR Close#58228
The shared style host now has the capability to add component styles as
link elements with external style references. This is currently unused
within the runtime but is an enabling feature for upcoming features such
as automatic component style HMR and development server deferred
stylesheet processing. Instead of inline style content that is then
added to a `style` element for each host node, a `link` element with a
stylesheet `rel` attribute and a `href` attribute can now be created.
The development server must be configured to provide the relevant
component stylesheet upon request. The Angular CLI development server
will provide this functionality once this capability is enabled.
Since the primary use of this capability is development mode and will
not be used for production code, server (SSR) style reuse is currently
not yet implemented but may be implemented in the future.
A component feature is used to provide the DOM renderer access to any
external styles that were emitted at compile time. When external styles
are present, the `getExternalStyles` function will be present on the
runtime component metadata object. The DOM render will use this function
to access and encapsulate the external style URLs as required by the
component.
PR Close#57922
Adds a `manualCleanup` flag to `afterRender` and `afterNextRender`, similarly to `effect`. The reason is that currently if the hook is created outside of an injection context, it requires an injector to be passed in. In some cases that injector might be an injector that is never destroyed (e.g. `EnvironmentInjector`) which can give a false sense of security users thinking that the hook will be cleaned up automatically. We fell into this in the CDK which caused a memory leak (see https://github.com/angular/components/pull/29709). With the `manualCleanup` option users explicitly opt into cleaning the hook up themselves.
PR Close#57917
`@angular/upgrade` writes to inputs when downgrading an Angular 2+ component
into an Angular.JS adapter. Previously, it wrote directly to the input
property, which isn't compatible with input signals. It also handles
`ngOnChanges` directly.
The correct way to support input signals would be to refactor upgrade to use
`ComponentRef.setInput`, which also handles `ngOnChanges` internally.
However, this refactoring might be more breaking since it would change the
timing of certain operations. Instead, this commit updates the code to
recognize `InputSignal` and write it through the `InputSignalNode`. This
avoids the above breaking changes for now, until a bigger refactoring can be
tested.
Fixes#56860.
PR Close#57020
This commit promotes the `ExperimentalPendingTasks` service from
experimental to developer preview and includes a migration schematic for
the rename.
BREAKING CHANGE: `ExperimentalPendingTasks` has been renamed to
`PendingTasks`.
PR Close#57533
The original effect design for Angular had one "bucket" of effects, which
are scheduled on the microtask queue. This approach got us pretty far, but
as developers have built more complex reactive systems, we've hit the
limitations of this design.
This commit changes the nature of effects significantly. In particular,
effects created in components have a completely new scheduling system, which
executes them as a part of the change detection cycle. This results in
behavior similar to that of nested effects in other reactive frameworks. The
scheduling behavior here uses the "mark for traversal" flag
(`HasChildViewsToRefresh`). This has really nice behavior:
* if the component is dirty already, effects run following preorder hooks
(ngOnInit, etc).
* if the component isn't dirty, it doesn't get change detected only because
of the dirty effect.
This is not a breaking change, since `effect()` is in developer preview (and
it remains so).
As a part of this redesigned `effect()` behavior, the `allowSignalWrites`
flag was removed. Effects no longer prohibit writing to signals at all. This
decision was taken in response to feedback / observations of usage patterns,
which showed the benefit of the restriction did not justify the DX cost.
The new effect timing is not yet enabled - a future PR will flip the flag.
PR Close#56501
This helper method is simply a convenience function that reduces some
boilerplate with manually adding and removing a task around some
asynchronous function.
PR Close#56546
This commit introduces an overload for `input` to accept `undefined` as initial value if only
options are needed to be provided, inferring an input of type `T|undefined`. Prior to this change,
the type argument as specified needed to include `|undefined` explicitly even though that isn't
necessary when passing options isn't needed.
Relates to #53909
PR Close#57621
Implement the `afterRenderEffect` primitive, which creates effect(s) that
run as part of Angular's `afterRender` sequence. `afterRenderEffect` is a
useful primitive for expressing DOM operations in a declarative, reactive
way.
The API itself mirrors `afterRender` and `afterNextRender` with one big
difference: values are propagated from phase to phase as signals instead of
as plain values. As a result, later phases may not need to execute if the
values returned by earlier phases do not change.
PR Close#57549
This commit removes the abstract base class and two separate
implementations of `ComponentFixture` for zone vs zoneless. Now that the
behaviors have gotten close enough to the same, the diverged concrete
implementations serve less value. Instead, the different behaviors can
be easily handled in if/else branches. The difference is now limited to
the default for `autoDetect` and how `detectChanges` functions.
PR Close#57416
The zoneless scheduler callback was executed in the root zone rather
than simply in `runOutsideAngular` to allow us to land the hybrid mode
change detection (scheduler always enabled, even for zones) without
breaking a ton of existing `fakeAsync` tests that could/would fail with
the "timer(s) still in queue" error. However, this caused another
problem: when a test executes inside `fakeAsync`, it cannot flush the
scheduled time. A similar problem exists with event and run coalescing (#56767).
This change would allow `fakeAsync` to flush the zoneless-scheduled
change detections and minimize breaking existing tests
by flushing pending timers at the end of the test, which actually now
matches what's done internally.
PR Close#56932
Errors during change detection from `ApplicationRef.tick` are only
reported to the `ErrorHandler`. By default, this only logs the error to
console. As a result, these errors can be missed/ignored and allow tests
to pass when they should not. This change ensures that the errors are
surfaced. Note that this is already the behavior when zoneless is
enabled.
BREAKING CHANGE: Errors that are thrown during `ApplicationRef.tick`
will now be rethrown when using `TestBed`. These errors should be
resolved by ensuring the test environment is set up correctly to
complete change detection successfully. There are two alternatives to
catch the errors:
* Instead of waiting for automatic change detection to happen, trigger
it synchronously and expect the error. For example, a jasmine test
could write `expect(() => TestBed.inject(ApplicationRef).tick()).toThrow()`
* `TestBed` will reject any outstanding `ComponentFixture.whenStable` promises. A jasmine test,
for example, could write `expectAsync(fixture.whenStable()).toBeRejected()`.
As a last resort, you can configure errors to _not_ be rethrown by
setting `rethrowApplicationErrors` to `false` in `TestBed.configureTestingModule`.
PR Close#57200
From the internal issue on the matter:
> When using the standard Jasmine version of it promises returned by the body function are automatically awaited. The Catalyst version of it is fake-async, so awaiting the promise does not make sense; however it would be nice if Catalyst automatically flushed the promise to replicate the experience of using standard it. This would allow users to do the following:
```
it('should fail later', async () => {
await new Promise(r => setTimeout(r));
fail('failure');
});
```
> In Catalyst today the above test will pass. If this proposal to automatically flush the resulting promise were implemented it would fail.
Flushing after the tests complete has been the default behavior inside
Google since 2020. Very few tests remain that use the old behavior of
only flushing microtasks. The example above would actually fail with
`fakeAsync` due to the pending timer, but the argument still remains the
same. We might as well just flush if we're going to fail the test
anyways by throwing if there's no flush at the end.
PR Close#57239
This was an old feature that mapped shift + click (et al) to "clickmod". This doesn't really make sense to add to Angular, so let's remove it.
PR Close#57201
This option was introduced out of caution as a way for developers to opt out of the new behavior in v18 which schedule change detection for the above events when they occur outside the Zone. After monitoring the results post-release, we have determined that this feature is working as desired and do not believe it should ever be disabled by setting this option to `true`.
PR Close#57029
This is the first step towards combining `EarlyEventContract` and `EventContract`. It contains a few refactors, such as making names more consistent.
The goal of this refactor is to remove the `EarlyEventContract` class altogether, as well as `EventContract`.
To install the early event contract with the default events in early script tag, users will call:
`bootstrapGlobalEarlyEventContract()`
And for boostraping:
`registerGlobalDispatcher(dispatcher)`
PR Close#56900
The option introduced in 5df3e78c99 has been named `equals` whereas the existing option in `signal` is named `equal`.
This commit renames the new option to `equal` as well to keep the naming coherent across these APIs.
PR Close#56769
This should make things somewhat faster, since setAttribute can be slower than addEventListener. Jsaction attribute is still needed for SSR though.
PR Close#56747
Export `producerIncrementEpoch` which was missing before, as well as a new
`runPostSignalSetFn` helper. These changes make it easier to write `signal`-
like utilities which don't use the `createSignal` abstraction.
PR Close#56759
Now that all `Dispatcher` implementations use `ActionResolver`, `EventContract` no longer needs to. Additionally, all a11y click support has been removed. `EventContract` will not specifically listen for `keydown` automatically, as all `EventContract` instances already have `keydown` listeners. This removes the need for the `A11Y_CLICK_SUPPORT` define, which will be removed in a future PR.
PR Close#56723
These values are inlined in ActionFlow internally in google3, and are no longer used.
Do some additional cleanup to only define the properties once.
PR Close#56590
`EventContract` usages in Angular now use `false` for
`useActionResolver`. Tests have been updated, with functionality that
depends on `ActionResolver` moving to dispatcher_test.ts.
PR Close#56369
PR Close#56369
Adds the implementation of the following new instructions:
* `declareLet` - creation-time instruction that initializes the slot for a let declaration.
* `storeLet` - update-time instruction that stores the current value of a let declaration.
* `readContextLet` - instruction that reads the stored value of a let declaration from a different view.
On top of the instructions, it also introduces a new `LetDeclaration` TNode type.
The new TNode is nececessary for DI to work correctly in pipes inside the let expression,
as well as for proper hydration support.
PR Close#56527
This commit fixes a typo in the `AfterRenderPhase` deprecation warning and improves the documentation of the options parameter of the afterRender hooks (which are now all named `options` instead of being called `opts` in some functions and `options` in others).
PR Close#56522
This allows for helpers like the following to work intuitively for all
types of "input fields". It also establishes the intended mental
philosophy that a model is both an input and an output.
```ts
/** Unwraps all signal input properties. */
export type UnwrapSignalInputs<T> = {
[K in keyof T]: T[K] extends InputSignalWithTransform<any, infer WriteT>
? WriteT
: T[K];
};
```
PR Close#56452
`toSignal` predates the decision to allow a more flexible equality check in
signals, and thus doesn't support a custom equality function. This commit
adds the ability to pass a custom value equality function. As a side effect,
it now adds the default equality check where it wasn't used before.
Fixes#55573
PR Close#56447
We don't have any docs yet for that error, so I'm removing the minus sign which indicate that there is a dedicated error doc.
Fixes#56424
PR Close#56441
This commit starts exposing `isSignal` for inputs in the
`ComponentMirror`. We initially had this as a draft when rolling out
signal inputs, but there were no good use-cases, so we skipped it.
Now, inside G3, for the testing infrastructure and rolling out
advancements for signal inputs, having this information is necessary and
allows identifying signal inputs without "accessing fields" on the class
that may cause side-effects (like triggering setters).
PR Close#56402
`EventContract` usages in Angular now use `false` for
`useActionResolver`. Tests have been updated, with functionality that
depends on `ActionResolver` moving to dispatcher_test.ts.
PR Close#56369
Adds back the ability to set the phase of an `afterRender` /
`afterNextRender` callback using the `phase` option. However, this API
is now deprecated, and the phase should instead be specified by passing
a spec object rather than a callback function.
PR Close#55648