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((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( engineId: Id<'engines'>, name: Name, ): (args: InputArgs) => Promise> { const convex = useConvex(); return async (args) => { const inputId = await convex.mutation(api.world.sendWorldInput, { engineId, name, args }); return await waitForInput(convex, inputId); }; }