import { derived, readable, writable } from 'svelte/store'; import { createClient } from '@supabase/supabase-js'; import { supabase } from '$lib/config'; import { maxSize } from '$lib/config'; const boxParser = /\(([0-9]+),([0-9]+)\),\(([0-9]+),([0-9]+)\)/; const client = createClient(supabase.url, supabase.key); export const sensor = writable({ left: 0, top: 0, right: 0, bottom: 0 }); const getBoxes = function getBoxes({ left, top, right, bottom }) { const results = [ `box.ov."((${left},${top}),(${right},${bottom}))"`, `box.ov."((${left + maxSize},${top + maxSize}),(${right + maxSize},${bottom + maxSize}))"`, `box.ov."((${left + maxSize},${top}),(${right + maxSize},${bottom}))"`, `box.ov."((${left},${top + maxSize}),(${right},${bottom + maxSize}))"`, `box.ov."((${left - maxSize},${top - maxSize}),(${right - maxSize},${bottom - maxSize}))"`, `box.ov."((${left - maxSize},${top}),(${right - maxSize},${bottom}))"`, `box.ov."((${left},${top - maxSize}),(${right},${bottom - maxSize}))"` ]; return results; }; const serialize = function serialize(widget) { const boxComponents = widget.box.match(boxParser).slice(1, 5).map(Number); const box = { left: Math.min(boxComponents[0], boxComponents[2]), right: Math.max(boxComponents[0], boxComponents[2]), top: Math.min(boxComponents[1], boxComponents[3]), bottom: Math.max(boxComponents[1], boxComponents[3]) }; return { ...widget, box }; }; let ac = null; export const widgets = derived(sensor, async function ($sensor, set) { const boxes = getBoxes($sensor); ac && ac.abort(); ac = new AbortController(); const { data } = await client.from('widgets').select().or(boxes.join(',')).abortSignal(ac.signal); if (data) { return set(data.map(serialize)); } }); export const countElements = function countElements(left, top, right, bottom) { let countAc = null; return readable(0, (set) => { (async function () { countAc && countAc.abort(); countAc = new AbortController(); const { data } = await client .from('widgets') .select('*', { head: true, count: 'estimated' }) .or(`box.ov."((${left},${top}),(${right},${bottom}))"`) .abortSignal(countAc.signal); if (data) { return set(data); } })(); }); };