import type { ChildEntity, Entity, Group } from '@h5web/shared'; import { isGroup } from '@h5web/shared'; import type { PropsWithChildren } from 'react'; import { createContext, useContext, useMemo } from 'react'; import { createFetchStore } from 'react-suspense-fetch'; import { hasAttribute } from '../utils'; import type { ImageAttribute } from '../vis-packs/core/models'; import type { NxAttribute } from '../vis-packs/nexus/models'; import type { DataProviderApi } from './api'; import type { AttrValuesStore, EntitiesStore, ProgressCallback, ValuesStore, } from './models'; import { getNameFromPath,getFileNameFromFilePath } from './utils'; export interface DataContextValue { // filepath: string[]; filepath: string; fileExt:string; filename: string; entitiesStore: EntitiesStore; valuesStore: ValuesStore; attrValuesStore: AttrValuesStore; // Undocumented getExportURL?: DataProviderApi['getExportURL']; addProgressListener: (cb: ProgressCallback) => void; removeProgressListener: (cb: ProgressCallback) => void; } // interface SingleDataContextValue { // filepath: string; // fileExt:string; // filename: string; // entitiesStore: EntitiesStore; // valuesStore: ValuesStore; // attrValuesStore: AttrValuesStore; // // Undocumented // getExportURL?: DataProviderApi['getExportURL']; // addProgressListener: (cb: ProgressCallback) => void; // removeProgressListener: (cb: ProgressCallback) => void; // } const DataContext = createContext({} as DataContextValue); // const SingleDataContext = createContext({} as SingleDataContextValue); export function useDataContext() { return useContext(DataContext); } interface Props { api: DataProviderApi; } function DataProvider(props: PropsWithChildren) { const { api, children } = props; const entitiesStore = useMemo(() => { const childCache = new Map>(); const store = createFetchStore(async (path: string) => { const cachedEntity = childCache.get(path); if (cachedEntity) { return cachedEntity; } const entity = await api.getEntity(path); if (isGroup(entity)) { // Cache non-group children (datasets, datatypes and links) entity.children.forEach((child) => { if (!isGroup(child)) { childCache.set(child.path, child); } }); } return entity; }); store.prefetch('/'); // pre-fetch root group return store; }, [api]); const valuesStore = useMemo(() => { const store = createFetchStore(api.getValue.bind(api), { type: 'Map', areEqual: (a, b) => a.dataset.path === b.dataset.path && a.selection === b.selection, }); return Object.assign(store, { cancelOngoing: () => api.cancelValueRequests(), evictCancelled: () => { api.cancelledValueRequests.forEach(({ storeParams }) => { valuesStore.evict(storeParams); }); api.cancelledValueRequests.clear(); }, }); }, [api]); const attrValuesStore = useMemo(() => { const store = createFetchStore(api.getAttrValues.bind(api), { type: 'Map', areEqual: (a, b) => a.path === b.path, }); return Object.assign(store, { getSingle: (entity: Entity, attrName: NxAttribute | ImageAttribute) => { return hasAttribute(entity, attrName) ? attrValuesStore.get(entity)[attrName] : undefined; }, }); }, [api]); var name = getFileNameFromFilePath(api.filepath) // var name = getFileNameFromFilePath(api.filepath,api.fileExt) return ( {children} ); } export default DataProvider;