import type { NdArray } from 'ndarray' ; import type { ReactChild , ReactElement } from 'react' ; import { EntityKind , DTypeClass } from './models-hdf5' ; import type { Entity , Group , GroupWithChildren , Dataset , Datatype , Shape , ScalarShape , ArrayShape , DType , NumericType , H5WebComplex , ComplexArray , BooleanType , ComplexType , PrintableType , StringType , Primitive , Value , } from './models-hdf5' ; import { ScaleType } from './models-vis' ; import { toArray } from './utils' ; const PRINTABLE_DTYPES = new Set ( [ DTypeClass . Unsigned , DTypeClass . Integer , DTypeClass . Float , DTypeClass . String , DTypeClass . Bool , DTypeClass . Complex , ] ) ; export function isAbsolutePath ( path ) { return path . startsWith ( '/' ) ; } export function assertAbsolutePath ( path ) { if ( ! isAbsolutePath ( path ) ) { throw new Error ( "Expected path to start with '/'" ) ; } } export function isReactElement ( child ) { return typeof child !== 'string' && typeof child !== 'number' ; } export function isDefined < T > ( val ) { return val !== undefined ; } export function assertDefined < T > ( val , message = 'Expected some value' ) { if ( ! isDefined ( val ) ) { throw new TypeError ( message ) ; } } function assertNum ( val ) { if ( typeof val !== 'number' ) { throw new TypeError ( 'Expected number' ) ; } } function assertBool ( val ) { if ( typeof val !== 'boolean' ) { throw new TypeError ( 'Expected boolean' ) ; } } export function assertStr ( val , message = 'Expected string' ) { if ( typeof val !== 'string' ) { throw new TypeError ( message ) ; } } function assertComplex ( val ) { if ( ! Array . isArray ( val ) || val . length !== 2 || typeof val [ 0 ] !== 'number' || typeof val [ 1 ] !== 'number' ) { throw new TypeError ( 'Expected complex' ) ; } } export function assertArray < T > ( val ) { if ( ! Array . isArray ( val ) ) { throw new TypeError ( 'Expected array' ) ; } } export function isGroup ( entity ) { return entity . kind === EntityKind . Group ; } export function hasChildren ( group ) { return 'children' in group ; } export function assertGroupWithChildren ( entity ) { if ( ! isGroup ( entity ) || ! hasChildren ( entity ) ) { throw new Error ( 'Expected group with children' ) ; } } export function isDataset ( entity ) { return entity . kind === EntityKind . Dataset ; } export function assertDataset ( entity , message = 'Expected dataset' ) { if ( ! isDataset ( entity ) ) { throw new Error ( message ) ; } } export function isDatatype ( entity ) { return entity . kind === EntityKind . Datatype ; } export function isH5WebComplex ( complex ) { return typeof complex [ 0 ] === 'number' ; } export function isScalarShape ( shape ) { return shape !== null && shape . length === 0 ; } export function hasScalarShape < T extends DType > ( dataset ) { return isScalarShape ( dataset . shape ) ; } export function assertScalarShape < T extends DType > ( dataset ) { if ( ! hasScalarShape ( dataset ) ) { throw new Error ( 'Expected dataset to have scalar shape' ) ; } } export function hasArrayShape < T extends DType > ( dataset ) { return dataset . shape !== null && dataset . shape . length > 0 ; } export function assertArrayShape < T extends DType > ( dataset ) { if ( ! hasArrayShape ( dataset ) ) { throw new Error ( 'Expected dataset to have array shape' ) ; } } export function hasNonNullShape < T extends DType > ( dataset ) { return dataset . shape !== null ; } export function assertNonNullShape < T extends DType > ( dataset ) { if ( ! hasNonNullShape ( dataset ) ) { throw new Error ( 'Expected dataset to have non-null shape' ) ; } } export function hasMinDims ( dataset , min ) { return dataset . shape . length >= min ; } export function assertMinDims ( dataset , min ) { if ( ! hasMinDims ( dataset , min ) ) { throw new Error ( `Expected dataset with at least ${ min } dimensions` ) ; } } export function hasNumDims ( dataset , num ) { return dataset . shape . length === num ; } export function assertNumDims ( dataset , num ) { if ( ! hasNumDims ( dataset , num ) ) { throw new Error ( `Expected dataset with ${ num } dimensions` ) ; } } function hasBoolType < S extends Shape > ( dataset ) { return dataset . type . class === DTypeClass . Bool ; } function hasStringType < S extends Shape > ( dataset ) { return dataset . type . class === DTypeClass . String ; } export function assertStringType < S extends Shape > ( dataset ) { if ( ! hasStringType ( dataset ) ) { throw new Error ( 'Expected dataset to have string type' ) ; } } export function isNumericType ( type ) { return [ DTypeClass . Integer , DTypeClass . Unsigned , DTypeClass . Float ] . includes ( type . class ) ; } export function hasNumericType < S extends Shape > ( dataset ) { return isNumericType ( dataset . type ) ; } export function assertNumericType < S extends Shape > ( dataset ) { if ( ! hasNumericType ( dataset ) ) { throw new Error ( 'Expected dataset to have numeric type' ) ; } } export function isStringType ( type ) { return type . class === DTypeClass . String ; } export function hasComplexType < S extends Shape > ( dataset ) { return dataset . type . class === DTypeClass . Complex ; } export function assertComplexType < S extends Shape > ( dataset ) { if ( ! hasComplexType ( dataset ) ) { throw new Error ( 'Expected dataset to have complex type' ) ; } } export function assertNumericOrComplexType < S extends Shape > ( dataset ) { if ( ! hasNumericType ( dataset ) && ! hasComplexType ( dataset ) ) { throw new Error ( 'Expected dataset to have numeric or complex type' ) ; } } export function hasPrintableType < S extends Shape > ( entity ) { return PRINTABLE_DTYPES . has ( entity . type . class ) ; } export function assertPrintableType < S extends Shape > ( dataset ) { if ( ! hasStringType ( dataset ) && ! hasNumericType ( dataset ) && ! hasBoolType ( dataset ) && ! hasComplexType ( dataset ) ) { throw new Error ( 'Expected dataset to have displayable type' ) ; } } export function isComplexValue ( type , value ) { return type . class === DTypeClass . Complex ; } function assertPrimitiveValue < T extends DType , D extends Dataset < Shape , T > > ( dataset , value ) { if ( hasNumericType ( dataset ) ) { assertNum ( value ) ; } else if ( hasStringType ( dataset ) ) { assertStr ( value ) ; } else if ( hasBoolType ( dataset ) ) { assertBool ( value ) ; } else if ( hasComplexType ( dataset ) ) { assertComplex ( value ) ; } } export function assertDatasetValue < D extends Dataset < ScalarShape | ArrayShape > > ( value , dataset ) { if ( hasArrayShape ( dataset ) ) { assertArray ( value ) ; if ( value . length > 0 ) { assertPrimitiveValue ( dataset , value [ 0 ] ) ; } } else { assertPrimitiveValue ( dataset , value ) ; } } export function assertDataLength ( arr , dataArray , arrName ) { if ( ! arr ) { return ; } const { length : arrLength } = toArray ( arr ) ; const { length : dataLength } = toArray ( dataArray ) ; if ( arrLength !== dataLength ) { throw new Error ( `Expected ${ arrName } array (${ arrLength }) to have same length as data array (${ dataLength })` ) ; } } export function isScaleType ( val ) { return ( typeof val === 'string' && Object . values < string > ( ScaleType ) . includes ( val ) ) ; }