Skip to content

Commit

Permalink
refactor: move typeHooks to ctx level
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonkuhrt committed Oct 31, 2024
1 parent c2d0caf commit d7d0752
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 57 deletions.
4 changes: 2 additions & 2 deletions src/extensions/SchemaErrors/tests/SchemaError.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ const g = GraffleSchemaErrors.create({ schema }).use(SchemaErrors())

// todo move test to test suite for .use method
test(`config type is augmented with type hook`, () => {
expectTypeOf<typeof g._.config.typeHooks.onRequestResult>().toMatchTypeOf<[Extension.Hooks.OnRequestResult]>()
expectTypeOf<typeof g._.typeHooks.onRequestResult>().toMatchTypeOf<[Extension.Hooks.OnRequestResult]>()
})

test(`config type is augmented with type hook after "with"`, () => {
const g2 = g.with({ output: { defaults: { errorChannel: `throw` } } })
expectTypeOf<typeof g2._.config.typeHooks.onRequestResult>().toMatchTypeOf<[Extension.Hooks.OnRequestResult]>()
expectTypeOf<typeof g2._.typeHooks.onRequestResult>().toMatchTypeOf<[Extension.Hooks.OnRequestResult]>()
})

const resultFieldSelect =
Expand Down
4 changes: 0 additions & 4 deletions src/layers/6_client/Settings/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { RequireProperties } from '../../../lib/prelude.js'
import type { TransportHttp, TransportMemory } from '../../../requestPipeline/Transport.js'
import type { GlobalRegistry } from '../../../types/GlobalRegistry/GlobalRegistry.js'
import type { SchemaDrivenDataMap } from '../../../types/SchemaDrivenDataMap/__.js'
import type { Extension } from '../extension/extension.js'
import type { TransportHttpInput } from '../transportHttp/request.js'
import type { InputStatic } from './Input.js'

Expand Down Expand Up @@ -112,9 +111,6 @@ export type Config = {
* The initial input that was given to derive this config.
*/
initialInput: InputStatic
typeHooks: {
onRequestResult: Extension.Hooks.OnRequestResult[]
}
name: GlobalRegistry.ClientNames // todo remove? it is in context
output: OutputConfig
schemaMap: SchemaDrivenDataMap | null
Expand Down
5 changes: 0 additions & 5 deletions src/layers/6_client/Settings/InputToConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ export type NormalizeInput<$Input extends InputStatic> = {
name: HandleName<$Input>
schemaMap: ConfigManager.OrDefault<$Input['schemaMap'], null>
transport: HandleTransport<$Input>
typeHooks: {
property: []
onRequestDocumentRootType: []
onRequestResult: []
},
output: {
defaults: {
errorChannel: ConfigManager.ReadOrDefault<$Input, ['output', 'defaults', 'errorChannel'], 'throw'>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import type { Transport, TransportMemory } from '../../../../requestPipeline/Transport.js'
import type { GlobalRegistry } from '../../../../types/GlobalRegistry/GlobalRegistry.js'
import type { TransportHttpInput } from '../../transportHttp/request.js'
import type { Config } from '../Config.js'
import type { NormalizeInput } from '../InputToConfig.js'
import type { OutputInput } from './output.js'

// dprint-ignore
Expand All @@ -25,10 +23,3 @@ export type IncrementableInputContext = {
type: Transport
}
}

// dprint-ignore
export type AddIncrementalInput<$Config extends Config, $Input extends WithInput> =
& Omit<NormalizeInput<$Config['initialInput'] & $Input>, 'typeHooks'>
& {
typeHooks: $Config['typeHooks']
}
37 changes: 15 additions & 22 deletions src/layers/6_client/client.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Chain } from '../../lib/chain/__.js'
import { proxyGet } from '../../lib/prelude.js'
import { Schema } from '../../types/Schema/__.js'
import { type Context, type ContextWithoutConfig, createContext } from './context.js'
import { type Context, type ContextWithoutConfig, createContext, type TypeHooksEmpty } from './context.js'
import { type Use_, useProperties } from './extension/use.js'
import { type Gql_, gqlProperties } from './gql/gql.js'
import { type Anyware_, AnywareExtension } from './properties/anyware.js'
Expand All @@ -28,14 +28,6 @@ export type Client<$Context extends Context> = Chain.Definition.MaterializeWithN
$Context
>

// export type IncrementWthNewConfig<
// $Parameters extends FnParametersProperty,
// $ConfigNew extends Context['config'],
// > = Chain.IncrementWthNewContext<
// $Parameters,
// ConfigManager.SetProperty<$Parameters['state']['context'], 'config', $ConfigNew>
// >

// dprint-ignore
type Create = <$Input extends InputStatic>(input: $Input) =>
// todo fixme
Expand All @@ -48,43 +40,44 @@ type Create = <$Input extends InputStatic>(input: $Input) =>
retry: null
extensions: []
scalars: {}
typeHooks: TypeHooksEmpty,
}>

export const create: Create = (input) => {
const initialState = createContext({
const initialContext = createContext({
name: input.name ?? `default`, // todo import from shared constants
extensions: [],
scalars: Schema.Scalar.Registry.empty,
retry: null,
input,
})
return createWithState(initialState)
return createWithContext(initialContext)
}

export const createWithState = (
initialState: ContextWithoutConfig,
export const createWithContext = (
initialContext: ContextWithoutConfig,
) => {
const state = createContext(initialState)
const context = createContext(initialContext)

// @ts-expect-error ignoreme
const clientDirect: Client = {
_: state,
...gqlProperties(createWithState, state),
...withProperties(createWithState, state),
...useProperties(createWithState, state),
...AnywareExtension(createWithState, state),
...scalarProperties(createWithState, state),
_: context,
...gqlProperties(createWithContext, context),
...withProperties(createWithContext, context),
...useProperties(createWithContext, context),
...AnywareExtension(createWithContext, context),
...scalarProperties(createWithContext, context),
}

// todo test that access to this works without generation in a unit like test. We discovered bug and covered this in an e2e test.
Object.assign(clientDirect, {
...requestMethodsProperties(createWithState, state),
...requestMethodsProperties(createWithContext, context),
})

const clientProxy = proxyGet(clientDirect, ({ path, property }) => {
// eslint-disable-next-line
// @ts-ignore fixme "Type instantiation is excessively deep and possibly infinite"
const onGetHandlers = state.extensions.map(_ => _.onBuilderGet).filter(_ => _ !== undefined)
const onGetHandlers = context.extensions.map(_ => _.onBuilderGet).filter(_ => _ !== undefined)

for (const onGetHandler of onGetHandlers) {
const result = onGetHandler({
Expand Down
7 changes: 4 additions & 3 deletions src/layers/6_client/clientPrefilled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { type Exact } from '../../lib/prelude.js'
import type { GlobalRegistry } from '../../types/GlobalRegistry/GlobalRegistry.js'
import { type Schema } from '../../types/Schema/__.js'
import type { SchemaDrivenDataMap } from '../../types/SchemaDrivenDataMap/__.js'
import { type Client, createWithState } from './client.js'
import { createContext } from './context.js'
import { type Client, createWithContext } from './client.js'
import { createContext, type TypeHooksEmpty } from './context.js'
import type { InputBase } from './Settings/Input.js'
import type { NormalizeInput } from './Settings/InputToConfig.js'

Expand All @@ -28,7 +28,7 @@ export const createPrefilled: CreatePrefilled = (name, schemaMap, scalars, schem
},
})

const instance = createWithState(initialState)
const instance = createWithContext(initialState)

return instance
}
Expand Down Expand Up @@ -62,4 +62,5 @@ Client<{
extensions: []
// @ts-expect-error fixme - TS cannot figure out that name input meets constraint
config: NormalizeInput<$Input & { name: $Name; schemaMap: SchemaDrivenDataMap }>
typeHooks: TypeHooksEmpty
}>
16 changes: 14 additions & 2 deletions src/layers/6_client/context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Anyware } from '../../lib/anyware/__.js'
import type { Chain } from '../../lib/chain/__.js'
import type { RequestPipeline } from '../../requestPipeline/__.js'
import type { Schema } from '../../types/Schema/__.js'
import type { Extension } from './extension/extension.js'
Expand All @@ -13,6 +14,17 @@ export interface Context {
retry: Anyware.Extension2<RequestPipeline.Core, { retrying: true }> | null
extensions: Extension[]
scalars: Schema.Scalar.Registry
typeHooks: {
onRequestResult: Extension.Hooks.OnRequestResult[]
property: Chain.Extension[]
onRequestDocumentRootType: Extension.Hooks.OnRequestDocumentRootType[]
}
}

export type TypeHooksEmpty = {
property: []
onRequestDocumentRootType: []
onRequestResult: []
}

export const createContext = (contextWithoutConfig: ContextWithoutConfig): Context => {
Expand All @@ -24,7 +36,7 @@ export const createContext = (contextWithoutConfig: ContextWithoutConfig): Conte
const configFound = config ?? inputToConfig(contextWithoutConfig.input)
return configFound as any
},
}
} as Context
}

export type ContextWithoutConfig = Omit<Context, 'config'>
export type ContextWithoutConfig = Omit<Context, 'config' | 'typeHooks'>
2 changes: 1 addition & 1 deletion src/layers/6_client/extension/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export type RunTypeHookOnRequestResult<
$Context extends Context,
$Params extends Extension.Hooks.OnRequestResult.Params,
> = AssertExtends<
TypeFunction.CallPipeline<$Context['config']['typeHooks']['onRequestResult'], $Params>,
TypeFunction.CallPipeline<$Context['typeHooks']['onRequestResult'], $Params>,
Extension.Hooks.OnRequestResult.Params
>

Expand Down
8 changes: 3 additions & 5 deletions src/layers/6_client/extension/use.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,17 @@ export interface Use<$Args extends Chain.Extension.Parameters<Use_>> {
(
$Extension['typeHooks']['property'] extends Chain.Extension
? Chain.Definition.Extend<$Args['chain'], $Extension['typeHooks']['property']>
// ? $Args['chain']
: $Args['chain']
),
// If the extension adds type hooks, merge them into the config.
ConfigManager.SetAtPath<
$Args['context'],
['config', 'typeHooks', 'onRequestResult'],
['typeHooks', 'onRequestResult'],
(
$Extension['typeHooks']['onRequestResult'] extends undefined
? $Args['context']['config']['typeHooks']['onRequestResult']
$Extension['typeHooks']['onRequestResult'] extends undefined ? $Args['context']['typeHooks']['onRequestResult']
// dprint-ignore
: [
...$Args['context']['config']['typeHooks']['onRequestResult'],
...$Args['context']['typeHooks']['onRequestResult'],
$Extension['typeHooks']['onRequestResult'],
]
)
Expand Down
9 changes: 7 additions & 2 deletions src/layers/6_client/properties/with.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Chain } from '../../../lib/chain/__.js'
import type { ConfigManager } from '../../../lib/config-manager/__.js'
import { mergeHeadersInit, mergeRequestInit } from '../../../lib/http.js'
import { type Context } from '../context.js'
import type { AddIncrementalInput, WithInput } from '../Settings/inputIncrementable/inputIncrementable.js'
import type { WithInput } from '../Settings/inputIncrementable/inputIncrementable.js'
import type { NormalizeInput } from '../Settings/InputToConfig.js'

export interface With_ extends Chain.Extension {
context: Context
Expand All @@ -21,7 +22,11 @@ export interface With<$Args extends Chain.Extension.Parameters<With_>> {
// @ts-ignore Passes after generation
) => Chain.Definition.MaterializeWithNewContext<
$Args['chain'],
ConfigManager.SetAtPath<$Args['context'], ['config'], AddIncrementalInput<$Args['context']['config'], $Input>>
ConfigManager.SetAtPath<
$Args['context'],
['config'],
NormalizeInput<$Args['context']['config']['initialInput'] & $Input>
>
>
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib/config-manager/ConfigManager.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ assertEqual<ConfigManager.SetAtPath<a1, ['c'], 9> , { a: { b: number
assertEqual<
ConfigManager.SetAtPath<
Context,
['config', 'typeHooks', 'onRequestResult'],
Context['config']['typeHooks']['onRequestResult']
['typeHooks', 'onRequestResult'],
Context['typeHooks']['onRequestResult']
>,
Context
>()

0 comments on commit d7d0752

Please sign in to comment.