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
8 changes: 1 addition & 7 deletions docs/typescript-examples/pipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,7 @@ const block3 = de.pipe({
return params;
},
after: ({ result }) => {
if (typeof result === 'number') {
return result;
} else if ('b1' in result) {
return result.b1;
} else if ('b2' in result) {
return result.b2;
}
return result * 2;
},
},
});
Expand Down
13 changes: 10 additions & 3 deletions lib/arrayBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
First,
InferResultFromBlock,
InferParamsInFromBlock,
IsRequiredBlock,
Tail,
DescriptBlockOptions,
} from './types';
Expand All @@ -15,17 +16,21 @@
import type { DescriptBlockDeps } from './depsDomain';
import type DepsDomain from './depsDomain';

type InferArrayElement<B> = B extends IsRequiredBlock
? InferResultFromBlock<B>
: InferResultFromBlock<B> | DescriptError;

export type GetArrayBlockResult<T extends ReadonlyArray<unknown>> = {
0: never;
1: [ InferResultFromBlock<First<T>> | DescriptError ];
2: [ InferResultFromBlock<First<T>> | DescriptError, ...GetArrayBlockResult<Tail<T>> ];
1: [ InferArrayElement<First<T>> ];
2: [ InferArrayElement<First<T>>, ...GetArrayBlockResult<Tail<T>> ];
}[ T extends [] ? 0 : T extends ((readonly [ any ]) | [ any ]) ? 1 : 2 ];

Check warning on line 27 in lib/arrayBlock.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected any. Specify a different type

Check warning on line 27 in lib/arrayBlock.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected any. Specify a different type

export type GetArrayBlockParamsUnion<T extends ReadonlyArray<unknown>> = {
0: never;
1: First<T>;
2: First<T> & GetArrayBlockParamsUnion<Tail<T>>;
}[ T extends [] ? 0 : T extends ((readonly [ any ]) | [ any ]) ? 1 : 2 ];

Check warning on line 33 in lib/arrayBlock.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected any. Specify a different type

Check warning on line 33 in lib/arrayBlock.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected any. Specify a different type

type GetArrayBlockParamsMap<T extends ReadonlyArray<unknown>> = {
[ P in keyof T ]: InferParamsInFromBlock<T[ P ]>;
Expand Down Expand Up @@ -57,6 +62,7 @@
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = GetArrayBlockParams<Block>,
IsRequired extends boolean = boolean,
> extends CompositeBlock<
Context,
ArrayBlockDefinition<Block>,
Expand All @@ -68,7 +74,8 @@
BeforeResultOut,
AfterResultOut,
ErrorResultOut,
Params
Params,
IsRequired
> {

extend<
Expand Down
2 changes: 2 additions & 0 deletions lib/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = ParamsOut,
IsRequired extends boolean = boolean,
> {
declare readonly __resultType: InferResultOrResult<ResultOut>;
declare readonly __isRequired: IsRequired;

protected block: CustomBlock;
protected options: BlockOptions<Context, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
Expand Down Expand Up @@ -442,7 +444,7 @@
blockCancel.throwIfCancelled();

if (typeof step.after === 'function') {
resultAfter = await step.after({ cancel, params, context, deps, dep, result: (resultBefore || resultBlock) as any });

Check warning on line 447 in lib/block.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected any. Specify a different type
blockCancel.throwIfCancelled();

if (resultAfter instanceof BaseBlock) {
Expand Down
4 changes: 3 additions & 1 deletion lib/compositeBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ abstract class CompositeBlock<
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = ParamsOut,
IsRequired extends boolean = boolean,
> extends BaseBlock<
Context,
CustomBlock,
Expand All @@ -39,7 +40,8 @@ abstract class CompositeBlock<
BeforeResultOut,
AfterResultOut,
ErrorResultOut,
Params
Params,
IsRequired
> {

protected blocks: Array<{
Expand Down
4 changes: 3 additions & 1 deletion lib/firstBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class FirstBlock<
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = GetFirstBlockParams<Block>,
IsRequired extends boolean = boolean,
> extends CompositeBlock<
Context,
FirstBlockDefinition<Block>,
Expand All @@ -79,7 +80,8 @@ class FirstBlock<
BeforeResultOut,
AfterResultOut,
ErrorResultOut,
Params
Params,
IsRequired
> {

extend<
Expand Down
20 changes: 12 additions & 8 deletions lib/functionBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class FunctionBlock<
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = never extends InferParamsOutFromBlock<BlockResult> ? ParamsOut : InferParamsOutFromBlock<BlockResult>,
IsRequired extends boolean = boolean,
> extends BaseBlock<
Context,
FunctionBlockDefinition<Context, ParamsOut, BlockResult>,
Expand All @@ -40,7 +41,8 @@ class FunctionBlock<
BeforeResultOut,
AfterResultOut,
ErrorResultOut,
Params
Params,
IsRequired
> {

protected initBlock(block: FunctionBlockDefinition<Context, ParamsOut, BlockResult>) {
Expand Down Expand Up @@ -104,6 +106,7 @@ class FunctionBlock<
ExtendedBeforeResultOut = unknown,
ExtendedAfterResultOut = unknown,
ExtendedErrorResultOut = unknown,
const ExtendedIsRequired extends boolean = IsRequired,
>({ options }: {
options: DescriptBlockOptions<
Context,
Expand All @@ -113,14 +116,15 @@ class FunctionBlock<
ExtendedAfterResultOut,
ExtendedErrorResultOut,
ExtendedParams
>;
> & { required?: ExtendedIsRequired };
}) {
return new FunctionBlock({
block: this.extendBlock(this.block) as typeof this.block,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
options: this.extendOptions(this.options, options) as typeof options,
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const result = new FunctionBlock({ block: this.extendBlock(this.block) as any, options: this.extendOptions(this.options, options) as any });
return result as unknown as FunctionBlock<
Context, ExtendedParamsOut, ExtendedBlockResult,
BlockResultOut<ExtendedBlockResult, ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut>,
ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut, ExtendedParams, ExtendedIsRequired
>;
}
}

Expand Down
4 changes: 3 additions & 1 deletion lib/httpBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ class HttpBlock<
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = ParamsOut,
IsRequired extends boolean = boolean,
> extends Block<
Context,
DescriptHttpBlockDescription<ParamsOut, Context, HttpResult>,
Expand All @@ -198,7 +199,8 @@ class HttpBlock<
BeforeResultOut,
AfterResultOut,
ErrorResultOut,
Params
Params,
IsRequired
> {

extend<
Expand Down
30 changes: 18 additions & 12 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,15 @@ const func = function<
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = ParamsOut,
const IsRequired extends boolean = false,
>({ block, options }: {
block: FunctionBlockDefinition<Context, ParamsOut, BlockResult>;
options?: DescriptBlockOptions<
Context, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params
>;
> & { required?: IsRequired };
} & ([ ExtractBadNestedParams<BlockResult, ParamsOut> ] extends [ never ] ? unknown : ExtractBadNestedParams<BlockResult, ParamsOut>)) {
return new FunctionBlock<
Context, ParamsOut, BlockResult, ResultOut, BeforeResultOut, AfterResultOut, ErrorResultOut, Params
Context, ParamsOut, BlockResult, ResultOut, BeforeResultOut, AfterResultOut, ErrorResultOut, Params, IsRequired
>({ block, options });
};
const array = function<
Expand All @@ -67,11 +68,12 @@ const array = function<
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = GetArrayBlockParams<Block>,
const IsRequired extends boolean = false,
>({ block, options }: {
block: ArrayBlockDefinition<Block>;
options?: DescriptBlockOptions<Context, NoInfer<ParamsOut>, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
options?: DescriptBlockOptions<Context, NoInfer<ParamsOut>, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params> & { required?: IsRequired };
}) {
return new ArrayBlock<Context, Block, ResultOut, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>({ block, options });
return new ArrayBlock<Context, Block, ResultOut, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params, IsRequired>({ block, options });
};
const object = function<
Context,
Expand All @@ -84,11 +86,12 @@ const object = function<
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = GetObjectBlockParams<Blocks>,
const IsRequired extends boolean = false,
>({ block, options }: {
block?: ObjectBlockDefinition<Blocks>;
options?: DescriptBlockOptions<Context, NoInfer<ParamsOut>, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
options?: DescriptBlockOptions<Context, NoInfer<ParamsOut>, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params> & { required?: IsRequired };
} = {}) {
return new ObjectBlock<Context, Blocks, ResultOut, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>({ block, options });
return new ObjectBlock<Context, Blocks, ResultOut, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params, IsRequired>({ block, options });
};
const http = function<
Context,
Expand All @@ -101,12 +104,13 @@ const http = function<
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = ParamsOut,
const IsRequired extends boolean = false,
>({ block, options }: {
block?: DescriptHttpBlockDescription<ParamsOut, Context, IntermediateResult>;
options?: DescriptBlockOptions<Context, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
options?: DescriptBlockOptions<Context, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params> & { required?: IsRequired };
}) {
return new HttpBlock<
Context, ParamsOut, IntermediateResult, ResultOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params
Context, ParamsOut, IntermediateResult, ResultOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params, IsRequired
>({ block, options });
};

Expand All @@ -120,11 +124,12 @@ const first = function<
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = GetFirstBlockParams<Block>,
const IsRequired extends boolean = false,
>({ block, options }: {
block: FirstBlockDefinition<Block>;
options?: DescriptBlockOptions<Context, NoInfer<ParamsOut>, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
options?: DescriptBlockOptions<Context, NoInfer<ParamsOut>, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params> & { required?: IsRequired };
}) {
return new FirstBlock<Context, Block, ResultOut, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>({ block, options });
return new FirstBlock<Context, Block, ResultOut, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params, IsRequired>({ block, options });
};

const pipe = function<
Expand All @@ -137,11 +142,12 @@ const pipe = function<
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = GetPipeBlockParams<Block>,
const IsRequired extends boolean = false,
>({ block, options }: {
block: PipeBlockDefinition<Block>;
options?: DescriptBlockOptions<Context, NoInfer<ParamsOut>, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
options?: DescriptBlockOptions<Context, NoInfer<ParamsOut>, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params> & { required?: IsRequired };
}) {
return new PipeBlock<Context, Block, ResultOut, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>({ block, options });
return new PipeBlock<Context, Block, ResultOut, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params, IsRequired>({ block, options });
};

const isBlock = function(block: any) {
Expand Down
10 changes: 7 additions & 3 deletions lib/objectBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import CompositeBlock from './compositeBlock';
import type { DescriptError } from './error';
import { createError, ERROR_ID } from './error';
import type BaseBlock from './block';
import type { InferParamsInFromBlock, DescriptBlockOptions, BlockResultOut, UnionToIntersection, InferResultFromBlock } from './types';
import type { InferParamsInFromBlock, DescriptBlockOptions, BlockResultOut, UnionToIntersection, InferResultFromBlock, IsRequiredBlock } from './types';
import type ContextClass from './context';
import type Cancel from './cancel';
import type { DescriptBlockDeps } from './depsDomain';
Expand All @@ -18,7 +18,9 @@ export type InferResultFromObjectBlocks<Block> = Block extends BaseBlock<
Block;

export type GetObjectBlockResult<T extends Record<string, any>> = {
[ P in keyof T ]: InferResultFromBlock<T[P]> | DescriptError
[ P in keyof T ]: T[P] extends IsRequiredBlock
? InferResultFromBlock<T[P]>
: InferResultFromBlock<T[P]> | DescriptError
};

export type GetObjectBlockParams<
Expand Down Expand Up @@ -50,6 +52,7 @@ class ObjectBlock<
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = GetObjectBlockParams<Blocks>,
IsRequired extends boolean = boolean,
> extends CompositeBlock<
Context,
ObjectBlockDefinition<Blocks>,
Expand All @@ -61,7 +64,8 @@ class ObjectBlock<
BeforeResultOut,
AfterResultOut,
ErrorResultOut,
Params
Params,
IsRequired
> {

protected initBlock(object: ObjectBlockDefinition<Blocks>) {
Expand Down
15 changes: 5 additions & 10 deletions lib/pipeBlock.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import CompositeBlock from './compositeBlock';
import { ERROR_ID, createError } from './error';
import type { DescriptError } from './error';
import type BaseBlock from './block';
import type {
BlockResultOut,
First,
Last,
InferResultFromBlock,
InferParamsInFromBlock,
Tail,
Expand Down Expand Up @@ -32,21 +32,14 @@ export type GetPipeBlockParams<
PU = GetPipeBlockParamsUnion<PA>,
> = PU;

type GetPipeBlockResultUnion<T extends ReadonlyArray<unknown>> = {
0: never;
1: First<T> | DescriptError;
2: First<T> | DescriptError | GetPipeBlockResultUnion<Tail<T>>;
}[ T extends [] ? 0 : T extends ((readonly [ any ]) | [ any ]) ? 1 : 2 ];

type GetPipeBlockResultMap<T extends ReadonlyArray<unknown>> = {
[ P in keyof T ]: InferResultFromBlock<T[ P ]>;
};

export type GetPipeBlockResult<
T extends ReadonlyArray<unknown>,
PA extends ReadonlyArray<unknown> = GetPipeBlockResultMap<T>,
PU = GetPipeBlockResultUnion<PA>,
> = PU;
> = Last<PA>;

export type PipeBlockDefinition<T> = {
[ P in keyof T ]: T[ P ] extends BaseBlock<
Expand All @@ -68,6 +61,7 @@ class PipeBlock<
AfterResultOut = unknown,
ErrorResultOut = unknown,
Params = GetPipeBlockParams<Block>,
IsRequired extends boolean = boolean,
> extends CompositeBlock<
Context,
PipeBlockDefinition<Block>,
Expand All @@ -79,7 +73,8 @@ class PipeBlock<
BeforeResultOut,
AfterResultOut,
ErrorResultOut,
Params
Params,
IsRequired
> {

extend<
Expand Down
18 changes: 18 additions & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,27 @@ export type InferResultOrResultOnce<Result> = Result extends BaseBlock<
infer BlockResult, infer BeforeResultOut, infer AfterResultOut, infer ErrorResultOut, infer Params
> ? ResultOut : Result;

export type IsRequiredBlock = { readonly __isRequired: true };

export type InferResultFromBlock<Type> = Type extends BaseBlock<
// eslint-disable-next-line @typescript-eslint/no-unused-vars
infer Context, infer CustomBlock, infer ParamsOut, infer ResultOut, infer IntermediateResult,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
infer BlockResult, infer BeforeResultOut, infer AfterResultOut, infer ErrorResultOut, infer Params
> ? InferResultOrResult<ResultOut> : never;

export type DeepResolveResult<T> =
// eslint-disable-next-line @typescript-eslint/no-explicit-any
T extends BaseBlock<any, any, any, infer ResultOut, any, any, any, any, any, any>
? DeepResolveResult<InferResultOrResult<ResultOut>>
: T extends DescriptError
? DescriptError
: T extends Record<string, unknown>
? { [K in keyof T]: DeepResolveResult<T[K]> }
: T;

export type DeepInferResultFromBlock<T> = DeepResolveResult<InferResultFromBlock<T>>;

export type InferParamsInFromBlock<Type> = Type extends BaseBlock<
// eslint-disable-next-line @typescript-eslint/no-unused-vars
infer Context, infer CustomBlock, infer ParamsOut, infer ResultOut, infer IntermediateResult,
Expand Down Expand Up @@ -161,6 +175,10 @@ export type Tail<T> =
// eslint-disable-next-line @typescript-eslint/no-unused-vars
T extends readonly [ infer First, ...infer Rest ] | [ infer First, ...infer Rest ] ? Rest : never;

export type Last<T> =
// eslint-disable-next-line @typescript-eslint/no-unused-vars
T extends readonly [ ...infer Rest, infer L ] | [ ...infer Rest, infer L ] ? L : never;

export type Equal<A, B> = A extends B ? (B extends A ? A : never) : never;

export type DepsIds = Array<DescriptBlockId<any> | UntypedId>;
Expand Down
Loading
Loading