@@ -241,8 +241,11 @@ Currently available:
|
|||||||
| - | - |
|
| - | - |
|
||||||
| `focusObjectOn` | Focuses to the field of an object |
|
| `focusObjectOn` | Focuses to the field of an object |
|
||||||
| `focusArrayAt` | Focuses to an indexed entry of an array |
|
| `focusArrayAt` | Focuses to an indexed entry of an array |
|
||||||
|
| `focusArrayLength` | Focuses to the length of an array |
|
||||||
| `focusTupleAt` | Focuses to an indexed entry of a tuple |
|
| `focusTupleAt` | Focuses to an indexed entry of a tuple |
|
||||||
| `focusChunkAt` | Focuses to an indexed entry of a `Chunk` |
|
| `focusChunkAt` | Focuses to an indexed entry of a `Chunk` |
|
||||||
|
| `focusChunkSize` | Focuses to the size of a `Chunk` |
|
||||||
|
| `focusIterableSize` | Focuses to the size of an iterable |
|
||||||
|
|
||||||
|
|
||||||
## Todo
|
## Todo
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import { describe, expect, test } from "bun:test"
|
||||||
|
import { Chunk, Effect, SubscriptionRef } from "effect"
|
||||||
|
import * as Subscribable from "./Subscribable.js"
|
||||||
|
|
||||||
|
|
||||||
|
describe("Subscribable", () => {
|
||||||
|
test("focusArrayLength reads the current array length and reflects updates", async () => {
|
||||||
|
const result = await Effect.runPromise(
|
||||||
|
Effect.flatMap(
|
||||||
|
SubscriptionRef.make([1, 2, 3]),
|
||||||
|
parent => {
|
||||||
|
const sizeSub = Subscribable.focusArrayLength(parent)
|
||||||
|
return Effect.flatMap(
|
||||||
|
sizeSub.get,
|
||||||
|
initial => Effect.flatMap(
|
||||||
|
SubscriptionRef.set(parent, [1, 2, 3, 4, 5]),
|
||||||
|
() => Effect.map(sizeSub.get, next => [initial, next] as const),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(result).toEqual([3, 5])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("focusChunkSize reads the current chunk size and reflects updates", async () => {
|
||||||
|
const result = await Effect.runPromise(
|
||||||
|
Effect.flatMap(
|
||||||
|
SubscriptionRef.make(Chunk.make(1, 2) as Chunk.Chunk<number>),
|
||||||
|
parent => {
|
||||||
|
const sizeSub = Subscribable.focusChunkSize(parent)
|
||||||
|
return Effect.flatMap(
|
||||||
|
sizeSub.get,
|
||||||
|
initial => Effect.flatMap(
|
||||||
|
SubscriptionRef.set(parent, Chunk.make(1, 2, 3, 4)),
|
||||||
|
() => Effect.map(sizeSub.get, next => [initial, next] as const),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(result).toEqual([2, 4])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("focusIterableSize also works for array values", async () => {
|
||||||
|
const result = await Effect.runPromise(
|
||||||
|
Effect.flatMap(
|
||||||
|
SubscriptionRef.make([1, 2, 3]),
|
||||||
|
parent => {
|
||||||
|
const sizeSub = Subscribable.focusIterableSize(parent)
|
||||||
|
return Effect.flatMap(
|
||||||
|
sizeSub.get,
|
||||||
|
initial => Effect.flatMap(
|
||||||
|
SubscriptionRef.set(parent, [1, 2, 3, 4, 5]),
|
||||||
|
() => Effect.map(sizeSub.get, next => [initial, next] as const),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(result).toEqual([3, 5])
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Array, Chunk, Effect, Function, Option, Subscribable } from "effect"
|
import { Array, Chunk, Effect, Function, Iterable, Option, Subscribable } from "effect"
|
||||||
import type { NoSuchElementException } from "effect/Cause"
|
import type { NoSuchElementException } from "effect/Cause"
|
||||||
|
|
||||||
|
|
||||||
@@ -71,6 +71,13 @@ export const focusArrayAt: {
|
|||||||
index: number,
|
index: number,
|
||||||
): Subscribable.Subscribable<A[number], E | NoSuchElementException, R> => Subscribable.mapEffect(self, Array.get(index)))
|
): Subscribable.Subscribable<A[number], E | NoSuchElementException, R> => Subscribable.mapEffect(self, Array.get(index)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Narrows the focus to the length of an array.
|
||||||
|
*/
|
||||||
|
export const focusArrayLength = <A extends readonly any[], E, R>(
|
||||||
|
self: Subscribable.Subscribable<A, E, R>,
|
||||||
|
): Subscribable.Subscribable<number, E, R> => Subscribable.map(self, a => a.length)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Narrows the focus to an indexed element of a readonly tuple.
|
* Narrows the focus to an indexed element of a readonly tuple.
|
||||||
*/
|
*/
|
||||||
@@ -102,3 +109,17 @@ export const focusChunkAt: {
|
|||||||
self: Subscribable.Subscribable<Chunk.Chunk<A>, E, R>,
|
self: Subscribable.Subscribable<Chunk.Chunk<A>, E, R>,
|
||||||
index: number,
|
index: number,
|
||||||
): Subscribable.Subscribable<A, E | NoSuchElementException, R> => Subscribable.mapEffect(self, Chunk.get(index)))
|
): Subscribable.Subscribable<A, E | NoSuchElementException, R> => Subscribable.mapEffect(self, Chunk.get(index)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Narrows the focus to the size of a `Chunk`.
|
||||||
|
*/
|
||||||
|
export const focusChunkSize = <A, E, R>(
|
||||||
|
self: Subscribable.Subscribable<Chunk.Chunk<A>, E, R>,
|
||||||
|
): Subscribable.Subscribable<number, E, R> => Subscribable.map(self, Chunk.size)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Narrows the focus to the size of a `Iterable`.
|
||||||
|
*/
|
||||||
|
export const focusIterableSize = <A, E, R>(
|
||||||
|
self: Subscribable.Subscribable<Iterable<A>, E, R>,
|
||||||
|
): Subscribable.Subscribable<number, E, R> => Subscribable.map(self, Iterable.size)
|
||||||
|
|||||||
Reference in New Issue
Block a user