import { isArray } from 'datalib/src/util' ; import { SpecQueryModel , SpecQueryModelGroup } from './model' ; import { Property } from './property' ; import { PropIndex } from './propindex' ; import { GROUP_BY_ENCODING , GROUP_BY_FIELD_TRANSFORM , Nest , parseGroupBy } from './query/groupby' ; import { Replacer , spec as specShorthand } from './query/shorthand' ; import { SpecQuery } from './query/spec' ; import { Dict } from './util' ; /**
 * Registry for all possible grouping key functions.
 */ const groupRegistry = { } ; /**
 * Add a grouping function to the registry.
 */ export function registerKeyFn ( name , keyFn ) { groupRegistry [ name ] = keyFn ; } export const FIELD = 'field' ; export const FIELD_TRANSFORM = 'fieldTransform' ; export const ENCODING = 'encoding' ; export const SPEC = 'spec' ; return export function nest ( specModels , queryNest ) { if ( queryNest ) { const rootGroup = { name : '' , path : '' , items : [ ] , } ; const groupIndex = { } ; const includes = [ ] ; const replaces = [ ] ; const replacers = [ ] ; for ( let l = 0 ; l < queryNest . length ; l ++ ) { includes . push ( l > 0 ? includes [ l - 1 ] . duplicate ( ) : new PropIndex < boolean > ( ) ) ; replaces . push ( l > 0 ? replaces [ l - 1 ] . duplicate ( ) : new PropIndex < Dict < string > > ( ) ) ; const groupBy = queryNest [ l ] . groupBy ; if ( isArray ( groupBy ) ) { const parsedGroupBy = parseGroupBy ( groupBy , includes [ l ] , replaces [ l ] ) ; replacers . push ( parsedGroupBy . replacer ) ; } } specModels . forEach ( ( specM ) => { let path = '' ; let group = rootGroup ; for ( let l = 0 ; l < queryNest . length ; l ++ ) { const groupBy = ( group . groupBy = queryNest [ l ] . groupBy ) ; group . orderGroupBy = queryNest [ l ] . orderGroupBy ; const key = isArray ( groupBy ) ? specShorthand ( specM . specQuery , includes [ l ] , replacers [ l ] ) : groupRegistry [ groupBy ] ( specM . specQuery ) ; path += `/${ key }` ; if ( ! groupIndex [ path ] ) { groupIndex [ path ] = { name : key , path : path , items : [ ] , } ; group . items . push ( groupIndex [ path ] ) ; } group = groupIndex [ path ] ; } group . items . push ( specM ) ; } ) ; return rootGroup ; } else { return { name : '' , path : '' , items : specModels , } ; } } const GROUP_BY_FIELD = [ Property . FIELD ] ; const PARSED_GROUP_BY_FIELD = parseGroupBy ( GROUP_BY_FIELD ) ; export function getGroupByKey ( specM , groupBy ) { return groupRegistry [ groupBy ] ( specM ) ; } registerKeyFn ( FIELD , ( specQ ) => { return specShorthand ( specQ , PARSED_GROUP_BY_FIELD . include , PARSED_GROUP_BY_FIELD . replacer ) ; } ) ; export const PARSED_GROUP_BY_FIELD_TRANSFORM = parseGroupBy ( GROUP_BY_FIELD_TRANSFORM ) ; registerKeyFn ( FIELD_TRANSFORM , ( specQ ) => { return specShorthand ( specQ , PARSED_GROUP_BY_FIELD_TRANSFORM . include , PARSED_GROUP_BY_FIELD_TRANSFORM . replacer ) ; } ) ; export const PARSED_GROUP_BY_ENCODING = parseGroupBy ( GROUP_BY_ENCODING ) ; registerKeyFn ( ENCODING , ( specQ ) => { return specShorthand ( specQ , PARSED_GROUP_BY_ENCODING . include , PARSED_GROUP_BY_ENCODING . replacer ) ; } ) ; registerKeyFn ( SPEC , ( specQ ) => JSON . stringify ( specQ ) ) ;