function / @typed/fx/RefSubject

make

Creates a new RefSubject from a value, Effect, or Fx.

Package version
2.0.0-beta.7
Category
Constructors
Since
1.0.0

Import

import { make } from "@typed/fx/RefSubject";

Signatures

export declare function make<A, E = never, R = never>(effect: A | Effect.Effect<A, E, R> | Stream.Stream<A, E, R> | Fx<A, E, R>, options?: RefSubjectOptions<A>): Effect.Effect<RefSubject<A, E>, never, R | Scope.Scope>;

Why

RefSubject keeps current state and pushed changes independent of any UI renderer. Domain transitions can therefore be constructed, composed, and tested with Effect alone; rendering is one optional consumer of the state. Plain values, Effect programs, pull-based Effect Streams, and push-based Fx sources all enter through the same state boundary.

Ownership and lifetime

Creation requires an Effect Scope. That scope owns source acquisition, subscriptions, and finalization. The returned RefSubject exposes the source error type when read or observed, while construction itself cannot fail. Closing the scope interrupts a live source and releases its resources.

Initialization

Calling make is lazy because it returns an Effect: nothing is allocated and no source runs until that creation Effect is executed. After creation, a plain value is immediately available. An Effect input runs once on the first current read or observation. Fx and Stream inputs instead start one shared source run when the creation Effect executes; reads wait for their first value or failure and later emissions replace the retained current state. Equality and buffering behavior can be customized with RefSubjectOptions.

Examples

import { Effect } from "effect"
import * as RefSubject from "@typed/fx/RefSubject"
import { Fx } from "@typed/fx"

// From a plain value
const program1 = Effect.gen(function* () {
  const ref = yield* RefSubject.make(42)
  const value = yield* ref
  console.log(value) // 42
})

// From an Effect
const program2 = Effect.gen(function* () {
  const ref = yield* RefSubject.make(
    Effect.succeed("Hello")
  )
  const value = yield* ref
  console.log(value) // "Hello"
})

// From an Fx (tracks the latest value)
const program3 = Effect.gen(function* () {
  const ref = yield* RefSubject.make(
    Fx.fromIterable([1, 2, 3])
  )
  const value = yield* ref
  console.log(value) // 3 (latest value)
})

Other public imports

These import paths expose the same declaration. Each page retains its own public name and signature.

Related reading

Source