From 7fa5f54f88b1346fd33e45bca2fda95e20ef8ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 18 May 2026 14:32:26 +0200 Subject: [PATCH] Fix provide --- packages/effect-lens/src/Lens.ts | 43 +++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/packages/effect-lens/src/Lens.ts b/packages/effect-lens/src/Lens.ts index 7ad71fe..491235d 100644 --- a/packages/effect-lens/src/Lens.ts +++ b/packages/effect-lens/src/Lens.ts @@ -1,4 +1,4 @@ -import { Array, Chunk, Effect, Function, identity, type Layer, Option, Pipeable, Predicate, Readable, Stream, type Context, type SubscriptionRef, type SynchronizedRef } from "effect" +import { Array, Chunk, type Context, Effect, Function, identity, type Layer, type ManagedRuntime, Option, Pipeable, Predicate, Readable, type Runtime, Stream, type SubscriptionRef, type SynchronizedRef } from "effect" import type { NoSuchElementException } from "effect/Cause" import * as Subscribable from "./Subscribable.js" @@ -270,7 +270,12 @@ export const mapStream: { })) /** - * Provides a single service to a `Lens`, removing it from both the read and write environments. + * Provides the requirements of a `Lens`, removing them from both the read and write environments. + * + * Accepts the same provider forms as `Effect.provide`: one or more `Layer`s, a `Context`, + * a `Runtime`, or a `ManagedRuntime`. + * + * Layer providers may add their construction errors to both the read and write error channels. */ export const provide: { ]>( @@ -288,6 +293,12 @@ export const provide: { ( context: Context.Context, ): (self: Lens) => Lens, Exclude> + ( + runtime: Runtime.Runtime, + ): (self: Lens) => Lens, Exclude> + ( + managedRuntime: ManagedRuntime.ManagedRuntime, + ): (self: Lens) => Lens, Exclude> ]>( self: Lens, layers: Layers, @@ -306,24 +317,38 @@ export const provide: { self: Lens, context: Context.Context, ): Lens, Exclude> -} = Function.dual(2, ( + ( + self: Lens, + runtime: Runtime.Runtime, + ): Lens, Exclude> + ( + self: Lens, + runtime: ManagedRuntime.ManagedRuntime, + ): Lens, Exclude> +} = Function.dual(2, ( self: Lens, - provider: unknown, -): Lens => make({ - get get() { return Effect.provide(self.get, provider as any) }, + layer: Layer.Layer, +): Lens, RIn | Exclude> => make({ + get get() { return Effect.provide(self.get, layer) }, get changes() { return Stream.unwrapScoped( Effect.map( - Effect.provide(Effect.context(), provider as any), - (context) => Stream.provideContext(self.changes as Stream.Stream, context), + Effect.provide(Effect.context(), layer), + context => Stream.provideContext(self.changes, context), ), ) }, modify: ( f: (a: A) => Effect.Effect - ) => Effect.provide(self.modify(f), provider as any), + ) => Effect.provide(self.modify(f), layer), })) +/** + * Provides a single service to a `Lens`, removing it from both the read and write environments. + * + * This is the `Lens` equivalent of `Effect.provideService`: use it when a lens requires one + * `Context.Tag` and you already have the concrete service value. + */ export const provideService: { ( self: Lens,