Fix Async docs
All checks were successful
Lint / lint (push) Successful in 12s

This commit is contained in:
Julien Valverdé
2026-03-10 19:46:44 +01:00
parent 6917c72101
commit c644f8c44b

View File

@@ -4,42 +4,21 @@ import * as React from "react"
import * as Component from "./Component.js" import * as Component from "./Component.js"
/**
* A unique symbol representing the Async component type.
* Used as a type brand to identify Async components.
*
* @experimental
*/
export const AsyncTypeId: unique symbol = Symbol.for("@effect-fc/Async/Async") export const AsyncTypeId: unique symbol = Symbol.for("@effect-fc/Async/Async")
export type AsyncTypeId = typeof AsyncTypeId
/** /**
* The type of the Async type ID symbol. * A trait for `Component`'s that allows them running asynchronous effects.
*/
export type AsyncTypeId = typeof AsyncTypeId
/**
* An Async component that supports suspense and promise-based async operations.
* Combines Component behavior with Async-specific options.
*
* @example
* ```ts
* const MyAsyncComponent = async(component({ ... }))
* ```
*/ */
export interface Async extends AsyncPrototype, AsyncOptions {} export interface Async extends AsyncPrototype, AsyncOptions {}
/**
* The prototype object for Async components containing their methods and behaviors.
*/
export interface AsyncPrototype { export interface AsyncPrototype {
/**
* The Async type ID brand.
*/
readonly [AsyncTypeId]: AsyncTypeId readonly [AsyncTypeId]: AsyncTypeId
} }
/** /**
* Configuration options for Async components. * Configuration options for `Async` components.
*/ */
export interface AsyncOptions { export interface AsyncOptions {
/** /**
@@ -50,34 +29,14 @@ export interface AsyncOptions {
} }
/** /**
* Props for Async components, extending React.SuspenseProps without the children prop. * Props for `Async` components.
* The children are managed internally by the Async component.
*/ */
export type AsyncProps = Omit<React.SuspenseProps, "children"> export type AsyncProps = Omit<React.SuspenseProps, "children">
/**
* The prototype object for Async components.
* Provides the `asFunctionComponent` method for converting async components to React function components.
*
* @internal Use the `async` function to create Async components instead of accessing this directly.
*/
export const AsyncPrototype: AsyncPrototype = Object.freeze({ export const AsyncPrototype: AsyncPrototype = Object.freeze({
[AsyncTypeId]: AsyncTypeId, [AsyncTypeId]: AsyncTypeId,
/**
* Converts an Async component to a React function component.
*
* @param runtimeRef - A reference to the Effect runtime for executing effects
* @returns A React function component that suspends while the async operation is executing
*
* @example
* ```ts
* const MyComponent = component({ ... })
* const AsyncMyComponent = async(MyComponent)
* const FunctionComponent = AsyncMyComponent.asFunctionComponent(runtimeRef)
* ```
*/
asFunctionComponent<P extends {}, A extends React.ReactNode, E, R>( asFunctionComponent<P extends {}, A extends React.ReactNode, E, R>(
this: Component.Component<P, A, E, R> & Async, this: Component.Component<P, A, E, R> & Async,
runtimeRef: React.RefObject<Runtime.Runtime<Exclude<R, Scope.Scope>>>, runtimeRef: React.RefObject<Runtime.Runtime<Exclude<R, Scope.Scope>>>,
@@ -102,14 +61,8 @@ export const AsyncPrototype: AsyncPrototype = Object.freeze({
} as const) } as const)
/** /**
* An equivalence function for comparing AsyncProps that ignores the `fallback` property. * An equivalence function for comparing `AsyncProps` that ignores the `fallback` property.
* Useful for memoization and re-render optimization. * Used by default by async components with `Memoized.memoized` applied.
*
* @param self - The first props object to compare
* @param that - The second props object to compare
* @returns `true` if the props are equivalent (excluding fallback), `false` otherwise
*
* @internal
*/ */
export const defaultPropsEquivalence: Equivalence.Equivalence<AsyncProps> = ( export const defaultPropsEquivalence: Equivalence.Equivalence<AsyncProps> = (
self: Record<string, unknown>, self: Record<string, unknown>,
@@ -136,42 +89,22 @@ export const defaultPropsEquivalence: Equivalence.Equivalence<AsyncProps> = (
} }
/**
* A type guard to check if a value is an Async component.
*
* @param u - The value to check
* @returns `true` if the value is an Async component, `false` otherwise
*
* @example
* ```ts
* if (isAsync(component)) {
* // component is an Async component
* }
* ```
*/
export const isAsync = (u: unknown): u is Async => Predicate.hasProperty(u, AsyncTypeId) export const isAsync = (u: unknown): u is Async => Predicate.hasProperty(u, AsyncTypeId)
/** /**
* Converts a Component into an Async component that supports suspense and promise-based async operations. * Converts a Component into an `Async` component that supports running asynchronous effects.
*
* The resulting component will wrap the original component with React.Suspense,
* allowing async Effect computations to suspend and resolve properly.
* *
* Note: The component cannot have a prop named "promise" as it's reserved for internal use. * Note: The component cannot have a prop named "promise" as it's reserved for internal use.
* *
* @param self - The component to convert to an Async component * @param self - The component to convert to an Async component
* @returns An Async component with the same body, error, and context types as the input * @returns A new Async component with the same body, error, and context types as the input
* *
* @example * @example
* ```ts * ```ts
* const MyComponent = component({ * const MyAsyncComponent = Component.make("MyComponent")(function*() { ... }).pipe(
* body: (props) => // ... * Async.async,
* }) * )
*
* const AsyncMyComponent = async(MyComponent)
* ``` * ```
*
* @throws Will produce a type error if the component has a "promise" prop
*/ */
export const async = <T extends Component.Component<any, any, any, any>>( export const async = <T extends Component.Component<any, any, any, any>>(
self: T & ( self: T & (
@@ -207,14 +140,19 @@ export const async = <T extends Component.Component<any, any, any, any>>(
* *
* @example * @example
* ```ts * ```ts
* const AsyncComponent = async(myComponent) * // Curried
* const MyAsyncComponent = Component.make("MyComponent")(function*() { ... }).pipe(
* Async.async,
* Async.withOptions({ defaultFallback: <p>Loading...</p> }),
* )
* *
* // Uncurried * // Uncurried
* const configured = withOptions(AsyncComponent, { defaultFallback: <Loading /> }) * const MyAsyncComponent = Component.make("MyComponent")(function*() { ... }).pipe(
* * Async.async,
* // Curried * )
* const configurer = withOptions({ defaultFallback: <Loading /> }) * const MyAsyncComponentWithOptions = Async.withOptions(MyAsyncComponent, {
* const configured = configurer(AsyncComponent) * defaultFallback: <p>Loading...</p>,
* })
* ``` * ```
*/ */
export const withOptions: { export const withOptions: {