@@ -35,18 +35,24 @@ extends Lens<A, ER, EW, RR, RW> {
|
||||
readonly [LensWithInternalsTypeId]: LensWithInternalsTypeId
|
||||
|
||||
readonly update: (a: A) => Effect.Effect<void, EW, RW>
|
||||
readonly semaphore: Effect.Semaphore
|
||||
readonly withLock: <A1, E1, R1>(self: Effect.Effect<A1, E1, R1>) => Effect.Effect<A1, E1, R1>
|
||||
}
|
||||
|
||||
export const isLensWithInternals = (u: unknown): u is LensWithInternals<unknown, unknown, unknown, unknown, unknown> => Predicate.hasProperty(u, LensWithInternalsTypeId)
|
||||
|
||||
export const asLensWithInternals = <A, ER, EW, RR, RW>(
|
||||
lens: Lens<A, ER, EW, RR, RW>
|
||||
): Effect.Effect<LensWithInternals<A, ER, EW, RR, RW>, never, never> => isLensWithInternals(lens)
|
||||
? Effect.succeed(lens as LensWithInternals<A, ER, EW, RR, RW>)
|
||||
: Effect.die("Not a 'LensWithInternals'.")
|
||||
|
||||
|
||||
export declare namespace LensImpl {
|
||||
export interface Source<in out A, in out ER = never, in out EW = never, in out RR = never, in out RW = never> {
|
||||
readonly get: Effect.Effect<A, ER, RR>,
|
||||
readonly changes: Stream.Stream<A, ER, RR>,
|
||||
readonly update: (a: A) => Effect.Effect<void, EW, RW>,
|
||||
readonly semaphore: Effect.Semaphore,
|
||||
readonly withLock: <A1, E1, R1>(self: Effect.Effect<A1, E1, R1>) => Effect.Effect<A1, E1, R1>,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +66,7 @@ extends Pipeable.Class() implements LensWithInternals<A, ER, EW, RR, RW> {
|
||||
readonly get: Effect.Effect<A, ER, RR>
|
||||
readonly changes: Stream.Stream<A, ER, RR>
|
||||
readonly update: (a: A) => Effect.Effect<void, EW, RW>
|
||||
readonly semaphore: Effect.Semaphore
|
||||
readonly withLock: <A1, E1, R1>(self: Effect.Effect<A1, E1, R1>) => Effect.Effect<A1, E1, R1>
|
||||
|
||||
constructor(
|
||||
source: LensImpl.Source<A, ER, EW, RR, RW>
|
||||
@@ -70,19 +76,20 @@ extends Pipeable.Class() implements LensWithInternals<A, ER, EW, RR, RW> {
|
||||
this.get = source.get
|
||||
this.changes = source.changes
|
||||
this.update = source.update
|
||||
this.semaphore = source.semaphore
|
||||
this.withLock = source.withLock
|
||||
}
|
||||
|
||||
modifyEffect<B, E1 = never, R1 = never>(
|
||||
f: (a: A) => Effect.Effect<readonly [B, A], E1, R1>
|
||||
) {
|
||||
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<A, B, ER = never, EW = never, E1 = never, RR = never, RW = never, R1 = never>(
|
||||
this: LensWithInternals<A, ER, EW, RR, RW>,
|
||||
f: (a: A) => Effect.Effect<readonly [B, A], E1, R1>,
|
||||
): Effect.Effect<B, ER | EW | E1, RR | RW | R1> {
|
||||
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<A, ER, EW, RR, RW> {
|
||||
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<B, E1 = never, R1 = never>(
|
||||
f: (a: A) => Effect.Effect<readonly [B, A], E1, R1>
|
||||
) {
|
||||
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<A, never, never, never, ne
|
||||
PubSub.publish(this.ref.pubsub, a),
|
||||
)
|
||||
}
|
||||
get semaphore() { return this.ref.semaphore }
|
||||
get withLock() { return this.ref.semaphore.withPermits(1) }
|
||||
|
||||
modifyEffect<B, E1 = never, R1 = never>(
|
||||
f: (a: A) => Effect.Effect<readonly [B, A], E1, R1>
|
||||
) {
|
||||
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 = <A, ER, EW, RR, RW, E1, R1>(
|
||||
): Lens<A, ER | E1, EW | E1, RR | R1, RW | R1> => 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<A, ER, EW, RR, RW>).update(a))
|
||||
|
||||
update: a => Effect.flatMap(
|
||||
effect,
|
||||
l => Effect.flatMap(asLensWithInternals(l), l => l.update(a))
|
||||
),
|
||||
withLock: <A2, E2, R2>(
|
||||
effect2: Effect.Effect<A2, E2, R2>
|
||||
): Effect.Effect<A2, E1 | E2, R1 | R2> => Effect.flatMap(
|
||||
effect,
|
||||
l => Effect.flatMap(asLensWithInternals(l), l2 => l2.withLock(effect2)),
|
||||
),
|
||||
})
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user