From e182cc4811be91baf64bdbfdc3cb430b0e098732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 29 Apr 2026 16:55:36 +0200 Subject: [PATCH] Cleanup --- packages/effect-fc/src/Form.ts | 3 +- packages/effect-fc/src/Lens.ts | 3 +- packages/effect-fc/src/PropertyPath.test.ts | 67 ------- packages/effect-fc/src/PropertyPath.ts | 98 --------- packages/effect-fc/src/SubmittableForm.ts | 3 +- packages/effect-fc/src/SubscriptionRef.ts | 61 ------ .../effect-fc/src/SubscriptionSubRef.test.ts | 183 ----------------- packages/effect-fc/src/SubscriptionSubRef.ts | 186 ------------------ packages/effect-fc/src/SynchronizedForm.ts | 3 +- packages/effect-fc/src/index.ts | 3 - 10 files changed, 4 insertions(+), 606 deletions(-) delete mode 100644 packages/effect-fc/src/PropertyPath.test.ts delete mode 100644 packages/effect-fc/src/PropertyPath.ts delete mode 100644 packages/effect-fc/src/SubscriptionRef.ts delete mode 100644 packages/effect-fc/src/SubscriptionSubRef.test.ts delete mode 100644 packages/effect-fc/src/SubscriptionSubRef.ts diff --git a/packages/effect-fc/src/Form.ts b/packages/effect-fc/src/Form.ts index d854eef..7343fdf 100644 --- a/packages/effect-fc/src/Form.ts +++ b/packages/effect-fc/src/Form.ts @@ -1,9 +1,8 @@ -import { Array, type Cause, Chunk, type Duration, Effect, Equal, Function, identity, Option, type ParseResult, Pipeable, Predicate, type Scope, Stream } from "effect" +import { Array, type Cause, Chunk, type Duration, Effect, Equal, Function, identity, Option, type ParseResult, Pipeable, Predicate, type Scope, Stream, SubscriptionRef } from "effect" import type * as React from "react" import * as Component from "./Component.js" import * as Lens from "./Lens.js" import * as Subscribable from "./Subscribable.js" -import * as SubscriptionRef from "./SubscriptionRef.js" export const FormTypeId: unique symbol = Symbol.for("@effect-fc/Form/Form") diff --git a/packages/effect-fc/src/Lens.ts b/packages/effect-fc/src/Lens.ts index e62e897..56a505d 100644 --- a/packages/effect-fc/src/Lens.ts +++ b/packages/effect-fc/src/Lens.ts @@ -1,9 +1,8 @@ -import { Effect, Equivalence, Stream } from "effect" +import { Effect, Equivalence, Stream, SubscriptionRef } from "effect" import { Lens } from "effect-lens" import * as React from "react" import * as Component from "./Component.js" import * as SetStateAction from "./SetStateAction.js" -import * as SubscriptionRef from "./SubscriptionRef.js" export * from "effect-lens/Lens" diff --git a/packages/effect-fc/src/PropertyPath.test.ts b/packages/effect-fc/src/PropertyPath.test.ts deleted file mode 100644 index 4c68a38..0000000 --- a/packages/effect-fc/src/PropertyPath.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { describe, expect, test } from "bun:test" -import { Option } from "effect" -import * as PropertyPath from "./PropertyPath.js" - - -describe("immutableSet with arrays", () => { - test("sets a top-level array element", () => { - const arr = [1, 2, 3] - const result = PropertyPath.immutableSet(arr, [1], 99) - expect(result).toEqual(Option.some([1, 99, 3])) - }) - - test("does not mutate the original array", () => { - const arr = [1, 2, 3] - PropertyPath.immutableSet(arr, [0], 42) - expect(arr).toEqual([1, 2, 3]) - }) - - test("sets the first element of an array", () => { - const arr = ["a", "b", "c"] - const result = PropertyPath.immutableSet(arr, [0], "z") - expect(result).toEqual(Option.some(["z", "b", "c"])) - }) - - test("sets the last element of an array", () => { - const arr = [10, 20, 30] - const result = PropertyPath.immutableSet(arr, [2], 99) - expect(result).toEqual(Option.some([10, 20, 99])) - }) - - test("sets a nested array element inside an object", () => { - const obj = { tags: ["foo", "bar", "baz"] } - const result = PropertyPath.immutableSet(obj, ["tags", 1], "qux") - expect(result).toEqual(Option.some({ tags: ["foo", "qux", "baz"] })) - }) - - test("sets a deeply nested value inside an array of objects", () => { - const obj = { items: [{ name: "alice" }, { name: "bob" }] } - const result = PropertyPath.immutableSet(obj, ["items", 0, "name"], "charlie") - expect(result).toEqual(Option.some({ items: [{ name: "charlie" }, { name: "bob" }] })) - }) - - test("sets a value in a nested array", () => { - const matrix = [[1, 2], [3, 4]] - const result = PropertyPath.immutableSet(matrix, [1, 0], 99) - expect(result).toEqual(Option.some([[1, 2], [99, 4]])) - }) - - test("returns Option.none() for an out-of-bounds index", () => { - const arr = [1, 2, 3] - const result = PropertyPath.immutableSet(arr, [5], 99) - expect(result).toEqual(Option.none()) - }) - - test("returns Option.none() for a non-numeric key on an array", () => { - const arr = [1, 2, 3] - // @ts-expect-error intentionally wrong key type - const result = PropertyPath.immutableSet(arr, ["length"], 0) - expect(result).toEqual(Option.none()) - }) - - test("empty path returns Option.some of the value itself", () => { - const arr = [1, 2, 3] - const result = PropertyPath.immutableSet(arr, [], [9, 9, 9] as any) - expect(result).toEqual(Option.some([9, 9, 9])) - }) -}) diff --git a/packages/effect-fc/src/PropertyPath.ts b/packages/effect-fc/src/PropertyPath.ts deleted file mode 100644 index b73d24d..0000000 --- a/packages/effect-fc/src/PropertyPath.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { Array, Equivalence, Function, Option, Predicate } from "effect" - - -export type PropertyPath = readonly PropertyKey[] - -type Prev = readonly [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - -export type Paths = readonly [] | ( - D extends never ? readonly [] : - T extends Seen ? readonly [] : - T extends readonly any[] ? { - [K in keyof T as K extends number ? K : never]: - | readonly [K] - | readonly [K, ...Paths] - } extends infer O - ? O[keyof O] - : never - : - T extends object ? { - [K in keyof T as K extends string | number | symbol ? K : never]-?: - NonNullable extends infer V - ? readonly [K] | readonly [K, ...Paths] - : never - } extends infer O - ? O[keyof O] - : never - : - never -) - -export type ValueFromPath = P extends readonly [infer Head, ...infer Tail] - ? Head extends keyof T - ? ValueFromPath - : T extends readonly any[] - ? Head extends number - ? ValueFromPath - : never - : never - : T - - -export const equivalence: Equivalence.Equivalence = Equivalence.array(Equivalence.strict()) - -export const unsafeGet: { - >(path: P): (self: T) => ValueFromPath - >(self: T, path: P): ValueFromPath -} = Function.dual(2, >(self: T, path: P): ValueFromPath => - path.reduce((acc: any, key: any) => acc?.[key], self) -) - -export const get: { - >(path: P): (self: T) => Option.Option> - >(self: T, path: P): Option.Option> -} = Function.dual(2, >(self: T, path: P): Option.Option> => - path.reduce( - (acc: Option.Option, key: any): Option.Option => Option.isSome(acc) - ? Predicate.hasProperty(acc.value, key) - ? Option.some(acc.value[key]) - : Option.none() - : acc, - - Option.some(self), - ) -) - -export const immutableSet: { - >(path: P, value: ValueFromPath): (self: T) => Option.Option - >(self: T, path: P, value: ValueFromPath): Option.Option -} = Function.dual(3, >(self: T, path: P, value: ValueFromPath): Option.Option => { - const key = Array.head(path as PropertyPath) - if (Option.isNone(key)) - return Option.some(value as T) - if (!Predicate.hasProperty(self, key.value)) - return Option.none() - - const child = immutableSet(self[key.value], Option.getOrThrow(Array.tail(path as PropertyPath)), value) - if (Option.isNone(child)) - return child - - if (Array.isArray(self)) - return typeof key.value === "number" - ? Option.some([ - ...self.slice(0, key.value), - child.value, - ...self.slice(key.value + 1), - ] as T) - : Option.none() - - if (typeof self === "object") - return Option.some( - Object.assign( - Object.create(Object.getPrototypeOf(self)), - { ...self, [key.value]: child.value }, - ) - ) - - return Option.none() -}) diff --git a/packages/effect-fc/src/SubmittableForm.ts b/packages/effect-fc/src/SubmittableForm.ts index 874ce6c..87c4c3e 100644 --- a/packages/effect-fc/src/SubmittableForm.ts +++ b/packages/effect-fc/src/SubmittableForm.ts @@ -1,10 +1,9 @@ -import { Array, Cause, Chunk, type Context, Effect, Exit, Fiber, identity, Option, ParseResult, Pipeable, Predicate, Schema, type Scope, Stream } from "effect" +import { Array, Cause, Chunk, type Context, Effect, Exit, Fiber, identity, Option, ParseResult, Pipeable, Predicate, Schema, type Scope, Stream, SubscriptionRef } from "effect" import * as Form from "./Form.js" import * as Lens from "./Lens.js" import * as Mutation from "./Mutation.js" import * as Result from "./Result.js" import * as Subscribable from "./Subscribable.js" -import * as SubscriptionRef from "./SubscriptionRef.js" export const SubmittableFormTypeId: unique symbol = Symbol.for("@effect-fc/Form/SubmittableForm") diff --git a/packages/effect-fc/src/SubscriptionRef.ts b/packages/effect-fc/src/SubscriptionRef.ts deleted file mode 100644 index 0671ec5..0000000 --- a/packages/effect-fc/src/SubscriptionRef.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Effect, Equivalence, Ref, Stream, SubscriptionRef } from "effect" -import * as React from "react" -import * as Component from "./Component.js" -import * as SetStateAction from "./SetStateAction.js" - - -export declare namespace useSubscriptionRefState { - export interface Options { - readonly equivalence?: Equivalence.Equivalence - } -} - -export const useSubscriptionRefState = Effect.fnUntraced(function* ( - ref: SubscriptionRef.SubscriptionRef, - options?: useSubscriptionRefState.Options>, -): Effect.fn.Return>]> { - const [reactStateValue, setReactStateValue] = React.useState(yield* Component.useOnMount(() => ref)) - - yield* Component.useReactEffect(() => Effect.forkScoped( - Stream.runForEach( - Stream.changesWith(ref.changes, options?.equivalence ?? Equivalence.strict()), - v => Effect.sync(() => setReactStateValue(v)), - ) - ), [ref]) - - const setValue = yield* Component.useCallbackSync( - (setStateAction: React.SetStateAction) => Effect.andThen( - Ref.updateAndGet(ref, prevState => SetStateAction.value(setStateAction, prevState)), - v => setReactStateValue(v), - ), - [ref], - ) - - return [reactStateValue, setValue] -}) - -export declare namespace useSubscriptionRefFromState { - export interface Options { - readonly equivalence?: Equivalence.Equivalence - } -} - -export const useSubscriptionRefFromState = Effect.fnUntraced(function* ( - [value, setValue]: readonly [A, React.Dispatch>], - options?: useSubscriptionRefFromState.Options>, -): Effect.fn.Return> { - const ref = yield* Component.useOnChange(() => Effect.tap( - SubscriptionRef.make(value), - ref => Effect.forkScoped( - Stream.runForEach( - Stream.changesWith(ref.changes, options?.equivalence ?? Equivalence.strict()), - v => Effect.sync(() => setValue(v)), - ) - ), - ), [setValue]) - - yield* Component.useReactEffect(() => Ref.set(ref, value), [value]) - return ref -}) - -export * from "effect/SubscriptionRef" diff --git a/packages/effect-fc/src/SubscriptionSubRef.test.ts b/packages/effect-fc/src/SubscriptionSubRef.test.ts deleted file mode 100644 index 4db616c..0000000 --- a/packages/effect-fc/src/SubscriptionSubRef.test.ts +++ /dev/null @@ -1,183 +0,0 @@ -import { describe, expect, test } from "bun:test" -import { Chunk, Effect, Ref, SubscriptionRef } from "effect" -import * as SubscriptionSubRef from "./SubscriptionSubRef.js" - - -describe("SubscriptionSubRef with array refs", () => { - test("creates a subref for a single array element using path", async () => { - const value = await Effect.runPromise( - Effect.flatMap( - SubscriptionRef.make([{ name: "alice" }, { name: "bob" }, { name: "charlie" }]), - parent => { - const subref = SubscriptionSubRef.makeFromPath(parent, [1, "name"]) - return subref.get - }, - ), - ) - - expect(value).toBe("bob") - }) - - test("modifies a single array element via subref", async () => { - const result = await Effect.runPromise( - Effect.flatMap( - SubscriptionRef.make([{ name: "alice" }, { name: "bob" }, { name: "charlie" }]), - parent => { - const subref = SubscriptionSubRef.makeFromPath(parent, [1, "name"]) - return Effect.flatMap( - Ref.set(subref, "bob-updated"), - () => Ref.get(parent), - ) - }, - ), - ) - - expect(result).toEqual([{ name: "alice" }, { name: "bob-updated" }, { name: "charlie" }]) - }) - - test("modifies array element at index 0", async () => { - const result = await Effect.runPromise( - Effect.flatMap( - SubscriptionRef.make([10, 20, 30]), - parent => { - const subref = SubscriptionSubRef.makeFromPath(parent, [0]) - return Effect.flatMap( - Ref.set(subref, 99), - () => Ref.get(parent), - ) - }, - ), - ) - - expect(result).toEqual([99, 20, 30]) - }) - - test("modifies array element at last index", async () => { - const result = await Effect.runPromise( - Effect.flatMap( - SubscriptionRef.make(["a", "b", "c"]), - parent => { - const subref = SubscriptionSubRef.makeFromPath(parent, [2]) - return Effect.flatMap( - Ref.set(subref, "z"), - () => Ref.get(parent), - ) - }, - ), - ) - - expect(result).toEqual(["a", "b", "z"]) - }) - - test("modifies nested array element", async () => { - const result = await Effect.runPromise( - Effect.flatMap( - SubscriptionRef.make([[1, 2], [3, 4], [5, 6]]), - parent => { - const subref = SubscriptionSubRef.makeFromPath(parent, [1, 0]) - return Effect.flatMap( - Ref.set(subref, 99), - () => Ref.get(parent), - ) - }, - ), - ) - - expect(result).toEqual([[1, 2], [99, 4], [5, 6]]) - }) - - test("uses modifyEffect to transform array element", async () => { - const result = await Effect.runPromise( - Effect.flatMap( - SubscriptionRef.make([{ count: 1 }, { count: 2 }, { count: 3 }]), - parent => { - const subref = SubscriptionSubRef.makeFromPath(parent, [1, "count"]) - return Effect.flatMap( - Ref.update(subref, count => count + 100), - () => Effect.map(Ref.get(parent), parentValue => ({ result: 102, parentValue })), - ) - }, - ), - ) - - expect(result.result).toBe(102) // count + 100 - expect(result.parentValue).toEqual([{ count: 1 }, { count: 102 }, { count: 3 }]) // count + 100 - }) - - test("uses modify to transform array element", async () => { - const result = await Effect.runPromise( - Effect.flatMap( - SubscriptionRef.make([10, 20, 30]), - parent => { - const subref = SubscriptionSubRef.makeFromPath(parent, [1]) - return Effect.flatMap( - Ref.update(subref, x => x + 5), - () => Effect.map(Ref.get(parent), parentValue => ({ result: 25, parentValue })), - ) - }, - ), - ) - - expect(result.result).toBe(25) // 20 + 5 - expect(result.parentValue).toEqual([10, 25, 30]) // 20 + 5 - }) - - test("makeFromChunkIndex modifies chunk element", async () => { - const result = await Effect.runPromise( - Effect.flatMap( - SubscriptionRef.make(Chunk.make(100, 200, 300)), - parent => { - const subref = SubscriptionSubRef.makeFromChunkIndex(parent, 1) - return Effect.flatMap( - Ref.set(subref, 999), - () => Ref.get(parent), - ) - }, - ), - ) - - expect(Chunk.toReadonlyArray(result)).toEqual([100, 999, 300]) - }) - - test("makeFromGetSet with custom getter/setter for array element", async () => { - const result = await Effect.runPromise( - Effect.flatMap( - SubscriptionRef.make([{ id: 1, value: "a" }, { id: 2, value: "b" }]), - parent => { - const subref = SubscriptionSubRef.makeFromGetSet(parent, { - get: arr => arr[0].value, - set: (arr, newValue) => [ - { ...arr[0], value: newValue }, - ...arr.slice(1), - ], - }) - return Effect.flatMap( - Ref.set(subref, "updated"), - () => Ref.get(parent), - ) - }, - ), - ) - - expect(result).toEqual([{ id: 1, value: "updated" }, { id: 2, value: "b" }]) - }) - - test("does not mutate original array when modifying via subref", async () => { - const original = [{ name: "alice" }, { name: "bob" }] - const result = await Effect.runPromise( - Effect.flatMap( - SubscriptionRef.make(original), - parent => { - const subref = SubscriptionSubRef.makeFromPath(parent, [0, "name"]) - return Effect.flatMap( - Ref.set(subref, "alice-updated"), - () => Ref.get(parent), - ) - }, - ), - ) - - expect(original).toEqual([{ name: "alice" }, { name: "bob" }]) // original unchanged - expect(result).toEqual([{ name: "alice-updated" }, { name: "bob" }]) // new value in ref - }) -}) diff --git a/packages/effect-fc/src/SubscriptionSubRef.ts b/packages/effect-fc/src/SubscriptionSubRef.ts deleted file mode 100644 index 95e8b0e..0000000 --- a/packages/effect-fc/src/SubscriptionSubRef.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { Chunk, Effect, Effectable, Option, Predicate, Readable, Ref, Stream, Subscribable, SubscriptionRef, SynchronizedRef, type Types, type Unify } from "effect" -import * as PropertyPath from "./PropertyPath.js" - - -export const SubscriptionSubRefTypeId: unique symbol = Symbol.for("@effect-fc/SubscriptionSubRef/SubscriptionSubRef") -export type SubscriptionSubRefTypeId = typeof SubscriptionSubRefTypeId - -export interface SubscriptionSubRef> -extends SubscriptionSubRef.Variance, SubscriptionRef.SubscriptionRef { - readonly parent: B - - readonly [Unify.typeSymbol]?: unknown - readonly [Unify.unifySymbol]?: SubscriptionSubRefUnify - readonly [Unify.ignoreSymbol]?: SubscriptionSubRefUnifyIgnore -} - -export declare namespace SubscriptionSubRef { - export interface Variance { - readonly [SubscriptionSubRefTypeId]: { - readonly _A: Types.Invariant - readonly _B: Types.Invariant - } - } -} - -export interface SubscriptionSubRefUnify extends SubscriptionRef.SubscriptionRefUnify { - SubscriptionSubRef?: () => Extract> -} - -export interface SubscriptionSubRefUnifyIgnore extends SubscriptionRef.SubscriptionRefUnifyIgnore { - SubscriptionRef?: true -} - - -const refVariance = { _A: (_: any) => _ } -const synchronizedRefVariance = { _A: (_: any) => _ } -const subscriptionRefVariance = { _A: (_: any) => _ } -const subscriptionSubRefVariance = { _A: (_: any) => _, _B: (_: any) => _ } - -class SubscriptionSubRefImpl> -extends Effectable.Class implements SubscriptionSubRef { - readonly [Readable.TypeId]: Readable.TypeId = Readable.TypeId - readonly [Subscribable.TypeId]: Subscribable.TypeId = Subscribable.TypeId - readonly [Ref.RefTypeId] = refVariance - readonly [SynchronizedRef.SynchronizedRefTypeId] = synchronizedRefVariance - readonly [SubscriptionRef.SubscriptionRefTypeId] = subscriptionRefVariance - readonly [SubscriptionSubRefTypeId] = subscriptionSubRefVariance - - readonly get: Effect.Effect - - constructor( - readonly parent: B, - readonly getter: (parentValue: Effect.Effect.Success) => A, - readonly setter: (parentValue: Effect.Effect.Success, value: A) => Effect.Effect.Success, - ) { - super() - this.get = Effect.map(this.parent, this.getter) - } - - commit() { - return this.get - } - - get changes(): Stream.Stream { - return Stream.unwrap( - Effect.map(this.get, a => Stream.concat( - Stream.make(a), - Stream.map(this.parent.changes, this.getter), - )) - ) - } - - modify(f: (a: A) => readonly [C, A]): Effect.Effect { - return this.modifyEffect(a => Effect.succeed(f(a))) - } - - modifyEffect(f: (a: A) => Effect.Effect): Effect.Effect { - return Effect.Do.pipe( - Effect.bind("b", (): Effect.Effect> => this.parent), - Effect.bind("ca", ({ b }) => f(this.getter(b))), - Effect.tap(({ b, ca: [, a] }) => SubscriptionRef.set(this.parent, this.setter(b, a))), - Effect.map(({ ca: [c] }) => c), - ) - } -} - - -export const isSubscriptionSubRef = (u: unknown): u is SubscriptionSubRef> => Predicate.hasProperty(u, SubscriptionSubRefTypeId) - -export const makeFromGetSet = >( - parent: B, - options: { - readonly get: (parentValue: Effect.Effect.Success) => A - readonly set: (parentValue: Effect.Effect.Success, value: A) => Effect.Effect.Success - }, -): SubscriptionSubRef => new SubscriptionSubRefImpl(parent, options.get, options.set) - -export const makeFromPath = < - B extends SubscriptionRef.SubscriptionRef, - const P extends PropertyPath.Paths>, ->( - parent: B, - path: P, -): SubscriptionSubRef, P>, B> => new SubscriptionSubRefImpl( - parent, - parentValue => Option.getOrThrow(PropertyPath.get(parentValue, path)), - (parentValue, value) => Option.getOrThrow(PropertyPath.immutableSet(parentValue, path, value)), -) - -export const makeFromChunkIndex: { - >>( - parent: B, - index: number, - ): SubscriptionSubRef< - Effect.Effect.Success extends Chunk.NonEmptyChunk ? A : never, - B - > - >>( - parent: B, - index: number, - ): SubscriptionSubRef< - Effect.Effect.Success extends Chunk.Chunk ? A : never, - B - > -} = ( - parent: SubscriptionRef.SubscriptionRef>, - index: number, -) => new SubscriptionSubRefImpl( - parent, - parentValue => Chunk.unsafeGet(parentValue, index), - (parentValue, value) => Chunk.replace(parentValue, index, value), -) as any - -export const makeFromChunkFindFirst: { - >>( - parent: B, - findFirstPredicate: Predicate.Predicate extends Chunk.NonEmptyChunk ? A : never>, - ): SubscriptionSubRef< - Effect.Effect.Success extends Chunk.NonEmptyChunk ? A : never, - B - > - >>( - parent: B, - findFirstPredicate: Predicate.Predicate extends Chunk.Chunk ? A : never>, - ): SubscriptionSubRef< - Effect.Effect.Success extends Chunk.Chunk ? A : never, - B - > -} = ( - parent: SubscriptionRef.SubscriptionRef>, - findFirstPredicate: Predicate.Predicate.Any, -) => new SubscriptionSubRefImpl( - parent, - parentValue => Option.getOrThrow(Chunk.findFirst(parentValue, findFirstPredicate)), - (parentValue, value) => Option.getOrThrow(Option.andThen( - Chunk.findFirstIndex(parentValue, findFirstPredicate), - index => Chunk.replace(parentValue, index, value), - )), -) as any - -export const makeFromChunkFindLast: { - >>( - parent: B, - findLastPredicate: Predicate.Predicate extends Chunk.NonEmptyChunk ? A : never>, - ): SubscriptionSubRef< - Effect.Effect.Success extends Chunk.NonEmptyChunk ? A : never, - B - > - >>( - parent: B, - findLastPredicate: Predicate.Predicate extends Chunk.Chunk ? A : never>, - ): SubscriptionSubRef< - Effect.Effect.Success extends Chunk.Chunk ? A : never, - B - > -} = ( - parent: SubscriptionRef.SubscriptionRef>, - findLastPredicate: Predicate.Predicate.Any, -) => new SubscriptionSubRefImpl( - parent, - parentValue => Option.getOrThrow(Chunk.findLast(parentValue, findLastPredicate)), - (parentValue, value) => Option.getOrThrow(Option.andThen( - Chunk.findLastIndex(parentValue, findLastPredicate), - index => Chunk.replace(parentValue, index, value), - )), -) as any diff --git a/packages/effect-fc/src/SynchronizedForm.ts b/packages/effect-fc/src/SynchronizedForm.ts index c40d712..923296e 100644 --- a/packages/effect-fc/src/SynchronizedForm.ts +++ b/packages/effect-fc/src/SynchronizedForm.ts @@ -1,8 +1,7 @@ -import { Array, Cause, Chunk, type Context, Effect, Equal, Exit, Fiber, Option, ParseResult, Pipeable, Predicate, Schema, type Scope, Stream } from "effect" +import { Array, Cause, Chunk, type Context, Effect, Equal, Exit, Fiber, Option, ParseResult, Pipeable, Predicate, Schema, type Scope, Stream, SubscriptionRef } from "effect" import * as Form from "./Form.js" import * as Lens from "./Lens.js" import * as Subscribable from "./Subscribable.js" -import * as SubscriptionRef from "./SubscriptionRef.js" export const SynchronizedFormTypeId: unique symbol = Symbol.for("@effect-fc/Form/SynchronizedForm") diff --git a/packages/effect-fc/src/index.ts b/packages/effect-fc/src/index.ts index 131cf54..8829e81 100644 --- a/packages/effect-fc/src/index.ts +++ b/packages/effect-fc/src/index.ts @@ -5,7 +5,6 @@ export * as Form from "./Form.js" export * as Lens from "./Lens.js" export * as Memoized from "./Memoized.js" export * as Mutation from "./Mutation.js" -export * as PropertyPath from "./PropertyPath.js" export * as PubSub from "./PubSub.js" export * as Query from "./Query.js" export * as QueryClient from "./QueryClient.js" @@ -15,6 +14,4 @@ export * as SetStateAction from "./SetStateAction.js" export * as Stream from "./Stream.js" export * as SubmittableForm from "./SubmittableForm.js" export * as Subscribable from "./Subscribable.js" -export * as SubscriptionRef from "./SubscriptionRef.js" -export * as SubscriptionSubRef from "./SubscriptionSubRef.js" export * as SynchronizedForm from "./SynchronizedForm.js"