function / @typed/fx

RefSubject.make

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

Package version
2.0.0-beta.13
Category
Constructors
Since
1.0.0
Member of
RefSubject

Import

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

Access RefSubject.make 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 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.

An Effect input is lazy even after construction: yield* make(effect) returns the ref without running or awaiting effect. The first read or observation starts its shared initializer. Return a template containing the ref to let rendering observe initialization; yield* ref instead waits for the current value before constructing the template.

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.

Source