UNPKG

react-storage-drafts

Version:

React Drafts is a library for creating, saving, and managing local documents in React applications.

113 lines (112 loc) 4.68 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { useCallback, useEffect, useMemo, useState } from 'react'; import { nanoid } from 'nanoid'; import DraftsContext from './Context'; import useOnline from './useOnline'; import { EDraftStatus } from './types'; export default function Provider({ referenceKey = '_duid', syncTrigger, syncInterval = 120, ...props }) { const isOnline = useOnline({ enabled: syncTrigger === 'connection', }); const [allDrafts, setDrafts] = useState([]); const [count, setCount] = useState(0); const [isLoadedStore, setIsLoadedStore] = useState(false); const drafts = useMemo(() => { return allDrafts.filter((draft) => (draft === null || draft === void 0 ? void 0 : draft.status) !== EDraftStatus.REMOVED); }, [allDrafts]); const unsyncedDrafts = useMemo(() => { return allDrafts.filter((draft) => (draft === null || draft === void 0 ? void 0 : draft.status) === EDraftStatus.CHANGED || (draft === null || draft === void 0 ? void 0 : draft.status) === EDraftStatus.REMOVED); }, [allDrafts]); const loadStoredData = useCallback(async () => { if (typeof (props === null || props === void 0 ? void 0 : props.onLoadStoredData) !== 'function') { return; } const storedData = await (props === null || props === void 0 ? void 0 : props.onLoadStoredData()); setDrafts(storedData); setIsLoadedStore(true); }, [props === null || props === void 0 ? void 0 : props.onLoadStoredData]); useEffect(() => { if (isLoadedStore) { return; } loadStoredData(); }, [isLoadedStore, loadStoredData]); const getDraft = useCallback((draftKey) => { var _a; return (_a = drafts.find((current) => current[referenceKey] === draftKey)) !== null && _a !== void 0 ? _a : null; }, [drafts, referenceKey]); const addDraft = useCallback((draft) => { if (!(draft === null || draft === void 0 ? void 0 : draft[referenceKey])) { draft._duid = nanoid(); } setDrafts((prev) => [...prev, { ...draft, status: EDraftStatus.CHANGED }]); }, [referenceKey]); const updateDraft = useCallback((draftKey, changes) => { setDrafts((prev) => prev.map((current) => { if (current[referenceKey] === draftKey) { current = { ...current, ...changes, status: EDraftStatus.CHANGED }; } return current; })); }, [referenceKey]); const removeDraft = useCallback((draftKey) => { setDrafts((prev) => prev.map((current) => { if (current[referenceKey] === draftKey) { current = { ...current, status: EDraftStatus.REMOVED }; } return current; })); }, [referenceKey]); const clearDrafts = useCallback(() => { setDrafts((prev) => prev.map((current) => ({ ...current, status: EDraftStatus.REMOVED }))); }, []); useEffect(() => { setCount(drafts === null || drafts === void 0 ? void 0 : drafts.length); }, [drafts]); const handleSync = useCallback(async () => { if (!unsyncedDrafts.length || typeof (props === null || props === void 0 ? void 0 : props.onSync) !== 'function') { return; } props.onSync(unsyncedDrafts); setDrafts((drafts) => drafts.reduce((prev, { status, ...draft }) => { if (status !== EDraftStatus.REMOVED) { prev.push(draft); } return prev; }, [])); }, [props === null || props === void 0 ? void 0 : props.onSync, unsyncedDrafts]); useEffect(() => { if (syncTrigger === 'interval' || syncTrigger === 'manual') { return; } if (syncTrigger === 'onChange' || (syncTrigger === 'connection' && isOnline)) { handleSync(); } }, [isOnline, handleSync, syncTrigger]); useEffect(() => { if (syncTrigger !== 'interval') { return; } const interval = setInterval(() => { handleSync(); }, syncInterval * 1000); return () => { clearInterval(interval); }; }, [handleSync, syncInterval, syncTrigger]); const value = useMemo(() => ({ count, drafts, addDraft, getDraft, clearDrafts, removeDraft, updateDraft, referenceKey, handleSync, }), [count, drafts, addDraft, clearDrafts, getDraft, removeDraft, updateDraft, referenceKey, handleSync]); return _jsx(DraftsContext.Provider, { value: value, children: props.children }); }