@@ -16,15 +16,11 @@ import {
1616 type ExportFormat ,
1717 type ExportURL ,
1818} from '@h5web/shared/vis-models' ;
19- import axios , {
20- AxiosError ,
21- type AxiosInstance ,
22- type AxiosRequestConfig ,
23- } from 'axios' ;
19+ import axios , { type AxiosRequestConfig } from 'axios' ;
2420
2521import { DataProviderApi } from '../api' ;
26- import { type ValuesStoreParams } from '../models' ;
27- import { AbortError , createAxiosProgressHandler } from '../utils' ;
22+ import { type Fetcher , type ValuesStoreParams } from '../models' ;
23+ import { createAxiosFetcher , FetcherError , toJSON } from '../utils' ;
2824import {
2925 type H5GroveAttrValuesResponse ,
3026 type H5GroveDataResponse ,
@@ -33,29 +29,31 @@ import {
3329} from './models' ;
3430import {
3531 h5groveTypedArrayFromDType ,
36- isH5GroveError ,
32+ isH5GroveErrorResponse ,
3733 parseEntity ,
3834} from './utils' ;
3935
4036const SUPPORTED_EXPORT_FORMATS = new Set < ExportFormat > ( [ 'npy' , 'tiff' ] ) ;
4137
4238export class H5GroveApi extends DataProviderApi {
43- private readonly client : AxiosInstance ;
39+ private readonly fetcher : Fetcher ;
4440
4541 /* API compatible with h5grove@2.3.0 */
4642 public constructor (
47- url : string ,
43+ private readonly baseURL : string ,
4844 filepath : string ,
4945 axiosConfig ?: AxiosRequestConfig ,
5046 private readonly _getExportURL ?: DataProviderApi [ 'getExportURL' ] ,
5147 ) {
5248 super ( filepath ) ;
5349
54- this . client = axios . create ( {
55- adapter : 'fetch' ,
56- baseURL : url ,
57- ...axiosConfig ,
58- } ) ;
50+ this . fetcher = createAxiosFetcher (
51+ axios . create ( {
52+ adapter : 'fetch' ,
53+ baseURL,
54+ ...axiosConfig ,
55+ } ) ,
56+ ) ;
5957 }
6058
6159 public override async getEntity ( path : string ) : Promise < ProvidedEntity > {
@@ -70,33 +68,25 @@ export class H5GroveApi extends DataProviderApi {
7068 ) : Promise < H5GroveDataResponse > {
7169 const { dataset } = params ;
7270
73- try {
74- if ( dataset . type . class === DTypeClass . Opaque ) {
75- return new Uint8Array (
76- await this . fetchBinaryData ( params , abortSignal , onProgress ) ,
77- ) ;
78- }
79-
80- const DTypedArray = h5groveTypedArrayFromDType ( dataset . type ) ;
81- if ( DTypedArray ) {
82- const buffer = await this . fetchBinaryData (
83- params ,
84- abortSignal ,
85- onProgress ,
86- true ,
87- ) ;
88- const array = new DTypedArray ( buffer ) ;
89- return hasScalarShape ( dataset ) ? array [ 0 ] : array ;
90- }
91-
92- return await this . fetchData ( params , abortSignal , onProgress ) ;
93- } catch ( error ) {
94- if ( error instanceof AxiosError && axios . isCancel ( error ) ) {
95- throw new AbortError ( abortSignal , error ) ;
96- }
71+ if ( dataset . type . class === DTypeClass . Opaque ) {
72+ return new Uint8Array (
73+ await this . fetchBinaryData ( params , abortSignal , onProgress ) ,
74+ ) ;
75+ }
9776
98- throw error ;
77+ const DTypedArray = h5groveTypedArrayFromDType ( dataset . type ) ;
78+ if ( DTypedArray ) {
79+ const buffer = await this . fetchBinaryData (
80+ params ,
81+ abortSignal ,
82+ onProgress ,
83+ true ,
84+ ) ;
85+ const array = new DTypedArray ( buffer ) ;
86+ return hasScalarShape ( dataset ) ? array [ 0 ] : array ;
9987 }
88+
89+ return await this . fetchData ( params , abortSignal , onProgress ) ;
10090 }
10191
10292 public override async getAttrValues (
@@ -135,42 +125,36 @@ export class H5GroveApi extends DataProviderApi {
135125 return undefined ;
136126 }
137127
138- const { baseURL, params } = this . client . defaults ;
139-
140- const searchParams = new URLSearchParams ( params as Record < string , string > ) ;
141- searchParams . set ( 'path' , dataset . path ) ;
142- searchParams . set ( 'format' , format ) ;
143-
144- if ( selection ) {
145- searchParams . set ( 'selection' , selection ) ;
146- }
128+ const searchParams = new URLSearchParams ( {
129+ file : this . filepath ,
130+ path : dataset . path ,
131+ format,
132+ ...( selection && { selection } ) ,
133+ } ) ;
147134
148- return new URL ( `${ baseURL || '' } /data/?${ searchParams . toString ( ) } ` ) ;
135+ return new URL ( `${ this . baseURL || '' } /data/?${ searchParams . toString ( ) } ` ) ;
149136 }
150137
151138 public override async getSearchablePaths ( path : string ) : Promise < string [ ] > {
152- const { data } = await this . client . get < H5GrovePathsResponse > ( `/paths/` , {
153- params : { path } ,
154- } ) ;
155-
156- return data ;
139+ const buffer = await this . fetcher ( `${ this . baseURL } /paths/` , { path } ) ;
140+ return toJSON ( buffer ) as H5GrovePathsResponse ;
157141 }
158142
159143 private async fetchEntity ( path : string ) : Promise < H5GroveEntityResponse > {
160144 try {
161- const { data } = await this . client . get < H5GroveEntityResponse > ( `/meta/` , {
162- params : { path } ,
163- } ) ;
164- return data ;
145+ const buffer = await this . fetcher ( `${ this . baseURL } /meta/` , { path } ) ;
146+ return toJSON ( buffer ) as H5GroveEntityResponse ;
165147 } catch ( error ) {
166- if (
167- ! ( error instanceof AxiosError ) ||
168- ! isH5GroveError ( error . response ?. data )
169- ) {
148+ if ( ! ( error instanceof FetcherError ) ) {
149+ throw error ;
150+ }
151+
152+ const payload = toJSON ( error . buffer ) ;
153+ if ( ! isH5GroveErrorResponse ( payload ) ) {
170154 throw error ;
171155 }
172156
173- const { message } = error . response . data ;
157+ const { message } = payload ;
174158 if ( message . includes ( 'File not found' ) ) {
175159 throw new Error ( `File not found: '${ this . filepath } '` , { cause : error } ) ;
176160 }
@@ -196,28 +180,28 @@ export class H5GroveApi extends DataProviderApi {
196180 private async fetchAttrValues (
197181 path : string ,
198182 ) : Promise < H5GroveAttrValuesResponse > {
199- const { data } = await this . client . get < H5GroveAttrValuesResponse > (
200- `/attr/` ,
201- { params : { path } } ,
202- ) ;
203- return data ;
183+ const buffer = await this . fetcher ( `${ this . baseURL } /attr/` , { path } ) ;
184+ return toJSON ( buffer ) as H5GroveAttrValuesResponse ;
204185 }
205186
206187 private async fetchData (
207188 params : ValuesStoreParams ,
208189 abortSignal : AbortSignal | undefined ,
209190 onProgress : OnProgress | undefined ,
210191 ) : Promise < H5GroveDataResponse > {
211- const { data } = await this . client . get < H5GroveDataResponse > ( '/data/' , {
212- params : {
213- path : params . dataset . path ,
214- selection : params . selection ,
215- flatten : true ,
192+ const { dataset, selection } = params ;
193+
194+ const buffer = await this . fetcher (
195+ `${ this . baseURL } /data/` ,
196+ {
197+ path : dataset . path ,
198+ ...( selection && { selection } ) ,
199+ flatten : 'true' ,
216200 } ,
217- signal : abortSignal ,
218- onDownloadProgress : createAxiosProgressHandler ( onProgress ) ,
219- } ) ;
220- return data ;
201+ { abortSignal, onProgress } ,
202+ ) ;
203+
204+ return toJSON ( buffer ) ;
221205 }
222206
223207 private async fetchBinaryData (
@@ -226,17 +210,17 @@ export class H5GroveApi extends DataProviderApi {
226210 onProgress : OnProgress | undefined ,
227211 safe = false ,
228212 ) : Promise < ArrayBuffer > {
229- const { data } = await this . client . get < ArrayBuffer > ( '/data/' , {
230- responseType : 'arraybuffer' ,
231- params : {
232- path : params . dataset . path ,
233- selection : params . selection ,
213+ const { dataset, selection } = params ;
214+
215+ return this . fetcher (
216+ `${ this . baseURL } /data/` ,
217+ {
218+ path : dataset . path ,
219+ ...( selection && { selection } ) ,
234220 format : 'bin' ,
235- dtype : safe ? 'safe' : undefined ,
221+ ... ( safe && { dtype : 'safe' } ) ,
236222 } ,
237- signal : abortSignal ,
238- onDownloadProgress : createAxiosProgressHandler ( onProgress ) ,
239- } ) ;
240- return data ;
223+ { abortSignal, onProgress } ,
224+ ) ;
241225 }
242226}
0 commit comments