Repository: angular
Issue: Add a way to receive old value when a signal changes
Labels: area: core,core: reactivity,cross-cutting: signals

### Which @angular/* package(s) are relevant/related to the feature request?

core

### Description

Hi

Long time react/mobx dev, me and the team are looking into moving to Angular.
Our timing seems to be ideal, with the launch of signals, which seem promising.

Coming from MobX which is awesome, signals share several similarities. 
We would like to use signals for a lightweight state management, however the API is limited
For example, there is no way for someone to "observe" a signal and once it changes, to have access to the previous value within the callback.
A similar request was added here for computed.
https://github.com/angular/angular/issues/54339

I would really like to see something like signal.subscribe(previousValue => {}) in order to avoid any issues or concerns as dicussed in the computed thread

 Inspired by MobX's reaction (which can track multiple observables) 
https://mobx.js.org/reactions.html#reaction

### Proposed solution

Introduce a subscription method to signals where the previous value is available. 
The subscription should return a disposer function, to stop the unsubscription 

### Alternatives considered

Currently we have added our own workaround, but it has its own limitations, since you need to always pass the same object that wraps the signal in order to function correctly. 

`
export class SubscriptableSignal<T>{
    private subscribers: ISubscribers<T> = {};
    protected model: WritableSignal<T>;
    public signal: Signal<T>;

    constructor(model: T) {
        this.model = signal<T>(model);
        this.signal = this.model.asReadonly();
    }

    /**
     * Subscribe to the model to be notified each time a change is made
     * @param fn
     */
    subscribe(fn: subscriber<T>){
        const uniqueId = `${Date.now()}-${Math.random()}`;
        this.subscribers[uniqueId] = fn;
        return this.disposerCallback(uniqueId);
    }

    /**
     * Return a function that cancels the subscription
     * @param subscription
     * @protected
     */
    protected disposerCallback(subscription: string){
        return () => {
            this.unSubscribe(subscription);
        }
    }

    /**
     * Removes subscription
     * @param uniqueId
     */
    protected unSubscribe(uniqueId: string){
        delete this.subscribers[uniqueId];
    }

    /**
     * Inform subscribers of model change
     * Subscribers receive previous and current value
     * @param previousValue
     * @param currentValue
     * @protected
     */
    protected informSubscribers(previousValue: T, currentValue: T){
        Object.values(this.subscribers).forEach(fn => {
            fn(previousValue, currentValue);
        });
    }

    /**
     * Wrap signal's update and after the update is done, notify subscribers
     * @param fn
     */
    update(fn: (value: T) => T){
        const previousValue = this.model();
        this.model.update(fn);
        this.informSubscribers(previousValue, this.model());
    }
}`