import type { ReadonlyPureSelectorToken, RegularAtomToken, ViewOf, } from "atom.io" import { atom, getInternalRelations, selector } from "atom.io" import type { RoomKey, SocketKey, UserKey } from "atom.io/realtime" import { ownersOfRooms, usersInRooms } from "atom.io/realtime" import type { UList } from "atom.io/transceivers/u-list" export const mySocketKeyAtom: RegularAtomToken = atom({ key: `mySocketKey`, default: undefined, }) export const myUserKeyAtom: RegularAtomToken = atom({ key: `myUserKey`, default: null, effects: [ async (userKey) => { if (typeof window !== `undefined`) { const { storageSync } = await import(`atom.io/web`) await storageSync(globalThis.localStorage, JSON, `myUserKey`)(userKey) } }, ], }) export const myRoomKeySelector: ReadonlyPureSelectorToken = selector({ key: `myRoomKey`, get: ({ get }) => { if ( `process` in globalThis && `env` in process && `REALTIME_ROOM_KEY` in process.env ) { // if a room running server-side wants its own key, this is where it lives return process.env[`REALTIME_ROOM_KEY`] as RoomKey } const myUserKey = get(myUserKeyAtom) if (!myUserKey) return null const [, usersInRoomsAtoms] = getInternalRelations(usersInRooms, `split`) const roomKeys = get(usersInRoomsAtoms, myUserKey) for (const roomKey of roomKeys) return roomKey return null }, }) export const usersHereSelector: ReadonlyPureSelectorToken< ViewOf | null> > = selector({ key: `usersHere`, get: ({ get, find }) => { const myRoomKey = get(myRoomKeySelector) if (!myRoomKey) return null const [usersInRoomsAtoms] = getInternalRelations(usersInRooms, `split`) const users = get(find(usersInRoomsAtoms, myRoomKey)) return users }, }) export const roomOwnerSelector: ReadonlyPureSelectorToken = selector({ key: `roomOwner`, get: ({ get }) => { const myRoomKey = get(myRoomKeySelector) if (!myRoomKey) return null const [, ownerOfRoomsAtoms] = getInternalRelations(ownersOfRooms, `split`) const owner = get(ownerOfRoomsAtoms, myRoomKey) for (const userKey of owner) return userKey return null }, })