Spaces:
Sleeping
Sleeping
import { ConvexReactClient, useConvex } from 'convex/react'; | |
import { InputArgs, InputReturnValue, Inputs } from '../../convex/aiTown/inputs'; | |
import { api } from '../../convex/_generated/api'; | |
import { Id } from '../../convex/_generated/dataModel'; | |
export async function waitForInput(convex: ConvexReactClient, inputId: Id<'inputs'>) { | |
const watch = convex.watchQuery(api.aiTown.main.inputStatus, { inputId }); | |
let result = watch.localQueryResult(); | |
// The result's undefined if the query's loading and null if the input hasn't | |
// been processed yet. | |
if (result === undefined || result === null) { | |
let dispose: undefined | (() => void); | |
try { | |
await new Promise<void>((resolve, reject) => { | |
dispose = watch.onUpdate(() => { | |
try { | |
result = watch.localQueryResult(); | |
} catch (e: any) { | |
reject(e); | |
return; | |
} | |
if (result !== undefined && result !== null) { | |
resolve(); | |
} | |
}); | |
}); | |
} finally { | |
if (dispose) { | |
dispose(); | |
} | |
} | |
} | |
if (!result) { | |
throw new Error(`Input ${inputId} was never processed.`); | |
} | |
if (result.kind === 'error') { | |
throw new Error(result.message); | |
} | |
return result.value; | |
} | |
export function useSendInput<Name extends keyof Inputs>( | |
engineId: Id<'engines'>, | |
name: Name, | |
): (args: InputArgs<Name>) => Promise<InputReturnValue<Name>> { | |
const convex = useConvex(); | |
return async (args) => { | |
const inputId = await convex.mutation(api.world.sendWorldInput, { engineId, name, args }); | |
return await waitForInput(convex, inputId); | |
}; | |
} | |