@vitessce/vit-s 3.6.7 → 3.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/data-hooks.js CHANGED
@@ -3,15 +3,13 @@ import { CoordinationType, DataType, STATUS } from '@vitessce/constants-internal
3
3
  import { useQuery, useQueries } from '@tanstack/react-query';
4
4
  import {
5
5
  LoaderNotFoundError,
6
- } from '@vitessce/abstract';
6
+ } from '@vitessce/error';
7
7
  import {
8
8
  useMultiCoordinationValues,
9
9
  useComplexCoordination,
10
- useSetWarning,
11
10
  getMatchingLoader,
12
11
  } from './state/hooks.js';
13
12
  import {
14
- warn,
15
13
  useDataType,
16
14
  useDataTypeMulti,
17
15
  } from './data-hook-utils.js';
@@ -61,9 +59,7 @@ export function useDescription(loaders, dataset) {
61
59
  * @param {object} initialCoordinationValues Object where
62
60
  * keys are coordination type names with the prefix 'initialize',
63
61
  * values are initialization preferences as boolean values.
64
- * @returns {array} [cells, cellsCount] where
65
- * cells is an object and cellsCount is the
66
- * number of items in the cells object.
62
+ * @returns {array} [data, status, urls, error]
67
63
  */
68
64
  export function useObsEmbeddingData(
69
65
  loaders, dataset, isRequired,
@@ -76,6 +72,16 @@ export function useObsEmbeddingData(
76
72
  );
77
73
  }
78
74
 
75
+ /**
76
+ * Wrapper around useDataType.
77
+ * @param {object} loaders
78
+ * @param {string} dataset
79
+ * @param {boolean} isRequired
80
+ * @param {object} coordinationSetters
81
+ * @param {object} initialCoordinationValues
82
+ * @param {object} matchOn
83
+ * @returns {array} [data, status, urls, error]
84
+ */
79
85
  export function useObsSpotsData(
80
86
  loaders, dataset, isRequired,
81
87
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -87,6 +93,16 @@ export function useObsSpotsData(
87
93
  );
88
94
  }
89
95
 
96
+ /**
97
+ * Wrapper around useDataType.
98
+ * @param {object} loaders
99
+ * @param {string} dataset
100
+ * @param {boolean} isRequired
101
+ * @param {object} coordinationSetters
102
+ * @param {object} initialCoordinationValues
103
+ * @param {object} matchOn
104
+ * @returns {array} [data, status, urls, error]
105
+ */
90
106
  export function useObsPointsData(
91
107
  loaders, dataset, isRequired,
92
108
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -98,6 +114,16 @@ export function useObsPointsData(
98
114
  );
99
115
  }
100
116
 
117
+ /**
118
+ * Wrapper around useDataType.
119
+ * @param {object} loaders
120
+ * @param {string} dataset
121
+ * @param {boolean} isRequired
122
+ * @param {object} coordinationSetters
123
+ * @param {object} initialCoordinationValues
124
+ * @param {object} matchOn
125
+ * @returns {array} [data, status, urls, error]
126
+ */
101
127
  export function useObsLocationsData(
102
128
  loaders, dataset, isRequired,
103
129
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -109,6 +135,16 @@ export function useObsLocationsData(
109
135
  );
110
136
  }
111
137
 
138
+ /**
139
+ * Wrapper around useDataType.
140
+ * @param {object} loaders
141
+ * @param {string} dataset
142
+ * @param {boolean} isRequired
143
+ * @param {object} coordinationSetters
144
+ * @param {object} initialCoordinationValues
145
+ * @param {object} matchOn
146
+ * @returns {array} [data, status, urls, error]
147
+ */
112
148
  export function useObsLabelsData(
113
149
  loaders, dataset, isRequired,
114
150
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -120,6 +156,16 @@ export function useObsLabelsData(
120
156
  );
121
157
  }
122
158
 
159
+ /**
160
+ * Wrapper around useDataType.
161
+ * @param {object} loaders
162
+ * @param {string} dataset
163
+ * @param {boolean} isRequired
164
+ * @param {object} coordinationSetters
165
+ * @param {object} initialCoordinationValues
166
+ * @param {object} matchOn
167
+ * @returns {array} [data, status, urls, error]
168
+ */
123
169
  export function useObsSegmentationsData(
124
170
  loaders, dataset, isRequired,
125
171
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -131,6 +177,16 @@ export function useObsSegmentationsData(
131
177
  );
132
178
  }
133
179
 
180
+ /**
181
+ * Wrapper around useDataType.
182
+ * @param {object} loaders
183
+ * @param {string} dataset
184
+ * @param {boolean} isRequired
185
+ * @param {object} coordinationSetters
186
+ * @param {object} initialCoordinationValues
187
+ * @param {object} matchOn
188
+ * @returns {array} [data, status, urls, error]
189
+ */
134
190
  export function useObsSetsData(
135
191
  loaders, dataset, isRequired,
136
192
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -142,6 +198,16 @@ export function useObsSetsData(
142
198
  );
143
199
  }
144
200
 
201
+ /**
202
+ * Wrapper around useDataType.
203
+ * @param {object} loaders
204
+ * @param {string} dataset
205
+ * @param {boolean} isRequired
206
+ * @param {object} coordinationSetters
207
+ * @param {object} initialCoordinationValues
208
+ * @param {object} matchOn
209
+ * @returns {array} [data, status, urls, error]
210
+ */
145
211
  export function useSampleSetsData(
146
212
  loaders, dataset, isRequired,
147
213
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -153,6 +219,16 @@ export function useSampleSetsData(
153
219
  );
154
220
  }
155
221
 
222
+ /**
223
+ * Wrapper around useDataType.
224
+ * @param {object} loaders
225
+ * @param {string} dataset
226
+ * @param {boolean} isRequired
227
+ * @param {object} coordinationSetters
228
+ * @param {object} initialCoordinationValues
229
+ * @param {object} matchOn
230
+ * @returns {array} [data, status, urls, error]
231
+ */
156
232
  export function useSampleEdgesData(
157
233
  loaders, dataset, isRequired,
158
234
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -164,6 +240,16 @@ export function useSampleEdgesData(
164
240
  );
165
241
  }
166
242
 
243
+ /**
244
+ * Wrapper around useDataType.
245
+ * @param {object} loaders
246
+ * @param {string} dataset
247
+ * @param {boolean} isRequired
248
+ * @param {object} coordinationSetters
249
+ * @param {object} initialCoordinationValues
250
+ * @param {object} matchOn
251
+ * @returns {array} [data, status, urls, error]
252
+ */
167
253
  export function useObsFeatureMatrixData(
168
254
  loaders, dataset, isRequired,
169
255
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -175,6 +261,16 @@ export function useObsFeatureMatrixData(
175
261
  );
176
262
  }
177
263
 
264
+ /**
265
+ * Wrapper around useDataType.
266
+ * @param {object} loaders
267
+ * @param {string} dataset
268
+ * @param {boolean} isRequired
269
+ * @param {object} coordinationSetters
270
+ * @param {object} initialCoordinationValues
271
+ * @param {object} matchOn
272
+ * @returns {array} [data, status, urls, error]
273
+ */
178
274
  export function useFeatureLabelsData(
179
275
  loaders, dataset, isRequired,
180
276
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -186,6 +282,16 @@ export function useFeatureLabelsData(
186
282
  );
187
283
  }
188
284
 
285
+ /**
286
+ * Wrapper around useDataType.
287
+ * @param {object} loaders
288
+ * @param {string} dataset
289
+ * @param {boolean} isRequired
290
+ * @param {object} coordinationSetters
291
+ * @param {object} initialCoordinationValues
292
+ * @param {object} matchOn
293
+ * @returns {array} [data, status, urls, error]
294
+ */
189
295
  export function useImageData(
190
296
  loaders, dataset, isRequired,
191
297
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -197,6 +303,16 @@ export function useImageData(
197
303
  );
198
304
  }
199
305
 
306
+ /**
307
+ * Wrapper around useDataType.
308
+ * @param {object} loaders
309
+ * @param {string} dataset
310
+ * @param {boolean} isRequired
311
+ * @param {object} coordinationSetters
312
+ * @param {object} initialCoordinationValues
313
+ * @param {object} matchOn
314
+ * @returns {array} [data, status, urls, error]
315
+ */
200
316
  export function useGenomicProfilesData(
201
317
  loaders, dataset, isRequired,
202
318
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -208,6 +324,16 @@ export function useGenomicProfilesData(
208
324
  );
209
325
  }
210
326
 
327
+ /**
328
+ * Wrapper around useDataType.
329
+ * @param {object} loaders
330
+ * @param {string} dataset
331
+ * @param {boolean} isRequired
332
+ * @param {object} coordinationSetters
333
+ * @param {object} initialCoordinationValues
334
+ * @param {object} matchOn
335
+ * @returns {array} [data, status, urls, error]
336
+ */
211
337
  export function useNeighborhoodsData(
212
338
  loaders, dataset, isRequired,
213
339
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -219,6 +345,16 @@ export function useNeighborhoodsData(
219
345
  );
220
346
  }
221
347
 
348
+ /**
349
+ * Wrapper around useDataType.
350
+ * @param {object} loaders
351
+ * @param {string} dataset
352
+ * @param {boolean} isRequired
353
+ * @param {object} coordinationSetters
354
+ * @param {object} initialCoordinationValues
355
+ * @param {object} matchOn
356
+ * @returns {array} [data, status, urls, error]
357
+ */
222
358
  export function useComparisonMetadata(
223
359
  loaders, dataset, isRequired,
224
360
  coordinationSetters, initialCoordinationValues, matchOn,
@@ -241,7 +377,9 @@ export function useComparisonMetadata(
241
377
  * @param {boolean} isRequired Should a warning be thrown if
242
378
  * loading is unsuccessful?
243
379
  * @param {boolean} selection A list of gene names to get expression data for.
244
- * @returns {array} [geneData] where geneData is an array [Uint8Array, ..., Uint8Array]
380
+ * @param {object} matchOn Coordination values used to obtain a matching loader.
381
+ * @returns {array} [geneData, geneName, status, errors]
382
+ * where geneData is an array [Uint8Array, ..., Uint8Array]
245
383
  * for however many genes are in the selection.
246
384
  */
247
385
  export function useFeatureSelection(
@@ -251,7 +389,6 @@ export function useFeatureSelection(
251
389
  selection,
252
390
  matchOn,
253
391
  ) {
254
- const setWarning = useSetWarning();
255
392
  const featureQueries = useQueries({
256
393
  queries: selection?.map(featureId => ({
257
394
  structuralSharing: false,
@@ -288,7 +425,7 @@ export function useFeatureSelection(
288
425
  }
289
426
  // No loader was found.
290
427
  if (isRequired) {
291
- throw new LoaderNotFoundError(loaders, dataset, DataType.OBS_FEATURE_MATRIX, matchOn);
428
+ throw new LoaderNotFoundError(`Loader not found for parameters: ${dataset}, ${DataType.OBS_FEATURE_MATRIX}, ${JSON.stringify(matchOn)}`);
292
429
  } else {
293
430
  return { data: null, dataKey: null };
294
431
  }
@@ -298,6 +435,7 @@ export function useFeatureSelection(
298
435
  });
299
436
  const anyLoading = featureQueries.some(q => q.isFetching);
300
437
  const anyError = featureQueries.some(q => q.isError);
438
+ const errors = anyError ? featureQueries.filter(q => q.isError).map(q => q.error) : [];
301
439
  // eslint-disable-next-line no-nested-ternary
302
440
  const dataStatus = anyLoading
303
441
  ? STATUS.LOADING
@@ -310,18 +448,7 @@ export function useFeatureSelection(
310
448
  isSuccess ? featureQueries.map(q => q.data?.dataKey || null) : null
311
449
  ), [isSuccess, selection, dataset]);
312
450
 
313
- useEffect(() => {
314
- featureQueries
315
- .map(q => q.error)
316
- .filter(e => Boolean(e))
317
- .forEach((error) => {
318
- warn(error, setWarning);
319
- });
320
- // Deliberate dependency omissions: use indirect dependencies for efficiency.
321
- // eslint-disable-next-line react-hooks/exhaustive-deps
322
- }, [anyError, setWarning]);
323
-
324
- return [geneData, loadedGeneName, dataStatus];
451
+ return [geneData, loadedGeneName, dataStatus, errors];
325
452
  }
326
453
 
327
454
  /**
@@ -338,13 +465,14 @@ export function useFeatureSelection(
338
465
  * @param {object} matchOn Coordination values used to obtain a matching loader.
339
466
  * @param {object} volcanoOptions Options to pass to the loadMulti function of the loader.
340
467
  * @param {string} dataType A data type.
341
- * @returns {array} [{ df, metadata }] Array of dataframes and their metadata, where
342
- * df is an object in which each column is stored as an array like { col1: arr1, col2: arr2 }.
468
+ * @returns {array} [{ df, metadata }, status, urls, error]
469
+ * Array of dataframes and their metadata, where
470
+ * df is an object in which each column is stored
471
+ * as an array like { col1: arr1, col2: arr2 }.
343
472
  */
344
473
  export function useComparativeDataType(
345
474
  loaders, dataset, isRequired, matchOn, volcanoOptions, dataType,
346
475
  ) {
347
- const setWarning = useSetWarning();
348
476
  const placeholderObject = useMemo(() => ({}), []);
349
477
  const statsQuery = useQuery({
350
478
  // TODO: only enable once `loaders` is available?
@@ -385,7 +513,7 @@ export function useComparativeDataType(
385
513
  // No loader was found.
386
514
  if (isRequired) {
387
515
  // Status: error
388
- throw new LoaderNotFoundError(loaders, dataset, dataType, matchOn);
516
+ throw new LoaderNotFoundError(`Loader not found for parameters: ${dataset}, ${dataType}, ${JSON.stringify(matchOn)}`);
389
517
  } else {
390
518
  // Status: success
391
519
  return { data: placeholderObject, dataKey: null };
@@ -399,15 +527,18 @@ export function useComparativeDataType(
399
527
  const dataStatus = isFetching ? STATUS.LOADING : status;
400
528
  const urls = data?.urls;
401
529
 
402
- useEffect(() => {
403
- if (error) {
404
- setWarning(error.message);
405
- }
406
- }, [error, setWarning]);
407
-
408
- return [loadedData, dataStatus, urls];
530
+ return [loadedData, dataStatus, urls, error];
409
531
  }
410
532
 
533
+ /**
534
+ * Wrapper around useComparativeDataType.
535
+ * @param {object} loaders
536
+ * @param {string} dataset
537
+ * @param {boolean} isRequired
538
+ * @param {object} matchOn
539
+ * @param {object} volcanoOptions
540
+ * @returns {array} [data, status, urls, error].
541
+ */
411
542
  export function useFeatureStatsData(
412
543
  loaders, dataset, isRequired, matchOn, volcanoOptions,
413
544
  ) {
@@ -417,6 +548,15 @@ export function useFeatureStatsData(
417
548
  );
418
549
  }
419
550
 
551
+ /**
552
+ * Wrapper around useComparativeDataType.
553
+ * @param {object} loaders
554
+ * @param {string} dataset
555
+ * @param {boolean} isRequired
556
+ * @param {object} matchOn
557
+ * @param {object} volcanoOptions
558
+ * @returns {array} [data, status, urls, error].
559
+ */
420
560
  export function useFeatureSetStatsData(
421
561
  loaders, dataset, isRequired, matchOn, volcanoOptions,
422
562
  ) {
@@ -426,6 +566,15 @@ export function useFeatureSetStatsData(
426
566
  );
427
567
  }
428
568
 
569
+ /**
570
+ * Wrapper around useComparativeDataType.
571
+ * @param {object} loaders
572
+ * @param {string} dataset
573
+ * @param {boolean} isRequired
574
+ * @param {object} matchOn
575
+ * @param {object} volcanoOptions
576
+ * @returns {array} [data, status, urls, error].
577
+ */
429
578
  export function useObsSetStatsData(
430
579
  loaders, dataset, isRequired, matchOn, volcanoOptions,
431
580
  ) {
@@ -447,12 +596,13 @@ export function useObsSetStatsData(
447
596
  * used to identify which loader to use.
448
597
  * @param {boolean} isRequired Should a warning be thrown if
449
598
  * loading is unsuccessful?
450
- * @returns {object} [attrs] { rows, cols } object containing cell and gene names.
599
+ * @param {object} matchOn Coordination values used to obtain a matching loader.
600
+ * @returns {object} [attrs, status, urls, error]
601
+ * where attrs is { rows, cols } object containing cell and gene names.
451
602
  */
452
603
  export function useObsFeatureMatrixIndices(
453
604
  loaders, dataset, isRequired, matchOn,
454
605
  ) {
455
- const setWarning = useSetWarning();
456
606
  const placeholderObject = useMemo(() => ({}), []);
457
607
  const indicesQuery = useQuery({
458
608
  // TODO: only enable once `loaders` is available?
@@ -501,7 +651,7 @@ export function useObsFeatureMatrixIndices(
501
651
  // No loader was found.
502
652
  if (isRequired) {
503
653
  // Status: error
504
- throw new LoaderNotFoundError(loaders, dataset, DataType.OBS_FEATURE_MATRIX, matchOn);
654
+ throw new LoaderNotFoundError(`Loader not found for parameters: ${dataset}, ${DataType.OBS_FEATURE_MATRIX}, ${JSON.stringify(matchOn)}`);
505
655
  } else {
506
656
  // Status: success
507
657
  return { data: placeholderObject, dataKey: null };
@@ -515,15 +665,19 @@ export function useObsFeatureMatrixIndices(
515
665
  const dataStatus = isFetching ? STATUS.LOADING : status;
516
666
  const urls = data?.urls;
517
667
 
518
- useEffect(() => {
519
- if (error) {
520
- setWarning(error.message);
521
- }
522
- }, [error, setWarning]);
523
-
524
- return [loadedData, dataStatus, urls];
668
+ return [loadedData, dataStatus, urls, error];
525
669
  }
526
670
 
671
+ /**
672
+ * Wrapper around useDataTypeMulti.
673
+ * @param {object} coordinationScopes
674
+ * @param {object} coordinationScopesBy
675
+ * @param {object} loaders
676
+ * @param {string} dataset
677
+ * @param {function} mergeCoordination
678
+ * @param {string} viewUid
679
+ * @returns {array} [data, status, urls, errors]
680
+ */
527
681
  export function useMultiObsPoints(
528
682
  coordinationScopes, coordinationScopesBy, loaders, dataset,
529
683
  mergeCoordination, viewUid,
@@ -541,14 +695,24 @@ export function useMultiObsPoints(
541
695
  // use coordinationScopes and coordinationScopesBy which are
542
696
  // indirect dependencies here.
543
697
  [coordinationScopes, coordinationScopesBy]);
544
- const [obsPointsData, obsPointsDataStatus, obsPointsUrls] = useDataTypeMulti(
698
+ const [obsPointsData, obsPointsDataStatus, obsPointsUrls, obsPointsErrors] = useDataTypeMulti(
545
699
  DataType.OBS_POINTS, loaders, dataset,
546
700
  false, {}, {},
547
701
  matchOnObj, mergeCoordination, viewUid,
548
702
  );
549
- return [obsPointsData, obsPointsDataStatus, obsPointsUrls];
703
+ return [obsPointsData, obsPointsDataStatus, obsPointsUrls, obsPointsErrors];
550
704
  }
551
705
 
706
+ /**
707
+ * Wrapper around useDataTypeMulti.
708
+ * @param {object} coordinationScopes
709
+ * @param {object} coordinationScopesBy
710
+ * @param {object} loaders
711
+ * @param {string} dataset
712
+ * @param {function} mergeCoordination
713
+ * @param {string} viewUid
714
+ * @returns {array} [data, status, urls, errors]
715
+ */
552
716
  export function useMultiObsSpots(
553
717
  coordinationScopes, coordinationScopesBy, loaders, dataset,
554
718
  mergeCoordination, viewUid,
@@ -566,14 +730,24 @@ export function useMultiObsSpots(
566
730
  // use coordinationScopes and coordinationScopesBy which are
567
731
  // indirect dependencies here.
568
732
  [coordinationScopes, coordinationScopesBy]);
569
- const [obsSpotsData, obsSpotsDataStatus, obsSpotsUrls] = useDataTypeMulti(
733
+ const [obsSpotsData, obsSpotsDataStatus, obsSpotsUrls, obsSpotsErrors] = useDataTypeMulti(
570
734
  DataType.OBS_SPOTS, loaders, dataset,
571
735
  false, {}, {},
572
736
  matchOnObj, mergeCoordination, viewUid,
573
737
  );
574
- return [obsSpotsData, obsSpotsDataStatus, obsSpotsUrls];
738
+ return [obsSpotsData, obsSpotsDataStatus, obsSpotsUrls, obsSpotsErrors];
575
739
  }
576
740
 
741
+ /**
742
+ * Wrapper around useDataTypeMulti.
743
+ * @param {object} coordinationScopes
744
+ * @param {object} coordinationScopesBy
745
+ * @param {object} loaders
746
+ * @param {string} dataset
747
+ * @param {function} mergeCoordination
748
+ * @param {string} viewUid
749
+ * @returns {array} [data, status, urls, errors]
750
+ */
577
751
  export function useSpotMultiObsSets(
578
752
  coordinationScopes, coordinationScopesBy, loaders, dataset,
579
753
  ) {
@@ -590,15 +764,24 @@ export function useSpotMultiObsSets(
590
764
  // use coordinationScopes and coordinationScopesBy which are
591
765
  // indirect dependencies here.
592
766
  [coordinationScopes, coordinationScopesBy]);
593
- const [obsSetsData, obsSetsDataStatus, obsSetsUrls] = useDataTypeMulti(
767
+ const [obsSetsData, obsSetsDataStatus, obsSetsUrls, obsSetsErrors] = useDataTypeMulti(
594
768
  DataType.OBS_SETS, loaders, dataset,
595
769
  false, {}, {},
596
770
  matchOnObj,
597
771
  );
598
- return [obsSetsData, obsSetsDataStatus, obsSetsUrls];
772
+ return [obsSetsData, obsSetsDataStatus, obsSetsUrls, obsSetsErrors];
599
773
  }
600
774
 
601
-
775
+ /**
776
+ * Wrapper around useDataTypeMulti.
777
+ * @param {object} coordinationScopes
778
+ * @param {object} coordinationScopesBy
779
+ * @param {object} loaders
780
+ * @param {string} dataset
781
+ * @param {function} mergeCoordination
782
+ * @param {string} viewUid
783
+ * @returns {array} [data, status, urls, errors]
784
+ */
602
785
  export function useSpotMultiFeatureLabels(
603
786
  coordinationScopes, coordinationScopesBy, loaders, dataset,
604
787
  ) {
@@ -615,15 +798,34 @@ export function useSpotMultiFeatureLabels(
615
798
  // use coordinationScopes and coordinationScopesBy which are
616
799
  // indirect dependencies here.
617
800
  [coordinationScopes, coordinationScopesBy]);
618
- const [featureLabelsData, featureLabelsStatus, featureLabelsUrls] = useDataTypeMulti(
801
+ const [
802
+ featureLabelsData,
803
+ featureLabelsStatus,
804
+ featureLabelsUrls,
805
+ featureLabelsErrors,
806
+ ] = useDataTypeMulti(
619
807
  DataType.FEATURE_LABELS, loaders, dataset,
620
808
  false, {}, {},
621
809
  matchOnObj,
622
810
  );
623
- return [featureLabelsData, featureLabelsStatus, featureLabelsUrls];
811
+ return [
812
+ featureLabelsData,
813
+ featureLabelsStatus,
814
+ featureLabelsUrls,
815
+ featureLabelsErrors,
816
+ ];
624
817
  }
625
818
 
626
-
819
+ /**
820
+ * Wrapper around useDataTypeMulti.
821
+ * @param {object} coordinationScopes
822
+ * @param {object} coordinationScopesBy
823
+ * @param {object} loaders
824
+ * @param {string} dataset
825
+ * @param {function} mergeCoordination
826
+ * @param {string} viewUid
827
+ * @returns {array} [labelsTypes, data, status, urls, errors]
828
+ */
627
829
  export function useMultiObsLabels(
628
830
  coordinationScopes, obsType, loaders, dataset,
629
831
  ) {
@@ -637,14 +839,24 @@ export function useMultiObsLabels(
637
839
  { obsLabelsType, obsType },
638
840
  ])),
639
841
  ), [obsLabelsTypes, obsType]);
640
- const [obsLabelsData, obsLabelsDataStatus, obsLabelsUrls] = useDataTypeMulti(
842
+ const [obsLabelsData, obsLabelsDataStatus, obsLabelsUrls, obsLabelsErrors] = useDataTypeMulti(
641
843
  DataType.OBS_LABELS, loaders, dataset,
642
844
  false, {}, {},
643
845
  obsLabelsMatchOnObj,
644
846
  );
645
- return [obsLabelsTypes, obsLabelsData, obsLabelsDataStatus, obsLabelsUrls];
847
+ return [obsLabelsTypes, obsLabelsData, obsLabelsDataStatus, obsLabelsUrls, obsLabelsErrors];
646
848
  }
647
849
 
850
+ /**
851
+ * Wrapper around useDataTypeMulti.
852
+ * @param {object} coordinationScopes
853
+ * @param {object} coordinationScopesBy
854
+ * @param {object} loaders
855
+ * @param {string} dataset
856
+ * @param {function} mergeCoordination
857
+ * @param {string} viewUid
858
+ * @returns {array} [data, status, urls, errors]
859
+ */
648
860
  export function useMultiObsSegmentations(
649
861
  coordinationScopes, coordinationScopesBy, loaders, dataset,
650
862
  mergeCoordination, viewUid,
@@ -666,14 +878,30 @@ export function useMultiObsSegmentations(
666
878
  obsSegmentationsData,
667
879
  obsSegmentationsDataStatus,
668
880
  obsSegmentationsUrls,
881
+ obsSegmentationsErrors,
669
882
  ] = useDataTypeMulti(
670
883
  DataType.OBS_SEGMENTATIONS, loaders, dataset,
671
884
  false, {}, {},
672
885
  matchOnObj, mergeCoordination, viewUid,
673
886
  );
674
- return [obsSegmentationsData, obsSegmentationsDataStatus, obsSegmentationsUrls];
887
+ return [
888
+ obsSegmentationsData,
889
+ obsSegmentationsDataStatus,
890
+ obsSegmentationsUrls,
891
+ obsSegmentationsErrors,
892
+ ];
675
893
  }
676
894
 
895
+ /**
896
+ * Wrapper around useDataTypeMulti.
897
+ * @param {object} coordinationScopes
898
+ * @param {object} coordinationScopesBy
899
+ * @param {object} loaders
900
+ * @param {string} dataset
901
+ * @param {function} mergeCoordination
902
+ * @param {string} viewUid
903
+ * @returns {array} [data, status, urls, errors]
904
+ */
677
905
  export function useMultiImages(
678
906
  coordinationScopes, coordinationScopesBy, loaders, dataset,
679
907
  mergeCoordination, viewUid,
@@ -693,10 +921,10 @@ export function useMultiImages(
693
921
  // use coordinationScopes and coordinationScopesBy which are
694
922
  // indirect dependencies here.
695
923
  [coordinationScopes, coordinationScopesBy]);
696
- const [imageData, imageDataStatus, imageUrls] = useDataTypeMulti(
924
+ const [imageData, imageDataStatus, imageUrls, imageErrors] = useDataTypeMulti(
697
925
  DataType.IMAGE, loaders, dataset,
698
926
  false, {}, {},
699
927
  matchOnObj, mergeCoordination, viewUid,
700
928
  );
701
- return [imageData, imageDataStatus, imageUrls];
929
+ return [imageData, imageDataStatus, imageUrls, imageErrors];
702
930
  }
package/src/hooks.js CHANGED
@@ -359,7 +359,7 @@ export function useExpandedFeatureLabelsMap(featureType, featureLabelsMap, optio
359
359
  ? Array.from(fetchedMapping).map(([k, v]) => ([k.split(':')[1], v.split(':')[1]]))
360
360
  : fetchedMapping
361
361
  ),
362
- ...(featureLabelsMap || []),
362
+ ...Array.from(featureLabelsMap?.entries() || []),
363
363
  ]);
364
364
  }, [fetchedMapping, featureLabelsMap, stripCuriePrefixes]);
365
365
  // If not enabled, return success
@@ -129,6 +129,10 @@ export function createLoaders(datasets, configDescription, fileTypes, coordinati
129
129
  const defaultCoordinationValues = Object.fromEntries(
130
130
  coordinationTypes.map(ct => ([ct.name, ct.defaultValue])),
131
131
  );
132
+ // Create an array of unique data source classes.
133
+ // This is used to get a unique index for each data source class,
134
+ // which is used below to construct `dataSourceKey`s.
135
+ const dataSourceClasses = Array.from(new Set(fileTypes.map(ft => ft.dataSourceClass)));
132
136
  datasets.forEach((dataset) => {
133
137
  const datasetLoaders = {
134
138
  name: dataset.name,
@@ -155,10 +159,11 @@ export function createLoaders(datasets, configDescription, fileTypes, coordinati
155
159
  // Create _one_ DataSourceClass instance per (URL, DataSource class name) pair.
156
160
  // Derived loaders share this object.
157
161
  const fileId = url || JSON.stringify(options);
158
- // The class name might be minified but that should not matter;
159
- // we just need a string that is unique to the class for the key.
160
- const dataSourceName = DataSourceClass.prototype.constructor.name;
161
- const dataSourceKey = [fileId, dataSourceName];
162
+ // The DataSourceClass class name might be minified, so
163
+ // DataSourceClass.prototype.constructor.name
164
+ // will not work, as it can result in conflicting strings.
165
+ const dataSourceIndex = dataSourceClasses.indexOf(DataSourceClass);
166
+ const dataSourceKey = [fileId, dataSourceIndex];
162
167
  if (!dataSources.has(dataSourceKey)) {
163
168
  dataSources.set(dataSourceKey, new DataSourceClass({
164
169
  url,