// Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 import * as jotai from "jotai"; import { atomFamily } from "jotai/utils"; import { v4 as uuidv4 } from "uuid"; import * as rxjs from "rxjs"; import type { WailsEvent } from "@wailsio/runtime/types/events"; import { Events } from "@wailsio/runtime"; import { produce } from "immer"; const globalStore = jotai.createStore(); const tabId1 = uuidv4(); const tabArr: TabData[] = [{ name: "Tab 1", tabid: tabId1, blockIds: [] }]; const blockDataMap = new Map>(); const blockAtomCache = new Map>>(); const atoms = { activeTabId: jotai.atom(tabId1), tabsAtom: jotai.atom(tabArr), blockDataMap: blockDataMap, }; type SubjectWithRef = rxjs.Subject & { refCount: number; release: () => void }; const blockSubjects = new Map>(); function getBlockSubject(blockId: string): SubjectWithRef { let subject = blockSubjects.get(blockId); if (subject == null) { subject = new rxjs.Subject() as any; subject.refCount = 0; subject.release = () => { subject.refCount--; if (subject.refCount === 0) { subject.complete(); blockSubjects.delete(blockId); } }; blockSubjects.set(blockId, subject); } subject.refCount++; return subject; } Events.On("block:ptydata", (event: any) => { const data = event?.data; if (data?.blockid == null) { console.log("block:ptydata with null blockid"); return; } // we don't use getBlockSubject here because we don't want to create a new subject const subject = blockSubjects.get(data.blockid); if (subject == null) { return; } subject.next(data); }); function addBlockIdToTab(tabId: string, blockId: string) { let tabArr = globalStore.get(atoms.tabsAtom); const newTabArr = produce(tabArr, (draft) => { const tab = draft.find((tab) => tab.tabid == tabId); tab.blockIds.push(blockId); }); globalStore.set(atoms.tabsAtom, newTabArr); } function removeBlock(blockId: string) { blockDataMap.delete(blockId); blockAtomCache.delete(blockId); } function useBlockAtom(blockId: string, name: string, makeFn: () => jotai.Atom): jotai.Atom { let blockCache = blockAtomCache.get(blockId); if (blockCache == null) { blockCache = new Map>(); blockAtomCache.set(blockId, blockCache); } let atom = blockCache.get(name); if (atom == null) { atom = makeFn(); blockCache.set(name, atom); } return atom as jotai.Atom; } export { globalStore, atoms, getBlockSubject, addBlockIdToTab, blockDataMap, useBlockAtom };