0.1.2 #1
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
A Lens type for [Effect](https://effect.website/) to easily manage nested state.
|
A Lens type for [Effect](https://effect.website/) to easily manage nested state.
|
||||||
|
|
||||||
A proper documentation is currently being written. In the meantime, you can take a look at the quickstart below and at the `packages/example` directory.
|
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
```
|
```
|
||||||
npm install effect-lens
|
npm install effect-lens
|
||||||
@@ -140,7 +138,7 @@ const ref = yield* SubscriptionRef.make<{
|
|||||||
// \/ Lens<User, NoSuchElementException, NoSuchElementException, never, never>
|
// \/ Lens<User, NoSuchElementException, NoSuchElementException, never, never>
|
||||||
const jeanDupontLens = ref.pipe(
|
const jeanDupontLens = ref.pipe(
|
||||||
Lens.fromSubscriptionRef, // Creates a lens that proxies the ref
|
Lens.fromSubscriptionRef, // Creates a lens that proxies the ref
|
||||||
Lens.focusField("users"), // Creates a focused lens that points to the users field
|
Lens.focusObjectField("users"), // Creates a focused lens that points to the users field
|
||||||
Lens.focusArrayAt(0), // Creates a focused lens that points to the first entry of the user array
|
Lens.focusArrayAt(0), // Creates a focused lens that points to the first entry of the user array
|
||||||
)
|
)
|
||||||
// Reading or writing from this lense can fail with NoSuchElementException
|
// Reading or writing from this lense can fail with NoSuchElementException
|
||||||
@@ -150,7 +148,7 @@ const jeanDupont = yield* Lens.get(jeanDupontLens)
|
|||||||
|
|
||||||
yield* Lens.set(
|
yield* Lens.set(
|
||||||
// You can focus even further down
|
// You can focus even further down
|
||||||
Lens.focusField(jeanDupontLens, "age"),
|
Lens.focusObjectField(jeanDupontLens, "age"),
|
||||||
yield* DateTime.make("03/25/1970"),
|
yield* DateTime.make("03/25/1970"),
|
||||||
)
|
)
|
||||||
// Mutations with the parent state are performed immutably by default
|
// Mutations with the parent state are performed immutably by default
|
||||||
@@ -160,10 +158,12 @@ yield* Lens.set(
|
|||||||
Currently available:
|
Currently available:
|
||||||
| Name | Description | Parent state mutation behavior | Notes |
|
| Name | Description | Parent state mutation behavior | Notes |
|
||||||
| - | - | - | - |
|
| - | - | - | - |
|
||||||
| `focusField` | Focuses to the field of an object. Replaces the parent object immutably when writing to the focused field | Immutable | |
|
| `focusObjectField` | Focuses to the field of an object. Replaces the parent object immutably when writing to the focused field | Immutable | |
|
||||||
| `focusMutableField` | Focuses to the field of an object. Mutates the parent object in place via the writable field | Mutable | Type-safe: will not allow you to mutate `readonly` fields |
|
| `focusObjectMutableField` | Focuses to the writable field of an object. Mutates the parent object in place via the writable field | Mutable | Type-safe: will not allow you to mutate `readonly` fields |
|
||||||
| `focusArrayAt` | Focuses to an indexed entry of an array. Replaces the parent array immutably when writing to the focused index | Immutable | |
|
| `focusArrayAt` | Focuses to an indexed entry of an array. Replaces the parent array immutably when writing to the focused index | Immutable | |
|
||||||
| `focusMutableArrayAt` | Focuses to an indexed entry of an array. Mutates the parent array in place at the focused index | Mutable | Type-safe: will not allow you to mutate `readonly` arrays |
|
| `focusMutableArrayAt` | Focuses to an indexed entry of an array. Mutates the parent array in place at the focused index | Mutable | Type-safe: will not allow you to mutate `readonly` arrays |
|
||||||
|
| `focusTupleAt` | Focuses to an indexed entry of a readonly tuple. Replaces the parent tuple immutably when writing to the focused index | Immutable | |
|
||||||
|
| `focusMutableTupleAt` | Focuses to an indexed entry of a mutable tuple. Mutates the parent tuple in place at the focused index | Mutable | Type-safe: will not allow you to mutate `readonly` tuples |
|
||||||
| `focusChunkAt` | Focuses to an indexed entry of a `Chunk`. Replaces the parent `Chunk` immutably when writing to the focused element | Immutable | |
|
| `focusChunkAt` | Focuses to an indexed entry of a `Chunk`. Replaces the parent `Chunk` immutably when writing to the focused element | Immutable | |
|
||||||
|
|
||||||
Also more to come!
|
Also more to come!
|
||||||
@@ -171,11 +171,6 @@ Also more to come!
|
|||||||
#### Manually
|
#### Manually
|
||||||
You can create focused Lenses by composing them manually using `map`, `mapEffect` and `unwrap`:
|
You can create focused Lenses by composing them manually using `map`, `mapEffect` and `unwrap`:
|
||||||
```typescript
|
```typescript
|
||||||
interface User {
|
|
||||||
readonly name: string
|
|
||||||
readonly age: DateTime.Utc
|
|
||||||
}
|
|
||||||
|
|
||||||
const ref = yield* SubscriptionRef.make<readonly User[]>([
|
const ref = yield* SubscriptionRef.make<readonly User[]>([
|
||||||
{ name: "Jean Dupont", age: yield* DateTime.make("03/25/1969") },
|
{ name: "Jean Dupont", age: yield* DateTime.make("03/25/1969") },
|
||||||
{ name: "Juan Joya Borja", age: yield* DateTime.make("04/05/1956") },
|
{ name: "Juan Joya Borja", age: yield* DateTime.make("04/05/1956") },
|
||||||
@@ -221,11 +216,33 @@ const someFunctionThatShouldOnlyHaveReadonlyAccessToTheState = (
|
|||||||
|
|
||||||
const lens = ref.pipe(
|
const lens = ref.pipe(
|
||||||
Lens.fromSubscriptionRef,
|
Lens.fromSubscriptionRef,
|
||||||
Lens.focusField("users"),
|
Lens.focusObjectField("users"),
|
||||||
)
|
)
|
||||||
yield* someFunctionThatShouldOnlyHaveReadonlyAccessToTheState(lens)
|
yield* someFunctionThatShouldOnlyHaveReadonlyAccessToTheState(lens)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Focusing
|
||||||
|
This library re-exports Effect's `Subscribable` module and adds a few transforms to narrow the focus of `Subscribable`'s, same as Lenses:
|
||||||
|
```typescript
|
||||||
|
import { Subscribable } from "effect-lens"
|
||||||
|
|
||||||
|
declare const sub: Subscribabe.Subscribable<readonly { name: string }[], never, never>
|
||||||
|
|
||||||
|
// \/ Subscribabe.Subscribable<string, NoSuchElementException, never>
|
||||||
|
const nameSub = sub.pipe(
|
||||||
|
Subscribable.focusArrayAt(1),
|
||||||
|
Subscribable.focusObjectField("name"),
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Currently available:
|
||||||
|
| Name | Description |
|
||||||
|
| - | - |
|
||||||
|
| `focusObjectField` | Focuses to the field of an object |
|
||||||
|
| `focusArrayAt` | Focuses to an indexed entry of an array |
|
||||||
|
| `focusTupleAt` | Focuses to an indexed entry of a tuple |
|
||||||
|
| `focusChunkAt` | Focuses to an indexed entry of a `Chunk` |
|
||||||
|
|
||||||
|
|
||||||
## Todo
|
## Todo
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "effect-lens",
|
"name": "effect-lens",
|
||||||
"description": "An effectful Lens type to easily manage nested state",
|
"description": "An effectful Lens type to easily manage nested state",
|
||||||
"version": "0.1.1",
|
"version": "0.1.2",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"files": [
|
"files": [
|
||||||
"./README.md",
|
"./README.md",
|
||||||
@@ -24,6 +24,10 @@
|
|||||||
"./PropertyPath": {
|
"./PropertyPath": {
|
||||||
"types": "./dist/PropertyPath.d.ts",
|
"types": "./dist/PropertyPath.d.ts",
|
||||||
"default": "./dist/PropertyPath.js"
|
"default": "./dist/PropertyPath.js"
|
||||||
|
},
|
||||||
|
"./Subscribable": {
|
||||||
|
"types": "./dist/Subscribable.d.ts",
|
||||||
|
"default": "./dist/Subscribable.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import * as Lens from "./Lens.js"
|
|||||||
|
|
||||||
|
|
||||||
describe("Lens", () => {
|
describe("Lens", () => {
|
||||||
test("focusField focuses a nested property without touching other fields", async () => {
|
test("focusObjectField 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.focusField(Lens.fromSubscriptionRef(parent), "count")
|
const countLens = Lens.focusObjectField(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("focusMutableField preserves the root identity when mutating in place", async () => {
|
test("focusObjectMutableField 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.focusMutableField(Lens.fromSubscriptionRef(parent), "detail")
|
const detailLens = Lens.focusObjectMutableField(Lens.fromSubscriptionRef(parent), "detail")
|
||||||
return Effect.flatMap(
|
return Effect.flatMap(
|
||||||
Lens.set(detailLens, "mutated"),
|
Lens.set(detailLens, "mutated"),
|
||||||
() => parent.get,
|
() => parent.get,
|
||||||
@@ -80,6 +80,42 @@ describe("Lens", () => {
|
|||||||
expect(updated).toEqual(["baz", "bar"])
|
expect(updated).toEqual(["baz", "bar"])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("focusTupleAt updates the selected tuple index immutably", async () => {
|
||||||
|
const updated = await Effect.runPromise(
|
||||||
|
Effect.flatMap(
|
||||||
|
SubscriptionRef.make<readonly [string, string, string]>(["a", "b", "c"]),
|
||||||
|
parent => {
|
||||||
|
const elementLens = Lens.focusTupleAt(Lens.fromSubscriptionRef(parent), 1)
|
||||||
|
return Effect.flatMap(
|
||||||
|
Lens.set(elementLens, "updated"),
|
||||||
|
() => parent.get,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(updated).toEqual(["a", "updated", "c"])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("focusMutableTupleAt mutates the tuple reference in place", async () => {
|
||||||
|
const original: [string, string] = ["foo", "bar"]
|
||||||
|
const updated = await Effect.runPromise(
|
||||||
|
Effect.flatMap(
|
||||||
|
SubscriptionRef.make(original),
|
||||||
|
parent => {
|
||||||
|
const elementLens = Lens.focusMutableTupleAt(Lens.fromSubscriptionRef(parent), 0)
|
||||||
|
return Effect.flatMap(
|
||||||
|
Lens.set(elementLens, "baz"),
|
||||||
|
() => parent.get,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(updated).toBe(original)
|
||||||
|
expect(updated).toEqual(["baz", "bar"])
|
||||||
|
})
|
||||||
|
|
||||||
test("focusChunkAt 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(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Array, Chunk, Effect, Function, Pipeable, Predicate, Readable, Stream, Subscribable, type SubscriptionRef, type SynchronizedRef } from "effect"
|
import { Array, Chunk, Effect, Function, Pipeable, Predicate, Readable, Stream, type SubscriptionRef, type SynchronizedRef } from "effect"
|
||||||
import type { NoSuchElementException } from "effect/Cause"
|
import type { NoSuchElementException } from "effect/Cause"
|
||||||
|
import * as Subscribable from "./Subscribable.js"
|
||||||
|
|
||||||
|
|
||||||
export const LensTypeId: unique symbol = Symbol.for("@effect-fc/Lens/Lens")
|
export const LensTypeId: unique symbol = Symbol.for("@effect-fc/Lens/Lens")
|
||||||
@@ -206,7 +207,7 @@ export const mapStream: {
|
|||||||
/**
|
/**
|
||||||
* Narrows the focus to a field of an object. Replaces the object in an immutable fashion when written to.
|
* Narrows the focus to a field of an object. Replaces the object in an immutable fashion when written to.
|
||||||
*/
|
*/
|
||||||
export const focusField: {
|
export const focusObjectField: {
|
||||||
<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,
|
||||||
@@ -223,7 +224,7 @@ export const focusField: {
|
|||||||
(a, b) => Object.setPrototypeOf({ ...a, [key]: b }, Object.getPrototypeOf(a)),
|
(a, b) => Object.setPrototypeOf({ ...a, [key]: b }, Object.getPrototypeOf(a)),
|
||||||
))
|
))
|
||||||
|
|
||||||
export declare namespace focusMutableField {
|
export declare namespace focusObjectMutableField {
|
||||||
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] },
|
||||||
@@ -239,15 +240,15 @@ export declare namespace focusMutableField {
|
|||||||
/**
|
/**
|
||||||
* Narrows the focus to a mutable field of an object. Mutates the object in place when written to.
|
* Narrows the focus to a mutable field of an object. Mutates the object in place when written to.
|
||||||
*/
|
*/
|
||||||
export const focusMutableField: {
|
export const focusObjectMutableField: {
|
||||||
<A extends object, K extends focusMutableField.WritableKeys<A>, ER, EW, RR, RW>(
|
<A extends object, K extends focusObjectMutableField.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 focusMutableField.WritableKeys<A>, ER, EW, RR, RW>(
|
<A extends object, K extends focusObjectMutableField.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 focusMutableField.WritableKeys<A>, ER, EW, RR, RW>(
|
} = Function.dual(2, <A extends object, K extends focusObjectMutableField.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 }))
|
||||||
@@ -259,7 +260,7 @@ 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,
|
||||||
): Lens<A[number]>
|
): Lens<A[number], ER | NoSuchElementException, EW | NoSuchElementException, RR, RW>
|
||||||
<A extends readonly any[], ER, EW, RR, RW>(
|
<A extends readonly any[], ER, EW, RR, RW>(
|
||||||
index: number
|
index: number
|
||||||
): (self: Lens<A, ER, EW, RR, RW>) => Lens<A[number], ER | NoSuchElementException, EW | NoSuchElementException, RR, RW>
|
): (self: Lens<A, ER, EW, RR, RW>) => Lens<A[number], ER | NoSuchElementException, EW | NoSuchElementException, RR, RW>
|
||||||
@@ -295,6 +296,46 @@ export const focusMutableArrayAt: {
|
|||||||
),
|
),
|
||||||
))
|
))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Narrows the focus to an indexed element of a readonly tuple. Replaces the tuple in an immutable fashion when written to.
|
||||||
|
*/
|
||||||
|
export const focusTupleAt: {
|
||||||
|
<T extends readonly [any, ...any[]], I extends number, ER, EW, RR, RW>(
|
||||||
|
self: Lens<T, ER, EW, RR, RW>,
|
||||||
|
index: I,
|
||||||
|
): Lens<T[I], ER, EW, RR, RW>
|
||||||
|
<T extends readonly [any, ...any[]], I extends number, ER, EW, RR, RW>(
|
||||||
|
index: I
|
||||||
|
): (self: Lens<T, ER, EW, RR, RW>) => Lens<T[I], ER, EW, RR, RW>
|
||||||
|
} = Function.dual(2, <T extends readonly [any, ...any[]], I extends number, ER, EW, RR, RW>(
|
||||||
|
self: Lens<T, ER, EW, RR, RW>,
|
||||||
|
index: I,
|
||||||
|
): Lens<T[I], ER, EW, RR, RW> => map(
|
||||||
|
self,
|
||||||
|
Array.unsafeGet(index),
|
||||||
|
(a, b) => Array.replace(a, index, b) as any,
|
||||||
|
))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Narrows the focus to an indexed element of a mutable tuple. Mutates the tuple in place when written to.
|
||||||
|
*/
|
||||||
|
export const focusMutableTupleAt: {
|
||||||
|
<T extends [any, ...any[]], I extends number, ER, EW, RR, RW>(
|
||||||
|
self: Lens<T, ER, EW, RR, RW>,
|
||||||
|
index: I,
|
||||||
|
): Lens<T[I], ER, EW, RR, RW>
|
||||||
|
<T extends [any, ...any[]], I extends number, ER, EW, RR, RW>(
|
||||||
|
index: I
|
||||||
|
): (self: Lens<T, ER, EW, RR, RW>) => Lens<T[I], ER, EW, RR, RW>
|
||||||
|
} = Function.dual(2, <T extends [any, ...any[]], I extends number, ER, EW, RR, RW>(
|
||||||
|
self: Lens<T, ER, EW, RR, RW>,
|
||||||
|
index: I,
|
||||||
|
): Lens<T[I], ER, EW, RR, RW> => map(
|
||||||
|
self,
|
||||||
|
Array.unsafeGet(index),
|
||||||
|
(a, b) => { a[index] = b; return a },
|
||||||
|
))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Narrows the focus to an indexed element of `Chunk`. Replaces the `Chunk` in an immutable fashion when written to.
|
* Narrows the focus to an indexed element of `Chunk`. Replaces the `Chunk` in an immutable fashion when written to.
|
||||||
*/
|
*/
|
||||||
|
|||||||
69
packages/effect-lens/src/Subscribable.ts
Normal file
69
packages/effect-lens/src/Subscribable.ts
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import { Array, Chunk, Function, Subscribable } from "effect"
|
||||||
|
import type { NoSuchElementException } from "effect/Cause"
|
||||||
|
|
||||||
|
|
||||||
|
export * from "effect/Subscribable"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Narrows the focus to a field of an object.
|
||||||
|
*/
|
||||||
|
export const focusObjectField: {
|
||||||
|
<A extends object, K extends keyof A, E, R>(
|
||||||
|
self: Subscribable.Subscribable<A, E, R>,
|
||||||
|
key: K,
|
||||||
|
): Subscribable.Subscribable<A[K], E, R>
|
||||||
|
<A extends object, K extends keyof A, E, R>(
|
||||||
|
key: K,
|
||||||
|
): (self: Subscribable.Subscribable<A, E, R>) => Subscribable.Subscribable<A[K], E, R>
|
||||||
|
} = Function.dual(2, <A extends object, K extends keyof A, E, R>(
|
||||||
|
self: Subscribable.Subscribable<A, E, R>,
|
||||||
|
key: K,
|
||||||
|
): Subscribable.Subscribable<A[K], E, R> => Subscribable.map(self, a => a[key]))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Narrows the focus to an indexed element of an array.
|
||||||
|
*/
|
||||||
|
export const focusArrayAt: {
|
||||||
|
<A extends readonly any[], E, R>(
|
||||||
|
self: Subscribable.Subscribable<A, E, R>,
|
||||||
|
index: number,
|
||||||
|
): Subscribable.Subscribable<A[number], E, R>
|
||||||
|
<A extends readonly any[], E, R>(
|
||||||
|
index: number
|
||||||
|
): (self: Subscribable.Subscribable<A, E, R>) => Subscribable.Subscribable<A[number], E | NoSuchElementException, R>
|
||||||
|
} = Function.dual(2, <A extends readonly any[], E, R>(
|
||||||
|
self: Subscribable.Subscribable<A, E, R>,
|
||||||
|
index: number,
|
||||||
|
): Subscribable.Subscribable<A[number], E | NoSuchElementException, R> => Subscribable.mapEffect(self, Array.get(index)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Narrows the focus to an indexed element of a readonly tuple.
|
||||||
|
*/
|
||||||
|
export const focusTupleAt: {
|
||||||
|
<T extends readonly [any, ...any[]], I extends number, E, R>(
|
||||||
|
self: Subscribable.Subscribable<T, E, R>,
|
||||||
|
index: I,
|
||||||
|
): Subscribable.Subscribable<T[I], E, R>
|
||||||
|
<T extends readonly [any, ...any[]], I extends number, E, R>(
|
||||||
|
index: I
|
||||||
|
): (self: Subscribable.Subscribable<T, E, R>) => Subscribable.Subscribable<T[I], E, R>
|
||||||
|
} = Function.dual(2, <T extends readonly [any, ...any[]], I extends number, E, R>(
|
||||||
|
self: Subscribable.Subscribable<T, E, R>,
|
||||||
|
index: I,
|
||||||
|
): Subscribable.Subscribable<T[I], E, R> => Subscribable.map(self, Array.unsafeGet(index)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Narrows the focus to an indexed element of `Chunk`.
|
||||||
|
*/
|
||||||
|
export const focusChunkAt: {
|
||||||
|
<A, E, R>(
|
||||||
|
self: Subscribable.Subscribable<Chunk.Chunk<A>, E, R>,
|
||||||
|
index: number,
|
||||||
|
): Subscribable.Subscribable<A, E | NoSuchElementException, R>
|
||||||
|
<A, E, R>(
|
||||||
|
index: number
|
||||||
|
): (self: Subscribable.Subscribable<Chunk.Chunk<A>, E, R>) => Subscribable.Subscribable<A, E | NoSuchElementException, R>
|
||||||
|
} = Function.dual(2, <A, E, R>(
|
||||||
|
self: Subscribable.Subscribable<Chunk.Chunk<A>, E, R>,
|
||||||
|
index: number,
|
||||||
|
): Subscribable.Subscribable<A, E | NoSuchElementException, R> => Subscribable.mapEffect(self, Chunk.get(index)))
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
export * as Lens from "./Lens.js"
|
export * as Lens from "./Lens.js"
|
||||||
export * as PropertyPath from "./PropertyPath.js"
|
export * as PropertyPath from "./PropertyPath.js"
|
||||||
|
export * as Subscribable from "./Subscribable.js"
|
||||||
|
|||||||
Reference in New Issue
Block a user