import { defineStore } from "pinia" import type { MemberLight, Member } from "@shared/types/member" import { getLightMembers, getFullMembers } from "@/api/member" import { reactive, ref } from "vue" import { resolve } from "path" import { rejects } from "assert" export const useMemberDirectory = defineStore('memberDirectory', () => { const light = reactive>({}); const full = reactive>({}) function getLight(id: number): Promise { if (light[id]) return Promise.resolve(light[id]); if (!lightWaiters.has(id)) { pendingLight.add(id); lightWaiters.set(id, []); } scheduleBatch(); return new Promise((resolve, reject) => { lightWaiters.get(id)!.push({ resolve, reject }) }) } function getFull(id: number): Promise { if (full[id]) return Promise.resolve(full[id]) if (!fullWaiters.has(id)) { pendingFull.add(id) fullWaiters.set(id, []) } scheduleBatch() return new Promise((resolve, reject) => { fullWaiters.get(id)!.push({ resolve, reject }) }) } function invalidateMember(id: number) { delete light[id] delete full[id] } //batching system const pendingLight = new Set() const pendingFull = new Set() // promises const lightWaiters = new Map void; reject: (e: any) => void }>>() const fullWaiters = new Map void; reject: (e: any) => void }>>() let batchTimer: ReturnType | null = null; function scheduleBatch() { if (batchTimer) return batchTimer = setTimeout(async () => { batchTimer = null; //Batch light if (pendingLight.size > 0) { const ids = Array.from(pendingLight); pendingLight.clear(); try { const res = await getLightMembers(ids); for (const m of res) { light[m.id] = m; const waiters = lightWaiters.get(m.id); if (waiters) { for (const w of waiters) w.resolve(m) lightWaiters.delete(m.id) } } for (const id of ids) { if (!light[id]) { const waiters = lightWaiters.get(id); if (waiters) { for (const w of waiters) w.reject("Not found"); lightWaiters.delete(id); } } } } catch (error) { for (const id of ids) { const waiters = lightWaiters.get(id); if (waiters) { for (const w of waiters) w.reject(error); lightWaiters.delete(id); } } } } //batch full if (pendingFull.size > 0) { const ids = Array.from(pendingFull); pendingFull.clear(); try { const res = await getFullMembers(ids); for (const m of res) { full[m.member_id] = m; const waiters = fullWaiters.get(m.member_id); if (waiters) { for (const w of waiters) w.resolve(m) fullWaiters.delete(m.member_id); } } for (const id of ids) { if (!light[id]) { const waiters = fullWaiters.get(id); if (waiters) { for (const w of waiters) w.reject("Not found"); fullWaiters.delete(id); } } } } catch (error) { for (const id of ids) { const waiters = fullWaiters.get(id); if (waiters) { for (const w of waiters) w.reject(error); fullWaiters.delete(id); } } } } }) } return { light, full, getLight, getFull, invalidateMember } })