angular/packages/core/src/resource
Alex Rickabaugh 1ba9b7ac50 feat(core): resource composition via snapshots
* Define `ResourceSnapshot<T>` as a type union of possible states for a
`Resource<T>`.
* Add `Resource.snapshot()` to convert a `Resource` to a signal of its
  snapshot.
* Add `resourceFromSnapshots` to convert a reactive snapshot back into a
  `Resource`.

By converting resources from/to `Signal<ResourceSnapshot>`s, full
composition of resources is now possible on top of signal composition APIs
like `computed` and `linkedSignal`.

For example, a common feature request is to have a `Resource` which retains
its value when its reactive source (params) changes. This can now be built
as a utility, leveraging `linkedSignal`'s previous value capability:

```ts
function withPreviousValue<T>(input: Resource<T>): Resource<T> {
  const derived = linkedSignal({
    source: input.snapshot,
    computation: (snap, previous) => {
      if (snap.status === 'loading' && previous?.value) {
        // When the input resource enters loading state, we keep the value
        // from its previous state, if any.
        return {status: 'loading', value: previous.value.value};
      }

      // Otherwise we simply forward the state of the input resource.
      return snap;
    },
  });

  return resourceFromSnapshots(derived);
}

// In application code:

userId = input.required<number>();
user = withPreviousValue(httpResource(() => `/user/{this.userId()}`));
// if `userId()` switches, `user.value()` will keep the old value until
// the new one is ready!
```
2026-01-12 13:49:56 -08:00
..
api.ts feat(core): resource composition via snapshots 2026-01-12 13:49:56 -08:00
from_snapshots.ts feat(core): resource composition via snapshots 2026-01-12 13:49:56 -08:00
index.ts feat(core): resource composition via snapshots 2026-01-12 13:49:56 -08:00
resource.ts feat(core): resource composition via snapshots 2026-01-12 13:49:56 -08:00