Implement \`toggleWatchSignal(id)\` in \`signal_debug.ts\` to enable toggling reactive watch listeners on individual signal graph nodes.
- Create reactive \`Watch\` instances using \`createWatch\` to log signal value/state changes to the console when active.
- Use \`WeakRef\` mapping and \`FinalizationRegistry\` (\`watchCleanupRegistry\`) so active watches do not retain strong references to signal nodes or prevent garbage collection.
- Expose \`watched\` status on \`DebugSignalGraphNode\` and publish \`toggleWatchSignal\` onto \`window.ng\` in development mode.
- Add acceptance tests covering watch activation, signal mutation logging, manual disposal, GC cleanup, and safe invalid ID handling.
This makes it possible to batch effects, where we can "reopen" consumers
during initial render and then finalize them after we are finally done
adding all the effects to a batch:
```
function createBatch() {
const effect = // ... create effect node
resetConsumerBeforeComputation(effect);
return effect;
}
// pseudo-code
function appendEffect(effectBatch, updater) {
if (value is a signal) {
const prevConsumer = setActiveConsumer(effectBatch.node);
const output = value();
setActiveConsumer(prevConsumer);
effectBatch.push({ signal, updater });
return output;
}
}
function finalizeBatch(effectBatch) {
if (effectBatch.length > 0) {
finalizeConsumerAfterComputation(effectBatch.node);
}
}
const effectBatch = createBatchEffectNode();
appendEffect(signal1, (newValue) => /* something */);
appendEffect(signal2, (newValue) => /* something different */);
finalizeBatch(effectBatch);
```
PR Close#62549
This way, an arbitrary service can implement Angular's service requirements without a hard dependency on @angular/core
ex:
class Foo {
bar = inject(Bar);
}
registerInjectable(Foo);
PR Close#62087
Refactor createSignal to return a tuple instead of a signal getter. createSignalTuple will be removed in a follow up pr once createSignalTuple usages in google3 are migrated to createSignal.
PR Close#61705
Add createSignalTuple function to match Wiz array destructuring signal return. This will be the implementation for createSignal once createSignal usages in google3 are migrated to createSignalTuple.
PR Close#60903
This updates `createSignal` to use `signalGetFn` to define the signal getter and exports `signalGetFn` from the shared signal primitives.
PR Close#60497
Adds a hook in the same style as `postSignalSetFn` for running side effects when a producer has been created. This hook will be passed the reactive node being created.
PR Close#60333
This change moves more logic to the primitives package by pushing
the equal configuration on a reactive node to the signal and
computed creation utilities.
PR Close#60300
Instead of relying on Microsoft's API extractor for `d.ts` bundling,
we are switching to Rollup-based `.d.ts` bundling.
This allows us to support code spliting, even for `.d.ts` files,
allowing for relative imports to be used between entry-points, without
ending up duplicating `.d.ts` definitions in two files. This would otherwise cause
problems with assignability of types.
It also nicely integrates into our existing rollup configuration, and
overall simplifies the `ng_package` rule even further!
Notably `tsup` also uses this rollup plugin, and it seems to work well.
Keep in mind that Microsoft's API extractor is pretty hard to integrate,
caused many problems in the past, and isn't capable of code splitting.
This aligns our d.ts bundling with the .mjs bundling (great alignment).
PR Close#60321
This should keep the existing behavior intact. Right now retrieve never returns back NOT_FOUND. This should not be the case, but tests fail if I do add this behavior so itll have to be later.
PR Close#60192
Note that this does NOT use the retrieve method yet. I believe we need to move the logic for notFoundValue into the inject implementation.
PR Close#60154
This change casts the injector back and forth since all instances of
injector currently don't implement the `retrieve` method. Note that
the retrieve method is seen as optional, so that Angular can revert back to
inject if necessary.
PR Close#60090
Updates the signature of the `throwInvalidWriteToSignalError` to take the signal node in question and pass it along to the throwInvalidWriteToSignalErrorFn handler function. This allows the handler to e.g. include the signal name in error messaging.
PR Close#59600
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 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
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 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
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
`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
This makes events bubble! This change also contains changes to
dispatcher and event_dispatcher to make replay synchronous,
so that we avoid odd timing issues. This can be split out though.
Lastly, we have one cleanup change to move the mapping from
event type to functions on the element itself.
PR Close#56036
This will prevent running `ActionResolver` logic multiple times while
migrating to use `Dispatcher` to resolve actions rather than
`EventContract`.
PR Close#55864