Skip to content

Commit

Permalink
Merge pull request #1241 from interval/async-metadata-props
Browse files Browse the repository at this point in the history
Allow all `io.display.metadata` `data` item props to be async (except `label`)
  • Loading branch information
jacobmischka authored May 2, 2023
2 parents 05a01a6 + 3b7addb commit 7e28046
Show file tree
Hide file tree
Showing 7 changed files with 343 additions and 18 deletions.
29 changes: 24 additions & 5 deletions src/classes/IOClient.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { v4 } from 'uuid'
import { z } from 'zod'
import { Evt } from 'evt'
import superjson from '../utils/superjson'
import {
T_IO_RENDER_INPUT,
Expand Down Expand Up @@ -35,6 +36,7 @@ import displayGrid from '../components/displayGrid'
import displayLink from '../components/displayLink'
import displayImage from '../components/displayImage'
import displayVideo from '../components/displayVideo'
import displayMetadata from '../components/displayMetadata'
import urlInput from '../components/url'
import { date, datetime } from '../components/inputDate'
import { file } from '../components/upload'
Expand Down Expand Up @@ -413,7 +415,8 @@ export class IOClient {
Props,
Output,
DefaultValue
>
>,
onPropsUpdate?: Evt<T_IO_PROPS<MethodName>>
) {
let props: T_IO_PROPS<MethodName> = inputProps
? (inputProps as T_IO_PROPS<MethodName>)
Expand All @@ -427,7 +430,8 @@ export class IOClient {

if (componentDef) {
const componentGetters = componentDef.bind(this)(
inputProps ?? ({} as Props)
inputProps ?? ({} as Props),
onPropsUpdate
)

if (componentGetters.props) {
Expand Down Expand Up @@ -540,6 +544,8 @@ export class IOClient {
} = {}
) {
return (label: string, props?: Props) => {
const onPropsUpdate = new Evt<T_IO_PROPS<MethodName>>()

if (supportsMultiple(methodName)) {
return new MultipleableIOPromise({
...this.getPromiseProps(
Expand All @@ -551,14 +557,18 @@ export class IOClient {
Props,
T_IO_RETURNS<T_IO_MULTIPLEABLE_METHOD_NAMES>
>
| undefined
| undefined,
onPropsUpdate as Evt<T_IO_PROPS<T_IO_MULTIPLEABLE_METHOD_NAMES>>
),
methodName: methodName as T_IO_MULTIPLEABLE_METHOD_NAMES,
renderer: this.renderComponents.bind(
this
) as ComponentRenderer<T_IO_MULTIPLEABLE_METHOD_NAMES>,
label,
displayResolvesImmediately: this.displayResolvesImmediately,
onPropsUpdate: onPropsUpdate as Evt<
T_IO_PROPS<T_IO_MULTIPLEABLE_METHOD_NAMES>
>,
})
}

Expand All @@ -573,14 +583,18 @@ export class IOClient {
Props,
T_IO_RETURNS<T_IO_DISPLAY_METHOD_NAMES>
>
| undefined
| undefined,
onPropsUpdate as Evt<T_IO_PROPS<T_IO_DISPLAY_METHOD_NAMES>>
),
methodName: methodName as T_IO_DISPLAY_METHOD_NAMES,
renderer: this.renderComponents.bind(
this
) as ComponentRenderer<T_IO_DISPLAY_METHOD_NAMES>,
label,
displayResolvesImmediately: this.displayResolvesImmediately,
onPropsUpdate: onPropsUpdate as Evt<
T_IO_PROPS<T_IO_DISPLAY_METHOD_NAMES>
>,
})
: new InputIOPromise({
...this.getPromiseProps(
Expand All @@ -592,14 +606,18 @@ export class IOClient {
Props,
T_IO_RETURNS<T_IO_INPUT_METHOD_NAMES>
>
| undefined
| undefined,
onPropsUpdate as Evt<T_IO_PROPS<T_IO_INPUT_METHOD_NAMES>>
),
methodName: methodName as T_IO_INPUT_METHOD_NAMES,
renderer: this.renderComponents.bind(
this
) as ComponentRenderer<T_IO_INPUT_METHOD_NAMES>,
label,
displayResolvesImmediately: this.displayResolvesImmediately,
onPropsUpdate: onPropsUpdate as Evt<
T_IO_PROPS<T_IO_INPUT_METHOD_NAMES>
>,
})
}
}
Expand Down Expand Up @@ -1016,6 +1034,7 @@ export class IOClient {
* ```
*/
metadata: this.createIOMethod('DISPLAY_METADATA', {
componentDef: displayMetadata(this.logger),
propsRequired: true,
}),
/**
Expand Down
8 changes: 8 additions & 0 deletions src/classes/IOComponent.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { z, ZodError } from 'zod'
import { Evt } from 'evt'
import {
ioSchema,
resolvesImmediately,
Expand Down Expand Up @@ -70,6 +71,7 @@ export default class IOComponent<MethodName extends T_IO_METHOD_NAMES> {
incomingState: z.infer<IoSchema[MethodName]['state']>
) => Promise<Partial<z.input<IoSchema[MethodName]['props']>>>)
| undefined
onPropsUpdate: (() => T_IO_PROPS<MethodName>) | undefined

validator:
| IOPromiseValidator<
Expand Down Expand Up @@ -100,6 +102,7 @@ export default class IOComponent<MethodName extends T_IO_METHOD_NAMES> {
validator,
multipleProps,
displayResolvesImmediately,
onPropsUpdate,
}: {
methodName: MethodName
label: string
Expand All @@ -116,11 +119,16 @@ export default class IOComponent<MethodName extends T_IO_METHOD_NAMES> {
defaultValue?: T_IO_RETURNS<MethodName>[] | null
}
displayResolvesImmediately?: boolean
onPropsUpdate?: Evt<T_IO_PROPS<MethodName>>
}) {
this.handleStateChange = onStateChange
this.schema = ioSchema[methodName]
this.validator = validator

if (onPropsUpdate) {
onPropsUpdate.attach(this.setProps.bind(this))
}

try {
initialProps = this.schema.props.parse(initialProps ?? {})
} catch (err) {
Expand Down
14 changes: 14 additions & 0 deletions src/classes/IOPromise.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Evt } from 'evt'
import {
ioSchema,
T_IO_DISPLAY_METHOD_NAMES,
Expand Down Expand Up @@ -38,6 +39,7 @@ interface IOPromiseProps<
methodName: MethodName
label: string
props: Props
onPropsUpdate?: Evt<T_IO_PROPS<MethodName>>
valueGetter?: (response: ComponentReturnValue<MethodName>) => ComponentOutput
onStateChange?: (
incomingState: T_IO_STATE<MethodName>
Expand Down Expand Up @@ -71,6 +73,7 @@ export class IOPromise<
| undefined
/* @internal */ validator: IOPromiseValidator<ComponentOutput> | undefined
protected displayResolvesImmediately: boolean | undefined
protected onPropsUpdate: Evt<T_IO_PROPS<MethodName>> | undefined

constructor({
renderer,
Expand All @@ -81,6 +84,7 @@ export class IOPromise<
onStateChange,
validator,
displayResolvesImmediately,
onPropsUpdate,
}: IOPromiseProps<MethodName, Props, ComponentOutput>) {
this.renderer = renderer
this.methodName = methodName
Expand All @@ -90,6 +94,7 @@ export class IOPromise<
this.onStateChange = onStateChange
this.validator = validator
this.displayResolvesImmediately = displayResolvesImmediately
this.onPropsUpdate = onPropsUpdate
}

then(
Expand Down Expand Up @@ -130,6 +135,7 @@ export class IOPromise<
initialProps: this.props,
onStateChange: this.onStateChange,
displayResolvesImmediately: this.displayResolvesImmediately,
onPropsUpdate: this.onPropsUpdate,
})
}
}
Expand Down Expand Up @@ -172,6 +178,7 @@ export class InputIOPromise<
onStateChange: this.onStateChange,
validator: this.validator ? this.handleValidation.bind(this) : undefined,
displayResolvesImmediately: this.displayResolvesImmediately,
onPropsUpdate: this.onPropsUpdate,
})
}

Expand Down Expand Up @@ -289,6 +296,7 @@ export class OptionalIOPromise<
isOptional: true,
validator: this.validator ? this.handleValidation.bind(this) : undefined,
displayResolvesImmediately: this.displayResolvesImmediately,
onPropsUpdate: this.onPropsUpdate,
})
}

Expand Down Expand Up @@ -353,6 +361,7 @@ export class MultipleableIOPromise<
) => Promise<Partial<Props>>
validator?: IOPromiseValidator<ComponentOutput> | undefined
displayResolvesImmediately?: boolean
onPropsUpdate?: Evt<T_IO_PROPS<MethodName>>
}) {
super(props)
this.defaultValueGetter = defaultValueGetter
Expand Down Expand Up @@ -439,6 +448,7 @@ export class MultipleIOPromise<
incomingState: T_IO_STATE<MethodName>
) => Promise<Partial<Props>>
validator?: IOPromiseValidator<ComponentOutput[]> | undefined
onPropsUpdate?: Evt<T_IO_PROPS<MethodName>>
}) {
super(rest)
this.getSingleValue = valueGetter
Expand Down Expand Up @@ -512,6 +522,7 @@ export class MultipleIOPromise<
defaultValue: this.defaultValue,
},
displayResolvesImmediately: this.displayResolvesImmediately,
onPropsUpdate: this.onPropsUpdate,
})
}

Expand Down Expand Up @@ -572,6 +583,7 @@ export class OptionalMultipleIOPromise<
incomingState: T_IO_STATE<MethodName>
) => Promise<Partial<Props>>
validator?: IOPromiseValidator<ComponentOutput[] | undefined> | undefined
onPropsUpdate?: Evt<T_IO_PROPS<MethodName>>
}) {
super(rest)
this.getSingleValue = valueGetter
Expand Down Expand Up @@ -645,6 +657,7 @@ export class OptionalMultipleIOPromise<
defaultValue: this.defaultValue,
},
displayResolvesImmediately: this.displayResolvesImmediately,
onPropsUpdate: this.onPropsUpdate,
})
}
}
Expand Down Expand Up @@ -1037,6 +1050,7 @@ export class ExclusiveIOPromise<
isOptional: false,
validator: this.validator ? this.handleValidation.bind(this) : undefined,
displayResolvesImmediately: this.displayResolvesImmediately,
onPropsUpdate: this.onPropsUpdate,
})
}

Expand Down
13 changes: 7 additions & 6 deletions src/classes/Layout.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { z } from 'zod'
import { Literal, IO_RENDER, buttonItem, metaItemSchema } from '../ioSchema'
import { AnyDisplayIOPromise, ButtonItem, PageError } from '../types'
import {
AnyDisplayIOPromise,
ButtonItem,
PageError,
EventualValue,
} from '../types'

type EventualString =
| string
| Promise<string>
| (() => string)
| (() => Promise<string>)
type EventualString = EventualValue<string>

export interface BasicLayoutConfig {
title?: EventualString
Expand Down
Loading

0 comments on commit 7e28046

Please sign in to comment.