Import
import { RefSubject } from "@typed/fx";Access RefSubject.RefSubject through the imported RefSubject export. Its declaration below describes the member.
This public exposure is a re-export. Its import path is supported; declaration documentation is shared with the other public exposures below.
Signatures
export interface RefSubject<A, E = never, R = never> extends Computed<A, E, R>, Subject.Subject<A, E, R> {
readonly [RefSubjectTypeId]: RefSubjectTypeId;
readonly updates: <B, E2, R2>(f: (ref: GetSetDelete<A, E, R>) => Effect.Effect<B, E2, R2>) => Effect.Effect<B, E | E2, R | R2>;
readonly interrupt: Effect.Effect<void, never, R>;
}export declare namespace RefSubject {
type Any = RefSubject<any, any, any> | RefSubject<any, any> | RefSubject<any, never, any> | RefSubject<any>;
interface Service<Self, Id extends string, A, E> extends RefSubject<A, E, Self> {
readonly id: Id;
readonly service: Context.Service<Self, RefSubject<A, E>>;
readonly make: <R = never>(value: A | Effect.Effect<A, E, R> | Fx<A, E, R>, options?: RefSubjectOptions<A> & {
readonly skip?: number;
readonly take?: number;
}) => Layer.Layer<Self, never, Exclude<R, Scope.Scope>>;
readonly layer: <E2, R2>(make: Effect.Effect<RefSubject<A, E>, E2, R2 | Scope.Scope>) => Layer.Layer<Self, E2, Exclude<R2, Scope.Scope>>;
}
interface Class<Self, Id extends string, A, E> extends RefSubject.Service<Self, Id, A, E> {
new (): RefSubject.Service<Self, Id, A, E>;
}
}Why
Unifies synchronized mutable state, Effectful current reads, and Fx pushes so the same state can be tested and consumed without a renderer.
Ownership and lifetime
RefSubject is a contract and performs no acquisition. Implementations retain the errors, services, interruption, and Scope requirements expressed by its members.
Property: [[computed:[RefSubjectTypeId]]]
Carries the runtime marker recognized by isRefSubject.
Property: [[computed:[RefSubjectTypeId]]]: Why
Marks the value as a writable RefSubject for runtime guards while retaining its Computed and Subject capabilities.
Property: [[computed:[RefSubjectTypeId]]]: Ownership and lifetime
This declaration performs no acquisition and retains no resources. Implementations preserve source errors, services, and lifetime.
Property: interrupt
Interrupts the RefSubject, stopping all subscriptions and cleaning up resources.
Property: interrupt: Why
Interrupts the RefSubject, stopping all subscriptions and cleaning up resources.
Property: interrupt: Ownership and lifetime
Running this Effect returns void: it resets pending initialization, closes the RefSubject’s
private Scope, interrupts its initializer fiber, and interrupts its Subject. It cannot fail;
R supplies services captured by the RefSubject’s internal lifetime.
Property: updates
Runs an effect that can modify the RefSubject transactionally. All operations within the transaction are atomic and serialized.
Property: updates: Why
Runs an effect that can modify the RefSubject transactionally. All operations within the transaction are atomic and serialized. The transition is serialized at the RefSubject rather than coordinated by callers or UI components.
Property: updates: Ownership and lifetime
Running updates performs one serialized subject transition and returns the committed value. It acquires no resource and preserves source failures and services.
Examples
import { Effect } from "effect"
import { Fx, RefSubject } from "@typed/fx"
// Create a RefSubject with an initial value
const program = Effect.scoped(Effect.gen(function* () {
const count = yield* RefSubject.make(0)
// Get the current value
const current = yield* count
console.log(current) // 0
// Update the value
yield* RefSubject.set(count, 5)
const updated = yield* count
console.log(updated) // 5
// Use as an Fx to observe changes
yield* Effect.forkScoped(Fx.observe(
count,
(value) => Effect.sync(() => console.log("Count changed:", value))
))
// Increment
yield* RefSubject.increment(count)
// Output: "Count changed: 6"
}))import { Effect } from "effect"
import * as RefSubject from "@typed/fx/RefSubject"
const program = Effect.gen(function* () {
const ref = yield* RefSubject.make(0)
// Later, clean up
yield* ref.interrupt
})import { Effect } from "effect"
import * as RefSubject from "@typed/fx/RefSubject"
const program = Effect.gen(function* () {
const balance = yield* RefSubject.make(100)
// Transfer money atomically
yield* balance.updates((ref) =>
Effect.gen(function* () {
const current = yield* ref.get
if (current >= 50) {
yield* ref.set(current - 50)
return "Transfer successful"
}
return "Insufficient funds"
})
)
})Members
RefSubject.RefSubject.AnyDescribes the any type.
RefSubject.RefSubject.ClassDefines the class state contract.
RefSubject.RefSubject.ServiceDefines the service state contract.
Other public imports
These import paths expose the same declaration. Each page retains its own public name and signature.