This commit is contained in:
@@ -5,7 +5,8 @@ import * as PropertyPath from "./PropertyPath.js"
|
|||||||
export const SubscriptionSubRefTypeId: unique symbol = Symbol.for("effect-fc/types/SubscriptionSubRef")
|
export const SubscriptionSubRefTypeId: unique symbol = Symbol.for("effect-fc/types/SubscriptionSubRef")
|
||||||
export type SubscriptionSubRefTypeId = typeof SubscriptionSubRefTypeId
|
export type SubscriptionSubRefTypeId = typeof SubscriptionSubRefTypeId
|
||||||
|
|
||||||
export interface SubscriptionSubRef<in out A, in out B> extends SubscriptionSubRef.Variance<A, B>, SubscriptionRef.SubscriptionRef<A> {
|
export interface SubscriptionSubRef<in out A, in out B extends SubscriptionRef.SubscriptionRef<any>>
|
||||||
|
extends SubscriptionSubRef.Variance<A, B>, SubscriptionRef.SubscriptionRef<A> {
|
||||||
readonly parent: SubscriptionRef.SubscriptionRef<B>
|
readonly parent: SubscriptionRef.SubscriptionRef<B>
|
||||||
|
|
||||||
readonly [Unify.typeSymbol]?: unknown
|
readonly [Unify.typeSymbol]?: unknown
|
||||||
@@ -36,7 +37,8 @@ const synchronizedRefVariance = { _A: (_: any) => _ }
|
|||||||
const subscriptionRefVariance = { _A: (_: any) => _ }
|
const subscriptionRefVariance = { _A: (_: any) => _ }
|
||||||
const subscriptionSubRefVariance = { _A: (_: any) => _, _B: (_: any) => _ }
|
const subscriptionSubRefVariance = { _A: (_: any) => _, _B: (_: any) => _ }
|
||||||
|
|
||||||
class SubscriptionSubRefImpl<in out A, in out B> extends Effectable.Class<A> implements SubscriptionSubRef<A, B> {
|
class SubscriptionSubRefImpl<in out A, in out B extends SubscriptionRef.SubscriptionRef<any>>
|
||||||
|
extends Effectable.Class<A> implements SubscriptionSubRef<A, B> {
|
||||||
readonly [Readable.TypeId]: Readable.TypeId = Readable.TypeId
|
readonly [Readable.TypeId]: Readable.TypeId = Readable.TypeId
|
||||||
readonly [Subscribable.TypeId]: Subscribable.TypeId = Subscribable.TypeId
|
readonly [Subscribable.TypeId]: Subscribable.TypeId = Subscribable.TypeId
|
||||||
readonly [Ref.RefTypeId] = refVariance
|
readonly [Ref.RefTypeId] = refVariance
|
||||||
@@ -47,9 +49,9 @@ class SubscriptionSubRefImpl<in out A, in out B> extends Effectable.Class<A> imp
|
|||||||
readonly get: Effect.Effect<A>
|
readonly get: Effect.Effect<A>
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly parent: SubscriptionRef.SubscriptionRef<B>,
|
readonly parent: B,
|
||||||
readonly getter: (parentValue: B) => A,
|
readonly getter: (parentValue: Effect.Effect.Success<B>) => A,
|
||||||
readonly setter: (parentValue: B, value: A) => B,
|
readonly setter: (parentValue: Effect.Effect.Success<B>, value: A) => Effect.Effect.Success<B>,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
this.get = Effect.map(this.parent, this.getter)
|
this.get = Effect.map(this.parent, this.getter)
|
||||||
@@ -60,12 +62,11 @@ class SubscriptionSubRefImpl<in out A, in out B> extends Effectable.Class<A> imp
|
|||||||
}
|
}
|
||||||
|
|
||||||
get changes(): Stream.Stream<A> {
|
get changes(): Stream.Stream<A> {
|
||||||
return this.get.pipe(
|
return Stream.unwrap(
|
||||||
Effect.map(a => this.parent.changes.pipe(
|
Effect.map(this.get, a => Stream.concat(
|
||||||
Stream.map(this.getter),
|
Stream.make(a),
|
||||||
s => Stream.concat(Stream.make(a), s),
|
Stream.map(this.parent.changes, this.getter),
|
||||||
)),
|
))
|
||||||
Stream.unwrap,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ class SubscriptionSubRefImpl<in out A, in out B> extends Effectable.Class<A> imp
|
|||||||
|
|
||||||
modifyEffect<C, E, R>(f: (a: A) => Effect.Effect<readonly [C, A], E, R>): Effect.Effect<C, E, R> {
|
modifyEffect<C, E, R>(f: (a: A) => Effect.Effect<readonly [C, A], E, R>): Effect.Effect<C, E, R> {
|
||||||
return Effect.Do.pipe(
|
return Effect.Do.pipe(
|
||||||
Effect.bind("b", () => this.parent),
|
Effect.bind("b", (): Effect.Effect<Effect.Effect.Success<B>> => this.parent),
|
||||||
Effect.bind("ca", ({ b }) => f(this.getter(b))),
|
Effect.bind("ca", ({ b }) => f(this.getter(b))),
|
||||||
Effect.tap(({ b, ca: [, a] }) => Ref.set(this.parent, this.setter(b, a))),
|
Effect.tap(({ b, ca: [, a] }) => Ref.set(this.parent, this.setter(b, a))),
|
||||||
Effect.map(({ ca: [c] }) => c),
|
Effect.map(({ ca: [c] }) => c),
|
||||||
@@ -84,28 +85,34 @@ class SubscriptionSubRefImpl<in out A, in out B> extends Effectable.Class<A> imp
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const makeFromGetSet = <A, B>(
|
export const makeFromGetSet = <A, B extends SubscriptionRef.SubscriptionRef<any>>(
|
||||||
parent: SubscriptionRef.SubscriptionRef<B>,
|
parent: B,
|
||||||
options: {
|
options: {
|
||||||
readonly get: (parentValue: B) => A
|
readonly get: (parentValue: Effect.Effect.Success<B>) => A
|
||||||
readonly set: (parentValue: B, value: A) => B
|
readonly set: (parentValue: Effect.Effect.Success<B>, value: A) => Effect.Effect.Success<B>
|
||||||
},
|
},
|
||||||
): SubscriptionSubRef<A, B> => new SubscriptionSubRefImpl(parent, options.get, options.set)
|
): SubscriptionSubRef<A, B> => new SubscriptionSubRefImpl(parent, options.get, options.set)
|
||||||
|
|
||||||
export const makeFromPath = <B, const P extends PropertyPath.Paths<B>>(
|
export const makeFromPath = <
|
||||||
parent: SubscriptionRef.SubscriptionRef<B>,
|
B extends SubscriptionRef.SubscriptionRef<any>,
|
||||||
|
const P extends PropertyPath.Paths<Effect.Effect.Success<B>>,
|
||||||
|
>(
|
||||||
|
parent: B,
|
||||||
path: P,
|
path: P,
|
||||||
): SubscriptionSubRef<PropertyPath.ValueFromPath<B, P>, B> => new SubscriptionSubRefImpl(
|
): SubscriptionSubRef<PropertyPath.ValueFromPath<Effect.Effect.Success<B>, P>, B> => new SubscriptionSubRefImpl(
|
||||||
parent,
|
parent,
|
||||||
parentValue => Option.getOrThrow(PropertyPath.get(parentValue, path)),
|
parentValue => Option.getOrThrow(PropertyPath.get(parentValue, path)),
|
||||||
(parentValue, value) => Option.getOrThrow(PropertyPath.immutableSet(parentValue, path, value)),
|
(parentValue, value) => Option.getOrThrow(PropertyPath.immutableSet(parentValue, path, value)),
|
||||||
)
|
)
|
||||||
|
|
||||||
export const makeFromChunkRef = <A>(
|
export const makeFromChunkRef = <A, B extends SubscriptionRef.SubscriptionRef<Chunk.Chunk<any> | Chunk.NonEmptyChunk<any>>>(
|
||||||
parent: SubscriptionRef.SubscriptionRef<Chunk.Chunk<A>>,
|
parent: B,
|
||||||
index: number,
|
index: number,
|
||||||
): SubscriptionSubRef<A, Chunk.Chunk<A>> => new SubscriptionSubRefImpl(
|
): SubscriptionSubRef<
|
||||||
parent,
|
Effect.Effect.Success<B> extends Chunk.Chunk<infer A> ? A : never,
|
||||||
|
B
|
||||||
|
> => new SubscriptionSubRefImpl(
|
||||||
|
parent as SubscriptionRef.SubscriptionRef<Chunk.Chunk<any>>,
|
||||||
parentValue => Chunk.unsafeGet(parentValue, index),
|
parentValue => Chunk.unsafeGet(parentValue, index),
|
||||||
(parentValue, value) => Chunk.replace(parentValue, index, value),
|
(parentValue, value) => Chunk.replace(parentValue, index, value),
|
||||||
)
|
) as any
|
||||||
|
|||||||
@@ -2,13 +2,17 @@ import { runtime } from "@/runtime"
|
|||||||
import { Flex, Text, TextField } from "@radix-ui/themes"
|
import { Flex, Text, TextField } from "@radix-ui/themes"
|
||||||
import { createFileRoute } from "@tanstack/react-router"
|
import { createFileRoute } from "@tanstack/react-router"
|
||||||
import { GetRandomValues, makeUuid4 } from "@typed/id"
|
import { GetRandomValues, makeUuid4 } from "@typed/id"
|
||||||
import { Effect } from "effect"
|
import { Chunk, Effect, SubscriptionRef } from "effect"
|
||||||
import { Component, Memoized } from "effect-fc"
|
import { Component, Memoized } from "effect-fc"
|
||||||
|
import { SubscriptionSubRef } from "effect-fc/types"
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
|
|
||||||
|
|
||||||
const RouteComponent = Component.make(function* RouteComponent() {
|
const RouteComponent = Component.make(function* RouteComponent() {
|
||||||
const [value, setValue] = React.useState("")
|
const [value, setValue] = React.useState("")
|
||||||
|
const myRef = yield* SubscriptionRef.make(Chunk.make({ name: "person 1" } as const))
|
||||||
|
// const myRef = yield* SubscriptionRef.make(Chunk.empty<{ readonly name: "person 1" }>())
|
||||||
|
const mySubRef = SubscriptionSubRef.makeFromChunkRef(myRef, 0)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex direction="column" gap="2">
|
<Flex direction="column" gap="2">
|
||||||
|
|||||||
Reference in New Issue
Block a user