/* eslint-disable prefer-arrow-callback */ import React, { Fragment, memo, type ComponentType, type ReactNode } from 'react'; type PipelineProps = Readonly<{ request: R }> & P; type InnerPipelineProps = PipelineProps & Readonly<{ originalRequest: R }>; type NextComponent = ComponentType

>; type ComposedComponent = ComponentType>; type StageComponent = ComponentType< PipelineProps & { Next: NextComponent; } >; type PipelineComponent = ComponentType>; const Passthrough = memo(function PipelinePassthrough({ children }: Readonly<{ children?: ReactNode | undefined }>) { return {children}; }); export function composePipeline< Request, Props extends { children?: ReactNode | undefined } = { children?: ReactNode | undefined } >(stages: StageComponent[], PassthroughComponent = Passthrough): PipelineComponent { const ComposedPipeline = stages.reduceRight>((Next, Stage) => { const StageMemo = memo(Stage); const StageWrapper = memo>(({ originalRequest, request, ...innerRest }) => { const resolvedRequest = request ?? originalRequest; return ( } request={resolvedRequest} {...(innerRest as Props)} originalRequest={originalRequest} /> ); }); StageWrapper.displayName = `PipelineStage(Memo(${Stage.displayName || Stage.name}))`; return StageWrapper; }, PassthroughComponent); const Pipeline: PipelineComponent = function Pipeline(props: PipelineProps) { const { request, ...restProps } = props; return ; }; Pipeline.displayName = 'Pipeline'; return memo(Pipeline); } export type { NextComponent, PipelineComponent, PipelineProps, StageComponent };