import { z } from 'zod'; import { useAppDispatch } from 'soapbox/hooks'; import { importEntities } from '../actions'; import type { Entity } from '../types'; import type { EntitySchema } from './types'; type EntityPath = [entityType: string, listKey?: string] type CreateFn = (params: Params) => Promise | Result; interface UseCreateEntityOpts { schema?: EntitySchema } type CreateEntityResult = { success: true result: Result entity: TEntity } | { success: false error: Error } interface EntityCallbacks { onSuccess?(entity: TEntity): void onError?(error: Error): void } function useCreateEntity( path: EntityPath, createFn: CreateFn, opts: UseCreateEntityOpts = {}, ) { const [entityType, listKey] = path; const dispatch = useAppDispatch(); return async function createEntity( params: Params, callbacks: EntityCallbacks = {}, ): Promise> { try { const result = await createFn(params); const schema = opts.schema || z.custom(); const entity = schema.parse(result); // TODO: optimistic updating dispatch(importEntities([entity], entityType, listKey)); if (callbacks.onSuccess) { callbacks.onSuccess(entity); } return { success: true, result, entity, }; } catch (error) { if (callbacks.onError) { callbacks.onError(error); } return { success: false, error, }; } }; } export { useCreateEntity };