# Push.mapBoth

Transforms both the output (Fx) success and error channels of a `Push` using the provided options.

Mirrors `Effect.mapBoth` on the Fx side: `onSuccess` maps every emitted value
one-to-one and `onFailure` maps typed failures via `Cause.map`; defects and
interrupts are preserved. Ordering, services, and the input side are unchanged.

## Signatures

```ts
export declare const mapBoth: {
    <B, C, E2, E3>(options: {
        readonly onFailure: (e: E2) => E3;
        readonly onSuccess: (b: B) => C;
    }): <A, E, R, R2>(push: Push<A, E, R, B, E2, R2>) => Push<A, E, R, C, E3, R2>;
    <A, E, R, B, E2, R2, C, E3>(push: Push<A, E, R, B, E2, R2>, options: {
        readonly onFailure: (e: E2) => E3;
        readonly onSuccess: (b: B) => C;
    }): Push<A, E, R, C, E3, R2>;
};
```

## Why

Adapt both observable result channels at once while leaving command handling
and non-typed Cause information intact.

## Ownership and lifetime

Both functions run synchronously in the output delivery path and acquire no
resources. The wrapped Fx retains ownership of its subscription and finalizers.

## Examples

```ts
import { Effect } from "effect"
import * as Fx from "@typed/fx/Fx"
import * as Push from "@typed/fx/Push"
import * as Sink from "@typed/fx/Sink"

const push = Push.make(Sink.make(() => Effect.void, (_: string) => Effect.void), Fx.succeed(2))
const labeled = Push.mapBoth(push, {
  onFailure: (error: never) => error,
  onSuccess: (value) => `value:${value}`
})
```
