diff --git a/index.ts b/index.ts index b9272b6..e69de29 100644 --- a/index.ts +++ b/index.ts @@ -1,164 +0,0 @@ -declare const machine: - >(definition: D) => MachineHandle.Of & Tag<"Machine">; - -namespace MachineDefinition { - export type Of = - { initial: - { value: keyof Prop - , context?: unknown - } - , states: { [state in string]: State, unknown, unknown, unknown> } - }; - - type State = - | ( - & StateBase - & { initial?: never - , states?: never - } - ) - | ( - & StateBase - & Tag<"ChildMachine"> - ); - - type StateBase = - { on?: - { [event in string]: - | T - | { target?: T - , actions: Array<(c: Ci, e: E) => Co> - } - } - } -} - -namespace MachineHandle { - export type Of = { - transition: (event: Event) => State - } - - type Event = { - [S in StateIdentifier]: { - [E in keyof Transitions]: - HasTransition extends true - ? { type: E } & EventPayloadFromActions> - : never - }[keyof Transitions] - }[StateIdentifier] - - type EventPayloadFromActions = - Actions extends [] - ? never - : Prop extends (_: any, payload: infer P) => any - ? P - : never; - - type State = - | { - [S in StateIdentifier]: - { [E in keyof Transitions]: - HasTransition extends true - ? { value: Target - , context: ContextFromActions> - } - : never - }[keyof Transitions] - }[StateIdentifier] - | Prop - - type ContextFromActions = - Actions extends [] - ? never - : Prop extends (ci: any, payload: any) => infer Co - ? Co - : never; - - type StateIdentifier = keyof Prop; - type Transitions = Prop3; - type HasTransition = Not, {}>> - type Transition = Prop4; - type Actions = Prop, "actions", []>; - type Target = - Transition extends string - ? Transition - : Prop, "target", S>; -} - -type Prop = A extends keyof T ? T[A] extends undefined ? F : T[A] : F; -type Prop2 = Prop, B, F> -type Prop3 = Prop, C, F>; -type Prop4 = Prop, D, F>; -type Prop5 = Prop, E, F>; -type AreEqual = - Exclude extends never - ? Exclude extends never - ? true - : false - : false; -type Not = T extends true ? false : true; -type Opaque = { __value: T }; -type FromOpaque = T extends Opaque ? V : never; -type Tag = { __type: N }; -type Brand = T & { __brand: N } & E; -type Cast = T extends U ? T : U; - -const promiseMachine = machine({ - initial: { value: "pending", context: {} }, - states: { - pending: { - on: { - FULFILL: { - target: "fulfilled", - actions: [ - (_: {}, { value }: { value: unknown }) => ({ value }) - ] - }, - REJECT: { - target: "rejected", - actions: [ - (_: {}, { error }: { error: unknown }) => ({ error }) - ] - } - } - }, - fulfilled: {}, - rejected: {} - } -}); - -// @ts-expect-error -promiseMachine.transition({ type: "FOO" }) - -// @ts-expect-error -promiseMachine.transition({ type: "FULFILL" }) - -promiseMachine.transition({ type: "FULFILL", value: 100 }) - -// @ts-expect-error -promiseMachine.transition({ type: "REJECT" }) - -promiseMachine.transition({ type: "REJECT", error: new Error() }) - -// @ts-expect-error -promiseMachine.transition({ type: "REJECT", error: new Error(), foo: "foo" }) - - -let nextState = promiseMachine.transition({ type: "FULFILL", value: 100 }) - -// @ts-expect-error -nextState.value === "foo" - -// @ts-expect-error -nextState.context.value - -if (nextState.value === "fulfilled") { - nextState.context.value -} - -// @ts-expect-error -nextState.context.error - -if (nextState.value === "rejected") { - nextState.context.error -} \ No newline at end of file