sdk input spec improvements (#2785)

* sdk input spec improvements

* more sdk changes

* fe changes

* alpha.14

* fix tests

* separate validator in filehelper

* use deeppartial for getinput

* fix union type and update ts-matches

* alpha.15

* alpha.16

* alpha.17

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
This commit is contained in:
Aiden McClelland
2024-11-19 11:25:43 -07:00
committed by GitHub
parent 46179f5c83
commit 1771797453
24 changed files with 550 additions and 512 deletions

View File

@@ -1,5 +1,8 @@
import { InputSpec } from "./input/builder"
import { ExtractInputSpecType } from "./input/builder/inputSpec"
import {
ExtractInputSpecType,
ExtractPartialInputSpecType,
} from "./input/builder/inputSpec"
import * as T from "../types"
import { once } from "../util"
@@ -20,7 +23,10 @@ export type GetInput<
> = (options: {
effects: T.Effects
}) => Promise<
null | void | undefined | (ExtractInputSpecType<A> & Record<string, any>)
| null
| void
| undefined
| (ExtractPartialInputSpecType<A> & Record<string, any>)
>
export type MaybeFn<T> = T | ((options: { effects: T.Effects }) => Promise<T>)
@@ -52,15 +58,13 @@ export class Action<
| Record<string, any>
| InputSpec<any, Store>
| InputSpec<any, never>,
Type extends
ExtractInputSpecType<InputSpecType> = ExtractInputSpecType<InputSpecType>,
> {
private constructor(
readonly id: Id,
private readonly metadataFn: MaybeFn<T.ActionMetadata>,
private readonly inputSpec: InputSpecType,
private readonly getInputFn: GetInput<Type>,
private readonly runFn: Run<Type>,
private readonly getInputFn: GetInput<ExtractInputSpecType<InputSpecType>>,
private readonly runFn: Run<ExtractInputSpecType<InputSpecType>>,
) {}
static withInput<
Id extends T.ActionId,
@@ -69,15 +73,13 @@ export class Action<
| Record<string, any>
| InputSpec<any, Store>
| InputSpec<any, never>,
Type extends
ExtractInputSpecType<InputSpecType> = ExtractInputSpecType<InputSpecType>,
>(
id: Id,
metadata: MaybeFn<Omit<T.ActionMetadata, "hasInput">>,
inputSpec: InputSpecType,
getInput: GetInput<Type>,
run: Run<Type>,
): Action<Id, Store, InputSpecType, Type> {
getInput: GetInput<ExtractInputSpecType<InputSpecType>>,
run: Run<ExtractInputSpecType<InputSpecType>>,
): Action<Id, Store, InputSpecType> {
return new Action(
id,
mapMaybeFn(metadata, (m) => ({ ...m, hasInput: true })),
@@ -90,7 +92,7 @@ export class Action<
id: Id,
metadata: MaybeFn<Omit<T.ActionMetadata, "hasInput">>,
run: Run<{}>,
): Action<Id, Store, {}, {}> {
): Action<Id, Store, {}> {
return new Action(
id,
mapMaybeFn(metadata, (m) => ({ ...m, hasInput: false })),
@@ -114,7 +116,7 @@ export class Action<
}
async run(options: {
effects: T.Effects
input: Type
input: ExtractInputSpecType<InputSpecType>
}): Promise<T.ActionResult | null> {
return (await this.runFn(options)) || null
}
@@ -122,13 +124,13 @@ export class Action<
export class Actions<
Store,
AllActions extends Record<T.ActionId, Action<T.ActionId, Store, any, any>>,
AllActions extends Record<T.ActionId, Action<T.ActionId, Store, any>>,
> {
private constructor(private readonly actions: AllActions) {}
static of<Store>(): Actions<Store, {}> {
return new Actions({})
}
addAction<A extends Action<T.ActionId, Store, any, any>>(
addAction<A extends Action<T.ActionId, Store, any>>(
action: A,
): Actions<Store, AllActions & { [id in A["id"]]: A }> {
return new Actions({ ...this.actions, [action.id]: action })