From 6f65574ebdd1e65d216e705e80c3d8ff767a22b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 11 May 2025 08:11:03 +0200 Subject: [PATCH] Cleanup --- packages/example/src/routes/streams/pull.tsx | 21 ++++++--- packages/example/src/routes/tests.tsx | 4 +- packages/reffuse/src/ReffuseNamespace.ts | 46 +------------------- 3 files changed, 18 insertions(+), 53 deletions(-) diff --git a/packages/example/src/routes/streams/pull.tsx b/packages/example/src/routes/streams/pull.tsx index 0524b53..c7c0722 100644 --- a/packages/example/src/routes/streams/pull.tsx +++ b/packages/example/src/routes/streams/pull.tsx @@ -1,8 +1,8 @@ import { R } from "@/reffuse" import { Button, Flex, Text } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" -import { Option, Random, Stream } from "effect" -import { useMemo } from "react" +import { Chunk, Effect, Exit, Option, Queue, Random, Scope, Stream } from "effect" +import { useMemo, useState } from "react" export const Route = createFileRoute("/streams/pull")({ @@ -11,13 +11,24 @@ export const Route = createFileRoute("/streams/pull")({ function RouteComponent() { const stream = useMemo(() => Stream.repeatEffect(Random.nextInt), []) - const [value, pull] = R.usePullStream(stream) - const pullNext = R.useCallbackSync(() => pull, [pull]) + const streamScope = R.useScope([stream]) + + const queue = R.useMemo(() => Effect.provideService(Stream.toQueueOfElements(stream), Scope.Scope, streamScope), [streamScope]) + + const [value, setValue] = useState(Option.none()) + const pullLatest = R.useCallbackSync(() => Queue.takeAll(queue).pipe( + Effect.flatMap(Chunk.last), + Effect.flatMap(Exit.matchEffect({ + onSuccess: Effect.succeed, + onFailure: Effect.fail, + })), + Effect.tap(v => Effect.sync(() => setValue(Option.some(v)))), + ), [queue]) return ( {Option.isSome(value) && {value.value}} - + ) } diff --git a/packages/example/src/routes/tests.tsx b/packages/example/src/routes/tests.tsx index ac58463..51ce6a5 100644 --- a/packages/example/src/routes/tests.tsx +++ b/packages/example/src/routes/tests.tsx @@ -15,7 +15,6 @@ export const Route = createFileRoute("/tests")({ function RouteComponent() { const runSync = R.useRunSync() - const runPromise = R.useRunPromise() const [uuid, setUuid] = useState(R.useMemo(() => makeUuid, [])) const generateUuid = R.useCallbackSync(() => makeUuid.pipe( @@ -23,7 +22,7 @@ function RouteComponent() { ), []) const uuidStream = R.useStreamFromReactiveValues([uuid]) - const [uuidStreamLatestValue, pullUuidStream] = R.usePullStream(uuidStream) + const uuidStreamLatestValue = R.useSubscribeStream(uuidStream) const scope = R.useScope([uuid]) @@ -43,7 +42,6 @@ function RouteComponent() { onNone: () => <>, })} - ) } diff --git a/packages/reffuse/src/ReffuseNamespace.ts b/packages/reffuse/src/ReffuseNamespace.ts index 0250fdc..19ddee6 100644 --- a/packages/reffuse/src/ReffuseNamespace.ts +++ b/packages/reffuse/src/ReffuseNamespace.ts @@ -1,4 +1,4 @@ -import { Chunk, type Context, Effect, ExecutionStrategy, Exit, type Fiber, flow, type Layer, Match, Option, pipe, Pipeable, PubSub, Ref, Runtime, Scope, Stream, SubscriptionRef } from "effect" +import { type Context, Effect, ExecutionStrategy, Exit, type Fiber, type Layer, Match, Option, pipe, Pipeable, PubSub, Ref, Runtime, Scope, Stream, SubscriptionRef } from "effect" import * as React from "react" import * as ReffuseContext from "./ReffuseContext.js" import * as ReffuseRuntime from "./ReffuseRuntime.js" @@ -527,50 +527,6 @@ export abstract class ReffuseNamespace { return reactStateValue } - usePullStream( - this: ReffuseNamespace, - stream: Stream.Stream, - ): [latestValue: Option.Option, pull: Effect.Effect, Option.Option>] - usePullStream( - this: ReffuseNamespace, - stream: Stream.Stream, - initialValue: () => Effect.Effect, - ): [latestValue: Option.Some, pull: Effect.Effect, Option.Option>] - usePullStream( - this: ReffuseNamespace, - stream: Stream.Stream, - initialValue?: () => Effect.Effect, - ): [latestValue: Option.Option, pull: Effect.Effect, Option.Option>] { - const scope = this.useScope([stream]) - - const [reactStateValue, setReactStateValue] = React.useState(this.useMemo( - () => initialValue - ? Effect.map(initialValue(), Option.some) - : Effect.succeed(Option.none()), - [], - { doNotReExecuteOnRuntimeOrContextChange: true }, - )) - - const pull = this.useMemo(() => Effect.context().pipe( - Effect.flatMap(context => Stream.toPull(Stream.changesWith(stream, (x, y) => x === y)).pipe( - Effect.map(effect => effect.pipe( - Effect.tap(flow( - Chunk.last, - v => Option.match(v, { - onSome: () => Effect.sync(() => setReactStateValue(v)), - onNone: () => Effect.void, - }), - )), - Effect.provide(context), - )), - - Effect.provideService(Scope.Scope, scope), - )) - ), [stream, scope]) - - return [reactStateValue, pull] - } - SubRef, R>( this: ReffuseNamespace,