0.2.0 #5

Merged
Thilawyn merged 59 commits from next into master 2026-05-30 06:10:54 +02:00
2 changed files with 35 additions and 52 deletions
Showing only changes of commit 2e5ef92bb1 - Show all commits
+11 -6
View File
@@ -1,5 +1,5 @@
import { describe, expect, test } from "bun:test" import { describe, expect, test } from "bun:test"
import { Chunk, Context, Effect, Option, Stream, SubscriptionRef } from "effect" import { Chunk, Context, Effect, identity, Option, Stream, SubscriptionRef } from "effect"
import * as Lens from "./Lens.js" import * as Lens from "./Lens.js"
@@ -11,7 +11,8 @@ describe("Lens", () => {
Lens.make<number, "read", never, never, never>({ Lens.make<number, "read", never, never, never>({
get: Effect.fail("read" as const), get: Effect.fail("read" as const),
changes: Stream.fail("read" as const), changes: Stream.fail("read" as const),
set: () => Effect.void, commit: () => Effect.void,
withLock: identity,
}), }),
error => `mapped:${ error }`, error => `mapped:${ error }`,
) )
@@ -26,7 +27,8 @@ describe("Lens", () => {
Lens.make<number, never, "write", never, never>({ Lens.make<number, never, "write", never, never>({
get: Effect.succeed(1), get: Effect.succeed(1),
changes: Stream.make(1), changes: Stream.make(1),
set: () => Effect.fail("write" as const), commit: () => Effect.fail("write" as const),
withLock: identity,
}), }),
() => "mapped-write", () => "mapped-write",
) )
@@ -41,7 +43,8 @@ describe("Lens", () => {
Lens.make<number, "read", "write", never, never>({ Lens.make<number, "read", "write", never, never>({
get: Effect.fail("read" as const), get: Effect.fail("read" as const),
changes: Stream.fail("read" as const), changes: Stream.fail("read" as const),
set: () => Effect.fail("write" as const), commit: () => Effect.fail("write" as const),
withLock: identity,
}), }),
() => "mapped", () => "mapped",
) )
@@ -84,7 +87,8 @@ describe("Lens", () => {
Lens.make<number, "read", never, never, never>({ Lens.make<number, "read", never, never, never>({
get: Effect.fail("read" as const), get: Effect.fail("read" as const),
changes: Stream.fail("read" as const), changes: Stream.fail("read" as const),
set: () => Effect.void, commit: () => Effect.void,
withLock: identity,
}), }),
() => SubscriptionRef.modify(counter, n => [void 0, n + 1] as const), () => SubscriptionRef.modify(counter, n => [void 0, n + 1] as const),
) )
@@ -108,7 +112,8 @@ describe("Lens", () => {
Lens.make<number, never, "write", never, never>({ Lens.make<number, never, "write", never, never>({
get: Effect.succeed(1), get: Effect.succeed(1),
changes: Stream.make(1), changes: Stream.make(1),
set: () => Effect.fail("write" as const), commit: () => Effect.fail("write" as const),
withLock: identity,
}), }),
() => SubscriptionRef.modify(counter, n => [void 0, n + 1] as const), () => SubscriptionRef.modify(counter, n => [void 0, n + 1] as const),
) )
+24 -46
View File
@@ -40,13 +40,7 @@ export declare namespace LensImpl {
} }
} }
export abstract class LensImpl< export abstract class LensImpl<in out A, in out ER = never, in out EW = never, in out RR = never, in out RW = never>
in out A,
in out ER = never,
in out EW = never,
in out RR = never,
in out RW = never,
>
extends Pipeable.Class() implements Lens<A, ER, EW, RR, RW> { extends Pipeable.Class() implements Lens<A, ER, EW, RR, RW> {
readonly [Readable.TypeId]: Readable.TypeId = Readable.TypeId readonly [Readable.TypeId]: Readable.TypeId = Readable.TypeId
readonly [Subscribable.TypeId]: Subscribable.TypeId = Subscribable.TypeId readonly [Subscribable.TypeId]: Subscribable.TypeId = Subscribable.TypeId
@@ -57,13 +51,11 @@ extends Pipeable.Class() implements Lens<A, ER, EW, RR, RW> {
abstract readonly changes: Stream.Stream<A, ER, RR> abstract readonly changes: Stream.Stream<A, ER, RR>
abstract readonly withLock: <A1, E1, R1>(self: Effect.Effect<A1, E1, R1>) => Effect.Effect<A1, EW | E1, RW | R1> abstract readonly withLock: <A1, E1, R1>(self: Effect.Effect<A1, E1, R1>) => Effect.Effect<A1, EW | E1, RW | R1>
get get(): Effect.Effect<A, ER, RR> { get get() { return Effect.map(this.access, frame => frame.value) }
return Effect.map(this.access, frame => frame.value)
}
modifyEffect<C, E1 = never, R1 = never>( modifyEffect<B, E1 = never, R1 = never>(
f: (a: A) => Effect.Effect<readonly [C, A], E1, R1>, f: (a: A) => Effect.Effect<readonly [B, A], E1, R1>,
): Effect.Effect<C, ER | EW | E1, RR | RW | R1> { ): Effect.Effect<B, ER | EW | E1, RR | RW | R1> {
return this.withLock(Effect.flatMap( return this.withLock(Effect.flatMap(
this.access, this.access,
frame => Effect.flatMap( frame => Effect.flatMap(
@@ -86,29 +78,23 @@ export const asLensImpl = <A, ER, EW, RR, RW>(
export declare namespace LensLazyImpl { export declare namespace LensLazyImpl {
export interface Source<in out B, in out ESW = never, in out ESR = never, in out RSR = never, in out RSW = never> { 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<B, ESR, RSR> readonly get: Effect.Effect<A, ER, RR>
readonly changes: Stream.Stream<B, ESR, RSR> readonly changes: Stream.Stream<A, ER, RR>
readonly commit: (b: B) => Effect.Effect<void, ESW, RSW> readonly commit: (a: A) => Effect.Effect<void, EW, RW>
readonly withLock: <A1, E1, R1>(self: Effect.Effect<A1, E1, R1>) => Effect.Effect<A1, E1, R1> readonly withLock: <A1, E1, R1>(self: Effect.Effect<A1, E1, R1>) => Effect.Effect<A1, E1, R1>
} }
} }
export class LensLazyImpl< export class LensLazyImpl<in out A, in out ER = never, in out EW = never, in out RR = never, in out RW = never>
in out B, extends LensImpl<A, ER, EW, RR, RW> {
in out ESW = never,
in out ESR = never,
in out RSR = never,
in out RSW = never,
>
extends LensImpl<B, ESR, ESW, RSR, RSW> {
constructor( constructor(
readonly source: LensLazyImpl.Source<B, ESW, ESR, RSR, RSW>, readonly source: LensLazyImpl.Source<A, ER, EW, RR, RW>,
) { ) {
super() super()
} }
get access(): Effect.Effect<LensImpl.Frame<B, ESW, RSW>, ESR, RSR> { get access(): Effect.Effect<LensImpl.Frame<A, EW, RW>, ER, RR> {
return Effect.map( return Effect.map(
this.source.get, this.source.get,
value => ({ value => ({
@@ -117,7 +103,6 @@ extends LensImpl<B, ESR, ESW, RSR, RSW> {
}), }),
) )
} }
get changes() { return this.source.changes } get changes() { return this.source.changes }
get withLock() { return this.source.withLock } get withLock() { return this.source.withLock }
} }
@@ -125,9 +110,9 @@ extends LensImpl<B, ESR, ESW, RSR, RSW> {
/** /**
* Creates a `Lens` by supplying how to read the current value, observe changes, and apply transformations. * Creates a `Lens` by supplying how to read the current value, observe changes, and apply transformations.
*/ */
export const make = <B, ESW, ESR, RSR, RSW>( export const make = <A, ER, EW, RR, RW>(
source: LensLazyImpl.Source<B, ESW, ESR, RSR, RSW> source: LensLazyImpl.Source<A, ER, EW, RR, RW>
): Lens<B, ESR, ESW, RSR, RSW> => new LensLazyImpl(source) ): Lens<A, ER, EW, RR, RW> => new LensLazyImpl(source)
export declare namespace DerivedLensImpl { export declare namespace DerivedLensImpl {
@@ -168,17 +153,9 @@ extends LensImpl<A, ER, EW, RR, RW> {
super() super()
} }
get access(): Effect.Effect<LensImpl.Frame<A, EW, RW>, ER, RR> { get access() { return this.source.access(this.parent.access) }
return this.source.access(this.parent.access) get changes() { return this.source.transformStream(this.parent.changes) }
} get withLock() { return this.parent.withLock }
get changes(): Stream.Stream<A, ER, RR> {
return this.source.transformStream(this.parent.changes)
}
get withLock() {
return this.parent.withLock
}
} }
/** /**
@@ -222,13 +199,14 @@ extends LensImpl<A, never, never, never, never> {
this.ref.get, this.ref.get,
value => ({ value => ({
value, value,
commit: next => Effect.flatMap(next, value => Ref.set(this.ref.ref, value)), commit: next => Effect.flatMap(next, value => this.commit(value)),
}), }),
) )
} }
get changes() { return Stream.unwrap(Effect.map(this.ref.get, Stream.make)) } get changes() { return Stream.unwrap(Effect.map(this.ref.get, Stream.make)) }
get withLock() { return this.ref.withLock } get withLock() { return this.ref.withLock }
commit(a: A) { return Ref.set(this.ref.ref, a) }
} }
/** /**
@@ -271,15 +249,15 @@ extends LensImpl<A, never, never, never, never> {
}), }),
) )
} }
get changes() { return this.ref.changes } get changes() { return this.ref.changes }
get withLock() { return this.ref.semaphore.withPermits(1) }
commit(a: A) { commit(a: A) {
return Effect.zipLeft( return Effect.zipLeft(
Ref.set(this.ref.ref, a), Ref.set(this.ref.ref, a),
PubSub.publish(this.ref.pubsub, a), PubSub.publish(this.ref.pubsub, a),
) )
} }
get withLock() { return this.ref.semaphore.withPermits(1) }
} }
/** /**