import type { JSX } from "react"; import { start } from "@/logic/api"; import IO from "@/logic/requests/nostrill"; import type { ComposerData } from "@/types/ui"; import { create } from "zustand"; import type { UserProfile } from "@/types/nostrill"; import type { Event } from "@/types/nostr"; import type { FC, Poast } from "@/types/trill"; import { useShallow } from "zustand/shallow"; // TODO handle airlock connection issues // the SSE pipeline has a "status-update" event FWIW // type AirlockState = "connecting" | "connected" | "failed"; export type LocalState = { isNew: boolean; api: IO | null; init: () => Promise; UISettings: Record; modal: JSX.Element | null; setModal: (modal: JSX.Element | null) => void; composerData: ComposerData | null; setComposerData: (c: ComposerData | null) => void; key: string; nostrFeed: Event[]; relays: Record; profiles: Map; // pubkey key following: Map; followers: string[]; }; const creator = create(); export const useStore = creator((set, get) => ({ isNew: false, api: null, init: async () => { const airlock = await start(); const api = new IO(airlock); console.log({ api }); await api.subscribeStore((data) => { console.log("store sub", data); if ("state" in data) { const { feed, nostr, following, relays, profiles, key } = data.state; const flwing = new Map(Object.entries(following as Record)); flwing.set(api!.airlock.our!, feed); set({ relays, nostrFeed: nostr, profiles: new Map(Object.entries(profiles)), following: flwing, key, }); } else if ("fact" in data) { if ("post" in data.fact) { if ("add" in data.fact.post) { const post: Poast = data.fact.post.add.post; const following = get().following; const curr = following.get(post.author); const fc = curr ? curr : { feed: {}, start: null, end: null }; fc.feed[post.id] = post; following.set(post.author, fc); set({ following }); } } } }); set({ api }); }, key: "", profiles: new Map(), relays: {}, nostrFeed: [], following: new Map(), followers: [], UISettings: {}, modal: null, setModal: (modal) => set({ modal }), // composer data composerData: null, setComposerData: (composerData) => set({ composerData }), })); const useShallowStore = any>( selector: T, ): ReturnType => useStore(useShallow(selector)); export default useShallowStore;