@@ -4,12 +4,12 @@ import * as Lens from "./Lens.js"
|
|||||||
|
|
||||||
|
|
||||||
describe("Lens", () => {
|
describe("Lens", () => {
|
||||||
test("mapField focuses a nested property without touching other fields", async () => {
|
test("focusField focuses a nested property without touching other fields", async () => {
|
||||||
const [initialCount, updatedState] = await Effect.runPromise(
|
const [initialCount, updatedState] = await Effect.runPromise(
|
||||||
Effect.flatMap(
|
Effect.flatMap(
|
||||||
SubscriptionRef.make({ count: 1, label: "original" }),
|
SubscriptionRef.make({ count: 1, label: "original" }),
|
||||||
parent => {
|
parent => {
|
||||||
const countLens = Lens.mapField(Lens.fromSubscriptionRef(parent), "count")
|
const countLens = Lens.focusField(Lens.fromSubscriptionRef(parent), "count")
|
||||||
return Effect.flatMap(
|
return Effect.flatMap(
|
||||||
Lens.get(countLens),
|
Lens.get(countLens),
|
||||||
count => Effect.flatMap(
|
count => Effect.flatMap(
|
||||||
@@ -25,13 +25,13 @@ describe("Lens", () => {
|
|||||||
expect(updatedState).toEqual({ count: 6, label: "original" })
|
expect(updatedState).toEqual({ count: 6, label: "original" })
|
||||||
})
|
})
|
||||||
|
|
||||||
test("mapMutableField preserves the root identity when mutating in place", async () => {
|
test("focusMutableField preserves the root identity when mutating in place", async () => {
|
||||||
const original = { detail: "keep" }
|
const original = { detail: "keep" }
|
||||||
const updated = await Effect.runPromise(
|
const updated = await Effect.runPromise(
|
||||||
Effect.flatMap(
|
Effect.flatMap(
|
||||||
SubscriptionRef.make(original),
|
SubscriptionRef.make(original),
|
||||||
parent => {
|
parent => {
|
||||||
const detailLens = Lens.mapMutableField(Lens.fromSubscriptionRef(parent), "detail")
|
const detailLens = Lens.focusMutableField(Lens.fromSubscriptionRef(parent), "detail")
|
||||||
return Effect.flatMap(
|
return Effect.flatMap(
|
||||||
Lens.set(detailLens, "mutated"),
|
Lens.set(detailLens, "mutated"),
|
||||||
() => parent.get,
|
() => parent.get,
|
||||||
@@ -44,12 +44,12 @@ describe("Lens", () => {
|
|||||||
expect(updated.detail).toBe("mutated")
|
expect(updated.detail).toBe("mutated")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("mapArrayAt updates the selected index", async () => {
|
test("focusArrayAt updates the selected index", async () => {
|
||||||
const updated = await Effect.runPromise(
|
const updated = await Effect.runPromise(
|
||||||
Effect.flatMap(
|
Effect.flatMap(
|
||||||
SubscriptionRef.make([10, 20, 30]),
|
SubscriptionRef.make([10, 20, 30]),
|
||||||
parent => {
|
parent => {
|
||||||
const elementLens = Lens.mapArrayAt(Lens.fromSubscriptionRef(parent), 1)
|
const elementLens = Lens.focusArrayAt(Lens.fromSubscriptionRef(parent), 1)
|
||||||
return Effect.flatMap(
|
return Effect.flatMap(
|
||||||
Lens.update(elementLens, value => value + 5),
|
Lens.update(elementLens, value => value + 5),
|
||||||
() => parent.get,
|
() => parent.get,
|
||||||
@@ -61,13 +61,13 @@ describe("Lens", () => {
|
|||||||
expect(updated).toEqual([10, 25, 30])
|
expect(updated).toEqual([10, 25, 30])
|
||||||
})
|
})
|
||||||
|
|
||||||
test("mapMutableArrayAt mutates the array reference in place", async () => {
|
test("focusMutableArrayAt mutates the array reference in place", async () => {
|
||||||
const original = ["foo", "bar"]
|
const original = ["foo", "bar"]
|
||||||
const updated = await Effect.runPromise(
|
const updated = await Effect.runPromise(
|
||||||
Effect.flatMap(
|
Effect.flatMap(
|
||||||
SubscriptionRef.make(original),
|
SubscriptionRef.make(original),
|
||||||
parent => {
|
parent => {
|
||||||
const elementLens = Lens.mapMutableArrayAt(Lens.fromSubscriptionRef(parent), 0)
|
const elementLens = Lens.focusMutableArrayAt(Lens.fromSubscriptionRef(parent), 0)
|
||||||
return Effect.flatMap(
|
return Effect.flatMap(
|
||||||
Lens.set(elementLens, "baz"),
|
Lens.set(elementLens, "baz"),
|
||||||
() => parent.get,
|
() => parent.get,
|
||||||
@@ -80,12 +80,12 @@ describe("Lens", () => {
|
|||||||
expect(updated).toEqual(["baz", "bar"])
|
expect(updated).toEqual(["baz", "bar"])
|
||||||
})
|
})
|
||||||
|
|
||||||
test("mapChunkAt replaces the focused chunk element", async () => {
|
test("focusChunkAt replaces the focused chunk element", async () => {
|
||||||
const updated = await Effect.runPromise(
|
const updated = await Effect.runPromise(
|
||||||
Effect.flatMap(
|
Effect.flatMap(
|
||||||
SubscriptionRef.make(Chunk.make(1, 2, 3) as Chunk.Chunk<number>),
|
SubscriptionRef.make(Chunk.make(1, 2, 3) as Chunk.Chunk<number>),
|
||||||
parent => {
|
parent => {
|
||||||
const elementLens = Lens.mapChunkAt(Lens.fromSubscriptionRef(parent), 2)
|
const elementLens = Lens.focusChunkAt(Lens.fromSubscriptionRef(parent), 2)
|
||||||
return Effect.flatMap(
|
return Effect.flatMap(
|
||||||
Lens.set(elementLens, 99),
|
Lens.set(elementLens, 99),
|
||||||
() => parent.get,
|
() => parent.get,
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ export const mapStream: {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
||||||
export const mapField: {
|
export const focusField: {
|
||||||
<A extends object, K extends keyof A, ER, EW, RR, RW>(
|
<A extends object, K extends keyof A, ER, EW, RR, RW>(
|
||||||
self: Lens<A, ER, EW, RR, RW>,
|
self: Lens<A, ER, EW, RR, RW>,
|
||||||
key: K,
|
key: K,
|
||||||
@@ -174,7 +174,7 @@ export const mapField: {
|
|||||||
(a, b) => Object.setPrototypeOf({ ...a, [key]: b }, Object.getPrototypeOf(a)),
|
(a, b) => Object.setPrototypeOf({ ...a, [key]: b }, Object.getPrototypeOf(a)),
|
||||||
))
|
))
|
||||||
|
|
||||||
export declare namespace mapMutableField {
|
export declare namespace focusMutableField {
|
||||||
export type WritableKeys<T> = {
|
export type WritableKeys<T> = {
|
||||||
[K in keyof T]-?: IfEquals<
|
[K in keyof T]-?: IfEquals<
|
||||||
{ [P in K]: T[K] },
|
{ [P in K]: T[K] },
|
||||||
@@ -187,20 +187,20 @@ export declare namespace mapMutableField {
|
|||||||
type IfEquals<X, Y, A = X, B = never> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? A : B
|
type IfEquals<X, Y, A = X, B = never> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? A : B
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mapMutableField: {
|
export const focusMutableField: {
|
||||||
<A extends object, K extends mapMutableField.WritableKeys<A>, ER, EW, RR, RW>(
|
<A extends object, K extends focusMutableField.WritableKeys<A>, ER, EW, RR, RW>(
|
||||||
self: Lens<A, ER, EW, RR, RW>,
|
self: Lens<A, ER, EW, RR, RW>,
|
||||||
key: K,
|
key: K,
|
||||||
): Lens<A[K], ER, EW, RR, RW>
|
): Lens<A[K], ER, EW, RR, RW>
|
||||||
<A extends object, K extends mapMutableField.WritableKeys<A>, ER, EW, RR, RW>(
|
<A extends object, K extends focusMutableField.WritableKeys<A>, ER, EW, RR, RW>(
|
||||||
key: K,
|
key: K,
|
||||||
): (self: Lens<A, ER, EW, RR, RW>) => Lens<A[K], ER, EW, RR, RW>
|
): (self: Lens<A, ER, EW, RR, RW>) => Lens<A[K], ER, EW, RR, RW>
|
||||||
} = Function.dual(2, <A extends object, K extends mapMutableField.WritableKeys<A>, ER, EW, RR, RW>(
|
} = Function.dual(2, <A extends object, K extends focusMutableField.WritableKeys<A>, ER, EW, RR, RW>(
|
||||||
self: Lens<A, ER, EW, RR, RW>,
|
self: Lens<A, ER, EW, RR, RW>,
|
||||||
key: K,
|
key: K,
|
||||||
): Lens<A[K], ER, EW, RR, RW> => map(self, a => a[key], (a, b) => { a[key] = b; return a }))
|
): Lens<A[K], ER, EW, RR, RW> => map(self, a => a[key], (a, b) => { a[key] = b; return a }))
|
||||||
|
|
||||||
export const mapArrayAt: {
|
export const focusArrayAt: {
|
||||||
<A extends readonly any[], ER, EW, RR, RW>(
|
<A extends readonly any[], ER, EW, RR, RW>(
|
||||||
self: Lens<A, ER, EW, RR, RW>,
|
self: Lens<A, ER, EW, RR, RW>,
|
||||||
index: number,
|
index: number,
|
||||||
@@ -217,7 +217,7 @@ export const mapArrayAt: {
|
|||||||
(a, b) => Array.replaceOption(a, index, b) as any,
|
(a, b) => Array.replaceOption(a, index, b) as any,
|
||||||
))
|
))
|
||||||
|
|
||||||
export const mapMutableArrayAt: {
|
export const focusMutableArrayAt: {
|
||||||
<A, ER, EW, RR, RW>(
|
<A, ER, EW, RR, RW>(
|
||||||
self: Lens<A[], ER, EW, RR, RW>,
|
self: Lens<A[], ER, EW, RR, RW>,
|
||||||
index: number,
|
index: number,
|
||||||
@@ -237,7 +237,7 @@ export const mapMutableArrayAt: {
|
|||||||
),
|
),
|
||||||
))
|
))
|
||||||
|
|
||||||
export const mapChunkAt: {
|
export const focusChunkAt: {
|
||||||
<A, ER, EW, RR, RW>(
|
<A, ER, EW, RR, RW>(
|
||||||
self: Lens<Chunk.Chunk<A>, ER, EW, RR, RW>,
|
self: Lens<Chunk.Chunk<A>, ER, EW, RR, RW>,
|
||||||
index: number,
|
index: number,
|
||||||
|
|||||||
Reference in New Issue
Block a user