# Sink

Consumes pushed successes and failures through effectful callbacks.

## Signatures

```ts
export interface Sink<A, E = never, R = never> {
    readonly onSuccess: (value: A) => Effect<unknown, never, R>;
    readonly onFailure: (cause: Cause.Cause<E>) => Effect<unknown, never, R>;
}
```

```ts
export declare namespace Sink {
    type Any = Sink<any, any, any>;
    type Success<T> = T extends Sink<infer _A, infer _E, infer _R> ? _A : never;
    type Error<T> = T extends Sink<infer _A, infer _E, infer _R> ? _E : never;
    type Services<T> = T extends Sink<infer _A, infer _E, infer _R> ? _R : never;
    interface Service<Self, Id extends string, A, E> extends Sink<A, E, Self> {
        readonly id: Id;
        readonly service: Context.Service<Self, Sink<A, E>>;
        readonly make: <R = never>(onFailure: (cause: Cause.Cause<E>) => Effect<unknown, never, R>, onSuccess: (value: A) => Effect<unknown, never, R>) => Layer<Self, never, Exclude<R, Scope>>;
    }
    interface Class<Self, Id extends string, A, E> extends Service<Self, Id, A, E> {
        new (): Service<Self, Id, A, E>;
    }
}
```

## Why

`Sink` gives an `Fx` producer one uniform destination while retaining Effect's typed service
requirements and complete failure `Cause`. Callback Effects have no typed failure channel, but
they may still defect or be interrupted. Handling an incoming Cause is the consumer's policy;
accepting it successfully does not mean the failed producer operation succeeded.

## Ownership and lifetime

A sink is inert until a producer invokes one of its callbacks. The producer's fiber controls
ordering, interruption, and callback lifetime; services in `R` must be available when callbacks
run. `Sink` itself acquires no resources.

## Property: onFailure

Handles the producer's complete typed failure, defect, or interruption cause.

## Property: onFailure: Why

Accepting `Cause` retains information that would be lost by an error-only callback.

## Property: onFailure: Ownership and lifetime

The invoking producer owns ordering and interruption. The returned Effect acquires and releases
any resources according to its own services and Scope.

## Property: onSuccess

Handles one successful value.

## Property: onSuccess: Why

The success callback is the value-side consumer boundary used by Fx producers.

## Property: onSuccess: Ownership and lifetime

The invoking producer owns ordering and interruption. The returned Effect acquires and releases
any resources according to its own services and Scope.

## Examples

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

const logger: Sink.Sink<number, string> = Sink.make(
  (cause) => Effect.logError(cause),
  (value) => Effect.log(`received ${value}`)
)
```
