import { createReactiveState } from '@/util/reactive-state.js'; import { isApplicationCommand, isAutocomplete } from './command-helpers'; import type { CommandState, ExecutableInteraction, PartialContext } from '../types'; export async function getCommandState(interaction: ExecutableInteraction, ctx: PartialContext): Promise> { const id = instanceIdFromInteraction(interaction); let state: CommandState; // get state from kv store if possible if (ctx.kv.has(`command-state:${id}`)) { state = await ctx.kv.get>(`command-state:${id}`); } if (!state) { state = { id: id, name: '', data: {} as T }; } const [reactiveState, subscribe] = createReactiveState(state); subscribe(async (newState) => { if (ctx.kv) { await ctx.kv.set(`command-state:${id}`, newState); } }); ctx.state = reactiveState; return reactiveState; } function instanceIdFromInteraction(interaction: ExecutableInteraction) { if (isAutocomplete(interaction)) { // autocomplete should not be stateful, they get no id return ''; } if (isApplicationCommand(interaction)) { // for application commands, we create a new instance id const instance_id = crypto.randomUUID(); return instance_id; } const interact = interaction; const customId: string = interact.data.custom_id; const commandId = customId.split('_').pop(); interaction; // command id should be a uuid if (commandId && /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(commandId)) { return commandId; } console.error(`Invalid command id extracted from interaction: ${customId}`); return ''; }