Refactor Form
All checks were successful
Lint / lint (push) Successful in 13s

This commit is contained in:
Julien Valverdé
2026-03-30 14:20:25 +02:00
parent 212da47e12
commit 075e92cb66
4 changed files with 33 additions and 7 deletions

View File

@@ -37,7 +37,7 @@
"name": "effect-fc",
"version": "0.2.4",
"dependencies": {
"effect-lens": "^0.1.3",
"effect-lens": "^0.1.4",
},
"devDependencies": {
"@effect/platform-browser": "^0.76.0",
@@ -1380,7 +1380,7 @@
"effect-fc": ["effect-fc@workspace:packages/effect-fc"],
"effect-lens": ["effect-lens@0.1.3", "", { "peerDependencies": { "effect": "^3.21.0" } }, "sha512-LtGugMzJehYlQfD9GAbvAOFolVj6UOokqA2EI3M43GC2+wqTDloQjyiW3hrpH3UlayDor7Yg1ZG05Do5a0knsA=="],
"effect-lens": ["effect-lens@0.1.4", "", { "peerDependencies": { "effect": "^3.21.0" } }, "sha512-jq/yWuUQcF0tKYsWPPXc0GMtanR1wFo8SGLCI+9nFmDPBJsDmLZDjVj0n15P94om5vfGNOBWtmszqMV1NliYmw=="],
"electron-to-chromium": ["electron-to-chromium@1.5.313", "", {}, "sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA=="],

View File

@@ -46,6 +46,6 @@
"react": "^19.2.0"
},
"dependencies": {
"effect-lens": "^0.1.3"
"effect-lens": "^0.1.4"
}
}

View File

@@ -233,6 +233,14 @@ export const service = <A, I = A, R = never, MA = void, ME = never, MR = never,
form => Effect.forkScoped(form.run),
)
const filterIssuesByPath = (
issues: readonly ParseResult.ArrayFormatterIssue[],
path: readonly PropertyKey[],
): readonly ParseResult.ArrayFormatterIssue[] => Array.filter(issues, issue =>
issue.path.length >= path.length && Array.every(path, (p, i) => p === issue.path[i])
)
export const focusObjectField = <P extends readonly PropertyKey[], A extends object, I extends object, ER, EW, K extends keyof A & keyof I>(
self: Form<P, A, I, ER, EW>,
key: K,
@@ -242,9 +250,26 @@ export const focusObjectField = <P extends readonly PropertyKey[], A extends obj
return new FormImpl(
path,
Subscribable.map(form.value, Option.map(a => a[key])),
Subscribable.mapOption(form.value, a => a[key]),
Lens.focusObjectField(form.encodedValue, key),
Subscribable.map(form.issues, issues => Array.filter(issues, issue => issue.path.length >= path.length && Array.every(path, (p, i) => p === issue.path[i]))),
Subscribable.map(form.issues, issues => filterIssuesByPath(issues, path)),
form.isValidating,
form.canSubmit,
)
}
export const focusArrayAt = <P extends readonly PropertyKey[], A extends readonly any[], I extends readonly any[], ER, EW>(
self: Form<P, A, I, ER, EW>,
index: number,
): Form<readonly [...P, number], A[number], I[number], ER | Cause.NoSuchElementException, EW | Cause.NoSuchElementException> => {
const form = self as FormImpl<P, A, I, ER, EW>
const path = [...form.path, index] as const
return new FormImpl(
path,
Subscribable.mapOptionEffect(form.value, Array.get(index)),
Lens.focusArrayAt(form.encodedValue, index),
Subscribable.map(form.issues, issues => filterIssuesByPath(issues, path)),
form.isValidating,
form.canSubmit,
)

View File

@@ -1,9 +1,10 @@
import { Effect, Equivalence, Stream, Subscribable } from "effect"
import { Effect, Equivalence, Stream } from "effect"
import { Subscribable } from "effect-lens"
import * as React from "react"
import * as Component from "./Component.js"
export * from "effect/Subscribable"
export * from "effect-lens/Subscribable"
export const zipLatestAll = <const T extends readonly Subscribable.Subscribable<any, any, any>[]>(
...elements: T