import { atom } from 'jotai'; import { selectAtom } from 'jotai/utils'; import type { AnyModel } from '../bindings/gen_models'; import { ExtractModel } from './types'; import { newStoreData } from './util'; export const modelStoreDataAtom = atom(newStoreData()); export const cookieJarsAtom = createOrderedModelAtom('cookie_jar', 'name', 'asc'); export const environmentsAtom = createOrderedModelAtom('environment', 'sortPriority', 'asc'); export const foldersAtom = createModelAtom('folder'); export const grpcConnectionsAtom = createOrderedModelAtom('grpc_connection', 'createdAt', 'desc'); export const grpcEventsAtom = createOrderedModelAtom('grpc_event', 'createdAt', 'asc'); export const grpcRequestsAtom = createModelAtom('grpc_request'); export const httpRequestsAtom = createModelAtom('http_request'); export const httpResponsesAtom = createOrderedModelAtom('http_response', 'createdAt', 'desc'); export const httpResponseEventsAtom = createOrderedModelAtom('http_response_event', 'createdAt', 'asc'); export const keyValuesAtom = createModelAtom('key_value'); export const pluginsAtom = createModelAtom('plugin'); export const settingsAtom = createSingularModelAtom('settings'); export const websocketRequestsAtom = createModelAtom('websocket_request'); export const websocketEventsAtom = createOrderedModelAtom('websocket_event', 'createdAt', 'asc'); export const websocketConnectionsAtom = createOrderedModelAtom( 'websocket_connection', 'createdAt', 'desc', ); export const workspaceMetasAtom = createModelAtom('workspace_meta'); export const workspacesAtom = createOrderedModelAtom('workspace', 'name', 'asc'); export function createModelAtom(modelType: M) { return selectAtom( modelStoreDataAtom, (data) => Object.values(data[modelType] ?? {}), shallowEqual, ); } export function createSingularModelAtom(modelType: M) { return selectAtom(modelStoreDataAtom, (data) => { const modelData = Object.values(data[modelType] ?? {}); const item = modelData[0]; if (item == null) throw new Error('Failed creating singular model with no data: ' + modelType); return item; }); } export function createOrderedModelAtom( modelType: M, field: keyof ExtractModel, order: 'asc' | 'desc', ) { return selectAtom( modelStoreDataAtom, (data) => { const modelData = data[modelType] ?? {}; return Object.values(modelData).sort( (a: ExtractModel, b: ExtractModel) => { const n = a[field] > b[field] ? 1 : -1; return order === 'desc' ? n * -1 : n; }, ); }, shallowEqual, ); } function shallowEqual(a: T[], b: T[]): boolean { if (a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { if (a[i] !== b[i]) { return false; } } return true; }