UNPKG

@replyke/core

Version:

Replyke: Build interactive apps with social features like comments, votes, feeds, user lists, notifications, and more.

114 lines 4.03 kB
import { useCallback, useEffect, useRef, useState } from "react"; import useFetchEntity from "./useFetchEntity"; import useFetchEntityByForeignId from "./useFetchEntityByForeignId"; import useFetchEntityByShortId from "./useFetchEntityByShortId"; import useUpdateEntity from "./useUpdateEntity"; import useDeleteEntity from "./useDeleteEntity"; import { handleError } from "../../utils/handleError"; function useEntityData({ entityId, foreignId, shortId, entity: entityProp, createIfNotFound, }) { const [entity, setEntity] = useState(entityProp); // Cache to store fetched entities keyed by unique identifier const entityCache = useRef({}); const fetchEntity = useFetchEntity(); const fetchEntityByForeignId = useFetchEntityByForeignId(); const fetchEntityByShortId = useFetchEntityByShortId(); const updateEntity = useUpdateEntity(); const deleteEntity = useDeleteEntity(); const handleUpdateEntity = useCallback(async ({ update }) => { if (!entity) return; try { const newEntity = await updateEntity({ entityId: entity.id, update, }); if (newEntity) setEntity(newEntity); return newEntity; } catch (err) { handleError(err, "Failed to update entity"); } }, [entity, updateEntity]); const handleDeleteEntity = useCallback(async () => { if (!entity) return; try { await deleteEntity({ entityId: entity.id }); setEntity(undefined); } catch (err) { handleError(err, "Failed to delete entity"); } }, [entity, deleteEntity]); useEffect(() => { const handleFetchEntity = async () => { if (!foreignId && !entityId && !shortId) return; if (entity && entityId && entity.id === entityId) return; if (entity && foreignId && entity.foreignId === foreignId) return; if (entity && shortId && entity.shortId === shortId) return; const uniqueKey = `${entityId ?? ""}-${foreignId ?? ""}-${shortId ?? ""}`; // If we have a cached entity, update the state and exit. if (entityCache.current[uniqueKey]) { setEntity(entityCache.current[uniqueKey]); return; } try { let fetchedEntity = null; if (entityId) { fetchedEntity = await fetchEntity({ entityId, }); } else if (foreignId) { fetchedEntity = await fetchEntityByForeignId({ foreignId, createIfNotFound, }); } else if (shortId) { fetchedEntity = await fetchEntityByShortId({ shortId, }); } if (fetchedEntity) { // Store the fetched entity in cache. entityCache.current[uniqueKey] = fetchedEntity; setEntity(fetchedEntity); } else { setEntity(null); } } catch (err) { handleError(err, "Failed to fetch entity"); } }; handleFetchEntity(); }, [ fetchEntity, fetchEntityByForeignId, fetchEntityByShortId, entityId, foreignId, shortId, entity, createIfNotFound, ]); useEffect(() => { if (entityProp) setEntity(entityProp); }, [entityProp]); return { entity, setEntity, updateEntity: handleUpdateEntity, deleteEntity: handleDeleteEntity, }; } export default useEntityData; //# sourceMappingURL=useEntityData.js.map