Import
import { Fx } from "@typed/fx/Fx";Signatures
export interface Fx<A, E = never, R = never> extends Pipeable {
readonly [FxTypeId]: Fx.Variance<A, E, R>;
readonly run: <RSink>(sink: Sink.Sink<A, E, RSink>) => Effect.Effect<unknown, never, R | RSink>;
}export declare namespace Fx {
type Any = Fx<any, any, any>;
interface Variance<A, E, R> {
readonly _A: Types.Covariant<A>;
readonly _E: Types.Covariant<E>;
readonly _R: Types.Covariant<R>;
}
type Success<T> = [
T
] extends [
never
] ? never : T extends Fx<infer _A, infer _E, infer _R> ? _A : never;
type Error<T> = [
T
] extends [
never
] ? never : T extends Fx<infer _A, infer _E, infer _R> ? _E : never;
type Services<T> = [
T
] extends [
never
] ? never : [
T
] extends [
Fx<infer _A, infer _E, infer _R>
] ? _R : never;
interface Service<Self, Id extends string, A, E> extends Fx<A, E, Self> {
readonly id: Id;
readonly service: Context.Service<Self, Fx<A, E>>;
readonly make: <R = never>(fx: Fx<A, E, R> | Effect.Effect<Fx<A, E, R>, E, R>) => Layer<Self, E, Exclude<R, Scope.Scope>>;
}
interface Class<Self, Id extends string, A, E> extends Service<Self, Id, A, E> {
new (): Service<Self, Id, A, E>;
}
}Why
Browser events, clocks, sockets, and users decide when work exists. Fx
models that producer-driven direction while retaining Effect’s explicit
success, error, and service channels. An Effect, Stream, Promise,
ReadableStream, iterable, or custom source can participate through an
explicit constructor; Fx extends the Effect ecosystem rather than
replacing it.
Ownership and lifetime
Constructing an Fx starts no work. Calling run returns an Effect whose
running fiber and Scope own subscriptions, child fibers, and finalizers.
Interruption propagates through that Effect lifetime. The supplied Sink
contributes its requirements to run; failures are delivered to the Sink,
which is why the returned Effect itself cannot fail.
Composition
The type parameters follow Effect’s A, E, R vocabulary. Consequently,
an Fx<RenderEvent, E, R> can describe arbitrary UI without hiding its
failures or required services.
Effect foundations
Fx execution is an Effect,
resource ownership uses Scope,
concurrent runs use Fiber, and
failures retain Effect’s structured Cause.
Property: [[computed:[FxTypeId]]]
Identifies this value as an Fx and records its success, error, and service variance.
Property: [[computed:[FxTypeId]]]: Why
The marker makes Fx distinguishable at runtime without executing it, while its
type carries the three channels through structural composition.
Property: [[computed:[FxTypeId]]]: Ownership and lifetime
Reading the marker starts no work and acquires no resources.
Property: run
Connects this producer to a Sink and returns the Effect that owns the connection.
Property: run: Why
Keeping execution behind an Effect preserves typed services, structured
concurrency, and interruption instead of starting hidden work during construction.
Values are offered to the sink in the order chosen by this Fx; the producer may
emit zero, one, or many values.
Property: run: Ownership and lifetime
Work starts when the returned Effect runs. Its fiber owns the subscription and
any child scopes. Interrupting it interrupts the producer and runs its finalizers.
Producer failures are delivered to sink.onFailure, so they are not repeated in
the returned Effect’s error channel.
Examples
import { Effect } from "effect"
import { Fx } from "@typed/fx"
const keys: Fx.Fx<KeyboardEvent> = Fx.callback((emit) => {
const onKey = (event: KeyboardEvent) => emit.succeed(event)
document.addEventListener("keydown", onKey)
return Effect.sync(() => document.removeEventListener("keydown", onKey))
})Members
Fx.AnyMatches any
Fxregardless of its value, error, or service channels.Fx.ClassThe constructible service class returned by
Fx.Service.Fx.ErrorExtracts the typed error from an
Fx.Fx.ServiceAn
Fxwhose implementation is obtained from an Effect service.Fx.ServicesExtracts the services required to run an
Fx.Fx.SuccessExtracts the emitted value type from an
Fx.Fx.VarianceDescribes how an
Fxvaries in its value, error, and service channels.
Other public imports
These import paths expose the same declaration. Each page retains its own public name and signature.