Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/strange-bottles-walk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"effect-react": patch
---

useSyncExternalStore for useReactCallback
21 changes: 21 additions & 0 deletions src/FiberStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type * as Runtime from "@effect/io/Runtime"
import type * as Stream from "@effect/stream/Stream"
import * as internal from "effect-react/internal/fiberStore"
import type * as ResultBag from "effect-react/ResultBag"

/**
* @since 1.0.0
* @category models
*/
export interface FiberStore<R, E, A> {
readonly snapshot: () => ResultBag.ResultBag<E, A>
readonly run: (stream: Stream.Stream<R, E, A>) => void
readonly subscribe: (listener: () => void) => () => void
readonly interruptIfRunning: () => void
}

/**
* @since 1.0.0
* @category constructors
*/
export const make: <R, E, A>(runtime: Runtime.Runtime<R>) => FiberStore<R, E, A> = internal.make
38 changes: 38 additions & 0 deletions src/ResultBag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type * as Option from "@effect/data/Option"
import type * as Cause from "@effect/io/Cause"
import * as internal from "effect-react/internal/resultBag"
import type * as Result from "effect-react/Result"
import type * as TrackedProperties from "effect-react/TrackedProperties"

/**
* @since 1.0.0
* @category models
*/
export interface ResultBag<E, A> {
readonly result: Result.Result<E, A>
readonly dataUpdatedAt: Option.Option<Date>
readonly errorUpdatedAt: Option.Option<Date>
readonly errorRunningCount: number
readonly failureCount: number
readonly failureCause: Cause.Cause<E>
readonly isError: boolean
readonly isRefreshing: boolean
readonly isRetrying: boolean
readonly isLoading: boolean
readonly isLoadingFailure: boolean
readonly isRefreshingFailure: boolean
readonly isSuccess: boolean
// readonly isFetched: boolean;
// readonly isFetchedAfterMount: boolean;
// readonly isInitialLoading: boolean;
// readonly isPreviousData: boolean;
}

/**
* @since 1.0.0
* @category constructors
*/
export const make: <E, A>(
result: Result.Result<E, A>,
tracked: TrackedProperties.TrackedProperties
) => ResultBag<E, A> = internal.make
61 changes: 50 additions & 11 deletions src/RuntimeProvider.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,54 @@
"use client"
import type { LazyArg } from "@effect/data/Function"
import { pipe } from "@effect/data/Function"
import * as Effect from "@effect/io/Effect"
import * as Layer from "@effect/io/Layer"
import type * as Runtime from "@effect/io/Runtime"
import * as Scope from "@effect/io/Scope"
import type { UseResult } from "effect-react/hooks/useResult"
import { makeUseResult } from "effect-react/hooks/useResult"
import type { UseResultCallback } from "effect-react/hooks/useResultCallback"
import { makeUseResultCallback } from "effect-react/hooks/useResultCallback"
import type * as Stream from "@effect/stream/Stream"
import * as internalUseResult from "effect-react/internal/hooks/useResult"
import * as internalUseResultCallback from "effect-react/internal/hooks/useResultCallback"
import type * as ResultBag from "effect-react/ResultBag"
import type { DependencyList } from "react"
import { createContext } from "react"

export { RuntimeContext } from "effect-react/internal/runtimeContext"
/**
* @since 1.0.0
* @category models
*/
export type RuntimeContext<R> = React.Context<Runtime.Runtime<R>>

/**
* @since 1.0.0
* @category hooks
*/
export type UseResult<R> = <R0 extends R, E, A>(
evaluate: LazyArg<Stream.Stream<R0, E, A>>,
deps: DependencyList
) => ResultBag.ResultBag<E, A>

/**
* @since 1.0.0
* @category hooks
*/
export type UseResultCallback<R> = <Args extends Array<any>, R0 extends R, E, A>(
f: (...args: Args) => Stream.Stream<R0, E, A>
) => readonly [ResultBag.ResultBag<E, A>, (...args: Args) => void]

/**
* @since 1.0.0
* @category models
*/
export interface ReactEffectBag<R> {
readonly RuntimeContext: React.Context<Runtime.Runtime<R>>
readonly useResultCallback: UseResultCallback<R>
readonly useResult: UseResult<R>
}

/**
* @since 1.0.0
* @category constructors
*/
export const makeFromLayer = <R, E>(
layer: Layer.Layer<never, E, R>
): ReactEffectBag<R> => {
Expand All @@ -33,29 +64,37 @@ export const makeFromLayer = <R, E>(

return {
RuntimeContext,
useResultCallback: makeUseResultCallback(RuntimeContext),
useResult: makeUseResult(RuntimeContext)
useResultCallback: internalUseResultCallback.make(RuntimeContext),
useResult: internalUseResult.make(RuntimeContext)
}
}

/**
* @since 1.0.0
* @category constructors
*/
export const makeFromRuntime = <R>(
runtime: Runtime.Runtime<R>
): ReactEffectBag<R> => {
const RuntimeContext = createContext(runtime)

return {
RuntimeContext,
useResultCallback: makeUseResultCallback(RuntimeContext),
useResult: makeUseResult(RuntimeContext)
useResultCallback: internalUseResultCallback.make(RuntimeContext),
useResult: internalUseResult.make(RuntimeContext)
}
}

/**
* @since 1.0.0
* @category constructors
*/
export const makeFromRuntimeContext = <R>(
RuntimeContext: React.Context<Runtime.Runtime<R>>
): ReactEffectBag<R> => {
return {
RuntimeContext,
useResultCallback: makeUseResultCallback(RuntimeContext),
useResult: makeUseResult(RuntimeContext)
useResultCallback: internalUseResultCallback.make(RuntimeContext),
useResult: internalUseResult.make(RuntimeContext)
}
}
34 changes: 34 additions & 0 deletions src/TrackedProperties.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type * as Option from "@effect/data/Option"
import type * as Cause from "@effect/io/Cause"
import * as internal from "effect-react/internal/trackedProperties"
import type * as Result from "effect-react/Result"

/**
* @since 1.0.0
* @category models
*/
export interface TrackedProperties {
dataUpdatedAt: Option.Option<Date>
errorUpdatedAt: Option.Option<Date>
currentErrorCount: number
currentFailureCount: number
currentDefectCount: number
runningErrorCount: number
invocationCount: number
interruptCount: number
currentStatus: Result.Result<any, any>["_tag"]
failureCause: Cause.Cause<unknown>
}

/**
* @since 1.0.0
* @category constructors
*/
export const initial: () => TrackedProperties = internal.initial

/**
* @since 1.0.0
* @category combinators
*/
export const updateFromResult: <E, A>(self: TrackedProperties, result: Result.Result<E, A>) => void =
internal.updateFromResult
68 changes: 0 additions & 68 deletions src/hooks/useResult.ts

This file was deleted.

Loading