variable / @typed/fx/RefSubject

update

Updates a RefSubject using a pure function.

Package version
2.0.0-beta.7
Category
State updates
Since
1.0.0

Import

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

Signatures

export declare const update: {
    <A>(f: (value: A) => A): <E, R>(ref: RefSubject<A, E, R>) => Effect.Effect<A, E, R>;
    <A, E, R>(ref: RefSubject<A, E, R>, f: (value: A) => A): Effect.Effect<A, E, R>;
};

Why

update expresses a state transition where the state lives, without moving transition logic into a component or renderer. The same function can run in application code, tests, workers, event handlers, or a Typed template.

Ownership and lifetime

The update runs inside the RefSubject’s existing synchronized update boundary: it reads the committed value, derives the next value, commits it, and publishes that change. It acquires no independent resource and retains the subject’s existing error and service channels.

Concurrency and failure

Concurrent updates are serialized by the subject core so each function sees a committed value. A pure updater adds no error channel; failures already associated with reading or writing the RefSubject remain explicit in E.

Examples

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

const program = Effect.gen(function* () {
  const count = yield* RefSubject.make(5)

  // Increment by 1
  yield* RefSubject.update(count, (n) => n + 1)
  const value = yield* count
  console.log(value) // 6

  // Can also use pipe syntax
  yield* count.pipe(RefSubject.update((n) => n * 2))
  const doubled = yield* count
  console.log(doubled) // 12
})

Other public imports

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

Related reading

Source