From a65f139858a06dc2516cb50af8447de043b88c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 20 May 2026 17:08:40 +0200 Subject: [PATCH] Refactor --- packages/effect-lens/src/Lens.ts | 73 +++++++++++++++----------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/packages/effect-lens/src/Lens.ts b/packages/effect-lens/src/Lens.ts index b3384b7..b5ddd94 100644 --- a/packages/effect-lens/src/Lens.ts +++ b/packages/effect-lens/src/Lens.ts @@ -35,18 +35,24 @@ extends Lens { readonly [LensWithInternalsTypeId]: LensWithInternalsTypeId readonly update: (a: A) => Effect.Effect - readonly semaphore: Effect.Semaphore + readonly withLock: (self: Effect.Effect) => Effect.Effect } export const isLensWithInternals = (u: unknown): u is LensWithInternals => Predicate.hasProperty(u, LensWithInternalsTypeId) +export const asLensWithInternals = ( + lens: Lens +): Effect.Effect, never, never> => isLensWithInternals(lens) + ? Effect.succeed(lens as LensWithInternals) + : Effect.die("Not a 'LensWithInternals'.") + export declare namespace LensImpl { export interface Source { readonly get: Effect.Effect, readonly changes: Stream.Stream, readonly update: (a: A) => Effect.Effect, - readonly semaphore: Effect.Semaphore, + readonly withLock: (self: Effect.Effect) => Effect.Effect, } } @@ -60,7 +66,7 @@ extends Pipeable.Class() implements LensWithInternals { readonly get: Effect.Effect readonly changes: Stream.Stream readonly update: (a: A) => Effect.Effect - readonly semaphore: Effect.Semaphore + readonly withLock: (self: Effect.Effect) => Effect.Effect constructor( source: LensImpl.Source @@ -70,19 +76,20 @@ extends Pipeable.Class() implements LensWithInternals { this.get = source.get this.changes = source.changes this.update = source.update - this.semaphore = source.semaphore + this.withLock = source.withLock } - modifyEffect( - f: (a: A) => Effect.Effect - ) { - return this.semaphore.withPermits(1)( - Effect.flatMap( - this.get, - a => Effect.flatMap(f(a), ([b, next]) => Effect.as(this.update(next), b), - )) - ) - } + modifyEffect = modifyEffect +} + +function modifyEffect( + this: LensWithInternals, + f: (a: A) => Effect.Effect, +): Effect.Effect { + return this.withLock(Effect.flatMap( + this.get, + a => Effect.flatMap(f(a), ([b, next]) => Effect.as(this.update(next), b), + ))) } /** @@ -109,18 +116,9 @@ extends Pipeable.Class() implements LensWithInternals { get get() { return this.source.get } get changes() { return this.source.changes } get update() { return this.source.update } - get semaphore() { return this.source.semaphore } + get withLock() { return this.source.withLock } - modifyEffect( - f: (a: A) => Effect.Effect - ) { - return this.semaphore.withPermits(1)( - Effect.flatMap( - this.get, - a => Effect.flatMap(f(a), ([b, next]) => Effect.as(this.update(next), b), - )) - ) - } + modifyEffect = modifyEffect } /** @@ -164,18 +162,9 @@ extends Pipeable.Class() implements LensWithInternals( - f: (a: A) => Effect.Effect - ) { - return this.semaphore.withPermits(1)( - Effect.flatMap( - this.get, - a => Effect.flatMap(f(a), ([b, next]) => Effect.as(this.update(next), b), - )) - ) - } + modifyEffect = modifyEffect } /** @@ -211,8 +200,16 @@ export const unwrap = ( ): Lens => make({ get: Effect.flatMap(effect, l => l.get), changes: Stream.unwrap(Effect.map(effect, l => l.changes)), - update: a => Effect.flatMap(effect, l => (l as LensWithInternals).update(a)) - + update: a => Effect.flatMap( + effect, + l => Effect.flatMap(asLensWithInternals(l), l => l.update(a)) + ), + withLock: ( + effect2: Effect.Effect + ): Effect.Effect => Effect.flatMap( + effect, + l => Effect.flatMap(asLensWithInternals(l), l2 => l2.withLock(effect2)), + ), }) /**