UNPKG

supastash

Version:

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

52 lines (51 loc) 2.27 kB
import { getSupastashConfig } from "../../../core/config"; import log from "../../logs"; import { supabaseClientErr } from "../../supabaseClientErr"; import { getLastDeletedInfo, updateLastDeletedInfo, } from "./getLastDeletedInfo"; import isValidFilter from "./validateFilters"; let timesPulled = 0; let lastPulled = 0; /** * Pulls deleted data from the remote database for a given table * @param table - The table to pull deleted data from * @returns The deleted data from the table as a map of id to record and the reordered data */ export async function pullDeletedData(table, filters) { const lastDeletedAt = await getLastDeletedInfo(table); const supabase = getSupastashConfig().supabaseClient; if (!supabase) throw new Error(`No supabase client found: ${supabaseClientErr}`); let filteredQuery = supabase .from(table) .select("*") .gt("deleted_at", lastDeletedAt) .order("deleted_at", { ascending: false, nullsFirst: false }); for (const filter of filters || []) { if (!isValidFilter([filter])) { throw new Error(`Invalid syncFilter: ${JSON.stringify(filter)} for table ${table}`); } filteredQuery = filteredQuery[filter.operator](filter.column, filter.value); } // Fetch records deleted after the last sync const { data, error } = await filteredQuery; if (error) { log(`[Supastash] Error fetching from ${table}:`, error.message); return null; } if (!data || data.length === 0) { timesPulled++; if (timesPulled >= 150) { const timeSinceLastPull = Date.now() - lastPulled; lastPulled = Date.now(); log(`[Supastash] No deleted records for ${table} from ${lastDeletedAt} (times pulled: ${timesPulled}) in the last ${timeSinceLastPull}ms`); timesPulled = 0; } return null; } log(`Received ${data.length} deleted records for ${table}`); // Update the supastash_deleted_status table with the lastest timestamp const lastest = data.find((r) => r.deleted_at)?.deleted_at; await updateLastDeletedInfo(table, lastest); const deletedDataMap = new Map(data.map((d) => [d.id, d])); return { deletedDataMap, records: data }; }