Suspense refactoring
All checks were successful
Lint / lint (push) Successful in 11s

This commit is contained in:
Julien Valverdé
2025-07-21 11:19:55 +02:00
parent f7534d63f8
commit 30bd1a0180

View File

@@ -368,14 +368,21 @@ export const memoWithOptions: {
export interface Suspense { export interface Suspense {
readonly suspense: true readonly suspense: true
readonly suspenseOptions: Suspense.Options
} }
export type SuspenseProps = Omit<React.SuspenseProps, "children"> export namespace Suspense {
export interface Options {
readonly defaultFallback?: React.ReactNode
}
export type Props = Omit<React.SuspenseProps, "children">
}
export const suspense = <T extends Component<any, any, P>, P extends {}>( export const suspense = <T extends Component<any, any, P>, P extends {}>(
self: ExcludeKeys<T, keyof Suspense> & Component<any, any, ExcludeKeys<P, keyof SuspenseProps>> self: ExcludeKeys<T, keyof Suspense> & Component<any, any, ExcludeKeys<P, keyof Suspense.Props>>
): T & Suspense => Object.setPrototypeOf( ): T & Suspense => Object.setPrototypeOf(
{ ...self, suspense: true }, { ...self, suspense: true, suspenseOptions: {} },
Object.getPrototypeOf(self), Object.getPrototypeOf(self),
) )
@@ -383,7 +390,7 @@ export const suspense = <T extends Component<any, any, P>, P extends {}>(
export const useFC: { export const useFC: {
<E, R, P extends {}>( <E, R, P extends {}>(
self: Component<E, R, P> & Suspense self: Component<E, R, P> & Suspense
): Effect.Effect<React.FC<P & SuspenseProps>, never, Exclude<R, Scope.Scope>> ): Effect.Effect<React.FC<P & Suspense.Props>, never, Exclude<R, Scope.Scope>>
<E, R, P extends {}>( <E, R, P extends {}>(
self: Component<E, R, P> self: Component<E, R, P>
): Effect.Effect<React.FC<P>, never, Exclude<R, Scope.Scope>> ): Effect.Effect<React.FC<P>, never, Exclude<R, Scope.Scope>>
@@ -408,14 +415,14 @@ export const useFC: {
return React.use(props.promise) return React.use(props.promise)
}, },
SuspenseInner => ({ fallback, name, ...props }: P & SuspenseProps) => { SuspenseInner => ({ fallback, name, ...props }: P & Suspense.Props) => {
const promise = Runtime.runPromise(runtimeRef.current)( const promise = Runtime.runPromise(runtimeRef.current)(
Effect.provideService(self.body(props as P), Scope.Scope, scope) Effect.provideService(self.body(props as P), Scope.Scope, scope)
) )
return React.createElement( return React.createElement(
React.Suspense, React.Suspense,
{ fallback, name }, { fallback: fallback ?? self.suspenseOptions.defaultFallback, name },
React.createElement(SuspenseInner, { promise }), React.createElement(SuspenseInner, { promise }),
) )
}, },
@@ -437,7 +444,7 @@ export const useFC: {
export const use: { export const use: {
<E, R, P extends {}>( <E, R, P extends {}>(
self: Component<E, R, P> & Suspense, self: Component<E, R, P> & Suspense,
fn: (Component: React.FC<P & SuspenseProps>) => React.ReactNode, fn: (Component: React.FC<P & Suspense.Props>) => React.ReactNode,
): Effect.Effect<React.ReactNode, never, Exclude<R, Scope.Scope>> ): Effect.Effect<React.ReactNode, never, Exclude<R, Scope.Scope>>
<E, R, P extends {}>( <E, R, P extends {}>(
self: Component<E, R, P>, self: Component<E, R, P>,
@@ -451,13 +458,13 @@ export const withRuntime: {
<T extends Component<any, R, any>, R>( <T extends Component<any, R, any>, R>(
context: React.Context<Runtime.Runtime<R>>, context: React.Context<Runtime.Runtime<R>>,
): (self: T) => React.FC<T extends Suspense ): (self: T) => React.FC<T extends Suspense
? Component.Props<T> & SuspenseProps ? Component.Props<T> & Suspense.Props
: Component.Props<T> : Component.Props<T>
> >
<E, R, P extends {}>( <E, R, P extends {}>(
self: Component<E, R, P> & Suspense, self: Component<E, R, P> & Suspense,
context: React.Context<Runtime.Runtime<R>>, context: React.Context<Runtime.Runtime<R>>,
): React.FC<P & SuspenseProps> ): React.FC<P & Suspense.Props>
<E, R, P extends {}>( <E, R, P extends {}>(
self: Component<E, R, P>, self: Component<E, R, P>,
context: React.Context<Runtime.Runtime<R>>, context: React.Context<Runtime.Runtime<R>>,