Skip to content

Commit

Permalink
FiberRef<A> subtype of Effect<A> (#3577)
Browse files Browse the repository at this point in the history
Co-authored-by: maksim.khramtsov <maksim.khramtsov@btsdigital.kz>
  • Loading branch information
2 people authored and mikearnaldi committed Sep 10, 2024
1 parent 68cf4ce commit aa5f3eb
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 14 deletions.
16 changes: 16 additions & 0 deletions .changeset/wise-kiwis-tan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"effect": minor
---

The `FiberRef<A>` is now a subtype of `Effect<A>`. This change simplifies handling of deferred values, removing the need for explicit call `FiberRef.get`.

```typescript
import { Effect, FiberRef } from "effect"

Effect.gen(function* () {
const fiberRef = yield* FiberRef.make("value")

const before = yield* FiberRef.get(fiberRef)
const after = yield* fiberRef
})
```
10 changes: 9 additions & 1 deletion packages/effect/dtslint/Unify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type * as Deferred from "effect/Deferred"
import type * as Effect from "effect/Effect"
import * as Either from "effect/Either"
import type * as Exit from "effect/Exit"
import type * as FiberRef from "effect/FiberRef"
import type * as Micro from "effect/Micro"
import type * as Option from "effect/Option"
import type * as RcRef from "effect/RcRef"
Expand Down Expand Up @@ -72,8 +73,13 @@ export type DeferredUnify = Unify.Unify<
| Deferred.Deferred<1, 2>
| Deferred.Deferred<"a", "b">
>
// $ExpectType FiberRef<1> | FiberRef<"a">
export type FiberRefUnify = Unify.Unify<
| FiberRef.FiberRef<1>
| FiberRef.FiberRef<"a">
>

// $ExpectType 0 | Option<string | number> | Ref<1> | SynchronizedRef<1> | SubscriptionRef<1> | Deferred<1, 2> | Deferred<"a", "b"> | Ref<"A"> | SynchronizedRef<"A"> | SubscriptionRef<"A"> | Either<1 | "A", 0 | "E"> | Effect<1 | "A", 0 | "E", "R" | "R1"> | RcRef<1 | "A", 0 | "E">
// $ExpectType 0 | Option<string | number> | Ref<1> | SynchronizedRef<1> | SubscriptionRef<1> | Deferred<1, 2> | Deferred<"a", "b"> | Ref<"A"> | SynchronizedRef<"A"> | SubscriptionRef<"A"> | FiberRef<12> | FiberRef<"a2"> | Either<1 | "A", 0 | "E"> | Effect<1 | "A", 0 | "E", "R" | "R1"> | RcRef<1 | "A", 0 | "E">
export type AllUnify = Unify.Unify<
| Either.Either<1, 0>
| Either.Either<"A", "E">
Expand All @@ -91,5 +97,7 @@ export type AllUnify = Unify.Unify<
| RcRef.RcRef<"A", "E">
| Deferred.Deferred<1, 2>
| Deferred.Deferred<"a", "b">
| FiberRef.FiberRef<12>
| FiberRef.FiberRef<"a2">
| 0
>
23 changes: 21 additions & 2 deletions packages/effect/src/FiberRef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ import type * as LogLevel from "./LogLevel.js"
import type * as LogSpan from "./LogSpan.js"
import type * as MetricLabel from "./MetricLabel.js"
import type * as Option from "./Option.js"
import type { Pipeable } from "./Pipeable.js"
import type * as Request from "./Request.js"
import type * as RuntimeFlags from "./RuntimeFlags.js"
import * as Scheduler from "./Scheduler.js"
import type * as Scope from "./Scope.js"
import type * as Supervisor from "./Supervisor.js"
import type * as Tracer from "./Tracer.js"
import type * as Types from "./Types.js"
import type * as Unify from "./Unify.js"

/**
* @since 2.0.0
Expand All @@ -43,7 +43,7 @@ export type FiberRefTypeId = typeof FiberRefTypeId
* @since 2.0.0
* @category model
*/
export interface FiberRef<in out A> extends Variance<A>, Pipeable {
export interface FiberRef<in out A> extends Effect.Effect<A>, Variance<A> {
/** @internal */
readonly initial: A
/** @internal */
Expand All @@ -56,6 +56,25 @@ export interface FiberRef<in out A> extends Variance<A>, Pipeable {
readonly fork: unknown
/** @internal */
join(oldValue: A, newValue: A): A
readonly [Unify.typeSymbol]?: unknown
readonly [Unify.unifySymbol]?: FiberRefUnify<this>
readonly [Unify.ignoreSymbol]?: FiberRefUnifyIgnore
}

/**
* @category models
* @since 3.8.0
*/
export interface FiberRefUnify<A extends { [Unify.typeSymbol]?: any }> extends Effect.EffectUnify<A> {
FiberRef?: () => Extract<A[Unify.typeSymbol], FiberRef<any>>
}

/**
* @category models
* @since 3.8.0
*/
export interface FiberRefUnifyIgnore extends Effect.EffectUnifyIgnore {
Effect?: true
}

/**
Expand Down
26 changes: 15 additions & 11 deletions packages/effect/src/internal/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1955,18 +1955,22 @@ export const fiberRefUnsafeMakePatch = <Value, Patch>(
readonly fork: Patch
readonly join?: ((oldV: Value, newV: Value) => Value) | undefined
}
): FiberRef.FiberRef<Value> => ({
[FiberRefTypeId]: fiberRefVariance,
initial,
diff: (oldValue, newValue) => options.differ.diff(oldValue, newValue),
combine: (first, second) => options.differ.combine(first as Patch, second as Patch),
patch: (patch) => (oldValue) => options.differ.patch(patch as Patch, oldValue),
fork: options.fork,
join: options.join ?? ((_, n) => n),
pipe() {
return pipeArguments(this, arguments)
): FiberRef.FiberRef<Value> => {
const _fiberRef = {
...CommitPrototype,
[FiberRefTypeId]: fiberRefVariance,
initial,
commit() {
return fiberRefGet(this)
},
diff: (oldValue: Value, newValue: Value) => options.differ.diff(oldValue, newValue),
combine: (first: Patch, second: Patch) => options.differ.combine(first, second),
patch: (patch: Patch) => (oldValue: Value) => options.differ.patch(patch, oldValue),
fork: options.fork,
join: options.join ?? ((_, n) => n)
}
})
return _fiberRef
}

/** @internal */
export const fiberRefUnsafeMakeRuntimeFlags = (
Expand Down
6 changes: 6 additions & 0 deletions packages/effect/test/FiberRef.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,4 +361,10 @@ describe("FiberRef", () => {
const result = yield* $(Deferred.await(deferred))
assert.isTrue(result)
}))
it.scoped("is subtype of Effect", () =>
Effect.gen(function*() {
const fiberRef = yield* FiberRef.make(initial)
const result = yield* fiberRef
assert.strictEqual(result, initial)
}))
})

0 comments on commit aa5f3eb

Please sign in to comment.