Skip to content

Commit 63a0a7d

Browse files
committed
Reduce reliance on ArrayShape type
1 parent 0d75e12 commit 63a0a7d

8 files changed

Lines changed: 47 additions & 32 deletions

File tree

packages/app/src/dim-mapping-store.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { type DimensionMapping, initDimMapping } from '@h5web/lib';
2-
import { type ArrayShape } from '@h5web/shared/hdf5-models';
32
import { type NoProps } from '@h5web/shared/vis-models';
43
import {
54
createContext,
@@ -15,7 +14,7 @@ import { type DefaultSlice } from './vis-packs/nexus/models';
1514
import { applyDefaultSlice, areSameDims } from './vis-packs/nexus/utils';
1615

1716
interface DimMappingState {
18-
dims: ArrayShape;
17+
dims: number[];
1918
axesCount: number;
2019
lockedDimsCount: number;
2120
mapping: DimensionMapping;

packages/app/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ export {
125125
assertDatatype,
126126
isScalarShape,
127127
isArrayShape,
128+
isNonNullShape,
128129
hasScalarShape,
129130
hasArrayShape,
130131
hasNonNullShape,

packages/app/src/metadata-viewer/EntityInfo.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { isDataset, isDatatype } from '@h5web/shared/guards';
1+
import { isDataset, isDatatype, isNonNullShape } from '@h5web/shared/guards';
22
import { type ProvidedEntity } from '@h5web/shared/hdf5-models';
33

44
import { useDataContext } from '../providers/DataProvider';
55
import styles from './MetadataViewer.module.css';
66
import RawInspector from './RawInspector';
7-
import { renderShape, renderType } from './utils';
7+
import { renderDims, renderType } from './utils';
88

99
interface Props {
1010
entity: ProvidedEntity;
@@ -36,13 +36,15 @@ function EntityInfo(props: Props) {
3636
{isDataset(entity) && (
3737
<tr>
3838
<th scope="row">Shape</th>
39-
<td>{renderShape(entity.shape)}</td>
39+
<td>
40+
{isNonNullShape(entity.shape) ? renderDims(entity.shape) : 'None'}
41+
</td>
4042
</tr>
4143
)}
4244
{isDataset(entity) && entity.chunks && (
4345
<tr>
4446
<th scope="row">Chunk shape</th>
45-
<td>{renderShape(entity.chunks)}</td>
47+
<td>{renderDims(entity.chunks)}</td>
4648
</tr>
4749
)}
4850
{entity.link?.path && (
Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
import { describe, expect, it } from 'vitest';
22

3-
import { renderShape } from './utils';
3+
import { renderDims } from './utils';
44

5-
describe('renderShape', () => {
6-
it('should render scalar shape', () => {
7-
expect(renderShape([])).toBe('Scalar');
5+
describe('renderDims', () => {
6+
it('should render zero dimension', () => {
7+
expect(renderDims([])).toBe('Scalar');
88
});
99

10-
it('should render shape with one dimension', () => {
11-
expect(renderShape([5])).toBe('5');
10+
it('should render single dimension', () => {
11+
expect(renderDims([5])).toBe('5');
1212
});
1313

14-
it('should render shape with multiple dimensions', () => {
15-
expect(renderShape([10, 2, 6])).toBe('10 x 2 x 6 = 120');
16-
});
17-
18-
it('should render null shape', () => {
19-
expect(renderShape(null)).toBe('None');
14+
it('should render multiple dimensions', () => {
15+
expect(renderDims([10, 2, 6])).toBe('10 x 2 x 6 = 120');
2016
});
2117
});

packages/app/src/metadata-viewer/utils.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,25 @@ import {
22
isFloatType,
33
isH5WebComplex,
44
isIntegerType,
5-
isScalarShape,
65
} from '@h5web/shared/guards';
76
import {
87
type ComplexArray,
98
type DType,
109
DTypeClass,
1110
type H5WebComplex,
12-
type Shape,
1311
} from '@h5web/shared/hdf5-models';
1412
import { formatScalarComplex } from '@h5web/shared/vis-utils';
1513

16-
export function renderShape(shape: Shape): string {
17-
if (shape === null) {
18-
return 'None';
14+
export function renderDims(dims: number[]): string {
15+
if (dims.length === 0) {
16+
return 'Scalar';
1917
}
2018

21-
if (isScalarShape(shape)) {
22-
return 'Scalar';
19+
if (dims.length === 1) {
20+
dims.toString();
2321
}
2422

25-
return shape.length === 1
26-
? shape.toString()
27-
: `${shape.join(' x ')} = ${shape.reduce((acc, value) => acc * value)}`;
23+
return `${dims.join(' x ')} = ${dims.reduce((acc, value) => acc * value)}`;
2824
}
2925

3026
export function renderType(type: DType): string {

packages/app/src/vis-packs/nexus/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ export function guessKeepRatio(
340340
return xAxisDef?.unit === yAxisDef?.unit;
341341
}
342342

343-
export function areSameDims(dims1: ArrayShape, dims2: ArrayShape): boolean {
343+
export function areSameDims(dims1: number[], dims2: number[]): boolean {
344344
return (
345345
dims1.length === dims2.length &&
346346
dims1.every((dim, index) => dim === dims2[index])

packages/lib/src/vis/matrix/MatrixVis.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type ArrayShape } from '@h5web/shared/hdf5-models';
1+
import { assertNonEmptyArray } from '@h5web/shared/guards';
22
import { useMemo, useState } from 'react';
33
import { Grid } from 'react-window';
44
import { useStore } from 'zustand';
@@ -11,7 +11,7 @@ import { createRenderedCellsStore } from './store';
1111
import { CELL_HEIGHT } from './utils';
1212

1313
interface Props extends ClassStyleAttrs {
14-
dims: ArrayShape;
14+
dims: number[];
1515
cellFormatter: (row: number, col: number) => string;
1616
cellWidth: number;
1717
columnHeaders?: string[];
@@ -26,6 +26,8 @@ function MatrixVis(props: Props) {
2626
className = '',
2727
style,
2828
} = props;
29+
30+
assertNonEmptyArray(dims);
2931
const [rowCount, columnCount = 1] = dims;
3032

3133
const [store] = useState(createRenderedCellsStore);

packages/shared/src/guards.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,19 @@ export function assertArray(
146146
}
147147
}
148148

149+
export function isNonEmptyArray<T>(val: T[]): val is [T, ...T[]] {
150+
return val.length > 0;
151+
}
152+
153+
export function assertNonEmptyArray<T>(
154+
val: T[],
155+
message = 'Expected non-empty array',
156+
): asserts val is [T, ...T[]] {
157+
if (!isNonEmptyArray(val)) {
158+
throw new Error(message);
159+
}
160+
}
161+
149162
export function isComplexArray(val: unknown): val is H5WebComplex[] {
150163
return Array.isArray(val) && isComplex(val[0]);
151164
}
@@ -309,10 +322,16 @@ export function assertArrayShape<O extends HasShape>(
309322
}
310323
}
311324

325+
export function isNonNullShape(
326+
shape: Shape,
327+
): shape is ScalarShape | ArrayShape {
328+
return isNonNull(shape);
329+
}
330+
312331
export function hasNonNullShape<O extends HasShape>(
313332
obj: O,
314333
): obj is O & HasShape<ScalarShape | ArrayShape> {
315-
return isNonNull(obj.shape);
334+
return isNonNullShape(obj.shape);
316335
}
317336

318337
export function assertNonNullShape<O extends HasShape>(

0 commit comments

Comments
 (0)