SubscriptionRef.ts
SubscriptionRef.ts overview
Section titled “SubscriptionRef.ts overview”Stores mutable state and publishes changes as a stream.
A SubscriptionRef<A> stores the latest value, publishes the initial value,
and publishes every committed update so subscribers can observe state over
time. Updates are serialized so only one change is applied at a time. This
module includes constructors, current-value reads, the changes stream,
writes, updates, partial updates, and effectful update helpers.
Since v2.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”changes
Section titled “changes”changes
Section titled “changes”Creates a stream that emits the current value and all subsequent changes to
the SubscriptionRef.
Details
The stream will first emit the current value, then emit all future changes as they occur.
Example (Streaming changes)
import { Deferred, Effect, Fiber, Stream, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(0) const ready = yield* Deferred.make<void>()
const fiber = yield* SubscriptionRef.changes(ref).pipe( Stream.tap(() => Deferred.succeed(ready, void 0)), Stream.take(3), Stream.runCollect, Effect.forkChild )
yield* Deferred.await(ready) yield* SubscriptionRef.set(ref, 1) yield* SubscriptionRef.set(ref, 2)
const values = yield* Fiber.join(fiber) console.log(values) // [ 0, 1, 2 ]})
Effect.runPromise(program)Signature
declare const changes: <A>(self: SubscriptionRef<A>) => Stream.Stream<A>Since v4.0.0
constructors
Section titled “constructors”Constructs a new SubscriptionRef from an initial value.
When to use
Use to create a SubscriptionRef when consumers need to read the latest
value and subscribe to every update.
Details
The initial value is published during construction, so changes starts new
subscribers with that value before future updates.
See
changesfor streaming the current value and subsequent updatessetfor replacing the value and notifying subscribers
Signature
declare const make: <A>(value: A) => Effect.Effect<SubscriptionRef<A>>Since v2.0.0
getters
Section titled “getters”Retrieves the current value of the SubscriptionRef.
Example (Reading the current value)
import { Effect, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(42)
const value = yield* SubscriptionRef.get(ref) console.log(value)})Signature
declare const get: <A>(self: SubscriptionRef<A>) => Effect.Effect<A>Since v2.0.0
getAndSet
Section titled “getAndSet”Retrieves the current value and sets a new value atomically, notifying subscribers of the change.
Example (Getting and setting a value)
import { Effect, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
const oldValue = yield* SubscriptionRef.getAndSet(ref, 20) console.log("Old value:", oldValue)
const newValue = yield* SubscriptionRef.get(ref) console.log("New value:", newValue)})Signature
declare const getAndSet: { <A>(value: A): (self: SubscriptionRef<A>) => Effect.Effect<A> <A>(self: SubscriptionRef<A>, value: A): Effect.Effect<A>}Since v2.0.0
getAndUpdate
Section titled “getAndUpdate”Retrieves the current value and updates it atomically with the result of applying a function, notifying subscribers of the change.
Example (Getting and updating a value)
import { Effect, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
const oldValue = yield* SubscriptionRef.getAndUpdate(ref, (n) => n * 2) console.log("Old value:", oldValue)
const newValue = yield* SubscriptionRef.get(ref) console.log("New value:", newValue)})Signature
declare const getAndUpdate: { <A>(update: (a: A) => A): (self: SubscriptionRef<A>) => Effect.Effect<A> <A>(self: SubscriptionRef<A>, update: (a: A) => A): Effect.Effect<A>}Since v2.0.0
getAndUpdateEffect
Section titled “getAndUpdateEffect”Retrieves the current value and updates it atomically with the result of applying an effectful function, notifying subscribers of the change.
Example (Getting and updating with an effect)
import { Effect, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
const oldValue = yield* SubscriptionRef.getAndUpdateEffect(ref, (n) => Effect.succeed(n + 5)) console.log("Old value:", oldValue)
const newValue = yield* SubscriptionRef.get(ref) console.log("New value:", newValue)})Signature
declare const getAndUpdateEffect: { <A, E, R>(update: (a: A) => Effect.Effect<A, E, R>): (self: SubscriptionRef<A>) => Effect.Effect<A, E, R> <A, E, R>(self: SubscriptionRef<A>, update: (a: A) => Effect.Effect<A, E, R>): Effect.Effect<A, E, R>}Since v2.0.0
getAndUpdateSome
Section titled “getAndUpdateSome”Retrieves the current value and optionally updates the reference.
When to use
Use to read the old SubscriptionRef value while applying a synchronous
update only when a new value is available.
Details
If the function returns Option.some, the new value is set and published. If
it returns Option.none, the reference is left unchanged and no update is
published.
Example (Getting and conditionally updating a value)
import { Effect, Option, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
const oldValue = yield* SubscriptionRef.getAndUpdateSome(ref, (n) => (n > 5 ? Option.some(n * 2) : Option.none())) console.log("Old value:", oldValue)
const newValue = yield* SubscriptionRef.get(ref) console.log("New value:", newValue)})Signature
declare const getAndUpdateSome: { <A>(update: (a: A) => Option.Option<A>): (self: SubscriptionRef<A>) => Effect.Effect<A> <A>(self: SubscriptionRef<A>, update: (a: A) => Option.Option<A>): Effect.Effect<A>}Since v2.0.0
getAndUpdateSomeEffect
Section titled “getAndUpdateSomeEffect”Retrieves the current value and optionally updates the reference effectfully.
When to use
Use to read the old SubscriptionRef value while applying an effectful
update only when a new value is available.
Details
If the effect succeeds with Option.some, the new value is set and
published. If it succeeds with Option.none, the reference is left unchanged
and no update is published.
Example (Getting and conditionally updating with an effect)
import { Effect, Option, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
const oldValue = yield* SubscriptionRef.getAndUpdateSomeEffect(ref, (n) => Effect.succeed(n > 5 ? Option.some(n + 3) : Option.none()) ) console.log("Old value:", oldValue)
const newValue = yield* SubscriptionRef.get(ref) console.log("New value:", newValue)})Signature
declare const getAndUpdateSomeEffect: { <A, R, E>( update: (a: A) => Effect.Effect<Option.Option<A>, E, R> ): (self: SubscriptionRef<A>) => Effect.Effect<A, E, R> <A, R, E>(self: SubscriptionRef<A>, update: (a: A) => Effect.Effect<Option.Option<A>, E, R>): Effect.Effect<A, E, R>}Since v2.0.0
getUnsafe
Section titled “getUnsafe”Retrieves the current value of the SubscriptionRef unsafely.
When to use
Use when you are in synchronous internals or test setup where concurrent updates are controlled.
Gotchas
This function directly accesses the underlying reference without any synchronization. It should only be used when you are certain there are no concurrent modifications.
Example (Reading the current value unsafely)
import { Effect, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(42)
const value = SubscriptionRef.getUnsafe(ref) console.log(value)})Signature
declare const getUnsafe: <A>(self: SubscriptionRef<A>) => ASince v4.0.0
guards
Section titled “guards”isSubscriptionRef
Section titled “isSubscriptionRef”Returns true if the provided value is a SubscriptionRef.
When to use
Use to narrow an unknown value before calling SubscriptionRef operations
that require a subscription reference.
Signature
declare const isSubscriptionRef: (u: unknown) => u is SubscriptionRef<unknown>Since v4.0.0
models
Section titled “models”SubscriptionRef (interface)
Section titled “SubscriptionRef (interface)”A mutable reference whose updates are serialized and published to subscribers.
When to use
Use to observe the current value and subsequent updates as a stream.
Signature
export interface SubscriptionRef<in out A> extends SubscriptionRef.Variance<A>, Pipeable { value: A readonly semaphore: Semaphore.Semaphore readonly pubsub: PubSub.PubSub<A>}Since v2.0.0
modifications
Section titled “modifications”modify
Section titled “modify”Modifies the SubscriptionRef atomically with a function that computes a
return value and a new value, notifying subscribers of the change.
Example (Modifying a value)
import { Effect, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
const result = yield* SubscriptionRef.modify(ref, (n) => [`Old value was ${n}`, n * 2]) console.log(result)
const newValue = yield* SubscriptionRef.get(ref) console.log("New value:", newValue)})Signature
declare const modify: { <A, B>(modify: (a: A) => readonly [B, A]): (self: SubscriptionRef<A>) => Effect.Effect<B> <A, B>(self: SubscriptionRef<A>, f: (a: A) => readonly [B, A]): Effect.Effect<B>}Since v2.0.0
modifyEffect
Section titled “modifyEffect”Modifies the SubscriptionRef atomically with an effectful function that
computes a return value and a new value, notifying subscribers of the
change.
Example (Modifying with an effect)
import { Effect, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
const result = yield* SubscriptionRef.modifyEffect(ref, (n) => Effect.succeed([`Doubled from ${n}`, n * 2] as const)) console.log(result)
const newValue = yield* SubscriptionRef.get(ref) console.log("New value:", newValue)})Signature
declare const modifyEffect: { <B, A, E, R>( modify: (a: A) => Effect.Effect<readonly [B, A], E, R> ): (self: SubscriptionRef<A>) => Effect.Effect<B, E, R> <A, B, E, R>(self: SubscriptionRef<A>, modify: (a: A) => Effect.Effect<readonly [B, A], E, R>): Effect.Effect<B, E, R>}Since v2.0.0
modifySome
Section titled “modifySome”Computes a return value and optionally updates the reference.
When to use
Use to return a separate result while synchronously deciding whether to
publish a new SubscriptionRef value.
Details
If the function returns Option.some for the new value, the value is set and
published. If it returns Option.none, the reference is left unchanged and
no update is published.
Example (Conditionally modifying a value)
import { Effect, Option, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
const result = yield* SubscriptionRef.modifySome(ref, (n) => n > 5 ? ["Updated", Option.some(n * 2)] : ["Not updated", Option.none()] ) console.log(result)
const newValue = yield* SubscriptionRef.get(ref) console.log("New value:", newValue)})Signature
declare const modifySome: { <B, A>(modify: (a: A) => readonly [B, Option.Option<A>]): (self: SubscriptionRef<A>) => Effect.Effect<B> <A, B>(self: SubscriptionRef<A>, modify: (a: A) => readonly [B, Option.Option<A>]): Effect.Effect<B>}Since v2.0.0
modifySomeEffect
Section titled “modifySomeEffect”Computes a return value and optionally updates the reference effectfully.
When to use
Use to return a separate result while effectfully deciding whether to publish
a new SubscriptionRef value.
Details
If the effect succeeds with Option.some, the new value is set and
published. If it succeeds with Option.none, the reference is left unchanged
and no update is published.
Example (Conditionally modifying with an effect)
import { Effect, Option, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
const result = yield* SubscriptionRef.modifySomeEffect(ref, (n) => Effect.succeed(n > 5 ? (["Updated", Option.some(n + 5)] as const) : (["Not updated", Option.none()] as const)) ) console.log(result)
const newValue = yield* SubscriptionRef.get(ref) console.log("New value:", newValue)})Signature
declare const modifySomeEffect: { <A, B, R, E>( modify: (a: A) => Effect.Effect<readonly [B, Option.Option<A>], E, R> ): (self: SubscriptionRef<A>) => Effect.Effect<B, E, R> <A, B, R, E>( self: SubscriptionRef<A>, modify: (a: A) => Effect.Effect<readonly [B, Option.Option<A>], E, R> ): Effect.Effect<B, E, R>}Since v2.0.0
setters
Section titled “setters”Sets the value of the SubscriptionRef, notifying all subscribers of the
change.
Example (Setting a value)
import { Effect, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(0)
yield* SubscriptionRef.set(ref, 42)
const value = yield* SubscriptionRef.get(ref) console.log(value)})Signature
declare const set: { <A>(value: A): (self: SubscriptionRef<A>) => Effect.Effect<void> <A>(self: SubscriptionRef<A>, value: A): Effect.Effect<void>}Since v2.0.0
setAndGet
Section titled “setAndGet”Sets the value of the SubscriptionRef and returns the new value,
notifying all subscribers of the change.
Example (Setting and reading the new value)
import { Effect, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(0)
const newValue = yield* SubscriptionRef.setAndGet(ref, 42) console.log("New value:", newValue)})Signature
declare const setAndGet: { <A>(value: A): (self: SubscriptionRef<A>) => Effect.Effect<A> <A>(self: SubscriptionRef<A>, value: A): Effect.Effect<A>}Since v2.0.0
updating
Section titled “updating”update
Section titled “update”Updates the value of the SubscriptionRef with the result of applying a
function, notifying subscribers of the change.
Example (Updating a value)
import { Effect, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
yield* SubscriptionRef.update(ref, (n) => n * 2)
const value = yield* SubscriptionRef.get(ref) console.log(value)})Signature
declare const update: { <A>(update: (a: A) => A): (self: SubscriptionRef<A>) => Effect.Effect<void> <A>(self: SubscriptionRef<A>, update: (a: A) => A): Effect.Effect<void>}Since v2.0.0
updateAndGet
Section titled “updateAndGet”Updates the value of the SubscriptionRef with the result of applying a
function and returns the new value, notifying subscribers of the change.
Example (Updating and reading the new value)
import { Effect, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
const newValue = yield* SubscriptionRef.updateAndGet(ref, (n) => n * 2) console.log("New value:", newValue)})Signature
declare const updateAndGet: { <A>(update: (a: A) => A): (self: SubscriptionRef<A>) => Effect.Effect<A> <A>(self: SubscriptionRef<A>, update: (a: A) => A): Effect.Effect<A>}Since v2.0.0
updateAndGetEffect
Section titled “updateAndGetEffect”Updates the value of the SubscriptionRef with the result of applying an
effectful function and returns the new value, notifying subscribers of the
change.
Example (Updating with an effect and reading the new value)
import { Effect, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
const newValue = yield* SubscriptionRef.updateAndGetEffect(ref, (n) => Effect.succeed(n + 5)) console.log("New value:", newValue)})Signature
declare const updateAndGetEffect: { <A, E, R>(update: (a: A) => Effect.Effect<A, E, R>): (self: SubscriptionRef<A>) => Effect.Effect<A, E, R> <A, E, R>(self: SubscriptionRef<A>, update: (a: A) => Effect.Effect<A, E, R>): Effect.Effect<A, E, R>}Since v2.0.0
updateEffect
Section titled “updateEffect”Updates the value of the SubscriptionRef with the result of applying an
effectful function, notifying subscribers of the change.
Example (Updating with an effect)
import { Effect, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
yield* SubscriptionRef.updateEffect(ref, (n) => Effect.succeed(n + 5))
const value = yield* SubscriptionRef.get(ref) console.log(value)})Signature
declare const updateEffect: { <A, E, R>(update: (a: A) => Effect.Effect<A, E, R>): (self: SubscriptionRef<A>) => Effect.Effect<void, E, R> <A, E, R>(self: SubscriptionRef<A>, update: (a: A) => Effect.Effect<A, E, R>): Effect.Effect<void, E, R>}Since v2.0.0
updateSome
Section titled “updateSome”Applies an update function to the current value. If it returns
Option.some, sets and publishes that value; if it returns Option.none,
leaves the reference unchanged and does not publish.
Example (Conditionally updating a value)
import { Effect, Option, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
yield* SubscriptionRef.updateSome(ref, (n) => (n > 5 ? Option.some(n * 2) : Option.none()))
const value = yield* SubscriptionRef.get(ref) console.log(value)})Signature
declare const updateSome: { <A>(update: (a: A) => Option.Option<A>): (self: SubscriptionRef<A>) => Effect.Effect<void> <A>(self: SubscriptionRef<A>, update: (a: A) => Option.Option<A>): Effect.Effect<void>}Since v2.0.0
updateSomeAndGet
Section titled “updateSomeAndGet”Applies an optional update and returns the current value afterward.
When to use
Use to conditionally update a SubscriptionRef and read the value that is
current after the update decision.
Details
If the function returns Option.some, the new value is set, published, and
returned. If it returns Option.none, the unchanged current value is
returned without publishing.
Example (Conditionally updating and reading the new value)
import { Effect, Option, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
const newValue = yield* SubscriptionRef.updateSomeAndGet(ref, (n) => (n > 5 ? Option.some(n * 2) : Option.none())) console.log("New value:", newValue)})Signature
declare const updateSomeAndGet: { <A>(update: (a: A) => Option.Option<A>): (self: SubscriptionRef<A>) => Effect.Effect<A> <A>(self: SubscriptionRef<A>, update: (a: A) => Option.Option<A>): Effect.Effect<A>}Since v2.0.0
updateSomeAndGetEffect
Section titled “updateSomeAndGetEffect”Applies an effectful optional update and returns the current value afterward.
When to use
Use to conditionally update a SubscriptionRef effectfully and read the
value that is current after the update decision.
Details
If the effect succeeds with Option.some, the new value is set, published,
and returned. If it succeeds with Option.none, the unchanged current value
is returned without publishing.
Example (Conditionally updating with an effect and reading the new value)
import { Effect, Option, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
const newValue = yield* SubscriptionRef.updateSomeAndGetEffect(ref, (n) => Effect.succeed(n > 5 ? Option.some(n + 3) : Option.none()) ) console.log("New value:", newValue)})Signature
declare const updateSomeAndGetEffect: { <A, E, R>( update: (a: A) => Effect.Effect<Option.Option<A>, E, R> ): (self: SubscriptionRef<A>) => Effect.Effect<A, E, R> <A, E, R>(self: SubscriptionRef<A>, update: (a: A) => Effect.Effect<Option.Option<A>, E, R>): Effect.Effect<A, E, R>}Since v2.0.0
updateSomeEffect
Section titled “updateSomeEffect”Applies an effectful update only when it produces a new value.
When to use
Use to conditionally update a SubscriptionRef with an effectful function
while discarding the resulting value.
Details
If the effect succeeds with Option.some, the new value is set and
published. If it succeeds with Option.none, the reference is left unchanged
and no update is published.
Example (Conditionally updating with an effect)
import { Effect, Option, SubscriptionRef } from "effect"
const program = Effect.gen(function* () { const ref = yield* SubscriptionRef.make(10)
yield* SubscriptionRef.updateSomeEffect(ref, (n) => Effect.succeed(n > 5 ? Option.some(n + 3) : Option.none()))
const value = yield* SubscriptionRef.get(ref) console.log(value)})Signature
declare const updateSomeEffect: { <A, E, R>( update: (a: A) => Effect.Effect<Option.Option<A>, E, R> ): (self: SubscriptionRef<A>) => Effect.Effect<void, E, R> <A, E, R>( self: SubscriptionRef<A>, update: (a: A) => Effect.Effect<Option.Option<A>, E, R> ): Effect.Effect<void, E, R>}Since v2.0.0
SubscriptionRef (namespace)
Section titled “SubscriptionRef (namespace)”The SubscriptionRef namespace containing type definitions associated with
subscription references.
Since v2.0.0
Variance (interface)
Section titled “Variance (interface)”Type-level variance marker for the value type carried by a
SubscriptionRef.
Signature
export interface Variance<in out A> { readonly [TypeId]: { readonly _A: Invariant<A> }}Since v2.0.0