0.2.0 #5
@@ -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),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user