-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a provider for h5core example app
- Loading branch information
Showing
13 changed files
with
435 additions
and
176 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { useLocation } from 'react-router-dom'; | ||
import { App } from '../packages/app'; | ||
import H5CoreProvider from '../h5web/providers/h5core/H5CoreProvider'; | ||
|
||
const URL = process.env.REACT_APP_H5CORE_URL || ''; | ||
const FILEPATH = process.env.REACT_APP_H5CORE_FALLBACK_FILEPATH || ''; | ||
|
||
function H5CoreApp() { | ||
const query = new URLSearchParams(useLocation().search); | ||
const filepath = query.get('file'); | ||
|
||
return ( | ||
<H5CoreProvider url={URL} filepath={filepath || FILEPATH}> | ||
<App /> | ||
</H5CoreProvider> | ||
); | ||
} | ||
|
||
export default H5CoreApp; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { ReactNode, useMemo } from 'react'; | ||
import { H5CoreApi } from './h5core-api'; | ||
import Provider from '../Provider'; | ||
|
||
interface Props { | ||
url: string; | ||
filepath: string; | ||
children: ReactNode; | ||
} | ||
|
||
function H5CoreProvider(props: Props) { | ||
const { url, filepath, children } = props; | ||
const api = useMemo(() => new H5CoreApi(url, filepath), [filepath, url]); | ||
|
||
return <Provider api={api}>{children}</Provider>; | ||
} | ||
|
||
export default H5CoreProvider; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import { | ||
ValueRequestParams, | ||
Attribute, | ||
Entity, | ||
Dataset, | ||
EntityKind, | ||
Group, | ||
} from '../models'; | ||
import { isDatasetResponse, isGroupResponse } from './utils'; | ||
import { assertDataset } from '../../guards'; | ||
import { ProviderApi } from '../api'; | ||
import type { | ||
H5CoreDataResponse, | ||
H5CoreAttrResponse, | ||
H5CoreMetaResponse, | ||
H5CoreDatasetMetaReponse, | ||
H5CoreGroupMetaResponse, | ||
} from './models'; | ||
import { convertDtype, flattenValue } from '../utils'; | ||
|
||
export class H5CoreApi extends ProviderApi { | ||
/* API compatible with h5core@bccdb1f77f568d6f7d3519a07c9b3bef7e9ecc20 */ | ||
public constructor(url: string, filepath: string) { | ||
super(filepath, { baseURL: url }); | ||
} | ||
|
||
public async getEntity(path: string): Promise<Entity> { | ||
return this.processEntity(path, 1); | ||
} | ||
|
||
public async getValue(params: ValueRequestParams): Promise<unknown> { | ||
const { path, selection } = params; | ||
const [value, entity] = await Promise.all([ | ||
this.fetchData(params), | ||
this.getEntity(path), | ||
]); | ||
|
||
assertDataset(entity); | ||
|
||
return flattenValue(value, entity, selection); | ||
} | ||
|
||
private async fetchAttributes(path: string): Promise<H5CoreAttrResponse> { | ||
const { data } = await this.client.get<H5CoreAttrResponse>( | ||
`/attr/${this.filepath}?path=${path}` | ||
); | ||
return data; | ||
} | ||
|
||
private async fetchData( | ||
params: ValueRequestParams | ||
): Promise<H5CoreDataResponse> { | ||
const { path, selection = '' } = params; | ||
const { data } = await this.cancellableFetchValue<H5CoreDataResponse>( | ||
`/data/${this.filepath}?path=${path}${ | ||
selection && `&selection=${selection}` | ||
}`, | ||
params | ||
); | ||
return data; | ||
} | ||
|
||
private async fetchMetadata(path: string): Promise<H5CoreMetaResponse> { | ||
const { data } = await this.client.get<H5CoreMetaResponse>( | ||
`/meta/${this.filepath}?path=${path}` | ||
); | ||
return data; | ||
} | ||
|
||
private async processEntity( | ||
path: string, | ||
depth: number | ||
): Promise<Group | Dataset | Entity> { | ||
const response = await this.fetchMetadata(path); | ||
|
||
if (isGroupResponse(response)) { | ||
const { name, type, children } = response; | ||
|
||
if (depth === 0) { | ||
return { | ||
attributes: await this.processAttributes(path, response), | ||
path, | ||
name, | ||
kind: type, | ||
children: [], | ||
}; | ||
} | ||
|
||
return { | ||
attributes: await this.processAttributes(path, response), | ||
path, | ||
name, | ||
kind: type, | ||
children: await Promise.all( | ||
children.map((content) => | ||
this.processEntity( | ||
`${path !== '/' ? path : ''}/${content.name}`, | ||
depth - 1 | ||
) | ||
) | ||
), | ||
}; | ||
} | ||
|
||
if (isDatasetResponse(response)) { | ||
// `dtype` is the type of the data contained in the dataset | ||
const { name, type: kind, dtype, shape } = response; | ||
|
||
return { | ||
attributes: await this.processAttributes(path, response), | ||
path, | ||
name, | ||
kind, | ||
shape, | ||
type: convertDtype(dtype), | ||
rawType: dtype, | ||
}; | ||
} | ||
|
||
// Treat 'other' entities as unresolved | ||
return { | ||
attributes: [], | ||
name: response.name, | ||
path, | ||
kind: EntityKind.Unresolved, | ||
}; | ||
} | ||
|
||
private async processAttributes( | ||
path: string, | ||
response: H5CoreDatasetMetaReponse | H5CoreGroupMetaResponse | ||
): Promise<Attribute[]> { | ||
const { attributes: attrsMetadata } = response; | ||
|
||
if (attrsMetadata.length === 0) { | ||
return []; | ||
} | ||
|
||
const attrValues = await this.fetchAttributes(path); | ||
return attrsMetadata.map<Attribute>((attrMetadata) => { | ||
const { name, dtype, shape } = attrMetadata; | ||
return { | ||
name, | ||
shape, | ||
type: convertDtype(dtype), | ||
value: attrValues[name], | ||
}; | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import type { EntityKind } from '../models'; | ||
|
||
export type H5CoreAttrResponse = Record<string, unknown>; | ||
|
||
export type H5CoreDataResponse = unknown; | ||
|
||
export interface H5CoreMetaResponse { | ||
name: string; | ||
type: | ||
| EntityKind.Dataset | ||
| EntityKind.Group | ||
| 'externalLink' | ||
| 'softLink' | ||
| 'other'; | ||
} | ||
|
||
export interface H5CoreSoftLinkMetaResponse extends H5CoreMetaResponse { | ||
target_path: string; | ||
type: 'softLink'; | ||
} | ||
|
||
export interface H5CoreExternalLinkMetaResponse extends H5CoreMetaResponse { | ||
target_file: string; | ||
target_path: string; | ||
type: 'externalLink'; | ||
} | ||
|
||
interface H5CoreAttrMetadata { | ||
dtype: string; | ||
name: string; | ||
shape: number[]; | ||
} | ||
|
||
export interface H5CoreDatasetMetaReponse extends H5CoreMetaResponse { | ||
attributes: H5CoreAttrMetadata[]; | ||
dtype: string; | ||
shape: number[]; | ||
type: EntityKind.Dataset; | ||
} | ||
|
||
export interface H5CoreGroupMetaResponse extends H5CoreMetaResponse { | ||
attributes: H5CoreAttrMetadata[]; | ||
children: H5CoreMetaResponse[]; | ||
type: EntityKind.Group; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { EntityKind } from '../models'; | ||
import type { | ||
H5CoreMetaResponse, | ||
H5CoreDatasetMetaReponse, | ||
H5CoreGroupMetaResponse, | ||
} from './models'; | ||
|
||
export function isGroupResponse( | ||
response: H5CoreMetaResponse | ||
): response is H5CoreGroupMetaResponse { | ||
return response.type === EntityKind.Group; | ||
} | ||
export function isDatasetResponse( | ||
response: H5CoreMetaResponse | ||
): response is H5CoreDatasetMetaReponse { | ||
return response.type === EntityKind.Dataset; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.