UNPKG

supastash

Version:

Offline-first sync engine for Supabase in React Native using SQLite

89 lines (88 loc) 3.05 kB
import { useEffect, useRef, useState } from "react"; import { syncCalls } from "../../store/syncCalls"; import { tableFilters, tableFiltersUsed } from "../../store/tableFilters"; import { fetchLocalData } from "../../utils/fetchData/fetchLocalData"; import { initialFetch } from "../../utils/fetchData/initialFetch"; import { logError } from "../../utils/logs"; export function fetchCalls(table, options, initialized) { const { shouldFetch = true, limit, filter, onPushToRemote, onInsertAndUpdate, useFilterWhileSyncing = true, extraMapKeys, daylength, onlyUseFilterForRealtime, orderBy, orderDesc, sqlFilter, } = options; const cancelled = useRef(false); const [isFetching, setIsFetching] = useState(false); useEffect(() => { if (filter && useFilterWhileSyncing && !tableFiltersUsed.has(table)) { tableFilters.set(table, [filter]); } if (onPushToRemote && !syncCalls.get(table)?.push) { syncCalls.set(table, { ...(syncCalls.get(table) || {}), push: onPushToRemote, }); } if (onInsertAndUpdate && !syncCalls.get(table)?.pull) { syncCalls.set(table, { ...(syncCalls.get(table) || {}), pull: onInsertAndUpdate, }); } }, [filter]); const fetch = async () => { let filters; if (sqlFilter) { filters = sqlFilter; } else if (tableFilters.has(table)) { filters = tableFilters.get(table); } else if (!onlyUseFilterForRealtime) { filters = filter ? [filter] : undefined; } if (!cancelled.current) { await fetchLocalData(table, shouldFetch, limit, extraMapKeys, daylength, filters, orderBy ?? "created_at", orderDesc ?? true); } }; const trigger = () => { if (!initialized.current) { initialized.current = true; cancelled.current = false; fetch(); } }; const cancel = () => { cancelled.current = true; }; const triggerRefresh = async () => { await fetch(); }; const initialFetchAndSync = async () => { if (!shouldFetch || cancelled.current) return; let filters; if (sqlFilter) { filters = sqlFilter; } else if (tableFilters.has(table)) { filters = tableFilters.get(table); } else if (!onlyUseFilterForRealtime) { filters = filter ? [filter] : undefined; } try { setIsFetching(true); await initialFetch(table, filters, onInsertAndUpdate, onPushToRemote); await fetch(); } catch (error) { logError(`[Supastash] Error on initial fetch for ${table}`, error); } finally { setIsFetching(false); } }; return { triggerRefresh, trigger, cancel, initialFetchAndSync, isFetching, }; }