Skip to content

Commit

Permalink
improve(lib/builder): refine jsdoc and terms (#1270)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonkuhrt authored Nov 20, 2024
1 parent 2299e33 commit 629a1fe
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 105 deletions.
2 changes: 1 addition & 1 deletion src/client/builderExtensions/anyware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface Anyware<$Arguments extends Builder.Extension.Parameters<Builder
interceptor: AnywareLib.Interceptor.InferConstructor<
RequestPipeline['spec']
>,
) => Builder.Definition.MaterializeWithNewContext<$Arguments['chain'], $Arguments['context']>
) => Builder.Definition.MaterializeWith<$Arguments['definition'], $Arguments['context']>
}

export const builderExtensionAnyware = Builder.Extension.create<BuilderExtensionAnyware>((builder, context) => {
Expand Down
8 changes: 4 additions & 4 deletions src/client/builderExtensions/scalar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ type ScalarMethod<$Args extends Builder.Extension.Parameters<BuilderExtensionSca
decode: (value: string) => $Decoded
encode: (value: $Decoded) => string
},
): Builder.Definition.MaterializeWithNewContext<
$Args['chain'],
): Builder.Definition.MaterializeWith<
$Args['definition'],
ConfigManager.SetAtPath<
$Args['context'],
['scalars'],
Expand All @@ -53,8 +53,8 @@ type ScalarMethod<$Args extends Builder.Extension.Parameters<BuilderExtensionSca
*/
<$Scalar extends Schema.Scalar<GlobalRegistry.GetOrGeneric<$Args['context']['name']>['schema']['scalarNamesUnion']>>(
scalar: $Scalar,
): Builder.Definition.MaterializeWithNewContext<
$Args['chain'],
): Builder.Definition.MaterializeWith<
$Args['definition'],
ConfigManager.SetAtPath<
$Args['context'],
['scalars'],
Expand Down
6 changes: 3 additions & 3 deletions src/client/builderExtensions/use.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ export interface Use<$Args extends Builder.Extension.Parameters<BuilderExtension
export type UseExtensionDo<
$Args extends Builder.Extension.Parameters<BuilderExtensionUse>,
$Extension extends Extension,
> = Builder.Definition.MaterializeWithNewContext<
> = Builder.Definition.MaterializeWith<
// Apply any builder extensions.
(
ConfigManager.GetOptional<$Extension, ['builder', 'type']> extends Builder.Extension
? Builder.Definition.AddExtension<$Args['chain'], ConfigManager.GetOptional<$Extension, ['builder', 'type']>>
: $Args['chain']
? Builder.Definition.AddExtension<$Args['definition'], ConfigManager.GetOptional<$Extension, ['builder', 'type']>>
: $Args['definition']
),
// Extend context.
ConfigManager.SetMany<
Expand Down
4 changes: 2 additions & 2 deletions src/client/builderExtensions/with.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export interface With<$Args extends Builder.Extension.Parameters<BuilderExtensio
// todo fixme
// eslint-disable-next-line
// @ts-ignore Passes after generation
) => Builder.Definition.MaterializeWithNewContext<
$Args['chain'],
) => Builder.Definition.MaterializeWith<
$Args['definition'],
ConfigManager.SetProperties<
$Args['context'],
{
Expand Down
22 changes: 12 additions & 10 deletions src/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,21 @@ import { type NormalizeInput } from './Settings/InputToConfig.js'
// >
// >

export type Client<$Context extends Context> = Builder.Definition.MaterializeWithNewContext<
Builder.Definition.Create<[
BuilderExtensionInternal,
BuilderExtensionRequestMethods,
BuilderExtensionWith,
BuilderExtensionUse,
BuilderExtensionAnyware,
BuilderExtensionGql,
BuilderExtensionScalar,
]>,
export type Client<$Context extends Context> = Builder.Definition.MaterializeWith<
ClientDefinition,
$Context
>

type ClientDefinition = Builder.Definition.Create<[
BuilderExtensionInternal,
BuilderExtensionRequestMethods,
BuilderExtensionWith,
BuilderExtensionUse,
BuilderExtensionAnyware,
BuilderExtensionGql,
BuilderExtensionScalar,
]>

// dprint-ignore
type Create = <$Input extends InputStatic>(input: Exact<$Input, InputStatic>) =>
// todo fixme
Expand Down
4 changes: 2 additions & 2 deletions src/extensions/Throws/Throws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ interface BuilderExtension_<$Args extends Builder.Extension.Parameters<BuilderEx
/**
* TODO
*/
throws: () => Builder.Definition.MaterializeWithNewContext<
$Args['chain'],
throws: () => Builder.Definition.MaterializeWith<
$Args['definition'],
ConfigManager.UpdateAtKey<
$Args['context'],
'config',
Expand Down
175 changes: 119 additions & 56 deletions src/lib/builder/Definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@ import type { TypeFunction } from '../type-function/__.js'
import type { Context, Extension } from './Extension.js'

/**
* A chain. Type level function with extensions.
* When called, it returns itself with the given extensions.
* A builder definition.
* Technically it is a type level function with additional properties.
* When called, returns itself with the given extensions attached as a property.
*/
export interface Definition_<$Extensions extends [...Extension[]] = [...Extension[]]> extends TypeFunction.Fn {
extensions: $Extensions
return: Definition_<AssertExtends<this['params'], Extension[]>>
}

type InvokeDefinition<_ extends Definition_, $Arguments extends [...Extension[]]> = TypeFunction.Call<
_,
type InvokeDefinition<$Definition extends Definition_, $Arguments extends [...Extension[]]> = TypeFunction.Call<
$Definition,
$Arguments
>

/**
* An empty chain definition. Useful for creation of new chains.
* A definition literal, empty. Useful for creation of new builders.
*/
export type Empty = Definition_<[]>

Expand All @@ -29,107 +30,169 @@ export type Empty = Definition_<[]>
export type Create<$Extensions extends [...Extension[]]> = AddExtensions<Empty, $Extensions>

/**
* Extend the definition with many extensions. Refer to `Extend` for more details.
* Extend the definition with many extensions. See {@link AddExtension} for details.
*/
// dprint-ignore
export type AddExtensions<$Chain_ extends Definition_, $Extensions extends [...Extension[]]> =
export type AddExtensions<$Definition extends Definition_, $Extensions extends [...Extension[]]> =
$Extensions extends [infer $FirstExtension extends Extension, ...infer $RestExtensions extends Extension[]]
? AddExtensions<AddExtension<$Chain_, $FirstExtension>, $RestExtensions>
: $Chain_
? AddExtensions<AddExtension<$Definition, $FirstExtension>, $RestExtensions>
: $Definition

/**
* Extend the definition. During materialization the extension can contribute properties
* that make up the final builder.
*/
// dprint-ignore
export type AddExtension<$Chain_ extends Definition_, $Extension_ extends Extension> =
InvokeDefinition<$Chain_, [...$Chain_['extensions'], $Extension_]>
export type AddExtension<$definition_ extends Definition_, $Extension_ extends Extension> =
InvokeDefinition<$definition_, [...$definition_['extensions'], $Extension_]>

//
// Materialize Utilities
//

/**
* Materialize the definition using each extension's generic context type.
*
* Each extension will be invoked with its own generic context type.
* Then results will be merged to produce the builder object.
*
* All extensions' generic context types will be merged to produce
* the builder object context property.
*/
// dprint-ignore
export type MaterializeGeneric<$Chain_ extends Definition_> =
export type MaterializeGeneric<$Definition extends Definition_> =
Simplify<
Private.Add<
{
chain: $Chain_,
context: Tuple.IntersectItems<
MaterializeExtensionsGenericContext<$Chain_['extensions']>
>
definition: $Definition,
context: MaterializeGeneric_Context<$Definition>
},
Tuple.IntersectItems<
MaterializeExtensionsGeneric<$Chain_, $Chain_['extensions']>
>
MaterializeGeneric_Extensions<$Definition>
>
>

// dprint-ignore
type MaterializeExtensionsGeneric<$Chain_ extends Definition_, $Extensions extends [...Extension[]]> = {
[$Index in keyof $Extensions]: Extension.Invoke<$Extensions[$Index], {
chain: $Chain_,
context: $Extensions[$Index]['context']
}>
}
type MaterializeGeneric_Extensions<$Definition extends Definition_> =
Tuple.IntersectItems<
MaterializeGeneric_Extensions_<
$Definition,
$Definition['extensions']
>
>
// dprint-ignore
type MaterializeExtensionsGenericContext<$Extensions extends [...Extension[]]> = {
type MaterializeGeneric_Extensions_<
$Definition extends Definition_,
$Extensions extends [...Extension[]]
> = {
[$Index in keyof $Extensions]:
Extension.Invoke<$Extensions[$Index], {
definition: $Definition,
context: $Extensions[$Index]['context'],
}>
}

type MaterializeGeneric_Context<$Definition extends Definition_> = Tuple.IntersectItems<
MaterializeGeneric_Context_<$Definition['extensions']>
>
type MaterializeGeneric_Context_<$Extensions extends [...Extension[]]> = {
[$Index in keyof $Extensions]: $Extensions[$Index]['context']
}

//
//
// ---------------------------------------------------------------------------------------------
//
//

/**
* Materialize the definition using each extension's empty context type.
*
* Each extension will be invoked with its own empty context.
* Then results will be merged to produce the builder object.
*
* All extensions' empty context types will be merged to produce
* the builder object context property.
*/
// dprint-ignore
export type MaterializeSpecific<$Chain_ extends Definition_> =
export type MaterializeEmpty<$Definition extends Definition_> =
Simplify<
Private.Add<
{
chain: $Chain_,
context: Tuple.IntersectItems<
MaterializeExtensionsInitialContext<$Chain_['extensions']>
>
definition: $Definition,
context: MaterializeEmpty_Context<$Definition>,
},
Tuple.IntersectItems<
MaterializeExtensionsInitial<$Chain_, $Chain_['extensions']>
MaterializeEmpty_Extensions<$Definition, $Definition['extensions']>
>
>
>

// dprint-ignore
type MaterializeExtensionsInitial<$Chain_ extends Definition_, $Extensions extends [...Extension[]]> = {
type MaterializeEmpty_Extensions<
$Definition extends Definition_,
$Extensions extends [...Extension[]]
> = {
[$Index in keyof $Extensions]: Extension.Invoke<$Extensions[$Index], {
chain: $Chain_,
definition: $Definition,
context: $Extensions[$Index]['contextEmpty']
}>
}
// dprint-ignore
type MaterializeExtensionsInitialContext<$Extensions extends [...Extension[]]> = {
type MaterializeEmpty_Context<$Definition extends Definition_> =
Tuple.IntersectItems<
MaterializeEmpty_Context_<$Definition['extensions']>
>
// dprint-ignore
type MaterializeEmpty_Context_<$Extensions extends [...Extension[]]> = {
[$Index in keyof $Extensions]: $Extensions[$Index]['contextEmpty']
}

//
//
// ---------------------------------------------------------------------------------------------
//
//

/**
* Materialize the definition with a new context.
*
* Each extension will be invoked with the given context.
* Then results will be merged to produce the builder object.
*
* The given context will be used as-is for the builder object context property.
*/
// dprint-ignore
export type MaterializeWithNewContext<$Chain_ extends Definition_, $Context extends Context> =
// Simplify<
Private.Add<
{
chain: $Chain_,
context: $Context
},
Tuple.IntersectItems<
MaterializeExtensionsWithNewState<
$Chain_,
$Context,
$Chain_['extensions']
>
export type MaterializeWith<
$Definition extends Definition_,
$Context extends Context
> =

Private.Add<
{
definition: $Definition,
context: $Context
},
Tuple.IntersectItems<
MaterializeWith_Extensions<
$Definition,
$Definition['extensions'],
$Context
>
>
// >
>

type MaterializeExtensionsWithNewState<
$Chain_ extends Definition_,
$Context extends Context,
// dprint-ignore
type MaterializeWith_Extensions<
$Definition extends Definition_,
$Extensions extends [...Extension[]],
$Context extends Context,
> = {
[$Index in keyof $Extensions]: Extension.Invoke<
$Extensions[$Index],
{ chain: $Chain_; context: $Context }
>
[$Index in keyof $Extensions]:
Extension.Invoke<
$Extensions[$Index],
{
definition: $Definition
context: $Context
}
>
}
Loading

0 comments on commit 629a1fe

Please sign in to comment.